X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/17ec74586a21b6283bedb3fb35630e3231001758..ad973d63e038f293f2b158f19b04c1582e616af0:/src/scan.l diff --git a/src/scan.l b/src/scan.l index 54cea88..cc152b9 100644 --- a/src/scan.l +++ b/src/scan.l @@ -26,15 +26,21 @@ %option prefix="cdecl__yy" %{ -#define lex_error(msg) do { \ - cdecl__yyerror(yylloc, NULL, NULL, (msg)); \ +#include +#include "cdecl-internal.h" +#include "cdecl.h" + +#define lex_error(...) do { \ + cdecl__err(CDECL_ENOPARSE, __VA_ARGS__); \ return T_LEX_ERROR; \ } while(0) #define dup_token() do { \ yylval->strval = malloc(yyleng+1); \ - if (!yylval->strval) \ - lex_error("failed to allocate memory"); \ + if (!yylval->strval) { \ + cdecl__err(CDECL_ENOMEM); \ + return T_LEX_ERROR; \ + } \ strcpy(yylval->strval, yytext); \ } while(0) %} @@ -98,9 +104,9 @@ INTEGER 0x[[:xdigit:]]+|0[0-7]+|[[:digit:]]+ errno = 0; yylval->uintval = strtoumax(yytext, &end, 0); if (errno == ERANGE) - lex_error("integer constant out of range"); + lex_error(_("integer constant out of range")); if (*end) - lex_error("invalid integer constant"); + lex_error(_("invalid integer constant")); return T_UINT; } @@ -122,7 +128,28 @@ INTEGER 0x[[:xdigit:]]+|0[0-7]+|[[:digit:]]+ [[:space:]]+ . { - char buf[] = "syntax error, unexpected #"; - *strchr(buf, '#') = *yytext; - lex_error(buf); + char buf[5] = { yytext[0] }; + unsigned char c = buf[0]; + + if (!isprint(c) || c == '\\' || c == '\'') { + /* Encode nonprinting characters with C-style escapes */ + buf[0] = '\\'; + switch (c) { + case '\a': buf[1] = 'a'; break; + case '\b': buf[1] = 'b'; break; + case '\f': buf[1] = 'f'; break; + case '\n': buf[1] = 'n'; break; + case '\r': buf[1] = 'r'; break; + case '\t': buf[1] = 't'; break; + case '\v': buf[1] = 'v'; break; + case '\\': buf[1] = '\\'; break; + case '\'': buf[1] = '\''; break; + default: + buf[1] = '0' + ((c >> 6) & 3); + buf[2] = '0' + ((c >> 3) & 7); + buf[3] = '0' + ((c >> 0) & 7); + } + } + + lex_error(_("syntax error, unexpected '%s'"), buf); }