From a67f32289a6e22daa2665310f4a8f26979f7ed60 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 14 Sep 2009 13:07:25 +0200 Subject: glsl/pp: Add a dictionary to a context. --- src/glsl/pp/sl_pp_dict.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/glsl/pp/sl_pp_dict.c (limited to 'src/glsl/pp/sl_pp_dict.c') diff --git a/src/glsl/pp/sl_pp_dict.c b/src/glsl/pp/sl_pp_dict.c new file mode 100644 index 00000000000..65b91d9e989 --- /dev/null +++ b/src/glsl/pp/sl_pp_dict.c @@ -0,0 +1,56 @@ +/************************************************************************** + * + * 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 "sl_pp_context.h" +#include "sl_pp_dict.h" + + +#define ADD_NAME_STR(CTX, NAME, STR)\ + do {\ + (CTX)->dict.NAME = sl_pp_context_add_unique_str((CTX), (STR));\ + if ((CTX)->dict.NAME == -1) {\ + return -1;\ + }\ + } while (0) + +#define ADD_NAME(CTX, NAME) ADD_NAME_STR(CTX, NAME, #NAME) + + +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); + ADD_NAME(context, warn); + ADD_NAME(context, disable); + + return 0; +} -- 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_dict.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 2f89e1a5a18c4c3c88d4e7613cbfc0f85a5fcfc9 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 23 Sep 2009 09:37:37 +0200 Subject: glsl/pp: Add `0' and `1' to dictionary. --- src/glsl/pp/sl_pp_dict.c | 3 +++ src/glsl/pp/sl_pp_dict.h | 3 +++ src/glsl/pp/sl_pp_if.c | 9 +-------- 3 files changed, 7 insertions(+), 8 deletions(-) (limited to 'src/glsl/pp/sl_pp_dict.c') diff --git a/src/glsl/pp/sl_pp_dict.c b/src/glsl/pp/sl_pp_dict.c index f2885c763d7..0e1fa368577 100644 --- a/src/glsl/pp/sl_pp_dict.c +++ b/src/glsl/pp/sl_pp_dict.c @@ -79,5 +79,8 @@ sl_pp_dict_init(struct sl_pp_context *context) ADD_NAME(context, version); + ADD_NAME_STR(context, _0, "0"); + ADD_NAME_STR(context, _1, "1"); + return 0; } diff --git a/src/glsl/pp/sl_pp_dict.h b/src/glsl/pp/sl_pp_dict.h index ba82b389b23..683752e000a 100644 --- a/src/glsl/pp/sl_pp_dict.h +++ b/src/glsl/pp/sl_pp_dict.h @@ -64,6 +64,9 @@ struct sl_pp_dict { int undef; int version; + + int _0; + int _1; }; diff --git a/src/glsl/pp/sl_pp_if.c b/src/glsl/pp/sl_pp_if.c index 5fa27fcf053..c8e958eab49 100644 --- a/src/glsl/pp/sl_pp_if.c +++ b/src/glsl/pp/sl_pp_if.c @@ -82,14 +82,7 @@ _parse_defined(struct sl_pp_context *context, } result.token = SL_PP_UINT; - if (defined) { - result.data._uint = sl_pp_context_add_unique_str(context, "1"); - } else { - result.data._uint = sl_pp_context_add_unique_str(context, "0"); - } - if (result.data._uint == -1) { - return -1; - } + result.data._uint = (defined ? context->dict._1 : context->dict._0); if (sl_pp_process_out(state, &result)) { strcpy(context->error_msg, "out of memory"); -- 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_dict.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 abe1f332983e5c70d75b5ae83f06c0dfdd081a26 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 21 Nov 2009 20:41:48 +0100 Subject: glsl/pp: Do purification and tokenisation in a single step. --- src/glsl/pp/sl_pp_context.c | 7 + src/glsl/pp/sl_pp_context.h | 11 +- src/glsl/pp/sl_pp_dict.c | 1 + src/glsl/pp/sl_pp_public.h | 4 + src/glsl/pp/sl_pp_token.c | 844 ++++++++++++++++++++++++++++---------------- src/glsl/pp/sl_pp_token.h | 1 + 6 files changed, 561 insertions(+), 307 deletions(-) (limited to 'src/glsl/pp/sl_pp_dict.c') diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index 8ce189d955c..134588d9066 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -46,6 +46,12 @@ sl_pp_context_create(void) return NULL; } + context->getc_buf = malloc(64 * sizeof(char)); + if (!context->getc_buf) { + sl_pp_context_destroy(context); + return NULL; + } + context->macro_tail = &context->macro; context->if_ptr = SL_PP_MAX_IF_NESTING; context->if_value = 1; @@ -62,6 +68,7 @@ sl_pp_context_destroy(struct sl_pp_context *context) if (context) { free(context->cstr_pool); sl_pp_macro_free(context->macro); + free(context->getc_buf); free(context); } } diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index 6b8cc2f960d..569a2d735b9 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -30,6 +30,7 @@ #include "sl_pp_dict.h" #include "sl_pp_macro.h" +#include "sl_pp_purify.h" #define SL_PP_MAX_IF_NESTING 64 @@ -53,10 +54,12 @@ struct sl_pp_context { unsigned int line; unsigned int file; -}; -int -sl_pp_context_add_unique_str(struct sl_pp_context *context, - const char *str); + struct sl_pp_purify_state pure; + + char *getc_buf; + unsigned int getc_buf_size; + unsigned int getc_buf_capacity; +}; #endif /* SL_PP_CONTEXT_H */ diff --git a/src/glsl/pp/sl_pp_dict.c b/src/glsl/pp/sl_pp_dict.c index 82fb9127b50..2dd77a69e90 100644 --- a/src/glsl/pp/sl_pp_dict.c +++ b/src/glsl/pp/sl_pp_dict.c @@ -25,6 +25,7 @@ * **************************************************************************/ +#include "sl_pp_public.h" #include "sl_pp_context.h" #include "sl_pp_dict.h" diff --git a/src/glsl/pp/sl_pp_public.h b/src/glsl/pp/sl_pp_public.h index b1d92d02a7a..8317c7e378a 100644 --- a/src/glsl/pp/sl_pp_public.h +++ b/src/glsl/pp/sl_pp_public.h @@ -45,6 +45,10 @@ 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_unique_str(struct sl_pp_context *context, + const char *str); + const char * sl_pp_context_cstr(const struct sl_pp_context *context, int offset); diff --git a/src/glsl/pp/sl_pp_token.c b/src/glsl/pp/sl_pp_token.c index f232dafc682..03f2f09cfd6 100644 --- a/src/glsl/pp/sl_pp_token.c +++ b/src/glsl/pp/sl_pp_token.c @@ -25,12 +25,106 @@ * **************************************************************************/ +#include #include #include +#include "sl_pp_public.h" #include "sl_pp_context.h" #include "sl_pp_token.h" +#define PURE_ERROR 256 + +int +_pure_getc(struct sl_pp_context *context) +{ + char c; + unsigned int current_line; + + if (context->getc_buf_size) { + return context->getc_buf[--context->getc_buf_size]; + } + + if (sl_pp_purify_getc(&context->pure, &c, ¤t_line, context->error_msg, sizeof(context->error_msg)) == 0) { + return PURE_ERROR; + } + return c; +} + + +void +_pure_ungetc(struct sl_pp_context *context, + int c) +{ + assert(c != PURE_ERROR); + + if (context->getc_buf_size == context->getc_buf_capacity) { + context->getc_buf_capacity += 64; + context->getc_buf = realloc(context->getc_buf, context->getc_buf_capacity * sizeof(char)); + assert(context->getc_buf); + } + + context->getc_buf[context->getc_buf_size++] = (char)c; +} + + +struct lookahead_state { + char buf[256]; + unsigned int pos; + struct sl_pp_context *context; +}; + + +static void +_lookahead_init(struct lookahead_state *lookahead, + struct sl_pp_context *context) +{ + lookahead->pos = 0; + lookahead->context = context; +} + + +static unsigned int +_lookahead_tell(const struct lookahead_state *lookahead) +{ + return lookahead->pos; +} + + +static const void * +_lookahead_buf(const struct lookahead_state *lookahead) +{ + return lookahead->buf; +} + + +static void +_lookahead_revert(struct lookahead_state *lookahead, + unsigned int pos) +{ + assert(pos <= lookahead->pos); + + while (lookahead->pos > pos) { + _pure_ungetc(lookahead->context, lookahead->buf[--lookahead->pos]); + } +} + + +static int +_lookahead_getc(struct lookahead_state *lookahead) +{ + int c; + + assert(lookahead->pos < sizeof(lookahead->buf) / sizeof(lookahead->buf[0])); + + c = _pure_getc(lookahead->context); + if (c != PURE_ERROR) { + lookahead->buf[lookahead->pos++] = (char)c; + } + return c; +} + + static int _is_identifier_char(char c) { @@ -40,32 +134,51 @@ _is_identifier_char(char c) static int _tokenise_identifier(struct sl_pp_context *context, - const char **pinput, - struct sl_pp_token_info *info) + struct sl_pp_token_info *out) { - const char *input = *pinput; + int c; char identifier[256]; /* XXX: Remove this artifical limit. */ unsigned int i = 0; - info->token = SL_PP_IDENTIFIER; - info->data.identifier = -1; + out->token = SL_PP_IDENTIFIER; + out->data.identifier = -1; - identifier[i++] = *input++; - while (_is_identifier_char(*input)) { - if (i >= sizeof(identifier) - 1) { - strcpy(context->error_msg, "out of memory"); + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + identifier[i++] = (char)c; + for (;;) { + c = _pure_getc(context); + if (c == PURE_ERROR) { return -1; } - identifier[i++] = *input++; + + if (_is_identifier_char((char)c)) { + if (i >= sizeof(identifier) / sizeof(char) - 1) { + strcpy(context->error_msg, "out of memory"); + _pure_ungetc(context, c); + while (i) { + _pure_ungetc(context, identifier[--i]); + } + return -1; + } + identifier[i++] = (char)c; + } else { + _pure_ungetc(context, c); + break; + } } - identifier[i++] = '\0'; + identifier[i] = '\0'; - info->data.identifier = sl_pp_context_add_unique_str(context, identifier); - if (info->data.identifier == -1) { + out->data.identifier = sl_pp_context_add_unique_str(context, identifier); + if (out->data.identifier == -1) { + while (i) { + _pure_ungetc(context, identifier[--i]); + } return -1; } - *pinput = input; return 0; } @@ -74,12 +187,18 @@ _tokenise_identifier(struct sl_pp_context *context, * Return the number of consecutive decimal digits in the input stream. */ static unsigned int -_parse_float_digits(const char *input) +_parse_float_digits(struct lookahead_state *lookahead) { - unsigned int eaten = 0; + unsigned int eaten; + + for (eaten = 0;; eaten++) { + unsigned int pos = _lookahead_tell(lookahead); + char c = _lookahead_getc(lookahead); - while (input[eaten] >= '0' && input[eaten] <= '9') { - eaten++; + if (c < '0' || c > '9') { + _lookahead_revert(lookahead, pos); + break; + } } return eaten; } @@ -96,29 +215,33 @@ _parse_float_digits(const char *input) * of eaten characters from the input stream. */ static unsigned int -_parse_float_frac(const char *input) +_parse_float_frac(struct lookahead_state *lookahead) { + unsigned int pos; + int c; unsigned int eaten; - if (input[0] == '.') { - eaten = _parse_float_digits(&input[1]); + pos = _lookahead_tell(lookahead); + c = _lookahead_getc(lookahead); + if (c == '.') { + eaten = _parse_float_digits(lookahead); if (eaten) { return eaten + 1; } + _lookahead_revert(lookahead, pos); return 0; } - eaten = _parse_float_digits(input); - if (eaten && input[eaten] == '.') { - unsigned int trailing; - - trailing = _parse_float_digits(&input[eaten + 1]); - if (trailing) { - return eaten + trailing + 1; + _lookahead_revert(lookahead, pos); + eaten = _parse_float_digits(lookahead); + if (eaten) { + c = _lookahead_getc(lookahead); + if (c == '.') { + return eaten + 1 + _parse_float_digits(lookahead); } - return eaten + 1; } + _lookahead_revert(lookahead, pos); return 0; } @@ -133,22 +256,31 @@ _parse_float_frac(const char *input) * of eaten characters from the input stream. */ static unsigned int -_parse_float_exp(const char *input) +_parse_float_exp(struct lookahead_state *lookahead) { + unsigned int pos, pos2; + int c; unsigned int eaten, digits; - if (input[0] != 'e' && input[0] != 'E') { + pos = _lookahead_tell(lookahead); + c = _lookahead_getc(lookahead); + if (c != 'e' && c != 'E') { + _lookahead_revert(lookahead, pos); return 0; } - if (input[1] == '-' || input[1] == '+') { + pos2 = _lookahead_tell(lookahead); + c = _lookahead_getc(lookahead); + if (c == '-' || c == '+') { eaten = 2; } else { + _lookahead_revert(lookahead, pos2); eaten = 1; } - digits = _parse_float_digits(&input[eaten]); + digits = _parse_float_digits(lookahead); if (!digits) { + _lookahead_revert(lookahead, pos); return 0; } @@ -166,86 +298,117 @@ _parse_float_exp(const char *input) * of eaten characters from the input stream. */ static unsigned int -_parse_float(const char *input) +_parse_float(struct lookahead_state *lookahead) { unsigned int eaten; - eaten = _parse_float_frac(input); + eaten = _parse_float_frac(lookahead); if (eaten) { - unsigned int exponent; + unsigned int pos; + int c; - exponent = _parse_float_exp(&input[eaten]); - if (exponent) { - eaten += exponent; - } + eaten += _parse_float_exp(lookahead); - if (input[eaten] == 'f' || input[eaten] == 'F') { + pos = _lookahead_tell(lookahead); + c = _lookahead_getc(lookahead); + if (c == 'f' || c == 'F') { eaten++; + } else { + _lookahead_revert(lookahead, pos); } return eaten; } - eaten = _parse_float_digits(input); + eaten = _parse_float_digits(lookahead); if (eaten) { unsigned int exponent; - exponent = _parse_float_exp(&input[eaten]); + exponent = _parse_float_exp(lookahead); if (exponent) { + unsigned int pos; + int c; + eaten += exponent; - if (input[eaten] == 'f' || input[eaten] == 'F') { + pos = _lookahead_tell(lookahead); + c = _lookahead_getc(lookahead); + if (c == 'f' || c == 'F') { eaten++; + } else { + _lookahead_revert(lookahead, pos); } return eaten; } } + _lookahead_revert(lookahead, 0); return 0; } static unsigned int -_parse_hex(const char *input) +_parse_hex(struct lookahead_state *lookahead) { + int c; unsigned int n; - if (input[0] != '0') { + c = _lookahead_getc(lookahead); + if (c != '0') { + _lookahead_revert(lookahead, 0); return 0; } - if (input[1] != 'x' && input[1] != 'X') { + c = _lookahead_getc(lookahead); + if (c != 'x' && c != 'X') { + _lookahead_revert(lookahead, 0); return 0; } - n = 2; - while ((input[n] >= '0' && input[n] <= '9') || - (input[n] >= 'a' && input[n] <= 'f') || - (input[n] >= 'A' && input[n] <= 'F')) { - n++; + for (n = 2;;) { + unsigned int pos = _lookahead_tell(lookahead); + + c = _lookahead_getc(lookahead); + if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { + n++; + } else { + _lookahead_revert(lookahead, pos); + break; + } } if (n > 2) { return n; } + _lookahead_revert(lookahead, 0); return 0; } static unsigned int -_parse_oct(const char *input) +_parse_oct(struct lookahead_state *lookahead) { + int c; unsigned int n; - if (input[0] != '0') { + c = _lookahead_getc(lookahead); + if (c != '0') { + _lookahead_revert(lookahead, 0); return 0; } - n = 1; - while ((input[n] >= '0' && input[n] <= '7')) { - n++; + for (n = 1;;) { + unsigned int pos = _lookahead_tell(lookahead); + + c = _lookahead_getc(lookahead); + if ((c >= '0' && c <= '7')) { + n++; + } else { + _lookahead_revert(lookahead, pos); + break; + } } return n; @@ -253,12 +416,20 @@ _parse_oct(const char *input) static unsigned int -_parse_dec(const char *input) +_parse_dec(struct lookahead_state *lookahead) { unsigned int n = 0; - while ((input[n] >= '0' && input[n] <= '9')) { - n++; + for (;;) { + unsigned int pos = _lookahead_tell(lookahead); + int c = _lookahead_getc(lookahead); + + if ((c >= '0' && c <= '9')) { + n++; + } else { + _lookahead_revert(lookahead, pos); + break; + } } return n; @@ -267,327 +438,394 @@ _parse_dec(const char *input) static int _tokenise_number(struct sl_pp_context *context, - const char **pinput, - struct sl_pp_token_info *info) + struct sl_pp_token_info *out) { - const char *input = *pinput; + struct lookahead_state lookahead; unsigned int eaten; unsigned int is_float = 0; + unsigned int pos; + int c; char number[256]; /* XXX: Remove this artifical limit. */ - eaten = _parse_float(input); + _lookahead_init(&lookahead, context); + + eaten = _parse_float(&lookahead); if (!eaten) { - eaten = _parse_hex(input); + eaten = _parse_hex(&lookahead); if (!eaten) { - eaten = _parse_oct(input); + eaten = _parse_oct(&lookahead); if (!eaten) { - eaten = _parse_dec(input); + eaten = _parse_dec(&lookahead); } } } else { is_float = 1; } - if (!eaten || _is_identifier_char(input[eaten])) { + if (!eaten) { strcpy(context->error_msg, "expected a number"); return -1; } + pos = _lookahead_tell(&lookahead); + c = _lookahead_getc(&lookahead); + _lookahead_revert(&lookahead, pos); + + if (_is_identifier_char(c)) { + strcpy(context->error_msg, "expected a number"); + _lookahead_revert(&lookahead, 0); + return -1; + } + if (eaten > sizeof(number) - 1) { strcpy(context->error_msg, "out of memory"); + _lookahead_revert(&lookahead, 0); return -1; } - memcpy(number, input, eaten); + assert(_lookahead_tell(&lookahead) == eaten); + + memcpy(number, _lookahead_buf(&lookahead), eaten); number[eaten] = '\0'; if (is_float) { - info->token = SL_PP_FLOAT; - info->data._float = sl_pp_context_add_unique_str(context, number); - if (info->data._float == -1) { + out->token = SL_PP_FLOAT; + out->data._float = sl_pp_context_add_unique_str(context, number); + if (out->data._float == -1) { + _lookahead_revert(&lookahead, 0); return -1; } } else { - info->token = SL_PP_UINT; - info->data._uint = sl_pp_context_add_unique_str(context, number); - if (info->data._uint == -1) { + out->token = SL_PP_UINT; + out->data._uint = sl_pp_context_add_unique_str(context, number); + if (out->data._uint == -1) { + _lookahead_revert(&lookahead, 0); return -1; } } - *pinput = input + eaten; return 0; } int -sl_pp_tokenise(struct sl_pp_context *context, - const char *input, - struct sl_pp_token_info **output) +sl_pp_token_get(struct sl_pp_context *context, + struct sl_pp_token_info *out) { - struct sl_pp_token_info *out = NULL; - unsigned int out_len = 0; - unsigned int out_max = 0; + int c = _pure_getc(context); - for (;;) { - struct sl_pp_token_info info; + switch (c) { + case ' ': + case '\t': + out->token = SL_PP_WHITESPACE; + break; - switch (*input) { - case ' ': - case '\t': - input++; - info.token = SL_PP_WHITESPACE; - break; + case '\n': + out->token = SL_PP_NEWLINE; + break; - case '\n': - input++; - info.token = SL_PP_NEWLINE; - break; + case '#': + out->token = SL_PP_HASH; + break; - case '#': - input++; - info.token = SL_PP_HASH; - break; + case ',': + out->token = SL_PP_COMMA; + break; - case ',': - input++; - info.token = SL_PP_COMMA; - break; + case ';': + out->token = SL_PP_SEMICOLON; + break; - case ';': - input++; - info.token = SL_PP_SEMICOLON; - break; + case '{': + out->token = SL_PP_LBRACE; + break; - case '{': - input++; - info.token = SL_PP_LBRACE; - break; + case '}': + out->token = SL_PP_RBRACE; + break; - case '}': - input++; - info.token = SL_PP_RBRACE; - break; + case '(': + out->token = SL_PP_LPAREN; + break; - case '(': - input++; - info.token = SL_PP_LPAREN; - break; + case ')': + out->token = SL_PP_RPAREN; + break; - case ')': - input++; - info.token = SL_PP_RPAREN; - break; + case '[': + out->token = SL_PP_LBRACKET; + break; - case '[': - input++; - info.token = SL_PP_LBRACKET; - break; + case ']': + out->token = SL_PP_RBRACKET; + break; - case ']': - input++; - info.token = SL_PP_RBRACKET; - break; + case '.': + { + int c2 = _pure_getc(context); - case '.': - if (input[1] >= '0' && input[1] <= '9') { - if (_tokenise_number(context, &input, &info)) { - free(out); + if (c2 == PURE_ERROR) { + return -1; + } + if (c2 >= '0' && c2 <= '9') { + _pure_ungetc(context, c2); + _pure_ungetc(context, c); + if (_tokenise_number(context, out)) { return -1; } } else { - input++; - info.token = SL_PP_DOT; + _pure_ungetc(context, c2); + out->token = SL_PP_DOT; } - break; + } + break; - case '+': - input++; - if (*input == '+') { - input++; - info.token = SL_PP_INCREMENT; - } else if (*input == '=') { - input++; - info.token = SL_PP_ADDASSIGN; - } else { - info.token = SL_PP_PLUS; - } - break; + case '+': + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + if (c == '+') { + out->token = SL_PP_INCREMENT; + } else if (c == '=') { + out->token = SL_PP_ADDASSIGN; + } else { + _pure_ungetc(context, c); + out->token = SL_PP_PLUS; + } + break; - case '-': - input++; - if (*input == '-') { - input++; - info.token = SL_PP_DECREMENT; - } else if (*input == '=') { - input++; - info.token = SL_PP_SUBASSIGN; - } else { - info.token = SL_PP_MINUS; - } - break; + case '-': + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + if (c == '-') { + out->token = SL_PP_DECREMENT; + } else if (c == '=') { + out->token = SL_PP_SUBASSIGN; + } else { + _pure_ungetc(context, c); + out->token = SL_PP_MINUS; + } + break; - case '~': - input++; - info.token = SL_PP_BITNOT; - break; + case '~': + out->token = SL_PP_BITNOT; + break; - case '!': - input++; - if (*input == '=') { - input++; - info.token = SL_PP_NOTEQUAL; - } else { - info.token = SL_PP_NOT; - } - break; + case '!': + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + if (c == '=') { + out->token = SL_PP_NOTEQUAL; + } else { + _pure_ungetc(context, c); + out->token = SL_PP_NOT; + } + break; - case '*': - input++; - if (*input == '=') { - input++; - info.token = SL_PP_MULASSIGN; - } else { - info.token = SL_PP_STAR; - } - break; + case '*': + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + if (c == '=') { + out->token = SL_PP_MULASSIGN; + } else { + _pure_ungetc(context, c); + out->token = SL_PP_STAR; + } + break; - case '/': - input++; - if (*input == '=') { - input++; - info.token = SL_PP_DIVASSIGN; - } else { - info.token = SL_PP_SLASH; - } - break; + case '/': + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + if (c == '=') { + out->token = SL_PP_DIVASSIGN; + } else { + _pure_ungetc(context, c); + out->token = SL_PP_SLASH; + } + break; - case '%': - input++; - if (*input == '=') { - input++; - info.token = SL_PP_MODASSIGN; - } else { - info.token = SL_PP_MODULO; - } - break; + case '%': + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + if (c == '=') { + out->token = SL_PP_MODASSIGN; + } else { + _pure_ungetc(context, c); + out->token = SL_PP_MODULO; + } + break; - case '<': - input++; - if (*input == '<') { - input++; - if (*input == '=') { - input++; - info.token = SL_PP_LSHIFTASSIGN; - } else { - info.token = SL_PP_LSHIFT; - } - } else if (*input == '=') { - input++; - info.token = SL_PP_LESSEQUAL; - } else { - info.token = SL_PP_LESS; + case '<': + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + if (c == '<') { + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; } - break; - - case '>': - input++; - if (*input == '>') { - input++; - if (*input == '=') { - input++; - info.token = SL_PP_RSHIFTASSIGN; - } else { - info.token = SL_PP_RSHIFT; - } - } else if (*input == '=') { - input++; - info.token = SL_PP_GREATEREQUAL; + if (c == '=') { + out->token = SL_PP_LSHIFTASSIGN; } else { - info.token = SL_PP_GREATER; + _pure_ungetc(context, c); + out->token = SL_PP_LSHIFT; } - break; + } else if (c == '=') { + out->token = SL_PP_LESSEQUAL; + } else { + _pure_ungetc(context, c); + out->token = SL_PP_LESS; + } + break; - case '=': - input++; - if (*input == '=') { - input++; - info.token = SL_PP_EQUAL; - } else { - info.token = SL_PP_ASSIGN; + case '>': + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + if (c == '>') { + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; } - break; - - case '&': - input++; - if (*input == '&') { - input++; - info.token = SL_PP_AND; - } else if (*input == '=') { - input++; - info.token = SL_PP_BITANDASSIGN; + if (c == '=') { + out->token = SL_PP_RSHIFTASSIGN; } else { - info.token = SL_PP_BITAND; + _pure_ungetc(context, c); + out->token = SL_PP_RSHIFT; } - break; + } else if (c == '=') { + out->token = SL_PP_GREATEREQUAL; + } else { + _pure_ungetc(context, c); + out->token = SL_PP_GREATER; + } + break; - case '^': - input++; - if (*input == '^') { - input++; - info.token = SL_PP_XOR; - } else if (*input == '=') { - input++; - info.token = SL_PP_BITXORASSIGN; - } else { - info.token = SL_PP_BITXOR; - } - break; + case '=': + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + if (c == '=') { + out->token = SL_PP_EQUAL; + } else { + _pure_ungetc(context, c); + out->token = SL_PP_ASSIGN; + } + break; - case '|': - input++; - if (*input == '|') { - input++; - info.token = SL_PP_OR; - } else if (*input == '=') { - input++; - info.token = SL_PP_BITORASSIGN; - } else { - info.token = SL_PP_BITOR; - } - break; + case '&': + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + if (c == '&') { + out->token = SL_PP_AND; + } else if (c == '=') { + out->token = SL_PP_BITANDASSIGN; + } else { + _pure_ungetc(context, c); + out->token = SL_PP_BITAND; + } + break; - case '?': - input++; - info.token = SL_PP_QUESTION; - break; + case '^': + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + if (c == '^') { + out->token = SL_PP_XOR; + } else if (c == '=') { + out->token = SL_PP_BITXORASSIGN; + } else { + _pure_ungetc(context, c); + out->token = SL_PP_BITXOR; + } + break; - case ':': - input++; - info.token = SL_PP_COLON; - break; + case '|': + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + if (c == '|') { + out->token = SL_PP_OR; + } else if (c == '=') { + out->token = SL_PP_BITORASSIGN; + } else { + _pure_ungetc(context, c); + out->token = SL_PP_BITOR; + } + break; - case '\0': - info.token = SL_PP_EOF; - break; + case '?': + out->token = SL_PP_QUESTION; + break; - default: - if ((*input >= 'a' && *input <= 'z') || - (*input >= 'A' && *input <= 'Z') || - (*input == '_')) { - if (_tokenise_identifier(context, &input, &info)) { - free(out); - return -1; - } - } else if (*input >= '0' && *input <= '9') { - if (_tokenise_number(context, &input, &info)) { - free(out); - return -1; - } - } else { - info.data.other = *input++; - info.token = SL_PP_OTHER; + case ':': + out->token = SL_PP_COLON; + break; + + case '\0': + out->token = SL_PP_EOF; + break; + + case PURE_ERROR: + return -1; + + default: + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_') { + _pure_ungetc(context, c); + if (_tokenise_identifier(context, out)) { + return -1; } + } else if (c >= '0' && c <= '9') { + _pure_ungetc(context, c); + if (_tokenise_number(context, out)) { + return -1; + } + } else { + out->data.other = c; + out->token = SL_PP_OTHER; + } + } + + return 0; +} + + +int +sl_pp_tokenise(struct sl_pp_context *context, + const char *input, + const struct sl_pp_purify_options *options, + struct sl_pp_token_info **output) +{ + struct sl_pp_token_info *out = NULL; + unsigned int out_len = 0; + unsigned int out_max = 0; + + sl_pp_purify_state_init(&context->pure, input, options); + + for (;;) { + struct sl_pp_token_info info; + + if (sl_pp_token_get(context, &info)) { + free(out); + return -1; } if (out_len >= out_max) { diff --git a/src/glsl/pp/sl_pp_token.h b/src/glsl/pp/sl_pp_token.h index 29c7571711e..7a8fa2f1b9d 100644 --- a/src/glsl/pp/sl_pp_token.h +++ b/src/glsl/pp/sl_pp_token.h @@ -123,6 +123,7 @@ struct sl_pp_token_info { int sl_pp_tokenise(struct sl_pp_context *context, const char *input, + const struct sl_pp_purify_options *options, struct sl_pp_token_info **output); #endif /* SL_PP_TOKEN_H */ -- 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_dict.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