glsl: add preprocessor support for #pragma
authorBrian Paul <brianp@vmware.com>
Tue, 13 Jan 2009 22:06:52 +0000 (15:06 -0700)
committerBrian Paul <brianp@vmware.com>
Tue, 13 Jan 2009 22:09:40 +0000 (15:09 -0700)
Two forms are supported:

Pragmas are silently ignored at this time.

src/mesa/shader/slang/library/slang_pp_directives.syn
src/mesa/shader/slang/library/slang_pp_directives_syn.h
src/mesa/shader/slang/slang_preprocess.c

index d4a321034d1693b8e16725b5ba266415c71c86ef..b51d168cc03e0fda15e6e0c0836b2d8f70b94ade 100644 (file)
 .emtcode BEHAVIOR_WARN    3
 .emtcode BEHAVIOR_DISABLE 4
 
+/*
+ * The PRAGMA_* symbols follow TOKEN_PRAGMA
+ */
+.emtcode PRAGMA_NO_PARAM 0
+.emtcode PRAGMA_PARAM    1
+
 source
    optional_directive .and .loop source_element .and '\0' .emit ESCAPE_TOKEN .emit TOKEN_END;
 
@@ -153,6 +159,7 @@ directive
    dir_elif .emit TOKEN_ELIF .or
    dir_endif .emit TOKEN_ENDIF .or
    dir_ext .emit TOKEN_EXTENSION .or
+   dir_pragma .emit TOKEN_PRAGMA .or
    dir_line .emit TOKEN_LINE;
 
 dir_define
@@ -187,6 +194,19 @@ dir_ext
 dir_line
    optional_space .and '#' .and optional_space .and "line" .and expression;
 
+dir_pragma
+   optional_space .and '#' .and optional_space .and "pragma" .and symbol .and opt_pragma_param;
+
+
+opt_pragma_param
+   pragma_param .or .true .emit PRAGMA_NO_PARAM;
+
+pragma_param
+   optional_space .and '(' .emit PRAGMA_PARAM .and optional_space .and symbol_no_space .and optional_space .and ')';
+
+symbol_no_space
+   symbol_character .emit * .and .loop symbol_character2 .emit * .and .true .emit '\0';
+
 symbol
    space .and symbol_character .emit * .and .loop symbol_character2 .emit * .and .true .emit '\0';
 
index 35e7bc276165d6dd3fb39dccd65f287871d901fc..430f8d8217cc6a53d8ec9687ef5cadb7f895ef4e 100644 (file)
@@ -20,6 +20,8 @@
 ".emtcode BEHAVIOR_ENABLE 2\n"
 ".emtcode BEHAVIOR_WARN 3\n"
 ".emtcode BEHAVIOR_DISABLE 4\n"
+".emtcode PRAGMA_NO_PARAM 0\n"
+".emtcode PRAGMA_PARAM 1\n"
 "source\n"
 " optional_directive .and .loop source_element .and '\\0' .emit ESCAPE_TOKEN .emit TOKEN_END;\n"
 "source_element\n"
@@ -76,6 +78,7 @@
 " dir_elif .emit TOKEN_ELIF .or\n"
 " dir_endif .emit TOKEN_ENDIF .or\n"
 " dir_ext .emit TOKEN_EXTENSION .or\n"
+" dir_pragma .emit TOKEN_PRAGMA .or\n"
 " dir_line .emit TOKEN_LINE;\n"
 "dir_define\n"
 " optional_space .and '#' .and optional_space .and \"define\" .and symbol .and opt_parameters .and\n"
 " optional_space .and ':' .and optional_space .and extension_behavior;\n"
 "dir_line\n"
 " optional_space .and '#' .and optional_space .and \"line\" .and expression;\n"
+"dir_pragma\n"
+" optional_space .and '#' .and optional_space .and \"pragma\" .and symbol .and opt_pragma_param;\n"
+"opt_pragma_param\n"
+" pragma_param .or .true .emit PRAGMA_NO_PARAM;\n"
+"pragma_param\n"
+" optional_space .and '(' .emit PRAGMA_PARAM .and optional_space .and symbol_no_space .and optional_space .and ')';\n"
+"symbol_no_space\n"
+" symbol_character .emit * .and .loop symbol_character2 .emit * .and .true .emit '\\0';\n"
 "symbol\n"
 " space .and symbol_character .emit * .and .loop symbol_character2 .emit * .and .true .emit '\\0';\n"
 "opt_parameters\n"
index 76e757cb381a4673ee82259465f53a8650839231..244a09171c7db8f85d90d0c80e84c6df5454321a 100644 (file)
@@ -51,6 +51,9 @@ grammar_error_to_log (slang_info_log *log)
    GLint pos;
 
    grammar_get_last_error ((byte *) (buf), sizeof (buf), &pos);
+   if (buf[0] == 0) {
+      _mesa_snprintf(buf, sizeof(buf), "Preprocessor error");
+   }
    slang_info_log_error (log, buf);
 }
 
@@ -528,6 +531,20 @@ pp_ext_set(pp_ext *self, const char *name, GLboolean enable)
 }
 
 
+/**
+ * Called in response to #pragma.  For example, "#pragma debug(on)" would
+ * call this function as pp_pragma("debug", "on").
+ * At this time, pragmas are silently ignored.
+ */
+static void
+pp_pragma(const char *pragma, const char *param)
+{
+#if 0
+   printf("#pragma %s %s\n", pragma, param);
+#endif
+}
+
+
 /**
  * The state of preprocessor: current line, file and version number, list
  * of all defined macros and the #if/#endif context.
@@ -862,6 +879,10 @@ parse_if (slang_string *output, const byte *prod, GLuint *pi, GLint *result, pp_
 #define BEHAVIOR_WARN    3
 #define BEHAVIOR_DISABLE 4
 
+#define PRAGMA_NO_PARAM  0
+#define PRAGMA_PARAM     1
+
+
 static GLboolean
 preprocess_source (slang_string *output, const char *source,
                    grammar pid, grammar eid,
@@ -940,9 +961,11 @@ preprocess_source (slang_string *output, const char *source,
       else {
          const char *id;
          GLuint idlen;
+         GLubyte token;
 
          i++;
-         switch (prod[i++]) {
+         token = prod[i++];
+         switch (token) {
 
          case TOKEN_END:
             /* End of source string.
@@ -1159,6 +1182,25 @@ preprocess_source (slang_string *output, const char *source,
             }
             break;
 
+         case TOKEN_PRAGMA:
+            {
+               GLint have_param;
+               const char *pragma, *param;
+
+               pragma = (const char *) (&prod[i]);
+               i += _mesa_strlen(pragma) + 1;
+               have_param = (prod[i++] == PRAGMA_PARAM);
+               if (have_param) {
+                  param = (const char *) (&prod[i]);
+                  i += _mesa_strlen(param) + 1;
+               }
+               else {
+                  param = NULL;
+               }
+               pp_pragma(pragma, param);
+            }
+            break;
+
          case TOKEN_LINE:
             id = (const char *) (&prod[i]);
             i += _mesa_strlen (id) + 1;