X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=libcpp%2Fdirectives.c;h=c2e71016f2417689ad27057d4b251a290e6bcb0b;hb=941f2388c6654af085ec92de505bc6b53d90b5fa;hp=ccb9f32b61da20998a6ec49c7c995e34ac504c54;hpb=f23c2abe56dba9a57738db7696938c78e4bcc1b3;p=pf3gnuchains%2Fgcc-fork.git
diff --git a/libcpp/directives.c b/libcpp/directives.c
index ccb9f32b61d..c2e71016f24 100644
--- a/libcpp/directives.c
+++ b/libcpp/directives.c
@@ -1,14 +1,14 @@
/* CPP Library. (Directive handling.)
Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2007 Free Software Foundation, Inc.
+ 2007, 2008, 2009 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
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
+Free Software Foundation; either version 3, or (at your option) any
later version.
This program is distributed in the hope that it will be useful,
@@ -17,8 +17,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+along with this program; see the file COPYING3. If not see
+. */
#include "config.h"
#include "system.h"
@@ -32,7 +32,7 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
struct if_stack
{
struct if_stack *next;
- unsigned int line; /* Line where condition started. */
+ linenum_type line; /* Line where condition started. */
const cpp_hashnode *mi_cmacro;/* macro name for #ifndef around entire file */
bool skip_elses; /* Can future #else / #elif be skipped? */
bool was_skipping; /* If were skipping on entry. */
@@ -75,6 +75,7 @@ struct pragma_entry
#define INCL (1 << 2)
#define IN_I (1 << 3)
#define EXPAND (1 << 4)
+#define DEPRECATED (1 << 5)
/* Defines one #-directive, including how to handle it. */
typedef void (*directive_handler) (cpp_reader *);
@@ -91,7 +92,7 @@ struct directive
/* Forward declarations. */
static void skip_rest_of_line (cpp_reader *);
-static void check_eol (cpp_reader *);
+static void check_eol (cpp_reader *, bool);
static void start_directive (cpp_reader *);
static void prepare_directive_trad (cpp_reader *);
static void end_directive (cpp_reader *, int);
@@ -101,7 +102,7 @@ static char *glue_header_name (cpp_reader *);
static const char *parse_include (cpp_reader *, int *, const cpp_token ***);
static void push_conditional (cpp_reader *, int, int, const cpp_hashnode *);
static unsigned int read_flag (cpp_reader *, unsigned int);
-static int strtoul_for_line (const uchar *, unsigned int, unsigned long *);
+static bool strtolinenum (const uchar *, size_t, linenum_type *, bool *);
static void do_diagnostic (cpp_reader *, int, int);
static cpp_hashnode *lex_macro_node (cpp_reader *, bool);
static int undefine_macros (cpp_reader *, cpp_hashnode *, void *);
@@ -130,9 +131,9 @@ static void handle_assertion (cpp_reader *, const char *, int);
counts from all the source code I have lying around (egcs and libc
CVS as of 1999-05-18, plus grub-0.5.91, linux-2.2.9, and
pcmcia-cs-3.0.9). This is no longer important as directive lookup
- is now O(1). All extensions other than #warning and #include_next
- are deprecated. The name is where the extension appears to have
- come from. */
+ is now O(1). All extensions other than #warning, #include_next,
+ and #import are deprecated. The name is where the extension
+ appears to have come from. */
#define DIRECTIVE_TABLE \
D(define, T_DEFINE = 0, KANDR, IN_I) /* 270554 */ \
@@ -149,11 +150,11 @@ 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 | EXPAND) /* 19 */ \
-D(ident, T_IDENT, EXTENSION, IN_I) /* 11 */ \
+D(ident, T_IDENT, EXTENSION, IN_I | DEPRECATED) /* 11 */ \
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 */ \
-D(sccs, T_SCCS, EXTENSION, IN_I) /* 0 SVR4? */
+D(assert, T_ASSERT, EXTENSION, DEPRECATED) /* 0 SVR4 */ \
+D(unassert, T_UNASSERT, EXTENSION, DEPRECATED) /* 0 SVR4 */ \
+D(sccs, T_SCCS, EXTENSION, IN_I | DEPRECATED) /* 0 SVR4? */
/* #sccs is synonymous with #ident. */
#define do_sccs do_ident
@@ -188,7 +189,7 @@ DIRECTIVE_TABLE
did use this notation in its preprocessed output. */
static const directive linemarker_dir =
{
- do_linemarker, U"#", 1, KANDR, IN_I
+ do_linemarker, UC"#", 1, KANDR, IN_I
};
#define SEEN_EOL() (pfile->cur_token[-1].type == CPP_EOF)
@@ -207,11 +208,14 @@ skip_rest_of_line (cpp_reader *pfile)
;
}
-/* Ensure there are no stray tokens at the end of a directive. */
+/* Ensure there are no stray tokens at the end of a directive. If
+ EXPAND is true, tokens macro-expanding to nothing are allowed. */
static void
-check_eol (cpp_reader *pfile)
+check_eol (cpp_reader *pfile, bool expand)
{
- if (! SEEN_EOL () && _cpp_lex_token (pfile)->type != CPP_EOF)
+ if (! SEEN_EOL () && (expand
+ ? cpp_get_token (pfile)
+ : _cpp_lex_token (pfile))->type != CPP_EOF)
cpp_error (pfile, CPP_DL_PEDWARN, "extra tokens at end of #%s directive",
pfile->directive->name);
}
@@ -337,11 +341,20 @@ prepare_directive_trad (cpp_reader *pfile)
static void
directive_diagnostics (cpp_reader *pfile, const directive *dir, int indented)
{
- /* Issue -pedantic warnings for extensions. */
- if (CPP_PEDANTIC (pfile)
- && ! pfile->state.skipping
- && dir->origin == EXTENSION)
- cpp_error (pfile, CPP_DL_PEDWARN, "#%s is a GCC extension", dir->name);
+ /* Issue -pedantic or deprecated warnings for extensions. We let
+ -pedantic take precedence if both are applicable. */
+ if (! pfile->state.skipping)
+ {
+ if (dir->origin == EXTENSION
+ && !(dir == &dtable[T_IMPORT] && CPP_OPTION (pfile, objc))
+ && CPP_PEDANTIC (pfile))
+ cpp_error (pfile, CPP_DL_PEDWARN, "#%s is a GCC extension", dir->name);
+ else if (((dir->flags & DEPRECATED) != 0
+ || (dir == &dtable[T_IMPORT] && !CPP_OPTION (pfile, objc)))
+ && CPP_OPTION (pfile, warn_deprecated))
+ cpp_error (pfile, CPP_DL_WARNING, "#%s is a deprecated GCC extension",
+ dir->name);
+ }
/* Traditionally, a directive is ignored unless its # is in
column 1. Therefore in code intended to work with K+R
@@ -424,8 +437,13 @@ _cpp_handle_directive (cpp_reader *pfile, int indented)
does not cause '#define foo bar' to get executed when
compiled with -save-temps, we recognize directives in
-fpreprocessed mode only if the # is in column 1. macro.c
- puts a space in front of any '#' at the start of a macro. */
+ puts a space in front of any '#' at the start of a macro.
+
+ We exclude the -fdirectives-only case because macro expansion
+ has not been performed yet, and block comments can cause spaces
+ to preceed the directive. */
if (CPP_OPTION (pfile, preprocessed)
+ && !CPP_OPTION (pfile, directives_only)
&& (indented || !(dir->flags & IN_I)))
{
skip = 0;
@@ -470,7 +488,7 @@ _cpp_handle_directive (cpp_reader *pfile, int indented)
_cpp_backup_tokens (pfile, 1);
end_directive (pfile, skip);
- if (was_parsing_args)
+ if (was_parsing_args && !pfile->state.in_deferred_pragma)
{
/* Restore state when within macro args. */
pfile->state.parsing_args = 2;
@@ -554,9 +572,14 @@ do_define (cpp_reader *pfile)
pfile->state.save_comments =
! CPP_OPTION (pfile, discard_comments_in_macro_exp);
+ if (pfile->cb.before_define)
+ pfile->cb.before_define (pfile);
+
if (_cpp_create_definition (pfile, node))
if (pfile->cb.define)
pfile->cb.define (pfile, pfile->directive_line, node);
+
+ node->flags &= ~NODE_USED;
}
}
@@ -568,6 +591,9 @@ do_undef (cpp_reader *pfile)
if (node)
{
+ if (pfile->cb.before_define)
+ pfile->cb.before_define (pfile);
+
if (pfile->cb.undef)
pfile->cb.undef (pfile, pfile->directive_line, node);
@@ -586,7 +612,7 @@ do_undef (cpp_reader *pfile)
}
}
- check_eol (pfile);
+ check_eol (pfile, false);
}
/* Undefine a single macro/assertion/whatever. */
@@ -598,7 +624,7 @@ undefine_macros (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *h,
/* Body of _cpp_free_definition inlined here for speed.
Macros and assertions no longer have anything to free. */
h->type = NT_VOID;
- h->flags &= ~(NODE_POISONED|NODE_BUILTIN|NODE_DISABLED);
+ h->flags &= ~(NODE_POISONED|NODE_BUILTIN|NODE_DISABLED|NODE_USED);
return 1;
}
@@ -684,7 +710,7 @@ parse_include (cpp_reader *pfile, int *pangle_brackets,
const unsigned char *dir;
if (pfile->directive == &dtable[T_PRAGMA])
- dir = U"pragma dependency";
+ dir = UC"pragma dependency";
else
dir = pfile->directive->name;
cpp_error (pfile, CPP_DL_ERROR, "#%s expects \"FILENAME\" or ",
@@ -693,8 +719,12 @@ parse_include (cpp_reader *pfile, int *pangle_brackets,
return NULL;
}
- if (buf == NULL || CPP_OPTION (pfile, discard_comments))
- check_eol (pfile);
+ if (pfile->directive == &dtable[T_PRAGMA])
+ {
+ /* This pragma allows extra tokens after the file name. */
+ }
+ else if (buf == NULL || CPP_OPTION (pfile, discard_comments))
+ check_eol (pfile, true);
else
{
/* If we are not discarding comments, then gather them while
@@ -810,23 +840,30 @@ read_flag (cpp_reader *pfile, unsigned int last)
}
/* Subroutine of do_line and do_linemarker. Convert a number in STR,
- of length LEN, to binary; store it in NUMP, and return 0 if the
- number was well-formed, 1 if not. Temporary, hopefully. */
-static int
-strtoul_for_line (const uchar *str, unsigned int len, long unsigned int *nump)
+ of length LEN, to binary; store it in NUMP, and return false if the
+ number was well-formed, true if not. WRAPPED is set to true if the
+ number did not fit into 'unsigned long'. */
+static bool
+strtolinenum (const uchar *str, size_t len, linenum_type *nump, bool *wrapped)
{
- unsigned long reg = 0;
+ linenum_type reg = 0;
+ linenum_type reg_prev = 0;
+
uchar c;
+ *wrapped = false;
while (len--)
{
c = *str++;
if (!ISDIGIT (c))
- return 1;
+ return true;
reg *= 10;
reg += c - '0';
+ if (reg < reg_prev)
+ *wrapped = true;
+ reg_prev = reg;
}
*nump = reg;
- return 0;
+ return false;
}
/* Interpret #line command.
@@ -844,25 +881,31 @@ do_line (cpp_reader *pfile)
unsigned char map_sysp = map->sysp;
const cpp_token *token;
const char *new_file = map->to_file;
- unsigned long new_lineno;
+ linenum_type new_lineno;
/* C99 raised the minimum limit on #line numbers. */
- unsigned int cap = CPP_OPTION (pfile, c99) ? 2147483647 : 32767;
+ linenum_type cap = CPP_OPTION (pfile, c99) ? 2147483647 : 32767;
+ bool wrapped;
/* #line commands expand macros. */
token = cpp_get_token (pfile);
if (token->type != CPP_NUMBER
- || strtoul_for_line (token->val.str.text, token->val.str.len,
- &new_lineno))
+ || strtolinenum (token->val.str.text, token->val.str.len,
+ &new_lineno, &wrapped))
{
- cpp_error (pfile, CPP_DL_ERROR,
- "\"%s\" after #line is not a positive integer",
- cpp_token_as_text (pfile, token));
+ if (token->type == CPP_EOF)
+ cpp_error (pfile, CPP_DL_ERROR, "unexpected end of file after #line");
+ else
+ 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))
+ if (CPP_PEDANTIC (pfile) && (new_lineno == 0 || new_lineno > cap || wrapped))
cpp_error (pfile, CPP_DL_PEDWARN, "line number out of range");
+ else if (wrapped)
+ cpp_error (pfile, CPP_DL_WARNING, "line number out of range");
token = cpp_get_token (pfile);
if (token->type == CPP_STRING)
@@ -871,7 +914,7 @@ do_line (cpp_reader *pfile)
if (cpp_interpret_string_notranslate (pfile, &token->val.str, 1,
&s, false))
new_file = (const char *)s.text;
- check_eol (pfile);
+ check_eol (pfile, true);
}
else if (token->type != CPP_EOF)
{
@@ -881,7 +924,7 @@ do_line (cpp_reader *pfile)
}
skip_rest_of_line (pfile);
- _cpp_do_file_change (pfile, LC_RENAME, new_file, new_lineno,
+ _cpp_do_file_change (pfile, LC_RENAME_VERBATIM, new_file, new_lineno,
map_sysp);
}
@@ -895,10 +938,11 @@ do_linemarker (cpp_reader *pfile)
const struct line_map *map = &line_table->maps[line_table->used - 1];
const cpp_token *token;
const char *new_file = map->to_file;
- unsigned long new_lineno;
+ linenum_type new_lineno;
unsigned int new_sysp = map->sysp;
- enum lc_reason reason = LC_RENAME;
+ enum lc_reason reason = LC_RENAME_VERBATIM;
int flag;
+ bool wrapped;
/* Back up so we can get the number again. Putting this in
_cpp_handle_directive risks two calls to _cpp_backup_tokens in
@@ -908,9 +952,11 @@ do_linemarker (cpp_reader *pfile)
/* #line commands expand macros. */
token = cpp_get_token (pfile);
if (token->type != CPP_NUMBER
- || strtoul_for_line (token->val.str.text, token->val.str.len,
- &new_lineno))
+ || strtolinenum (token->val.str.text, token->val.str.len,
+ &new_lineno, &wrapped))
{
+ /* Unlike #line, there does not seem to be a way to get an EOF
+ here. So, it should be safe to always spell the token. */
cpp_error (pfile, CPP_DL_ERROR,
"\"%s\" after # is not a positive integer",
cpp_token_as_text (pfile, token));
@@ -948,7 +994,7 @@ do_linemarker (cpp_reader *pfile)
}
pfile->buffer->sysp = new_sysp;
- check_eol (pfile);
+ check_eol (pfile, false);
}
else if (token->type != CPP_EOF)
{
@@ -967,7 +1013,7 @@ do_linemarker (cpp_reader *pfile)
and zero otherwise. */
void
_cpp_do_file_change (cpp_reader *pfile, enum lc_reason reason,
- const char *to_file, unsigned int file_line,
+ const char *to_file, linenum_type file_line,
unsigned int sysp)
{
const struct line_map *map = linemap_add (pfile->line_table, reason, sysp,
@@ -984,14 +1030,20 @@ _cpp_do_file_change (cpp_reader *pfile, enum lc_reason reason,
static void
do_diagnostic (cpp_reader *pfile, int code, int print_dir)
{
- if (_cpp_begin_message (pfile, code, pfile->cur_token[-1].src_loc, 0))
- {
- if (print_dir)
- fprintf (stderr, "#%s ", pfile->directive->name);
- pfile->state.prevent_expansion++;
- cpp_output_line (pfile, stderr);
- pfile->state.prevent_expansion--;
- }
+ const unsigned char *dir_name;
+ unsigned char *line;
+ source_location src_loc = pfile->cur_token[-1].src_loc;
+
+ if (print_dir)
+ dir_name = pfile->directive->name;
+ else
+ dir_name = NULL;
+ pfile->state.prevent_expansion++;
+ line = cpp_output_line_to_string (pfile, dir_name);
+ pfile->state.prevent_expansion--;
+
+ cpp_error_with_line (pfile, code, src_loc, 0, "%s", line);
+ free (line);
}
static void
@@ -1019,7 +1071,7 @@ do_ident (cpp_reader *pfile)
else if (pfile->cb.ident)
pfile->cb.ident (pfile, pfile->directive_line, &str->val.str);
- check_eol (pfile);
+ check_eol (pfile, false);
}
/* Lookup a PRAGMA name in a singly-linked CHAIN. Returns the
@@ -1063,7 +1115,7 @@ register_pragma_1 (cpp_reader *pfile, const char *space, const char *name,
if (space)
{
- node = cpp_lookup (pfile, U space, strlen (space));
+ node = cpp_lookup (pfile, UC space, strlen (space));
entry = lookup_pragma_entry (*chain, node);
if (!entry)
{
@@ -1092,7 +1144,7 @@ register_pragma_1 (cpp_reader *pfile, const char *space, const char *name,
}
/* Check for duplicates. */
- node = cpp_lookup (pfile, U name, strlen (name));
+ node = cpp_lookup (pfile, UC name, strlen (name));
entry = lookup_pragma_entry (*chain, node);
if (entry == NULL)
{
@@ -1240,7 +1292,7 @@ restore_registered_pragmas (cpp_reader *pfile, struct pragma_entry *pe,
{
if (pe->is_nspace)
sd = restore_registered_pragmas (pfile, pe->u.space, sd);
- pe->pragma = cpp_lookup (pfile, U *sd, strlen (*sd));
+ pe->pragma = cpp_lookup (pfile, UC *sd, strlen (*sd));
free (*sd);
sd++;
}
@@ -1352,7 +1404,7 @@ do_pragma_once (cpp_reader *pfile)
if (cpp_in_primary_file (pfile))
cpp_error (pfile, CPP_DL_WARNING, "#pragma once in main file");
- check_eol (pfile);
+ check_eol (pfile, false);
_cpp_mark_file_once_only (pfile, pfile->buffer->file);
}
@@ -1404,7 +1456,7 @@ do_pragma_system_header (cpp_reader *pfile)
"#pragma system_header ignored outside include file");
else
{
- check_eol (pfile);
+ check_eol (pfile, false);
skip_rest_of_line (pfile);
cpp_make_system_header (pfile, 1, 0);
}
@@ -1458,15 +1510,25 @@ static const cpp_token *
get__Pragma_string (cpp_reader *pfile)
{
const cpp_token *string;
+ const cpp_token *paren;
- if (get_token_no_padding (pfile)->type != CPP_OPEN_PAREN)
+ paren = get_token_no_padding (pfile);
+ if (paren->type == CPP_EOF)
+ _cpp_backup_tokens (pfile, 1);
+ if (paren->type != CPP_OPEN_PAREN)
return NULL;
string = get_token_no_padding (pfile);
- if (string->type != CPP_STRING && string->type != CPP_WSTRING)
+ if (string->type == CPP_EOF)
+ _cpp_backup_tokens (pfile, 1);
+ if (string->type != CPP_STRING && string->type != CPP_WSTRING
+ && string->type != CPP_STRING32 && string->type != CPP_STRING16)
return NULL;
- if (get_token_no_padding (pfile)->type != CPP_CLOSE_PAREN)
+ paren = get_token_no_padding (pfile);
+ if (paren->type == CPP_EOF)
+ _cpp_backup_tokens (pfile, 1);
+ if (paren->type != CPP_CLOSE_PAREN)
return NULL;
return string;
@@ -1484,6 +1546,7 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in)
tokenrun *saved_cur_run;
cpp_token *toks;
int count;
+ const struct directive *save_directive;
dest = result = (char *) alloca (in->len - 1);
src = in->text + 1 + (in->text[0] == 'L');
@@ -1524,8 +1587,11 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in)
start_directive (pfile);
_cpp_clean_line (pfile);
+ save_directive = pfile->directive;
+ pfile->directive = &dtable[T_PRAGMA];
do_pragma (pfile);
end_directive (pfile, 1);
+ pfile->directive = save_directive;
/* We always insert at least one token, the directive result. It'll
either be a CPP_PADDING or a CPP_PRAGMA. In the later case, we
@@ -1586,18 +1652,21 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in)
_cpp_push_token_context (pfile, NULL, toks, count);
}
-/* Handle the _Pragma operator. */
-void
+/* Handle the _Pragma operator. Return 0 on error, 1 if ok. */
+int
_cpp_do__Pragma (cpp_reader *pfile)
{
const cpp_token *string = get__Pragma_string (pfile);
pfile->directive_result.type = CPP_PADDING;
if (string)
- destringize_and_run (pfile, &string->val.str);
- else
- cpp_error (pfile, CPP_DL_ERROR,
- "_Pragma takes a parenthesized string literal");
+ {
+ destringize_and_run (pfile, &string->val.str);
+ return 1;
+ }
+ cpp_error (pfile, CPP_DL_ERROR,
+ "_Pragma takes a parenthesized string literal");
+ return 0;
}
/* Handle #ifdef. */
@@ -1608,13 +1677,27 @@ do_ifdef (cpp_reader *pfile)
if (! pfile->state.skipping)
{
- const cpp_hashnode *node = lex_macro_node (pfile, false);
+ cpp_hashnode *node = lex_macro_node (pfile, false);
if (node)
{
skip = node->type != NT_MACRO;
_cpp_mark_macro_used (node);
- check_eol (pfile);
+ if (!(node->flags & NODE_USED))
+ {
+ node->flags |= NODE_USED;
+ if (node->type == NT_MACRO)
+ {
+ if (pfile->cb.used_define)
+ pfile->cb.used_define (pfile, pfile->directive_line, node);
+ }
+ else
+ {
+ if (pfile->cb.used_undef)
+ pfile->cb.used_undef (pfile, pfile->directive_line, node);
+ }
+ }
+ check_eol (pfile, false);
}
}
@@ -1626,7 +1709,7 @@ static void
do_ifndef (cpp_reader *pfile)
{
int skip = 1;
- const cpp_hashnode *node = 0;
+ cpp_hashnode *node = 0;
if (! pfile->state.skipping)
{
@@ -1636,7 +1719,21 @@ do_ifndef (cpp_reader *pfile)
{
skip = node->type == NT_MACRO;
_cpp_mark_macro_used (node);
- check_eol (pfile);
+ if (!(node->flags & NODE_USED))
+ {
+ node->flags |= NODE_USED;
+ if (node->type == NT_MACRO)
+ {
+ if (pfile->cb.used_define)
+ pfile->cb.used_define (pfile, pfile->directive_line, node);
+ }
+ else
+ {
+ if (pfile->cb.used_undef)
+ pfile->cb.used_undef (pfile, pfile->directive_line, node);
+ }
+ }
+ check_eol (pfile, false);
}
}
@@ -1654,7 +1751,7 @@ do_if (cpp_reader *pfile)
int skip = 1;
if (! pfile->state.skipping)
- skip = _cpp_parse_expr (pfile) == false;
+ skip = _cpp_parse_expr (pfile, true) == false;
push_conditional (pfile, skip, T_IF, pfile->mi_ind_cmacro);
}
@@ -1689,7 +1786,7 @@ do_else (cpp_reader *pfile)
/* Only check EOL if was not originally skipping. */
if (!ifs->was_skipping && CPP_OPTION (pfile, warn_endif_labels))
- check_eol (pfile);
+ check_eol (pfile, false);
}
}
@@ -1713,15 +1810,23 @@ do_elif (cpp_reader *pfile)
}
ifs->type = T_ELIF;
- /* Only evaluate this if we aren't skipping elses. During
- evaluation, set skipping to false to get lexer warnings. */
- if (ifs->skip_elses)
- pfile->state.skipping = 1;
- else
+ if (! ifs->was_skipping)
{
+ bool value;
+ /* The standard mandates that the expression be parsed even
+ if we are skipping elses at this point -- the lexical
+ restrictions on #elif only apply to skipped groups, but
+ this group is not being skipped. Temporarily set
+ skipping to false to get lexer warnings. */
pfile->state.skipping = 0;
- pfile->state.skipping = ! _cpp_parse_expr (pfile);
- ifs->skip_elses = ! pfile->state.skipping;
+ value = _cpp_parse_expr (pfile, false);
+ if (ifs->skip_elses)
+ pfile->state.skipping = 1;
+ else
+ {
+ pfile->state.skipping = ! value;
+ ifs->skip_elses = value;
+ }
}
/* Invalidate any controlling macro. */
@@ -1742,7 +1847,7 @@ do_endif (cpp_reader *pfile)
{
/* Only check EOL if was not originally skipping. */
if (!ifs->was_skipping && CPP_OPTION (pfile, warn_endif_labels))
- check_eol (pfile);
+ check_eol (pfile, false);
/* If potential control macro, we go back outside again. */
if (ifs->next == 0 && ifs->mi_cmacro)
@@ -1986,7 +2091,7 @@ do_assert (cpp_reader *pfile)
node->type = NT_ASSERTION;
node->value.answers = new_answer;
- check_eol (pfile);
+ check_eol (pfile, false);
}
}
@@ -2014,7 +2119,7 @@ do_unassert (cpp_reader *pfile)
if (node->value.answers == 0)
node->type = NT_VOID;
- check_eol (pfile);
+ check_eol (pfile, false);
}
else
_cpp_free_definition (node);
@@ -2056,6 +2161,26 @@ cpp_define (cpp_reader *pfile, const char *str)
run_directive (pfile, T_DEFINE, buf, count);
}
+
+/* Use to build macros to be run through cpp_define() as
+ described above.
+ Example: cpp_define_formatted (pfile, "MACRO=%d", value); */
+
+void
+cpp_define_formatted (cpp_reader *pfile, const char *fmt, ...)
+{
+ char *ptr = NULL;
+
+ va_list ap;
+ va_start (ap, fmt);
+ vasprintf (&ptr, fmt, ap);
+ va_end (ap);
+
+ cpp_define (pfile, ptr);
+ free (ptr);
+}
+
+
/* Slight variant of the above for use by initialize_builtins. */
void
_cpp_define_builtin (cpp_reader *pfile, const char *str)
@@ -2115,6 +2240,9 @@ cpp_pop_definition (cpp_reader *pfile, const char *str, cpp_macro *dfn)
if (node == NULL)
return;
+ if (pfile->cb.before_define)
+ pfile->cb.before_define (pfile);
+
if (node->type == NT_MACRO)
{
if (pfile->cb.undef)
@@ -2174,13 +2302,6 @@ handle_assertion (cpp_reader *pfile, const char *str, int type)
run_directive (pfile, type, str, count);
}
-/* The number of errors for a given reader. */
-unsigned int
-cpp_errors (cpp_reader *pfile)
-{
- return pfile->errors;
-}
-
/* The options structure. */
cpp_options *
cpp_get_options (cpp_reader *pfile)