Mesa (glsl-pp-rework-1): glsl: Simplify directive parser skeleton.

Michał Król michal at kemper.freedesktop.org
Fri Jun 19 10:02:41 UTC 2009


Module: Mesa
Branch: glsl-pp-rework-1
Commit: deec3cfca28b2c6c6b9fdb38b738cb715ffa9f3c
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=deec3cfca28b2c6c6b9fdb38b738cb715ffa9f3c

Author: Michal Krol <michal at vmware.com>
Date:   Wed Jun 17 20:29:46 2009 +0200

glsl: Simplify directive parser skeleton.

---

 src/glsl/pp/sl_pp_context.h |    2 +-
 src/glsl/pp/sl_pp_process.c |  229 ++++++++++++++++++++++++++-----------------
 src/glsl/pp/sl_pp_process.h |    1 +
 3 files changed, 141 insertions(+), 91 deletions(-)

diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h
index 3a1e215..e4686b8 100644
--- a/src/glsl/pp/sl_pp_context.h
+++ b/src/glsl/pp/sl_pp_context.h
@@ -49,4 +49,4 @@ const char *
 sl_pp_context_cstr(const struct sl_pp_context *context,
                    int offset);
 
-#endif /* SL_PP_VERSION_H */
+#endif /* SL_PP_CONTEXT_H */
diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c
index a97c750..1005c50 100644
--- a/src/glsl/pp/sl_pp_process.c
+++ b/src/glsl/pp/sl_pp_process.c
@@ -29,117 +29,166 @@
 #include "sl_pp_process.h"
 
 
