This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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 *);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]