/* CPP Library. (Directive handling.)
Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Per Bothner, 1994-95.
Based on CCCP program by Paul Rubin, June 1986
Adapted to ANSI C, Richard Stallman, Jan 1987
check_eol (cpp_reader *pfile)
{
if (! SEEN_EOL () && _cpp_lex_token (pfile)->type != CPP_EOF)
- cpp_error (pfile, DL_PEDWARN, "extra tokens at end of #%s directive",
+ cpp_error (pfile, CPP_DL_PEDWARN, "extra tokens at end of #%s directive",
pfile->directive->name);
}
&& ! (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 (pfile->state.in_expression)
+ pfile->state.skipping = false;
+
if (no_expand)
pfile->state.prevent_expansion++;
_cpp_scan_out_logical_line (pfile, NULL);
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);
if (CPP_PEDANTIC (pfile)
&& ! pfile->state.skipping
&& dir->origin == EXTENSION)
- cpp_error (pfile, DL_PEDWARN, "#%s is a GCC extension", dir->name);
+ cpp_error (pfile, CPP_DL_PEDWARN, "#%s is a GCC extension", dir->name);
/* Traditionally, a directive is ignored unless its # is in
column 1. Therefore in code intended to work with K+R
if (CPP_WTRADITIONAL (pfile))
{
if (dir == &dtable[T_ELIF])
- cpp_error (pfile, DL_WARNING,
+ cpp_error (pfile, CPP_DL_WARNING,
"suggest not using #elif in traditional C");
else if (indented && dir->origin == KANDR)
- cpp_error (pfile, DL_WARNING,
+ cpp_error (pfile, CPP_DL_WARNING,
"traditional C ignores #%s with the # indented",
dir->name);
else if (!indented && dir->origin != KANDR)
- cpp_error (pfile, DL_WARNING,
+ cpp_error (pfile, CPP_DL_WARNING,
"suggest hiding #%s from traditional C with an indented #",
dir->name);
}
if (was_parsing_args)
{
if (CPP_OPTION (pfile, pedantic))
- cpp_error (pfile, DL_PEDWARN,
+ cpp_error (pfile, CPP_DL_PEDWARN,
"embedding a directive within macro arguments is not portable");
pfile->state.parsing_args = 0;
pfile->state.prevent_expansion = 0;
dir = &linemarker_dir;
if (CPP_PEDANTIC (pfile) && ! CPP_OPTION (pfile, preprocessed)
&& ! pfile->state.skipping)
- cpp_error (pfile, DL_PEDWARN,
+ cpp_error (pfile, CPP_DL_PEDWARN,
"style of line directive is a GCC extension");
}
if (CPP_OPTION (pfile, lang) == CLK_ASM)
skip = 0;
else if (!pfile->state.skipping)
- cpp_error (pfile, DL_ERROR, "invalid preprocessing directive #%s",
+ cpp_error (pfile, CPP_DL_ERROR, "invalid preprocessing directive #%s",
cpp_token_as_text (pfile, dname));
}
run_directive (cpp_reader *pfile, int dir_no, const char *buf, size_t count)
{
cpp_push_buffer (pfile, (const uchar *) buf, count,
- /* from_stage3 */ true, 1);
+ /* from_stage3 */ true);
/* Disgusting hack. */
if (dir_no == T_PRAGMA)
- pfile->buffer->inc = pfile->buffer->prev->inc;
+ pfile->buffer->file = pfile->buffer->prev->file;
start_directive (pfile);
/* This is a short-term fix to prevent a leading '#' being
pfile->directive->handler (pfile);
end_directive (pfile, 1);
if (dir_no == T_PRAGMA)
- pfile->buffer->inc = NULL;
+ pfile->buffer->file = NULL;
_cpp_pop_buffer (pfile);
}
cpp_hashnode *node = token->val.node;
if (node == pfile->spec_nodes.n_defined)
- cpp_error (pfile, DL_ERROR,
+ cpp_error (pfile, CPP_DL_ERROR,
"\"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,
+ cpp_error (pfile, CPP_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",
+ cpp_error (pfile, CPP_DL_ERROR, "no macro name given in #%s directive",
pfile->directive->name);
else
- cpp_error (pfile, DL_ERROR, "macro names must be identifiers");
+ cpp_error (pfile, CPP_DL_ERROR, "macro names must be identifiers");
return NULL;
}
{
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 && node->type == NT_MACRO)
+ if (node)
{
if (pfile->cb.undef)
pfile->cb.undef (pfile, pfile->directive_line, node);
- if (node->flags & NODE_WARN)
- cpp_error (pfile, DL_WARNING, "undefining \"%s\"", NODE_NAME (node));
+ /* 6.10.3.5 paragraph 2: [#undef] is ignored if the specified
+ identifier is not currently defined as a macro name. */
+ if (node->type == NT_MACRO)
+ {
+ if (node->flags & NODE_WARN)
+ cpp_error (pfile, CPP_DL_WARNING,
+ "undefining \"%s\"", NODE_NAME (node));
- if (CPP_OPTION (pfile, warn_unused_macros))
- _cpp_warn_if_unused_macro (pfile, node, NULL);
+ if (CPP_OPTION (pfile, warn_unused_macros))
+ _cpp_warn_if_unused_macro (pfile, node, NULL);
- _cpp_free_definition (node);
+ _cpp_free_definition (node);
+ }
}
+
check_eol (pfile);
}
/* Undefine a single macro/assertion/whatever. */
static int
-undefine_macros (cpp_reader *pfile, cpp_hashnode *h,
+undefine_macros (cpp_reader *pfile, cpp_hashnode *h,
void *data_p ATTRIBUTE_UNUSED)
{
switch (h->type)
{
case NT_VOID:
break;
-
+
case NT_MACRO:
if (pfile->cb.undef)
(*pfile->cb.undef) (pfile, pfile->directive_line, h);
break;
if (token->type == CPP_EOF)
{
- cpp_error (pfile, DL_ERROR, "missing terminating > character");
+ cpp_error (pfile, CPP_DL_ERROR, "missing terminating > character");
break;
}
dir = U"pragma dependency";
else
dir = pfile->directive->name;
- cpp_error (pfile, DL_ERROR, "#%s expects \"FILENAME\" or <FILENAME>",
+ cpp_error (pfile, CPP_DL_ERROR, "#%s expects \"FILENAME\" or <FILENAME>",
dir);
return NULL;
return;
/* Prevent #include recursion. */
- if (pfile->line_maps.depth >= CPP_STACK_MAX)
- cpp_error (pfile, DL_ERROR, "#include nested too deeply");
+ if (pfile->line_table->depth >= CPP_STACK_MAX)
+ cpp_error (pfile, CPP_DL_ERROR, "#include nested too deeply");
else
{
/* Get out of macro context, if we are. */
pfile->cb.include (pfile, pfile->directive_line,
pfile->directive->name, fname, angle_brackets);
- _cpp_execute_include (pfile, fname, angle_brackets, type);
+ _cpp_stack_include (pfile, fname, angle_brackets, type);
}
free ((void *) fname);
static void
do_import (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);
}
search logic. */
if (! pfile->buffer->prev)
{
- cpp_error (pfile, DL_WARNING,
+ cpp_error (pfile, CPP_DL_WARNING,
"#include_next in primary source file");
type = IT_INCLUDE;
}
}
if (token->type != CPP_EOF)
- cpp_error (pfile, DL_ERROR, "invalid flag \"%s\" in line directive",
+ cpp_error (pfile, CPP_DL_ERROR, "invalid flag \"%s\" in line directive",
cpp_token_as_text (pfile, token));
return 0;
}
static void
do_line (cpp_reader *pfile)
{
+ const struct line_map *map = linemap_lookup (pfile->line_table, pfile->line);
const cpp_token *token;
- const char *new_file = pfile->map->to_file;
+ const char *new_file = map->to_file;
unsigned long new_lineno;
/* C99 raised the minimum limit on #line numbers. */
|| strtoul_for_line (token->val.str.text, token->val.str.len,
&new_lineno))
{
- cpp_error (pfile, DL_ERROR,
+ cpp_error (pfile, CPP_DL_ERROR,
"\"%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, CPP_DL_PEDWARN, "line number out of range");
token = cpp_get_token (pfile);
if (token->type == CPP_STRING)
{
cpp_string s = { 0, 0 };
- if (_cpp_interpret_string_notranslate (pfile, &token->val.str, &s))
+ if (cpp_interpret_string_notranslate (pfile, &token->val.str, 1,
+ &s, false))
new_file = (const char *)s.text;
check_eol (pfile);
}
else if (token->type != CPP_EOF)
{
- cpp_error (pfile, DL_ERROR, "\"%s\" is not a valid filename",
+ cpp_error (pfile, CPP_DL_ERROR, "\"%s\" is not a valid filename",
cpp_token_as_text (pfile, token));
return;
}
skip_rest_of_line (pfile);
_cpp_do_file_change (pfile, LC_RENAME, new_file, new_lineno,
- pfile->map->sysp);
+ map->sysp);
}
/* Interpret the # 44 "file" [flags] notation, which has slightly
static void
do_linemarker (cpp_reader *pfile)
{
+ const struct line_map *map = linemap_lookup (pfile->line_table, pfile->line);
const cpp_token *token;
- const char *new_file = pfile->map->to_file;
+ const char *new_file = map->to_file;
unsigned long new_lineno;
- unsigned int new_sysp = pfile->map->sysp;
+ unsigned int new_sysp = map->sysp;
enum lc_reason reason = LC_RENAME;
int flag;
|| strtoul_for_line (token->val.str.text, token->val.str.len,
&new_lineno))
{
- cpp_error (pfile, DL_ERROR, "\"%s\" after # is not a positive integer",
+ cpp_error (pfile, CPP_DL_ERROR,
+ "\"%s\" after # is not a positive integer",
cpp_token_as_text (pfile, token));
return;
}
if (token->type == CPP_STRING)
{
cpp_string s = { 0, 0 };
- if (_cpp_interpret_string_notranslate (pfile, &token->val.str, &s))
+ if (cpp_interpret_string_notranslate (pfile, &token->val.str,
+ 1, &s, false))
new_file = (const char *)s.text;
-
+
new_sysp = 0;
flag = read_flag (pfile, 0);
if (flag == 1)
flag = read_flag (pfile, flag);
if (flag == 4)
new_sysp = 2;
+ pfile->buffer->sysp = new_sysp;
}
check_eol (pfile);
}
else if (token->type != CPP_EOF)
{
- cpp_error (pfile, DL_ERROR, "\"%s\" is not a valid filename",
+ cpp_error (pfile, CPP_DL_ERROR, "\"%s\" is not a valid filename",
cpp_token_as_text (pfile, token));
return;
}
const char *to_file, unsigned int file_line,
unsigned int sysp)
{
- pfile->map = linemap_add (&pfile->line_maps, reason, sysp,
- pfile->line, to_file, file_line);
+ const struct line_map *map = linemap_add (pfile->line_table, reason, sysp,
+ to_file, file_line);
+ if (map == NULL)
+ pfile->line = 0;
+ else
+ pfile->line = linemap_line_start (pfile->line_table, map->to_line, 127);
if (pfile->cb.file_change)
- pfile->cb.file_change (pfile, pfile->map);
+ pfile->cb.file_change (pfile, map);
}
/* Report a warning or error detected by the program we are
static void
do_diagnostic (cpp_reader *pfile, int code, int print_dir)
{
- if (_cpp_begin_message (pfile, code,
- pfile->cur_token[-1].line,
- pfile->cur_token[-1].col))
+ if (_cpp_begin_message (pfile, code, pfile->cur_token[-1].src_loc, 0))
{
if (print_dir)
fprintf (stderr, "#%s ", pfile->directive->name);
static void
do_error (cpp_reader *pfile)
{
- do_diagnostic (pfile, DL_ERROR, 1);
+ do_diagnostic (pfile, CPP_DL_ERROR, 1);
}
static void
do_warning (cpp_reader *pfile)
{
/* We want #warning diagnostics to be emitted in system headers too. */
- do_diagnostic (pfile, DL_WARNING_SYSHDR, 1);
+ do_diagnostic (pfile, CPP_DL_WARNING_SYSHDR, 1);
}
/* Report program identification. */
const cpp_token *str = cpp_get_token (pfile);
if (str->type != CPP_STRING)
- cpp_error (pfile, DL_ERROR, "invalid #ident directive");
+ cpp_error (pfile, CPP_DL_ERROR, "invalid #ident directive");
else if (pfile->cb.ident)
pfile->cb.ident (pfile, pfile->directive_line, &str->val.str);
{
if (entry->is_nspace)
clash:
- cpp_error (pfile, DL_ICE,
+ cpp_error (pfile, CPP_DL_ICE,
"registering \"%s\" as both a pragma and a pragma namespace",
NODE_NAME (node));
else if (space)
- cpp_error (pfile, DL_ICE, "#pragma %s %s is already registered",
+ cpp_error (pfile, CPP_DL_ICE, "#pragma %s %s is already registered",
space, name);
else
- cpp_error (pfile, DL_ICE, "#pragma %s is already registered", name);
+ cpp_error (pfile, CPP_DL_ICE, "#pragma %s is already registered", name);
}
else
insert_pragma_entry (pfile, chain, node, handler);
do_pragma (cpp_reader *pfile)
{
const struct pragma_entry *p = NULL;
- const cpp_token *token;
+ const cpp_token *token, *pragma_token = pfile->cur_token;
unsigned int count = 1;
pfile->state.prevent_expansion++;
}
}
- /* FIXME. This is an awful kludge to get the front ends to update
- their notion of line number for diagnostic purposes. The line
- number should be passed to the handler and they should do it
- themselves. Stand-alone CPP must ignore us, otherwise it will
- prefix the directive with spaces, hence the 1. Ugh. */
- if (pfile->cb.line_change)
- pfile->cb.line_change (pfile, token, 1);
-
if (p)
- p->u.handler (pfile);
+ {
+ /* Since the handler below doesn't get the line number, that it
+ might need for diagnostics, make sure it has the right
+ numbers in place. */
+ if (pfile->cb.line_change)
+ (*pfile->cb.line_change) (pfile, pragma_token, false);
+ (*p->u.handler) (pfile);
+ }
else if (pfile->cb.def_pragma)
{
_cpp_backup_tokens (pfile, count);
static void
do_pragma_once (cpp_reader *pfile)
{
- 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
- _cpp_never_reread (pfile->buffer->inc);
+ cpp_error (pfile, CPP_DL_WARNING, "#pragma once in main file");
check_eol (pfile);
+ _cpp_mark_file_once_only (pfile, pfile->buffer->file);
}
/* Handle #pragma GCC poison, to poison one or more identifiers so
break;
if (tok->type != CPP_NAME)
{
- cpp_error (pfile, DL_ERROR, "invalid #pragma GCC poison directive");
+ cpp_error (pfile, CPP_DL_ERROR,
+ "invalid #pragma GCC poison directive");
break;
}
continue;
if (hp->type == NT_MACRO)
- cpp_error (pfile, DL_WARNING, "poisoning existing macro \"%s\"",
+ cpp_error (pfile, CPP_DL_WARNING, "poisoning existing macro \"%s\"",
NODE_NAME (hp));
_cpp_free_definition (hp);
hp->flags |= NODE_POISONED | NODE_DIAGNOSTIC;
cpp_buffer *buffer = pfile->buffer;
if (buffer->prev == 0)
- cpp_error (pfile, DL_WARNING,
+ cpp_error (pfile, CPP_DL_WARNING,
"#pragma system_header ignored outside include file");
else
{
ordering = _cpp_compare_file_date (pfile, fname, angle_brackets);
if (ordering < 0)
- cpp_error (pfile, DL_WARNING, "cannot find source file %s", fname);
+ cpp_error (pfile, CPP_DL_WARNING, "cannot find source file %s", fname);
else if (ordering > 0)
{
- cpp_error (pfile, DL_WARNING, "current file is older than %s", fname);
+ cpp_error (pfile, CPP_DL_WARNING,
+ "current file is older than %s", fname);
if (cpp_get_token (pfile)->type != CPP_EOF)
{
_cpp_backup_tokens (pfile, 1);
- do_diagnostic (pfile, DL_WARNING, 0);
+ do_diagnostic (pfile, CPP_DL_WARNING, 0);
}
}
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
if (string)
destringize_and_run (pfile, &string->val.str);
else
- cpp_error (pfile, DL_ERROR,
+ cpp_error (pfile, CPP_DL_ERROR,
"_Pragma takes a parenthesized string literal");
}
struct if_stack *ifs = buffer->if_stack;
if (ifs == NULL)
- cpp_error (pfile, DL_ERROR, "#else without #if");
+ cpp_error (pfile, CPP_DL_ERROR, "#else without #if");
else
{
if (ifs->type == T_ELSE)
{
- cpp_error (pfile, DL_ERROR, "#else after #else");
- cpp_error_with_line (pfile, DL_ERROR, ifs->line, 0,
+ cpp_error (pfile, CPP_DL_ERROR, "#else after #else");
+ cpp_error_with_line (pfile, CPP_DL_ERROR, ifs->line, 0,
"the conditional began here");
}
ifs->type = T_ELSE;
struct if_stack *ifs = buffer->if_stack;
if (ifs == NULL)
- cpp_error (pfile, DL_ERROR, "#elif without #if");
+ cpp_error (pfile, CPP_DL_ERROR, "#elif without #if");
else
{
if (ifs->type == T_ELSE)
{
- cpp_error (pfile, DL_ERROR, "#elif after #else");
- cpp_error_with_line (pfile, DL_ERROR, ifs->line, 0,
+ cpp_error (pfile, CPP_DL_ERROR, "#elif after #else");
+ cpp_error_with_line (pfile, CPP_DL_ERROR, ifs->line, 0,
"the conditional began here");
}
ifs->type = T_ELIF;
struct if_stack *ifs = buffer->if_stack;
if (ifs == NULL)
- cpp_error (pfile, DL_ERROR, "#endif without #if");
+ cpp_error (pfile, CPP_DL_ERROR, "#endif without #if");
else
{
/* Only check EOL if was not originally skipping. */
if (type == T_UNASSERT && paren->type == CPP_EOF)
return 0;
- cpp_error (pfile, DL_ERROR, "missing '(' after predicate");
+ cpp_error (pfile, CPP_DL_ERROR, "missing '(' after predicate");
return 1;
}
if (token->type == CPP_EOF)
{
- cpp_error (pfile, DL_ERROR, "missing ')' to complete answer");
+ cpp_error (pfile, CPP_DL_ERROR, "missing ')' to complete answer");
return 1;
}
if (acount == 0)
{
- cpp_error (pfile, DL_ERROR, "predicate's answer is empty");
+ cpp_error (pfile, CPP_DL_ERROR, "predicate's answer is empty");
return 1;
}
*answerp = 0;
predicate = cpp_get_token (pfile);
if (predicate->type == CPP_EOF)
- cpp_error (pfile, DL_ERROR, "assertion without predicate");
+ cpp_error (pfile, CPP_DL_ERROR, "assertion without predicate");
else if (predicate->type != CPP_NAME)
- cpp_error (pfile, DL_ERROR, "predicate must be an identifier");
+ cpp_error (pfile, CPP_DL_ERROR, "predicate must be an identifier");
else if (parse_answer (pfile, answerp, type) == 0)
{
unsigned int len = NODE_LEN (predicate->val.node);
{
if (*find_answer (node, new_answer))
{
- cpp_error (pfile, DL_WARNING, "\"%s\" re-asserted",
+ cpp_error (pfile, CPP_DL_WARNING, "\"%s\" re-asserted",
NODE_NAME (node) + 1);
return;
}
return &pfile->cb;
}
-/* The line map set. */
-const struct line_maps *
-cpp_get_line_maps (cpp_reader *pfile)
-{
- return &pfile->line_maps;
-}
-
/* Copy the given callbacks structure to our own. */
void
cpp_set_callbacks (cpp_reader *pfile, cpp_callbacks *cb)
is the responsibility of the caller. */
cpp_buffer *
cpp_push_buffer (cpp_reader *pfile, const uchar *buffer, size_t len,
- int from_stage3, int return_at_eof)
+ int from_stage3)
{
cpp_buffer *new = xobnew (&pfile->buffer_ob, cpp_buffer);
new->rlimit = buffer + len;
new->from_stage3 = from_stage3;
new->prev = pfile->buffer;
- new->return_at_eof = return_at_eof;
new->need_line = true;
pfile->buffer = new;
+
return new;
}
_cpp_pop_buffer (cpp_reader *pfile)
{
cpp_buffer *buffer = pfile->buffer;
- struct include_file *inc = buffer->inc;
+ struct _cpp_file *inc = buffer->file;
struct if_stack *ifs;
/* Walk back up the conditional stack till we reach its level at
entry to this file, issuing error messages. */
for (ifs = buffer->if_stack; ifs; ifs = ifs->next)
- cpp_error_with_line (pfile, DL_ERROR, ifs->line, 0,
+ cpp_error_with_line (pfile, CPP_DL_ERROR, ifs->line, 0,
"unterminated #%s", dtable[ifs->type].name);
/* In case of a missing #endif. */
{
_cpp_pop_file_buffer (pfile, inc);
- /* Don't generate a callback for popping the main file. */
- if (pfile->buffer)
- _cpp_do_file_change (pfile, LC_LEAVE, 0, 0, 0);
+ _cpp_do_file_change (pfile, LC_LEAVE, 0, 0, 0);
}
}