]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - ftepp.c
Revert "Smaller memory footprint, 4/8 bytes vs 12/24 for individual token lex_ctx...
[xonotic/gmqcc.git] / ftepp.c
diff --git a/ftepp.c b/ftepp.c
old mode 100755 (executable)
new mode 100644 (file)
index 7d5ba3e..d68eed4
--- a/ftepp.c
+++ b/ftepp.c
  * SOFTWARE.
  */
 #include <time.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
 #include "gmqcc.h"
 #include "lexer.h"
 
@@ -64,8 +68,7 @@ typedef struct ftepp_s {
     bool         output_on;
     ppcondition *conditions;
     /*ppmacro    **macros;*/
-    ht           macros; /* hashtable<string, ppmacro*> */
-
+    ht           macros;  /* hashtable<string, ppmacro*> */
     char        *output_string;
 
     char        *itemname;
@@ -81,7 +84,7 @@ static uint32_t ftepp_predef_countval = 0;
 static uint32_t ftepp_predef_randval  = 0;
 
 /* __DATE__ */
-char *ftepp_predef_date(lex_file *context) {
+static char *ftepp_predef_date(lex_file *context) {
     struct tm *itime = NULL;
     time_t     rtime;
     char      *value = (char*)mem_a(82);
@@ -104,7 +107,7 @@ char *ftepp_predef_date(lex_file *context) {
 }
 
 /* __TIME__ */
-char *ftepp_predef_time(lex_file *context) {
+static char *ftepp_predef_time(lex_file *context) {
     struct tm *itime = NULL;
     time_t     rtime;
     char      *value = (char*)mem_a(82);
@@ -127,13 +130,13 @@ char *ftepp_predef_time(lex_file *context) {
 }
 
 /* __LINE__ */
-char *ftepp_predef_line(lex_file *context) {
+static char *ftepp_predef_line(lex_file *context) {
     char   *value;
     util_asprintf(&value, "%d", (int)context->line);
     return value;
 }
 /* __FILE__ */
-char *ftepp_predef_file(lex_file *context) {
+static 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);
     util_snprintf(value, length, "\"%s\"", context->name);
@@ -141,7 +144,7 @@ char *ftepp_predef_file(lex_file *context) {
     return value;
 }
 /* __COUNTER_LAST__ */
-char *ftepp_predef_counterlast(lex_file *context) {
+static char *ftepp_predef_counterlast(lex_file *context) {
     char   *value;
     util_asprintf(&value, "%u", ftepp_predef_countval);
 
@@ -149,7 +152,7 @@ char *ftepp_predef_counterlast(lex_file *context) {
     return value;
 }
 /* __COUNTER__ */
-char *ftepp_predef_counter(lex_file *context) {
+static char *ftepp_predef_counter(lex_file *context) {
     char   *value;
     ftepp_predef_countval ++;
     util_asprintf(&value, "%u", ftepp_predef_countval);
@@ -158,7 +161,7 @@ char *ftepp_predef_counter(lex_file *context) {
     return value;
 }
 /* __RANDOM__ */
-char *ftepp_predef_random(lex_file *context) {
+static char *ftepp_predef_random(lex_file *context) {
     char  *value;
     ftepp_predef_randval = (util_rand() % 0xFF) + 1;
     util_asprintf(&value, "%u", ftepp_predef_randval);
@@ -167,15 +170,42 @@ char *ftepp_predef_random(lex_file *context) {
     return value;
 }
 /* __RANDOM_LAST__ */
-char *ftepp_predef_randomlast(lex_file *context) {
+static char *ftepp_predef_randomlast(lex_file *context) {
     char   *value;
     util_asprintf(&value, "%u", ftepp_predef_randval);
 
     (void)context;
     return value;
 }
+/* __TIMESTAMP__ */
+static 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>\"");
 
-const ftepp_predef_t ftepp_predefs[FTEPP_PREDEF_COUNT] = {
+    /*
+     * ctime and its 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;
+}
+
+typedef struct {
+    const char   *name;
+    char       *(*func)(lex_file *);
+} ftepp_predef_t;
+
+static const ftepp_predef_t ftepp_predefs[] = {
     { "__LINE__",         &ftepp_predef_line        },
     { "__FILE__",         &ftepp_predef_file        },
     { "__COUNTER__",      &ftepp_predef_counter     },
@@ -183,9 +213,29 @@ 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   }
 };
 
+static GMQCC_INLINE int ftepp_predef_index(const char *name) {
+    /* no hashtable here, we simply check for one to exist the naive way */
+    int i;
+    for(i = 0; i < (int)(sizeof(ftepp_predefs)/sizeof(*ftepp_predefs)); i++)
+        if (!strcmp(ftepp_predefs[i].name, name))
+            return i;
+    return -1;
+}
+
+bool ftepp_predef_exists(const char *name) {
+    return ftepp_predef_index(name) != -1;
+}
+
+/* singleton because we're allowed */
+static GMQCC_INLINE char *(*ftepp_predef(const char *name))(lex_file *context) {
+    int i = ftepp_predef_index(name);
+    return (i != -1) ? ftepp_predefs[i].func : NULL;
+}
+
 #define ftepp_tokval(f) ((f)->lex->tok.value)
 #define ftepp_ctx(f)    ((f)->lex->tok.ctx)
 
@@ -266,7 +316,7 @@ static void ppmacro_delete(ppmacro *self)
     mem_d(self);
 }
 
-static ftepp_t* ftepp_new()
+static ftepp_t* ftepp_new(void)
 {
     ftepp_t *ftepp;
 
@@ -327,7 +377,7 @@ static GMQCC_INLINE ppmacro* ftepp_macro_find(ftepp_t *ftepp, const char *name)
 
 static GMQCC_INLINE void ftepp_macro_delete(ftepp_t *ftepp, const char *name)
 {
-    util_htrm(ftepp->macros, name, NULL);
+    util_htrm(ftepp->macros, name, (void (*)(void*))&ppmacro_delete);
 }
 
 static GMQCC_INLINE int ftepp_next(ftepp_t *ftepp)
@@ -517,10 +567,6 @@ static bool ftepp_define(ftepp_t *ftepp)
         return false;
     }
 
-#if 0
-    if (ftepp->output_on)
-        vec_push(ftepp->macros, macro);
-#endif
     if (ftepp->output_on)
         util_htset(ftepp->macros, macro->name, (void*)macro);
     else {
@@ -578,7 +624,7 @@ static bool ftepp_macro_call_params(ftepp_t *ftepp, macroparam **out_params)
             ptok = pptoken_make(ftepp);
             vec_push(mp.tokens, ptok);
             if (ftepp_next(ftepp) >= TOKEN_EOF) {
-                ftepp_error(ftepp, "unexpected EOF in macro call");
+                ftepp_error(ftepp, "unexpected end of file in macro call");
                 goto on_error;
             }
         }
@@ -591,16 +637,10 @@ static bool ftepp_macro_call_params(ftepp_t *ftepp, macroparam **out_params)
             goto on_error;
         }
         if (ftepp_next(ftepp) >= TOKEN_EOF) {
-            ftepp_error(ftepp, "unexpected EOF in macro call");
+            ftepp_error(ftepp, "unexpected end of file in macro call");
             goto on_error;
         }
     }
-    /* need to leave that up
-    if (ftepp_next(ftepp) >= TOKEN_EOF) {
-        ftepp_error(ftepp, "unexpected EOF in macro call");
-        goto on_error;
-    }
-    */
     *out_params = params;
     return true;
 
@@ -1628,7 +1668,6 @@ static bool ftepp_preprocess(ftepp_t *ftepp)
 
     /* predef stuff */
     char    *expand  = NULL;
-    size_t   i;
 
     ftepp->lex->flags.preprocessing = true;
     ftepp->lex->flags.mergelines    = false;
@@ -1649,15 +1688,14 @@ static bool ftepp_preprocess(ftepp_t *ftepp)
             case TOKEN_TYPENAME:
                 /* is it a predef? */
                 if (OPTS_FLAG(FTEPP_PREDEFS)) {
-                    for (i = 0; i < sizeof(ftepp_predefs) / sizeof (*ftepp_predefs); i++) {
-                        if (!strcmp(ftepp_predefs[i].name, ftepp_tokval(ftepp))) {
-                            expand = ftepp_predefs[i].func(ftepp->lex);
-                            ftepp_out(ftepp, expand, false);
-                            ftepp_next(ftepp); /* skip */
-
-                            mem_d(expand); /* free memory */
-                            break;
-                        }
+                    char *(*predef)(lex_file*) = ftepp_predef(ftepp_tokval(ftepp));
+                    if (predef) {
+                        expand = predef(ftepp->lex);
+                        ftepp_out (ftepp, expand, false);
+                        ftepp_next(ftepp);
+
+                        mem_d(expand);
+                        break;
                     }
                 }
 
@@ -1840,7 +1878,7 @@ ftepp_t *ftepp_create()
 void ftepp_add_define(ftepp_t *ftepp, const char *source, const char *name)
 {
     ppmacro *macro;
-    lex_ctx ctx = { "__builtin__", 0 };
+    lex_ctx ctx = { "__builtin__", 0, 0 };
     ctx.file = source;
     macro = ppmacro_new(ctx, name);
     /*vec_push(ftepp->macros, macro);*/