From: borutr Date: Sat, 23 Dec 2006 19:46:24 +0000 (+0000) Subject: * support/cpp2/cpphash.h, support/cpp2/cpplex.c, X-Git-Url: https://git.gag.com/?p=fw%2Fsdcc;a=commitdiff_plain;h=48f3534d77a08a1a8307a51ccb3e65c3bb656a08 * support/cpp2/cpphash.h, support/cpp2/cpplex.c, support/cpp2/cpplib.[ch], support/cpp2/sdcppinit.c, doc/sdccman.lyx: an other try to fix bug #982435: introduced -pedantic-parse-number command line option and pedantic_parse_number pragma git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4522 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index 6649830a..de6c3a6e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2006-12-23 Borut Razem + + * support/cpp2/cpphash.h, support/cpp2/cpplex.c, + support/cpp2/cpplib.[ch], support/cpp2/sdcppinit.c, doc/sdccman.lyx: + an other try to fix bug #982435: introduced -pedantic-parse-number + command line option and pedantic_parse_number pragma + 2006-12-21 Maarten Brock * as/link/mcs51/lkarea.c (lnkarea2): handle absolute areas, restructured diff --git a/doc/sdccman.lyx b/doc/sdccman.lyx index 6aa3baa8..86817c15 100644 --- a/doc/sdccman.lyx +++ b/doc/sdccman.lyx @@ -6121,6 +6121,34 @@ file"'. \bar default Like `-dD' except that the macro arguments and contents are omitted. Only `#define name' is included in the output. +\layout List +\labelwidthstring 00.00.0000 + + +\series bold +-pedantic-parse-number +\begin_inset LatexCommand \index{-pedantic-parse-number} + +\end_inset + + +\size large +\bar under + +\series default +\size default +\bar default +Pedentic parse numbers so that situations like 0xfe-LO_B(3) are parsed properly + and the macro LO_B(3) gets expanded. + See also #pragma pedantic_parse_number in section +\begin_inset LatexCommand \ref{sec:Pragmas} + +\end_inset + + +\emph on +Note: this functionality is not in conformance with standard! + \layout List \added_space_bottom bigskip \labelwidthstring 00.00.0000 @@ -16958,6 +16986,57 @@ void foo (void) } \newline +\layout Itemize + + +\series bold +pedantic_parse_number +\series default + +\begin_inset LatexCommand \index{\#pragma pedantic\_parse\_number} + +\end_inset + + (+ | -) - Pedantic parse numbers so that situations like 0xfe-LO_B(3) are + parsed properly and the macro LO_B(3) gets expanded. + Default is off. + Below is an example on how to use this pragma. + +\emph on + Note: this functionality is not in conformance with standard! + +\layout Verse + + +\family typewriter +#pragma pedantic_parse_number + +\begin_inset LatexCommand \index{\#pragma pedantic\_parse\_number} + +\end_inset + + +\newline +\newline +#define LO_B(x) ((x) & 0xff) +\newline +\newline +unsigned char foo(void) +\newline +\InsetSpace ~ +\InsetSpace ~ +\InsetSpace ~ +unsigned char c=0xfe-LO_B(3); +\newline +\newline +\InsetSpace ~ +\InsetSpace ~ +\InsetSpace ~ + +return c; +\newline +} +\newline + \layout Standard The pragma's are intended to be used to turn-on or off certain optimizations diff --git a/support/cpp2/cpphash.h b/support/cpp2/cpphash.h index d619fcbf..0643f93b 100644 --- a/support/cpp2/cpphash.h +++ b/support/cpp2/cpphash.h @@ -43,10 +43,6 @@ typedef unsigned char uchar; || (((prevc) == 'p' || (prevc) == 'P') \ && CPP_OPTION (pfile, extended_numbers)))) -/* Test if a X or x is valid within a preprocessing number. */ -#define VALID_HEX(c, prevc) \ - (((c) == 'X' || (c) == 'x') && (prevc) == '0') - #define CPP_OPTION(PFILE, OPTION) ((PFILE)->opts.OPTION) #define CPP_BUFFER(PFILE) ((PFILE)->buffer) #define CPP_BUF_COLUMN(BUF, CUR) ((CUR) - (BUF)->line_base + (BUF)->col_adjust) diff --git a/support/cpp2/cpplex.c b/support/cpp2/cpplex.c index b802ed60..a24b68d3 100644 --- a/support/cpp2/cpplex.c +++ b/support/cpp2/cpplex.c @@ -74,6 +74,7 @@ static int skip_whitespace PARAMS ((cpp_reader *, cppchar_t)); static cpp_hashnode *parse_identifier PARAMS ((cpp_reader *)); static uchar *parse_slow PARAMS ((cpp_reader *, const uchar *, int, unsigned int *)); +static void pedantic_parse_number PARAMS ((cpp_reader *, cpp_string *, int)); static void parse_number PARAMS ((cpp_reader *, cpp_string *, int)); static int unescaped_terminator_p PARAMS ((cpp_reader *, const uchar *)); static void parse_string PARAMS ((cpp_reader *, cpp_token *, cppchar_t)); @@ -577,42 +578,26 @@ parse_slow (pfile, cur, number_p, plen) if (c == '?' || c == '\\') c = skip_escaped_newlines (pfile); - if (number_p) - { - if (!ISXDIGIT (c) && c != '.' && !VALID_SIGN (c, prevc) && !VALID_HEX (c, prevc)) + if (!is_idchar (c)) + { + if (!number_p) break; + if (c != '.' && !VALID_SIGN (c, prevc)) + break; + } - obstack_1grow (stack, c); - - base = cur = buffer->cur; - while (ISXDIGIT (*cur)) - ++cur; - - if (cur != base) - obstack_grow (stack, base, cur - base); - - prevc = cur[-1]; - c = *cur++; - buffer->cur = cur; - } - else - { - if (!is_idchar (c)) - break; - - /* Handle normal identifier characters in this loop. */ - do - { - prevc = c; - obstack_1grow (stack, c); + /* Handle normal identifier characters in this loop. */ + do + { + prevc = c; + obstack_1grow (stack, c); - if (c == '$') - saw_dollar++; + if (c == '$') + saw_dollar++; - c = *buffer->cur++; - } - while (is_idchar (c)); - } + c = *buffer->cur++; + } + while (is_idchar (c)); } /* Step back over the unwanted char. */ @@ -630,6 +615,249 @@ parse_slow (pfile, cur, number_p, plen) return obstack_finish (stack); } +/* SDCC specific */ +/* Pedantic parse a number, beginning with character C, skipping embedded + backslash-newlines. LEADING_PERIOD is nonzero if there was a "." + before C. Place the result in NUMBER. */ +static void +pedantic_parse_number (pfile, number, leading_period) + cpp_reader *pfile; + cpp_string *number; + int leading_period; +{ + enum num_type_e { NT_DEC, NT_HEX } num_type = NT_DEC; + enum num_part_e { NP_WHOLE, NP_FRACT, NP_EXP, NP_INT_SUFFIX, NP_FLOAT_SUFFIX } num_part = NP_WHOLE; + + uchar c = *(pfile->buffer->cur - 1); + struct obstack *stack = &pfile->hash_table->stack; + cpp_buffer *buffer = pfile->buffer; + int len = 0; + int has_whole = 0; + int has_fract = 0; + + if (leading_period) + { + num_part = NP_FRACT; + ++len; + obstack_1grow (stack, '.'); + c = get_effective_char(pfile); + } + else + { + if ('0' == c) + { + has_whole = 1; + ++len; + obstack_1grow (stack, c); + c = get_effective_char(pfile); + + switch (c) + { + case 'X': + case 'x': + num_type = NT_HEX; + ++len; + obstack_1grow (stack, c); + c = get_effective_char(pfile); + break; + + case '.': + num_part = NP_FRACT; + ++len; + obstack_1grow (stack, c); + c = get_effective_char(pfile); + break; + } + } + } + + for (; ; ) + { + switch (num_part) + { + case NP_WHOLE: + if (NT_DEC == num_type) + { + while (ISDIGIT (c)) + { + has_whole = 1; + ++len; + obstack_1grow (stack, c); + c = get_effective_char(pfile); + } + + if ('.' == c) + { + num_part = NP_FRACT; + ++len; + obstack_1grow (stack, c); + c = get_effective_char(pfile); + continue; + } + else if ('E' == c || 'e' == c) + { + if (has_whole || has_fract) + { + num_part = NP_EXP; + ++len; + obstack_1grow (stack, c); + c = get_effective_char(pfile); + continue; + } + else + break; + } + } + else + { + while (ISXDIGIT (c)) + { + has_whole = 1; + ++len; + obstack_1grow (stack, c); + c = get_effective_char(pfile); + } + + if ('.' == c) + { + num_part = NP_FRACT; + ++len; + obstack_1grow (stack, c); + c = get_effective_char(pfile); + continue; + } + else if ('P' == c || 'p' == c) + { + if (has_whole || has_fract) + { + num_part = NP_EXP; + ++len; + obstack_1grow (stack, c); + c = get_effective_char(pfile); + continue; + } + else + break; + } + } + num_part = NP_INT_SUFFIX; + continue; + + case NP_FRACT: + if (NT_DEC == num_type) + { + while (ISDIGIT (c)) + { + has_fract = 1; + ++len; + obstack_1grow (stack, c); + c = get_effective_char(pfile); + } + + if ('E' == c || 'e' == c) + { + if (has_whole || has_fract) + { + num_part = NP_EXP; + ++len; + obstack_1grow (stack, c); + c = get_effective_char(pfile); + continue; + } + } + } + else + { + while (ISXDIGIT (c)) + { + has_fract = 1; + ++len; + obstack_1grow (stack, c); + c = get_effective_char(pfile); + } + + if ('P' == c || 'p' == c) + { + if (has_whole || has_fract) + { + num_part = NP_EXP; + ++len; + obstack_1grow (stack, c); + c = get_effective_char(pfile); + continue; + } + } + } + num_part = NP_FLOAT_SUFFIX; + continue; + + case NP_EXP: + if ('+' == c || '-' == c) + { + ++len; + obstack_1grow (stack, c); + c = get_effective_char(pfile); + } + + while (ISDIGIT (c)) + { + ++len; + obstack_1grow (stack, c); + c = get_effective_char(pfile); + } + + num_part = NP_FLOAT_SUFFIX; + continue; + + case NP_INT_SUFFIX: + if ('L' == c || 'l' == c) + { + uchar prevc = c; + + ++len; + obstack_1grow (stack, c); + c = get_effective_char(pfile); + + if (c == prevc) + { + ++len; + obstack_1grow (stack, c); + c = get_effective_char(pfile); + } + } + else if ('U' == c || 'u' == c) + { + ++len; + obstack_1grow (stack, c); + c = get_effective_char(pfile); + } + break; + + case NP_FLOAT_SUFFIX: + if ('F' == c || 'f' == c) + { + ++len; + obstack_1grow (stack, c); + c = get_effective_char(pfile); + } + else if ('L' == c || 'l' == c) + { + ++len; + obstack_1grow (stack, c); + c = get_effective_char(pfile); + } + break; + } + break; + } + + /* Step back over the unwanted char. */ + BACKUP (); + + number->text = obstack_finish (stack); + number->len = len; +} + /* Parse a number, beginning with character C, skipping embedded backslash-newlines. LEADING_PERIOD is nonzero if there was a "." before C. Place the result in NUMBER. */ @@ -644,8 +872,7 @@ parse_number (pfile, number, leading_period) /* Fast-path loop. Skim over a normal number. N.B. ISIDNUM does not include $. */ cur = pfile->buffer->cur; - - while (ISXDIGIT (*cur) || *cur == '.' || VALID_SIGN (*cur, cur[-1]) || VALID_HEX (*cur, cur[-1])) + while (ISIDNUM (*cur) || *cur == '.' || VALID_SIGN (*cur, cur[-1])) cur++; /* Check for slow-path cases. */ @@ -1163,7 +1390,10 @@ _cpp_lex_direct (pfile) case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': result->type = CPP_NUMBER; - parse_number (pfile, &result->val.str, 0); + if (CPP_OPTION(pfile, pedantic_parse_number)) + pedantic_parse_number (pfile, &result->val.str, 0); + else + parse_number (pfile, &result->val.str, 0); break; case 'L': @@ -1366,7 +1596,10 @@ _cpp_lex_direct (pfile) else if (ISDIGIT (c)) { result->type = CPP_NUMBER; - parse_number (pfile, &result->val.str, 1); + if (CPP_OPTION(pfile, pedantic_parse_number)) + pedantic_parse_number (pfile, &result->val.str, 1); + else + parse_number (pfile, &result->val.str, 1); } else if (c == '*' && CPP_OPTION (pfile, cplusplus)) result->type = CPP_DOT_STAR; diff --git a/support/cpp2/cpplib.c b/support/cpp2/cpplib.c index e903bca8..6d2984a7 100644 --- a/support/cpp2/cpplib.c +++ b/support/cpp2/cpplib.c @@ -123,6 +123,7 @@ static void do_pragma_once PARAMS ((cpp_reader *)); static void do_pragma_poison PARAMS ((cpp_reader *)); static void do_pragma_sdcc_hash PARAMS ((cpp_reader *)); static void do_pragma_preproc_asm PARAMS ((cpp_reader *)); +static void do_pragma_pedantic_parse_number PARAMS ((cpp_reader *)); static void do_pragma_system_header PARAMS ((cpp_reader *)); static void do_pragma_dependency PARAMS ((cpp_reader *)); static void do_linemarker PARAMS ((cpp_reader *)); @@ -1089,6 +1090,8 @@ _cpp_init_internal_pragmas (pfile) cpp_register_pragma(pfile, 0, "sdcc_hash", do_pragma_sdcc_hash); /* SDCC _asm specific */ cpp_register_pragma(pfile, 0, "preproc_asm", do_pragma_preproc_asm); + /* SDCC specific */ + cpp_register_pragma(pfile, 0, "pedantic_parse_number", do_pragma_pedantic_parse_number); } /* Pragmata handling. We handle some, and pass the rest on to the @@ -1193,21 +1196,44 @@ do_pragma_poison (pfile) static void do_pragma_sdcc_hash (pfile) cpp_reader *pfile; +{ + const cpp_token *tok = _cpp_lex_token (pfile); + + if (tok->type == CPP_PLUS) + { + CPP_OPTION(pfile, allow_naked_hash)++; + } + else if (tok->type == CPP_MINUS) + { + CPP_OPTION(pfile, allow_naked_hash)--; + } + else + { + cpp_error (pfile, DL_ERROR, + "invalid #pragma sdcc_hash directive, need '+' or '-'"); + } +} + +/* SDCC specific + pedantic_parse_number pragma */ +static void +do_pragma_pedantic_parse_number (pfile) + cpp_reader *pfile; { const cpp_token *tok = _cpp_lex_token (pfile); - if (tok->type == CPP_PLUS) + if (tok->type == CPP_PLUS) { - CPP_OPTION(pfile, allow_naked_hash)++; + CPP_OPTION(pfile, pedantic_parse_number)++; } - else if (tok->type == CPP_MINUS) + else if (tok->type == CPP_MINUS) { - CPP_OPTION(pfile, allow_naked_hash)--; + CPP_OPTION(pfile, pedantic_parse_number)--; } - else + else { - cpp_error (pfile, DL_ERROR, - "invalid #pragma sdcc_hash directive, need '+' or '-'"); + cpp_error (pfile, DL_ERROR, + "invalid #pragma pedantic_parse_number directive, need '+' or '-'"); } } @@ -1230,7 +1256,7 @@ do_pragma_preproc_asm (pfile) else { cpp_error (pfile, DL_ERROR, - "invalid #pragma preproc_asm directive, need '+' or '-'"); + "invalid #pragma preproc_asm directive, need '+' or '-'"); } } diff --git a/support/cpp2/cpplib.h b/support/cpp2/cpplib.h index 8b788128..7875af4b 100644 --- a/support/cpp2/cpplib.h +++ b/support/cpp2/cpplib.h @@ -403,6 +403,10 @@ struct cpp_options object file exetnsion */ const char *obj_ext; + /* SDCC specific + pedantic_parse_number */ + unsigned char pedantic_parse_number; + /* Dependency generation. */ struct { diff --git a/support/cpp2/sdcppinit.c b/support/cpp2/sdcppinit.c index 1c96fddc..6b5551f3 100644 --- a/support/cpp2/sdcppinit.c +++ b/support/cpp2/sdcppinit.c @@ -1245,6 +1245,8 @@ new_pending_directive (pend, text, handler) DEF_OPT("obj-ext=", no_arg, OPT_obj_ext) \ DEF_OPT("pedantic", 0, OPT_pedantic) \ DEF_OPT("pedantic-errors", 0, OPT_pedantic_errors) \ + /* SDCC specific */ \ + DEF_OPT("pedantic-parse-number", 0, OPT_pedantic_parse_number) \ DEF_OPT("remap", 0, OPT_remap) \ DEF_OPT("std=c++98", 0, OPT_std_cplusplus98) \ DEF_OPT("std=c89", 0, OPT_std_c89) \ @@ -1488,8 +1490,11 @@ cpp_handle_option (pfile, argc, argv) case OPT_pedantic: CPP_OPTION (pfile, pedantic) = 1; break; + case OPT_pedantic_parse_number: + CPP_OPTION (pfile, pedantic_parse_number) = 1; + break; case OPT_trigraphs: - CPP_OPTION (pfile, trigraphs) = 1; + CPP_OPTION (pfile, trigraphs) = 1; break; case OPT_plus: CPP_OPTION (pfile, cplusplus) = 1; @@ -1850,6 +1855,10 @@ Switches:\n\ -trigraphs Support ISO C trigraphs\n\ -lang-c Assume that the input sources are in C\n\ -lang-c89 Assume that the input sources are in C89\n\ +"), stdout); + /* SDCC specific */ + fputs (_("\ + -pedantic-parse-number Pedantic parse number\n\ "), stdout); fputs (_("\ -lang-c++ Assume that the input sources are in C++\n\ @@ -1890,7 +1899,7 @@ Switches:\n\ -MG Treat missing header file as generated files\n\ "), stdout); fputs (_("\ - -MP Generate phony targets for all headers\n\ + -MP Generate phony targets for all headers\n\ -MQ Add a MAKE-quoted target\n\ -MT Add an unquoted target\n\ "), stdout);