From 22d19a4cefe5c60107c4d2510589c4be8e9f88fc Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Fri, 31 May 2013 06:10:32 +0000 Subject: [PATCH] Added diagnostic for expected tokens, a test, and a testsuite underflow bug. --- diag.c | 19 ++++++++++++++++--- gmqcc.h | 5 +++-- parser.c | 6 ++++-- test.c | 5 +++-- tests/diag/expected.qc | 1 + tests/diag/expected.tmpl | 7 +++++++ 6 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 tests/diag/expected.qc create mode 100644 tests/diag/expected.tmpl diff --git a/diag.c b/diag.c index c6476b4..73807f2 100644 --- a/diag.c +++ b/diag.c @@ -103,7 +103,7 @@ static void diagnostic_line(const char *file, size_t line, diagnostic_data_t *** vec_push((*read), datas[feed]); } -static void diagnostic_feed(const char *file, size_t line, size_t beg, size_t end, bool marker, size_t diagnostic) { +static void diagnostic_feed(const char *file, size_t line, size_t column, size_t beg, size_t end, bool marker, size_t diagnostic) { diagnostic_data_t **read = NULL; size_t feed = 0; size_t space = 6; @@ -160,6 +160,15 @@ static void diagnostic_feed(const char *file, size_t line, size_t beg, size_t en space -= beg - end; break; + case DIAGNOSTIC_EXPECTED: + /* + * use the column number here, it's the EASIEST method yet + * because it points to the exact space. + */ + space += column; + len = 0; + break; + case DIAGNOSTIC_UNEXPECTED_IDENT: for (itr = 0; len < vec_size(vec_last(read)->tokens); len++) { if (vec_last(read)->tokens[len] == TOKEN_IDENT) @@ -212,7 +221,7 @@ void diagnostic_destroy() { util_htrem(diagnostic_table, diagnostic_destory_data); } -void diagnostic_calculate(const char *file, size_t line, size_t diagnostic) { +void diagnostic_calculate(const char *file, size_t line, size_t column, size_t diagnostic) { size_t linebeg = 1; size_t linecnt = 1; bool marker = false; @@ -234,6 +243,10 @@ void diagnostic_calculate(const char *file, size_t line, size_t diagnostic) { marker = true; break; + case DIAGNOSTIC_EXPECTED: + marker = true; + break; + case DIAGNOSTIC_UNEXPECTED_IDENT: marker = true; break; @@ -243,5 +256,5 @@ void diagnostic_calculate(const char *file, size_t line, size_t diagnostic) { return; } - diagnostic_feed(file, line, linebeg, linecnt, marker, diagnostic); + diagnostic_feed(file, line, column, linebeg, linecnt, marker, diagnostic); } diff --git a/gmqcc.h b/gmqcc.h index 238f2d1..1882a30 100644 --- a/gmqcc.h +++ b/gmqcc.h @@ -1034,11 +1034,12 @@ enum { DIAGNOSTIC_NULL, DIAGNOSTIC_SEMICOLON, DIAGNOSTIC_EXPRESSION_CASE, - DIAGNOSTIC_UNEXPECTED_IDENT + DIAGNOSTIC_UNEXPECTED_IDENT, + DIAGNOSTIC_EXPECTED }; void diagnostic_destroy(); -void diagnostic_calculate(const char *file, size_t line, size_t diagnostic); +void diagnostic_calculate(const char *file, size_t line, size_t column, size_t diagnostic); /*===================================================================*/ diff --git a/parser.c b/parser.c index d0aaf4a..2d6cd1d 100644 --- a/parser.c +++ b/parser.c @@ -139,7 +139,7 @@ static void parseerror(parser_t *parser, const char *fmt, ...) vcompile_error(parser->lex->tok.ctx, fmt, ap); va_end(ap); - diagnostic_calculate(parser->lex->name, parser->lex->line, parser->diagnostic); + diagnostic_calculate(parser->lex->name, parser->lex->line, parser->lex->column, parser->diagnostic); } /* returns true if it counts as an error */ @@ -151,7 +151,7 @@ static bool GMQCC_WARN parsewarning(parser_t *parser, int warntype, const char * r = vcompile_warning(parser->lex->tok.ctx, warntype, fmt, ap); va_end(ap); - diagnostic_calculate(parser->lex->name, parser->lex->line, parser->diagnostic); + diagnostic_calculate(parser->lex->name, parser->lex->line, parser->lex->column, parser->diagnostic); return r; } @@ -3898,6 +3898,7 @@ static bool parse_enum(parser_t *parser) parser_addglobal(parser, var->name, (ast_expression*)var); if (!parser_next(parser)) { + parser->diagnostic = DIAGNOSTIC_EXPECTED; parseerror(parser, "expected `=`, `}` or comma after identifier"); goto onerror; } @@ -3907,6 +3908,7 @@ static bool parse_enum(parser_t *parser) if (parser->tok == '}') break; if (parser->tok != '=') { + parser->diagnostic = DIAGNOSTIC_EXPECTED; parseerror(parser, "expected `=`, `}` or comma after identifier"); goto onerror; } diff --git a/test.c b/test.c index 445fa3d..e68211b 100644 --- a/test.c +++ b/test.c @@ -436,7 +436,7 @@ static bool task_template_parse(const char *file, task_template_t *tmpl, FILE *f goto failure; } - if (value && *value && (*value == ' ' || *value == '\t')) + if (value && (*value == ' ' || *value == '\t')) value++; /* @@ -449,6 +449,7 @@ static bool task_template_parse(const char *file, task_template_t *tmpl, FILE *f exit(EXIT_FAILURE); vec_push(tmpl->comparematch, util_strdup(value)); + printf("VALUE: %s\n", value); break; } @@ -1230,7 +1231,7 @@ static void task_schedualize(size_t *pad) { ); for (; d < vec_size(task_tasks[i].tmpl->comparematch); d++) { char *select = task_tasks[i].tmpl->comparematch[d]; - size_t length = 40 - strlen(select); + size_t length = 60 - strlen(select); con_out(" Expected: \"%s\"", select); while (length --) diff --git a/tests/diag/expected.qc b/tests/diag/expected.qc new file mode 100644 index 0000000..1b24a57 --- /dev/null +++ b/tests/diag/expected.qc @@ -0,0 +1 @@ +enum { A B }; diff --git a/tests/diag/expected.tmpl b/tests/diag/expected.tmpl new file mode 100644 index 0000000..a665769 --- /dev/null +++ b/tests/diag/expected.tmpl @@ -0,0 +1,7 @@ +I: expected.qc +D: expected comma after identifier +T: -diagnostic +C: -std=gmqcc +M: expected `=`, `}` or comma after identifier +M: 1: enum { A B }; +M: ^ -- 2.39.2