X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=libcpp%2Fmacro.c;h=748635f408ed9cd9550c7f8061f5f735fa25ead3;hb=dd97b5e44d5287ad62c24e81cd2c3ee8a8b954b0;hp=2f1a97497a1a1f047336e266c327ac02bc0cd678;hpb=b75b98aa8366f8c69c546a6e0a8f0e7559540363;p=pf3gnuchains%2Fgcc-fork.git diff --git a/libcpp/macro.c b/libcpp/macro.c index 2f1a97497a1..748635f408e 100644 --- a/libcpp/macro.c +++ b/libcpp/macro.c @@ -1,6 +1,7 @@ /* 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, 2005 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005, + 2006 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 @@ -123,6 +124,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: { @@ -169,16 +208,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: @@ -396,21 +431,19 @@ 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; - const cpp_token *lhs; + unsigned char *buf, *end, *lhsend; + cpp_token *lhs; unsigned int len; - bool valid; - lhs = *plhs; - len = cpp_token_len (lhs) + cpp_token_len (rhs) + 1; + len = cpp_token_len (*plhs) + cpp_token_len (rhs) + 1; buf = (unsigned char *) alloca (len); - end = cpp_spell_token (pfile, lhs, buf, false); + end = lhsend = cpp_spell_token (pfile, *plhs, 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 lexer to ignore comments in some circumstances. Simply returning false doesn't work, since we want to clear the PASTE_LEFT flag. */ - if (lhs->type == CPP_DIV && rhs->type != CPP_EQ) + if ((*plhs)->type == CPP_DIV && rhs->type != CPP_EQ) *end++ = ' '; end = cpp_spell_token (pfile, rhs, end, false); *end = '\n'; @@ -420,11 +453,33 @@ 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); + lhs = _cpp_lex_direct (pfile); + if (pfile->buffer->cur != pfile->buffer->rlimit) + { + source_location saved_loc = lhs->src_loc; - return valid; + _cpp_pop_buffer (pfile); + _cpp_backup_tokens (pfile, 1); + *lhsend = '\0'; + + /* We have to remove the PASTE_LEFT flag from the old lhs, but + we want to keep the new location. */ + *lhs = **plhs; + *plhs = lhs; + lhs->src_loc = saved_loc; + lhs->flags &= ~PASTE_LEFT; + + /* 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; + } + + *plhs = lhs; + _cpp_pop_buffer (pfile); + return true; } /* Handles an arbitrarily long sequence of ## operators, with initial @@ -456,17 +511,7 @@ 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); @@ -1146,7 +1191,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) @@ -1363,10 +1408,12 @@ alloc_expansion_token (cpp_reader *pfile, cpp_macro *macro) static cpp_token * lex_expansion_token (cpp_reader *pfile, cpp_macro *macro) { - cpp_token *token; + cpp_token *token, *saved_cur_token; + saved_cur_token = pfile->cur_token; pfile->cur_token = alloc_expansion_token (pfile, macro); token = _cpp_lex_direct (pfile); + pfile->cur_token = saved_cur_token; /* Is this a parameter? */ if (token->type == CPP_NAME @@ -1555,18 +1602,12 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node) ok = _cpp_create_trad_definition (pfile, macro); else { - cpp_token *saved_cur_token = pfile->cur_token; - ok = create_iso_definition (pfile, macro); - /* Restore lexer position because of games lex_expansion_token() - plays lexing the macro. We set the type for SEEN_EOL() in - directives.c. + /* We set the type for SEEN_EOL() in directives.c. Longer term we should lex the whole line before coming here, and just copy the expansion. */ - saved_cur_token[-1].type = pfile->cur_token[-1].type; - pfile->cur_token = saved_cur_token; /* Stop the lexer accepting __VA_ARGS__. */ pfile->state.va_args_ok = 0;