glsl: Simplify directive parser skeleton.
authorMichal Krol <michal@vmware.com>
Wed, 17 Jun 2009 18:29:46 +0000 (20:29 +0200)
committerMichal Krol <michal@vmware.com>
Mon, 7 Sep 2009 08:11:44 +0000 (10:11 +0200)
src/glsl/pp/sl_pp_context.h
src/glsl/pp/sl_pp_process.c
src/glsl/pp/sl_pp_process.h

index 3a1e215625c842bccee5c428b6e3d02e265b56ab..e4686b89e33a4d7be67601e58f96ba8582a0f05d 100644 (file)
@@ -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 */
index a97c750de461cc80705bbba32abd4bce96639f04..1005c501050dd27c38e9bba2823d481c0f00d922 100644 (file)
 #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;
 }
index b71ee4466a1122ab05c8c6be5d85e3b0390c7e2c..d6401de960edf07a1ea4a9608bdc5fcc4ec37c11 100644 (file)
@@ -28,6 +28,7 @@
 #ifndef SL_PP_PROCESS_H
 #define SL_PP_PROCESS_H
 
+#include "sl_pp_context.h"
 #include "sl_pp_token.h"