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));
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. */
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. */
/* 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. */
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':
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;
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 *));
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
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 '-'");
}
}
else
{
cpp_error (pfile, DL_ERROR,
- "invalid #pragma preproc_asm directive, need '+' or '-'");
+ "invalid #pragma preproc_asm directive, need '+' or '-'");
}
}
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) \
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;
-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\
-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 <target> Add a MAKE-quoted target\n\
-MT <target> Add an unquoted target\n\
"), stdout);