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]

Re: [patch] __TIMESTAMP__ predefined macro


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:
       {

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