]> git.rm.cloudns.org Git - xonotic/gmqcc.git/commitdiff
Removing #error/#warning/#message from parser, and making it part of preprocessor...
authorDale Weiler <killfieldengine@gmail.com>
Wed, 30 Jan 2013 05:49:08 +0000 (05:49 +0000)
committerDale Weiler <killfieldengine@gmail.com>
Wed, 30 Jan 2013 05:49:08 +0000 (05:49 +0000)
ftepp.c
parser.c

diff --git a/ftepp.c b/ftepp.c
index 34eec593bc8754019c635a4ddf1accc604cb54cb..ce5dd8ac2e0044f1388c815e797478334bac97f7 100644 (file)
--- a/ftepp.c
+++ b/ftepp.c
@@ -1269,6 +1269,79 @@ 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));
+}
+
+static void ftepp_directive_message(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, "#message", 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');
+        con_cprintmsg(&ftepp->lex->tok.ctx, LVL_MSG, "message", message);
+        vec_free(message);
+        return;
+    }
+
+    unescape     (ftepp_tokval(ftepp), ftepp_tokval(ftepp));
+    con_cprintmsg(&ftepp->lex->tok.ctx, LVL_MSG, "message",  ftepp_tokval(ftepp));
+}
+
 /**
  * Include a file.
  * FIXME: do we need/want a -I option?
@@ -1464,6 +1537,18 @@ 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 (!strcmp(ftepp_tokval(ftepp), "message")) {
+                ftepp_directive_message(ftepp);
+                break;
+            }
             else {
                 if (ftepp->output_on) {
                     ftepp_error(ftepp, "unrecognized preprocessor directive: `%s`", ftepp_tokval(ftepp));
index a54094a841f32beb80f736f756f7b00fee1226f8..5b1e0112f577f010240677f05945fe79cf5e4a23 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -3292,24 +3292,6 @@ static bool parse_eol(parser_t *parser)
     return parser->tok == TOKEN_EOL;
 }
 
-/*
- * 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) {
@@ -3336,85 +3318,25 @@ static bool parse_pragma_do(parser_t *parser) {
     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);
-    }
-
-    parseerror(parser, "invalid directive `%s`", parser_tokval(parser));
-    return false;
-}
 
-static bool parse_directive_or_pragma(parser_t *parser)
+static bool parse_pragma(parser_t *parser)
 {
     bool rv;
-    bool pragma; /* true when parsing pragma */
  
     parser->lex->flags.preprocessing = true;
     parser->lex->flags.mergelines    = true;
 
-    rv = parse_directive_or_pragma_do(parser, &pragma);
+    rv = parse_pragma_do(parser);
 
     if (parser->tok != TOKEN_EOL) {
-        parseerror(parser, "junk after %s", (pragma) ? "pragma" : "directive");
+        parseerror(parser, "junk after pragma");
         rv = false;
     }
     parser->lex->flags.preprocessing = false;
     parser->lex->flags.mergelines    = false;
 
     if (!parser_next(parser)) {
-        parseerror(parser, "parse error after %s", (pragma) ? "pragma" : "directive");
+        parseerror(parser, "parse error after pragma");
         rv = false;
     }
     return rv;
@@ -5595,7 +5517,7 @@ static bool parser_global_statement(parser_t *parser)
     }
     else if (parser->tok == '#')
     {
-        return parse_directive_or_pragma(parser);
+        return parse_pragma(parser);
     }
     else if (parser->tok == '$')
     {