]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - ftepp.c
Added ftepp predefs flag (ability to turn on/off predefs) disabled by default (even...
[xonotic/gmqcc.git] / ftepp.c
diff --git a/ftepp.c b/ftepp.c
index ed501a50a43c7b229e80afcdabbdbb46d49e4e4d..e1ee582c634c722eac2a285a575b595f9788bb15 100644 (file)
--- a/ftepp.c
+++ b/ftepp.c
@@ -68,6 +68,77 @@ typedef struct {
     char        *includename;
 } ftepp_t;
 
+typedef struct {
+    const char  *name;
+    char      *(*func)(lex_file *);
+} predef_t;
+
+/*
+ * Implement the predef subsystem now.  We can do this safely with the
+ * help of lexer contexts.
+ */  
+static int ftepp_predef_countval = 0;
+static int ftepp_predef_randval  = 0;
+
+/* __LINE__ */
+char *ftepp_predef_line(lex_file *context) {
+    char   *value = (char*)mem_a(128);
+    sprintf(value, "%d", (int)context->line);
+    return value;
+}
+/* __FILE__ */
+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);
+    memset (value, 0, length);
+    sprintf(value, "\"%s\"", context->name);
+
+    return value;
+}
+/* __COUNTER_LAST__ */
+char *ftepp_predef_counterlast(lex_file *context) {
+    char   *value = (char*)mem_a(128);
+    sprintf(value, "%d", ftepp_predef_countval);
+
+    (void)context;
+    return value;
+}
+/* __COUNTER__ */
+char *ftepp_predef_counter(lex_file *context) {
+    char   *value = (char*)mem_a(128);
+    ftepp_predef_countval ++;
+    sprintf(value, "%d", ftepp_predef_countval);
+    (void)context;
+
+    return value;
+}
+/* __RANDOM__ */
+char *ftepp_predef_random(lex_file *context) {
+    char  *value = (char*)mem_a(128);
+    ftepp_predef_randval = rand() % 0xFFFF; /* short int */
+    sprintf(value, "%d", ftepp_predef_randval);
+
+    (void)context;
+    return value;
+}
+/* __RANDOM_LAST__ */
+char *ftepp_predef_randomlast(lex_file *context) {
+    char   *value = (char*)mem_a(128);
+    sprintf(value, "%d", ftepp_predef_randval);
+
+    (void)context;
+    return value;
+}
+
+static const predef_t ftepp_predefs[] = {
+    { "__LINE__",         &ftepp_predef_line        },
+    { "__FILE__",         &ftepp_predef_file        },
+    { "__COUNTER__",      &ftepp_predef_counter     },
+    { "__COUNTER_LAST__", &ftepp_predef_counterlast },
+    { "__RANDOM__",       &ftepp_predef_random      },
+    { "__RANDOM_LAST__",  &ftepp_predef_randomlast  },
+};
+
 #define ftepp_tokval(f) ((f)->lex->tok.value)
 #define ftepp_ctx(f)    ((f)->lex->tok.ctx)
 
@@ -1010,14 +1081,15 @@ static char *ftepp_include_find(ftepp_t *ftepp, const char *file)
     return filename;
 }
 
-static void ftepp_directive_warning(ftepp_t *ftepp) {
+static bool ftepp_directive_warning(ftepp_t *ftepp) {
     char *message = NULL;
 
     if (!ftepp_skipspace(ftepp))
-        return;
+        return false;
 
     /* handle the odd non string constant case so it works like C */
     if (ftepp->token != TOKEN_STRINGCONST) {
+        bool  store   = false;
         vec_upload(message, "#warning", 8);
         ftepp_next(ftepp);
         while (ftepp->token != TOKEN_EOL) {
@@ -1025,13 +1097,13 @@ static void ftepp_directive_warning(ftepp_t *ftepp) {
             ftepp_next(ftepp);
         }
         vec_push(message, '\0');
-        (void)!!ftepp_warn(ftepp, WARN_CPP, message);
+        store = ftepp_warn(ftepp, WARN_CPP, message);
         vec_free(message);
-        return;
+        return store;
     }
 
     unescape  (ftepp_tokval(ftepp), ftepp_tokval(ftepp));
-    (void)!!ftepp_warn(ftepp, WARN_CPP, "#warning %s", ftepp_tokval(ftepp));
+    return ftepp_warn(ftepp, WARN_CPP, "#warning %s", ftepp_tokval(ftepp));
 }
 
 static void ftepp_directive_error(ftepp_t *ftepp) {
@@ -1297,6 +1369,10 @@ static bool ftepp_preprocess(ftepp_t *ftepp)
     ppmacro *macro;
     bool     newline = true;
 
+    /* predef stuff */
+    char    *expand  = NULL;
+    size_t   i;
+
     ftepp->lex->flags.preprocessing = true;
     ftepp->lex->flags.mergelines    = false;
     ftepp->lex->flags.noops         = true;
@@ -1314,10 +1390,25 @@ static bool ftepp_preprocess(ftepp_t *ftepp)
             case TOKEN_KEYWORD:
             case TOKEN_IDENT:
             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;
+                        }
+                    }
+                }
+
                 if (ftepp->output_on)
                     macro = ftepp_macro_find(ftepp, ftepp_tokval(ftepp));
                 else
                     macro = NULL;
+
                 if (!macro) {
                     ftepp_out(ftepp, ftepp_tokval(ftepp), false);
                     ftepp_next(ftepp);