glsl: Allow for preprocessor macro redefinition.
authorMichal Krol <michal@vmware.com>
Fri, 26 Jun 2009 10:26:05 +0000 (12:26 +0200)
committerMichal Krol <michal@vmware.com>
Mon, 7 Sep 2009 08:11:52 +0000 (10:11 +0200)
src/glsl/pp/sl_pp_context.c
src/glsl/pp/sl_pp_context.h
src/glsl/pp/sl_pp_define.c
src/glsl/pp/sl_pp_macro.c
src/glsl/pp/sl_pp_macro.h
src/glsl/pp/sl_pp_process.c
src/glsl/pp/sl_pp_process.h

index 1afe9a5d5e036e69d2d81278fdbbc4523ec9ea21..50ec790cc500199d8bfa954ea4d63fa21da21738 100644 (file)
@@ -33,6 +33,7 @@ void
 sl_pp_context_init(struct sl_pp_context *context)
 {
    memset(context, 0, sizeof(struct sl_pp_context));
+   context->macro_tail = &context->macro;
    context->if_ptr = SL_PP_MAX_IF_NESTING;
    context->if_value = 1;
 }
index e8200d55d7fb2a597885da0243cee3ede8b1e2de..1dbd10e30ee506e5e6ac4c75919da7815fb8173c 100644 (file)
@@ -39,6 +39,7 @@ struct sl_pp_context {
    unsigned int cstr_pool_len;
 
    struct sl_pp_macro *macro;
+   struct sl_pp_macro **macro_tail;
 
    unsigned int if_stack[SL_PP_MAX_IF_NESTING];
    unsigned int if_ptr;
index e8a23fedcd8d3175fec9f9ed51cece8f3350ae9b..0509646430ac59e8c3df2524560c2c30d823c53d 100644 (file)
@@ -105,22 +105,42 @@ int
 sl_pp_process_define(struct sl_pp_context *context,
                      const struct sl_pp_token_info *input,
                      unsigned int first,
-                     unsigned int last,
-                     struct sl_pp_macro *macro)
+                     unsigned int last)
 {
+   int macro_name = -1;
+   struct sl_pp_macro *macro;
    unsigned int i;
    unsigned int body_len;
    unsigned int j;
 
    if (first < last && input[first].token == SL_PP_IDENTIFIER) {
-      macro->name = input[first].data.identifier;
+      macro_name = input[first].data.identifier;
       first++;
    }
-
-   if (macro->name == -1) {
+   if (macro_name == -1) {
       return -1;
    }
 
+   for (macro = context->macro; macro; macro = macro->next) {
+      if (macro->name == macro_name) {
+         break;
+      }
+   }
+
+   if (!macro) {
+      macro = sl_pp_macro_new();
+      if (!macro) {
+         return -1;
+      }
+
+      *context->macro_tail = macro;
+      context->macro_tail = &macro->next;
+   } else {
+      sl_pp_macro_reset(macro);
+   }
+
+   macro->name = macro_name;
+
    /*
     * If there is no whitespace between macro name and left paren, a macro
     * formal argument list follows. This is the only place where the presence
index a8412f0651c4b37254ed5b41cb2800ff45438214..a82c30cb167642e577fd311f3281f9c3840091c6 100644 (file)
 #include "sl_pp_process.h"
 
 
+static void
+_macro_init(struct sl_pp_macro *macro)
+{
+   macro->name = -1;
+   macro->num_args = -1;
+   macro->arg = NULL;
+   macro->body = NULL;
+}
+
 struct sl_pp_macro *
 sl_pp_macro_new(void)
 {
@@ -37,33 +46,45 @@ sl_pp_macro_new(void)
 
    macro = calloc(1, sizeof(struct sl_pp_macro));
    if (macro) {
-      macro->name = -1;
-      macro->num_args = -1;
+      _macro_init(macro);
    }
    return macro;
 }
 
+static void
+_macro_destroy(struct sl_pp_macro *macro)
+{
+   struct sl_pp_macro_formal_arg *arg = macro->arg;
+
+   while (arg) {
+      struct sl_pp_macro_formal_arg *next_arg = arg->next;
+
+      free(arg);
+      arg = next_arg;
+   }
+
+   free(macro->body);
+}
+
 void
 sl_pp_macro_free(struct sl_pp_macro *macro)
 {
    while (macro) {
       struct sl_pp_macro *next_macro = macro->next;
-      struct sl_pp_macro_formal_arg *arg = macro->arg;
-
-      while (arg) {
-         struct sl_pp_macro_formal_arg *next_arg = arg->next;
-
-         free(arg);
-         arg = next_arg;
-      }
-
-      free(macro->body);
 
+      _macro_destroy(macro);
       free(macro);
       macro = next_macro;
    }
 }
 
+void
+sl_pp_macro_reset(struct sl_pp_macro *macro)
+{
+   _macro_destroy(macro);
+   _macro_init(macro);
+}
+
 static void
 skip_whitespace(const struct sl_pp_token_info *input,
                 unsigned int *pi)
index 476991d581d20752246d5d4766be51ae7107e014..7af11c5ece77241a30676e680941dc151b9cb14c 100644 (file)
@@ -50,6 +50,9 @@ sl_pp_macro_new(void);
 void
 sl_pp_macro_free(struct sl_pp_macro *macro);
 
+void
+sl_pp_macro_reset(struct sl_pp_macro *macro);
+
 int
 sl_pp_macro_expand(struct sl_pp_context *context,
                    const struct sl_pp_token_info *input,
index 441de9439c5d26f6ed7638d58c549eeae45adbcc..4715eed2fcd94fba070748d8095ada3cb37c3af8 100644 (file)
@@ -71,10 +71,8 @@ sl_pp_process(struct sl_pp_context *context,
 {
    unsigned int i = 0;
    int found_eof = 0;
-   struct sl_pp_macro **macro;
    struct sl_pp_process_state state;
 
-   macro = &context->macro;
    memset(&state, 0, sizeof(state));
 
    while (!found_eof) {
@@ -126,16 +124,9 @@ sl_pp_process(struct sl_pp_context *context,
 
                if (!strcmp(name, "define")) {
                   if (context->if_value) {
-                     *macro = sl_pp_macro_new();
-                     if (!*macro) {
+                     if (sl_pp_process_define(context, input, first, last)) {
                         return -1;
                      }
-
-                     if (sl_pp_process_define(context, input, first, last, *macro)) {
-                        return -1;
-                     }
-
-                     macro = &(**macro).next;
                   }
                } else if (!strcmp(name, "if")) {
                   if (sl_pp_process_if(context, input, first, last)) {
index cc934bd89c531f8409d437ec46ea697034781070..66d61496a2dc15bf3a1bf54813a6235fb12fb375 100644 (file)
@@ -48,8 +48,7 @@ int
 sl_pp_process_define(struct sl_pp_context *context,
                      const struct sl_pp_token_info *input,
                      unsigned int first,
-                     unsigned int last,
-                     struct sl_pp_macro *macro);
+                     unsigned int last);
 
 int
 sl_pp_process_if(struct sl_pp_context *context,