X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/fed6418a32d3b0fd6036d169bd325c1172b391b5..898aa30bfb038ffeca54d6dea95f0f80fbc08f7f:/src/scan.l diff --git a/src/scan.l b/src/scan.l index fbe80b2..5d460ed 100644 --- a/src/scan.l +++ b/src/scan.l @@ -1,7 +1,7 @@ %top{ /* * Scanner for C declarations. - * Copyright © 2011, 2021, 2023 Nick Bowler + * Copyright © 2011, 2021, 2023-2024 Nick Bowler * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,10 +18,63 @@ */ #include +#include #include "parse.h" +/* Disable various generated code we don't use */ +#define YY_INPUT(a, b, c) do {} while (0) #define YY_NO_INPUT 1 #define YY_NO_UNPUT 1 + +/* + * The flex-generated scanner defines a huge pile of external functions of + * which we use almost none elsewhere. Explicitly declare any unneeded + * functions static, which allows better optimization (especially wrt. + * dead code elimination). + */ +#if !cdecl__yyIN_HEADER + +#if __GNUC__ +# define static __attribute__((__unused__)) static +#endif + +static struct yy_buffer_state *cdecl__yy_create_buffer(FILE *, int, void *); +static struct yy_buffer_state *cdecl__yy_scan_bytes(const char *, int, void *); +static struct yy_buffer_state *cdecl__yy_scan_buffer(char *, size_t, void *); +static void cdecl__yy_switch_to_buffer(struct yy_buffer_state *, void *); +static void cdecl__yy_flush_buffer(struct yy_buffer_state *, void *); +static void cdecl__yypush_buffer_state(struct yy_buffer_state *, void *); +static void cdecl__yypop_buffer_state(void *); +static void cdecl__yyrestart(FILE *, void *); +static int cdecl__yylex_init(void **); + +static int cdecl__yyget_extra(void *); +static YYLTYPE *cdecl__yyget_lloc(void *); +static YYSTYPE *cdecl__yyget_lval(void *); +static char *cdecl__yyget_text(void *); +static FILE *cdecl__yyget_out(void *); +static FILE *cdecl__yyget_in(void *); +static int cdecl__yyget_debug(void *); +static int cdecl__yyget_lineno(void *); +static int cdecl__yyget_column(void *); +static int cdecl__yyget_leng(void *); + +static void cdecl__yyset_extra(int, void *); +static void cdecl__yyset_lloc(YYLTYPE *, void *); +static void cdecl__yyset_lval(YYSTYPE *, void *); +static void cdecl__yyset_in(FILE *, void *); +static void cdecl__yyset_out(FILE *, void *); +static void cdecl__yyset_debug(int, void *); +static void cdecl__yyset_lineno(int, void *); +static void cdecl__yyset_column(int, void *); + +static void *cdecl__yyrealloc(void *, size_t, void *); +static void *cdecl__yyalloc(size_t, void *); +static void cdecl__yyfree(void *, void *); + +#undef static + +#endif } %option nodefault noyywrap bison-locations reentrant never-interactive @@ -33,20 +86,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 +151,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 +179,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; + cdecl_uintmax 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 +227,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); @@ -193,6 +240,6 @@ INTEGER 0[Xx][[:xdigit:]]*|[[:digit:]]+ c = yytext; invalid_char: to_readable_ch(buf, *c); - cdecl__err(CDECL_ENOPARSE, _("syntax error, unexpected %s"), buf); + cdecl__err(_("syntax error, unexpected %s"), buf); return T_LEX_ERROR; }