cpplex.c (parse_identifier_slow): Rename parse_slow, adjust prototype, and handle lexing numbers and identifiers.

* cpplex.c (parse_identifier_slow): Rename parse_slow, adjust
	prototype, and handle lexing numbers and identifiers.
	(parse_identifier): Update to new form of parse_slow.
	(parse_number): Fast path only, use parse_slow otherwise.
	(_cpp_lex_direct): Update calls to parse_number.

From-SVN: r51161
This commit is contained in:
Neil Booth 2002-03-22 07:23:21 +00:00 committed by Neil Booth
parent fbc2782eff
commit 10cf9bdee6
2 changed files with 85 additions and 82 deletions

View File

@ -1,3 +1,11 @@
2002-03-22 Neil Booth <neil@daikokuya.demon.co.uk>
* cpplex.c (parse_identifier_slow): Rename parse_slow, adjust
prototype, and handle lexing numbers and identifiers.
(parse_identifier): Update to new form of parse_slow.
(parse_number): Fast path only, use parse_slow otherwise.
(_cpp_lex_direct): Update calls to parse_number.
2002-03-21 DJ Delorie <dj@redhat.com>
* bb-reorder.c (make_reorder_chain_1): Protect against

View File

@ -77,9 +77,9 @@ static int skip_line_comment PARAMS ((cpp_reader *));
static void adjust_column PARAMS ((cpp_reader *));
static int skip_whitespace PARAMS ((cpp_reader *, cppchar_t));
static cpp_hashnode *parse_identifier PARAMS ((cpp_reader *));
static cpp_hashnode *parse_identifier_slow PARAMS ((cpp_reader *,
const U_CHAR *));
static void parse_number PARAMS ((cpp_reader *, cpp_string *, cppchar_t, int));
static U_CHAR *parse_slow PARAMS ((cpp_reader *, const U_CHAR *, int,
unsigned int *));
static void parse_number PARAMS ((cpp_reader *, cpp_string *, int));
static int unescaped_terminator_p PARAMS ((cpp_reader *, const U_CHAR *));
static void parse_string PARAMS ((cpp_reader *, cpp_token *, cppchar_t));
static void unterminated PARAMS ((cpp_reader *, int));
@ -412,13 +412,13 @@ name_p (pfile, string)
seen:unseen identifiers in normal code; the distribution is
Poisson-like). Second most common case is a new identifier, not
split and no dollar sign. The other possibilities are rare and
have been relegated to parse_identifier_slow. */
have been relegated to parse_slow. */
static cpp_hashnode *
parse_identifier (pfile)
cpp_reader *pfile;
{
cpp_hashnode *result;
const U_CHAR *cur;
const U_CHAR *cur, *base;
/* Fast-path loop. Skim over a normal identifier.
N.B. ISIDNUM does not include $. */
@ -428,13 +428,19 @@ parse_identifier (pfile)
/* Check for slow-path cases. */
if (*cur == '?' || *cur == '\\' || *cur == '$')
result = parse_identifier_slow (pfile, cur);
{
unsigned int len;
base = parse_slow (pfile, cur, 0, &len);
result = (cpp_hashnode *)
ht_lookup (pfile->hash_table, base, len, HT_ALLOCED);
}
else
{
const U_CHAR *base = pfile->buffer->cur - 1;
base = pfile->buffer->cur - 1;
pfile->buffer->cur = cur;
result = (cpp_hashnode *)
ht_lookup (pfile->hash_table, base, cur - base, HT_ALLOC);
pfile->buffer->cur = cur;
}
/* Rarely, identifiers require diagnostics when lexed.
@ -458,30 +464,55 @@ parse_identifier (pfile)
return result;
}
/* Slow path. This handles identifiers which have been split, and
identifiers which contain dollar signs. The part of the identifier
from PFILE->buffer->cur-1 to CUR has already been scanned. */
static cpp_hashnode *
parse_identifier_slow (pfile, cur)
/* Slow path. This handles numbers and identifiers which have been
split, or contain dollar signs. The part of the token from
PFILE->buffer->cur-1 to CUR has already been scanned. NUMBER_P is
1 if it's a number, and 2 if it has a leading period. Returns a
pointer to the token's NUL-terminated spelling in permanent
storage, and sets PLEN to its length. */
static U_CHAR *
parse_slow (pfile, cur, number_p, plen)
cpp_reader *pfile;
const U_CHAR *cur;
int number_p;
unsigned int *plen;
{
cpp_buffer *buffer = pfile->buffer;
const U_CHAR *base = buffer->cur - 1;
struct obstack *stack = &pfile->hash_table->stack;
unsigned int c, saw_dollar = 0, len;
unsigned int c, prevc, saw_dollar = 0;
/* Place any leading period. */
if (number_p == 2)
obstack_1grow (stack, '.');
/* Copy the part of the token which is known to be okay. */
obstack_grow (stack, base, cur - base);
/* Now process the part which isn't. We are looking at one of
'$', '\\', or '?' on entry to this loop. */
prevc = cur[-1];
c = *cur++;
buffer->cur = cur;
do
for (;;)
{
while (is_idchar (c))
/* Potential escaped newline? */
buffer->backup_to = buffer->cur - 1;
if (c == '?' || c == '\\')
c = skip_escaped_newlines (pfile);
if (!is_idchar (c))
{
if (!number_p)
break;
if (c != '.' && !VALID_SIGN (c, prevc))
break;
}
/* Handle normal identifier characters in this loop. */
do
{
prevc = c;
obstack_1grow (stack, c);
if (c == '$')
@ -489,14 +520,8 @@ parse_identifier_slow (pfile, cur)
c = *buffer->cur++;
}
/* Potential escaped newline? */
buffer->backup_to = buffer->cur - 1;
if (c != '?' && c != '\\')
break;
c = skip_escaped_newlines (pfile);
while (is_idchar (c));
}
while (is_idchar (c));
/* Step back over the unwanted char. */
BACKUP ();
@ -505,79 +530,49 @@ parse_identifier_slow (pfile, cur)
accepted as an extension. Don't warn about it in skipped
conditional blocks. */
if (saw_dollar && CPP_PEDANTIC (pfile) && ! pfile->state.skipping)
cpp_pedwarn (pfile, "'$' character(s) in identifier");
cpp_pedwarn (pfile, "'$' character(s) in identifier or number");
/* Identifiers are null-terminated. */
len = obstack_object_size (stack);
/* Identifiers and numbers are null-terminated. */
*plen = obstack_object_size (stack);
obstack_1grow (stack, '\0');
return (cpp_hashnode *)
ht_lookup (pfile->hash_table, obstack_finish (stack), len, HT_ALLOCED);
return obstack_finish (stack);
}
/* Parse a number, beginning with character C, skipping embedded
backslash-newlines. LEADING_PERIOD is non-zero if there was a "."
before C. Place the result in NUMBER. */
static void
parse_number (pfile, number, c, leading_period)
parse_number (pfile, number, leading_period)
cpp_reader *pfile;
cpp_string *number;
cppchar_t c;
int leading_period;
{
cpp_buffer *buffer = pfile->buffer;
unsigned char *dest, *limit;
const U_CHAR *cur;
dest = BUFF_FRONT (pfile->u_buff);
limit = BUFF_LIMIT (pfile->u_buff);
/* Fast-path loop. Skim over a normal number.
N.B. ISIDNUM does not include $. */
cur = pfile->buffer->cur;
while (ISIDNUM (*cur) || *cur == '.' || VALID_SIGN (*cur, cur[-1]))
cur++;
/* Place a leading period. */
if (leading_period)
/* Check for slow-path cases. */
if (*cur == '?' || *cur == '\\' || *cur == '$')
number->text = parse_slow (pfile, cur, 1 + leading_period, &number->len);
else
{
if (dest == limit)
{
_cpp_extend_buff (pfile, &pfile->u_buff, 1);
dest = BUFF_FRONT (pfile->u_buff);
limit = BUFF_LIMIT (pfile->u_buff);
}
*dest++ = '.';
const U_CHAR *base = pfile->buffer->cur - 1;
U_CHAR *dest;
number->len = cur - base + leading_period;
dest = _cpp_unaligned_alloc (pfile, number->len + 1);
dest[number->len] = '\0';
number->text = dest;
if (leading_period)
*dest++ = '.';
memcpy (dest, base, cur - base);
pfile->buffer->cur = cur;
}
do
{
do
{
/* Need room for terminating null. */
if ((size_t) (limit - dest) < 2)
{
size_t len_so_far = dest - BUFF_FRONT (pfile->u_buff);
_cpp_extend_buff (pfile, &pfile->u_buff, 2);
dest = BUFF_FRONT (pfile->u_buff) + len_so_far;
limit = BUFF_LIMIT (pfile->u_buff);
}
*dest++ = c;
c = *buffer->cur++;
}
while (is_numchar (c) || c == '.' || VALID_SIGN (c, dest[-1]));
/* Potential escaped newline? */
buffer->backup_to = buffer->cur - 1;
if (c != '?' && c != '\\')
break;
c = skip_escaped_newlines (pfile);
}
while (is_numchar (c) || c == '.' || VALID_SIGN (c, dest[-1]));
/* Step back over the unwanted char. */
BACKUP ();
/* Null-terminate the number. */
*dest = '\0';
number->text = BUFF_FRONT (pfile->u_buff);
number->len = dest - number->text;
BUFF_FRONT (pfile->u_buff) = dest + 1;
}
/* Subroutine of parse_string. Emits error for unterminated strings. */
@ -978,7 +973,7 @@ _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, c, 0);
parse_number (pfile, &result->val.str, 0);
break;
case 'L':
@ -1171,7 +1166,7 @@ _cpp_lex_direct (pfile)
else if (ISDIGIT (c))
{
result->type = CPP_NUMBER;
parse_number (pfile, &result->val.str, c, 1);
parse_number (pfile, &result->val.str, 1);
}
else if (c == '*' && CPP_OPTION (pfile, cplusplus))
result->type = CPP_DOT_STAR;