]> git.rm.cloudns.org Git - xonotic/gmqcc.git/commitdiff
Removed #warning and #error from ftepp, and made it part of the parser routine. ...
authorDale Weiler <killfieldengine@gmail.com>
Wed, 30 Jan 2013 01:24:58 +0000 (01:24 +0000)
committerDale Weiler <killfieldengine@gmail.com>
Wed, 30 Jan 2013 01:24:58 +0000 (01:24 +0000)
ftepp.c
parser.c

diff --git a/ftepp.c b/ftepp.c
index 9be8c5494ddef2572e5ad84fa7eddb2c48d5ff0d..054972efeca90115b0182b1e8c4f3ba85a31f6bb 100644 (file)
--- a/ftepp.c
+++ b/ftepp.c
@@ -1269,55 +1269,6 @@ static char *ftepp_include_find(ftepp_t *ftepp, const char *file)
     return filename;
 }
 
-static bool ftepp_directive_warning(ftepp_t *ftepp) {
-    char *message = NULL;
-
-    if (!ftepp_skipspace(ftepp))
-        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) {
-            vec_upload(message, ftepp_tokval(ftepp), strlen(ftepp_tokval(ftepp)));
-            ftepp_next(ftepp);
-        }
-        vec_push(message, '\0');
-        store = ftepp_warn(ftepp, WARN_CPP, message);
-        vec_free(message);
-        return store;
-    }
-
-    unescape  (ftepp_tokval(ftepp), ftepp_tokval(ftepp));
-    return 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?
@@ -1513,14 +1464,6 @@ 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));
index 2e8652800e9c78cfef0c4227c8985e728be98bec..d64dd2e1de187c2f133b528b07a0a443cf1591a4 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -3292,15 +3292,26 @@ static bool parse_eol(parser_t *parser)
     return parser->tok == TOKEN_EOL;
 }
 
-static bool parse_pragma_do(parser_t *parser)
-{
-    if (!parser_next(parser) ||
-        parser->tok != TOKEN_IDENT ||
-        strcmp(parser_tokval(parser), "pragma"))
-    {
-        parseerror(parser, "expected `pragma` keyword after `#`, got `%s`", parser_tokval(parser));
-        return false;
-    }
+/*
+ * Traditionally you'd implement warning, error, and message
+ * directives in the preprocessor. However, like #pragma, these
+ * shouldn't depend on -fftepp to utilize.  So they're instead
+ * implemented here.
+ */   
+enum {
+    PARSE_DIRECTIVE_ERROR,
+    PARSE_DIRECTIVE_MESSAGE,
+    PARSE_DIRECTIVE_WARNING,
+    PARSE_DIRECTIVE_COUNT
+};
+
+static const char *parser_directives[PARSE_DIRECTIVE_COUNT] = {
+    "error",
+    "message",
+    "warning"
+};
+
+static bool parse_pragma_do(parser_t *parser) {
     if (!parse_skipwhite(parser) || parser->tok != TOKEN_IDENT) {
         parseerror(parser, "expected pragma, got `%s`", parser_tokval(parser));
         return false;
@@ -3311,35 +3322,102 @@ static bool parse_pragma_do(parser_t *parser)
             parseerror(parser, "`noref` pragma requires an argument: 0 or 1");
             return false;
         }
+
         parser->noref = !!parser_token(parser)->constval.i;
+
         if (!parse_eol(parser)) {
             parseerror(parser, "parse error after `noref` pragma");
             return false;
         }
-    }
-    else
-    {
+    } else {
         (void)!parsewarning(parser, WARN_UNKNOWN_PRAGMAS, "ignoring #pragma %s", parser_tokval(parser));
         return false;
     }
+    return true;
+}
+
+static bool parse_directive_or_pragma_do(parser_t *parser, bool *pragma) {
+
+    size_t type = PARSE_DIRECTIVE_COUNT;
+
+    if (!parser_next(parser) || parser->tok != TOKEN_IDENT) {
+        parseerror(parser, "expected `pragma, error, message, warning` after `#`, got `%s`",
+            parser_tokval(parser));
+
+        return false;
+    }
+
+    if (!strcmp(parser_tokval(parser), "pragma" )) {
+        *pragma = true;
+
+        return parse_pragma_do(parser);
+    }
+
+    if (!strcmp(parser_tokval(parser), "error"  )) type = PARSE_DIRECTIVE_ERROR;
+    if (!strcmp(parser_tokval(parser), "message")) type = PARSE_DIRECTIVE_MESSAGE;
+    if (!strcmp(parser_tokval(parser), "warning")) type = PARSE_DIRECTIVE_WARNING;
+
+    switch (type) {
+        case PARSE_DIRECTIVE_ERROR:
+        case PARSE_DIRECTIVE_MESSAGE:
+        case PARSE_DIRECTIVE_WARNING:
+            *pragma = false;
+
+            if (!parse_skipwhite(parser) || parser->tok != TOKEN_STRINGCONST) {
+                parseerror(parser, "expected %s, got `%`", parser_directives[type], parser_tokval(parser));
+                return false;
+            }
+
+            switch (type) {
+                case PARSE_DIRECTIVE_ERROR:
+                    con_cprintmsg(&parser->lex->tok.ctx, LVL_ERROR, "error", parser_tokval(parser));
+                    compile_errors ++; /* hack */
+                    break;
+                    /*break;*/
+
+                case PARSE_DIRECTIVE_MESSAGE:
+                    con_cprintmsg(&parser->lex->tok.ctx, LVL_MSG, "message", parser_tokval(parser));
+                    break;
+
+                case PARSE_DIRECTIVE_WARNING:
+                    con_cprintmsg(&parser->lex->tok.ctx, LVL_WARNING, "warning", parser_tokval(parser));
+                    break;
+            }
+
+            if (!parse_eol(parser)) {
+                parseerror(parser, "parse error after `%` directive", parser_directives[type]);
+                return false;
+            }
+
+            return (type != PARSE_DIRECTIVE_ERROR);
+
+        default:
+            parseerror(parser, "invalid directive `%s`", parser_tokval(parser));
+            return false;
+    }
 
     return true;
 }
 
-static bool parse_pragma(parser_t *parser)
+static bool parse_directive_or_pragma(parser_t *parser)
 {
     bool rv;
+    bool pragma; /* true when parsing pragma */
     parser->lex->flags.preprocessing = true;
-    parser->lex->flags.mergelines = true;
-    rv = parse_pragma_do(parser);
+    parser->lex->flags.mergelines    = true;
+
+    rv = parse_directive_or_pragma_do(parser, &pragma);
+
     if (parser->tok != TOKEN_EOL) {
-        parseerror(parser, "junk after pragma");
+        parseerror(parser, "junk after %s", (pragma) ? "pragma" : "directive");
         rv = false;
     }
     parser->lex->flags.preprocessing = false;
-    parser->lex->flags.mergelines = false;
+    parser->lex->flags.mergelines    = false;
+
     if (!parser_next(parser)) {
-        parseerror(parser, "parse error after pragma");
+        parseerror(parser, "parse error after %s", (pragma) ? "pragma" : "directive");
         rv = false;
     }
     return rv;
@@ -5520,7 +5598,7 @@ static bool parser_global_statement(parser_t *parser)
     }
     else if (parser->tok == '#')
     {
-        return parse_pragma(parser);
+        return parse_directive_or_pragma(parser);
     }
     else if (parser->tok == '$')
     {