From fd991d845a5f639b9b675a4840ad234c151d56b4 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 19 Jun 2009 12:02:28 +0200 Subject: glsl: Parse define directive in preprocessor. --- src/glsl/pp/sl_pp_define.c | 156 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 src/glsl/pp/sl_pp_define.c (limited to 'src/glsl/pp/sl_pp_define.c') diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c new file mode 100644 index 0000000000..5ce0f0551b --- /dev/null +++ b/src/glsl/pp/sl_pp_define.c @@ -0,0 +1,156 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include +#include "sl_pp_process.h" + + +static void +skip_whitespace(const struct sl_pp_token_info *input, + unsigned int *first, + unsigned int last) +{ + while (*first < last && input[*first].token == SL_PP_WHITESPACE) { + (*first)++; + } +} + + +static int +_parse_formal_args(const struct sl_pp_token_info *input, + unsigned int *first, + unsigned int last, + struct sl_pp_macro *macro) +{ + struct sl_pp_macro_formal_arg **arg; + + skip_whitespace(input, first, last); + if (*first < last) { + if (input[*first].token == SL_PP_RPAREN) { + (*first)++; + return 0; + } + } else { + /* Expected either an identifier or `)'. */ + return -1; + } + + arg = ¯o->arg; + + for (;;) { + if (*first < last && input[*first].token != SL_PP_IDENTIFIER) { + /* Expected an identifier. */ + return -1; + } + + *arg = malloc(sizeof(struct sl_pp_macro_formal_arg)); + if (!*arg) { + return -1; + } + + (**arg).name = input[*first].data.identifier; + (*first)++; + + (**arg).next = NULL; + arg = &(**arg).next; + + skip_whitespace(input, first, last); + if (*first < last) { + if (input[*first].token == SL_PP_COMMA) { + (*first)++; + } else if (input[*first].token == SL_PP_RPAREN) { + (*first)++; + return 0; + } else { + /* Expected either `,' or `)'. */ + return -1; + } + } else { + /* Expected either `,' or `)'. */ + return -1; + } + } +} + + +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) +{ + macro->name = -1; + macro->arg = NULL; + macro->body = NULL; + macro->next = NULL; + + if (first < last && input[first].token == SL_PP_IDENTIFIER) { + macro->name = input[first].data.identifier; + first++; + } + + if (macro->name == -1) { + return -1; + } + + /* + * 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 + * of a whitespace matters and it's the only reason why we are dealing + * with whitespace at this level. + */ + if (first < last && input[first].token == SL_PP_LPAREN) { + first++; + if (_parse_formal_args(input, &first, last, macro)) { + return -1; + } + } + + /* Trim whitespace from the left side. */ + skip_whitespace(input, &first, last); + + /* Trom whitespace from the right side. */ + while (first < last && input[last - 1].token == SL_PP_WHITESPACE) { + last--; + } + + /* All that is left between first and last is the macro definition. */ + macro->body_len = last - first; + if (macro->body_len) { + macro->body = malloc(sizeof(struct sl_pp_token_info) * macro->body_len); + if (!macro->body) { + return -1; + } + + memcpy(macro->body, + &input[first], + sizeof(struct sl_pp_token_info) * macro->body_len); + } + + return 0; +} -- cgit v1.2.3 From 6a11d4150cfcdd646c17f8b365b5481c2c583208 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 22 Jun 2009 09:05:29 +0200 Subject: glsl: Implement macro expansion. --- src/glsl/pp/sl_pp_define.c | 38 +++++---- src/glsl/pp/sl_pp_macro.c | 204 ++++++++++++++++++++++++++++++++++++++++++++ src/glsl/pp/sl_pp_macro.h | 9 +- src/glsl/pp/sl_pp_process.c | 31 ++++--- src/glsl/pp/sl_pp_process.h | 6 ++ 5 files changed, 259 insertions(+), 29 deletions(-) (limited to 'src/glsl/pp/sl_pp_define.c') diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c index 5ce0f0551b..39d1435064 100644 --- a/src/glsl/pp/sl_pp_define.c +++ b/src/glsl/pp/sl_pp_define.c @@ -48,6 +48,8 @@ _parse_formal_args(const struct sl_pp_token_info *input, { struct sl_pp_macro_formal_arg **arg; + macro->num_args = 0; + skip_whitespace(input, first, last); if (*first < last) { if (input[*first].token == SL_PP_RPAREN) { @@ -78,6 +80,8 @@ _parse_formal_args(const struct sl_pp_token_info *input, (**arg).next = NULL; arg = &(**arg).next; + macro->num_args++; + skip_whitespace(input, first, last); if (*first < last) { if (input[*first].token == SL_PP_COMMA) { @@ -104,7 +108,12 @@ sl_pp_process_define(struct sl_pp_context *context, unsigned int last, struct sl_pp_macro *macro) { + unsigned int i; + unsigned int body_len; + unsigned int j; + macro->name = -1; + macro->num_args = -1; macro->arg = NULL; macro->body = NULL; macro->next = NULL; @@ -131,26 +140,25 @@ sl_pp_process_define(struct sl_pp_context *context, } } - /* Trim whitespace from the left side. */ - skip_whitespace(input, &first, last); + /* Calculate body size, trim out whitespace, make room for EOF. */ + body_len = 1; + for (i = first; i < last; i++) { + if (input[i].token != SL_PP_WHITESPACE) { + body_len++; + } + } - /* Trom whitespace from the right side. */ - while (first < last && input[last - 1].token == SL_PP_WHITESPACE) { - last--; + macro->body = malloc(sizeof(struct sl_pp_token_info) * body_len); + if (!macro->body) { + return -1; } - /* All that is left between first and last is the macro definition. */ - macro->body_len = last - first; - if (macro->body_len) { - macro->body = malloc(sizeof(struct sl_pp_token_info) * macro->body_len); - if (!macro->body) { - return -1; + for (j = 0, i = first; i < last; i++) { + if (input[i].token != SL_PP_WHITESPACE) { + macro->body[j++] = input[i]; } - - memcpy(macro->body, - &input[first], - sizeof(struct sl_pp_token_info) * macro->body_len); } + macro->body[j++].token = SL_PP_EOF; return 0; } diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index eed0978304..82591b9d77 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -27,8 +27,18 @@ #include #include "sl_pp_macro.h" +#include "sl_pp_process.h" +static void +skip_whitespace(const struct sl_pp_token_info *input, + unsigned int *pi) +{ + while (input[*pi].token == SL_PP_WHITESPACE) { + (*pi)++; + } +} + void sl_pp_macro_free(struct sl_pp_macro *macro) { @@ -49,3 +59,197 @@ sl_pp_macro_free(struct sl_pp_macro *macro) macro = next_macro; } } + +int +sl_pp_macro_expand(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int *pi, + struct sl_pp_macro *local, + struct sl_pp_process_state *state) +{ + int macro_name; + struct sl_pp_macro *macro = NULL; + struct sl_pp_macro *actual_arg = NULL; + unsigned int j; + + if (input[*pi].token != SL_PP_IDENTIFIER) { + return -1; + } + + macro_name = input[*pi].data.identifier; + + if (local) { + for (macro = local; macro; macro = macro->next) { + if (macro->name == macro_name) { + break; + } + } + } + + if (!macro) { + for (macro = context->macro; macro; macro = macro->next) { + if (macro->name == macro_name) { + break; + } + } + } + + if (!macro) { + if (sl_pp_process_out(state, &input[*pi])) { + return -1; + } + (*pi)++; + return 0; + } + + (*pi)++; + + if (macro->num_args >= 0) { + skip_whitespace(input, pi); + if (input[*pi].token != SL_PP_LPAREN) { + return -1; + } + (*pi)++; + skip_whitespace(input, pi); + } + + if (macro->num_args > 0) { + struct sl_pp_macro_formal_arg *formal_arg = macro->arg; + struct sl_pp_macro **pmacro = &actual_arg; + + for (j = 0; j < (unsigned int)macro->num_args; j++) { + unsigned int body_len; + unsigned int i; + int done = 0; + unsigned int paren_nesting = 0; + unsigned int k; + + *pmacro = malloc(sizeof(struct sl_pp_macro)); + if (!*pmacro) { + return -1; + } + + (**pmacro).name = formal_arg->name; + (**pmacro).num_args = -1; + (**pmacro).arg = NULL; + (**pmacro).body = NULL; + (**pmacro).next = NULL; + + body_len = 1; + for (i = *pi; !done; i++) { + switch (input[i].token) { + case SL_PP_WHITESPACE: + break; + + case SL_PP_COMMA: + if (!paren_nesting) { + if (j < (unsigned int)macro->num_args - 1) { + done = 1; + } else { + return -1; + } + } else { + body_len++; + } + break; + + case SL_PP_LPAREN: + paren_nesting++; + body_len++; + break; + + case SL_PP_RPAREN: + if (!paren_nesting) { + if (j == (unsigned int)macro->num_args - 1) { + done = 1; + } else { + return -1; + } + } else { + paren_nesting--; + body_len++; + } + break; + + case SL_PP_EOF: + return -1; + + default: + body_len++; + } + } + + (**pmacro).body = malloc(sizeof(struct sl_pp_token_info) * body_len); + if (!(**pmacro).body) { + return -1; + } + + for (done = 0, k = 0, i = *pi; !done; i++) { + switch (input[i].token) { + case SL_PP_WHITESPACE: + break; + + case SL_PP_COMMA: + if (!paren_nesting && j < (unsigned int)macro->num_args - 1) { + done = 1; + } else { + (**pmacro).body[k++] = input[i]; + } + break; + + case SL_PP_LPAREN: + paren_nesting++; + (**pmacro).body[k++] = input[i]; + break; + + case SL_PP_RPAREN: + if (!paren_nesting && j == (unsigned int)macro->num_args - 1) { + done = 1; + } else { + paren_nesting--; + (**pmacro).body[k++] = input[i]; + } + break; + + default: + (**pmacro).body[k++] = input[i]; + } + } + + (**pmacro).body[k++].token = SL_PP_EOF; + (*pi) = i; + + formal_arg = formal_arg->next; + pmacro = &(**pmacro).next; + } + } + + /* Right paren for non-empty argument list has already been eaten. */ + if (macro->num_args == 0) { + skip_whitespace(input, pi); + if (input[*pi].token != SL_PP_RPAREN) { + return -1; + } + (*pi)++; + } + + for (j = 0;;) { + switch (macro->body[j].token) { + case SL_PP_IDENTIFIER: + if (sl_pp_macro_expand(context, macro->body, &j, actual_arg, state)) { + return -1; + } + break; + + case SL_PP_EOF: + sl_pp_macro_free(actual_arg); + return 0; + + default: + if (sl_pp_process_out(state, ¯o->body[j])) { + return -1; + } + j++; + } + } +} diff --git a/src/glsl/pp/sl_pp_macro.h b/src/glsl/pp/sl_pp_macro.h index 4ebbff5590..eeb338eec4 100644 --- a/src/glsl/pp/sl_pp_macro.h +++ b/src/glsl/pp/sl_pp_macro.h @@ -38,13 +38,20 @@ struct sl_pp_macro_formal_arg { struct sl_pp_macro { int name; + int num_args; struct sl_pp_macro_formal_arg *arg; struct sl_pp_token_info *body; - unsigned int body_len; struct sl_pp_macro *next; }; void sl_pp_macro_free(struct sl_pp_macro *macro); +int +sl_pp_macro_expand(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int *pi, + struct sl_pp_macro *local, + struct sl_pp_process_state *state); + #endif /* SL_PP_MACRO_H */ diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index 2a375df71a..e930966604 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -39,16 +39,16 @@ skip_whitespace(const struct sl_pp_token_info *input, } -struct process_state { +struct sl_pp_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) +int +sl_pp_process_out(struct sl_pp_process_state *state, + const struct sl_pp_token_info *token) { if (state->out_len >= state->out_max) { unsigned int new_max = state->out_max; @@ -72,7 +72,6 @@ out_token(struct process_state *state, return 0; } - int sl_pp_process(struct sl_pp_context *context, const struct sl_pp_token_info *input, @@ -81,7 +80,7 @@ sl_pp_process(struct sl_pp_context *context, unsigned int i = 0; int found_eof = 0; struct sl_pp_macro **macro; - struct process_state state; + struct sl_pp_process_state state; macro = &context->macro; memset(&state, 0, sizeof(state)); @@ -110,7 +109,7 @@ sl_pp_process(struct sl_pp_context *context, switch (input[i].token) { case SL_PP_NEWLINE: /* Preserve newline just for the sake of line numbering. */ - if (out_token(&state, &input[i])) { + if (sl_pp_process_out(&state, &input[i])) { return -1; } i++; @@ -118,7 +117,7 @@ sl_pp_process(struct sl_pp_context *context, break; case SL_PP_EOF: - if (out_token(&state, &input[i])) { + if (sl_pp_process_out(&state, &input[i])) { return -1; } i++; @@ -152,7 +151,7 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_NEWLINE: /* Empty directive. */ - if (out_token(&state, &input[i])) { + if (sl_pp_process_out(&state, &input[i])) { return -1; } i++; @@ -160,7 +159,7 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_EOF: /* Empty directive. */ - if (out_token(&state, &input[i])) { + if (sl_pp_process_out(&state, &input[i])) { return -1; } i++; @@ -182,7 +181,7 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_NEWLINE: /* Preserve newline just for the sake of line numbering. */ - if (out_token(&state, &input[i])) { + if (sl_pp_process_out(&state, &input[i])) { return -1; } i++; @@ -190,7 +189,7 @@ sl_pp_process(struct sl_pp_context *context, break; case SL_PP_EOF: - if (out_token(&state, &input[i])) { + if (sl_pp_process_out(&state, &input[i])) { return -1; } i++; @@ -198,8 +197,14 @@ sl_pp_process(struct sl_pp_context *context, found_eol = 1; break; + case SL_PP_IDENTIFIER: + if (sl_pp_macro_expand(context, input, &i, NULL, &state)) { + return -1; + } + break; + default: - if (out_token(&state, &input[i])) { + if (sl_pp_process_out(&state, &input[i])) { return -1; } i++; diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h index f7df9a2850..37cdc4c9a7 100644 --- a/src/glsl/pp/sl_pp_process.h +++ b/src/glsl/pp/sl_pp_process.h @@ -33,6 +33,8 @@ #include "sl_pp_token.h" +struct sl_pp_process_state; + int sl_pp_process(struct sl_pp_context *context, const struct sl_pp_token_info *input, @@ -45,4 +47,8 @@ sl_pp_process_define(struct sl_pp_context *context, unsigned int last, struct sl_pp_macro *macro); +int +sl_pp_process_out(struct sl_pp_process_state *state, + const struct sl_pp_token_info *token); + #endif /* SL_PP_PROCESS_H */ -- cgit v1.2.3 From 2dad8ed9d68289ba25a4023da12fc5ddf6a621dd Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 22 Jun 2009 09:14:14 +0200 Subject: glsl: Centralise sl_pp_macro constructor. --- src/glsl/pp/sl_pp_define.c | 6 ------ src/glsl/pp/sl_pp_macro.c | 29 +++++++++++++++++++---------- src/glsl/pp/sl_pp_macro.h | 5 ++++- src/glsl/pp/sl_pp_process.c | 2 +- 4 files changed, 24 insertions(+), 18 deletions(-) (limited to 'src/glsl/pp/sl_pp_define.c') diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c index 39d1435064..e8a23fedcd 100644 --- a/src/glsl/pp/sl_pp_define.c +++ b/src/glsl/pp/sl_pp_define.c @@ -112,12 +112,6 @@ sl_pp_process_define(struct sl_pp_context *context, unsigned int body_len; unsigned int j; - macro->name = -1; - macro->num_args = -1; - macro->arg = NULL; - macro->body = NULL; - macro->next = NULL; - if (first < last && input[first].token == SL_PP_IDENTIFIER) { macro->name = input[first].data.identifier; first++; diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index 82591b9d77..0138270c67 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -30,13 +30,17 @@ #include "sl_pp_process.h" -static void -skip_whitespace(const struct sl_pp_token_info *input, - unsigned int *pi) +struct sl_pp_macro * +sl_pp_macro_new(void) { - while (input[*pi].token == SL_PP_WHITESPACE) { - (*pi)++; + struct sl_pp_macro *macro; + + macro = calloc(1, sizeof(struct sl_pp_macro)); + if (macro) { + macro->name = -1; + macro->num_args = -1; } + return macro; } void @@ -60,6 +64,15 @@ sl_pp_macro_free(struct sl_pp_macro *macro) } } +static void +skip_whitespace(const struct sl_pp_token_info *input, + unsigned int *pi) +{ + while (input[*pi].token == SL_PP_WHITESPACE) { + (*pi)++; + } +} + int sl_pp_macro_expand(struct sl_pp_context *context, const struct sl_pp_token_info *input, @@ -124,16 +137,12 @@ sl_pp_macro_expand(struct sl_pp_context *context, unsigned int paren_nesting = 0; unsigned int k; - *pmacro = malloc(sizeof(struct sl_pp_macro)); + *pmacro = sl_pp_macro_new(); if (!*pmacro) { return -1; } (**pmacro).name = formal_arg->name; - (**pmacro).num_args = -1; - (**pmacro).arg = NULL; - (**pmacro).body = NULL; - (**pmacro).next = NULL; body_len = 1; for (i = *pi; !done; i++) { diff --git a/src/glsl/pp/sl_pp_macro.h b/src/glsl/pp/sl_pp_macro.h index eeb338eec4..63edd21aa2 100644 --- a/src/glsl/pp/sl_pp_macro.h +++ b/src/glsl/pp/sl_pp_macro.h @@ -38,12 +38,15 @@ struct sl_pp_macro_formal_arg { struct sl_pp_macro { int name; - int num_args; + int num_args; /* -1 means no args, 0 means `()' */ struct sl_pp_macro_formal_arg *arg; struct sl_pp_token_info *body; struct sl_pp_macro *next; }; +struct sl_pp_macro * +sl_pp_macro_new(void); + void sl_pp_macro_free(struct sl_pp_macro *macro); diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index e930966604..baffaf2cd9 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -133,7 +133,7 @@ sl_pp_process(struct sl_pp_context *context, last = i - 1; if (!strcmp(name, "define")) { - *macro = malloc(sizeof(struct sl_pp_macro)); + *macro = sl_pp_macro_new(); if (!*macro) { return -1; } -- cgit v1.2.3 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(-) (limited to 'src/glsl/pp/sl_pp_define.c') 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 From 3dc2b5f71c2a519409becb6c1f177b5981fbacf7 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 26 Jun 2009 12:48:14 +0200 Subject: glsl: Implement `undef' preprocessor directive. --- src/glsl/pp/sl_pp_define.c | 35 +++++++++++++++++++++++++++++++++++ src/glsl/pp/sl_pp_process.c | 22 +++++++++++++--------- src/glsl/pp/sl_pp_process.h | 6 ++++++ 3 files changed, 54 insertions(+), 9 deletions(-) (limited to 'src/glsl/pp/sl_pp_define.c') diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c index 0509646430..9bc9fb5359 100644 --- a/src/glsl/pp/sl_pp_define.c +++ b/src/glsl/pp/sl_pp_define.c @@ -176,3 +176,38 @@ sl_pp_process_define(struct sl_pp_context *context, return 0; } + + +int +sl_pp_process_undef(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last) +{ + int macro_name = -1; + struct sl_pp_macro **pmacro; + struct sl_pp_macro *macro; + + if (first < last && input[first].token == SL_PP_IDENTIFIER) { + macro_name = input[first].data.identifier; + } + if (macro_name == -1) { + return 0; + } + + for (pmacro = &context->macro; *pmacro; pmacro = &(**pmacro).next) { + if ((**pmacro).name == macro_name) { + break; + } + } + if (!*pmacro) { + return 0; + } + + macro = *pmacro; + *pmacro = macro->next; + macro->next = NULL; + sl_pp_macro_free(macro); + + return 0; +} diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index 4715eed2fc..c17a3ac7ce 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -122,13 +122,7 @@ sl_pp_process(struct sl_pp_context *context, last = i - 1; - if (!strcmp(name, "define")) { - if (context->if_value) { - if (sl_pp_process_define(context, input, first, last)) { - return -1; - } - } - } else if (!strcmp(name, "if")) { + if (!strcmp(name, "if")) { if (sl_pp_process_if(context, input, first, last)) { return -1; } @@ -152,8 +146,18 @@ sl_pp_process(struct sl_pp_context *context, if (sl_pp_process_endif(context, input, first, last)) { return -1; } - } else { - /* XXX: Ignore. */ + } else if (context->if_value) { + if (!strcmp(name, "define")) { + if (sl_pp_process_define(context, input, first, last)) { + return -1; + } + } else if (!strcmp(name, "undef")) { + if (sl_pp_process_undef(context, input, first, last)) { + return -1; + } + } else { + /* XXX: Ignore. */ + } } } break; diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h index 66d61496a2..61e67fef0b 100644 --- a/src/glsl/pp/sl_pp_process.h +++ b/src/glsl/pp/sl_pp_process.h @@ -50,6 +50,12 @@ sl_pp_process_define(struct sl_pp_context *context, unsigned int first, unsigned int last); +int +sl_pp_process_undef(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last); + int sl_pp_process_if(struct sl_pp_context *context, const struct sl_pp_token_info *input, -- cgit v1.2.3 From 0ddf41d34d511b339e0bb5a59673765f1bf0b3a5 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 17 Sep 2009 11:51:35 +0200 Subject: glsl/pp: Add remaining error messages. --- src/glsl/pp/sl_pp_context.c | 1 + src/glsl/pp/sl_pp_context.h | 2 +- src/glsl/pp/sl_pp_define.c | 19 ++++++++++++------ src/glsl/pp/sl_pp_expression.c | 2 ++ src/glsl/pp/sl_pp_if.c | 35 +++++++++++++++++++------------- src/glsl/pp/sl_pp_line.c | 45 ++++++++---------------------------------- src/glsl/pp/sl_pp_macro.c | 18 ++++++++++++++++- src/glsl/pp/sl_pp_pragma.c | 1 + src/glsl/pp/sl_pp_version.c | 42 ++++----------------------------------- 9 files changed, 68 insertions(+), 97 deletions(-) (limited to 'src/glsl/pp/sl_pp_define.c') diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index 88a002c1c7..b196d8102a 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -85,6 +85,7 @@ sl_pp_context_add_unique_str(struct sl_pp_context *context, } if (!context->cstr_pool) { + strcpy(context->error_msg, "out of memory"); return -1; } diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index 5826f9448d..8bed142045 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -47,7 +47,7 @@ struct sl_pp_context { unsigned int if_stack[SL_PP_MAX_IF_NESTING]; unsigned int if_ptr; - int if_value; + unsigned int if_value; char error_msg[SL_PP_MAX_ERROR_MSG]; diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c index 9bc9fb5359..391178aa69 100644 --- a/src/glsl/pp/sl_pp_define.c +++ b/src/glsl/pp/sl_pp_define.c @@ -41,7 +41,8 @@ skip_whitespace(const struct sl_pp_token_info *input, static int -_parse_formal_args(const struct sl_pp_token_info *input, +_parse_formal_args(struct sl_pp_context *context, + const struct sl_pp_token_info *input, unsigned int *first, unsigned int last, struct sl_pp_macro *macro) @@ -57,7 +58,7 @@ _parse_formal_args(const struct sl_pp_token_info *input, return 0; } } else { - /* Expected either an identifier or `)'. */ + strcpy(context->error_msg, "expected either an identifier or `)'"); return -1; } @@ -65,12 +66,13 @@ _parse_formal_args(const struct sl_pp_token_info *input, for (;;) { if (*first < last && input[*first].token != SL_PP_IDENTIFIER) { - /* Expected an identifier. */ + strcpy(context->error_msg, "expected an identifier"); return -1; } *arg = malloc(sizeof(struct sl_pp_macro_formal_arg)); if (!*arg) { + strcpy(context->error_msg, "out of memory"); return -1; } @@ -90,14 +92,16 @@ _parse_formal_args(const struct sl_pp_token_info *input, (*first)++; return 0; } else { - /* Expected either `,' or `)'. */ + strcpy(context->error_msg, "expected either `,' or `)'"); return -1; } } else { - /* Expected either `,' or `)'. */ + strcpy(context->error_msg, "expected either `,' or `)'"); return -1; } } + + /* Should not gete here. */ } @@ -118,6 +122,7 @@ sl_pp_process_define(struct sl_pp_context *context, first++; } if (macro_name == -1) { + strcpy(context->error_msg, "expected an identifier"); return -1; } @@ -130,6 +135,7 @@ sl_pp_process_define(struct sl_pp_context *context, if (!macro) { macro = sl_pp_macro_new(); if (!macro) { + strcpy(context->error_msg, "out of memory"); return -1; } @@ -149,7 +155,7 @@ sl_pp_process_define(struct sl_pp_context *context, */ if (first < last && input[first].token == SL_PP_LPAREN) { first++; - if (_parse_formal_args(input, &first, last, macro)) { + if (_parse_formal_args(context, input, &first, last, macro)) { return -1; } } @@ -164,6 +170,7 @@ sl_pp_process_define(struct sl_pp_context *context, macro->body = malloc(sizeof(struct sl_pp_token_info) * body_len); if (!macro->body) { + strcpy(context->error_msg, "out of memory"); return -1; } diff --git a/src/glsl/pp/sl_pp_expression.c b/src/glsl/pp/sl_pp_expression.c index a692430abb..6b2329ed1a 100644 --- a/src/glsl/pp/sl_pp_expression.c +++ b/src/glsl/pp/sl_pp_expression.c @@ -47,6 +47,7 @@ _parse_primary(struct parse_context *ctx, ctx->input++; } else { if (ctx->input->token != SL_PP_LPAREN) { + strcpy(ctx->context->error_msg, "expected `('"); return -1; } ctx->input++; @@ -54,6 +55,7 @@ _parse_primary(struct parse_context *ctx, return -1; } if (ctx->input->token != SL_PP_RPAREN) { + strcpy(ctx->context->error_msg, "expected `)'"); return -1; } ctx->input++; diff --git a/src/glsl/pp/sl_pp_if.c b/src/glsl/pp/sl_pp_if.c index 90b8051237..44bbefa357 100644 --- a/src/glsl/pp/sl_pp_if.c +++ b/src/glsl/pp/sl_pp_if.c @@ -59,7 +59,7 @@ _parse_defined(struct sl_pp_context *context, } if (input[*pi].token != SL_PP_IDENTIFIER) { - /* Identifier expected. */ + strcpy(context->error_msg, "expected an identifier"); return -1; } @@ -75,7 +75,7 @@ _parse_defined(struct sl_pp_context *context, if (parens) { skip_whitespace(input, pi); if (input[*pi].token != SL_PP_RPAREN) { - /* `)' expected */ + strcpy(context->error_msg, "expected `)'"); return -1; } (*pi)++; @@ -91,10 +91,15 @@ _parse_defined(struct sl_pp_context *context, return -1; } - return sl_pp_process_out(state, &result); + if (sl_pp_process_out(state, &result)) { + strcpy(context->error_msg, "out of memory"); + return -1; + } + + return 0; } -static int +static unsigned int _evaluate_if_stack(struct sl_pp_context *context) { unsigned int i; @@ -119,7 +124,7 @@ _parse_if(struct sl_pp_context *context, int result; if (!context->if_ptr) { - /* #if nesting too deep. */ + strcpy(context->error_msg, "`#if' nesting too deep"); return -1; } @@ -151,6 +156,7 @@ _parse_if(struct sl_pp_context *context, default: if (sl_pp_process_out(&state, &input[i])) { + strcpy(context->error_msg, "out of memory"); free(state.out); return -1; } @@ -160,6 +166,7 @@ _parse_if(struct sl_pp_context *context, eof.token = SL_PP_EOF; if (sl_pp_process_out(&state, &eof)) { + strcpy(context->error_msg, "out of memory"); free(state.out); return -1; } @@ -182,13 +189,13 @@ static int _parse_else(struct sl_pp_context *context) { if (context->if_ptr == SL_PP_MAX_IF_NESTING) { - /* No matching #if. */ + strcpy(context->error_msg, "no matching `#if'"); return -1; } /* Bit b1 indicates we already went through #else. */ if (context->if_stack[context->if_ptr] & 2) { - /* No matching #if. */ + strcpy(context->error_msg, "no matching `#if'"); return -1; } @@ -217,7 +224,7 @@ sl_pp_process_ifdef(struct sl_pp_context *context, unsigned int i; if (!context->if_ptr) { - /* #if nesting too deep. */ + strcpy(context->error_msg, "`#if' nesting too deep"); return -1; } @@ -246,12 +253,12 @@ sl_pp_process_ifdef(struct sl_pp_context *context, break; default: - /* Expected an identifier. */ + strcpy(context->error_msg, "expected an identifier"); return -1; } } - /* Expected an identifier. */ + strcpy(context->error_msg, "expected an identifier"); return -1; } @@ -264,7 +271,7 @@ sl_pp_process_ifndef(struct sl_pp_context *context, unsigned int i; if (!context->if_ptr) { - /* #if nesting too deep. */ + strcpy(context->error_msg, "`#if' nesting too deep"); return -1; } @@ -293,12 +300,12 @@ sl_pp_process_ifndef(struct sl_pp_context *context, break; default: - /* Expected an identifier. */ + strcpy(context->error_msg, "expected an identifier"); return -1; } } - /* Expected an identifier. */ + strcpy(context->error_msg, "expected an identifier"); return -1; } @@ -341,7 +348,7 @@ sl_pp_process_endif(struct sl_pp_context *context, unsigned int last) { if (context->if_ptr == SL_PP_MAX_IF_NESTING) { - /* No matching #if. */ + strcpy(context->error_msg, "no matching `#if'"); return -1; } diff --git a/src/glsl/pp/sl_pp_line.c b/src/glsl/pp/sl_pp_line.c index a56417a861..c38f4b0f2e 100644 --- a/src/glsl/pp/sl_pp_line.c +++ b/src/glsl/pp/sl_pp_line.c @@ -29,31 +29,6 @@ #include "sl_pp_process.h" -static int -_parse_integer(const char *input, - unsigned int *number) -{ - unsigned int n = 0; - - while (*input >= '0' && *input <= '9') { - if (n * 10 < n) { - /* Overflow. */ - return -1; - } - - n = n * 10 + (*input++ - '0'); - } - - if (*input != '\0') { - /* Invalid decimal number. */ - return -1; - } - - *number = n; - return 0; -} - - int sl_pp_process_line(struct sl_pp_context *context, const struct sl_pp_token_info *input, @@ -65,7 +40,6 @@ sl_pp_process_line(struct sl_pp_context *context, struct sl_pp_process_state state; int line_number = -1; int file_number = -1; - const char *str; unsigned int line; memset(&state, 0, sizeof(state)); @@ -84,6 +58,7 @@ sl_pp_process_line(struct sl_pp_context *context, default: if (sl_pp_process_out(&state, &input[i])) { + strcpy(context->error_msg, "out of memory"); free(state.out); return -1; } @@ -94,7 +69,7 @@ sl_pp_process_line(struct sl_pp_context *context, if (state.out_len > 0 && state.out[0].token == SL_PP_NUMBER) { line_number = state.out[0].data.number; } else { - strcpy(context->error_msg, "expected number after `#line'"); + strcpy(context->error_msg, "expected a number after `#line'"); free(state.out); return -1; } @@ -103,13 +78,13 @@ sl_pp_process_line(struct sl_pp_context *context, if (state.out[1].token == SL_PP_NUMBER) { file_number = state.out[1].data.number; } else { - strcpy(context->error_msg, "expected number after line number"); + strcpy(context->error_msg, "expected a number after line number"); free(state.out); return -1; } if (state.out_len > 2) { - strcpy(context->error_msg, "expected end of line after file number"); + strcpy(context->error_msg, "expected an end of line after file number"); free(state.out); return -1; } @@ -117,10 +92,7 @@ sl_pp_process_line(struct sl_pp_context *context, free(state.out); - str = sl_pp_context_cstr(context, line_number); - if (_parse_integer(str, &line)) { - return -1; - } + line = atoi(sl_pp_context_cstr(context, line_number)); if (context->line != line) { struct sl_pp_token_info ti; @@ -128,6 +100,7 @@ sl_pp_process_line(struct sl_pp_context *context, ti.token = SL_PP_LINE; ti.data.line = line; if (sl_pp_process_out(pstate, &ti)) { + strcpy(context->error_msg, "out of memory"); return -1; } @@ -137,10 +110,7 @@ sl_pp_process_line(struct sl_pp_context *context, if (file_number != -1) { unsigned int file; - str = sl_pp_context_cstr(context, file_number); - if (_parse_integer(str, &file)) { - return -1; - } + file_number = atoi(sl_pp_context_cstr(context, file_number)); if (context->file != file) { struct sl_pp_token_info ti; @@ -148,6 +118,7 @@ sl_pp_process_line(struct sl_pp_context *context, ti.token = SL_PP_FILE; ti.data.file = file; if (sl_pp_process_out(pstate, &ti)) { + strcpy(context->error_msg, "out of memory"); return -1; } diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index d14c982555..7793562781 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -107,7 +107,12 @@ _out_number(struct sl_pp_context *context, ti.token = SL_PP_NUMBER; ti.data.number = sl_pp_context_add_unique_str(context, buf); - return sl_pp_process_out(state, &ti); + if (sl_pp_process_out(state, &ti)) { + strcpy(context->error_msg, "out of memory"); + return -1; + } + + return 0; } int @@ -125,6 +130,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, unsigned int j; if (input[*pi].token != SL_PP_IDENTIFIER) { + strcpy(context->error_msg, "expected an identifier"); return -1; } @@ -172,6 +178,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, if (!macro) { if (!mute) { if (sl_pp_process_out(state, &input[*pi])) { + strcpy(context->error_msg, "out of memory"); return -1; } } @@ -184,6 +191,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, if (macro->num_args >= 0) { skip_whitespace(input, pi); if (input[*pi].token != SL_PP_LPAREN) { + strcpy(context->error_msg, "expected `('"); return -1; } (*pi)++; @@ -203,6 +211,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, *pmacro = sl_pp_macro_new(); if (!*pmacro) { + strcpy(context->error_msg, "out of memory"); return -1; } @@ -219,6 +228,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, if (j < (unsigned int)macro->num_args - 1) { done = 1; } else { + strcpy(context->error_msg, "too many actual macro arguments"); return -1; } } else { @@ -236,6 +246,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, if (j == (unsigned int)macro->num_args - 1) { done = 1; } else { + strcpy(context->error_msg, "too few actual macro arguments"); return -1; } } else { @@ -245,6 +256,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, break; case SL_PP_EOF: + strcpy(context->error_msg, "too few actual macro arguments"); return -1; default: @@ -254,6 +266,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, (**pmacro).body = malloc(sizeof(struct sl_pp_token_info) * body_len); if (!(**pmacro).body) { + strcpy(context->error_msg, "out of memory"); return -1; } @@ -301,6 +314,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, if (macro->num_args == 0) { skip_whitespace(input, pi); if (input[*pi].token != SL_PP_RPAREN) { + strcpy(context->error_msg, "expected `)'"); return -1; } (*pi)++; @@ -310,6 +324,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, switch (macro->body[j].token) { case SL_PP_NEWLINE: if (sl_pp_process_out(state, ¯o->body[j])) { + strcpy(context->error_msg, "out of memory"); return -1; } j++; @@ -328,6 +343,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, default: if (!mute) { if (sl_pp_process_out(state, ¯o->body[j])) { + strcpy(context->error_msg, "out of memory"); return -1; } } diff --git a/src/glsl/pp/sl_pp_pragma.c b/src/glsl/pp/sl_pp_pragma.c index 059bc6f288..1cd9fd8234 100644 --- a/src/glsl/pp/sl_pp_pragma.c +++ b/src/glsl/pp/sl_pp_pragma.c @@ -99,6 +99,7 @@ sl_pp_process_pragma(struct sl_pp_context *context, /* Ignore the tokens that follow. */ if (sl_pp_process_out(state, &out)) { + strcpy(context->error_msg, "out of memory"); return -1; } diff --git a/src/glsl/pp/sl_pp_version.c b/src/glsl/pp/sl_pp_version.c index 82acdd1d5a..6cd63f4925 100644 --- a/src/glsl/pp/sl_pp_version.c +++ b/src/glsl/pp/sl_pp_version.c @@ -25,34 +25,10 @@ * **************************************************************************/ +#include #include "sl_pp_version.h" -static int -_parse_integer(const char *input, - unsigned int *number) -{ - unsigned int n = 0; - - while (*input >= '0' && *input <= '9') { - if (n * 10 < n) { - /* Overflow. */ - return -1; - } - - n = n * 10 + (*input++ - '0'); - } - - if (*input != '\0') { - /* Invalid decimal number. */ - return -1; - } - - *number = n; - return 0; -} - - int sl_pp_version(struct sl_pp_context *context, const struct sl_pp_token_info *input, @@ -130,19 +106,9 @@ sl_pp_version(struct sl_pp_context *context, break; case SL_PP_NUMBER: - { - const char *num = sl_pp_context_cstr(context, input[i].data.number); - - if (!num) { - return -1; - } - if (_parse_integer(num, version)) { - strcpy(context->error_msg, "expected version number after `#version'"); - return -1; - } - i++; - found_number = 1; - } + *version = atoi(sl_pp_context_cstr(context, input[i].data.number)); + i++; + found_number = 1; break; default: -- cgit v1.2.3 From 32966991c629fa43818f42912deb9deca913ef60 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 23 Sep 2009 09:33:12 +0200 Subject: glsl/pp: Check for reserved macro names. --- src/glsl/pp/sl_pp_define.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/glsl/pp/sl_pp_define.c') diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c index 391178aa69..d18a7ee289 100644 --- a/src/glsl/pp/sl_pp_define.c +++ b/src/glsl/pp/sl_pp_define.c @@ -26,7 +26,9 @@ **************************************************************************/ #include +#include #include "sl_pp_process.h" +#include "sl_pp_public.h" static void @@ -126,6 +128,20 @@ sl_pp_process_define(struct sl_pp_context *context, return -1; } + /* Check for reserved macro names */ + { + const char *name = sl_pp_context_cstr(context, macro_name); + + if (strstr(name, "__")) { + strcpy(context->error_msg, "macro names containing `__' are reserved"); + return 1; + } + if (name[0] == 'G' && name[1] == 'L' && name[2] == '_') { + strcpy(context->error_msg, "macro names prefixed with `GL_' are reserved"); + return 1; + } + } + for (macro = context->macro; macro; macro = macro->next) { if (macro->name == macro_name) { break; -- cgit v1.2.3 From 547ac2869b1e1bbdbf8e51cd40d50e6ab0f4f9f1 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 17 Nov 2009 09:06:53 +0100 Subject: glsl/pp: Fix macro formal argument parsing, more descriptive error msgs. --- src/glsl/pp/sl_pp_define.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/glsl/pp/sl_pp_define.c') diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c index d18a7ee289..e004c9f95b 100644 --- a/src/glsl/pp/sl_pp_define.c +++ b/src/glsl/pp/sl_pp_define.c @@ -60,7 +60,7 @@ _parse_formal_args(struct sl_pp_context *context, return 0; } } else { - strcpy(context->error_msg, "expected either an identifier or `)'"); + strcpy(context->error_msg, "expected either macro formal argument or `)'"); return -1; } @@ -68,7 +68,7 @@ _parse_formal_args(struct sl_pp_context *context, for (;;) { if (*first < last && input[*first].token != SL_PP_IDENTIFIER) { - strcpy(context->error_msg, "expected an identifier"); + strcpy(context->error_msg, "expected macro formal argument"); return -1; } @@ -90,6 +90,7 @@ _parse_formal_args(struct sl_pp_context *context, if (*first < last) { if (input[*first].token == SL_PP_COMMA) { (*first)++; + skip_whitespace(input, first, last); } else if (input[*first].token == SL_PP_RPAREN) { (*first)++; return 0; @@ -124,7 +125,7 @@ sl_pp_process_define(struct sl_pp_context *context, first++; } if (macro_name == -1) { - strcpy(context->error_msg, "expected an identifier"); + strcpy(context->error_msg, "expected macro name"); return -1; } -- cgit v1.2.3 From d801c296c602d04055b02b3be2f1369bfe1092b7 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 20 Dec 2009 21:11:16 +0100 Subject: glsl: Do syntax parsing inline with processing. --- src/glsl/cl/sl_cl_parse.c | 151 ++++++++++++++++++++++++++++++++++++------ src/glsl/cl/sl_cl_parse.h | 1 - src/glsl/pp/sl_pp_context.c | 3 + src/glsl/pp/sl_pp_context.h | 3 + src/glsl/pp/sl_pp_define.c | 1 + src/glsl/pp/sl_pp_error.c | 1 + src/glsl/pp/sl_pp_extension.c | 1 + src/glsl/pp/sl_pp_line.c | 1 + src/glsl/pp/sl_pp_macro.c | 1 + src/glsl/pp/sl_pp_pragma.c | 1 + src/glsl/pp/sl_pp_process.c | 116 +++++++++++++++++++++----------- src/glsl/pp/sl_pp_process.h | 3 +- src/glsl/pp/sl_pp_public.h | 4 ++ 13 files changed, 225 insertions(+), 62 deletions(-) (limited to 'src/glsl/pp/sl_pp_define.c') diff --git a/src/glsl/cl/sl_cl_parse.c b/src/glsl/cl/sl_cl_parse.c index a9db65c7ad..5dddf434e1 100644 --- a/src/glsl/cl/sl_cl_parse.c +++ b/src/glsl/cl/sl_cl_parse.c @@ -321,10 +321,13 @@ struct parse_dict { struct parse_context { struct sl_pp_context *context; - const struct sl_pp_token_info *input; struct parse_dict dict; + struct sl_pp_token_info *tokens; + unsigned int tokens_read; + unsigned int tokens_cap; + unsigned char *out_buf; unsigned int out_cap; @@ -332,6 +335,7 @@ struct parse_context { unsigned int parsing_builtin; char error[256]; + int process_error; }; @@ -366,7 +370,7 @@ _update(struct parse_context *ctx, static void _error(struct parse_context *ctx, - char *msg) + const char *msg) { if (ctx->error[0] == '\0') { strcpy(ctx->error, msg); @@ -374,12 +378,96 @@ _error(struct parse_context *ctx, } +static const struct sl_pp_token_info * +_fetch_token(struct parse_context *ctx, + unsigned int pos) +{ + if (ctx->process_error) { + return NULL; + } + + while (pos >= ctx->tokens_read) { + if (ctx->tokens_read == ctx->tokens_cap) { + ctx->tokens_cap += 1024; + ctx->tokens = realloc(ctx->tokens, + ctx->tokens_cap * sizeof(struct sl_pp_token_info)); + if (!ctx->tokens) { + _error(ctx, "out of memory"); + ctx->process_error = 1; + return NULL; + } + } + if (sl_pp_process_get(ctx->context, &ctx->tokens[ctx->tokens_read])) { + _error(ctx, sl_pp_context_error_message(ctx->context)); + ctx->process_error = 1; + return NULL; + } + switch (ctx->tokens[ctx->tokens_read].token) { + case SL_PP_COMMA: + case SL_PP_SEMICOLON: + case SL_PP_LBRACE: + case SL_PP_RBRACE: + case SL_PP_LPAREN: + case SL_PP_RPAREN: + case SL_PP_LBRACKET: + case SL_PP_RBRACKET: + case SL_PP_DOT: + case SL_PP_INCREMENT: + case SL_PP_ADDASSIGN: + case SL_PP_PLUS: + case SL_PP_DECREMENT: + case SL_PP_SUBASSIGN: + case SL_PP_MINUS: + case SL_PP_BITNOT: + case SL_PP_NOTEQUAL: + case SL_PP_NOT: + case SL_PP_MULASSIGN: + case SL_PP_STAR: + case SL_PP_DIVASSIGN: + case SL_PP_SLASH: + case SL_PP_MODASSIGN: + case SL_PP_MODULO: + case SL_PP_LSHIFTASSIGN: + case SL_PP_LSHIFT: + case SL_PP_LESSEQUAL: + case SL_PP_LESS: + case SL_PP_RSHIFTASSIGN: + case SL_PP_RSHIFT: + case SL_PP_GREATEREQUAL: + case SL_PP_GREATER: + case SL_PP_EQUAL: + case SL_PP_ASSIGN: + case SL_PP_AND: + case SL_PP_BITANDASSIGN: + case SL_PP_BITAND: + case SL_PP_XOR: + case SL_PP_BITXORASSIGN: + case SL_PP_BITXOR: + case SL_PP_OR: + case SL_PP_BITORASSIGN: + case SL_PP_BITOR: + case SL_PP_QUESTION: + case SL_PP_COLON: + case SL_PP_IDENTIFIER: + case SL_PP_UINT: + case SL_PP_FLOAT: + case SL_PP_EOF: + ctx->tokens_read++; + break; + } + } + return &ctx->tokens[pos]; +} + + static int _parse_token(struct parse_context *ctx, enum sl_pp_token token, struct parse_state *ps) { - if (ctx->input[ps->in].token == token) { + const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in); + + if (input && input->token == token) { ps->in++; return 0; } @@ -392,8 +480,9 @@ _parse_id(struct parse_context *ctx, int id, struct parse_state *ps) { - if (ctx->input[ps->in].token == SL_PP_IDENTIFIER && - ctx->input[ps->in].data.identifier == id) { + const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in); + + if (input && input->token == SL_PP_IDENTIFIER && input->data.identifier == id) { ps->in++; return 0; } @@ -405,8 +494,10 @@ static int _parse_identifier(struct parse_context *ctx, struct parse_state *ps) { - if (ctx->input[ps->in].token == SL_PP_IDENTIFIER) { - const char *cstr = sl_pp_context_cstr(ctx->context, ctx->input[ps->in].data.identifier); + const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in); + + if (input && input->token == SL_PP_IDENTIFIER) { + const char *cstr = sl_pp_context_cstr(ctx->context, input->data.identifier); do { _emit(ctx, &ps->out, *cstr); @@ -422,8 +513,10 @@ static int _parse_float(struct parse_context *ctx, struct parse_state *ps) { - if (ctx->input[ps->in].token == SL_PP_FLOAT) { - const char *cstr = sl_pp_context_cstr(ctx->context, ctx->input[ps->in].data._float); + const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in); + + if (input && input->token == SL_PP_FLOAT) { + const char *cstr = sl_pp_context_cstr(ctx->context, input->data._float); _emit(ctx, &ps->out, 1); do { @@ -440,8 +533,10 @@ static int _parse_uint(struct parse_context *ctx, struct parse_state *ps) { - if (ctx->input[ps->in].token == SL_PP_UINT) { - const char *cstr = sl_pp_context_cstr(ctx->context, ctx->input[ps->in].data._uint); + const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in); + + if (input && input->token == SL_PP_UINT) { + const char *cstr = sl_pp_context_cstr(ctx->context, input->data._uint); _emit(ctx, &ps->out, 1); do { @@ -614,13 +709,14 @@ _parse_type_qualifier(struct parse_context *ctx, struct parse_state *ps) { struct parse_state p = *ps; + const struct sl_pp_token_info *input = _fetch_token(ctx, p.in); unsigned int e = _emit(ctx, &p.out, 0); int id; - if (ctx->input[p.in].token != SL_PP_IDENTIFIER) { + if (!input || input->token != SL_PP_IDENTIFIER) { return -1; } - id = ctx->input[p.in].data.identifier; + id = input->data.identifier; if (id == ctx->dict._const) { _update(ctx, e, TYPE_QUALIFIER_CONST); @@ -771,6 +867,7 @@ _parse_type_specifier_nonarray(struct parse_context *ctx, { struct parse_state p = *ps; unsigned int e = _emit(ctx, &p.out, 0); + const struct sl_pp_token_info *input; int id; if (_parse_struct_specifier(ctx, &p) == 0) { @@ -779,10 +876,11 @@ _parse_type_specifier_nonarray(struct parse_context *ctx, return 0; } - if (ctx->input[p.in].token != SL_PP_IDENTIFIER) { + input = _fetch_token(ctx, p.in); + if (!input || input->token != SL_PP_IDENTIFIER) { return -1; } - id = ctx->input[p.in].data.identifier; + id = input->data.identifier; if (id == ctx->dict._void) { _update(ctx, e, TYPE_SPECIFIER_VOID); @@ -1696,13 +1794,14 @@ static int _parse_precision(struct parse_context *ctx, struct parse_state *ps) { + const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in); int id; unsigned int precision; - if (ctx->input[ps->in].token != SL_PP_IDENTIFIER) { + if (!input || input->token != SL_PP_IDENTIFIER) { return -1; } - id = ctx->input[ps->in].data.identifier; + id = input->data.identifier; if (id == ctx->dict.lowp) { precision = PRECISION_LOW; @@ -1724,13 +1823,14 @@ static int _parse_prectype(struct parse_context *ctx, struct parse_state *ps) { + const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in); int id; unsigned int type; - if (ctx->input[ps->in].token != SL_PP_IDENTIFIER) { + if (!input || input->token != SL_PP_IDENTIFIER) { return -1; } - id = ctx->input[ps->in].data.identifier; + id = input->data.identifier; if (id == ctx->dict._int) { type = TYPE_SPECIFIER_INT; @@ -2607,7 +2707,6 @@ _parse_translation_unit(struct parse_context *ctx, int sl_cl_compile(struct sl_pp_context *context, - const struct sl_pp_token_info *input, unsigned int shader_type, unsigned int parsing_builtin, unsigned char **output, @@ -2619,7 +2718,6 @@ sl_cl_compile(struct sl_pp_context *context, struct parse_state ps; ctx.context = context; - ctx.input = input; ADD_NAME_STR(ctx, _void, "void"); ADD_NAME_STR(ctx, _float, "float"); @@ -2699,16 +2797,27 @@ sl_cl_compile(struct sl_pp_context *context, ctx.parsing_builtin = 1; ctx.error[0] = '\0'; + ctx.process_error = 0; + + ctx.tokens_cap = 1024; + ctx.tokens_read = 0; + ctx.tokens = malloc(ctx.tokens_cap * sizeof(struct sl_pp_token_info)); + if (!ctx.tokens) { + strncpy(error, "out of memory", cberror); + return -1; + } ps.in = 0; ps.out = 0; if (_parse_translation_unit(&ctx, &ps)) { strncpy(error, ctx.error, cberror); + free(ctx.tokens); return -1; } *output = ctx.out_buf; *cboutput = ps.out; + free(ctx.tokens); return 0; } diff --git a/src/glsl/cl/sl_cl_parse.h b/src/glsl/cl/sl_cl_parse.h index 23a0d5fee0..dd5791d590 100644 --- a/src/glsl/cl/sl_cl_parse.h +++ b/src/glsl/cl/sl_cl_parse.h @@ -30,7 +30,6 @@ int sl_cl_compile(struct sl_pp_context *context, - const struct sl_pp_token_info *input, unsigned int shader_type, unsigned int parsing_builtin, unsigned char **output, diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index c1cef41bce..74a9bdddfd 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -69,6 +69,8 @@ sl_pp_context_create(const char *input, sl_pp_purify_state_init(&context->pure, input, options); + memset(&context->process_state, 0, sizeof(context->process_state)); + return context; } @@ -80,6 +82,7 @@ sl_pp_context_destroy(struct sl_pp_context *context) sl_pp_macro_free(context->macro); free(context->getc_buf); sl_pp_token_buffer_destroy(&context->tokens); + free(context->process_state.out); free(context); } } diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index 5e1c563048..3eada380cd 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -30,6 +30,7 @@ #include "sl_pp_dict.h" #include "sl_pp_macro.h" +#include "sl_pp_process.h" #include "sl_pp_purify.h" #include "sl_pp_token_util.h" @@ -84,6 +85,8 @@ struct sl_pp_context { unsigned int getc_buf_capacity; struct sl_pp_token_buffer tokens; + + struct sl_pp_process_state process_state; }; #endif /* SL_PP_CONTEXT_H */ diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c index e004c9f95b..808a6a0d4f 100644 --- a/src/glsl/pp/sl_pp_define.c +++ b/src/glsl/pp/sl_pp_define.c @@ -27,6 +27,7 @@ #include #include +#include "sl_pp_context.h" #include "sl_pp_process.h" #include "sl_pp_public.h" diff --git a/src/glsl/pp/sl_pp_error.c b/src/glsl/pp/sl_pp_error.c index a9eeff98ba..b628e37ce8 100644 --- a/src/glsl/pp/sl_pp_error.c +++ b/src/glsl/pp/sl_pp_error.c @@ -27,6 +27,7 @@ #include #include +#include "sl_pp_context.h" #include "sl_pp_process.h" #include "sl_pp_public.h" diff --git a/src/glsl/pp/sl_pp_extension.c b/src/glsl/pp/sl_pp_extension.c index 67b24404d4..8af5731e84 100644 --- a/src/glsl/pp/sl_pp_extension.c +++ b/src/glsl/pp/sl_pp_extension.c @@ -27,6 +27,7 @@ #include #include +#include "sl_pp_context.h" #include "sl_pp_process.h" #include "sl_pp_public.h" diff --git a/src/glsl/pp/sl_pp_line.c b/src/glsl/pp/sl_pp_line.c index 87987fc2ba..6f7e9eb562 100644 --- a/src/glsl/pp/sl_pp_line.c +++ b/src/glsl/pp/sl_pp_line.c @@ -27,6 +27,7 @@ #include #include +#include "sl_pp_context.h" #include "sl_pp_public.h" #include "sl_pp_process.h" diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index c98ab6559a..9f520b8fc5 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -28,6 +28,7 @@ #include #include #include +#include "sl_pp_context.h" #include "sl_pp_public.h" #include "sl_pp_macro.h" #include "sl_pp_process.h" diff --git a/src/glsl/pp/sl_pp_pragma.c b/src/glsl/pp/sl_pp_pragma.c index 489eb17b8e..caf4c63f65 100644 --- a/src/glsl/pp/sl_pp_pragma.c +++ b/src/glsl/pp/sl_pp_pragma.c @@ -27,6 +27,7 @@ #include #include +#include "sl_pp_context.h" #include "sl_pp_process.h" diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index 6dcd0ab401..563ea948e7 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -27,6 +27,7 @@ #include #include +#include "sl_pp_context.h" #include "sl_pp_process.h" #include "sl_pp_public.h" @@ -58,34 +59,47 @@ sl_pp_process_out(struct sl_pp_process_state *state, } int -sl_pp_process(struct sl_pp_context *context, - struct sl_pp_token_info **output) +sl_pp_process_get(struct sl_pp_context *context, + struct sl_pp_token_info *output) { - struct sl_pp_process_state state; - int found_eof = 0; - - memset(&state, 0, sizeof(state)); - - if (context->line > 1) { - struct sl_pp_token_info ti; - - ti.token = SL_PP_LINE; - ti.data.line.lineno = context->line - 1; - ti.data.line.fileno = context->file; - if (sl_pp_process_out(&state, &ti)) { - strcpy(context->error_msg, "out of memory"); - return -1; - } + if (!context->process_state.out) { + if (context->line > 1) { + struct sl_pp_token_info ti; + + ti.token = SL_PP_LINE; + ti.data.line.lineno = context->line - 1; + ti.data.line.fileno = context->file; + if (sl_pp_process_out(&context->process_state, &ti)) { + strcpy(context->error_msg, "out of memory"); + return -1; + } - ti.token = SL_PP_NEWLINE; - if (sl_pp_process_out(&state, &ti)) { - strcpy(context->error_msg, "out of memory"); - return -1; + ti.token = SL_PP_NEWLINE; + if (sl_pp_process_out(&context->process_state, &ti)) { + strcpy(context->error_msg, "out of memory"); + return -1; + } } } - while (!found_eof) { + for (;;) { struct sl_pp_token_info input; + int found_eof = 0; + + if (context->process_state.out_len) { + *output = context->process_state.out[0]; + + if (context->process_state.out_len > 1) { + unsigned int i; + + for (i = 1; i < context->process_state.out_len; i++) { + context->process_state.out[i - 1] = context->process_state.out[i]; + } + } + context->process_state.out_len--; + + return 0; + } if (sl_pp_token_buffer_skip_white(&context->tokens, &input)) { return -1; @@ -101,7 +115,7 @@ sl_pp_process(struct sl_pp_context *context, int found_eol = 0; struct sl_pp_token_info endof; struct sl_pp_token_peek peek; - int result; + int result = 0; /* Directive name. */ name = input.data.identifier; @@ -166,17 +180,17 @@ sl_pp_process(struct sl_pp_context *context, sl_pp_process_error(context, peek.tokens, 0, peek.size - 1); result = -1; } else if (name == context->dict.extension) { - result = sl_pp_process_extension(context, peek.tokens, 0, peek.size - 1, &state); + result = sl_pp_process_extension(context, peek.tokens, 0, peek.size - 1, &context->process_state); } else if (name == context->dict.line) { struct sl_pp_token_buffer buffer; result = sl_pp_token_peek_to_buffer(&peek, &buffer); if (result == 0) { - result = sl_pp_process_line(context, &buffer, &state); + result = sl_pp_process_line(context, &buffer, &context->process_state); sl_pp_token_buffer_destroy(&buffer); } } else if (name == context->dict.pragma) { - result = sl_pp_process_pragma(context, peek.tokens, 0, peek.size - 1, &state); + result = sl_pp_process_pragma(context, peek.tokens, 0, peek.size - 1, &context->process_state); } else if (name == context->dict.undef) { result = sl_pp_process_undef(context, peek.tokens, 0, peek.size - 1); } else { @@ -192,7 +206,7 @@ sl_pp_process(struct sl_pp_context *context, return result; } - if (sl_pp_process_out(&state, &endof)) { + if (sl_pp_process_out(&context->process_state, &endof)) { strcpy(context->error_msg, "out of memory"); return -1; } @@ -202,7 +216,7 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_NEWLINE: /* Empty directive. */ - if (sl_pp_process_out(&state, &input)) { + if (sl_pp_process_out(&context->process_state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } @@ -211,7 +225,7 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_EOF: /* Empty directive. */ - if (sl_pp_process_out(&state, &input)) { + if (sl_pp_process_out(&context->process_state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } @@ -239,7 +253,7 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_NEWLINE: /* Preserve newline just for the sake of line numbering. */ - if (sl_pp_process_out(&state, &input)) { + if (sl_pp_process_out(&context->process_state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } @@ -248,7 +262,7 @@ sl_pp_process(struct sl_pp_context *context, break; case SL_PP_EOF: - if (sl_pp_process_out(&state, &input)) { + if (sl_pp_process_out(&context->process_state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } @@ -258,7 +272,7 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_IDENTIFIER: sl_pp_token_buffer_unget(&context->tokens, &input); - if (sl_pp_macro_expand(context, &context->tokens, NULL, &state, + if (sl_pp_macro_expand(context, &context->tokens, NULL, &context->process_state, context->if_value ? sl_pp_macro_expand_normal : sl_pp_macro_expand_mute)) { return -1; } @@ -266,7 +280,7 @@ sl_pp_process(struct sl_pp_context *context, default: if (context->if_value) { - if (sl_pp_process_out(&state, &input)) { + if (sl_pp_process_out(&context->process_state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } @@ -274,13 +288,37 @@ sl_pp_process(struct sl_pp_context *context, } } } - } - if (context->if_ptr != SL_PP_MAX_IF_NESTING) { - strcpy(context->error_msg, "expected `#endif' directive"); - return -1; + if (found_eof) { + if (context->if_ptr != SL_PP_MAX_IF_NESTING) { + strcpy(context->error_msg, "expected `#endif' directive"); + return -1; + } + } } +} - *output = state.out; - return 0; +int +sl_pp_process(struct sl_pp_context *context, + struct sl_pp_token_info **output) +{ + struct sl_pp_process_state state; + + memset(&state, 0, sizeof(state)); + for (;;) { + struct sl_pp_token_info input; + + if (sl_pp_process_get(context, &input)) { + free(state.out); + return -1; + } + if (sl_pp_process_out(&state, &input)) { + free(state.out); + return -1; + } + if (input.token == SL_PP_EOF) { + *output = state.out; + return 0; + } + } } diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h index 31defd911a..fe6ff0d464 100644 --- a/src/glsl/pp/sl_pp_process.h +++ b/src/glsl/pp/sl_pp_process.h @@ -28,11 +28,12 @@ #ifndef SL_PP_PROCESS_H #define SL_PP_PROCESS_H -#include "sl_pp_context.h" #include "sl_pp_macro.h" #include "sl_pp_token.h" +struct sl_pp_context; + struct sl_pp_process_state { struct sl_pp_token_info *out; unsigned int out_len; diff --git a/src/glsl/pp/sl_pp_public.h b/src/glsl/pp/sl_pp_public.h index 309a70c07f..12528d6f8d 100644 --- a/src/glsl/pp/sl_pp_public.h +++ b/src/glsl/pp/sl_pp_public.h @@ -73,6 +73,10 @@ int sl_pp_version(struct sl_pp_context *context, unsigned int *version); +int +sl_pp_process_get(struct sl_pp_context *context, + struct sl_pp_token_info *output); + int sl_pp_process(struct sl_pp_context *context, struct sl_pp_token_info **output); -- cgit v1.2.3