Mesa (glsl-pp-rework-1): glsl: Allow for preprocessor macro redefinition.

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


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

Author: Michal Krol <michal at vmware.com>
Date:   Fri Jun 26 12:26:05 2009 +0200

glsl: Allow for preprocessor macro redefinition.

---

 src/glsl/pp/sl_pp_context.c |    1 +
 src/glsl/pp/sl_pp_context.h |    1 +
 src/glsl/pp/sl_pp_define.c  |   30 +++++++++++++++++++++++----
 src/glsl/pp/sl_pp_macro.c   |   45 +++++++++++++++++++++++++++++++-----------
 src/glsl/pp/sl_pp_macro.h   |    3 ++
 src/glsl/pp/sl_pp_process.c |   11 +---------
 src/glsl/pp/sl_pp_process.h |    3 +-
 7 files changed, 65 insertions(+), 29 deletions(-)

diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c
index 1afe9a5..50ec790 100644
--- a/src/glsl/pp/sl_pp_context.c
+++ b/src/glsl/pp/sl_pp_context.c
@@ -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;
 }
diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h
index e8200d5..1dbd10e 100644
--- a/src/glsl/pp/sl_pp_context.h
+++ b/src/glsl/pp/sl_pp_context.h
@@ -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;
diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c
index e8a23fe..0509646 100644
--- a/src/glsl/pp/sl_pp_define.c
+++ b/src/glsl/pp/sl_pp_define.c
@@ -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
diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c
index a8412f0..a82c30c 100644
--- a/src/glsl/pp/sl_pp_macro.c
+++ b/src/glsl/pp/sl_pp_macro.c
@@ -30,6 +30,15 @@
 #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)
diff --git a/src/glsl/pp/sl_pp_macro.h b/src/glsl/pp/sl_pp_macro.h
index 476991d..7af11c5 100644
--- a/src/glsl/pp/sl_pp_macro.h
+++ b/src/glsl/pp/sl_pp_macro.h
@@ -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,
diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c
index 441de94..4715eed 100644
--- a/src/glsl/pp/sl_pp_process.c
+++ b/src/glsl/pp/sl_pp_process.c
@@ -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)) {
diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h
index cc934bd..66d6149 100644
--- a/src/glsl/pp/sl_pp_process.h
+++ b/src/glsl/pp/sl_pp_process.h
@@ -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,




More information about the mesa-commit mailing list