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)
{
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;
/* 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])
{
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
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);
.representation = ss_buffer (&src->buffer[start - src->tail],
end - start),
};
+ src->middle += middle_ofs + 1;
n_call = macro_expander_add (me, &mt);
+ src->middle -= middle_ofs + 1;
}
if (n_call < 0)
{
const struct lex_token *call_first
= &src->tokens[src->middle & (src->capacity - 1)];
const struct lex_token *call_last
- = &src->tokens[(src->middle + n_call) & (src->capacity - 1)];
+ = &src->tokens[(src->middle + n_call - 1) & (src->capacity - 1)];
size_t call_pos = call_first->token_pos;
size_t call_len = (call_last->token_pos + call_last->token_len) - call_pos;
size_t line_pos = call_first->line_pos;