Report prescan errors on their source lines
Some checks failed
akbasic CI Build / coverage (push) Failing after 27s
akbasic CI Build / cmake_build (push) Failing after 33s
akbasic CI Build / akgl_build (push) Failing after 18s
akbasic CI Build / sanitizers (push) Failing after 1m7s
akbasic CI Build / mutation_test (push) Failing after 39s
Some checks failed
akbasic CI Build / coverage (push) Failing after 27s
akbasic CI Build / cmake_build (push) Failing after 33s
akbasic CI Build / akgl_build (push) Failing after 18s
akbasic CI Build / sanitizers (push) Failing after 1m7s
akbasic CI Build / mutation_test (push) Failing after 39s
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
* below.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "harness.h"
|
||||
|
||||
/**
|
||||
@@ -341,6 +343,28 @@ static akerr_ErrorContext AKERR_NOIGNORE *test_prescan_boundaries(void)
|
||||
SUCCEED_RETURN(errctx);
|
||||
}
|
||||
|
||||
/** @brief A full label table reports the line whose label could not be filed. */
|
||||
static void test_label_prescan_error_line(void)
|
||||
{
|
||||
char source[4096] = "";
|
||||
size_t used = 0;
|
||||
int i = 0;
|
||||
|
||||
for ( i = 1; i <= AKBASIC_MAX_LABELS + 1; i++ ) {
|
||||
used += (size_t)snprintf(source + used, sizeof(source) - used,
|
||||
"%d LABEL L%d\n", i, i);
|
||||
}
|
||||
(void)snprintf(source + used, sizeof(source) - used, "100 PRINT 1\n");
|
||||
|
||||
TEST_REQUIRE_OK(harness_start(NULL));
|
||||
TEST_REQUIRE_OK(akbasic_runtime_load(&HARNESS_RUNTIME, source));
|
||||
TEST_REQUIRE_OK(akbasic_runtime_start(&HARNESS_RUNTIME, AKBASIC_MODE_RUN));
|
||||
TEST_REQUIRE(strstr(HARNESS_OUTPUT, "? 65 : PARSE ERROR") != NULL,
|
||||
"a full label table should report its source line, got \"%s\"",
|
||||
HARNESS_OUTPUT);
|
||||
harness_stop();
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
PREPARE_ERROR(errctx);
|
||||
@@ -355,6 +379,7 @@ int main(void)
|
||||
CATCH(errctx, test_undefined_label_is_reported());
|
||||
CATCH(errctx, test_arm_refusals());
|
||||
CATCH(errctx, test_prescan_boundaries());
|
||||
test_label_prescan_error_line();
|
||||
} CLEANUP {
|
||||
} PROCESS(errctx) {
|
||||
} HANDLE_DEFAULT(errctx) {
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
? 90 : PARSE ERROR TYPE POINT: POINT is a reserved word and cannot name a type
|
||||
? 60 : PARSE ERROR TYPE POINT: POINT is a reserved word and cannot name a type
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
* TODO.md section 6.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <akbasic/error.h>
|
||||
@@ -174,6 +175,34 @@ static void test_colon_ends_data(void)
|
||||
harness_stop();
|
||||
}
|
||||
|
||||
/** @brief DATA overflow reports the line where the item limit was crossed. */
|
||||
static void test_data_prescan_error_line(void)
|
||||
{
|
||||
char source[4096] = "";
|
||||
size_t used = 0;
|
||||
int line = 0;
|
||||
int item = 0;
|
||||
|
||||
for ( line = 1; line <= 34; line++ ) {
|
||||
used += (size_t)snprintf(source + used, sizeof(source) - used, "%d DATA ", line);
|
||||
for ( item = 0; item < 15; item++ ) {
|
||||
used += (size_t)snprintf(source + used, sizeof(source) - used,
|
||||
"%s1", (item == 0 ? "" : ","));
|
||||
}
|
||||
used += (size_t)snprintf(source + used, sizeof(source) - used, "\n");
|
||||
}
|
||||
used += (size_t)snprintf(source + used, sizeof(source) - used, "100 DATA 1,1\n");
|
||||
(void)snprintf(source + used, sizeof(source) - used, "101 DATA 1\n200 PRINT 1\n");
|
||||
|
||||
TEST_REQUIRE_OK(harness_start(NULL));
|
||||
TEST_REQUIRE_OK(akbasic_runtime_load(&HARNESS_RUNTIME, source));
|
||||
TEST_REQUIRE_OK(akbasic_runtime_start(&HARNESS_RUNTIME, AKBASIC_MODE_RUN));
|
||||
TEST_REQUIRE(strstr(HARNESS_OUTPUT, "? 101 : PARSE ERROR") != NULL,
|
||||
"DATA overflow should report its source line, got \"%s\"",
|
||||
HARNESS_OUTPUT);
|
||||
harness_stop();
|
||||
}
|
||||
|
||||
/** @brief A float item fills a float variable with its fractional part intact. */
|
||||
static void test_float_items(void)
|
||||
{
|
||||
@@ -227,6 +256,7 @@ int main(void)
|
||||
test_type_mismatch();
|
||||
test_quoted_items();
|
||||
test_colon_ends_data();
|
||||
test_data_prescan_error_line();
|
||||
test_float_items();
|
||||
test_negative_items();
|
||||
return akbasic_test_failures;
|
||||
|
||||
@@ -218,6 +218,22 @@ static void test_declaration_errors_are_basic_errors(void)
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief A field declaration error reports the field's source line. */
|
||||
static void test_type_prescan_error_line(void)
|
||||
{
|
||||
TEST_REQUIRE_OK(harness_start(NULL));
|
||||
TEST_REQUIRE_OK(akbasic_runtime_load(&HARNESS_RUNTIME,
|
||||
"10 TYPE RECT\n"
|
||||
"20 W# EXTRA\n"
|
||||
"30 END TYPE\n"
|
||||
"40 PRINT 1\n"));
|
||||
TEST_REQUIRE_OK(akbasic_runtime_start(&HARNESS_RUNTIME, AKBASIC_MODE_RUN));
|
||||
TEST_REQUIRE(strstr(HARNESS_OUTPUT, "? 20 : PARSE ERROR") != NULL,
|
||||
"TYPE prescan should report its source line, got \"%s\"",
|
||||
HARNESS_OUTPUT);
|
||||
harness_stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief An over-long type or field name is refused, not silently trimmed.
|
||||
*
|
||||
@@ -270,6 +286,7 @@ int main(void)
|
||||
test_missing_field_lists_the_others();
|
||||
test_self_by_value_refused();
|
||||
test_declaration_errors_are_basic_errors();
|
||||
test_type_prescan_error_line();
|
||||
test_long_names_are_refused();
|
||||
|
||||
return akbasic_test_failures;
|
||||
|
||||
Reference in New Issue
Block a user