-enum process_state {
-   state_seek_hash,
-   state_seek_directive,
-   state_seek_newline,
-   state_expand
+static void
+skip_whitespace(const struct sl_pp_token_info *input,
+                unsigned int *pi)
+{
+   while (input[*pi].token == SL_PP_WHITESPACE) {
+      (*pi)++;
+   }
+}
+
+
+struct process_state {
+   struct sl_pp_token_info *out;
+   unsigned int out_len;
+   unsigned int out_max;
 };
 
+
+static int
+out_token(struct process_state *state,
+          const struct sl_pp_token_info *token)
+{
+   if (state->out_len >= state->out_max) {
+      unsigned int new_max = state->out_max;
+
+      if (new_max < 0x100) {
+         new_max = 0x100;
+      } else if (new_max < 0x10000) {
+         new_max *= 2;
+      } else {
+         new_max += 0x10000;
+      }
+
+      state->out = realloc(state->out, new_max * sizeof(struct sl_pp_token_info));
+      if (!state->out) {
+         return -1;
+      }
+      state->out_max = new_max;
+   }
+
+   state->out[state->out_len++] = *token;
+   return 0;
+}
+
+
 int
 sl_pp_process(struct sl_pp_context *context,
               const struct sl_pp_token_info *input,
               struct sl_pp_token_info **output)
 {
    unsigned int i = 0;
-   enum process_state state = state_seek_hash;
-   struct sl_pp_token_info *out = NULL;
-   unsigned int out_len = 0;
-   unsigned int out_max = 0;
-
-   for (;;) {
-      struct sl_pp_token_info info;
-      int info_valid = 0;
-
-      switch (input[i].token) {
-      case SL_PP_WHITESPACE:
-         /* Drop whitespace alltogether at this point. */
-         i++;
-         break;
+   int found_eof = 0;
+   struct process_state state;
+
+   memset(&state, 0, sizeof(state));
 
-      case SL_PP_NEWLINE:
-      case SL_PP_EOF:
-         /* Preserve newline just for the sake of line numbering. */
-         info = input[i];
-         info_valid = 1;
+   while (!found_eof) {
+      skip_whitespace(input, &i);
+      if (input[i].token == SL_PP_HASH) {
          i++;
-         /* Restart directive parsing. */
-         state = state_seek_hash;
-         break;
+         skip_whitespace(input, &i);
+         switch (input[i].token) {
+         case SL_PP_IDENTIFIER:
+            {
+               const char *name;
+               int found_eol = 0;
+
+               name = sl_pp_context_cstr(context, input[i].data.identifier);
+               i++;
+               skip_whitespace(input, &i);
+
+               while (!found_eol) {
+                  switch (input[i].token) {
+                  case SL_PP_WHITESPACE:
+                     /* Drop whitespace all together at this point. */
+                     i++;
+                     break;
+
+                  case SL_PP_NEWLINE:
+                     /* Preserve newline just for the sake of line numbering. */
+                     if (out_token(&state, &input[i])) {
+                        return -1;
+                     }
+                     i++;
+                     found_eol = 1;
+                     break;
+
+                  case SL_PP_EOF:
+                     if (out_token(&state, &input[i])) {
+                        return -1;
+                     }
+                     i++;
+                     found_eof = 1;
+                     found_eol = 1;
+                     break;
+
+                  default:
+                     i++;
+                  }
+               }
+            }
+            break;
 
-      case SL_PP_HASH:
-         if (state == state_seek_hash) {
+         case SL_PP_NEWLINE:
+            /* Empty directive. */
+            if (out_token(&state, &input[i])) {
+               return -1;
+            }
             i++;
-            state = state_seek_directive;
-         } else {
-            /* Error: unexpected token. */
-            return -1;
-         }
-         break;
+            break;
 
-      case SL_PP_IDENTIFIER:
-         if (state == state_seek_hash) {
-            info = input[i];
-            info_valid = 1;
-            i++;
-            state = state_expand;
-         } else if (state == state_seek_directive) {
-            i++;
-            state = state_seek_newline;
-         } else if (state == state_expand) {
-            info = input[i];
-            info_valid = 1;
-            i++;
-         } else {
+         case SL_PP_EOF:
+            /* Empty directive. */
+            if (out_token(&state, &input[i])) {
+               return -1;
+            }
             i++;
-         }
-         break;
+            found_eof = 1;
+            break;
 
-      default:
-         if (state == state_seek_hash) {
-            info = input[i];
-            info_valid = 1;
-            i++;
-            state = state_expand;
-         } else if (state == state_seek_directive) {
-            /* Error: expected directive name. */
+         default:
             return -1;
-         } else if (state == state_expand) {
-            info = input[i];
-            info_valid = 1;
-            i++;
-         } else {
-            i++;
          }
-      }
-
-      if (info_valid) {
-         if (out_len >= out_max) {
-            unsigned int new_max = out_max;
-
-            if (new_max < 0x100) {
-               new_max = 0x100;
-            } else if (new_max < 0x10000) {
-               new_max *= 2;
-            } else {
-               new_max += 0x10000;
+      } else {
+         int found_eol = 0;
+
+         while (!found_eol) {
+            switch (input[i].token) {
+            case SL_PP_WHITESPACE:
+               /* Drop whitespace all together at this point. */
+               i++;
+               break;
+
+            case SL_PP_NEWLINE:
+               /* Preserve newline just for the sake of line numbering. */
+               if (out_token(&state, &input[i])) {
+                  return -1;
+               }
+               i++;
+               found_eol = 1;
+               break;
+
+            case SL_PP_EOF:
+               if (out_token(&state, &input[i])) {
+                  return -1;
+               }
+               i++;
+               found_eof = 1;
+               found_eol = 1;
+               break;
+
+            default:
+               if (out_token(&state, &input[i])) {
+                  return -1;
+               }
+               i++;
             }
-
-            out = realloc(out, new_max * sizeof(struct sl_pp_token_info));
-            if (!out) {
-               return -1;
-            }
-            out_max = new_max;
-         }
-
-         out[out_len++] = info;
-
-         if (info.token == SL_PP_EOF) {
-            break;
          }
       }
    }
 
-   *output = out;
+   *output = state.out;
    return 0;
 }
diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h
index b71ee44..d6401de 100644
--- a/src/glsl/pp/sl_pp_process.h
+++ b/src/glsl/pp/sl_pp_process.h
@@ -28,6 +28,7 @@
 #ifndef SL_PP_PROCESS_H
 #define SL_PP_PROCESS_H
 
+#include "sl_pp_context.h"
 #include "sl_pp_token.h"
 
 




More information about the mesa-commit mailing list