This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch] __TIMESTAMP__ predefined macro
- From: Grigory Zagorodnev <grigory_zagorodnev at linux dot intel dot com>
- To: Andrew Pinski <pinskia at physics dot uc dot edu>
- Cc: gcc-patches at gcc dot gnu dot org, "H. J. Lu" <hjl at lucon dot org>, martin at dalecki dot de, drow at false dot org
- Date: Thu, 16 Feb 2006 21:56:11 +0300
- Subject: Re: [patch] __TIMESTAMP__ predefined macro
- References: <200602151439.k1FEdvV0015024@earth.phy.uc.edu>
Hi!
There is the updated patch that respects all comments, including use of
asctime(localtime()) instead of spelling out the string. Would you take
a look, please?
Verified at x86_64-redhat-linux-gnu.
- Grigory
2006-02-16 Grigory Zagorodnev <grigory_zagorodnev@linux.intel.com>
gcc/ChangeLog:
* doc/cpp.texi (__TIMESTAMP__): Document.
libcpp/ChangeLog:
* macro.c (_cpp_builtin_macro_text): Handle BT_TIMESTAMP.
* files.c (_cpp_get_file_stat): New function.
* include/cpplib.h (builtin_type): Add BT_TIMESTAMP.
* init.c (builtin_array): Add support for __TIMESTAMP__/BT_TIMESTAMP.
* internal.h (_cpp_get_file_stat): Prototype.
(struct cpp_buffer): Add timestamp.
gcc/testsuite/ChangeLog:
* gcc.dg/cpp/undef3.c: New test.
* gcc.dg/cpp/trad/builtins2.c: New test.
diff -rup src.org/gcc/doc/cpp.texi src/gcc/doc/cpp.texi
--- src.org/gcc/doc/cpp.texi 2006-02-16 17:55:22.000000000 +0300
+++ src/gcc/doc/cpp.texi 2006-02-16 19:13:16.000000000 +0300
@@ -2128,6 +2128,17 @@ use.
This macro is defined, with value 2, when @option{-fstack-protector-all} is
in use.
+@item __TIMESTAMP__
+This macro expands to a string constant that describes the date and time
+of the last modification of the current source file. The string constant
+contains abbreviated day of the week, month, day of the month, time in
+hh:mm:ss form, year and looks like @code{@w{"Sun Sep 16 01:03:52 1973"}}.
+If the day of the month is less than 10, it is padded with a space on the left.
+
+If GCC cannot determine the current date, it will emit a warning message
+(once per compilation) and @code{__TIMESTAMP__} will expand to
+@code{@w{"??? ??? ?? ??:??:?? ????"}}.
+
@end table
@node System-specific Predefined Macros
diff -rup src.org/gcc/testsuite/gcc.dg/cpp/trad/builtins2.c src/gcc/testsuite/gcc.dg/cpp/trad/builtins2.c
--- src.org/gcc/testsuite/gcc.dg/cpp/trad/builtins2.c 2006-02-16 19:15:14.000000000 +0300
+++ src/gcc/testsuite/gcc.dg/cpp/trad/builtins2.c 2006-02-16 13:09:59.000000000 +0300
@@ -0,0 +1,7 @@
+/* Test that __TIMESTAMP__ builtin-macro is OK. */
+
+/* { dg-do preprocess } */
+
+#if !defined (__TIMESTAMP__)
+# error __TIMESTAMP__ /* { dg-bogus "__TIMESTAMP__" } */
+#endif
diff -rup src.org/gcc/testsuite/gcc.dg/cpp/undef3.c src/gcc/testsuite/gcc.dg/cpp/undef3.c
--- src.org/gcc/testsuite/gcc.dg/cpp/undef3.c 2006-02-16 19:15:56.000000000 +0300
+++ src/gcc/testsuite/gcc.dg/cpp/undef3.c 2006-02-16 13:04:40.000000000 +0300
@@ -0,0 +1,8 @@
+/* C99 6.10.8 para 4: None of [the predefined macro names] shall be
+ the subject of a #define or an #undef preprocessing directive. We
+ pass -fno-show-column as otherwise dejagnu gets confused. */
+
+/* { dg-do preprocess } */
+/* { dg-options "-fno-show-column" } */
+
+#undef __TIMESTAMP__ /* { dg-warning "undefining" "__TIMESTAMP__" } */
diff -rup src.org/libcpp/files.c src/libcpp/files.c
--- src.org/libcpp/files.c 2006-02-16 17:52:55.000000000 +0300
+++ src/libcpp/files.c 2006-02-16 19:13:16.000000000 +0300
@@ -1147,6 +1147,13 @@ _cpp_pop_file_buffer (cpp_reader *pfile,
}
}
+/* Inteface to file statistics record in _cpp_file structure. */
+struct stat *
+_cpp_get_file_stat (_cpp_file *file)
+{
+ return &file->st;
+}
+
/* Set the include chain for "" to QUOTE, for <> to BRACKET. If
QUOTE_IGNORES_SOURCE_DIR, then "" includes do not look in the
directory of the including file.
diff -rup src.org/libcpp/include/cpplib.h src/libcpp/include/cpplib.h
--- src.org/libcpp/include/cpplib.h 2006-02-16 17:52:55.000000000 +0300
+++ src/libcpp/include/cpplib.h 2006-02-16 19:13:16.000000000 +0300
@@ -555,7 +555,8 @@ enum builtin_type
BT_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */
BT_TIME, /* `__TIME__' */
BT_STDC, /* `__STDC__' */
- BT_PRAGMA /* `_Pragma' operator */
+ BT_PRAGMA, /* `_Pragma' operator */
+ BT_TIMESTAMP /* `__TIMESTAMP__' */
};
#define CPP_HASHNODE(HNODE) ((cpp_hashnode *) (HNODE))
diff -rup src.org/libcpp/init.c src/libcpp/init.c
--- src.org/libcpp/init.c 2006-02-16 17:52:55.000000000 +0300
+++ src/libcpp/init.c 2006-02-16 19:13:16.000000000 +0300
@@ -301,6 +301,7 @@ struct builtin
#define B(n, t) { DSC(n), t }
static const struct builtin builtin_array[] =
{
+ B("__TIMESTAMP__", BT_TIMESTAMP),
B("__TIME__", BT_TIME),
B("__DATE__", BT_DATE),
B("__FILE__", BT_FILE),
diff -rup src.org/libcpp/internal.h src/libcpp/internal.h
--- src.org/libcpp/internal.h 2006-02-16 17:52:55.000000000 +0300
+++ src/libcpp/internal.h 2006-02-16 19:13:16.000000000 +0300
@@ -264,6 +264,10 @@ struct cpp_buffer
Used for include_next and to record control macros. */
struct _cpp_file *file;
+ /* Saved value of __TIMESTAMP__ macro - date and time of last modification
+ of the assotiated file. */
+ const unsigned char *timestamp;
+
/* Value of if_stack at start of this file.
Used to prohibit unmatched #endif (etc) in an include file. */
struct if_stack *if_stack;
@@ -524,6 +528,7 @@ extern void _cpp_cleanup_files (cpp_read
extern void _cpp_pop_file_buffer (cpp_reader *, struct _cpp_file *);
extern bool _cpp_save_file_entries (cpp_reader *pfile, FILE *f);
extern bool _cpp_read_file_entries (cpp_reader *, FILE *);
+extern struct stat *_cpp_get_file_stat (_cpp_file *);
/* In expr.c */
extern bool _cpp_parse_expr (cpp_reader *);
diff -rup src.org/libcpp/macro.c src/libcpp/macro.c
--- src.org/libcpp/macro.c 2006-02-16 17:52:55.000000000 +0300
+++ src/libcpp/macro.c 2006-02-16 20:04:28.000000000 +0300
@@ -123,6 +123,44 @@ _cpp_builtin_macro_text (cpp_reader *pfi
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:
{