summaryrefslogtreecommitdiff
path: root/src/glsl/pp/sl_pp_define.c
diff options
context:
space:
mode:
authorJosé Fonseca <jfonseca@vmware.com>2010-01-08 15:42:57 +0000
committerJosé Fonseca <jfonseca@vmware.com>2010-01-08 15:42:57 +0000
commit080c40ab32b2abd6d8381b4a0cc143d36a1652b2 (patch)
treee173767ebc5a82d81b9fc086449d915e29348976 /src/glsl/pp/sl_pp_define.c
parent9cdf6f025b2ed55cfb13dd09f870f01d0c7947d3 (diff)
parenta1de400e8de06a80ab140bb0fa950e990607572d (diff)
Merge remote branch 'origin/master' into lp-binning
Conflicts: src/gallium/auxiliary/util/u_surface.c src/gallium/drivers/llvmpipe/Makefile src/gallium/drivers/llvmpipe/SConscript src/gallium/drivers/llvmpipe/lp_bld_arit.c src/gallium/drivers/llvmpipe/lp_bld_flow.c src/gallium/drivers/llvmpipe/lp_bld_interp.c src/gallium/drivers/llvmpipe/lp_clear.c src/gallium/drivers/llvmpipe/lp_context.c src/gallium/drivers/llvmpipe/lp_context.h src/gallium/drivers/llvmpipe/lp_draw_arrays.c src/gallium/drivers/llvmpipe/lp_jit.c src/gallium/drivers/llvmpipe/lp_jit.h src/gallium/drivers/llvmpipe/lp_prim_vbuf.c src/gallium/drivers/llvmpipe/lp_setup.c src/gallium/drivers/llvmpipe/lp_setup_point.c src/gallium/drivers/llvmpipe/lp_state.h src/gallium/drivers/llvmpipe/lp_state_blend.c src/gallium/drivers/llvmpipe/lp_state_derived.c src/gallium/drivers/llvmpipe/lp_state_fs.c src/gallium/drivers/llvmpipe/lp_state_sampler.c src/gallium/drivers/llvmpipe/lp_state_surface.c src/gallium/drivers/llvmpipe/lp_tex_cache.c src/gallium/drivers/llvmpipe/lp_tex_cache.h src/gallium/drivers/llvmpipe/lp_tex_sample.h src/gallium/drivers/llvmpipe/lp_tile_cache.c
Diffstat (limited to 'src/glsl/pp/sl_pp_define.c')
-rw-r--r--src/glsl/pp/sl_pp_define.c238
1 files changed, 238 insertions, 0 deletions
diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c
new file mode 100644
index 0000000000..808a6a0d4f
--- /dev/null
+++ b/src/glsl/pp/sl_pp_define.c
@@ -0,0 +1,238 @@
+/**************************************************************************
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+#include "sl_pp_context.h"
+#include "sl_pp_process.h"
+#include "sl_pp_public.h"
+
+
+static void
+skip_whitespace(const struct sl_pp_token_info *input,
+ unsigned int *first,
+ unsigned int last)
+{
+ while (*first < last && input[*first].token == SL_PP_WHITESPACE) {
+ (*first)++;
+ }
+}
+
+
+static int
+_parse_formal_args(struct sl_pp_context *context,
+ const struct sl_pp_token_info *input,
+ unsigned int *first,
+ unsigned int last,
+ struct sl_pp_macro *macro)
+{
+ struct sl_pp_macro_formal_arg **arg;
+
+ macro->num_args = 0;
+
+ skip_whitespace(input, first, last);
+ if (*first < last) {
+ if (input[*first].token == SL_PP_RPAREN) {
+ (*first)++;
+ return 0;
+ }
+ } else {
+ strcpy(context->error_msg, "expected either macro formal argument or `)'");
+ return -1;
+ }
+
+ arg = &macro->arg;
+
+ for (;;) {
+ if (*first < last && input[*first].token != SL_PP_IDENTIFIER) {
+ strcpy(context->error_msg, "expected macro formal argument");
+ return -1;
+ }
+
+ *arg = malloc(sizeof(struct sl_pp_macro_formal_arg));
+ if (!*arg) {
+ strcpy(context->error_msg, "out of memory");
+ return -1;
+ }
+
+ (**arg).name = input[*first].data.identifier;
+ (*first)++;
+
+ (**arg).next = NULL;
+ arg = &(**arg).next;
+
+ macro->num_args++;
+
+ skip_whitespace(input, first, last);
+ if (*first < last) {
+ if (input[*first].token == SL_PP_COMMA) {
+ (*first)++;
+ skip_whitespace(input, first, last);
+ } else if (input[*first].token == SL_PP_RPAREN) {
+ (*first)++;
+ return 0;
+ } else {
+ strcpy(context->error_msg, "expected either `,' or `)'");
+ return -1;
+ }
+ } else {
+ strcpy(context->error_msg, "expected either `,' or `)'");
+ return -1;
+ }
+ }
+
+ /* Should not gete here. */
+}
+
+
+int
+sl_pp_process_define(struct sl_pp_context *context,
+ const struct sl_pp_token_info *input,
+ unsigned int first,
+ unsigned int last)
+{
+ int macro_name = -1;
+ struct sl_pp_macro *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;
+ first++;
+ }
+ if (macro_name == -1) {
+ strcpy(context->error_msg, "expected macro name");
+ return -1;
+ }
+
+ /* Check for reserved macro names */
+ {
+ const char *name = sl_pp_context_cstr(context, macro_name);
+
+ if (strstr(name, "__")) {
+ strcpy(context->error_msg, "macro names containing `__' are reserved");
+ return 1;
+ }
+ if (name[0] == 'G' && name[1] == 'L' && name[2] == '_') {
+ strcpy(context->error_msg, "macro names prefixed with `GL_' are reserved");
+ return 1;
+ }
+ }
+
+ for (macro = context->macro; macro; macro = macro->next) {
+ if (macro->name == macro_name) {
+ break;
+ }
+ }
+
+ if (!macro) {
+ macro = sl_pp_macro_new();
+ if (!macro) {
+ strcpy(context->error_msg, "out of memory");
+ return -1;
+ }
+
+ *context->macro_tail = macro;
+ context->macro_tail = &macro->next;
+ } else {
+ sl_pp_macro_reset(macro);
+ }
+
+ macro->name = macro_name;
+
+ /*
+ * If there is no whitespace between macro name and left paren, a macro
+ * formal argument list follows. This is the only place where the presence
+ * of a whitespace matters and it's the only reason why we are dealing
+ * with whitespace at this level.
+ */
+ if (first < last && input[first].token == SL_PP_LPAREN) {
+ first++;
+ if (_parse_formal_args(context, input, &first, last, macro)) {
+ return -1;
+ }
+ }
+
+ /* 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++;
+ }
+ }
+
+ macro->body = malloc(sizeof(struct sl_pp_token_info) * body_len);
+ if (!macro->body) {
+ strcpy(context->error_msg, "out of memory");
+ return -1;
+ }
+
+ for (j = 0, i = first; i < last; i++) {
+ if (input[i].token != SL_PP_WHITESPACE) {
+ macro->body[j++] = input[i];
+ }
+ }
+ macro->body[j++].token = SL_PP_EOF;
+
+ return 0;
+}
+
+
+int
+sl_pp_process_undef(struct sl_pp_context *context,
+ const struct sl_pp_token_info *input,
+ unsigned int first,
+ unsigned int last)
+{
+ int macro_name = -1;
+ struct sl_pp_macro **pmacro;
+ struct sl_pp_macro *macro;
+
+ if (first < last && input[first].token == SL_PP_IDENTIFIER) {
+ macro_name = input[first].data.identifier;
+ }
+ if (macro_name == -1) {
+ return 0;
+ }
+
+ for (pmacro = &context->macro; *pmacro; pmacro = &(**pmacro).next) {
+ if ((**pmacro).name == macro_name) {
+ break;
+ }
+ }
+ if (!*pmacro) {
+ return 0;
+ }
+
+ macro = *pmacro;
+ *pmacro = macro->next;
+ macro->next = NULL;
+ sl_pp_macro_free(macro);
+
+ return 0;
+}