+/* 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;
+}
+