X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Flexer%2Flexer.c;h=562fcc5827d3a4662d237633cb3785dee6e0cf33;hb=37cbc94c3ed75eb0ac345c7ada138ef4662f1433;hp=6e9bba43a789042259132b1ba7a3bde63407c6e8;hpb=458ce22a11c42436ad318d76bcbb39ed855d1c27;p=pspp diff --git a/src/language/lexer/lexer.c b/src/language/lexer/lexer.c index 6e9bba43a7..562fcc5827 100644 --- a/src/language/lexer/lexer.c +++ b/src/language/lexer/lexer.c @@ -1242,6 +1242,34 @@ lex_get_file_name (const struct lexer *lexer) return src == NULL ? NULL : src->reader->file_name; } +/* Returns a newly allocated msg_location for the syntax that represents tokens + with 0-based offsets N0...N1, inclusive, from the current token. The caller + must eventually free the location (with msg_location_destroy()). */ +struct msg_location * +lex_get_location (const struct lexer *lexer, int n0, int n1) +{ + struct msg_location *loc = lex_get_lines (lexer, n0, n1); + loc->first_column = lex_get_first_column (lexer, n0); + loc->last_column = lex_get_last_column (lexer, n1); + return loc; +} + +/* Returns a newly allocated msg_location for the syntax that represents tokens + with 0-based offsets N0...N1, inclusive, from the current token. The + location only covers the tokens' lines, not the columns. The caller must + eventually free the location (with msg_location_destroy()). */ +struct msg_location * +lex_get_lines (const struct lexer *lexer, int n0, int n1) +{ + struct msg_location *loc = xmalloc (sizeof *loc); + *loc = (struct msg_location) { + .file_name = xstrdup_if_nonnull (lex_get_file_name (lexer)), + .first_line = lex_get_first_line_number (lexer, n0), + .last_line = lex_get_last_line_number (lexer, n1), + }; + return loc; +} + const char * lex_get_encoding (const struct lexer *lexer) { @@ -1452,8 +1480,8 @@ lex_source_get_syntax__ (const struct lex_source *src, int n0, int n1) return ds_steal_cstr (&s); } -static void -lex_ellipsize__ (struct substring in, char *out, size_t out_size) +void +lex_ellipsize (struct substring in, char *out, size_t out_size) { size_t out_maxlen; size_t out_len; @@ -1527,14 +1555,14 @@ lex_source_error_valist (struct lex_source *src, int n0, int n1, /* Get the syntax that caused the error. */ char *syntax = lex_source_get_syntax__ (src, n0, n1); char syntax_cstr[64]; - lex_ellipsize__ (ss_cstr (syntax), syntax_cstr, sizeof syntax_cstr); + lex_ellipsize (ss_cstr (syntax), syntax_cstr, sizeof syntax_cstr); free (syntax); /* Get the macro call(s) that expanded to the syntax that caused the error. */ char call_cstr[64]; struct substring call = lex_source_get_macro_call (src, n0, n1); - lex_ellipsize__ (call, call_cstr, sizeof call_cstr); + lex_ellipsize (call, call_cstr, sizeof call_cstr); if (syntax_cstr[0]) { @@ -1560,34 +1588,44 @@ lex_source_error_valist (struct lex_source *src, int n0, int n1, if (ds_last (&s) != '.') ds_put_byte (&s, '.'); - struct msg m = { - .category = MSG_C_SYNTAX, - .severity = MSG_S_ERROR, - .file_name = src->reader->file_name, + struct msg_location *location = xmalloc (sizeof *location); + *location = (struct msg_location) { + .file_name = xstrdup_if_nonnull (src->reader->file_name), .first_line = lex_source_get_first_line_number (src, n0), .last_line = lex_source_get_last_line_number (src, n1), .first_column = lex_source_get_first_column (src, n0), .last_column = lex_source_get_last_column (src, n1), + }; + struct msg *m = xmalloc (sizeof *m); + *m = (struct msg) { + .category = MSG_C_SYNTAX, + .severity = MSG_S_ERROR, + .location = location, .text = ds_steal_cstr (&s), }; - msg_emit (&m); + msg_emit (m); } -static void PRINTF_FORMAT (2, 3) -lex_get_error (struct lex_source *src, const char *format, ...) +static void PRINTF_FORMAT (4, 5) +lex_source_error (struct lex_source *src, int n0, int n1, + const char *format, ...) { va_list args; va_start (args, format); + lex_source_error_valist (src, n0, n1, format, args); + va_end (args); +} +static void +lex_get_error (struct lex_source *src, const char *s) +{ size_t old_middle = src->middle; src->middle = src->front; size_t n = src->front - src->back - 1; - lex_source_error_valist (src, n, n, format, args); + lex_source_error (src, n, n, "%s", s); src->middle = old_middle; lex_source_pop_front (src); - - va_end (args); } /* Attempts to append an additional token at the front of SRC, reading more @@ -1739,44 +1777,17 @@ lex_source_try_get__ (struct lex_source *src) return true; case SCAN_BAD_HEX_LENGTH: - lex_get_error (src, _("String of hex digits has %d characters, which " - "is not a multiple of 2"), - (int) token->token.number); - return false; - case SCAN_BAD_HEX_DIGIT: case SCAN_BAD_UNICODE_DIGIT: - lex_get_error (src, _("`%c' is not a valid hex digit"), - (int) token->token.number); - return false; - case SCAN_BAD_UNICODE_LENGTH: - lex_get_error (src, _("Unicode string contains %d bytes, which is " - "not in the valid range of 1 to 8 bytes"), - (int) token->token.number); - return false; - case SCAN_BAD_UNICODE_CODE_POINT: - lex_get_error (src, _("U+%04X is not a valid Unicode code point"), - (int) token->token.number); - return false; - case SCAN_EXPECTED_QUOTE: - lex_get_error (src, _("Unterminated string constant")); - return false; - case SCAN_EXPECTED_EXPONENT: - lex_get_error (src, _("Missing exponent following `%s'"), - token->token.string.string); - return false; - case SCAN_UNEXPECTED_CHAR: - { - char c_name[16]; - lex_get_error (src, _("Bad character %s in input"), - uc_name (token->token.number, c_name)); - return false; - } + char *msg = scan_token_to_error (&token->token); + lex_get_error (src, msg); + free (msg); + return false; case SCAN_SKIP: lex_source_pop_front (src); @@ -1884,7 +1895,7 @@ lex_source_get (const struct lex_source *src_) /* Now expand the macro. */ struct macro_tokens expansion = { .n = 0 }; - macro_expander_get_expansion (me, &expansion); + macro_expander_get_expansion (me, src->reader->syntax, &expansion); macro_expander_destroy (me); /* Convert the macro expansion into syntax for possible error messages later. */