Commit a2a76ce7 by Zack Weinberg Committed by Zack Weinberg

cpphash.c: Fix formatting, update commentary.

	* cpphash.c: Fix formatting, update commentary.
	(dump_definition): Take three separate arguments instead of a
	MACRODEF structure argument.
	* cpphash.h: Update prototype of dump_definition.
	* cppinit.c (cpp_finish): Update call of dump_definition.

	* cpplib.c (do_define): Always create new hash entry with
	T_MACRO type.  Remove redundant check for redefinition of
	poisoned identifier.  Update call of dump_definition.
	(do_undef): Don't call check_macro_name.  Rename sym_length to
	len.
	(do_error, do_warning): Don't use copy_rest_of_line or
	SKIP_WHITE_SPACE.
	(do_warning): Don't use pedwarn for the actual warning,
	only the notice about its not being in the standard.  (Fixes
	bug with #warning in system headers.)
	(do_ident): Stricter argument checking - accept only a single
	string after #ident.  Also, macro-expand the line.
	(do_xifdef): Use cpp_defined.  De-obfuscate.

	(do_pragma): Split out specific pragma handling to separate
	functions.  Use get_directive_token.  Update commentary.  Do
	not pass on #pragma once or #pragma poison to the front end.
	(do_pragma_once, do_pragma_implementation, do_pragma_poison,
	do_pragma_default): New.

From-SVN: r31931
parent 2144ddea
2000-02-11 Zack Weinberg <zack@wolery.cumb.org>
* cpphash.c: Fix formatting, update commentary.
(dump_definition): Take three separate arguments instead of a
MACRODEF structure argument.
* cpphash.h: Update prototype of dump_definition.
* cppinit.c (cpp_finish): Update call of dump_definition.
* cpplib.c (do_define): Always create new hash entry with
T_MACRO type. Remove redundant check for redefinition of
poisoned identifier. Update call of dump_definition.
(do_undef): Don't call check_macro_name. Rename sym_length to
len.
(do_error, do_warning): Don't use copy_rest_of_line or
SKIP_WHITE_SPACE.
(do_warning): Don't use pedwarn for the actual warning,
only the notice about its not being in the standard. (Fixes
bug with #warning in system headers.)
(do_ident): Stricter argument checking - accept only a single
string after #ident. Also, macro-expand the line.
(do_xifdef): Use cpp_defined. De-obfuscate.
(do_pragma): Split out specific pragma handling to separate
functions. Use get_directive_token. Update commentary. Do
not pass on #pragma once or #pragma poison to the front end.
(do_pragma_once, do_pragma_implementation, do_pragma_poison,
do_pragma_default): New.
Feb 11 12:30:53 2000 Jeffrey A Law (law@cygnus.com) Feb 11 12:30:53 2000 Jeffrey A Law (law@cygnus.com)
* jump.c (jump_optimize_1): The first operand in a relational * jump.c (jump_optimize_1): The first operand in a relational
......
...@@ -89,8 +89,7 @@ struct argdata ...@@ -89,8 +89,7 @@ struct argdata
}; };
/* Return hash function on name. must be compatible with the one /* Calculate hash function on a string. */
computed a step at a time, elsewhere */
static unsigned int static unsigned int
hashf (s, len) hashf (s, len)
...@@ -169,7 +168,6 @@ void ...@@ -169,7 +168,6 @@ void
delete_macro (hp) delete_macro (hp)
HASHNODE *hp; HASHNODE *hp;
{ {
if (hp->prev != NULL) if (hp->prev != NULL)
hp->prev->next = hp->next; hp->prev->next = hp->next;
if (hp->next != NULL) if (hp->next != NULL)
...@@ -1575,15 +1573,15 @@ comp_def_part (first, beg1, len1, beg2, len2, last) ...@@ -1575,15 +1573,15 @@ comp_def_part (first, beg1, len1, beg2, len2, last)
to be read back in again. */ to be read back in again. */
void void
dump_definition (pfile, macro) dump_definition (pfile, sym, len, defn)
cpp_reader *pfile; cpp_reader *pfile;
MACRODEF macro; const U_CHAR *sym;
long len;
DEFINITION *defn;
{ {
DEFINITION *defn = macro.defn; CPP_RESERVE (pfile, len + sizeof "#define ");
CPP_RESERVE (pfile, macro.symlen + sizeof "#define ");
CPP_PUTS_Q (pfile, "#define ", sizeof "#define " -1); CPP_PUTS_Q (pfile, "#define ", sizeof "#define " -1);
CPP_PUTS_Q (pfile, macro.symnam, macro.symlen); CPP_PUTS_Q (pfile, sym, len);
if (defn->nargs == -1) if (defn->nargs == -1)
{ {
......
...@@ -107,6 +107,7 @@ extern MACRODEF create_definition PARAMS ((U_CHAR *, U_CHAR *, ...@@ -107,6 +107,7 @@ extern MACRODEF create_definition PARAMS ((U_CHAR *, U_CHAR *,
extern int compare_defs PARAMS ((cpp_reader *, DEFINITION *, extern int compare_defs PARAMS ((cpp_reader *, DEFINITION *,
DEFINITION *)); DEFINITION *));
extern void macroexpand PARAMS ((cpp_reader *, HASHNODE *)); extern void macroexpand PARAMS ((cpp_reader *, HASHNODE *));
extern void dump_definition PARAMS ((cpp_reader *, MACRODEF)); extern void dump_definition PARAMS ((cpp_reader *, const U_CHAR *, long,
DEFINITION *));
#endif #endif
...@@ -1040,16 +1040,12 @@ cpp_finish (pfile) ...@@ -1040,16 +1040,12 @@ cpp_finish (pfile)
{ {
int i; int i;
HASHNODE *h; HASHNODE *h;
MACRODEF m;
for (i = HASHSIZE; --i >= 0;) for (i = HASHSIZE; --i >= 0;)
{ {
for (h = pfile->hashtab[i]; h; h = h->next) for (h = pfile->hashtab[i]; h; h = h->next)
if (h->type == T_MACRO) if (h->type == T_MACRO)
{ {
m.defn = h->value.defn; dump_definition (pfile, h->name, h->length, h->value.defn);
m.symnam = h->name;
m.symlen = h->length;
dump_definition (pfile, m);
CPP_PUTC (pfile, '\n'); CPP_PUTC (pfile, '\n');
} }
} }
......
...@@ -669,16 +669,10 @@ do_define (pfile, keyword) ...@@ -669,16 +669,10 @@ do_define (pfile, keyword)
HASHNODE *hp; HASHNODE *hp;
long here; long here;
U_CHAR *macro, *buf, *end; U_CHAR *macro, *buf, *end;
enum node_type new_type;
here = CPP_WRITTEN (pfile); here = CPP_WRITTEN (pfile);
copy_rest_of_line (pfile); copy_rest_of_line (pfile);
if (keyword == NULL || keyword->type == T_DEFINE)
new_type = T_MACRO;
else
new_type = T_POISON;
/* Copy out the line so we can pop the token buffer. */ /* Copy out the line so we can pop the token buffer. */
buf = pfile->token_buffer + here; buf = pfile->token_buffer + here;
end = CPP_PWRITTEN (pfile); end = CPP_PWRITTEN (pfile);
...@@ -694,18 +688,19 @@ do_define (pfile, keyword) ...@@ -694,18 +688,19 @@ 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;
/* Redefining a poisoned identifier is even worse than `not ok'. */
if (hp->type == T_POISON)
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) if (hp->type == T_MACRO)
ok = ! compare_defs (pfile, mdef.defn, hp->value.defn); ok = ! compare_defs (pfile, mdef.defn, hp->value.defn);
/* Redefining a constant is ok with -D. */ /* Redefining a constant is ok with -D. */
else if (hp->type == T_CONST || hp->type == T_STDC) else if (hp->type == T_CONST || hp->type == T_STDC)
ok = ! CPP_OPTIONS (pfile)->done_initializing; ok = ! CPP_OPTIONS (pfile)->done_initializing;
/* Otherwise it's not ok. */
else
ok = 0;
/* Print the warning or error if it's not ok. */ /* Print the warning or error if it's not ok. */
if (ok <= 0) if (! ok)
{ {
if (hp->type == T_POISON) if (hp->type == T_POISON)
cpp_error (pfile, "redefining poisoned `%.*s'", cpp_error (pfile, "redefining poisoned `%.*s'",
...@@ -720,19 +715,19 @@ do_define (pfile, keyword) ...@@ -720,19 +715,19 @@ do_define (pfile, keyword)
if (hp->type != T_POISON) if (hp->type != T_POISON)
{ {
/* Replace the old definition. */ /* Replace the old definition. */
hp->type = new_type; hp->type = T_MACRO;
free_definition (hp->value.defn); free_definition (hp->value.defn);
hp->value.defn = mdef.defn; hp->value.defn = mdef.defn;
} }
} }
else else
cpp_install (pfile, mdef.symnam, mdef.symlen, new_type, (char *)mdef.defn); cpp_install (pfile, mdef.symnam, mdef.symlen, T_MACRO, (char *)mdef.defn);
if (keyword != NULL && keyword->type == T_DEFINE) if (keyword != NULL && keyword->type == T_DEFINE)
{ {
if (CPP_OPTIONS (pfile)->debug_output if (CPP_OPTIONS (pfile)->debug_output
|| CPP_OPTIONS (pfile)->dump_macros == dump_definitions) || CPP_OPTIONS (pfile)->dump_macros == dump_definitions)
dump_definition (pfile, mdef); dump_definition (pfile, mdef.symnam, mdef.symlen, mdef.defn);
else if (CPP_OPTIONS (pfile)->dump_macros == dump_names) else if (CPP_OPTIONS (pfile)->dump_macros == dump_names)
pass_thru_directive (mdef.symnam, mdef.symlen, pfile, keyword); pass_thru_directive (mdef.symnam, mdef.symlen, pfile, keyword);
} }
...@@ -1444,7 +1439,7 @@ do_undef (pfile, keyword) ...@@ -1444,7 +1439,7 @@ do_undef (pfile, keyword)
cpp_reader *pfile; cpp_reader *pfile;
const struct directive *keyword; const struct directive *keyword;
{ {
int sym_length; int len;
HASHNODE *hp; HASHNODE *hp;
U_CHAR *buf, *name, *limit; U_CHAR *buf, *name, *limit;
int c; int c;
...@@ -1465,8 +1460,9 @@ do_undef (pfile, keyword) ...@@ -1465,8 +1460,9 @@ do_undef (pfile, keyword)
limit = CPP_PWRITTEN(pfile); limit = CPP_PWRITTEN(pfile);
/* Copy out the token so we can pop the token buffer. */ /* Copy out the token so we can pop the token buffer. */
name = (U_CHAR *) alloca (limit - buf + 1); len = limit - buf;
bcopy(buf, name, limit - buf); name = (U_CHAR *) alloca (len + 1);
memcpy (name, buf, len);
name[limit - buf] = '\0'; name[limit - buf] = '\0';
token = get_directive_token (pfile); token = get_directive_token (pfile);
...@@ -1478,14 +1474,12 @@ do_undef (pfile, keyword) ...@@ -1478,14 +1474,12 @@ do_undef (pfile, keyword)
CPP_SET_WRITTEN (pfile, here); CPP_SET_WRITTEN (pfile, here);
sym_length = check_macro_name (pfile, buf); while ((hp = cpp_lookup (pfile, name, len)) != NULL)
while ((hp = cpp_lookup (pfile, name, sym_length)) != NULL)
{ {
/* If we are generating additional info for debugging (with -g) we /* If we are generating additional info for debugging (with -g) we
need to pass through all effective #undef commands. */ need to pass through all effective #undef commands. */
if (CPP_OPTIONS (pfile)->debug_output && keyword) if (CPP_OPTIONS (pfile)->debug_output && keyword)
pass_thru_directive (name, sym_length, pfile, keyword); pass_thru_directive (name, len, pfile, keyword);
if (hp->type == T_POISON) if (hp->type == T_POISON)
cpp_error (pfile, "cannot undefine poisoned `%s'", hp->name); cpp_error (pfile, "cannot undefine poisoned `%s'", hp->name);
else else
...@@ -1529,14 +1523,14 @@ do_error (pfile, keyword) ...@@ -1529,14 +1523,14 @@ do_error (pfile, keyword)
cpp_reader *pfile; cpp_reader *pfile;
const struct directive *keyword ATTRIBUTE_UNUSED; const struct directive *keyword ATTRIBUTE_UNUSED;
{ {
long here = CPP_WRITTEN (pfile); U_CHAR *text, *limit;
U_CHAR *text;
copy_rest_of_line (pfile);
text = pfile->token_buffer + here;
SKIP_WHITE_SPACE(text);
cpp_error (pfile, "#error %s", text); cpp_skip_hspace (pfile);
CPP_SET_WRITTEN (pfile, here); text = CPP_BUFFER (pfile)->cur;
skip_rest_of_line (pfile);
limit = CPP_BUFFER (pfile)->cur;
cpp_error (pfile, "#error %.*s", (int)(limit - text), text);
return 0; return 0;
} }
...@@ -1550,167 +1544,231 @@ do_warning (pfile, keyword) ...@@ -1550,167 +1544,231 @@ do_warning (pfile, keyword)
cpp_reader *pfile; cpp_reader *pfile;
const struct directive *keyword ATTRIBUTE_UNUSED; const struct directive *keyword ATTRIBUTE_UNUSED;
{ {
U_CHAR *text; U_CHAR *text, *limit;
long here = CPP_WRITTEN(pfile);
copy_rest_of_line (pfile); cpp_skip_hspace (pfile);
text = pfile->token_buffer + here; text = CPP_BUFFER (pfile)->cur;
SKIP_WHITE_SPACE(text); skip_rest_of_line (pfile);
limit = CPP_BUFFER (pfile)->cur;
if (CPP_PEDANTIC (pfile) && !CPP_BUFFER (pfile)->system_header_p) if (CPP_PEDANTIC (pfile) && !CPP_BUFFER (pfile)->system_header_p)
cpp_pedwarn (pfile, "ANSI C does not allow `#warning'"); cpp_pedwarn (pfile, "ANSI C does not allow `#warning'");
/* Use `pedwarn' not `warning', because #warning isn't in the C Standard; cpp_warning (pfile, "#warning %.*s", (int)(limit - text), text);
if -pedantic-errors is given, #warning should cause an error. */
cpp_pedwarn (pfile, "#warning %s", text);
CPP_SET_WRITTEN (pfile, here);
return 0; return 0;
} }
/* Report program identification. /* Report program identification. */
This is not precisely what cccp does with #ident, however I believe
it matches `closely enough' (behavior is identical as long as there
are no macros on the #ident line, which is pathological in my opinion). */
static int static int
do_ident (pfile, keyword) do_ident (pfile, keyword)
cpp_reader *pfile; cpp_reader *pfile;
const struct directive *keyword ATTRIBUTE_UNUSED; const struct directive *keyword ATTRIBUTE_UNUSED;
{ {
long old_written = CPP_WRITTEN (pfile);
/* Allow #ident in system headers, since that's not user's fault. */ /* Allow #ident in system headers, since that's not user's fault. */
if (CPP_PEDANTIC (pfile) && !CPP_BUFFER (pfile)->system_header_p) if (CPP_PEDANTIC (pfile) && !CPP_BUFFER (pfile)->system_header_p)
cpp_pedwarn (pfile, "ANSI C does not allow `#ident'"); cpp_pedwarn (pfile, "ANSI C does not allow `#ident'");
CPP_PUTS (pfile, "#ident ", 7); CPP_PUTS (pfile, "#ident ", 7);
cpp_skip_hspace (pfile);
copy_rest_of_line (pfile); /* Next token should be a string constant. */
if (get_directive_token (pfile) == CPP_STRING)
/* And then a newline. */
if (get_directive_token (pfile) == CPP_VSPACE)
/* Good - ship it. */
return 0;
cpp_error (pfile, "invalid #ident");
skip_rest_of_line (pfile);
CPP_SET_WRITTEN (pfile, old_written); /* discard directive */
return 0; return 0;
} }
/* Just check for some recognized pragmas that need validation here, /* Pragmata handling. We handle some of these, and pass the rest on
and leave the text in the token buffer to be output. */ to the front end. C99 defines three pragmas and says that no macro
expansion is to be performed on them; whether or not macro
expansion happens for other pragmas is implementation defined.
This implementation never macro-expands the text after #pragma.
We currently do not support the _Pragma operator. Support for that
has to be coordinated with the front end. Proposed implementation:
both #pragma blah blah and _Pragma("blah blah") become
__builtin_pragma(blah blah) and we teach the parser about that. */
/* Sub-handlers for the pragmas needing treatment here.
They return 1 if the token buffer is to be popped, 0 if not. */
static int do_pragma_once PARAMS ((cpp_reader *));
static int do_pragma_implementation PARAMS ((cpp_reader *));
static int do_pragma_poison PARAMS ((cpp_reader *));
static int do_pragma_default PARAMS ((cpp_reader *));
static int static int
do_pragma (pfile, keyword) do_pragma (pfile, keyword)
cpp_reader *pfile; cpp_reader *pfile;
const struct directive *keyword ATTRIBUTE_UNUSED; const struct directive *keyword ATTRIBUTE_UNUSED;
{ {
long here; long here, key;
U_CHAR *buf; U_CHAR *buf;
int pop;
here = CPP_WRITTEN (pfile);
CPP_PUTS (pfile, "#pragma ", 8); CPP_PUTS (pfile, "#pragma ", 8);
cpp_skip_hspace (pfile);
here = CPP_WRITTEN (pfile); key = CPP_WRITTEN (pfile);
copy_rest_of_line (pfile); pfile->no_macro_expand++;
buf = pfile->token_buffer + here; if (get_directive_token (pfile) != CPP_NAME)
goto skip;
if (!strncmp (buf, "once", 4)) buf = pfile->token_buffer + key;
CPP_PUTC (pfile, ' ');
#define tokis(x) !strncmp(buf, x, sizeof(x) - 1)
if (tokis ("once"))
pop = do_pragma_once (pfile);
else if (tokis ("implementation"))
pop = do_pragma_implementation (pfile);
else if (tokis ("poison"))
pop = do_pragma_poison (pfile);
else
pop = do_pragma_default (pfile);
#undef tokis
if (get_directive_token (pfile) != CPP_VSPACE)
goto skip;
if (pop)
CPP_SET_WRITTEN (pfile, here);
pfile->no_macro_expand--;
return 0;
skip:
cpp_error (pfile, "malformed #pragma directive");
skip_rest_of_line (pfile);
CPP_SET_WRITTEN (pfile, here);
pfile->no_macro_expand--;
return 0;
}
static int
do_pragma_default (pfile)
cpp_reader *pfile;
{
while (get_directive_token (pfile) != CPP_VSPACE)
CPP_PUTC (pfile, ' ');
return 0;
}
static int
do_pragma_once (pfile)
cpp_reader *pfile;
{
cpp_buffer *ip = CPP_BUFFER (pfile);
if (ip->fname == NULL)
{ {
cpp_buffer *ip = NULL; cpp_ice (pfile, "ip->fname == NULL in do_pragma_once");
return 1;
}
/* Allow #pragma once in system headers, since that's not the user's /* Allow #pragma once in system headers, since that's not the user's
fault. */ fault. */
if (!CPP_BUFFER (pfile)->system_header_p) if (!ip->system_header_p)
cpp_warning (pfile, "`#pragma once' is obsolete"); cpp_warning (pfile, "`#pragma once' is obsolete");
for (ip = CPP_BUFFER (pfile); ; ip = CPP_PREV_BUFFER (ip))
{
if (ip == CPP_NULL_BUFFER (pfile))
return 0;
if (ip->fname != NULL)
break;
}
if (CPP_PREV_BUFFER (ip) == CPP_NULL_BUFFER (pfile)) if (CPP_PREV_BUFFER (ip) == CPP_NULL_BUFFER (pfile))
cpp_warning (pfile, "`#pragma once' outside include file"); cpp_warning (pfile, "`#pragma once' outside include file");
else else
ip->ihash->control_macro = ""; /* never repeat */ ip->ihash->control_macro = ""; /* never repeat */
}
else if (!strncmp (buf, "implementation", 14)) return 1;
{ }
static int
do_pragma_implementation (pfile)
cpp_reader *pfile;
{
/* Be quiet about `#pragma implementation' for a file only if it hasn't /* Be quiet about `#pragma implementation' for a file only if it hasn't
been included yet. */ been included yet. */
struct include_hash *ptr; struct include_hash *ptr;
U_CHAR *p = buf + 14, *fname, *fcopy; enum cpp_token token;
SKIP_WHITE_SPACE (p); long written = CPP_WRITTEN (pfile);
if (*p == '\n' || *p != '\"') U_CHAR *name;
return 0; U_CHAR *copy;
fname = p + 1; token = get_directive_token (pfile);
p = (U_CHAR *) index (fname, '\"'); if (token == CPP_VSPACE)
return 0;
else if (token != CPP_STRING)
{
cpp_error (pfile, "malformed #pragma implementation");
return 1;
}
fcopy = (U_CHAR *) alloca (p - fname + 1); name = pfile->token_buffer + written + 1;
bcopy (fname, fcopy, p - fname); copy = xstrdup (name);
fcopy[p-fname] = '\0'; copy[strlen(copy)] = '\0'; /* trim trailing quote */
ptr = include_hash (pfile, fcopy, 0); ptr = include_hash (pfile, copy, 0);
if (ptr) if (ptr)
cpp_warning (pfile, cpp_warning (pfile,
"`#pragma implementation' for `%s' appears after file is included", "`#pragma implementation' for `%s' appears after file is included",
fcopy); copy);
} free (copy);
else if (!strncmp (buf, "poison", 6)) return 0;
{ }
static int
do_pragma_poison (pfile)
cpp_reader *pfile;
{
/* Poison these symbols so that all subsequent usage produces an /* Poison these symbols so that all subsequent usage produces an
error message. */ error message. */
U_CHAR *p = buf + 6; U_CHAR *p;
size_t plen; HASHNODE *hp;
U_CHAR *syms; long written;
size_t len;
enum cpp_token token;
int writeit; int writeit;
SKIP_WHITE_SPACE (p);
plen = strlen(p) + 1;
syms = (U_CHAR *) alloca (plen);
memcpy (syms, p, plen);
/* As a rule, don't include #pragma poison commands in output, /* As a rule, don't include #pragma poison commands in output,
unless the user asks for them. */ unless the user asks for them. */
writeit = (CPP_OPTIONS (pfile)->debug_output writeit = (CPP_OPTIONS (pfile)->debug_output
|| CPP_OPTIONS (pfile)->dump_macros == dump_definitions || CPP_OPTIONS (pfile)->dump_macros == dump_definitions
|| CPP_OPTIONS (pfile)->dump_macros == dump_names); || CPP_OPTIONS (pfile)->dump_macros == dump_names);
if (writeit) for (;;)
CPP_SET_WRITTEN (pfile, here);
else
CPP_SET_WRITTEN (pfile, here-8);
if (writeit)
{
CPP_RESERVE (pfile, plen + 7);
CPP_PUTS_Q (pfile, "poison", 7);
}
while (*syms != '\0')
{ {
U_CHAR *end = syms; written = CPP_WRITTEN (pfile);
token = get_directive_token (pfile);
while (is_idchar(*end)) if (token == CPP_VSPACE)
end++; break;
if (token != CPP_NAME)
if (!is_hspace(*end) && *end != '\0')
{ {
cpp_error (pfile, "invalid #pragma poison directive"); cpp_error (pfile, "invalid #pragma poison directive");
skip_rest_of_line (pfile);
return 1; return 1;
} }
if (cpp_push_buffer (pfile, syms, end - syms) != NULL) p = pfile->token_buffer + written;
len = strlen (p);
if ((hp = cpp_lookup (pfile, p, len)))
{ {
do_define (pfile, keyword); if (hp->type != T_POISON)
cpp_pop_buffer (pfile);
}
if (writeit)
{ {
CPP_PUTC_Q (pfile, ' '); cpp_warning (pfile, "poisoning existing macro `%s'", p);
CPP_PUTS_Q (pfile, syms, end - syms); free_definition (hp->value.defn);
hp->value.defn = 0;
hp->type = T_POISON;
} }
syms = end;
SKIP_WHITE_SPACE (syms);
} }
else
cpp_install (pfile, p, len, T_POISON, 0);
if (writeit)
CPP_PUTC (pfile, ' ');
} }
return !writeit;
return 0;
} }
#ifdef SCCS_DIRECTIVE #ifdef SCCS_DIRECTIVE
...@@ -1728,7 +1786,6 @@ do_sccs (pfile, keyword) ...@@ -1728,7 +1786,6 @@ do_sccs (pfile, keyword)
} }
#endif #endif
/* We've found an `#if' directive. If the only thing before it in /* We've found an `#if' directive. If the only thing before it in
this file is white space, and if it is of the form this file is white space, and if it is of the form
`#if ! defined SYMBOL', then SYMBOL is a possible controlling macro `#if ! defined SYMBOL', then SYMBOL is a possible controlling macro
...@@ -1933,18 +1990,15 @@ do_xifdef (pfile, keyword) ...@@ -1933,18 +1990,15 @@ do_xifdef (pfile, keyword)
} }
else if (token == CPP_NAME) else if (token == CPP_NAME)
{ {
HASHNODE *hp = cpp_lookup (pfile, ident, ident_length); skip = cpp_defined (pfile, ident, ident_length);
skip = (hp == NULL) ^ (keyword->type == T_IFNDEF); if (keyword->type == T_IFDEF)
skip = !skip;
if (start_of_file && !skip) if (start_of_file && !skip)
{ {
control_macro = (U_CHAR *) xmalloc (ident_length + 1); control_macro = (U_CHAR *) xmalloc (ident_length + 1);
bcopy (ident, control_macro, ident_length + 1); bcopy (ident, control_macro, ident_length + 1);
} }
if (hp != NULL && hp->type == T_POISON)
{
cpp_error (pfile, "attempt to use poisoned `%s'", hp->name);
skip = !skip;
}
} }
else else
{ {
......
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