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)