Commit cf4ed945 by Zack Weinberg Committed by Zack Weinberg

cppexp.c: Don't include cpphash.h.

	* cppexp.c: Don't include cpphash.h.
	(parse_charconst, cpp_lex): Use cpp_defined.
	(cpp_lex): Use get_directive_token throughout.  Remove
	unnecessary cases from switch.  Move assertion-handling code
	down to OTHER case.
	(cpp_parse_expr): If we see '+' or '-', check the context to
	determine if they are unary or binary operators.  Streamline
	the jumps a bit.  Do not call skip_rest_of_line.

	* cpplib.c: Make skip_rest_of_line and cpp_skip_hspace
	static.  Export get_directive_token.  Update commentary.
	(cpp_defined): New function.
	(do_define): Remove reference to T_PCSTRING.  Call
	free_definition to release memory for old definition, when
	redefining a macro.
	(eval_if_expression): Set only_seen_white to 0 before calling
	cpp_parse_expr.  Call skip_rest_of_line after it returns.
	(cpp_read_check_assertion): Don't preserve a pointer into the
	token buffer across a call to cpp_get_token.

	* Makefile.in (cppexp.o): Don't depend on cpphash.h.
	* cppfiles.c (redundant_include_p): Use cpp_defined.
	* cpphash.c (free_definition): New function.
	(delete_macro): Use it.  Update commentary.
	* cpphash.h: Typedef HASHNODE here.  Prototype cpp_lookup and
	free_definition.
	* cpplib.h: Don't typedef HASHNODE here. Delete T_PCSTRING
	from enum node_type.  Prototype cpp_defined and get_directive_token.
	Don't prototype cpp_lookup, skip_rest_of_line, or cpp_skip_hspace.

	* fix-header.c (check_macro_names): Use cpp_defined.
	(read_scan_file): Set inhibit_warnings and inhibit_errors in
	the options structure.

