From a294715612d14d64e12026361ff7cc29321607d6 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 26 Jun 2009 12:26:05 +0200 Subject: 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 1afe9a5d5e..50ec790cc5 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 e8200d55d7..1dbd10e30e 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 e8a23fedcd..0509646430 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 = ¯o->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 a8412f0651..a82c30cb16 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 476991d581..7af11c5ece 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 441de9439c..4715eed2fc 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 cc934bd89c..66d61496a2 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, -- cgit v1.2.3