X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=libcpp%2Fmacro.c;h=be50c111e32ed70a0d8088c55efa9cf7eea71f1f;hb=b64449a670af647182c674f1e9a6342827f72a1a;hp=729ea061b8bcf84970c9f94d2e5b51dd68349353;hpb=3b29876427e76f4cf4054a55c5cd6ad403ba61eb;p=pf3gnuchains%2Fgcc-fork.git diff --git a/libcpp/macro.c b/libcpp/macro.c index 729ea061b8b..be50c111e32 100644 --- a/libcpp/macro.c +++ b/libcpp/macro.c @@ -1,6 +1,6 @@ /* Part of CPP library. (Macro and #define handling.) Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1998, - 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Written by Per Bothner, 1994. Based on CCCP program by Paul Rubin, June 1986 Adapted to ANSI C, Richard Stallman, Jan 1987 @@ -17,7 +17,7 @@ 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. In other words, you are welcome to use, share and improve this program. You are forbidden to forbid anyone else to use, share and improve @@ -42,8 +42,6 @@ struct macro_arg static int enter_macro_context (cpp_reader *, cpp_hashnode *); static int builtin_macro (cpp_reader *, cpp_hashnode *); -static void push_token_context (cpp_reader *, cpp_hashnode *, - const cpp_token *, unsigned int); static void push_ptoken_context (cpp_reader *, cpp_hashnode *, _cpp_buff *, const cpp_token **, unsigned int); static _cpp_buff *collect_args (cpp_reader *, const cpp_hashnode *); @@ -109,10 +107,8 @@ static const char * const monthnames[] = "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; -/* Handle builtin macros like __FILE__, and push the resulting token - on the context stack. Also handles _Pragma, for which no new token - is created. Returns 1 if it generates a new token context, 0 to - return the token to the caller. */ +/* Helper function for builtin_macro. Returns the text generated by + a builtin macro. */ const uchar * _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node) { @@ -127,6 +123,44 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node) NODE_NAME (node)); break; + case BT_TIMESTAMP: + { + cpp_buffer *pbuffer = cpp_get_buffer (pfile); + if (pbuffer->timestamp == NULL) + { + /* Initialize timestamp value of the assotiated file. */ + struct _cpp_file *file = cpp_get_file (pbuffer); + if (file) + { + /* Generate __TIMESTAMP__ string, that represents + the date and time of the last modification + of the current source file. The string constant + looks like "Sun Sep 16 01:03:52 1973". */ + struct tm *tb = NULL; + struct stat *st = _cpp_get_file_stat (file); + if (st) + tb = localtime (&st->st_mtime); + if (tb) + { + char *str = asctime (tb); + size_t len = strlen (str); + unsigned char *buf = _cpp_unaligned_alloc (pfile, len + 2); + buf[0] = '"'; + strcpy ((char *) buf + 1, str); + buf[len] = '"'; + pbuffer->timestamp = buf; + } + else + { + cpp_errno (pfile, CPP_DL_WARNING, + "could not determine file timestamp"); + pbuffer->timestamp = U"\"??? ??? ?? ??:??:?? ????\""; + } + } + } + result = pbuffer->timestamp; + } + break; case BT_FILE: case BT_BASE_FILE: { @@ -141,7 +175,7 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node) name = map->to_file; len = strlen (name); - buf = _cpp_unaligned_alloc (pfile, len * 4 + 3); + buf = _cpp_unaligned_alloc (pfile, len * 2 + 3); result = buf; *buf = '"'; buf = cpp_quote_string (buf + 1, (const unsigned char *) name, len); @@ -173,16 +207,12 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node) However, if (a) we are in a system header, (b) the option stdc_0_in_system_headers is true (set by target config), and (c) we are not in strictly conforming mode, then it has the - value 0. */ + value 0. (b) and (c) are already checked in cpp_init_builtins. */ case BT_STDC: - { - if (cpp_in_system_header (pfile) - && CPP_OPTION (pfile, stdc_0_in_system_headers) - && !CPP_OPTION (pfile,std)) - number = 0; - else - number = 1; - } + if (cpp_in_system_header (pfile)) + number = 0; + else + number = 1; break; case BT_DATE: @@ -245,8 +275,8 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node) } /* Convert builtin macros like __FILE__ to a token and push it on the - context stack. Also handles _Pragma, for which no new token is - created. Returns 1 if it generates a new token context, 0 to + context stack. Also handles _Pragma, for which a new token may not + be created. Returns 1 if it generates a new token context, 0 to return the token to the caller. */ static int builtin_macro (cpp_reader *pfile, cpp_hashnode *node) @@ -268,7 +298,7 @@ builtin_macro (cpp_reader *pfile, cpp_hashnode *node) buf = _cpp_builtin_macro_text (pfile, node); len = ustrlen (buf); - nbuf = alloca (len + 1); + nbuf = (char *) alloca (len + 1); memcpy (nbuf, buf, len); nbuf[len]='\n'; @@ -277,7 +307,7 @@ builtin_macro (cpp_reader *pfile, cpp_hashnode *node) /* Set pfile->cur_token as required by _cpp_lex_direct. */ pfile->cur_token = _cpp_temp_token (pfile); - push_token_context (pfile, NULL, _cpp_lex_direct (pfile), 1); + _cpp_push_token_context (pfile, NULL, _cpp_lex_direct (pfile), 1); if (pfile->buffer->cur != pfile->buffer->rlimit) cpp_error (pfile, CPP_DL_ICE, "invalid built-in macro \"%s\"", NODE_NAME (node)); @@ -287,9 +317,8 @@ builtin_macro (cpp_reader *pfile, cpp_hashnode *node) } /* Copies SRC, of length LEN, to DEST, adding backslashes before all - backslashes and double quotes. Non-printable characters are - converted to octal. DEST must be of sufficient size. Returns - a pointer to the end of the string. */ + backslashes and double quotes. DEST must be of sufficient size. + Returns a pointer to the end of the string. */ uchar * cpp_quote_string (uchar *dest, const uchar *src, unsigned int len) { @@ -303,15 +332,7 @@ cpp_quote_string (uchar *dest, const uchar *src, unsigned int len) *dest++ = c; } else - { - if (ISPRINT (c)) - *dest++ = c; - else - { - sprintf ((char *) dest, "\\%03o", c); - dest += 4; - } - } + *dest++ = c; } return dest; @@ -375,12 +396,12 @@ stringify_arg (cpp_reader *pfile, macro_arg *arg) { _cpp_buff *buff = _cpp_get_buff (pfile, len); unsigned char *buf = BUFF_FRONT (buff); - len = cpp_spell_token (pfile, token, buf) - buf; + len = cpp_spell_token (pfile, token, buf, true) - buf; dest = cpp_quote_string (dest, buf, len); _cpp_release_buff (pfile, buff); } else - dest = cpp_spell_token (pfile, token, dest); + dest = cpp_spell_token (pfile, token, dest, true); if (token->type == CPP_OTHER && token->val.str.text[0] == '\\') backslash_count++; @@ -409,15 +430,14 @@ stringify_arg (cpp_reader *pfile, macro_arg *arg) static bool paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs) { - unsigned char *buf, *end; + unsigned char *buf, *end, *lhsend; const cpp_token *lhs; unsigned int len; - bool valid; lhs = *plhs; len = cpp_token_len (lhs) + cpp_token_len (rhs) + 1; - buf = alloca (len); - end = cpp_spell_token (pfile, lhs, buf); + buf = (unsigned char *) alloca (len); + end = lhsend = cpp_spell_token (pfile, lhs, buf, false); /* Avoid comment headers, since they are still processed in stage 3. It is simpler to insert a space here, rather than modifying the @@ -425,7 +445,7 @@ paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs) false doesn't work, since we want to clear the PASTE_LEFT flag. */ if (lhs->type == CPP_DIV && rhs->type != CPP_EQ) *end++ = ' '; - end = cpp_spell_token (pfile, rhs, end); + end = cpp_spell_token (pfile, rhs, end, false); *end = '\n'; cpp_push_buffer (pfile, buf, end - buf, /* from_stage3 */ true); @@ -434,10 +454,22 @@ paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs) /* Set pfile->cur_token as required by _cpp_lex_direct. */ pfile->cur_token = _cpp_temp_token (pfile); *plhs = _cpp_lex_direct (pfile); - valid = pfile->buffer->cur == pfile->buffer->rlimit; - _cpp_pop_buffer (pfile); + if (pfile->buffer->cur != pfile->buffer->rlimit) + { + _cpp_pop_buffer (pfile); + _cpp_backup_tokens (pfile, 1); + *lhsend = '\0'; + + /* Mandatory error for all apart from assembler. */ + if (CPP_OPTION (pfile, lang) != CLK_ASM) + cpp_error (pfile, CPP_DL_ERROR, + "pasting \"%s\" and \"%s\" does not give a valid preprocessing token", + buf, cpp_token_as_text (pfile, rhs)); + return false; + } - return valid; + _cpp_pop_buffer (pfile); + return true; } /* Handles an arbitrarily long sequence of ## operators, with initial @@ -469,22 +501,12 @@ paste_all_tokens (cpp_reader *pfile, const cpp_token *lhs) abort (); if (!paste_tokens (pfile, &lhs, rhs)) - { - _cpp_backup_tokens (pfile, 1); - - /* Mandatory error for all apart from assembler. */ - if (CPP_OPTION (pfile, lang) != CLK_ASM) - cpp_error (pfile, CPP_DL_ERROR, - "pasting \"%s\" and \"%s\" does not give a valid preprocessing token", - cpp_token_as_text (pfile, lhs), - cpp_token_as_text (pfile, rhs)); - break; - } + break; } while (rhs->flags & PASTE_LEFT); /* Put the resulting token in its own context. */ - push_token_context (pfile, NULL, lhs, 1); + _cpp_push_token_context (pfile, NULL, lhs, 1); } /* Returns TRUE if the number of arguments ARGC supplied in an @@ -698,7 +720,7 @@ funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node) too difficult. We re-insert it in its own context. */ _cpp_backup_tokens (pfile, 1); if (padding) - push_token_context (pfile, NULL, padding, 1); + _cpp_push_token_context (pfile, NULL, padding, 1); } return NULL; @@ -754,7 +776,7 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node) macro->used = 1; if (macro->paramc == 0) - push_token_context (pfile, node, macro->exp.tokens, macro->count); + _cpp_push_token_context (pfile, node, macro->exp.tokens, macro->count); return 1; } @@ -881,7 +903,7 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, macro_arg { cpp_token *token = _cpp_temp_token (pfile); token->type = (*paste_flag)->type; - token->val.str = (*paste_flag)->val.str; + token->val = (*paste_flag)->val; if (src->flags & PASTE_LEFT) token->flags = (*paste_flag)->flags | PASTE_LEFT; else @@ -905,7 +927,10 @@ padding_token (cpp_reader *pfile, const cpp_token *source) cpp_token *result = _cpp_temp_token (pfile); result->type = CPP_PADDING; - result->val.source = source; + + /* Data in GCed data structures cannot be made const so far, so we + need a cast here. */ + result->val.source = (cpp_token *) source; result->flags = 0; return result; } @@ -944,9 +969,9 @@ push_ptoken_context (cpp_reader *pfile, cpp_hashnode *macro, _cpp_buff *buff, } /* Push a list of tokens. */ -static void -push_token_context (cpp_reader *pfile, cpp_hashnode *macro, - const cpp_token *first, unsigned int count) +void +_cpp_push_token_context (cpp_reader *pfile, cpp_hashnode *macro, + const cpp_token *first, unsigned int count) { cpp_context *context = next_context (pfile); @@ -993,7 +1018,7 @@ expand_arg (cpp_reader *pfile, macro_arg *arg) /* Loop, reading in the arguments. */ capacity = 256; - arg->expanded = xmalloc (capacity * sizeof (cpp_token *)); + arg->expanded = XNEWVEC (const cpp_token *, capacity); push_ptoken_context (pfile, NULL, NULL, arg->first, arg->count + 1); for (;;) @@ -1003,8 +1028,8 @@ expand_arg (cpp_reader *pfile, macro_arg *arg) if (arg->expanded_count + 1 >= capacity) { capacity *= 2; - arg->expanded = xrealloc (arg->expanded, - capacity * sizeof (cpp_token *)); + arg->expanded = XRESIZEVEC (const cpp_token *, arg->expanded, + capacity); } token = cpp_get_token (pfile); @@ -1112,7 +1137,7 @@ cpp_get_token (cpp_reader *pfile) cpp_token *t = _cpp_temp_token (pfile); t->type = result->type; t->flags = result->flags | NO_EXPAND; - t->val.str = result->val.str; + t->val = result->val; result = t; } @@ -1156,7 +1181,7 @@ cpp_scan_nooutput (cpp_reader *pfile) pfile->state.prevent_expansion--; } -/* Step back one (or more) tokens. Can only step mack more than 1 if +/* Step back one (or more) tokens. Can only step back more than 1 if they are from the lexer, and not from macro expansion. */ void _cpp_backup_tokens (cpp_reader *pfile, unsigned int count) @@ -1264,7 +1289,8 @@ _cpp_save_parameter (cpp_reader *pfile, cpp_macro *macro, cpp_hashnode *node) len = macro->paramc * sizeof (union _cpp_hashnode_value); if (len > pfile->macro_buffer_len) { - pfile->macro_buffer = xrealloc (pfile->macro_buffer, len); + pfile->macro_buffer = XRESIZEVEC (unsigned char, pfile->macro_buffer, + len); pfile->macro_buffer_len = len; } ((union _cpp_hashnode_value *) pfile->macro_buffer)[macro->paramc - 1] @@ -1411,18 +1437,51 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro) /* Success. Commit or allocate the parameter array. */ if (pfile->hash_table->alloc_subobject) { - cpp_token *tokns = pfile->hash_table->alloc_subobject - (sizeof (cpp_token) * macro->paramc); - memcpy (tokns, macro->params, sizeof (cpp_token) * macro->paramc); - macro->params = tokns; + cpp_hashnode **params = + (cpp_hashnode **) pfile->hash_table->alloc_subobject + (sizeof (cpp_hashnode *) * macro->paramc); + memcpy (params, macro->params, + sizeof (cpp_hashnode *) * macro->paramc); + macro->params = params; } else BUFF_FRONT (pfile->a_buff) = (uchar *) ¯o->params[macro->paramc]; macro->fun_like = 1; } else if (ctoken->type != CPP_EOF && !(ctoken->flags & PREV_WHITE)) - cpp_error (pfile, CPP_DL_PEDWARN, - "ISO C requires whitespace after the macro name"); + { + /* While ISO C99 requires whitespace before replacement text + in a macro definition, ISO C90 with TC1 allows there characters + from the basic source character set. */ + if (CPP_OPTION (pfile, c99)) + cpp_error (pfile, CPP_DL_PEDWARN, + "ISO C99 requires whitespace after the macro name"); + else + { + int warntype = CPP_DL_WARNING; + switch (ctoken->type) + { + case CPP_ATSIGN: + case CPP_AT_NAME: + case CPP_OBJC_STRING: + /* '@' is not in basic character set. */ + warntype = CPP_DL_PEDWARN; + break; + case CPP_OTHER: + /* Basic character set sans letters, digits and _. */ + if (strchr ("!\"#%&'()*+,-./:;<=>?[\\]^{|}~", + ctoken->val.str.text[0]) == NULL) + warntype = CPP_DL_PEDWARN; + break; + default: + /* All other tokens start with a character from basic + character set. */ + break; + } + cpp_error (pfile, warntype, + "missing whitespace after the macro name"); + } + } if (macro->fun_like) token = lex_expansion_token (pfile, macro); @@ -1492,8 +1551,9 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro) /* Commit or allocate the memory. */ if (pfile->hash_table->alloc_subobject) { - cpp_token *tokns = pfile->hash_table->alloc_subobject (sizeof (cpp_token) - * macro->count); + cpp_token *tokns = + (cpp_token *) pfile->hash_table->alloc_subobject (sizeof (cpp_token) + * macro->count); memcpy (tokns, macro->exp.tokens, sizeof (cpp_token) * macro->count); macro->exp.tokens = tokns; } @@ -1512,7 +1572,8 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node) bool ok; if (pfile->hash_table->alloc_subobject) - macro = pfile->hash_table->alloc_subobject (sizeof (cpp_macro)); + macro = (cpp_macro *) pfile->hash_table->alloc_subobject + (sizeof (cpp_macro)); else macro = (cpp_macro *) _cpp_aligned_alloc (pfile, sizeof (cpp_macro)); macro->line = pfile->directive_line; @@ -1535,7 +1596,7 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node) /* Restore lexer position because of games lex_expansion_token() plays lexing the macro. We set the type for SEEN_EOL() in - cpplib.c. + directives.c. Longer term we should lex the whole line before coming here, and just copy the expansion. */ @@ -1657,6 +1718,7 @@ cpp_macro_definition (cpp_reader *pfile, const cpp_hashnode *node) len += NODE_LEN (macro->params[i]) + 1; /* "," */ } + /* This should match below where we fill in the buffer. */ if (CPP_OPTION (pfile, traditional)) len += _cpp_replacement_text_len (macro); else @@ -1668,17 +1730,21 @@ cpp_macro_definition (cpp_reader *pfile, const cpp_hashnode *node) if (token->type == CPP_MACRO_ARG) len += NODE_LEN (macro->params[token->val.arg_no - 1]); else - len += cpp_token_len (token) + 1; /* Includes room for ' '. */ + len += cpp_token_len (token); + if (token->flags & STRINGIFY_ARG) len++; /* "#" */ if (token->flags & PASTE_LEFT) len += 3; /* " ##" */ + if (token->flags & PREV_WHITE) + len++; /* " " */ } } if (len > pfile->macro_buffer_len) { - pfile->macro_buffer = xrealloc (pfile->macro_buffer, len); + pfile->macro_buffer = XRESIZEVEC (unsigned char, + pfile->macro_buffer, len); pfile->macro_buffer_len = len; } @@ -1732,13 +1798,13 @@ cpp_macro_definition (cpp_reader *pfile, const cpp_hashnode *node) if (token->type == CPP_MACRO_ARG) { - len = NODE_LEN (macro->params[token->val.arg_no - 1]); memcpy (buffer, - NODE_NAME (macro->params[token->val.arg_no - 1]), len); - buffer += len; + NODE_NAME (macro->params[token->val.arg_no - 1]), + NODE_LEN (macro->params[token->val.arg_no - 1])); + buffer += NODE_LEN (macro->params[token->val.arg_no - 1]); } else - buffer = cpp_spell_token (pfile, token, buffer); + buffer = cpp_spell_token (pfile, token, buffer, false); if (token->flags & PASTE_LEFT) {