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_macro.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/glsl/pp/sl_pp_macro.c (limited to 'src/glsl/pp/sl_pp_macro.c') diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c new file mode 100644 index 00000000000..eed09783040 --- /dev/null +++ b/src/glsl/pp/sl_pp_macro.c @@ -0,0 +1,51 @@ +/************************************************************************** + * + * 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_macro.h" + + +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); + + free(macro); + macro = next_macro; + } +} -- 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_macro.c') diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c index 5ce0f0551b8..39d14350641 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 eed09783040..82591b9d77d 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 4ebbff55906..eeb338eec45 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 2a375df71a4..e930966604c 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 f7df9a2850a..37cdc4c9a78 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_macro.c') diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c index 39d14350641..e8a23fedcd8 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 82591b9d77d..0138270c67b 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 eeb338eec45..63edd21aa24 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 e930966604c..baffaf2cd95 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 3b027bca9d54383b2fc8b2ad5a9cb6d2166c7acc Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 26 Jun 2009 11:44:43 +0200 Subject: glsl: Support if preprocessor directive and friends. --- src/glsl/pp/SConscript | 1 + src/glsl/pp/sl_pp_context.c | 2 + src/glsl/pp/sl_pp_context.h | 6 + src/glsl/pp/sl_pp_if.c | 276 ++++++++++++++++++++++++++++++++++++++++++++ src/glsl/pp/sl_pp_macro.c | 24 +++- src/glsl/pp/sl_pp_macro.h | 3 +- src/glsl/pp/sl_pp_process.c | 59 +++++++--- src/glsl/pp/sl_pp_process.h | 42 ++++++- 8 files changed, 388 insertions(+), 25 deletions(-) create mode 100644 src/glsl/pp/sl_pp_if.c (limited to 'src/glsl/pp/sl_pp_macro.c') diff --git a/src/glsl/pp/SConscript b/src/glsl/pp/SConscript index 623d2362ce0..c7718d1d8fd 100644 --- a/src/glsl/pp/SConscript +++ b/src/glsl/pp/SConscript @@ -11,6 +11,7 @@ glsl = env.StaticLibrary( 'sl_pp_context.c', 'sl_pp_define.c', 'sl_pp_expression.c', + 'sl_pp_if.c', 'sl_pp_macro.c', 'sl_pp_process.c', 'sl_pp_purify.c', diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index 6d3076b8697..1afe9a5d5e0 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -33,6 +33,8 @@ void sl_pp_context_init(struct sl_pp_context *context) { memset(context, 0, sizeof(struct sl_pp_context)); + context->if_ptr = SL_PP_MAX_IF_NESTING; + context->if_value = 1; } void diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index 56f70777507..e8200d55d7f 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -31,12 +31,18 @@ #include "sl_pp_macro.h" +#define SL_PP_MAX_IF_NESTING 64 + struct sl_pp_context { char *cstr_pool; unsigned int cstr_pool_max; unsigned int cstr_pool_len; struct sl_pp_macro *macro; + + unsigned int if_stack[SL_PP_MAX_IF_NESTING]; + unsigned int if_ptr; + int if_value; }; void diff --git a/src/glsl/pp/sl_pp_if.c b/src/glsl/pp/sl_pp_if.c new file mode 100644 index 00000000000..e331acc4cd5 --- /dev/null +++ b/src/glsl/pp/sl_pp_if.c @@ -0,0 +1,276 @@ +/************************************************************************** + * + * 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_expression.h" +#include "sl_pp_process.h" + + +static int +_evaluate_if_stack(struct sl_pp_context *context) +{ + unsigned int i; + + for (i = context->if_ptr; i < SL_PP_MAX_IF_NESTING; i++) { + if (!(context->if_stack[i] & 1)) { + return 0; + } + } + return 1; +} + +static int +_parse_if(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last) +{ + unsigned int i; + struct sl_pp_process_state state; + struct sl_pp_token_info eof; + int result; + + if (!context->if_ptr) { + /* #if nesting too deep. */ + return -1; + } + + memset(&state, 0, sizeof(state)); + for (i = first; i < last;) { + switch (input[i].token) { + case SL_PP_WHITESPACE: + i++; + break; + + case SL_PP_IDENTIFIER: + if (sl_pp_macro_expand(context, input, &i, NULL, &state, 0)) { + free(state.out); + return -1; + } + break; + + default: + if (sl_pp_process_out(&state, &input[i])) { + free(state.out); + return -1; + } + i++; + } + } + + eof.token = SL_PP_EOF; + if (sl_pp_process_out(&state, &eof)) { + free(state.out); + return -1; + } + + if (sl_pp_execute_expression(context, state.out, &result)) { + free(state.out); + return -1; + } + + free(state.out); + + context->if_ptr--; + context->if_stack[context->if_ptr] = result ? 1 : 0; + context->if_value = _evaluate_if_stack(context); + + return 0; +} + +static int +_parse_else(struct sl_pp_context *context) +{ + if (context->if_ptr == SL_PP_MAX_IF_NESTING) { + /* No matching #if. */ + return -1; + } + + /* Bit b1 indicates we already went through #else. */ + if (context->if_stack[context->if_ptr] & 2) { + /* No matching #if. */ + return -1; + } + + /* Invert current condition value and mark that we are in the #else block. */ + context->if_stack[context->if_ptr] = (1 - (context->if_stack[context->if_ptr] & 1)) | 2; + context->if_value = _evaluate_if_stack(context); + + return 0; +} + +int +sl_pp_process_if(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last) +{ + return _parse_if(context, input, first, last); +} + +int +sl_pp_process_ifdef(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last) +{ + unsigned int i; + + if (!context->if_ptr) { + /* #if nesting too deep. */ + return -1; + } + + for (i = first; i < last; i++) { + switch (input[i].token) { + case SL_PP_IDENTIFIER: + { + struct sl_pp_macro *macro; + int macro_name = input[i].data.identifier; + int defined = 0; + + for (macro = context->macro; macro; macro = macro->next) { + if (macro->name == macro_name) { + defined = 1; + break; + } + } + + context->if_ptr--; + context->if_stack[context->if_ptr] = defined ? 1 : 0; + context->if_value = _evaluate_if_stack(context); + } + return 0; + + case SL_PP_WHITESPACE: + break; + + default: + /* Expected an identifier. */ + return -1; + } + } + + /* Expected an identifier. */ + return -1; +} + +int +sl_pp_process_ifndef(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last) +{ + unsigned int i; + + if (!context->if_ptr) { + /* #if nesting too deep. */ + return -1; + } + + for (i = first; i < last; i++) { + switch (input[i].token) { + case SL_PP_IDENTIFIER: + { + struct sl_pp_macro *macro; + int macro_name = input[i].data.identifier; + int defined = 0; + + for (macro = context->macro; macro; macro = macro->next) { + if (macro->name == macro_name) { + defined = 1; + break; + } + } + + context->if_ptr--; + context->if_stack[context->if_ptr] = defined ? 0 : 1; + context->if_value = _evaluate_if_stack(context); + } + return 0; + + case SL_PP_WHITESPACE: + break; + + default: + /* Expected an identifier. */ + return -1; + } + } + + /* Expected an identifier. */ + return -1; +} + +int +sl_pp_process_elif(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last) +{ + if (_parse_else(context)) { + return -1; + } + + if (context->if_stack[context->if_ptr] & 1) { + context->if_ptr++; + if (_parse_if(context, input, first, last)) { + return -1; + } + } + + /* We are still in the #if block. */ + context->if_stack[context->if_ptr] = context->if_stack[context->if_ptr] & ~2; + + return 0; +} + +int +sl_pp_process_else(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last) +{ + return _parse_else(context); +} + +int +sl_pp_process_endif(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last) +{ + if (context->if_ptr == SL_PP_MAX_IF_NESTING) { + /* No matching #if. */ + return -1; + } + + context->if_ptr++; + context->if_value = _evaluate_if_stack(context); + + return 0; +} diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index 0138270c67b..a8412f0651c 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -78,7 +78,8 @@ 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) + struct sl_pp_process_state *state, + int mute) { int macro_name; struct sl_pp_macro *macro = NULL; @@ -108,8 +109,10 @@ sl_pp_macro_expand(struct sl_pp_context *context, } if (!macro) { - if (sl_pp_process_out(state, &input[*pi])) { - return -1; + if (!mute) { + if (sl_pp_process_out(state, &input[*pi])) { + return -1; + } } (*pi)++; return 0; @@ -244,8 +247,15 @@ sl_pp_macro_expand(struct sl_pp_context *context, for (j = 0;;) { switch (macro->body[j].token) { + case SL_PP_NEWLINE: + if (sl_pp_process_out(state, ¯o->body[j])) { + return -1; + } + j++; + break; + case SL_PP_IDENTIFIER: - if (sl_pp_macro_expand(context, macro->body, &j, actual_arg, state)) { + if (sl_pp_macro_expand(context, macro->body, &j, actual_arg, state, mute)) { return -1; } break; @@ -255,8 +265,10 @@ sl_pp_macro_expand(struct sl_pp_context *context, return 0; default: - if (sl_pp_process_out(state, ¯o->body[j])) { - return -1; + if (!mute) { + 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 63edd21aa24..476991d581d 100644 --- a/src/glsl/pp/sl_pp_macro.h +++ b/src/glsl/pp/sl_pp_macro.h @@ -55,6 +55,7 @@ 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); + struct sl_pp_process_state *state, + int mute); #endif /* SL_PP_MACRO_H */ diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index baffaf2cd95..441de9439c5 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -38,14 +38,6 @@ skip_whitespace(const struct sl_pp_token_info *input, } } - -struct sl_pp_process_state { - struct sl_pp_token_info *out; - unsigned int out_len; - unsigned int out_max; -}; - - int sl_pp_process_out(struct sl_pp_process_state *state, const struct sl_pp_token_info *token) @@ -133,16 +125,42 @@ sl_pp_process(struct sl_pp_context *context, last = i - 1; if (!strcmp(name, "define")) { - *macro = sl_pp_macro_new(); - if (!*macro) { + if (context->if_value) { + *macro = sl_pp_macro_new(); + if (!*macro) { + 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)) { return -1; } - - if (sl_pp_process_define(context, input, first, last, *macro)) { + } else if (!strcmp(name, "ifdef")) { + if (sl_pp_process_ifdef(context, input, first, last)) { + return -1; + } + } else if (!strcmp(name, "ifndef")) { + if (sl_pp_process_ifndef(context, input, first, last)) { + return -1; + } + } else if (!strcmp(name, "elif")) { + if (sl_pp_process_elif(context, input, first, last)) { + return -1; + } + } else if (!strcmp(name, "else")) { + if (sl_pp_process_else(context, input, first, last)) { + return -1; + } + } else if (!strcmp(name, "endif")) { + if (sl_pp_process_endif(context, input, first, last)) { return -1; } - - macro = &(**macro).next; } else { /* XXX: Ignore. */ } @@ -198,14 +216,16 @@ sl_pp_process(struct sl_pp_context *context, break; case SL_PP_IDENTIFIER: - if (sl_pp_macro_expand(context, input, &i, NULL, &state)) { + if (sl_pp_macro_expand(context, input, &i, NULL, &state, !context->if_value)) { return -1; } break; default: - if (sl_pp_process_out(&state, &input[i])) { - return -1; + if (context->if_value) { + if (sl_pp_process_out(&state, &input[i])) { + return -1; + } } i++; } @@ -213,6 +233,11 @@ sl_pp_process(struct sl_pp_context *context, } } + if (context->if_ptr != SL_PP_MAX_IF_NESTING) { + /* #endif expected. */ + return -1; + } + *output = state.out; return 0; } diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h index 37cdc4c9a78..cc934bd89c5 100644 --- a/src/glsl/pp/sl_pp_process.h +++ b/src/glsl/pp/sl_pp_process.h @@ -33,7 +33,11 @@ #include "sl_pp_token.h" -struct sl_pp_process_state; +struct sl_pp_process_state { + struct sl_pp_token_info *out; + unsigned int out_len; + unsigned int out_max; +}; int sl_pp_process(struct sl_pp_context *context, @@ -47,6 +51,42 @@ sl_pp_process_define(struct sl_pp_context *context, unsigned int last, struct sl_pp_macro *macro); +int +sl_pp_process_if(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last); + +int +sl_pp_process_ifdef(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last); + +int +sl_pp_process_ifndef(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last); + +int +sl_pp_process_elif(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last); + +int +sl_pp_process_else(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last); + +int +sl_pp_process_endif(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last); + int sl_pp_process_out(struct sl_pp_process_state *state, const struct sl_pp_token_info *token); -- 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_macro.c') 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 = ¯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 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, -- cgit v1.2.3 From e8afc6558909d9503a83c8cc184a2e2bb008746b Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 4 Sep 2009 13:30:40 +0200 Subject: glsl: Implement predefinded macros. The values are hardcoded: __LINE__ = 1, __FILE__ = 0 and __VERSION__ = 110. --- src/glsl/pp/sl_pp_macro.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'src/glsl/pp/sl_pp_macro.c') diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index a82c30cb167..bacd468964c 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -26,6 +26,7 @@ **************************************************************************/ #include +#include #include "sl_pp_macro.h" #include "sl_pp_process.h" @@ -94,6 +95,21 @@ skip_whitespace(const struct sl_pp_token_info *input, } } +static int +_out_number(struct sl_pp_context *context, + struct sl_pp_process_state *state, + unsigned int number) +{ + char buf[32]; + struct sl_pp_token_info ti; + + sprintf(buf, "%u", number); + + ti.token = SL_PP_NUMBER; + ti.data.number = sl_pp_context_add_unique_str(context, buf); + return sl_pp_process_out(state, &ti); +} + int sl_pp_macro_expand(struct sl_pp_context *context, const struct sl_pp_token_info *input, @@ -103,6 +119,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, int mute) { int macro_name; + const char *macro_str; struct sl_pp_macro *macro = NULL; struct sl_pp_macro *actual_arg = NULL; unsigned int j; @@ -112,6 +129,30 @@ sl_pp_macro_expand(struct sl_pp_context *context, } macro_name = input[*pi].data.identifier; + macro_str = sl_pp_context_cstr(context, macro_name); + + /* TODO: Having the following built-ins hardcoded is a bit lame. */ + if (!strcmp(macro_str, "__LINE__")) { + if (!mute && _out_number(context, state, 1)) { + return -1; + } + (*pi)++; + return 0; + } + if (!strcmp(macro_str, "__FILE__")) { + if (!mute && _out_number(context, state, 0)) { + return -1; + } + (*pi)++; + return 0; + } + if (!strcmp(macro_str, "__VERSION__")) { + if (!mute && _out_number(context, state, 110)) { + return -1; + } + (*pi)++; + return 0; + } if (local) { for (macro = local; macro; macro = macro->next) { -- cgit v1.2.3 From 4aa3222df315e3b36c73374e9000a6607c3b995c Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 4 Sep 2009 15:16:21 +0200 Subject: glsl: Correctly handle line numbering. --- src/glsl/pp/sl_pp_context.c | 1 + src/glsl/pp/sl_pp_context.h | 2 ++ src/glsl/pp/sl_pp_line.c | 47 +++++++++++++++++++++++++++++++++++++++++++-- src/glsl/pp/sl_pp_macro.c | 4 ++-- src/glsl/pp/sl_pp_process.c | 20 ++++++++++++++++++- src/glsl/pp/sl_pp_process.h | 3 ++- src/glsl/pp/sl_pp_token.h | 3 +++ src/glsl/pp/sl_pp_version.c | 8 +++++++- 8 files changed, 81 insertions(+), 7 deletions(-) (limited to 'src/glsl/pp/sl_pp_macro.c') diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index 38d633baeff..6aaf76828cc 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -37,6 +37,7 @@ sl_pp_context_init(struct sl_pp_context *context) context->if_ptr = SL_PP_MAX_IF_NESTING; context->if_value = 1; memset(context->error_msg, 0, sizeof(context->error_msg)); + context->line = 1; } void diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index 65ce3e37b7b..d656648d0dc 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -48,6 +48,8 @@ struct sl_pp_context { int if_value; char error_msg[SL_PP_MAX_ERROR_MSG]; + + unsigned int line; }; void diff --git a/src/glsl/pp/sl_pp_line.c b/src/glsl/pp/sl_pp_line.c index 3300a4785ba..b62af185bf5 100644 --- a/src/glsl/pp/sl_pp_line.c +++ b/src/glsl/pp/sl_pp_line.c @@ -29,16 +29,44 @@ #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, unsigned int first, - unsigned int last) + unsigned int last, + struct sl_pp_process_state *pstate) { unsigned int i; 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)); for (i = first; i < last;) { @@ -89,7 +117,22 @@ sl_pp_process_line(struct sl_pp_context *context, free(state.out); - /* TODO: Do something with line and file numbers. */ + str = sl_pp_context_cstr(context, line_number); + if (_parse_integer(str, &line)) { + return -1; + } + + if (context->line != line) { + struct sl_pp_token_info ti; + + ti.token = SL_PP_LINE; + ti.data.line = line; + if (sl_pp_process_out(pstate, &ti)) { + return -1; + } + } + + /* TODO: Do something with the file number. */ return 0; } diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index bacd468964c..b6214f66edc 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -131,14 +131,14 @@ sl_pp_macro_expand(struct sl_pp_context *context, macro_name = input[*pi].data.identifier; macro_str = sl_pp_context_cstr(context, macro_name); - /* TODO: Having the following built-ins hardcoded is a bit lame. */ if (!strcmp(macro_str, "__LINE__")) { - if (!mute && _out_number(context, state, 1)) { + if (!mute && _out_number(context, state, context->line)) { return -1; } (*pi)++; return 0; } + /* TODO: Having the following built-ins hardcoded is a bit lame. */ if (!strcmp(macro_str, "__FILE__")) { if (!mute && _out_number(context, state, 0)) { return -1; diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index 5479e8a8683..c4d6efaed38 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -75,6 +75,21 @@ sl_pp_process(struct sl_pp_context *context, memset(&state, 0, sizeof(state)); + if (context->line > 1) { + struct sl_pp_token_info ti; + + ti.token = SL_PP_LINE; + ti.data.line = context->line - 1; + if (sl_pp_process_out(&state, &ti)) { + return -1; + } + + ti.token = SL_PP_NEWLINE; + if (sl_pp_process_out(&state, &ti)) { + return -1; + } + } + while (!found_eof) { skip_whitespace(input, &i); if (input[i].token == SL_PP_HASH) { @@ -156,7 +171,7 @@ sl_pp_process(struct sl_pp_context *context, return -1; } } else if (!strcmp(name, "line")) { - if (sl_pp_process_line(context, input, first, last)) { + if (sl_pp_process_line(context, input, first, last, &state)) { return -1; } } else if (!strcmp(name, "pragma")) { @@ -176,6 +191,7 @@ sl_pp_process(struct sl_pp_context *context, if (sl_pp_process_out(&state, &endof)) { return -1; } + context->line++; } break; @@ -184,6 +200,7 @@ sl_pp_process(struct sl_pp_context *context, if (sl_pp_process_out(&state, &input[i])) { return -1; } + context->line++; i++; break; @@ -214,6 +231,7 @@ sl_pp_process(struct sl_pp_context *context, if (sl_pp_process_out(&state, &input[i])) { return -1; } + context->line++; i++; found_eol = 1; break; diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h index 6f90fbd3e77..adc08c18ae3 100644 --- a/src/glsl/pp/sl_pp_process.h +++ b/src/glsl/pp/sl_pp_process.h @@ -116,7 +116,8 @@ int sl_pp_process_line(struct sl_pp_context *context, const struct sl_pp_token_info *input, unsigned int first, - unsigned int last); + unsigned int last, + struct sl_pp_process_state *state); int sl_pp_process_out(struct sl_pp_process_state *state, diff --git a/src/glsl/pp/sl_pp_token.h b/src/glsl/pp/sl_pp_token.h index 7b60183a041..b347e5cf7a9 100644 --- a/src/glsl/pp/sl_pp_token.h +++ b/src/glsl/pp/sl_pp_token.h @@ -96,6 +96,8 @@ enum sl_pp_token { SL_PP_EXTENSION_WARN, SL_PP_EXTENSION_DISABLE, + SL_PP_LINE, + SL_PP_EOF }; @@ -105,6 +107,7 @@ union sl_pp_token_data { char other; int pragma; int extension; + unsigned int line; }; struct sl_pp_token_info { diff --git a/src/glsl/pp/sl_pp_version.c b/src/glsl/pp/sl_pp_version.c index 89c3cfa1a5b..80f7e971016 100644 --- a/src/glsl/pp/sl_pp_version.c +++ b/src/glsl/pp/sl_pp_version.c @@ -60,6 +60,7 @@ sl_pp_version(struct sl_pp_context *context, unsigned int *tokens_eaten) { unsigned int i = 0; + unsigned int line = context->line; /* Default values if `#version' is not present. */ *version = 110; @@ -77,8 +78,10 @@ sl_pp_version(struct sl_pp_context *context, /* Skip whitespace and newlines and seek for hash. */ while (!found_hash) { switch (input[i].token) { - case SL_PP_WHITESPACE: case SL_PP_NEWLINE: + line++; + /* pass thru */ + case SL_PP_WHITESPACE: i++; break; @@ -156,9 +159,12 @@ sl_pp_version(struct sl_pp_context *context, break; case SL_PP_NEWLINE: + line++; + /* pass thru */ case SL_PP_EOF: i++; *tokens_eaten = i; + context->line = line; found_end = 1; break; -- cgit v1.2.3 From a64ba93aab6de7ee2ceb70f39cf2dbe794940c97 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 4 Sep 2009 15:27:08 +0200 Subject: glsl: Handle file numbering. --- src/glsl/pp/sl_pp_context.c | 1 + src/glsl/pp/sl_pp_context.h | 1 + src/glsl/pp/sl_pp_line.c | 21 ++++++++++++++++++++- src/glsl/pp/sl_pp_macro.c | 3 +-- src/glsl/pp/sl_pp_token.h | 2 ++ 5 files changed, 25 insertions(+), 3 deletions(-) (limited to 'src/glsl/pp/sl_pp_macro.c') diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index 6aaf76828cc..2fca3791a26 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -38,6 +38,7 @@ sl_pp_context_init(struct sl_pp_context *context) context->if_value = 1; memset(context->error_msg, 0, sizeof(context->error_msg)); context->line = 1; + context->file = 0; } void diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index d656648d0dc..c7e6770f449 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -50,6 +50,7 @@ struct sl_pp_context { char error_msg[SL_PP_MAX_ERROR_MSG]; unsigned int line; + unsigned int file; }; void diff --git a/src/glsl/pp/sl_pp_line.c b/src/glsl/pp/sl_pp_line.c index 9b9f45dcedd..a56417a8610 100644 --- a/src/glsl/pp/sl_pp_line.c +++ b/src/glsl/pp/sl_pp_line.c @@ -134,7 +134,26 @@ sl_pp_process_line(struct sl_pp_context *context, context->line = line; } - /* TODO: Do something with the file number. */ + if (file_number != -1) { + unsigned int file; + + str = sl_pp_context_cstr(context, file_number); + if (_parse_integer(str, &file)) { + return -1; + } + + if (context->file != file) { + struct sl_pp_token_info ti; + + ti.token = SL_PP_FILE; + ti.data.file = file; + if (sl_pp_process_out(pstate, &ti)) { + return -1; + } + + context->file = file; + } + } return 0; } diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index b6214f66edc..d14c9825557 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -138,9 +138,8 @@ sl_pp_macro_expand(struct sl_pp_context *context, (*pi)++; return 0; } - /* TODO: Having the following built-ins hardcoded is a bit lame. */ if (!strcmp(macro_str, "__FILE__")) { - if (!mute && _out_number(context, state, 0)) { + if (!mute && _out_number(context, state, context->file)) { return -1; } (*pi)++; diff --git a/src/glsl/pp/sl_pp_token.h b/src/glsl/pp/sl_pp_token.h index b347e5cf7a9..59019593839 100644 --- a/src/glsl/pp/sl_pp_token.h +++ b/src/glsl/pp/sl_pp_token.h @@ -97,6 +97,7 @@ enum sl_pp_token { SL_PP_EXTENSION_DISABLE, SL_PP_LINE, + SL_PP_FILE, SL_PP_EOF }; @@ -108,6 +109,7 @@ union sl_pp_token_data { int pragma; int extension; unsigned int line; + unsigned int file; }; struct sl_pp_token_info { -- 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_macro.c') diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index 88a002c1c73..b196d8102a0 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 5826f9448d0..8bed1420454 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 9bc9fb53599..391178aa696 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 a692430abbf..6b2329ed1a7 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 90b80512375..44bbefa3577 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 a56417a8610..c38f4b0f2e6 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 d14c9825557..7793562781f 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 059bc6f2886..1cd9fd82348 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 82acdd1d5a4..6cd63f4925c 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 ce8f486156f5c4b28b51954ea862675275c38f6d Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 17 Sep 2009 12:12:34 +0200 Subject: slang/pp: Use a dictionary for the remaining string literals. --- src/glsl/pp/sl_pp_dict.c | 27 +++++++++++++++++++++++++++ src/glsl/pp/sl_pp_dict.h | 27 +++++++++++++++++++++++++++ src/glsl/pp/sl_pp_if.c | 24 ++++++++++-------------- src/glsl/pp/sl_pp_macro.c | 8 +++----- src/glsl/pp/sl_pp_pragma.c | 20 ++++++++++---------- src/glsl/pp/sl_pp_process.c | 28 ++++++++++++++-------------- src/glsl/pp/sl_pp_version.c | 15 ++++----------- 7 files changed, 95 insertions(+), 54 deletions(-) (limited to 'src/glsl/pp/sl_pp_macro.c') diff --git a/src/glsl/pp/sl_pp_dict.c b/src/glsl/pp/sl_pp_dict.c index 65b91d9e989..f2885c763d7 100644 --- a/src/glsl/pp/sl_pp_dict.c +++ b/src/glsl/pp/sl_pp_dict.c @@ -52,5 +52,32 @@ sl_pp_dict_init(struct sl_pp_context *context) ADD_NAME(context, warn); ADD_NAME(context, disable); + ADD_NAME(context, defined); + + ADD_NAME_STR(context, ___LINE__, "__LINE__"); + ADD_NAME_STR(context, ___FILE__, "__FILE__"); + ADD_NAME(context, __VERSION__); + + ADD_NAME(context, optimize); + ADD_NAME(context, debug); + + ADD_NAME(context, off); + ADD_NAME(context, on); + + ADD_NAME(context, define); + ADD_NAME(context, elif); + ADD_NAME_STR(context, _else, "else"); + ADD_NAME(context, endif); + ADD_NAME(context, error); + ADD_NAME(context, extension); + ADD_NAME_STR(context, _if, "if"); + ADD_NAME(context, ifdef); + ADD_NAME(context, ifndef); + ADD_NAME(context, line); + ADD_NAME(context, pragma); + ADD_NAME(context, undef); + + ADD_NAME(context, version); + return 0; } diff --git a/src/glsl/pp/sl_pp_dict.h b/src/glsl/pp/sl_pp_dict.h index ce138d98f51..ba82b389b23 100644 --- a/src/glsl/pp/sl_pp_dict.h +++ b/src/glsl/pp/sl_pp_dict.h @@ -37,6 +37,33 @@ struct sl_pp_dict { int enable; int warn; int disable; + + int defined; + + int ___LINE__; + int ___FILE__; + int __VERSION__; + + int optimize; + int debug; + + int off; + int on; + + int define; + int elif; + int _else; + int endif; + int error; + int extension; + int _if; + int ifdef; + int ifndef; + int line; + int pragma; + int undef; + + int version; }; diff --git a/src/glsl/pp/sl_pp_if.c b/src/glsl/pp/sl_pp_if.c index 44bbefa3577..cf1c746d5f6 100644 --- a/src/glsl/pp/sl_pp_if.c +++ b/src/glsl/pp/sl_pp_if.c @@ -136,20 +136,16 @@ _parse_if(struct sl_pp_context *context, break; case SL_PP_IDENTIFIER: - { - const char *id = sl_pp_context_cstr(context, input[i].data.identifier); - - if (!strcmp(id, "defined")) { - i++; - if (_parse_defined(context, input, &i, &state)) { - free(state.out); - return -1; - } - } else { - if (sl_pp_macro_expand(context, input, &i, NULL, &state, 0)) { - free(state.out); - return -1; - } + if (input[i].data.identifier == context->dict.defined) { + i++; + if (_parse_defined(context, input, &i, &state)) { + free(state.out); + return -1; + } + } else { + if (sl_pp_macro_expand(context, input, &i, NULL, &state, 0)) { + free(state.out); + return -1; } } break; diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index 7793562781f..6772100847b 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -124,7 +124,6 @@ sl_pp_macro_expand(struct sl_pp_context *context, int mute) { int macro_name; - const char *macro_str; struct sl_pp_macro *macro = NULL; struct sl_pp_macro *actual_arg = NULL; unsigned int j; @@ -135,23 +134,22 @@ sl_pp_macro_expand(struct sl_pp_context *context, } macro_name = input[*pi].data.identifier; - macro_str = sl_pp_context_cstr(context, macro_name); - if (!strcmp(macro_str, "__LINE__")) { + if (macro_name == context->dict.___LINE__) { if (!mute && _out_number(context, state, context->line)) { return -1; } (*pi)++; return 0; } - if (!strcmp(macro_str, "__FILE__")) { + if (macro_name == context->dict.___FILE__) { if (!mute && _out_number(context, state, context->file)) { return -1; } (*pi)++; return 0; } - if (!strcmp(macro_str, "__VERSION__")) { + if (macro_name == context->dict.__VERSION__) { if (!mute && _out_number(context, state, 110)) { return -1; } diff --git a/src/glsl/pp/sl_pp_pragma.c b/src/glsl/pp/sl_pp_pragma.c index 1cd9fd82348..03269b63db7 100644 --- a/src/glsl/pp/sl_pp_pragma.c +++ b/src/glsl/pp/sl_pp_pragma.c @@ -36,21 +36,21 @@ sl_pp_process_pragma(struct sl_pp_context *context, unsigned int last, struct sl_pp_process_state *state) { - const char *pragma_name = NULL; + int pragma_name = -1; struct sl_pp_token_info out; - const char *arg_name = NULL; + int arg_name = -1; if (first < last && input[first].token == SL_PP_IDENTIFIER) { - pragma_name = sl_pp_context_cstr(context, input[first].data.identifier); + pragma_name = input[first].data.identifier; first++; } - if (!pragma_name) { + if (pragma_name == -1) { return 0; } - if (!strcmp(pragma_name, "optimize")) { + if (pragma_name == context->dict.optimize) { out.token = SL_PP_PRAGMA_OPTIMIZE; - } else if (!strcmp(pragma_name, "debug")) { + } else if (pragma_name == context->dict.debug) { out.token = SL_PP_PRAGMA_DEBUG; } else { return 0; @@ -71,16 +71,16 @@ sl_pp_process_pragma(struct sl_pp_context *context, } if (first < last && input[first].token == SL_PP_IDENTIFIER) { - arg_name = sl_pp_context_cstr(context, input[first].data.identifier); + arg_name = input[first].data.identifier; first++; } - if (!arg_name) { + if (arg_name == -1) { return 0; } - if (!strcmp(arg_name, "off")) { + if (arg_name == context->dict.off) { out.data.pragma = 0; - } else if (!strcmp(arg_name, "on")) { + } else if (arg_name == context->dict.on) { out.data.pragma = 1; } else { return 0; diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index 03a3051838f..ab2f2d8eb45 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -100,14 +100,14 @@ sl_pp_process(struct sl_pp_context *context, switch (input[i].token) { case SL_PP_IDENTIFIER: { - const char *name; + int name; int found_eol = 0; unsigned int first; unsigned int last; struct sl_pp_token_info endof; /* Directive name. */ - name = sl_pp_context_cstr(context, input[i].data.identifier); + name = input[i].data.identifier; i++; skip_whitespace(input, &i); @@ -136,51 +136,51 @@ sl_pp_process(struct sl_pp_context *context, last = i - 1; - if (!strcmp(name, "if")) { + if (name == context->dict._if) { if (sl_pp_process_if(context, input, first, last)) { return -1; } - } else if (!strcmp(name, "ifdef")) { + } else if (name == context->dict.ifdef) { if (sl_pp_process_ifdef(context, input, first, last)) { return -1; } - } else if (!strcmp(name, "ifndef")) { + } else if (name == context->dict.ifndef) { if (sl_pp_process_ifndef(context, input, first, last)) { return -1; } - } else if (!strcmp(name, "elif")) { + } else if (name == context->dict.elif) { if (sl_pp_process_elif(context, input, first, last)) { return -1; } - } else if (!strcmp(name, "else")) { + } else if (name == context->dict._else) { if (sl_pp_process_else(context, input, first, last)) { return -1; } - } else if (!strcmp(name, "endif")) { + } else if (name == context->dict.endif) { if (sl_pp_process_endif(context, input, first, last)) { return -1; } } else if (context->if_value) { - if (!strcmp(name, "define")) { + if (name == context->dict.define) { if (sl_pp_process_define(context, input, first, last)) { return -1; } - } else if (!strcmp(name, "error")) { + } else if (name == context->dict.error) { sl_pp_process_error(context, input, first, last); return -1; - } else if (!strcmp(name, "extension")) { + } else if (name == context->dict.extension) { if (sl_pp_process_extension(context, input, first, last, &state)) { return -1; } - } else if (!strcmp(name, "line")) { + } else if (name == context->dict.line) { if (sl_pp_process_line(context, input, first, last, &state)) { return -1; } - } else if (!strcmp(name, "pragma")) { + } else if (name == context->dict.pragma) { if (sl_pp_process_pragma(context, input, first, last, &state)) { return -1; } - } else if (!strcmp(name, "undef")) { + } else if (name == context->dict.undef) { if (sl_pp_process_undef(context, input, first, last)) { return -1; } diff --git a/src/glsl/pp/sl_pp_version.c b/src/glsl/pp/sl_pp_version.c index 6cd63f4925c..814da46a672 100644 --- a/src/glsl/pp/sl_pp_version.c +++ b/src/glsl/pp/sl_pp_version.c @@ -79,18 +79,11 @@ sl_pp_version(struct sl_pp_context *context, break; case SL_PP_IDENTIFIER: - { - const char *id = sl_pp_context_cstr(context, input[i].data.identifier); - - if (!id) { - return -1; - } - if (strcmp(id, "version")) { - return 0; - } - i++; - found_version = 1; + if (input[i].data.identifier != context->dict.version) { + return 0; } + i++; + found_version = 1; break; default: -- cgit v1.2.3 From 90daefd1c474a6e0502df5053b581987c12b8673 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 17 Sep 2009 12:33:26 +0200 Subject: glsl/pp: Add a TODO for FEATURE_es2_glsl. --- src/glsl/pp/sl_pp_macro.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/glsl/pp/sl_pp_macro.c') diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index 6772100847b..878b22ed9c3 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -157,6 +157,11 @@ sl_pp_macro_expand(struct sl_pp_context *context, return 0; } + /* TODO: For FEATURE_es2_glsl, expand to 1 the following symbols. + * GL_ES + * GL_FRAGMENT_PRECISION_HIGH + */ + if (local) { for (macro = local; macro; macro = macro->next) { if (macro->name == macro_name) { -- cgit v1.2.3 From 0481e85af7195e13c30580afba233a80feeee740 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 22 Sep 2009 12:51:08 +0200 Subject: glsl/pp: Differentiate between integer and floating-point number tokens. --- src/glsl/pp/sl_pp_error.c | 8 ++++++-- src/glsl/pp/sl_pp_expression.c | 4 ++-- src/glsl/pp/sl_pp_if.c | 8 ++++---- src/glsl/pp/sl_pp_line.c | 8 ++++---- src/glsl/pp/sl_pp_macro.c | 4 ++-- src/glsl/pp/sl_pp_token.c | 19 +++++++++++++++---- src/glsl/pp/sl_pp_token.h | 6 ++++-- src/glsl/pp/sl_pp_version.c | 4 ++-- 8 files changed, 39 insertions(+), 22 deletions(-) (limited to 'src/glsl/pp/sl_pp_macro.c') diff --git a/src/glsl/pp/sl_pp_error.c b/src/glsl/pp/sl_pp_error.c index d42568d23dc..e591f4beef9 100644 --- a/src/glsl/pp/sl_pp_error.c +++ b/src/glsl/pp/sl_pp_error.c @@ -239,8 +239,12 @@ sl_pp_process_error(struct sl_pp_context *context, s = sl_pp_context_cstr(context, input[i].data.identifier); break; - case SL_PP_NUMBER: - s = sl_pp_context_cstr(context, input[i].data.number); + case SL_PP_UINT: + s = sl_pp_context_cstr(context, input[i].data._uint); + break; + + case SL_PP_FLOAT: + s = sl_pp_context_cstr(context, input[i].data._float); break; case SL_PP_OTHER: diff --git a/src/glsl/pp/sl_pp_expression.c b/src/glsl/pp/sl_pp_expression.c index 6b2329ed1a7..5093ef6cc9d 100644 --- a/src/glsl/pp/sl_pp_expression.c +++ b/src/glsl/pp/sl_pp_expression.c @@ -42,8 +42,8 @@ static int _parse_primary(struct parse_context *ctx, int *result) { - if (ctx->input->token == SL_PP_NUMBER) { - *result = atoi(sl_pp_context_cstr(ctx->context, ctx->input->data.number)); + if (ctx->input->token == SL_PP_UINT) { + *result = atoi(sl_pp_context_cstr(ctx->context, ctx->input->data._uint)); ctx->input++; } else { if (ctx->input->token != SL_PP_LPAREN) { diff --git a/src/glsl/pp/sl_pp_if.c b/src/glsl/pp/sl_pp_if.c index cf1c746d5f6..5fa27fcf053 100644 --- a/src/glsl/pp/sl_pp_if.c +++ b/src/glsl/pp/sl_pp_if.c @@ -81,13 +81,13 @@ _parse_defined(struct sl_pp_context *context, (*pi)++; } - result.token = SL_PP_NUMBER; + result.token = SL_PP_UINT; if (defined) { - result.data.number = sl_pp_context_add_unique_str(context, "1"); + result.data._uint = sl_pp_context_add_unique_str(context, "1"); } else { - result.data.number = sl_pp_context_add_unique_str(context, "0"); + result.data._uint = sl_pp_context_add_unique_str(context, "0"); } - if (result.data.number == -1) { + if (result.data._uint == -1) { return -1; } diff --git a/src/glsl/pp/sl_pp_line.c b/src/glsl/pp/sl_pp_line.c index cab0262686c..e8f751003ac 100644 --- a/src/glsl/pp/sl_pp_line.c +++ b/src/glsl/pp/sl_pp_line.c @@ -67,8 +67,8 @@ 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; + if (state.out_len > 0 && state.out[0].token == SL_PP_UINT) { + line_number = state.out[0].data._uint; } else { strcpy(context->error_msg, "expected a number after `#line'"); free(state.out); @@ -76,8 +76,8 @@ sl_pp_process_line(struct sl_pp_context *context, } if (state.out_len > 1) { - if (state.out[1].token == SL_PP_NUMBER) { - file_number = state.out[1].data.number; + if (state.out[1].token == SL_PP_UINT) { + file_number = state.out[1].data._uint; } else { strcpy(context->error_msg, "expected a number after line number"); free(state.out); diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index 878b22ed9c3..3956ba3b574 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -105,8 +105,8 @@ _out_number(struct sl_pp_context *context, sprintf(buf, "%u", number); - ti.token = SL_PP_NUMBER; - ti.data.number = sl_pp_context_add_unique_str(context, buf); + ti.token = SL_PP_UINT; + ti.data._uint = sl_pp_context_add_unique_str(context, buf); if (sl_pp_process_out(state, &ti)) { strcpy(context->error_msg, "out of memory"); return -1; diff --git a/src/glsl/pp/sl_pp_token.c b/src/glsl/pp/sl_pp_token.c index 3a7ffe7db15..99a32a6e671 100644 --- a/src/glsl/pp/sl_pp_token.c +++ b/src/glsl/pp/sl_pp_token.c @@ -271,6 +271,7 @@ _tokenise_number(struct sl_pp_context *context, { const char *input = *pinput; unsigned int eaten; + unsigned int is_float = 0; char number[256]; /* XXX: Remove this artifical limit. */ eaten = _parse_float(input); @@ -282,6 +283,8 @@ _tokenise_number(struct sl_pp_context *context, eaten = _parse_dec(input); } } + } else { + is_float = 1; } if (!eaten || _is_identifier_char(input[eaten])) { @@ -297,10 +300,18 @@ _tokenise_number(struct sl_pp_context *context, memcpy(number, input, eaten); number[eaten] = '\0'; - info->token = SL_PP_NUMBER; - info->data.number = sl_pp_context_add_unique_str(context, number); - if (info->data.number == -1) { - return -1; + if (is_float) { + info->token = SL_PP_FLOAT; + info->data._float = sl_pp_context_add_unique_str(context, number); + if (info->data._float == -1) { + return -1; + } + } else { + info->token = SL_PP_UINT; + info->data._uint = sl_pp_context_add_unique_str(context, number); + if (info->data._uint == -1) { + return -1; + } } *pinput = input + eaten; diff --git a/src/glsl/pp/sl_pp_token.h b/src/glsl/pp/sl_pp_token.h index 4131be6bdad..2a7b79ea3f7 100644 --- a/src/glsl/pp/sl_pp_token.h +++ b/src/glsl/pp/sl_pp_token.h @@ -82,7 +82,8 @@ enum sl_pp_token { SL_PP_IDENTIFIER, - SL_PP_NUMBER, + SL_PP_UINT, + SL_PP_FLOAT, SL_PP_OTHER, @@ -102,7 +103,8 @@ enum sl_pp_token { union sl_pp_token_data { int identifier; - int number; + int _uint; + int _float; char other; int pragma; int extension; diff --git a/src/glsl/pp/sl_pp_version.c b/src/glsl/pp/sl_pp_version.c index 825967d4c10..adf3017bf21 100644 --- a/src/glsl/pp/sl_pp_version.c +++ b/src/glsl/pp/sl_pp_version.c @@ -99,8 +99,8 @@ sl_pp_version(struct sl_pp_context *context, i++; break; - case SL_PP_NUMBER: - *version = atoi(sl_pp_context_cstr(context, input[i].data.number)); + case SL_PP_UINT: + *version = atoi(sl_pp_context_cstr(context, input[i].data._uint)); i++; found_number = 1; break; -- cgit v1.2.3 From 69fec23251740c3071ffc3fefc8981599bdb22ef Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 24 Sep 2009 10:57:32 +0200 Subject: glsl/pp: Avoid using `__VERSION__' as an identifier. --- src/glsl/pp/sl_pp_dict.c | 2 +- src/glsl/pp/sl_pp_dict.h | 5 ++++- src/glsl/pp/sl_pp_macro.c | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src/glsl/pp/sl_pp_macro.c') diff --git a/src/glsl/pp/sl_pp_dict.c b/src/glsl/pp/sl_pp_dict.c index 0e1fa368577..82fb9127b50 100644 --- a/src/glsl/pp/sl_pp_dict.c +++ b/src/glsl/pp/sl_pp_dict.c @@ -56,7 +56,7 @@ sl_pp_dict_init(struct sl_pp_context *context) ADD_NAME_STR(context, ___LINE__, "__LINE__"); ADD_NAME_STR(context, ___FILE__, "__FILE__"); - ADD_NAME(context, __VERSION__); + ADD_NAME_STR(context, ___VERSION__, "__VERSION__"); ADD_NAME(context, optimize); ADD_NAME(context, debug); diff --git a/src/glsl/pp/sl_pp_dict.h b/src/glsl/pp/sl_pp_dict.h index 683752e000a..49f0e0bf9fa 100644 --- a/src/glsl/pp/sl_pp_dict.h +++ b/src/glsl/pp/sl_pp_dict.h @@ -28,6 +28,9 @@ #ifndef SL_PP_DICT_H #define SL_PP_DICT_H + +struct sl_pp_context; + struct sl_pp_dict { int all; int _GL_ARB_draw_buffers; @@ -42,7 +45,7 @@ struct sl_pp_dict { int ___LINE__; int ___FILE__; - int __VERSION__; + int ___VERSION__; int optimize; int debug; diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index 3956ba3b574..a4e78861d69 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -27,6 +27,7 @@ #include #include +#include #include "sl_pp_macro.h" #include "sl_pp_process.h" @@ -149,7 +150,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, (*pi)++; return 0; } - if (macro_name == context->dict.__VERSION__) { + if (macro_name == context->dict.___VERSION__) { if (!mute && _out_number(context, state, 110)) { return -1; } -- cgit v1.2.3 From c4bd6ccde8241d6a5eb631c713ba79db51163701 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 28 Sep 2009 11:30:15 +0200 Subject: glsl/pp: Expand macro actual arguments before pasting into its body. --- src/glsl/pp/sl_pp_macro.c | 102 ++++++++++++++++++++++++---------------------- 1 file changed, 53 insertions(+), 49 deletions(-) (limited to 'src/glsl/pp/sl_pp_macro.c') diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index a4e78861d69..d6c32a0e782 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -136,6 +136,9 @@ sl_pp_macro_expand(struct sl_pp_context *context, macro_name = input[*pi].data.identifier; + /* First look for predefined macros. + */ + if (macro_name == context->dict.___LINE__) { if (!mute && _out_number(context, state, context->line)) { return -1; @@ -207,55 +210,73 @@ sl_pp_macro_expand(struct sl_pp_context *context, struct sl_pp_macro **pmacro = &actual_arg; for (j = 0; j < (unsigned int)macro->num_args; j++) { - unsigned int body_len; + struct sl_pp_process_state arg_state; unsigned int i; int done = 0; unsigned int paren_nesting = 0; - unsigned int k; - - *pmacro = sl_pp_macro_new(); - if (!*pmacro) { - strcpy(context->error_msg, "out of memory"); - return -1; - } + struct sl_pp_token_info eof; - (**pmacro).name = formal_arg->name; + memset(&arg_state, 0, sizeof(arg_state)); - body_len = 1; - for (i = *pi; !done; i++) { + for (i = *pi; !done;) { switch (input[i].token) { case SL_PP_WHITESPACE: + i++; break; case SL_PP_COMMA: if (!paren_nesting) { if (j < (unsigned int)macro->num_args - 1) { done = 1; + i++; } else { strcpy(context->error_msg, "too many actual macro arguments"); return -1; } } else { - body_len++; + if (sl_pp_process_out(&arg_state, &input[i])) { + strcpy(context->error_msg, "out of memory"); + free(arg_state.out); + return -1; + } + i++; } break; case SL_PP_LPAREN: paren_nesting++; - body_len++; + if (sl_pp_process_out(&arg_state, &input[i])) { + strcpy(context->error_msg, "out of memory"); + free(arg_state.out); + return -1; + } + i++; break; case SL_PP_RPAREN: if (!paren_nesting) { if (j == (unsigned int)macro->num_args - 1) { done = 1; + i++; } else { strcpy(context->error_msg, "too few actual macro arguments"); return -1; } } else { paren_nesting--; - body_len++; + if (sl_pp_process_out(&arg_state, &input[i])) { + strcpy(context->error_msg, "out of memory"); + free(arg_state.out); + return -1; + } + i++; + } + break; + + case SL_PP_IDENTIFIER: + if (sl_pp_macro_expand(context, input, &i, local, &arg_state, 0)) { + free(arg_state.out); + return -1; } break; @@ -264,50 +285,33 @@ sl_pp_macro_expand(struct sl_pp_context *context, return -1; default: - body_len++; + if (sl_pp_process_out(&arg_state, &input[i])) { + strcpy(context->error_msg, "out of memory"); + free(arg_state.out); + return -1; + } + i++; } } - (**pmacro).body = malloc(sizeof(struct sl_pp_token_info) * body_len); - if (!(**pmacro).body) { + (*pi) = i; + + eof.token = SL_PP_EOF; + if (sl_pp_process_out(&arg_state, &eof)) { strcpy(context->error_msg, "out of memory"); + free(arg_state.out); 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 = sl_pp_macro_new(); + if (!*pmacro) { + strcpy(context->error_msg, "out of memory"); + free(arg_state.out); + return -1; } - (**pmacro).body[k++].token = SL_PP_EOF; - (*pi) = i; + (**pmacro).name = formal_arg->name; + (**pmacro).body = arg_state.out; formal_arg = formal_arg->next; pmacro = &(**pmacro).next; -- cgit v1.2.3 From b89cd8afc510541a18f2f5c04884637626e104e1 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 20 Nov 2009 08:59:50 +0100 Subject: glsl/pp: Expand unknown identifiers to 0 in if/elif expressions. --- src/glsl/pp/sl_pp_if.c | 2 +- src/glsl/pp/sl_pp_line.c | 2 +- src/glsl/pp/sl_pp_macro.c | 15 +++++++++++---- src/glsl/pp/sl_pp_macro.h | 8 +++++++- src/glsl/pp/sl_pp_process.c | 3 ++- 5 files changed, 22 insertions(+), 8 deletions(-) (limited to 'src/glsl/pp/sl_pp_macro.c') diff --git a/src/glsl/pp/sl_pp_if.c b/src/glsl/pp/sl_pp_if.c index a0b3635dd5a..6610bc69f3c 100644 --- a/src/glsl/pp/sl_pp_if.c +++ b/src/glsl/pp/sl_pp_if.c @@ -137,7 +137,7 @@ _parse_if(struct sl_pp_context *context, return -1; } } else { - if (sl_pp_macro_expand(context, input, &i, NULL, &state, 0)) { + if (sl_pp_macro_expand(context, input, &i, NULL, &state, sl_pp_macro_expand_unknown_to_0)) { free(state.out); return -1; } diff --git a/src/glsl/pp/sl_pp_line.c b/src/glsl/pp/sl_pp_line.c index fc2dd89e68b..ed5acc697ce 100644 --- a/src/glsl/pp/sl_pp_line.c +++ b/src/glsl/pp/sl_pp_line.c @@ -53,7 +53,7 @@ sl_pp_process_line(struct sl_pp_context *context, break; case SL_PP_IDENTIFIER: - if (sl_pp_macro_expand(context, input, &i, NULL, &state, 0)) { + if (sl_pp_macro_expand(context, input, &i, NULL, &state, sl_pp_macro_expand_normal)) { free(state.out); return -1; } diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index d6c32a0e782..29f1229dd7d 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_public.h" #include "sl_pp_macro.h" #include "sl_pp_process.h" @@ -122,8 +123,9 @@ sl_pp_macro_expand(struct sl_pp_context *context, unsigned int *pi, struct sl_pp_macro *local, struct sl_pp_process_state *state, - int mute) + enum sl_pp_macro_expand_behaviour behaviour) { + int mute = (behaviour == sl_pp_macro_expand_mute); int macro_name; struct sl_pp_macro *macro = NULL; struct sl_pp_macro *actual_arg = NULL; @@ -183,7 +185,12 @@ sl_pp_macro_expand(struct sl_pp_context *context, } if (!macro) { - if (!mute) { + if (behaviour == sl_pp_macro_expand_unknown_to_0) { + if (_out_number(context, state, 0)) { + strcpy(context->error_msg, "out of memory"); + return -1; + } + } else if (!mute) { if (sl_pp_process_out(state, &input[*pi])) { strcpy(context->error_msg, "out of memory"); return -1; @@ -274,7 +281,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, break; case SL_PP_IDENTIFIER: - if (sl_pp_macro_expand(context, input, &i, local, &arg_state, 0)) { + if (sl_pp_macro_expand(context, input, &i, local, &arg_state, sl_pp_macro_expand_normal)) { free(arg_state.out); return -1; } @@ -339,7 +346,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, break; case SL_PP_IDENTIFIER: - if (sl_pp_macro_expand(context, macro->body, &j, actual_arg, state, mute)) { + if (sl_pp_macro_expand(context, macro->body, &j, actual_arg, state, behaviour)) { return -1; } break; diff --git a/src/glsl/pp/sl_pp_macro.h b/src/glsl/pp/sl_pp_macro.h index e3ae2fc7125..3ad3438236a 100644 --- a/src/glsl/pp/sl_pp_macro.h +++ b/src/glsl/pp/sl_pp_macro.h @@ -56,12 +56,18 @@ sl_pp_macro_free(struct sl_pp_macro *macro); void sl_pp_macro_reset(struct sl_pp_macro *macro); +enum sl_pp_macro_expand_behaviour { + sl_pp_macro_expand_normal, + sl_pp_macro_expand_mute, + sl_pp_macro_expand_unknown_to_0 +}; + 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 mute); + enum sl_pp_macro_expand_behaviour behaviour); #endif /* SL_PP_MACRO_H */ diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index 4b783e40b4d..e2adc2a0215 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -257,7 +257,8 @@ sl_pp_process(struct sl_pp_context *context, break; case SL_PP_IDENTIFIER: - if (sl_pp_macro_expand(context, input, &i, NULL, &state, !context->if_value)) { + if (sl_pp_macro_expand(context, input, &i, NULL, &state, + context->if_value ? sl_pp_macro_expand_normal : sl_pp_macro_expand_mute)) { return -1; } break; -- cgit v1.2.3 From 91e164b3d0b1d36bfdf369266ae7e1ab396f1ba2 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 10 Dec 2009 12:38:22 +0100 Subject: glsl/pp: Add sl_pp_context_add_extension(). This way third parties are able to add supported extension strings. --- src/glsl/pp/sl_pp_context.h | 10 +++++++++ src/glsl/pp/sl_pp_dict.c | 2 -- src/glsl/pp/sl_pp_dict.h | 2 -- src/glsl/pp/sl_pp_extension.c | 49 ++++++++++++++++++++++++++++++++----------- src/glsl/pp/sl_pp_macro.c | 12 +++++++++++ src/glsl/pp/sl_pp_public.h | 5 +++++ 6 files changed, 64 insertions(+), 16 deletions(-) (limited to 'src/glsl/pp/sl_pp_macro.c') diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index 569a2d735b9..5e3ae72fdfa 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -37,6 +37,13 @@ #define SL_PP_MAX_ERROR_MSG 1024 +#define SL_PP_MAX_EXTENSIONS 16 + +struct sl_pp_extension { + int name; /*< VENDOR_extension_name */ + int name_string; /*< GL_VENDOR_extension_name */ +}; + struct sl_pp_context { char *cstr_pool; unsigned int cstr_pool_max; @@ -46,6 +53,9 @@ struct sl_pp_context { struct sl_pp_macro *macro; struct sl_pp_macro **macro_tail; + struct sl_pp_extension extensions[SL_PP_MAX_EXTENSIONS]; + unsigned int num_extensions; + unsigned int if_stack[SL_PP_MAX_IF_NESTING]; unsigned int if_ptr; unsigned int if_value; diff --git a/src/glsl/pp/sl_pp_dict.c b/src/glsl/pp/sl_pp_dict.c index 2dd77a69e90..062139e6ac0 100644 --- a/src/glsl/pp/sl_pp_dict.c +++ b/src/glsl/pp/sl_pp_dict.c @@ -45,8 +45,6 @@ int sl_pp_dict_init(struct sl_pp_context *context) { ADD_NAME(context, all); - ADD_NAME_STR(context, _GL_ARB_draw_buffers, "GL_ARB_draw_buffers"); - ADD_NAME_STR(context, _GL_ARB_texture_rectangle, "GL_ARB_texture_rectangle"); ADD_NAME(context, require); ADD_NAME(context, enable); diff --git a/src/glsl/pp/sl_pp_dict.h b/src/glsl/pp/sl_pp_dict.h index 49f0e0bf9fa..875217bd309 100644 --- a/src/glsl/pp/sl_pp_dict.h +++ b/src/glsl/pp/sl_pp_dict.h @@ -33,8 +33,6 @@ struct sl_pp_context; struct sl_pp_dict { int all; - int _GL_ARB_draw_buffers; - int _GL_ARB_texture_rectangle; int require; int enable; diff --git a/src/glsl/pp/sl_pp_extension.c b/src/glsl/pp/sl_pp_extension.c index 4148fd9a5a3..67b24404d4d 100644 --- a/src/glsl/pp/sl_pp_extension.c +++ b/src/glsl/pp/sl_pp_extension.c @@ -28,8 +28,34 @@ #include #include #include "sl_pp_process.h" +#include "sl_pp_public.h" +int +sl_pp_context_add_extension(struct sl_pp_context *context, + const char *name, + const char *name_string) +{ + struct sl_pp_extension ext; + + if (context->num_extensions == SL_PP_MAX_EXTENSIONS) { + return -1; + } + + ext.name = sl_pp_context_add_unique_str(context, name); + if (ext.name == -1) { + return -1; + } + + ext.name_string = sl_pp_context_add_unique_str(context, name_string); + if (ext.name_string == -1) { + return -1; + } + + context->extensions[context->num_extensions++] = ext; + return 0; +} + int sl_pp_process_extension(struct sl_pp_context *context, const struct sl_pp_token_info *input, @@ -37,14 +63,7 @@ sl_pp_process_extension(struct sl_pp_context *context, unsigned int last, struct sl_pp_process_state *state) { - int extensions[] = { - context->dict.all, - context->dict._GL_ARB_draw_buffers, - context->dict._GL_ARB_texture_rectangle, - -1 - }; int extension_name = -1; - int *ext; int behavior = -1; struct sl_pp_token_info out; @@ -59,11 +78,17 @@ sl_pp_process_extension(struct sl_pp_context *context, } /* Make sure the extension is supported. */ - out.data.extension = -1; - for (ext = extensions; *ext != -1; ext++) { - if (extension_name == *ext) { - out.data.extension = extension_name; - break; + if (extension_name == context->dict.all) { + out.data.extension = extension_name; + } else { + unsigned int i; + + out.data.extension = -1; + for (i = 0; i < context->num_extensions; i++) { + if (extension_name == context->extensions[i].name_string) { + out.data.extension = extension_name; + break; + } } } diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index 29f1229dd7d..05466c9a7c3 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -163,6 +163,18 @@ sl_pp_macro_expand(struct sl_pp_context *context, return 0; } + /* Replace extension names with 1. + */ + for (j = 0; j < context->num_extensions; j++) { + if (macro_name == context->extensions[j].name) { + if (!mute && _out_number(context, state, 1)) { + return -1; + } + (*pi)++; + return 0; + } + } + /* TODO: For FEATURE_es2_glsl, expand to 1 the following symbols. * GL_ES * GL_FRAGMENT_PRECISION_HIGH diff --git a/src/glsl/pp/sl_pp_public.h b/src/glsl/pp/sl_pp_public.h index 8317c7e378a..20f208975e4 100644 --- a/src/glsl/pp/sl_pp_public.h +++ b/src/glsl/pp/sl_pp_public.h @@ -45,6 +45,11 @@ sl_pp_context_destroy(struct sl_pp_context *context); const char * sl_pp_context_error_message(const struct sl_pp_context *context); +int +sl_pp_context_add_extension(struct sl_pp_context *context, + const char *name, + const char *name_string); + int sl_pp_context_add_unique_str(struct sl_pp_context *context, const char *str); -- cgit v1.2.3 From 22200bcafcc77ecdca0127ac72d68e75e2ad7aee Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 10 Dec 2009 12:58:21 +0100 Subject: glsl/pp: Add support for user-defined macros. --- src/glsl/pp/sl_pp_context.c | 25 +++++++++++++++++++++++++ src/glsl/pp/sl_pp_context.h | 10 ++++++++++ src/glsl/pp/sl_pp_macro.c | 17 +++++++++++++++++ src/glsl/pp/sl_pp_public.h | 5 +++++ 4 files changed, 57 insertions(+) (limited to 'src/glsl/pp/sl_pp_macro.c') diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index 134588d9066..afc1b84d16a 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -79,6 +79,31 @@ sl_pp_context_error_message(const struct sl_pp_context *context) return context->error_msg; } +int +sl_pp_context_add_predefined(struct sl_pp_context *context, + const char *name, + const char *value) +{ + struct sl_pp_predefined pre; + + if (context->num_predefined == SL_PP_MAX_PREDEFINED) { + return -1; + } + + pre.name = sl_pp_context_add_unique_str(context, name); + if (pre.name == -1) { + return -1; + } + + pre.value = sl_pp_context_add_unique_str(context, value); + if (pre.value == -1) { + return -1; + } + + context->predefined[context->num_predefined++] = pre; + return 0; +} + int sl_pp_context_add_unique_str(struct sl_pp_context *context, const char *str) diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index 5e3ae72fdfa..d95d29e275c 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -39,11 +39,18 @@ #define SL_PP_MAX_EXTENSIONS 16 +#define SL_PP_MAX_PREDEFINED 16 + struct sl_pp_extension { int name; /*< VENDOR_extension_name */ int name_string; /*< GL_VENDOR_extension_name */ }; +struct sl_pp_predefined { + int name; + int value; +}; + struct sl_pp_context { char *cstr_pool; unsigned int cstr_pool_max; @@ -56,6 +63,9 @@ struct sl_pp_context { struct sl_pp_extension extensions[SL_PP_MAX_EXTENSIONS]; unsigned int num_extensions; + struct sl_pp_predefined predefined[SL_PP_MAX_PREDEFINED]; + unsigned int num_predefined; + unsigned int if_stack[SL_PP_MAX_IF_NESTING]; unsigned int if_ptr; unsigned int if_value; diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index 05466c9a7c3..08b44c7cbe4 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -163,6 +163,23 @@ sl_pp_macro_expand(struct sl_pp_context *context, return 0; } + for (j = 0; j < context->num_predefined; j++) { + if (macro_name == context->predefined[j].name) { + if (!mute) { + struct sl_pp_token_info ti; + + ti.token = SL_PP_UINT; + ti.data._uint = context->predefined[j].value; + if (sl_pp_process_out(state, &ti)) { + strcpy(context->error_msg, "out of memory"); + return -1; + } + } + (*pi)++; + return 0; + } + } + /* Replace extension names with 1. */ for (j = 0; j < context->num_extensions; j++) { diff --git a/src/glsl/pp/sl_pp_public.h b/src/glsl/pp/sl_pp_public.h index 20f208975e4..076903649cd 100644 --- a/src/glsl/pp/sl_pp_public.h +++ b/src/glsl/pp/sl_pp_public.h @@ -50,6 +50,11 @@ sl_pp_context_add_extension(struct sl_pp_context *context, const char *name, const char *name_string); +int +sl_pp_context_add_predefined(struct sl_pp_context *context, + const char *name, + const char *value); + int sl_pp_context_add_unique_str(struct sl_pp_context *context, const char *str); -- cgit v1.2.3