#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "cpplib.h"
#include "cpphash.h"
conditional; IF_COND an opening conditional. INCL means to treat
"..." and <...> as q-char and h-char sequences respectively. IN_I
means this directive should be handled even if -fpreprocessed is in
- effect (these are the directives with callback hooks). */
+ effect (these are the directives with callback hooks).
+
+ EXPAND is set on directives that are always macro-expanded. */
#define COND (1 << 0)
#define IF_COND (1 << 1)
#define INCL (1 << 2)
#define IN_I (1 << 3)
+#define EXPAND (1 << 4)
/* Defines one #-directive, including how to handle it. */
typedef void (*directive_handler) PARAMS ((cpp_reader *));
static void skip_rest_of_line PARAMS ((cpp_reader *));
static void check_eol PARAMS ((cpp_reader *));
static void start_directive PARAMS ((cpp_reader *));
+static void prepare_directive_trad PARAMS ((cpp_reader *));
static void end_directive PARAMS ((cpp_reader *, int));
static void directive_diagnostics
PARAMS ((cpp_reader *, const directive *, int));
static struct pragma_entry *insert_pragma_entry
PARAMS ((cpp_reader *, struct pragma_entry **, const cpp_hashnode *,
pragma_cb));
+static int count_registered_pragmas PARAMS ((struct pragma_entry *));
+static char ** save_registered_pragmas
+ PARAMS ((struct pragma_entry *, char **));
+static char ** restore_registered_pragmas
+ PARAMS ((cpp_reader *, struct pragma_entry *, char **));
static void do_pragma_once PARAMS ((cpp_reader *));
static void do_pragma_poison PARAMS ((cpp_reader *));
static void do_pragma_system_header PARAMS ((cpp_reader *));
#define DIRECTIVE_TABLE \
D(define, T_DEFINE = 0, KANDR, IN_I) /* 270554 */ \
-D(include, T_INCLUDE, KANDR, INCL) /* 52262 */ \
+D(include, T_INCLUDE, KANDR, INCL | EXPAND) /* 52262 */ \
D(endif, T_ENDIF, KANDR, COND) /* 45855 */ \
D(ifdef, T_IFDEF, KANDR, COND | IF_COND) /* 22000 */ \
-D(if, T_IF, KANDR, COND | IF_COND) /* 18162 */ \
+D(if, T_IF, KANDR, COND | IF_COND | EXPAND) /* 18162 */ \
D(else, T_ELSE, KANDR, COND) /* 9863 */ \
D(ifndef, T_IFNDEF, KANDR, COND | IF_COND) /* 9675 */ \
D(undef, T_UNDEF, KANDR, IN_I) /* 4837 */ \
-D(line, T_LINE, KANDR, 0) /* 2465 */ \
-D(elif, T_ELIF, STDC89, COND) /* 610 */ \
+D(line, T_LINE, KANDR, EXPAND) /* 2465 */ \
+D(elif, T_ELIF, STDC89, COND | EXPAND) /* 610 */ \
D(error, T_ERROR, STDC89, 0) /* 475 */ \
D(pragma, T_PRAGMA, STDC89, IN_I) /* 195 */ \
D(warning, T_WARNING, EXTENSION, 0) /* 22 */ \
-D(include_next, T_INCLUDE_NEXT, EXTENSION, INCL) /* 19 */ \
+D(include_next, T_INCLUDE_NEXT, EXTENSION, INCL | EXPAND) /* 19 */ \
D(ident, T_IDENT, EXTENSION, IN_I) /* 11 */ \
-D(import, T_IMPORT, EXTENSION, INCL) /* 0 ObjC */ \
+D(import, T_IMPORT, EXTENSION, INCL | EXPAND) /* 0 ObjC */ \
D(assert, T_ASSERT, EXTENSION, 0) /* 0 SVR4 */ \
D(unassert, T_UNASSERT, EXTENSION, 0) /* 0 SVR4 */ \
-SCCS_ENTRY /* 0 SVR4? */
-
-/* #sccs is not always recognized. */
-#ifdef SCCS_DIRECTIVE
-# define SCCS_ENTRY D(sccs, T_SCCS, EXTENSION, 0)
-#else
-# define SCCS_ENTRY /* nothing */
-#endif
+D(sccs, T_SCCS, EXTENSION, 0) /* 0 SVR4? */
/* Use the table to generate a series of prototypes, an enum for the
directive names, and an array of directive handlers. */
cpp_reader *pfile;
{
/* Discard all stacked contexts. */
- while (pfile->context != &pfile->base_context)
+ while (pfile->context->prev)
_cpp_pop_context (pfile);
/* Sweep up all tokens remaining on the line. */
cpp_reader *pfile;
int skip_line;
{
+ if (CPP_OPTION (pfile, traditional))
+ {
+ /* Revert change of prepare_directive_trad. */
+ pfile->state.prevent_expansion--;
+
+ if (pfile->directive != &dtable[T_DEFINE])
+ _cpp_remove_overlay (pfile);
+ }
/* We don't skip for an assembler #. */
- if (skip_line)
+ else if (skip_line)
{
skip_rest_of_line (pfile);
if (!pfile->keep_tokens)
/* Restore state. */
pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
pfile->state.in_directive = 0;
+ pfile->state.in_expression = 0;
pfile->state.angled_headers = 0;
pfile->directive = 0;
}
-/* Output diagnostics for a directive DIR. INDENTED is non-zero if
+/* Prepare to handle the directive in pfile->directive. */
+static void
+prepare_directive_trad (pfile)
+ cpp_reader *pfile;
+{
+ if (pfile->directive != &dtable[T_DEFINE])
+ {
+ bool no_expand = (pfile->directive
+ && ! (pfile->directive->flags & EXPAND));
+ bool was_skipping = pfile->state.skipping;
+
+ pfile->state.skipping = false;
+ pfile->state.in_expression = (pfile->directive == &dtable[T_IF]
+ || pfile->directive == &dtable[T_ELIF]);
+ if (no_expand)
+ pfile->state.prevent_expansion++;
+ _cpp_read_logical_line_trad (pfile);
+ if (no_expand)
+ pfile->state.prevent_expansion--;
+ pfile->state.skipping = was_skipping;
+ _cpp_overlay_buffer (pfile, pfile->out.base,
+ pfile->out.cur - pfile->out.base);
+ }
+
+ /* Stop ISO C from expanding anything. */
+ pfile->state.prevent_expansion++;
+}
+
+/* Output diagnostics for a directive DIR. INDENTED is nonzero if
the '#' was indented. */
static void
directive_diagnostics (pfile, dir, indented)
}
}
-/* Check if we have a known directive. INDENTED is non-zero if the
+/* Check if we have a known directive. INDENTED is nonzero if the
'#' of the directive was indented. This function is in this file
to save unnecessarily exporting dtable etc. to cpplex.c. Returns
- non-zero if the line of tokens has been handled, zero if we should
+ nonzero if the line of tokens has been handled, zero if we should
continue processing the line. */
int
_cpp_handle_directive (pfile, indented)
if (dname->type == CPP_NAME)
{
- if (dname->val.node->directive_index)
- dir = &dtable[dname->val.node->directive_index - 1];
+ if (dname->val.node->is_directive)
+ dir = &dtable[dname->val.node->directive_index];
}
- /* We do not recognise the # followed by a number extension in
+ /* We do not recognize the # followed by a number extension in
assembler code. */
else if (dname->type == CPP_NUMBER && CPP_OPTION (pfile, lang) != CLK_ASM)
{
skipping or not, we should lex angle-bracketed headers
correctly, and maybe output some diagnostics. */
pfile->state.angled_headers = dir->flags & INCL;
+ pfile->state.directive_wants_padding = dir->flags & INCL;
if (! CPP_OPTION (pfile, preprocessed))
directive_diagnostics (pfile, dir, indented);
if (pfile->state.skipping && !(dir->flags & COND))
cpp_token_as_text (pfile, dname));
}
+ pfile->directive = dir;
+ if (CPP_OPTION (pfile, traditional))
+ prepare_directive_trad (pfile);
+
if (dir)
- {
- /* If we are processing a `#define' directive and we have been
- requested to expand comments into macros, then re-enable
- saving of comments. */
- if (dir == &dtable[T_DEFINE])
- pfile->state.save_comments =
- ! CPP_OPTION (pfile, discard_comments_in_macro_exp);
-
- pfile->directive = dir;
- (*pfile->directive->handler) (pfile);
- }
+ (*pfile->directive->handler) (pfile);
else if (skip == 0)
_cpp_backup_tokens (pfile, 1);
{
cpp_push_buffer (pfile, (const uchar *) buf, count,
/* from_stage3 */ true, 1);
+ /* Disgusting hack. */
+ if (dir_no == T_PRAGMA)
+ pfile->buffer->inc = pfile->buffer->prev->inc;
start_directive (pfile);
/* We don't want a leading # to be interpreted as a directive. */
pfile->buffer->saved_flags = 0;
pfile->directive = &dtable[dir_no];
+ if (CPP_OPTION (pfile, traditional))
+ prepare_directive_trad (pfile);
(void) (*pfile->directive->handler) (pfile);
end_directive (pfile, 1);
+ if (dir_no == T_PRAGMA)
+ pfile->buffer->inc = NULL;
_cpp_pop_buffer (pfile);
}
lex_macro_node (pfile)
cpp_reader *pfile;
{
- cpp_hashnode *node;
const cpp_token *token = _cpp_lex_token (pfile);
/* The token immediately after #define must be an identifier. That
In C++, it may not be any of the "named operators" either,
per C++98 [lex.digraph], [lex.key].
Finally, the identifier may not have been poisoned. (In that case
- the lexer has issued the error message for us.)
-
- Note that if we're copying comments into macro expansions, we
- could encounter comment tokens here, so eat them all up first. */
+ the lexer has issued the error message for us.) */
- if (! CPP_OPTION (pfile, discard_comments_in_macro_exp))
+ if (token->type == CPP_NAME)
{
- while (token->type == CPP_COMMENT)
- token = _cpp_lex_token (pfile);
- }
+ cpp_hashnode *node = token->val.node;
- if (token->type != CPP_NAME)
- {
- if (token->type == CPP_EOF)
- cpp_error (pfile, DL_ERROR, "no macro name given in #%s directive",
- pfile->directive->name);
- else if (token->flags & NAMED_OP)
+ if (node == pfile->spec_nodes.n_defined)
cpp_error (pfile, DL_ERROR,
- "\"%s\" cannot be used as a macro name as it is an operator in C++",
- NODE_NAME (token->val.node));
- else
- cpp_error (pfile, DL_ERROR, "macro names must be identifiers");
-
- return 0;
- }
-
- node = token->val.node;
- if (node->flags & NODE_POISONED)
- return 0;
-
- if (node == pfile->spec_nodes.n_defined)
- {
- cpp_error (pfile, DL_ERROR, "\"%s\" cannot be used as a macro name",
- NODE_NAME (node));
- return 0;
+ "\"defined\" cannot be used as a macro name");
+ else if (! (node->flags & NODE_POISONED))
+ return node;
}
+ else if (token->flags & NAMED_OP)
+ cpp_error (pfile, DL_ERROR,
+ "\"%s\" cannot be used as a macro name as it is an operator in C++",
+ NODE_NAME (token->val.node));
+ else if (token->type == CPP_EOF)
+ cpp_error (pfile, DL_ERROR, "no macro name given in #%s directive",
+ pfile->directive->name);
+ else
+ cpp_error (pfile, DL_ERROR, "macro names must be identifiers");
- return node;
+ return NULL;
}
/* Process a #define directive. Most work is done in cppmacro.c. */
if (node)
{
+ /* If we have been requested to expand comments into macros,
+ then re-enable saving of comments. */
+ pfile->state.save_comments =
+ ! CPP_OPTION (pfile, discard_comments_in_macro_exp);
+
if (_cpp_create_definition (pfile, node))
if (pfile->cb.define)
(*pfile->cb.define) (pfile, pfile->directive_line, node);
do_undef (pfile)
cpp_reader *pfile;
{
- cpp_hashnode *node = lex_macro_node (pfile);
+ cpp_hashnode *node = lex_macro_node (pfile);
/* 6.10.3.5 paragraph 2: [#undef] is ignored if the specified identifier
is not currently defined as a macro name. */
if (node->flags & NODE_WARN)
cpp_error (pfile, DL_WARNING, "undefining \"%s\"", NODE_NAME (node));
+ if (CPP_OPTION (pfile, warn_unused_macros))
+ _cpp_warn_if_unused_macro (pfile, node, NULL);
+
_cpp_free_definition (node);
}
check_eol (pfile);
buffer = (unsigned char *) xmalloc (capacity);
for (;;)
{
- token = cpp_get_token (pfile);
+ token = get_token_no_padding (pfile);
if (token->type == CPP_GREATER || token->type == CPP_EOF)
break;
dir = pfile->directive->name;
/* Allow macro expansion. */
- header = cpp_get_token (pfile);
+ header = get_token_no_padding (pfile);
if (header->type != CPP_STRING && header->type != CPP_HEADER_NAME)
{
if (header->type != CPP_LESS)
return NULL;
}
+ check_eol (pfile);
return header;
}
cpp_reader *pfile;
enum include_type type;
{
- const cpp_token *header;
+ const cpp_token *header = parse_include (pfile);
+ if (!header)
+ return;
- /* For #include_next, if this is the primary source file, warn and
- use the normal search logic. */
- if (type == IT_INCLUDE_NEXT && ! pfile->buffer->prev)
- {
- cpp_error (pfile, DL_WARNING, "#include_next in primary source file");
- type = IT_INCLUDE;
- }
- else if (type == IT_IMPORT && CPP_OPTION (pfile, warn_import))
+ /* Prevent #include recursion. */
+ if (pfile->line_maps.depth >= CPP_STACK_MAX)
{
- CPP_OPTION (pfile, warn_import) = 0;
- cpp_error (pfile, DL_WARNING,
- "#import is obsolete, use an #ifndef wrapper in the header file");
+ cpp_error (pfile, DL_ERROR, "#include nested too deeply");
+ return;
}
- header = parse_include (pfile);
- if (header)
- {
- /* Prevent #include recursion. */
- if (pfile->line_maps.depth >= CPP_STACK_MAX)
- cpp_error (pfile, DL_FATAL, "#include nested too deeply");
- else
- {
- check_eol (pfile);
- /* Get out of macro context, if we are. */
- skip_rest_of_line (pfile);
- if (pfile->cb.include)
- (*pfile->cb.include) (pfile, pfile->directive_line,
- pfile->directive->name, header);
+ /* Get out of macro context, if we are. */
+ skip_rest_of_line (pfile);
- _cpp_execute_include (pfile, header, type);
- }
- }
+ if (pfile->cb.include)
+ (*pfile->cb.include) (pfile, pfile->directive_line,
+ pfile->directive->name, header);
+
+ _cpp_execute_include (pfile, header, type);
}
static void
do_import (pfile)
cpp_reader *pfile;
{
+ if (CPP_OPTION (pfile, warn_import))
+ {
+ CPP_OPTION (pfile, warn_import) = 0;
+ cpp_error (pfile, DL_WARNING,
+ "#import is obsolete, use an #ifndef wrapper in the header file");
+ }
+
do_include_common (pfile, IT_IMPORT);
}
do_include_next (pfile)
cpp_reader *pfile;
{
- do_include_common (pfile, IT_INCLUDE_NEXT);
+ enum include_type type = IT_INCLUDE_NEXT;
+
+ /* If this is the primary source file, warn and use the normal
+ search logic. */
+ if (! pfile->buffer->prev)
+ {
+ cpp_error (pfile, DL_WARNING,
+ "#include_next in primary source file");
+ type = IT_INCLUDE;
+ }
+ do_include_common (pfile, type);
}
/* Subroutine of do_linemarker. Read possible flags after file name.
uchar *result = _cpp_unaligned_alloc (pfile, len + 1);
uchar *dst = result;
const uchar *limit = str + len;
- unsigned int c;
- unsigned HOST_WIDE_INT mask;
+ cppchar_t c;
- /* We need the mask to match the host's 'unsigned char', not the
- target's. */
- if (CHAR_BIT < HOST_BITS_PER_WIDE_INT)
- mask = ((unsigned HOST_WIDE_INT) 1 << CHAR_BIT) - 1;
- else
- mask = ~(unsigned HOST_WIDE_INT)0;
-
while (str < limit)
{
c = *str++;
if (c != '\\')
*dst++ = c;
else
- *dst++ = cpp_parse_escape (pfile, (const uchar **)&str, limit, mask);
+ *dst++ = cpp_parse_escape (pfile, &str, limit, 0);
}
*dst++ = '\0';
return result;
"\"%s\" after #line is not a positive integer",
cpp_token_as_text (pfile, token));
return;
- }
+ }
if (CPP_PEDANTIC (pfile) && (new_lineno == 0 || new_lineno > cap))
cpp_error (pfile, DL_PEDWARN, "line number out of range");
cpp_error (pfile, DL_ERROR, "\"%s\" after # is not a positive integer",
cpp_token_as_text (pfile, token));
return;
- }
+ }
token = cpp_get_token (pfile);
if (token->type == CPP_STRING)
cpp_reader *pfile;
{
/* Pragmas in the global namespace. */
- cpp_register_pragma (pfile, 0, "poison", do_pragma_poison);
cpp_register_pragma (pfile, 0, "once", do_pragma_once);
/* New GCC-specific pragmas should be put in the GCC namespace. */
cpp_register_pragma (pfile, "GCC", "dependency", do_pragma_dependency);
}
+/* Return the number of registered pragmas in PE. */
+
+static int
+count_registered_pragmas (pe)
+ struct pragma_entry *pe;
+{
+ int ct = 0;
+ for (; pe != NULL; pe = pe->next)
+ {
+ if (pe->is_nspace)
+ ct += count_registered_pragmas (pe->u.space);
+ ct++;
+ }
+ return ct;
+}
+
+/* Save into SD the names of the registered pragmas referenced by PE,
+ and return a pointer to the next free space in SD. */
+
+static char **
+save_registered_pragmas (pe, sd)
+ struct pragma_entry *pe;
+ char **sd;
+{
+ for (; pe != NULL; pe = pe->next)
+ {
+ if (pe->is_nspace)
+ sd = save_registered_pragmas (pe->u.space, sd);
+ *sd++ = xmemdup (HT_STR (&pe->pragma->ident),
+ HT_LEN (&pe->pragma->ident),
+ HT_LEN (&pe->pragma->ident) + 1);
+ }
+ return sd;
+}
+
+/* Return a newly-allocated array which saves the names of the
+ registered pragmas. */
+
+char **
+_cpp_save_pragma_names (pfile)
+ cpp_reader *pfile;
+{
+ int ct = count_registered_pragmas (pfile->pragmas);
+ char **result = xnewvec (char *, ct);
+ (void) save_registered_pragmas (pfile->pragmas, result);
+ return result;
+}
+
+/* Restore from SD the names of the registered pragmas referenced by PE,
+ and return a pointer to the next unused name in SD. */
+
+static char **
+restore_registered_pragmas (pfile, pe, sd)
+ cpp_reader *pfile;
+ struct pragma_entry *pe;
+ char **sd;
+{
+ for (; pe != NULL; pe = pe->next)
+ {
+ if (pe->is_nspace)
+ sd = restore_registered_pragmas (pfile, pe->u.space, sd);
+ pe->pragma = cpp_lookup (pfile, U *sd, strlen (*sd));
+ free (*sd);
+ sd++;
+ }
+ return sd;
+}
+
+/* Restore the names of the registered pragmas from SAVED. */
+
+void
+_cpp_restore_pragma_names (pfile, saved)
+ cpp_reader *pfile;
+ char **saved;
+{
+ (void) restore_registered_pragmas (pfile, pfile->pragmas, saved);
+ free (saved);
+}
+
/* Pragmata handling. We handle some, and pass the rest on to the
front end. C99 defines three pragmas and says that no macro
expansion is to be performed on them; whether or not macro
do_pragma_once (pfile)
cpp_reader *pfile;
{
- cpp_error (pfile, DL_WARNING, "#pragma once is obsolete");
-
+ if (CPP_OPTION (pfile, warn_deprecated))
+ cpp_error (pfile, DL_WARNING, "#pragma once is obsolete");
+
if (pfile->buffer->prev == NULL)
cpp_error (pfile, DL_WARNING, "#pragma once in main file");
else
check_eol (pfile);
}
-/* Handle #pragma poison, to poison one or more identifiers so that
- the lexer produces a hard error for each subsequent usage. */
+/* Handle #pragma GCC poison, to poison one or more identifiers so
+ that the lexer produces a hard error for each subsequent usage. */
static void
do_pragma_poison (pfile)
cpp_reader *pfile;
{
const cpp_token *header;
int ordering;
-
+
header = parse_include (pfile);
if (!header)
return;
}
*dest = '\0';
- run_directive (pfile, T_PRAGMA, result, dest - result);
+ /* Ugh; an awful kludge. We are really not set up to be lexing
+ tokens when in the middle of a macro expansion. Use a new
+ context to force cpp_get_token to lex, and so skip_rest_of_line
+ doesn't go beyond the end of the text. Also, remember the
+ current lexing position so we can return to it later.
+
+ Something like line-at-a-time lexing should remove the need for
+ this. */
+ {
+ cpp_context *saved_context = pfile->context;
+ cpp_token *saved_cur_token = pfile->cur_token;
+ tokenrun *saved_cur_run = pfile->cur_run;
+
+ pfile->context = xnew (cpp_context);
+ pfile->context->macro = 0;
+ pfile->context->prev = 0;
+ run_directive (pfile, T_PRAGMA, result, dest - result);
+ free (pfile->context);
+ pfile->context = saved_context;
+ pfile->cur_token = saved_cur_token;
+ pfile->cur_run = saved_cur_run;
+ pfile->line--;
+ }
+
+ /* See above comment. For the moment, we'd like
+
+ token1 _Pragma ("foo") token2
+
+ to be output as
+
+ token1
+ # 7 "file.c"
+ #pragma foo
+ # 7 "file.c"
+ token2
+
+ Getting the line markers is a little tricky. */
+ if (pfile->cb.line_change)
+ (*pfile->cb.line_change) (pfile, pfile->cur_token, false);
}
/* Handle the _Pragma operator. */
{
const cpp_token *string = get__Pragma_string (pfile);
- if (!string)
+ if (string)
+ destringize_and_run (pfile, &string->val.str);
+ else
cpp_error (pfile, DL_ERROR,
"_Pragma takes a parenthesized string literal");
- else
- {
- /* Ideally, we'd like
- token1 _Pragma ("foo") token2
- to be output as
- token1
- # 7 "file.c"
- #pragma foo
- # 7 "file.c"
- token2
- Getting these correct line markers is a little tricky. */
-
- unsigned int orig_line = pfile->line;
- destringize_and_run (pfile, &string->val.str);
- pfile->line = orig_line;
- pfile->buffer->saved_flags = BOL;
- }
}
-/* Just ignore #sccs, on systems where we define it at all. */
-#ifdef SCCS_DIRECTIVE
+/* Just ignore #sccs on all systems. */
static void
do_sccs (pfile)
cpp_reader *pfile ATTRIBUTE_UNUSED;
{
}
-#endif
/* Handle #ifdef. */
static void
const cpp_hashnode *node = lex_macro_node (pfile);
if (node)
- skip = node->type != NT_MACRO;
-
- if (node)
- check_eol (pfile);
+ {
+ skip = node->type != NT_MACRO;
+ _cpp_mark_macro_used (node);
+ check_eol (pfile);
+ }
}
push_conditional (pfile, skip, T_IFDEF, 0);
if (! pfile->state.skipping)
{
node = lex_macro_node (pfile);
- if (node)
- skip = node->type == NT_MACRO;
if (node)
- check_eol (pfile);
+ {
+ skip = node->type == NT_MACRO;
+ _cpp_mark_macro_used (node);
+ check_eol (pfile);
+ }
}
push_conditional (pfile, skip, T_IFNDEF, node);
int skip = 1;
if (! pfile->state.skipping)
- skip = _cpp_parse_expr (pfile) == 0;
+ skip = _cpp_parse_expr (pfile) == false;
push_conditional (pfile, skip, T_IF, pfile->mi_ind_cmacro);
}
}
/* Test an assertion within a preprocessor conditional. Returns
- non-zero on failure, zero on success. On success, the result of
- the test is written into VALUE. */
+ nonzero on failure, zero on success. On success, the result of
+ the test is written into VALUE, otherwise the value 0. */
int
_cpp_test_assertion (pfile, value)
cpp_reader *pfile;
- int *value;
+ unsigned int *value;
{
struct answer *answer;
cpp_hashnode *node;
node = parse_assertion (pfile, &answer, T_IF);
+
+ /* For recovery, an erroneous assertion expression is handled as a
+ failing assertion. */
+ *value = 0;
+
if (node)
*value = (node->type == NT_ASSERTION &&
(answer == 0 || *find_answer (node, answer) != 0));
+ else if (pfile->cur_token[-1].type == CPP_EOF)
+ _cpp_backup_tokens (pfile, 1);
/* We don't commit the memory for the answer - it's temporary only. */
return node == 0;
{
struct answer *new_answer;
cpp_hashnode *node;
-
+
node = parse_assertion (pfile, &new_answer, T_ASSERT);
if (node)
{
{
cpp_hashnode *node;
struct answer *answer;
-
+
node = parse_assertion (pfile, &answer, T_UNASSERT);
/* It isn't an error to #unassert something that isn't asserted. */
if (node && node->type == NT_ASSERTION)
char *buf, *p;
size_t count;
- /* Copy the entire option so we can modify it.
+ /* Copy the entire option so we can modify it.
Change the first "=" in the string to a space. If there is none,
tack " 1" on the end. */
const char *str;
{
handle_assertion (pfile, str, T_UNASSERT);
-}
+}
/* Common code for cpp_assert (-A) and cpp_unassert (-A-). */
static void
new->line_base = new->buf = new->cur = buffer;
new->rlimit = buffer + len;
- new->from_stage3 = from_stage3;
+ new->from_stage3 = from_stage3 || CPP_OPTION (pfile, traditional);
new->prev = pfile->buffer;
new->return_at_eof = return_at_eof;
new->saved_flags = BOL;
}
}
-/* Enter all recognised directives in the hash table. */
+/* Enter all recognized directives in the hash table. */
void
_cpp_init_directives (pfile)
cpp_reader *pfile;
for (i = 0; i < (unsigned int) N_DIRECTIVES; i++)
{
node = cpp_lookup (pfile, dtable[i].name, dtable[i].length);
- node->directive_index = i + 1;
+ node->is_directive = 1;
+ node->directive_index = i;
}
}