From-SVN: r31908
parent 26439cc5
2000-02-10 Zack Weinberg <zack@wolery.cumb.org>
* cppexp.c: Don't include cpphash.h.
(parse_charconst, cpp_lex): Use cpp_defined.
(cpp_lex): Use get_directive_token throughout. Remove
unnecessary cases from switch. Move assertion-handling code
down to OTHER case.
(cpp_parse_expr): If we see '+' or '-', check the context to
determine if they are unary or binary operators. Streamline
the jumps a bit. Do not call skip_rest_of_line.
* cpplib.c: Make skip_rest_of_line and cpp_skip_hspace
static. Export get_directive_token. Update commentary.
(cpp_defined): New function.
(do_define): Remove reference to T_PCSTRING. Call
free_definition to release memory for old definition, when
redefining a macro.
(eval_if_expression): Set only_seen_white to 0 before calling
cpp_parse_expr. Call skip_rest_of_line after it returns.
(cpp_read_check_assertion): Don't preserve a pointer into the
token buffer across a call to cpp_get_token.
* Makefile.in (cppexp.o): Don't depend on cpphash.h.
* cppfiles.c (redundant_include_p): Use cpp_defined.
* cpphash.c (free_definition): New function.
(delete_macro): Use it. Update commentary.
* cpphash.h: Typedef HASHNODE here. Prototype cpp_lookup and
free_definition.
* cpplib.h: Don't typedef HASHNODE here. Delete T_PCSTRING
from enum node_type. Prototype cpp_defined and get_directive_token.
Don't prototype cpp_lookup, skip_rest_of_line, or cpp_skip_hspace.
* fix-header.c (check_macro_names): Use cpp_defined.
(read_scan_file): Set inhibit_warnings and inhibit_errors in
the options structure.
2000-02-10 Franz Sirl <Franz.Sirl-kernel@lauterbach.com> 2000-02-10 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
* c-pragma.c (maximum_field_alignment): Remove duplicate declaration. * c-pragma.c (maximum_field_alignment): Remove duplicate declaration.
......
...@@ -2043,7 +2043,7 @@ cpplib.o: cpplib.c $(CONFIG_H) cpplib.h intl.h system.h cpphash.h ...@@ -2043,7 +2043,7 @@ cpplib.o: cpplib.c $(CONFIG_H) cpplib.h intl.h system.h cpphash.h
cpphash.o: cpphash.c $(CONFIG_H) cpplib.h intl.h system.h cpphash.h cpphash.o: cpphash.c $(CONFIG_H) cpplib.h intl.h system.h cpphash.h
cppalloc.o: cppalloc.c $(CONFIG_H) cpplib.h intl.h system.h cppalloc.o: cppalloc.c $(CONFIG_H) cpplib.h intl.h system.h
cpperror.o: cpperror.c $(CONFIG_H) cpplib.h intl.h system.h cpperror.o: cpperror.c $(CONFIG_H) cpplib.h intl.h system.h
cppexp.o: cppexp.c $(CONFIG_H) cpplib.h intl.h system.h cpphash.h cppexp.o: cppexp.c $(CONFIG_H) cpplib.h intl.h system.h
cppfiles.o: cppfiles.c $(CONFIG_H) cpplib.h intl.h system.h cppfiles.o: cppfiles.c $(CONFIG_H) cpplib.h intl.h system.h
cppinit.o: cppinit.c $(CONFIG_H) cpplib.h intl.h system.h \ cppinit.o: cppinit.c $(CONFIG_H) cpplib.h intl.h system.h \
......
...@@ -27,7 +27,6 @@ Written by Per Bothner 1994. */ ...@@ -27,7 +27,6 @@ Written by Per Bothner 1994. */
#include "config.h" #include "config.h"
#include "system.h" #include "system.h"
#include "cpplib.h" #include "cpplib.h"
#include "cpphash.h"
#ifdef MULTIBYTE_CHARS #ifdef MULTIBYTE_CHARS
#include <locale.h> #include <locale.h>
...@@ -331,8 +330,8 @@ parse_charconst (pfile, start, end) ...@@ -331,8 +330,8 @@ parse_charconst (pfile, start, end)
/* If char type is signed, sign-extend the constant. */ /* If char type is signed, sign-extend the constant. */
num_bits = num_chars * width; num_bits = num_chars * width;
if (cpp_lookup (pfile, (const U_CHAR *)"__CHAR_UNSIGNED__", if (cpp_defined (pfile, (const U_CHAR *)"__CHAR_UNSIGNED__",
sizeof ("__CHAR_UNSIGNED__")-1) sizeof ("__CHAR_UNSIGNED__")-1)
|| ((result >> (num_bits - 1)) & 1) == 0) || ((result >> (num_bits - 1)) & 1) == 0)
op.value = result & ((unsigned HOST_WIDEST_INT) ~0 op.value = result & ((unsigned HOST_WIDEST_INT) ~0
>> (HOST_BITS_PER_WIDEST_INT - num_bits)); >> (HOST_BITS_PER_WIDEST_INT - num_bits));
...@@ -377,56 +376,28 @@ cpp_lex (pfile, skip_evaluation) ...@@ -377,56 +376,28 @@ cpp_lex (pfile, skip_evaluation)
cpp_reader *pfile; cpp_reader *pfile;
int skip_evaluation; int skip_evaluation;
{ {
U_CHAR c;
struct token *toktab; struct token *toktab;
enum cpp_token token; enum cpp_token token;
struct operation op; struct operation op;
U_CHAR *tok_start, *tok_end; U_CHAR *tok_start, *tok_end;
int old_written; long old_written;
retry:
old_written = CPP_WRITTEN (pfile); old_written = CPP_WRITTEN (pfile);
cpp_skip_hspace (pfile); token = get_directive_token (pfile);
c = CPP_BUF_PEEK (CPP_BUFFER (pfile));
if (c == '#')
{
op.op = INT;
op.value = cpp_read_check_assertion (pfile);
return op;
}
if (c == '\n')
{
op.op = 0;
return op;
}
token = cpp_get_token (pfile);
tok_start = pfile->token_buffer + old_written; tok_start = pfile->token_buffer + old_written;
tok_end = CPP_PWRITTEN (pfile); tok_end = CPP_PWRITTEN (pfile);
pfile->limit = tok_start; CPP_SET_WRITTEN (pfile, old_written);
switch (token) switch (token)
{ {
case CPP_EOF: /* Should not happen ... */ case CPP_EOF: /* Should not happen ... */
case CPP_VSPACE: case CPP_VSPACE:
op.op = 0; op.op = 0;
return op; return op;
case CPP_POP:
if (CPP_BUFFER (pfile)->fname != NULL)
{
op.op = 0;
return op;
}
cpp_pop_buffer (pfile);
goto retry;
case CPP_HSPACE:
case CPP_COMMENT:
goto retry;
case CPP_NUMBER: case CPP_NUMBER:
return parse_number (pfile, tok_start, tok_end); return parse_number (pfile, tok_start, tok_end);
case CPP_STRING: case CPP_STRING:
cpp_error (pfile, "string constants not allowed in #if expressions"); cpp_error (pfile, "string constants are not allowed in #if expressions");
op.op = ERROR; op.op = ERROR;
return op; return op;
case CPP_CHAR: case CPP_CHAR:
...@@ -445,45 +416,38 @@ cpp_lex (pfile, skip_evaluation) ...@@ -445,45 +416,38 @@ cpp_lex (pfile, skip_evaluation)
else else
{ {
int paren = 0, len; int paren = 0, len;
cpp_buffer *ip = CPP_BUFFER (pfile);
U_CHAR *tok; U_CHAR *tok;
HASHNODE *hp;
cpp_skip_hspace (pfile); pfile->no_macro_expand++;
if (*ip->cur == '(') token = get_directive_token (pfile);
if (token == CPP_LPAREN)
{ {
paren++; paren++;
ip->cur++; /* Skip over the paren */ CPP_SET_WRITTEN (pfile, old_written);
cpp_skip_hspace (pfile); token = get_directive_token (pfile);
} }
if (!is_idstart(*ip->cur)) if (token != CPP_NAME)
goto oops;
if (ip->cur[0] == 'L' && (ip->cur[1] == '\'' || ip->cur[1] == '"'))
goto oops; goto oops;
tok = ip->cur;
while (is_idchar(*ip->cur)) tok = pfile->token_buffer + old_written;
++ip->cur; len = CPP_PWRITTEN (pfile) - tok;
len = ip->cur - tok; if (cpp_defined (pfile, tok, len))
cpp_skip_hspace (pfile); op.value = 1;
if (paren) if (paren)
{ {
if (*ip->cur != ')') if (get_directive_token (pfile) != CPP_RPAREN)
goto oops; goto oops;
++ip->cur;
}
hp = cpp_lookup (pfile, tok, len);
if (hp != NULL)
{
if (hp->type == T_POISON)
cpp_error (pfile, "attempt to use poisoned `%s'", hp->name);
else
op.value = 1;
} }
CPP_SET_WRITTEN (pfile, old_written);
pfile->no_macro_expand--;
} }
return op; return op;
oops: oops:
CPP_SET_WRITTEN (pfile, old_written);
pfile->no_macro_expand--;
cpp_error (pfile, "`defined' without an identifier"); cpp_error (pfile, "`defined' without an identifier");
return op; return op;
...@@ -501,6 +465,13 @@ cpp_lex (pfile, skip_evaluation) ...@@ -501,6 +465,13 @@ cpp_lex (pfile, skip_evaluation)
op.op = toktab->token; op.op = toktab->token;
return op; return op;
} }
else if (tok_start + 1 == tok_end && *tok_start == '#')
{
CPP_FORWARD (CPP_BUFFER (pfile), -1);
op.op = INT;
op.value = cpp_read_check_assertion (pfile);
return op;
}
/* fall through */ /* fall through */
default: default:
op.op = *tok_start; op.op = *tok_start;
...@@ -736,15 +707,16 @@ cpp_parse_expr (pfile) ...@@ -736,15 +707,16 @@ cpp_parse_expr (pfile)
cpp_ice (pfile, "cpp_lex returns a NAME"); cpp_ice (pfile, "cpp_lex returns a NAME");
goto syntax_error; goto syntax_error;
case INT: case CHAR: case INT: case CHAR:
top->value = op.value;
top->unsignedp = op.unsignedp;
goto set_value; goto set_value;
case 0: case 0:
lprio = 0; goto maybe_reduce; lprio = 0; goto maybe_reduce;
case '+': case '-': case '+': case '-':
/* Is this correct if unary ? FIXME */ if (top->flags & HAVE_VALUE)
flags = RIGHT_OPERAND_REQUIRED; {
lprio = PLUS_PRIO; rprio = lprio + 1; goto maybe_reduce; lprio = PLUS_PRIO;
goto binop;
}
/* else fall through */
case '!': case '~': case '!': case '~':
flags = RIGHT_OPERAND_REQUIRED; flags = RIGHT_OPERAND_REQUIRED;
rprio = UNARY_PRIO; lprio = rprio + 1; goto maybe_reduce; rprio = UNARY_PRIO; lprio = rprio + 1; goto maybe_reduce;
...@@ -777,10 +749,6 @@ cpp_parse_expr (pfile) ...@@ -777,10 +749,6 @@ cpp_parse_expr (pfile)
goto maybe_reduce; goto maybe_reduce;
case ERROR: case ERROR:
goto syntax_error; goto syntax_error;
binop:
flags = LEFT_OPERAND_REQUIRED|RIGHT_OPERAND_REQUIRED;
rprio = lprio + 1;
goto maybe_reduce;
default: default:
cpp_error (pfile, "invalid character in #if"); cpp_error (pfile, "invalid character in #if");
goto syntax_error; goto syntax_error;
...@@ -793,9 +761,15 @@ cpp_parse_expr (pfile) ...@@ -793,9 +761,15 @@ cpp_parse_expr (pfile)
cpp_error (pfile, "syntax error in #if"); cpp_error (pfile, "syntax error in #if");
goto syntax_error; goto syntax_error;
} }
top->value = op.value;
top->unsignedp = op.unsignedp;
top->flags |= HAVE_VALUE; top->flags |= HAVE_VALUE;
continue; continue;
binop:
flags = LEFT_OPERAND_REQUIRED|RIGHT_OPERAND_REQUIRED;
rprio = lprio + 1;
maybe_reduce: maybe_reduce:
/* Push an operator, and check if we can reduce now. */ /* Push an operator, and check if we can reduce now. */
while (top->rprio > lprio) while (top->rprio > lprio)
...@@ -1065,6 +1039,5 @@ cpp_parse_expr (pfile) ...@@ -1065,6 +1039,5 @@ cpp_parse_expr (pfile)
syntax_error: syntax_error:
if (stack != init_stack) if (stack != init_stack)
free (stack); free (stack);
skip_rest_of_line (pfile);
return 0; return 0;
} }
...@@ -286,7 +286,7 @@ redundant_include_p (pfile, ihash, ilist) ...@@ -286,7 +286,7 @@ redundant_include_p (pfile, ihash, ilist)
included again if the string is the name of a defined macro. */ included again if the string is the name of a defined macro. */
return (i->control_macro return (i->control_macro
&& (i->control_macro[0] == '\0' && (i->control_macro[0] == '\0'
|| cpp_lookup (pfile, i->control_macro, -1))) || cpp_defined (pfile, i->control_macro, -1)))
? (struct include_hash *)-1 : i; ? (struct include_hash *)-1 : i;
return 0; return 0;
......
...@@ -140,20 +140,31 @@ cpp_lookup (pfile, name, len) ...@@ -140,20 +140,31 @@ cpp_lookup (pfile, name, len)
return (HASHNODE *) 0; return (HASHNODE *) 0;
} }
/* Free a DEFINITION structure. Used by delete_macro, and by
do_define when redefining macros. */
void
free_definition (d)
DEFINITION *d;
{
struct reflist *ap, *nextap;
for (ap = d->pattern; ap != NULL; ap = nextap)
{
nextap = ap->next;
free (ap);
}
if (d->nargs >= 0)
free (d->argnames);
free (d);
}
/* /*
* Delete a hash node. Some weirdness to free junk from macros. * Delete a hash node. Some weirdness to free junk from macros.
* More such weirdness will have to be added if you define more hash * More such weirdness will have to be added if you define more hash
* types that need it. * types that need it.
*/ */
/* Note that the DEFINITION of a macro is removed from the hash table
but its storage is not freed. This would be a storage leak
except that it is not reasonable to keep undefining and redefining
large numbers of macros many times.
In any case, this is necessary, because a macro can be #undef'd
in the middle of reading the arguments to a call to it.
If #undef freed the DEFINITION, that would crash. */
void void
delete_macro (hp) delete_macro (hp)
HASHNODE *hp; HASHNODE *hp;
...@@ -170,19 +181,7 @@ delete_macro (hp) ...@@ -170,19 +181,7 @@ delete_macro (hp)
*hp->bucket_hdr = hp->next; *hp->bucket_hdr = hp->next;
if (hp->type == T_MACRO) if (hp->type == T_MACRO)
{ free_definition (hp->value.defn);
DEFINITION *d = hp->value.defn;
struct reflist *ap, *nextap;
for (ap = d->pattern; ap != NULL; ap = nextap)
{
nextap = ap->next;
free (ap);
}
if (d->nargs >= 0)
free (d->argnames);
free (d);
}
free (hp); free (hp);
} }
......
...@@ -83,6 +83,7 @@ union hashval ...@@ -83,6 +83,7 @@ union hashval
struct hashnode *aschain; /* #assert */ struct hashnode *aschain; /* #assert */
}; };
typedef struct hashnode HASHNODE;
struct hashnode { struct hashnode {
struct hashnode *next; /* double links for easy deletion */ struct hashnode *next; /* double links for easy deletion */
struct hashnode *prev; struct hashnode *prev;
...@@ -97,6 +98,8 @@ struct hashnode { ...@@ -97,6 +98,8 @@ struct hashnode {
extern HASHNODE *cpp_install PARAMS ((cpp_reader *, const U_CHAR *, int, extern HASHNODE *cpp_install PARAMS ((cpp_reader *, const U_CHAR *, int,
enum node_type, const char *)); enum node_type, const char *));
extern HASHNODE *cpp_lookup PARAMS ((cpp_reader *, const U_CHAR *, int));
extern void free_definition PARAMS ((DEFINITION *));
extern void delete_macro PARAMS ((HASHNODE *)); extern void delete_macro PARAMS ((HASHNODE *));
extern MACRODEF create_definition PARAMS ((U_CHAR *, U_CHAR *, extern MACRODEF create_definition PARAMS ((U_CHAR *, U_CHAR *,
......
...@@ -93,11 +93,12 @@ static int null_cleanup PARAMS ((cpp_buffer *, cpp_reader *)); ...@@ -93,11 +93,12 @@ static int null_cleanup PARAMS ((cpp_buffer *, cpp_reader *));
static int skip_comment PARAMS ((cpp_reader *, int)); static int skip_comment PARAMS ((cpp_reader *, int));
static int copy_comment PARAMS ((cpp_reader *, int)); static int copy_comment PARAMS ((cpp_reader *, int));
static void copy_rest_of_line PARAMS ((cpp_reader *)); static void copy_rest_of_line PARAMS ((cpp_reader *));
static void skip_rest_of_line PARAMS ((cpp_reader *));
static void cpp_skip_hspace PARAMS ((cpp_reader *));
static int handle_directive PARAMS ((cpp_reader *)); static int handle_directive PARAMS ((cpp_reader *));
static void pass_thru_directive PARAMS ((const U_CHAR *, size_t, static void pass_thru_directive PARAMS ((const U_CHAR *, size_t,
cpp_reader *, cpp_reader *,
const struct directive *)); const struct directive *));
static enum cpp_token get_directive_token PARAMS ((cpp_reader *));
static int read_line_number PARAMS ((cpp_reader *, int *)); static int read_line_number PARAMS ((cpp_reader *, int *));
static U_CHAR *detect_if_not_defined PARAMS ((cpp_reader *)); static U_CHAR *detect_if_not_defined PARAMS ((cpp_reader *));
static int consider_directive_while_skipping PARAMS ((cpp_reader *, static int consider_directive_while_skipping PARAMS ((cpp_reader *,
...@@ -192,12 +193,7 @@ cpp_grow_buffer (pfile, n) ...@@ -192,12 +193,7 @@ cpp_grow_buffer (pfile, n)
CPP_SET_WRITTEN (pfile, old_written); CPP_SET_WRITTEN (pfile, old_written);
} }
/* Process the string STR as if it appeared as the body of a #define /* Process the string STR as if it appeared as the body of a #define.
If STR is just an identifier, define it with value 1.
If STR has anything after the identifier, then it should
be identifier=definition. */
/* Process the string STR as if it appeared as the body of a #define
If STR is just an identifier, define it with value 1. If STR is just an identifier, define it with value 1.
If STR has anything after the identifier, then it should If STR has anything after the identifier, then it should
be identifier=definition. */ be identifier=definition. */
...@@ -252,6 +248,21 @@ cpp_assert (pfile, str) ...@@ -252,6 +248,21 @@ cpp_assert (pfile, str)
} }
} }
/* Determine whether the identifier ID, of length LEN, is a defined macro. */
int
cpp_defined (pfile, id, len)
cpp_reader *pfile;
const U_CHAR *id;
int len;
{
HASHNODE *hp = cpp_lookup (pfile, id, len);
if (hp && hp->type == T_POISON)
{
cpp_error (pfile, "attempt to use poisoned `%s'", hp->name);
return 0;
}
return (hp != NULL);
}
static enum cpp_token static enum cpp_token
null_underflow (pfile) null_underflow (pfile)
...@@ -407,7 +418,7 @@ copy_comment (pfile, m) ...@@ -407,7 +418,7 @@ copy_comment (pfile, m)
/* Skip whitespace \-newline and comments. Does not macro-expand. */ /* Skip whitespace \-newline and comments. Does not macro-expand. */
void static void
cpp_skip_hspace (pfile) cpp_skip_hspace (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
...@@ -508,7 +519,7 @@ copy_rest_of_line (pfile) ...@@ -508,7 +519,7 @@ copy_rest_of_line (pfile)
the scan itself. >75% of calls to copy_r_o_l are from here or the scan itself. >75% of calls to copy_r_o_l are from here or
skip_if_group, which means the common case is to copy stuff into the skip_if_group, which means the common case is to copy stuff into the
token_buffer only to discard it. */ token_buffer only to discard it. */
void static void
skip_rest_of_line (pfile) skip_rest_of_line (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
...@@ -684,11 +695,8 @@ do_define (pfile, keyword) ...@@ -684,11 +695,8 @@ do_define (pfile, keyword)
if ((hp = cpp_lookup (pfile, mdef.symnam, mdef.symlen)) != NULL) if ((hp = cpp_lookup (pfile, mdef.symnam, mdef.symlen)) != NULL)
{ {
int ok = 0; int ok = 0;
/* Redefining a precompiled key is ok. */
if (hp->type == T_PCSTRING)
ok = 1;
/* Redefining a poisoned identifier is even worse than `not ok'. */ /* Redefining a poisoned identifier is even worse than `not ok'. */
else if (hp->type == T_POISON) if (hp->type == T_POISON)
ok = -1; ok = -1;
/* Redefining a macro is ok if the definitions are the same. */ /* Redefining a macro is ok if the definitions are the same. */
else if (hp->type == T_MACRO) else if (hp->type == T_MACRO)
...@@ -713,6 +721,7 @@ do_define (pfile, keyword) ...@@ -713,6 +721,7 @@ do_define (pfile, keyword)
{ {
/* Replace the old definition. */ /* Replace the old definition. */
hp->type = new_type; hp->type = new_type;
free_definition (hp->value.defn);
hp->value.defn = mdef.defn; hp->value.defn = mdef.defn;
} }
} }
...@@ -986,7 +995,7 @@ output_line_command (pfile, file_change) ...@@ -986,7 +995,7 @@ output_line_command (pfile, file_change)
/* Like cpp_get_token, except that it does not read past end-of-line. /* Like cpp_get_token, except that it does not read past end-of-line.
Also, horizontal space is skipped, and macros are popped. */ Also, horizontal space is skipped, and macros are popped. */
static enum cpp_token enum cpp_token
get_directive_token (pfile) get_directive_token (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
...@@ -1872,8 +1881,13 @@ eval_if_expression (pfile) ...@@ -1872,8 +1881,13 @@ eval_if_expression (pfile)
HOST_WIDEST_INT value; HOST_WIDEST_INT value;
long old_written = CPP_WRITTEN (pfile); long old_written = CPP_WRITTEN (pfile);
/* Work around bug in cpp_get_token where it may mistake an
assertion for a directive. */
pfile->only_seen_white = 0;
value = cpp_parse_expr (pfile); value = cpp_parse_expr (pfile);
skip_rest_of_line (pfile);
CPP_SET_WRITTEN (pfile, old_written); /* Pop */ CPP_SET_WRITTEN (pfile, old_written); /* Pop */
return value; return value;
...@@ -2631,10 +2645,7 @@ cpp_get_token (pfile) ...@@ -2631,10 +2645,7 @@ cpp_get_token (pfile)
return CPP_NAME; return CPP_NAME;
} }
/* If macro wants an arglist, verify that a '(' follows. /* If macro wants an arglist, verify that a '(' follows. */
first skip all whitespace, copying it to the output
after the macro name. Then, if there is no '(',
decide this is not a macro call and leave things that way. */
if (hp->type == T_MACRO && hp->value.defn->nargs >= 0) if (hp->type == T_MACRO && hp->value.defn->nargs >= 0)
{ {
int macbuf_whitespace = 0; int macbuf_whitespace = 0;
...@@ -3130,9 +3141,9 @@ int ...@@ -3130,9 +3141,9 @@ int
cpp_read_check_assertion (pfile) cpp_read_check_assertion (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
U_CHAR *name = CPP_PWRITTEN (pfile); U_CHAR *name;
int result; int result;
HASHNODE *hp; long written = CPP_WRITTEN (pfile);
FORWARD (1); /* Skip '#' */ FORWARD (1); /* Skip '#' */
cpp_skip_hspace (pfile); cpp_skip_hspace (pfile);
...@@ -3140,15 +3151,21 @@ cpp_read_check_assertion (pfile) ...@@ -3140,15 +3151,21 @@ cpp_read_check_assertion (pfile)
result = 0; result = 0;
else else
{ {
hp = cpp_lookup (pfile, name, CPP_PWRITTEN (pfile) - name); name = pfile->token_buffer + written;
result = (hp != 0); result = cpp_defined (pfile, name, CPP_PWRITTEN (pfile) - name);
} }
pfile->limit = name; CPP_SET_WRITTEN (pfile, written);
return result; return result;
} }
/* Remember the current position of PFILE. */ /* Remember the current position of PFILE so it may be returned to
after looking ahead a bit.
Note that when you set a mark, you _must_ return to that mark. You
may not forget about it and continue parsing. You may not pop a
buffer with an active mark. You may not call CPP_BUMP_LINE while a
mark is active. */
static void static void
parse_set_mark (pfile) parse_set_mark (pfile)
......
...@@ -61,8 +61,8 @@ typedef int (*parse_cleanup_t) PARAMS((cpp_buffer *, cpp_reader *)); ...@@ -61,8 +61,8 @@ typedef int (*parse_cleanup_t) PARAMS((cpp_buffer *, cpp_reader *));
extern int cpp_handle_option PARAMS ((cpp_reader *, int, char **)); extern int cpp_handle_option PARAMS ((cpp_reader *, int, char **));
extern int cpp_handle_options PARAMS ((cpp_reader *, int, char **)); extern int cpp_handle_options PARAMS ((cpp_reader *, int, char **));
extern enum cpp_token cpp_get_token PARAMS ((cpp_reader *)); extern enum cpp_token cpp_get_token PARAMS ((cpp_reader *));
extern void cpp_skip_hspace PARAMS((cpp_reader *));
extern enum cpp_token cpp_get_non_space_token PARAMS ((cpp_reader *)); extern enum cpp_token cpp_get_non_space_token PARAMS ((cpp_reader *));
extern enum cpp_token get_directive_token PARAMS ((cpp_reader *));
/* This frees resources used by PFILE. */ /* This frees resources used by PFILE. */
extern void cpp_cleanup PARAMS ((cpp_reader *PFILE)); extern void cpp_cleanup PARAMS ((cpp_reader *PFILE));
...@@ -139,9 +139,6 @@ struct file_name_map_list; ...@@ -139,9 +139,6 @@ struct file_name_map_list;
Applying cpp_get_token repeatedly yields a stream of pre-processor Applying cpp_get_token repeatedly yields a stream of pre-processor
tokens. Usually, there is only one cpp_reader object active. */ tokens. Usually, there is only one cpp_reader object active. */
struct hashnode;
typedef struct hashnode HASHNODE;
struct cpp_reader struct cpp_reader
{ {
parse_underflow_t get_token; parse_underflow_t get_token;
...@@ -169,7 +166,7 @@ struct cpp_reader ...@@ -169,7 +166,7 @@ struct cpp_reader
/* Hash table of macros and assertions. See cpphash.c */ /* Hash table of macros and assertions. See cpphash.c */
#define HASHSIZE 1403 #define HASHSIZE 1403
HASHNODE **hashtab; struct hashnode **hashtab;
/* Hash table of other included files. See cppfiles.c */ /* Hash table of other included files. See cppfiles.c */
#define ALL_INCLUDE_HASHSIZE 71 #define ALL_INCLUDE_HASHSIZE 71
...@@ -600,7 +597,6 @@ enum node_type { ...@@ -600,7 +597,6 @@ enum node_type {
T_CONST, /* Constant string, used by `__SIZE_TYPE__' etc */ T_CONST, /* Constant string, used by `__SIZE_TYPE__' etc */
T_MACRO, /* macro defined by `#define' */ T_MACRO, /* macro defined by `#define' */
T_DISABLED, /* macro temporarily turned off for rescan */ T_DISABLED, /* macro temporarily turned off for rescan */
T_PCSTRING, /* precompiled string (hashval is KEYDEF *) */
T_POISON, /* defined with `#pragma poison' */ T_POISON, /* defined with `#pragma poison' */
T_UNUSED /* Used for something not defined. */ T_UNUSED /* Used for something not defined. */
}; };
...@@ -686,13 +682,12 @@ extern void cpp_grow_buffer PARAMS ((cpp_reader *, long)); ...@@ -686,13 +682,12 @@ extern void cpp_grow_buffer PARAMS ((cpp_reader *, long));
extern cpp_buffer *cpp_push_buffer PARAMS ((cpp_reader *, extern cpp_buffer *cpp_push_buffer PARAMS ((cpp_reader *,
unsigned char *, long)); unsigned char *, long));
extern cpp_buffer *cpp_pop_buffer PARAMS ((cpp_reader *)); extern cpp_buffer *cpp_pop_buffer PARAMS ((cpp_reader *));
extern HASHNODE *cpp_lookup PARAMS ((cpp_reader *, const U_CHAR *, int)); extern int cpp_defined PARAMS ((cpp_reader *, const U_CHAR *, int));
extern void cpp_reader_init PARAMS ((cpp_reader *)); extern void cpp_reader_init PARAMS ((cpp_reader *));
extern void cpp_options_init PARAMS ((cpp_options *)); extern void cpp_options_init PARAMS ((cpp_options *));
extern int cpp_start_read PARAMS ((cpp_reader *, char *)); extern int cpp_start_read PARAMS ((cpp_reader *, char *));
extern int cpp_read_check_assertion PARAMS ((cpp_reader *)); extern int cpp_read_check_assertion PARAMS ((cpp_reader *));
extern void skip_rest_of_line PARAMS ((cpp_reader *));
extern void cpp_finish PARAMS ((cpp_reader *)); extern void cpp_finish PARAMS ((cpp_reader *));
extern void quote_string PARAMS ((cpp_reader *, const char *)); extern void quote_string PARAMS ((cpp_reader *, const char *));
......
...@@ -603,7 +603,7 @@ check_macro_names (pfile, names) ...@@ -603,7 +603,7 @@ check_macro_names (pfile, names)
{ {
while (*names) while (*names)
{ {
if (cpp_lookup (pfile, names, -1)) if (cpp_defined (pfile, names, -1))
recognized_macro (names); recognized_macro (names);
names += strlen (names) + 1; names += strlen (names) + 1;
} }
...@@ -626,6 +626,10 @@ read_scan_file (in_fname, argc, argv) ...@@ -626,6 +626,10 @@ read_scan_file (in_fname, argc, argv)
cpp_reader_init (&scan_in); cpp_reader_init (&scan_in);
scan_in.opts = &scan_options; scan_in.opts = &scan_options;
cpp_options_init (&scan_options); cpp_options_init (&scan_options);
/* We are going to be scanning a header file out of its proper context,
so ignore warnings and errors. */
scan_options.inhibit_warnings = 1;
scan_options.inhibit_errors = 1;
i = cpp_handle_options (&scan_in, argc, argv); i = cpp_handle_options (&scan_in, argc, argv);
if (i < argc && ! CPP_FATAL_ERRORS (&scan_in)) if (i < argc && ! CPP_FATAL_ERRORS (&scan_in))
cpp_fatal (&scan_in, "Invalid option `%s'", argv[i]); cpp_fatal (&scan_in, "Invalid option `%s'", argv[i]);
......
/* { dg-do preprocess } */
/* Test for proper handling of unary minus in #if. */
#if !(-1)
#error Error /* { dg-bogus "Error" "case !(-1)" } */
#endif
#if !-1
#error Error /* { dg-bogus "Error" "case !-1" } */
#endif
#if -1
#else
#error Error /* { dg-bogus "Error" "case -1" } */
#endif
/* { dg-do preprocess } */
/* Test for proper handling of unary plus in #if. */
#if !(+1)
#error Error /* { dg-bogus "Error" "case !(+1)" } */
#endif
#if !+1
#error Error /* { dg-bogus "Error" "case !+1" } */
#endif
#if +1
#else
#error Error /* { dg-bogus "Error" "case +1" } */
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment