apple: Update dispatch table to current OpenGL specs
[mesa.git] / src / glsl / glcpp / glcpp-lex.l
index afddd7ddb321e4c7bac6310aea44e0b1236da257..86618870885ab9a4f4c8aad6c3f7cb5ea0387a7c 100644 (file)
 
 #include <stdio.h>
 #include <string.h>
+#include <ctype.h>
 
 #include "glcpp.h"
 #include "glcpp-parse.h"
 
+/* Flex annoyingly generates some functions without making them
+ * static. Let's declare them here. */
+int glcpp_get_column  (yyscan_t yyscanner);
+void glcpp_set_column (int  column_no , yyscan_t yyscanner);
+
+#ifdef _MSC_VER
+#define YY_NO_UNISTD_H
+#endif
+
+#define YY_NO_INPUT
+
 #define YY_USER_ACTION                                          \
    do {                                                         \
-      yylloc->source = 0;                                       \
       yylloc->first_column = yycolumn + 1;                      \
       yylloc->first_line = yylineno;                            \
       yycolumn += yyleng;                                       \
    } while(0);
+
+#define YY_USER_INIT                   \
+       do {                            \
+               yylineno = 1;           \
+               yycolumn = 1;           \
+               yylloc->source = 0;     \
+       } while(0)
 %}
 
 %option bison-bridge bison-locations reentrant noyywrap
 %option extra-type="glcpp_parser_t *"
 %option prefix="glcpp_"
 %option stack
+%option never-interactive
 
-%x DONE COMMENT
+%x DONE COMMENT UNREACHABLE SKIP
 
 SPACE          [[:space:]]
 NONSPACE       [^[:space:]]
