]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - lexer.c
Ignore modelgen commands with lex->flags.preprocessing
[xonotic/gmqcc.git] / lexer.c
diff --git a/lexer.c b/lexer.c
index 6fbe41def69acdc486d96e031091deb7d07cff2f..5c9b7ee6d145077acf25c24730a5e253be3631bd 100644 (file)
--- a/lexer.c
+++ b/lexer.c
@@ -48,7 +48,9 @@ static const char *keywords_fg[] = {
     "struct", "union",
     "break", "continue",
     "typedef",
-    "goto"
+    "goto",
+
+    "__builtin_debug_printtype"
 };
 static size_t num_keywords_fg = sizeof(keywords_fg) / sizeof(keywords_fg[0]);
 
@@ -740,6 +742,7 @@ static bool lex_finish_frames(lex_file *lex)
 static int GMQCC_WARN lex_finish_string(lex_file *lex, int quote)
 {
     int ch = 0;
+    int nextch;
 
     while (ch != EOF)
     {
@@ -776,7 +779,61 @@ static int GMQCC_WARN lex_finish_string(lex_file *lex, int quote)
             case 't':  ch = '\t'; break;
             case 'f':  ch = '\f'; break;
             case 'v':  ch = '\v'; break;
+            case 'x':
+            case 'X':
+                /* same procedure as in fteqcc */
+                ch = 0;
+                nextch = lex_getch(lex);
+                if      (nextch >= '0' && nextch <= '9')
+                    ch += nextch - '0';
+                else if (nextch >= 'a' && nextch <= 'f')
+                    ch += nextch - 'a' + 10;
+                else if (nextch >= 'A' && nextch <= 'F')
+                    ch += nextch - 'A' + 10;
+                else {
+                    lexerror(lex, "bad character code");
+                    lex_ungetch(lex, nextch);
+                    return (lex->tok.ttype = TOKEN_ERROR);
+                }
+
+                ch *= 0x10;
+                nextch = lex_getch(lex);
+                if      (nextch >= '0' && nextch <= '9')
+                    ch += nextch - '0';
+                else if (nextch >= 'a' && nextch <= 'f')
+                    ch += nextch - 'a' + 10;
+                else if (nextch >= 'A' && nextch <= 'F')
+                    ch += nextch - 'A' + 10;
+                else {
+                    lexerror(lex, "bad character code");
+                    lex_ungetch(lex, nextch);
+                    return (lex->tok.ttype = TOKEN_ERROR);
+                }
+                break;
+
+            /* fteqcc support */
+            case '0': case '1': case '2': case '3':
+            case '4': case '5': case '6': case '7':
+            case '8': case '9':
+                ch = 18 + ch - '0';
+                break;
+            case '<':  ch = 29; break;
+            case '-':  ch = 30; break;
+            case '>':  ch = 31; break;
+            case '[':  ch = 16; break;
+            case ']':  ch = 17; break;
+            case '{':
+                ch = 0;
+                for (nextch = lex_getch(lex); nextch != '}'; nextch = lex_getch(lex)) {
+                    ch = ch * 10 + nextch - '0';
+                    if (nextch < '0' || nextch > '9' || ch > 255) {
+                        lexerror(lex, "bad character code");
+                        return (lex->tok.ttype = TOKEN_ERROR);
+                    }
+                }
+                break;
             case '\n':  ch = '\n'; break;
+
             default:
                 lexwarn(lex, WARN_UNKNOWN_CONTROL_SEQUENCE, "unrecognized control sequence: \\%c", ch);
                 /* so we just add the character plus backslash no matter what it actually is */
@@ -912,7 +969,7 @@ int lex_do(lex_file *lex)
     }
 
     /* modelgen / spiritgen commands */
-    if (ch == '$') {
+    if (ch == '$' && !lex->flags.preprocessing) {
         const char *v;
         size_t frame;
 
@@ -1162,7 +1219,7 @@ int lex_do(lex_file *lex)
         lex_tokench(lex, ch);
 
         nextch = lex_getch(lex);
-        if (nextch == ch || nextch == '=') {
+        if (nextch == '=' || (nextch == ch && ch != '!')) {
             lex_tokench(lex, nextch);
         } else if (ch == '-' && nextch == '>') {
             lex_tokench(lex, nextch);
@@ -1324,6 +1381,12 @@ int lex_do(lex_file *lex)
         return lex->tok.ttype;
     }
 
+    if (lex->flags.preprocessing) {
+        lex_tokench(lex, ch);
+        lex_endtoken(lex);
+        return (lex->tok.ttype = ch);
+    }
+
     lexerror(lex, "unknown token");
     return (lex->tok.ttype = TOKEN_ERROR);
 }