This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] __TIMESTAMP__ predefined macro
- From: Grigory Zagorodnev <grigory_zagorodnev at linux dot intel dot com>
- To: gcc-patches at gcc dot gnu dot org, "H. J. Lu" <hjl at lucon dot org>
- Date: Wed, 15 Feb 2006 16:52:56 +0300
- Subject: [patch] __TIMESTAMP__ predefined macro
Hi!
The patch implements __TIMESTAMP__ predefined macro in the form similar
to MSVC and ICC compilers - date and time of the last modification of
the current source file like "Thu Feb 9 18:07:36 2006". This macro
seems to be widely used but not implemented in GCC yet.
Verified at x86_64-redhat-linux-gnu.
Ok for mainline?
- Grigory
2006-02-15 Grigory Zagorodnev <grigory_zagorodnev@linux.intel.com>
* gcc/doc/cpp.texi: add description of __TIMESTAMP__ macro to the
user's documentation
* gcc/testsuite/gcc.dg/cpp/undef2.c: enlarge tests to cover new
predefined macro
* gcc/testsuite/gcc.dg/cpp/trad/builtins.c: same as above
* libcpp/macro.c (_cpp_builtin_macro_text): generate text for
__TIMESTAMP__ built-in macro
* libcpp/files.c (_cpp_get_file_stat): new function - interface to
file statistics record in _cpp_file structure.
* libcpp/include/cpplib.h: new constant to process __TIMESTAMP__
macro definition
* libcpp/init.c: new built in macro definition
* libcpp/internal.h: new declaration of _cpp_get_file_stat; new
field timestamp of cpp_buffer structure to hold generated string for
future possible reuse
Index: gcc/doc/cpp.texi
===================================================================
--- gcc/doc/cpp.texi (revision 110912)
+++ gcc/doc/cpp.texi (working copy)
@@ -2128,6 +2128,17 @@
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{"Thu Feb 9 18:07:36 2006"}}.
+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
Index: gcc/testsuite/gcc.dg/cpp/undef2.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/undef2.c (revision 110912)
+++ gcc/testsuite/gcc.dg/cpp/undef2.c (working copy)
@@ -10,6 +10,7 @@
#undef __FILE__ /* { dg-warning "undefining" "__FILE__" } */
#undef __LINE__ /* { dg-warning "undefining" "__LINE__" } */
#undef __STDC__ /* { dg-warning "undefining" "__STDC__" } */
+#undef __TIMESTAMP__ /* { dg-warning "undefining" "__TIMESTAMP__" } */
/* These should be protected from #undef, but aren't, because they
are set with normal #define commands - and on top of that, some
Index: gcc/testsuite/gcc.dg/cpp/trad/builtins.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/trad/builtins.c (revision 110912)
+++ gcc/testsuite/gcc.dg/cpp/trad/builtins.c (working copy)
@@ -35,6 +35,9 @@
# error __DATE__ /* { dg-bogus "__DATE__" } */
#endif
+#if !defined (__TIMESTAMP__)
+# error __TIMESTAMP__ /* { dg-bogus "__TIMESTAMP__" } */
+#endif
int main ()
{
Index: libcpp/macro.c
===================================================================
--- libcpp/macro.c (revision 110912)
+++ libcpp/macro.c (working copy)
@@ -107,6 +107,11 @@
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
+static const char * const daynames[] =
+{
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+};
+
/* Helper function for builtin_macro. Returns the text generated by
a builtin macro. */
const uchar *
@@ -123,6 +128,43 @@
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 "Thu Feb 9 18:07:36 2006". */
+ struct tm *tb = NULL;
+ struct stat *st = _cpp_get_file_stat(file);
+ if (st)
+ tb = localtime (&(st->st_mtime));
+ if (tb)
+ {
+ pbuffer->timestamp = _cpp_unaligned_alloc (pfile,
+ sizeof ("\"Thu Feb 9 18:07:36 2006\""));
+ sprintf ((char *)pbuffer->timestamp,
+ "\"%3s %3s %2d %02d:%02d:%02d %4d\"",
+ daynames[tb->tm_wday], monthnames[tb->tm_mon],
+ tb->tm_mday, tb->tm_hour, tb->tm_min,
+ tb->tm_sec, tb->tm_year + 1900);
+ }
+ 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:
{
Index: libcpp/files.c
===================================================================
--- libcpp/files.c (revision 110912)
+++ libcpp/files.c (working copy)
@@ -1147,6 +1147,13 @@
}
}
+/* 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.
Index: libcpp/include/cpplib.h
===================================================================
--- libcpp/include/cpplib.h (revision 110912)
+++ libcpp/include/cpplib.h (working copy)
@@ -555,7 +555,8 @@
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))
Index: libcpp/init.c
===================================================================
--- libcpp/init.c (revision 110912)
+++ libcpp/init.c (working copy)
@@ -301,6 +301,7 @@
#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),
Index: libcpp/internal.h
===================================================================
--- libcpp/internal.h (revision 110912)
+++ libcpp/internal.h (working copy)
@@ -264,6 +264,10 @@
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_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 *);