@@ -53,90 +72,129 @@ IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]*
 PUNCTUATION    [][(){}.&*~!/%<>^|;,=+-]
 OTHER          [^][(){}.&*~!/%<>^|;,=#[:space:]+-]+
 
+DIGITS                 [0-9][0-9]*
 DECIMAL_INTEGER                [1-9][0-9]*[uU]?
 OCTAL_INTEGER          0[0-7]*[uU]?
 HEXADECIMAL_INTEGER    0[xX][0-9a-fA-F]+[uU]?
 
 %%
+       /* Implicitly switch between SKIP and INITIAL (non-skipping);
+        * don't switch if some other state was explicitly set.
+        */
+       glcpp_parser_t *parser = yyextra;
+       if (YY_START == 0 || YY_START == SKIP) {
+               if (parser->lexing_if || parser->skip_stack == NULL || parser->skip_stack->type == SKIP_NO_SKIP) {
+                       BEGIN 0;
+               } else {
+                       BEGIN SKIP;
+               }
+       }
 
        /* Single-line comments */
-"//"[^\n]*\n {
-       yylineno++;
-       yycolumn = 0;
-       return NEWLINE;
+"//"[^\n]* {
 }
 
        /* Multi-line comments */
 "/*"                    { yy_push_state(COMMENT, yyscanner); }
 <COMMENT>[^*\n]*
-<COMMENT>[^*\n]*\n      { yylineno++; yycolumn = 0; }
+<COMMENT>[^*\n]*\n      { yylineno++; yycolumn = 0; return NEWLINE; }
 <COMMENT>"*"+[^*/\n]*
-<COMMENT>"*"+[^*/\n]*\n { yylineno++; yycolumn = 0; }
+<COMMENT>"*"+[^*/\n]*\n { yylineno++; yycolumn = 0; return NEWLINE; }
 <COMMENT>"*"+"/"        {
        yy_pop_state(yyscanner);
        if (yyextra->space_tokens)
                return SPACE;
 }
 
+{HASH}version {
+       yylval->str = ralloc_strdup (yyextra, yytext);
+       yyextra->space_tokens = 0;
+       return HASH_VERSION;
+}
+
        /* glcpp doesn't handle #extension, #version, or #pragma directives.
         * Simply pass them through to the main compiler's lexer/parser. */
-{HASH}(extension|version|pragma)[^\n]+ {
-       yylval->str = xtalloc_strdup (yyextra, yytext);
+{HASH}(extension|pragma)[^\n]+ {
+       yylval->str = ralloc_strdup (yyextra, yytext);
        yylineno++;
        yycolumn = 0;
        return OTHER;
 }
 
-{HASH}ifdef/.*\n {
+{HASH}line{HSPACE}+{DIGITS}{HSPACE}+{DIGITS}{HSPACE}*$ {
+       /* Eat characters until the first digit is
+        * encountered
+        */
+       char *ptr = yytext;
+       while (!isdigit(*ptr))
+               ptr++;
+
+       /* Subtract one from the line number because
+        * yylineno is zero-based instead of
+        * one-based.
+        */
+       yylineno = strtol(ptr, &ptr, 0) - 1;
+       yylloc->source = strtol(ptr, NULL, 0);
+}
+
+{HASH}line{HSPACE}+{DIGITS}{HSPACE}*$ {
+       /* Eat characters until the first digit is
+        * encountered
+        */
+       char *ptr = yytext;
+       while (!isdigit(*ptr))
+               ptr++;
+
+       /* Subtract one from the line number because
+        * yylineno is zero-based instead of
+        * one-based.
+        */
+       yylineno = strtol(ptr, &ptr, 0) - 1;
+}
+
+<SKIP,INITIAL>{
+{HASH}ifdef {
+       yyextra->lexing_if = 1;
        yyextra->space_tokens = 0;
        return HASH_IFDEF;
 }
 
-{HASH}ifndef/.*\n {
+{HASH}ifndef {
+       yyextra->lexing_if = 1;
        yyextra->space_tokens = 0;
        return HASH_IFNDEF;
 }
 
-{HASH}if{HSPACE}/.*\n {
+{HASH}if/[^_a-zA-Z0-9] {
        yyextra->lexing_if = 1;
        yyextra->space_tokens = 0;
        return HASH_IF;
 }
 
-{HASH}elif/.*\n {
+{HASH}elif {
        yyextra->lexing_if = 1;
        yyextra->space_tokens = 0;
        return HASH_ELIF;
 }
 
-{HASH}else/.*\n {
+{HASH}else {
        yyextra->space_tokens = 0;
        return HASH_ELSE;
 }
 
-{HASH}endif/.*\n {
+{HASH}endif {
        yyextra->space_tokens = 0;
        return HASH_ENDIF;
 }
+}
 
-       /* When skipping (due to an #if 0 or similar) consume anything
-        * up to a newline. We do this less priroty than any
-        * #if-related directive (#if, #elif, #else, #endif), but with
-        * more priority than any other directive or token to avoid
-        * any side-effects from skipped content.
-        *
-        * We use the lexing_if flag to avoid skipping any part of an
-        * if conditional expression. */
-[^\n]+/\n {
-       /* Since this rule always matches, YY_USER_ACTION gets called for it,
-        * wrongly incrementing yycolumn.  We undo that effect here. */
-       yycolumn -= yyleng;
-       if (yyextra->lexing_if ||
-           yyextra->skip_stack == NULL ||
-           yyextra->skip_stack->type == SKIP_NO_SKIP)
-       {
-               REJECT;
-       }
+<SKIP>[^\n] ;
+
+{HASH}error.* {
+       char *p;
+       for (p = yytext; !isalpha(p[0]); p++); /* skip "  #   " */
+       p += 5; /* skip "error" */
+       glcpp_error(yylloc, yyextra, "#error%s", p);
 }
 
 {HASH}define{HSPACE}+/{IDENTIFIER}"(" {
@@ -160,17 +218,17 @@ HEXADECIMAL_INTEGER       0[xX][0-9a-fA-F]+[uU]?
 }
 
 {DECIMAL_INTEGER} {
-       yylval->str = xtalloc_strdup (yyextra, yytext);
+       yylval->str = ralloc_strdup (yyextra, yytext);
        return INTEGER_STRING;
 }
 
 {OCTAL_INTEGER} {
-       yylval->str = xtalloc_strdup (yyextra, yytext);
+       yylval->str = ralloc_strdup (yyextra, yytext);
        return INTEGER_STRING;
 }
 
 {HEXADECIMAL_INTEGER} {
-       yylval->str = xtalloc_strdup (yyextra, yytext);
+       yylval->str = ralloc_strdup (yyextra, yytext);
        return INTEGER_STRING;
 }
 
@@ -215,7 +273,7 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]?
 }
 
 {IDENTIFIER} {
-       yylval->str = xtalloc_strdup (yyextra, yytext);
+       yylval->str = ralloc_strdup (yyextra, yytext);
        return IDENTIFIER;
 }
 
@@ -224,7 +282,7 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]?
 }
 
 {OTHER}+ {
-       yylval->str = xtalloc_strdup (yyextra, yytext);
+       yylval->str = ralloc_strdup (yyextra, yytext);
        return OTHER;
 }
 
@@ -234,7 +292,7 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]?
        }
 }
 
-\n {
+<SKIP,INITIAL>\n {
        yyextra->lexing_if = 0;
        yylineno++;
        yycolumn = 0;
@@ -248,6 +306,15 @@ HEXADECIMAL_INTEGER        0[xX][0-9a-fA-F]+[uU]?
        return NEWLINE;
 }
 
+       /* We don't actually use the UNREACHABLE start condition. We
+       only have this action here so that we can pretend to call some
+       generated functions, (to avoid "defined but not used"
+       warnings. */
+<UNREACHABLE>. {
+       unput('.');
+       yy_top_state(yyextra);
+}
+
 %%
 
 void