summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Krol <michal@vmware.com>2009-06-26 12:26:05 +0200
committerMichal Krol <michal@vmware.com>2009-09-07 10:11:52 +0200
commita294715612d14d64e12026361ff7cc29321607d6 (patch)
tree34f6fdc5ad039a504b7f99eba340b3668225af32
parent153b179862411e9de14d26bbcff16bc81f1edc91 (diff)
glsl: Allow for preprocessor macro redefinition.
-rw-r--r--src/glsl/pp/sl_pp_context.c1
-rw-r--r--src/glsl/pp/sl_pp_context.h1
-rw-r--r--src/glsl/pp/sl_pp_define.c30
-rw-r--r--src/glsl/pp/sl_pp_macro.c45
-rw-r--r--src/glsl/pp/sl_pp_macro.h3
-rw-r--r--src/glsl/pp/sl_pp_process.c11
-rw-r--r--src/glsl/pp/sl_pp_process.h3
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 1afe9a5d5e0..50ec790cc50 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 e8200d55d7f..1dbd10e30ee 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 e8a23fedcd8..0509646430a 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 a8412f0651c..a82c30cb167 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 476991d581d..7af11c5ece7 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 441de9439c5..4715eed2fcd 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 cc934bd89c5..66d61496a2d 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,