X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/fed6418a32d3b0fd6036d169bd325c1172b391b5..62fa1dac8cf3098d212c0e8f4b3cc2cadaddd4c5:/src/scan.l diff --git a/src/scan.l b/src/scan.l index fbe80b2..48314d4 100644 --- a/src/scan.l +++ b/src/scan.l @@ -33,20 +33,7 @@ #include "cdecl-internal.h" #include "cdecl.h" #include "errmsg.h" - -#if HAVE_STRTOUMAX -/* Best case, implementation provides strtoumax. */ -# define STRTOUMAX strtoumax -#elif HAVE_STRTOULL -/* Fall back to strtoull, with possibly reduced range. */ -#define STRTOUMAX strtoull -#elif HAVE___STRTOULL -/* HP-UX 11 has __strtoull in */ -#define STRTOUMAX __strtoull -#else -/* Fall back to strtoul, with possibly reduced range. */ -#define STRTOUMAX strtoul -#endif +#include "intconv.h" static char *to_octal(char *dst, unsigned val) { @@ -111,11 +98,11 @@ static void to_readable_ch(char *dst, char c) %} IDENT [_[:alpha:]][-_[:alnum:]]* -INTEGER 0[Xx][[:xdigit:]]*|[[:digit:]]+ %% %{ + int intconv_base; char *c; %} @@ -139,22 +126,29 @@ INTEGER 0[Xx][[:xdigit:]]*|[[:digit:]]+ return UNPACK_TOKEN(match[sizeof tab[0]]); } -{INTEGER} { - char *end; - - errno = 0; - yylval->uintval = STRTOUMAX(yytext, &end, 0); - if (errno == ERANGE) { - cdecl__errmsg(CDECL__ERANGE); - return T_LEX_ERROR; - } - if (*end) { - cdecl__errmsg(CDECL__EBADINT); - return T_LEX_ERROR; +0[0-7]* { intconv_base = INTCONV_OCTAL; goto int_parse; } +[1-9][0-9]* { intconv_base = INTCONV_DECIMAL; goto int_parse; } +0[Xx][[:xdigit:]]+ { + unsigned char d; + uintmax_t v; + + yytext += 2; + intconv_base = INTCONV_HEXADECIMAL; +int_parse: + for (v = 0; (d = *yytext++);) { + if (!intconv_shift(&v, intconv_base, intconv_digit(d))) { + cdecl__errmsg(CDECL__ERANGE); + return T_LEX_ERROR; + } } + yylval->uintval = v; return T_UINT; } +0[Xx]|[0-9]+ { + cdecl__errmsg(CDECL__EBADINT); + return T_LEX_ERROR; +} {IDENT} { int len = yyleng, tok; @@ -180,7 +174,7 @@ INTEGER 0[Xx][[:xdigit:]]*|[[:digit:]]+ yyless(strcspn(yytext, "-")); #endif if (!(yylval->item = cdecl__alloc_item(len+1))) - return T_LEX_ERROR; \ + return T_LEX_ERROR; memcpy(yylval->item->s, yytext, len+1); } return UNPACK_TOKEN(tok);