]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - ftepp.c
Get gmqcc/qcvm compiling on windows again. Plus work in progress support for the...
[xonotic/gmqcc.git] / ftepp.c
diff --git a/ftepp.c b/ftepp.c
index 6fff6e09be19b8db25064aea5fa88cb243d31c9e..96c20bf4f937f7ad0d55c9050e31b6813a3ab1a3 100644 (file)
--- a/ftepp.c
+++ b/ftepp.c
@@ -95,21 +95,13 @@ static void ftepp_error(ftepp_t *ftepp, const char *fmt, ...)
 
 static bool GMQCC_WARN ftepp_warn(ftepp_t *ftepp, int warntype, const char *fmt, ...)
 {
+    bool    r;
     va_list ap;
-    int lvl = LVL_WARNING;
-
-    if (!OPTS_WARN(warntype))
-        return false;
-
-    if (opts.werror) {
-           lvl = LVL_ERROR;
-        ftepp->errors++;
-    }
 
     va_start(ap, fmt);
-    con_cvprintmsg((void*)&ftepp->lex->tok.ctx, lvl, "error", fmt, ap);
+    r = vcompile_warning(ftepp->lex->tok.ctx, warntype, fmt, ap);
     va_end(ap);
-    return opts.werror;
+    return r;
 }
 
 static pptoken *pptoken_make(ftepp_t *ftepp)
@@ -225,7 +217,7 @@ static void ftepp_macro_delete(ftepp_t *ftepp, const char *name)
     }
 }
 
-static inline int ftepp_next(ftepp_t *ftepp)
+static GMQCC_INLINE int ftepp_next(ftepp_t *ftepp)
 {
     return (ftepp->token = lex_do(ftepp->lex));
 }
@@ -1018,6 +1010,54 @@ static char *ftepp_include_find(ftepp_t *ftepp, const char *file)
     return filename;
 }
 
+static void ftepp_directive_warning(ftepp_t *ftepp) {
+    char *message = NULL;
+
+    if (!ftepp_skipspace(ftepp))
+        return;
+
+    /* handle the odd non string constant case so it works like C */
+    if (ftepp->token != TOKEN_STRINGCONST) {
+        vec_upload(message, "#warning", 8);
+        ftepp_next(ftepp);
+        while (ftepp->token != TOKEN_EOL) {
+            vec_upload(message, ftepp_tokval(ftepp), strlen(ftepp_tokval(ftepp)));
+            ftepp_next(ftepp);
+        }
+        vec_push(message, '\0');
+        (void)!!ftepp_warn(ftepp, WARN_CPP, message);
+        vec_free(message);
+        return;
+    }
+
+    unescape  (ftepp_tokval(ftepp), ftepp_tokval(ftepp));
+    (void)!!ftepp_warn(ftepp, WARN_CPP, "#warning %s", ftepp_tokval(ftepp));
+}
+
+static void ftepp_directive_error(ftepp_t *ftepp) {
+    char *message = NULL;
+
+    if (!ftepp_skipspace(ftepp))
+        return;
+
+    /* handle the odd non string constant case so it works like C */
+    if (ftepp->token != TOKEN_STRINGCONST) {
+        vec_upload(message, "#error", 6);
+        ftepp_next(ftepp);
+        while (ftepp->token != TOKEN_EOL) {
+            vec_upload(message, ftepp_tokval(ftepp), strlen(ftepp_tokval(ftepp)));
+            ftepp_next(ftepp);
+        }
+        vec_push(message, '\0');
+        ftepp_error(ftepp, message);
+        vec_free(message);
+        return;
+    }
+
+    unescape  (ftepp_tokval(ftepp), ftepp_tokval(ftepp));
+    ftepp_error(ftepp, "#error %s", ftepp_tokval(ftepp));
+}
+
 /**
  * Include a file.
  * FIXME: do we need/want a -I option?
@@ -1213,6 +1253,14 @@ static bool ftepp_hash(ftepp_t *ftepp)
                 ftepp_out(ftepp, "#", false);
                 break;
             }
+            else if (!strcmp(ftepp_tokval(ftepp), "warning")) {
+                ftepp_directive_warning(ftepp);
+                break;
+            }
+            else if (!strcmp(ftepp_tokval(ftepp), "error")) {
+                ftepp_directive_error(ftepp);
+                break;
+            }
             else {
                 if (ftepp->output_on) {
                     ftepp_error(ftepp, "unrecognized preprocessor directive: `%s`", ftepp_tokval(ftepp));
@@ -1369,6 +1417,13 @@ bool ftepp_preprocess_string(const char *name, const char *str)
 
 void ftepp_add_macro(const char *name, const char *value) {
     char *create = NULL;
+
+    /* use saner path for empty macros */
+    if (!value) {
+        ftepp_add_define("__builtin__", name);
+        return;
+    }
+
     vec_upload(create, "#define ", 8);
     vec_upload(create, name,  strlen(name));
     vec_push  (create, ' ');