]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - ftepp.c
Implemented __TIME_STAMP__ predef, expands to a timestamp of when the __FILE__ was...
[xonotic/gmqcc.git] / ftepp.c
diff --git a/ftepp.c b/ftepp.c
old mode 100644 (file)
new mode 100755 (executable)
index 233dee5..28db0d2
--- a/ftepp.c
+++ b/ftepp.c
@@ -22,6 +22,7 @@
  * SOFTWARE.
  */
 #include <time.h>
+#include <sys/stat.h>
 #include "gmqcc.h"
 #include "lexer.h"
 
@@ -82,7 +83,7 @@ static uint32_t ftepp_predef_randval  = 0;
 
 /* __DATE__ */
 char *ftepp_predef_date(lex_file *context) {
-    struct tm *itime;
+    struct tm *itime = NULL;
     time_t     rtime;
     char      *value = (char*)mem_a(82);
     /* 82 is enough for strftime but we also have " " in our string */
@@ -91,7 +92,12 @@ char *ftepp_predef_date(lex_file *context) {
 
     /* get time */
     time (&rtime);
+
+#ifdef _MSC_VER
+    localtime_s(itime, &rtime);
+#else
     itime = localtime(&rtime);
+#endif
 
     strftime(value, 82, "\"%b %d %Y\"", itime);
 
@@ -100,7 +106,7 @@ char *ftepp_predef_date(lex_file *context) {
 
 /* __TIME__ */
 char *ftepp_predef_time(lex_file *context) {
-    struct tm *itime;
+    struct tm *itime = NULL;
     time_t     rtime;
     char      *value = (char*)mem_a(82);
     /* 82 is enough for strftime but we also have " " in our string */
@@ -109,7 +115,12 @@ char *ftepp_predef_time(lex_file *context) {
 
     /* get time */
     time (&rtime);
+
+#ifdef _MSC_VER
+    localtime_s(itime, &rtime);
+#else
     itime = localtime(&rtime);
+#endif
 
     strftime(value, 82, "\"%X\"", itime);
 
@@ -126,7 +137,7 @@ char *ftepp_predef_line(lex_file *context) {
 char *ftepp_predef_file(lex_file *context) {
     size_t  length = strlen(context->name) + 3; /* two quotes and a terminator */
     char   *value  = (char*)mem_a(length);
-    snprintf(value, length, "\"%s\"", context->name);
+    util_snprintf(value, length, "\"%s\"", context->name);
 
     return value;
 }
@@ -164,6 +175,28 @@ char *ftepp_predef_randomlast(lex_file *context) {
     (void)context;
     return value;
 }
+/* __TIMESTAMP__ */
+char *ftepp_predef_timestamp(lex_file *context) {
+    struct stat finfo;
+    char       *find;
+    char       *value;
+    size_t      size;
+    if (stat(context->name, &finfo))
+        return util_strdup("\"<failed to determine timestamp>\"");
+
+    /*
+     * ctime and it's fucking annoying newline char, no worries, we're
+     * professionals here.
+     */   
+    find  = ctime(&finfo.st_mtime);
+    value = (char*)mem_a(strlen(find) + 1);
+    memcpy(&value[1], find, (size = strlen(find)) - 1);
+
+    value[0]    = '"';
+    value[size] = '"';
+
+    return value;
+}
 
 const ftepp_predef_t ftepp_predefs[FTEPP_PREDEF_COUNT] = {
     { "__LINE__",         &ftepp_predef_line        },
@@ -173,7 +206,8 @@ const ftepp_predef_t ftepp_predefs[FTEPP_PREDEF_COUNT] = {
     { "__RANDOM__",       &ftepp_predef_random      },
     { "__RANDOM_LAST__",  &ftepp_predef_randomlast  },
     { "__DATE__",         &ftepp_predef_date        },
-    { "__TIME__",         &ftepp_predef_time        }
+    { "__TIME__",         &ftepp_predef_time        },
+    { "__TIME_STAMP__",   &ftepp_predef_timestamp   }
 };
 
 #define ftepp_tokval(f) ((f)->lex->tok.value)
@@ -832,7 +866,7 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param
 
     if (resetline && !ftepp->in_macro) {
         char lineno[128];
-        snprintf(lineno, 128, "\n#pragma line(%lu)\n", (unsigned long)(old_lexer->sline));
+        util_snprintf(lineno, 128, "\n#pragma line(%lu)\n", (unsigned long)(old_lexer->sline));
         ftepp_out(ftepp, lineno, false);
     }
 
@@ -1432,7 +1466,7 @@ static bool ftepp_include(ftepp_t *ftepp)
 
     ftepp_out(ftepp, "\n#pragma file(", false);
     ftepp_out(ftepp, ctx.file, false);
-    snprintf(lineno, sizeof(lineno), ")\n#pragma line(%lu)\n", (unsigned long)(ctx.line+1));
+    util_snprintf(lineno, sizeof(lineno), ")\n#pragma line(%lu)\n", (unsigned long)(ctx.line+1));
     ftepp_out(ftepp, lineno, false);
 
     /* skip the line */
@@ -1797,12 +1831,12 @@ ftepp_t *ftepp_create()
         minor[2] = '"';
     } else if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_GMQCC) {
         ftepp_add_define(ftepp, NULL, "__STD_GMQCC__");
-        snprintf(major, 32, "\"%d\"", GMQCC_VERSION_MAJOR);
-        snprintf(minor, 32, "\"%d\"", GMQCC_VERSION_MINOR);
+        util_snprintf(major, 32, "\"%d\"", GMQCC_VERSION_MAJOR);
+        util_snprintf(minor, 32, "\"%d\"", GMQCC_VERSION_MINOR);
     } else if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_QCCX) {
         ftepp_add_define(ftepp, NULL, "__STD_QCCX__");
-        snprintf(major, 32, "\"%d\"", GMQCC_VERSION_MAJOR);
-        snprintf(minor, 32, "\"%d\"", GMQCC_VERSION_MINOR);
+        util_snprintf(major, 32, "\"%d\"", GMQCC_VERSION_MAJOR);
+        util_snprintf(minor, 32, "\"%d\"", GMQCC_VERSION_MINOR);
     } else if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_QCC) {
         ftepp_add_define(ftepp, NULL, "__STD_QCC__");
         /* 1.0 */
@@ -1818,6 +1852,12 @@ ftepp_t *ftepp_create()
     ftepp_add_macro(ftepp, "__STD_VERSION_MINOR__", minor);
     ftepp_add_macro(ftepp, "__STD_VERSION_MAJOR__", major);
 
+    /*
+     * We're going to just make __NULL__ nil, which works for 60% of the
+     * cases of __NULL_ for fteqcc.
+     */
+    ftepp_add_macro(ftepp, "__NULL__", "nil");
+
     return ftepp;
 }