]> de.git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - lexer.c
sscanf -> sscanf_s on windows
[xonotic/gmqcc.git] / lexer.c
diff --git a/lexer.c b/lexer.c
index 1bea430edd36b1929505d8baf2fba3b7b9457cde..606ef5a9fee5cf768864d6a31e3cb84e5fe96c1a 100644 (file)
--- a/lexer.c
+++ b/lexer.c
@@ -24,6 +24,25 @@ void lexerror(lex_file *lex, const char *fmt, ...)
        printf("\n");
 }
 
+void lexwarn(lex_file *lex, int warn, const char *fmt, ...)
+{
+       va_list ap;
+
+       if (!OPTS_WARN(warn))
+           return;
+
+       if (lex)
+               printf("warning %s:%lu: ", lex->name, (unsigned long)lex->sline);
+       else
+               printf("warning: ");
+
+       va_start(ap, fmt);
+       vprintf(fmt, ap);
+       va_end(ap);
+
+       printf("\n");
+}
+
 token* token_new()
 {
        token *tok = (token*)mem_a(sizeof(token));
@@ -333,10 +352,6 @@ static int GMQCC_WARN lex_finish_string(lex_file *lex, int quote)
                if (ch == quote)
                        return TOKEN_STRINGCONST;
 
-               if (!lex_tokench(lex, ch))
-                       return (lex->tok->ttype = TOKEN_FATAL);
-
-               /* as lexer we only care about \" to not terminate the string prematurely */
                if (ch == '\\') {
                        ch = lex_getch(lex);
                        if (ch == EOF) {
@@ -344,10 +359,28 @@ static int GMQCC_WARN lex_finish_string(lex_file *lex, int quote)
                                lex_ungetch(lex, EOF); /* next token to be TOKEN_EOF */
                                return (lex->tok->ttype = TOKEN_ERROR);
                        }
-                       /* so we just add the next character no matter what it actually is */
+
+            switch (ch) {
+            case '\\': break;
+            case 'a':  ch = '\a'; break;
+            case 'b':  ch = '\b'; break;
+            case 'r':  ch = '\r'; break;
+            case 'n':  ch = '\n'; break;
+            case 't':  ch = '\t'; break;
+            case 'f':  ch = '\f'; break;
+            case 'v':  ch = '\v'; 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 */
+                           if (!lex_tokench(lex, '\\'))
+                                   return (lex->tok->ttype = TOKEN_FATAL);
+            }
+            /* add the character finally */
                        if (!lex_tokench(lex, ch))
                                return (lex->tok->ttype = TOKEN_FATAL);
                }
+               else if (!lex_tokench(lex, ch))
+                       return (lex->tok->ttype = TOKEN_FATAL);
        }
        lexerror(lex, "unexpected end of file within string constant");
        lex_ungetch(lex, EOF); /* next token to be TOKEN_EOF */
@@ -464,8 +497,6 @@ int lex_do(lex_file *lex)
                case '[':
                case ']':
 
-               case ',':
-
                case '#':
 
                        return (lex->tok->ttype = ch);
@@ -491,12 +522,23 @@ int lex_do(lex_file *lex)
                        case '|':
                        case '^':
                        case '~':
-                               return ch;
+                       case ',':
+                   case '.':
+                               return (lex->tok->ttype = ch);
                        default:
                                break;
                }
        }
 
+       if (ch == ',' || ch == '.') {
+           if (!lex_tokench(lex, ch) ||
+               !lex_endtoken(lex))
+           {
+               return (lex->tok->ttype = TOKEN_FATAL);
+           }
+           return (lex->tok->ttype = TOKEN_OPERATOR);
+       }
+
        if (ch == '+' || ch == '-' || /* ++, --, +=, -=  and -> as well! */
            ch == '>' || ch == '<' || /* <<, >>, <=, >= */
            ch == '=' ||              /* == */
@@ -582,7 +624,10 @@ int lex_do(lex_file *lex)
                } else if (!strcmp(v, "for")  ||
                         !strcmp(v, "while")  ||
                         !strcmp(v, "do")     ||
+                        !strcmp(v, "if")     ||
+                        !strcmp(v, "else")   ||
                         !strcmp(v, "var")    ||
+                        !strcmp(v, "local")  ||
                         !strcmp(v, "return") ||
                         !strcmp(v, "const"))
                        lex->tok->ttype = TOKEN_KEYWORD;
@@ -621,7 +666,13 @@ int lex_do(lex_file *lex)
                         return (lex->tok->ttype = TOKEN_FATAL);
 
                 /* It's a vector if we can successfully scan 3 floats */
-                if (sscanf(lex->tok->value, " %f %f %f ", &lex->tok->constval.v.x, &lex->tok->constval.v.y, &lex->tok->constval.v.z) == 3)
+#ifdef WIN32
+                if (sscanf_s(lex->tok->value, " %f %f %f ",
+                           &lex->tok->constval.v.x, &lex->tok->constval.v.y, &lex->tok->constval.v.z) == 3)
+#else
+                if (sscanf(lex->tok->value, " %f %f %f ",
+                           &lex->tok->constval.v.x, &lex->tok->constval.v.y, &lex->tok->constval.v.z) == 3)
+#endif
                 {
                         lex->tok->ttype = TOKEN_VECTORCONST;
                 }