From 9d336c5264d59e455380a305ee99675e2219ae06 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 15 Jun 2009 11:01:20 +0200 Subject: glsl: Add preprocessor skeleton for directive parsing. --- src/glsl/pp/sl_pp_process.c | 157 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 src/glsl/pp/sl_pp_process.c (limited to 'src/glsl/pp/sl_pp_process.c') diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c new file mode 100644 index 0000000000..56b8fab52a --- /dev/null +++ b/src/glsl/pp/sl_pp_process.c @@ -0,0 +1,157 @@ +/************************************************************************** + * + * 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 +#include "sl_pp_process.h" + + +enum process_state { + state_seek_hash, + state_seek_directive, + state_seek_newline, + state_expand +}; + +int +sl_pp_process(const struct sl_pp_token_info *input, + struct sl_pp_token_info **output) +{ + unsigned int i = 0; + enum process_state state = state_seek_hash; + struct sl_pp_token_info *out = NULL; + unsigned int out_len = 0; + unsigned int out_max = 0; + + for (;;) { + struct sl_pp_token_info info; + int info_valid = 0; + + switch (input[i].token) { + case SL_PP_WHITESPACE: + /* Drop whitespace alltogether at this point. */ + i++; + break; + + case SL_PP_NEWLINE: + case SL_PP_EOF: + /* Preserve newline just for the sake of line numbering. */ + info = input[i]; + info_valid = 1; + i++; + /* Restart directive parsing. */ + state = state_seek_hash; + break; + + case SL_PP_HASH: + if (state == state_seek_hash) { + i++; + state = state_seek_directive; + } else { + /* Error: unexpected token. */ + return -1; + } + break; + + case SL_PP_IDENTIFIER: + if (state == state_seek_hash) { + info = input[i]; + info_valid = 1; + i++; + state = state_expand; + } else if (state == state_seek_directive) { + i++; + state = state_seek_newline; + } else if (state == state_expand) { + info = input[i]; + info_valid = 1; + i++; + } else { + i++; + } + break; + + default: + if (state == state_seek_hash) { + info = input[i]; + info_valid = 1; + i++; + state = state_expand; + } else if (state == state_seek_directive) { + /* Error: expected directive name. */ + return -1; + } else if (state == state_expand) { + info = input[i]; + info_valid = 1; + i++; + } else { + i++; + } + } + + if (info_valid) { + if (out_len >= out_max) { + unsigned int new_max = out_max; + + if (new_max < 0x100) { + new_max = 0x100; + } else if (new_max < 0x10000) { + new_max *= 2; + } else { + new_max += 0x10000; + } + + out = realloc(out, new_max * sizeof(struct sl_pp_token_info)); + if (!out) { + return -1; + } + out_max = new_max; + } + + if (info.token == SL_PP_IDENTIFIER) { + info.data.identifier = strdup(info.data.identifier); + if (!info.data.identifier) { + return -1; + } + } else if (info.token == SL_PP_NUMBER) { + info.data.number = strdup(info.data.number); + if (!info.data.number) { + return -1; + } + } + + out[out_len++] = info; + + if (info.token == SL_PP_EOF) { + break; + } + } + } + + *output = out; + return 0; +} -- cgit v1.2.3 From f24322fbf6599b31f07ebc548e390c77b803d67c Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 17 Jun 2009 13:49:06 +0200 Subject: glsl: Introduce sl_pp_context and maintain a reuseable pool of strings. --- src/glsl/apps/process.c | 21 ++++++++----- src/glsl/apps/tokenise.c | 15 ++++++--- src/glsl/apps/version.c | 10 ++++-- src/glsl/pp/SConscript | 1 + src/glsl/pp/sl_pp_context.c | 77 +++++++++++++++++++++++++++++++++++++++++++++ src/glsl/pp/sl_pp_context.h | 52 ++++++++++++++++++++++++++++++ src/glsl/pp/sl_pp_process.c | 16 ++-------- src/glsl/pp/sl_pp_process.h | 3 +- src/glsl/pp/sl_pp_token.c | 29 ++++++++--------- src/glsl/pp/sl_pp_token.h | 7 +++-- src/glsl/pp/sl_pp_version.c | 35 +++++++++++++++------ src/glsl/pp/sl_pp_version.h | 4 ++- 12 files changed, 213 insertions(+), 57 deletions(-) create mode 100644 src/glsl/pp/sl_pp_context.c create mode 100644 src/glsl/pp/sl_pp_context.h (limited to 'src/glsl/pp/sl_pp_process.c') diff --git a/src/glsl/apps/process.c b/src/glsl/apps/process.c index 6e2828aa41..abcf1a92b8 100644 --- a/src/glsl/apps/process.c +++ b/src/glsl/apps/process.c @@ -28,6 +28,7 @@ #include #include #include +#include "../pp/sl_pp_context.h" #include "../pp/sl_pp_purify.h" #include "../pp/sl_pp_version.h" #include "../pp/sl_pp_process.h" @@ -42,6 +43,7 @@ main(int argc, char *inbuf; struct sl_pp_purify_options options; char *outbuf; + struct sl_pp_context context; struct sl_pp_token_info *tokens; unsigned int version; unsigned int tokens_eaten; @@ -86,19 +88,24 @@ main(int argc, free(inbuf); - if (sl_pp_tokenise(outbuf, &tokens)) { + sl_pp_context_init(&context); + + if (sl_pp_tokenise(&context, outbuf, &tokens)) { + sl_pp_context_destroy(&context); free(outbuf); return 1; } free(outbuf); - if (sl_pp_version(tokens, &version, &tokens_eaten)) { + if (sl_pp_version(&context, tokens, &version, &tokens_eaten)) { + sl_pp_context_destroy(&context); free(tokens); return -1; } - if (sl_pp_process(&tokens[tokens_eaten], &outtokens)) { + if (sl_pp_process(&context, &tokens[tokens_eaten], &outtokens)) { + sl_pp_context_destroy(&context); free(tokens); return -1; } @@ -107,6 +114,7 @@ main(int argc, out = fopen(argv[2], "wb"); if (!out) { + sl_pp_context_destroy(&context); free(outtokens); return 1; } @@ -298,13 +306,11 @@ main(int argc, break; case SL_PP_IDENTIFIER: - fprintf(out, "%s ", outtokens[i].data.identifier); - free(outtokens[i].data.identifier); + fprintf(out, "%s ", sl_pp_context_cstr(&context, outtokens[i].data.identifier)); break; case SL_PP_NUMBER: - fprintf(out, "(%s) ", outtokens[i].data.number); - free(outtokens[i].data.number); + fprintf(out, "%s ", sl_pp_context_cstr(&context, outtokens[i].data.number)); break; case SL_PP_OTHER: @@ -316,6 +322,7 @@ main(int argc, } } + sl_pp_context_destroy(&context); free(outtokens); fclose(out); diff --git a/src/glsl/apps/tokenise.c b/src/glsl/apps/tokenise.c index 2631b82998..b5092ba35f 100644 --- a/src/glsl/apps/tokenise.c +++ b/src/glsl/apps/tokenise.c @@ -28,6 +28,7 @@ #include #include #include +#include "../pp/sl_pp_context.h" #include "../pp/sl_pp_purify.h" #include "../pp/sl_pp_token.h" @@ -41,6 +42,7 @@ main(int argc, char *inbuf; struct sl_pp_purify_options options; char *outbuf; + struct sl_pp_context context; struct sl_pp_token_info *tokens; FILE *out; unsigned int i; @@ -82,7 +84,10 @@ main(int argc, free(inbuf); - if (sl_pp_tokenise(outbuf, &tokens)) { + sl_pp_context_init(&context); + + if (sl_pp_tokenise(&context, outbuf, &tokens)) { + sl_pp_context_destroy(&context); free(outbuf); return 1; } @@ -91,6 +96,7 @@ main(int argc, out = fopen(argv[2], "wb"); if (!out) { + sl_pp_context_destroy(&context); free(tokens); return 1; } @@ -289,13 +295,11 @@ main(int argc, break; case SL_PP_IDENTIFIER: - fprintf(out, "%s ", tokens[i].data.identifier); - free(tokens[i].data.identifier); + fprintf(out, "%s ", sl_pp_context_cstr(&context, tokens[i].data.identifier)); break; case SL_PP_NUMBER: - fprintf(out, "(%s) ", tokens[i].data.number); - free(tokens[i].data.number); + fprintf(out, "(%s) ", sl_pp_context_cstr(&context, tokens[i].data.number)); break; case SL_PP_OTHER: @@ -311,6 +315,7 @@ main(int argc, } } + sl_pp_context_destroy(&context); free(tokens); fclose(out); diff --git a/src/glsl/apps/version.c b/src/glsl/apps/version.c index b49395ba97..c56ae9dde9 100644 --- a/src/glsl/apps/version.c +++ b/src/glsl/apps/version.c @@ -41,6 +41,7 @@ main(int argc, char *inbuf; struct sl_pp_purify_options options; char *outbuf; + struct sl_pp_context context; struct sl_pp_token_info *tokens; unsigned int version; unsigned int tokens_eaten; @@ -83,18 +84,23 @@ main(int argc, free(inbuf); - if (sl_pp_tokenise(outbuf, &tokens)) { + sl_pp_context_init(&context); + + if (sl_pp_tokenise(&context, outbuf, &tokens)) { + sl_pp_context_destroy(&context); free(outbuf); return 1; } free(outbuf); - if (sl_pp_version(tokens, &version, &tokens_eaten)) { + if (sl_pp_version(&context, tokens, &version, &tokens_eaten)) { + sl_pp_context_destroy(&context); free(tokens); return -1; } + sl_pp_context_destroy(&context); free(tokens); out = fopen(argv[2], "wb"); diff --git a/src/glsl/pp/SConscript b/src/glsl/pp/SConscript index 0be2114794..3d4a1cb967 100644 --- a/src/glsl/pp/SConscript +++ b/src/glsl/pp/SConscript @@ -8,6 +8,7 @@ env = env.Clone() glsl = env.StaticLibrary( target = 'glsl', source = [ + 'sl_pp_context.c', 'sl_pp_process.c', 'sl_pp_purify.c', 'sl_pp_token.c', diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c new file mode 100644 index 0000000000..71712de1fe --- /dev/null +++ b/src/glsl/pp/sl_pp_context.c @@ -0,0 +1,77 @@ +/************************************************************************** + * + * 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_context.h" + + +void +sl_pp_context_init(struct sl_pp_context *context) +{ + memset(context, 0, sizeof(struct sl_pp_context)); +} + +void +sl_pp_context_destroy(struct sl_pp_context *context) +{ + free(context->cstr_pool); +} + +int +sl_pp_context_add_str(struct sl_pp_context *context, + const char *str) +{ + unsigned int size; + unsigned int offset; + + size = strlen(str) + 1; + + if (context->cstr_pool_len + size > context->cstr_pool_max) { + context->cstr_pool_max = (context->cstr_pool_len + size + 0xffff) & ~0xffff; + context->cstr_pool = realloc(context->cstr_pool, context->cstr_pool_max); + } + + if (!context->cstr_pool) { + return -1; + } + + offset = context->cstr_pool_len; + memcpy(&context->cstr_pool[offset], str, size); + context->cstr_pool_len += size; + + return offset; +} + +const char * +sl_pp_context_cstr(const struct sl_pp_context *context, + int offset) +{ + if (offset == -1) { + return NULL; + } + return &context->cstr_pool[offset]; +} diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h new file mode 100644 index 0000000000..3a1e215625 --- /dev/null +++ b/src/glsl/pp/sl_pp_context.h @@ -0,0 +1,52 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#ifndef SL_PP_CONTEXT_H +#define SL_PP_CONTEXT_H + + +struct sl_pp_context { + char *cstr_pool; + unsigned int cstr_pool_max; + unsigned int cstr_pool_len; +}; + +void +sl_pp_context_init(struct sl_pp_context *context); + +void +sl_pp_context_destroy(struct sl_pp_context *context); + +int +sl_pp_context_add_str(struct sl_pp_context *context, + const char *str); + +const char * +sl_pp_context_cstr(const struct sl_pp_context *context, + int offset); + +#endif /* SL_PP_VERSION_H */ diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index 56b8fab52a..a97c750de4 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -26,7 +26,6 @@ **************************************************************************/ #include -#include #include "sl_pp_process.h" @@ -38,7 +37,8 @@ enum process_state { }; int -sl_pp_process(const struct sl_pp_token_info *input, +sl_pp_process(struct sl_pp_context *context, + const struct sl_pp_token_info *input, struct sl_pp_token_info **output) { unsigned int i = 0; @@ -132,18 +132,6 @@ sl_pp_process(const struct sl_pp_token_info *input, out_max = new_max; } - if (info.token == SL_PP_IDENTIFIER) { - info.data.identifier = strdup(info.data.identifier); - if (!info.data.identifier) { - return -1; - } - } else if (info.token == SL_PP_NUMBER) { - info.data.number = strdup(info.data.number); - if (!info.data.number) { - return -1; - } - } - out[out_len++] = info; if (info.token == SL_PP_EOF) { diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h index 6e930ca567..b71ee4466a 100644 --- a/src/glsl/pp/sl_pp_process.h +++ b/src/glsl/pp/sl_pp_process.h @@ -32,7 +32,8 @@ int -sl_pp_process(const struct sl_pp_token_info *input, +sl_pp_process(struct sl_pp_context *context, + const struct sl_pp_token_info *input, struct sl_pp_token_info **output); #endif /* SL_PP_PROCESS_H */ diff --git a/src/glsl/pp/sl_pp_token.c b/src/glsl/pp/sl_pp_token.c index 4001fe54c8..e200b961aa 100644 --- a/src/glsl/pp/sl_pp_token.c +++ b/src/glsl/pp/sl_pp_token.c @@ -30,7 +30,8 @@ static int -_tokenise_identifier(const char **pinput, +_tokenise_identifier(struct sl_pp_context *context, + const char **pinput, struct sl_pp_token_info *info) { const char *input = *pinput; @@ -38,7 +39,7 @@ _tokenise_identifier(const char **pinput, unsigned int i = 0; info->token = SL_PP_IDENTIFIER; - info->data.identifier = NULL; + info->data.identifier = -1; identifier[i++] = *input++; while ((*input >= 'a' && *input <= 'z') || @@ -52,11 +53,10 @@ _tokenise_identifier(const char **pinput, } identifier[i++] = '\0'; - info->data.identifier = malloc(i); - if (!info->data.identifier) { + info->data.identifier = sl_pp_context_add_str(context, identifier); + if (info->data.identifier == -1) { return -1; } - memcpy(info->data.identifier, identifier, i); *pinput = input; return 0; @@ -64,7 +64,8 @@ _tokenise_identifier(const char **pinput, static int -_tokenise_number(const char **pinput, +_tokenise_number(struct sl_pp_context *context, + const char **pinput, struct sl_pp_token_info *info) { const char *input = *pinput; @@ -72,7 +73,7 @@ _tokenise_number(const char **pinput, unsigned int i = 0; info->token = SL_PP_NUMBER; - info->data.number = NULL; + info->data.number = -1; number[i++] = *input++; while ((*input >= '0' && *input <= '9') || @@ -90,11 +91,10 @@ _tokenise_number(const char **pinput, } number[i++] = '\0'; - info->data.number = malloc(i); - if (!info->data.number) { + info->data.number = sl_pp_context_add_str(context, number); + if (info->data.number == -1) { return -1; } - memcpy(info->data.number, number, i); *pinput = input; return 0; @@ -102,7 +102,8 @@ _tokenise_number(const char **pinput, int -sl_pp_tokenise(const char *input, +sl_pp_tokenise(struct sl_pp_context *context, + const char *input, struct sl_pp_token_info **output) { struct sl_pp_token_info *out = NULL; @@ -171,7 +172,7 @@ sl_pp_tokenise(const char *input, case '.': if (input[1] >= '0' && input[1] <= '9') { - if (_tokenise_number(&input, &info)) { + if (_tokenise_number(context, &input, &info)) { free(out); return -1; } @@ -355,12 +356,12 @@ sl_pp_tokenise(const char *input, if ((*input >= 'a' && *input <= 'z') || (*input >= 'A' && *input <= 'Z') || (*input == '_')) { - if (_tokenise_identifier(&input, &info)) { + if (_tokenise_identifier(context, &input, &info)) { free(out); return -1; } } else if (*input >= '0' && *input <= '9') { - if (_tokenise_number(&input, &info)) { + if (_tokenise_number(context, &input, &info)) { free(out); return -1; } diff --git a/src/glsl/pp/sl_pp_token.h b/src/glsl/pp/sl_pp_token.h index 5e7fae7d29..c801804ae6 100644 --- a/src/glsl/pp/sl_pp_token.h +++ b/src/glsl/pp/sl_pp_token.h @@ -90,8 +90,8 @@ enum sl_pp_token { }; union sl_pp_token_data { - char *identifier; - char *number; + int identifier; + int number; char other; }; @@ -101,7 +101,8 @@ struct sl_pp_token_info { }; int -sl_pp_tokenise(const char *input, +sl_pp_tokenise(struct sl_pp_context *context, + const char *input, struct sl_pp_token_info **output); #endif /* SL_PP_TOKEN_H */ diff --git a/src/glsl/pp/sl_pp_version.c b/src/glsl/pp/sl_pp_version.c index e743a09841..89c3cfa1a5 100644 --- a/src/glsl/pp/sl_pp_version.c +++ b/src/glsl/pp/sl_pp_version.c @@ -54,7 +54,8 @@ _parse_integer(const char *input, int -sl_pp_version(const struct sl_pp_token_info *input, +sl_pp_version(struct sl_pp_context *context, + const struct sl_pp_token_info *input, unsigned int *version, unsigned int *tokens_eaten) { @@ -99,11 +100,18 @@ sl_pp_version(const struct sl_pp_token_info *input, break; case SL_PP_IDENTIFIER: - if (strcmp(input[i].data.identifier, "version")) { - return 0; + { + 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; } - i++; - found_version = 1; break; default: @@ -119,12 +127,19 @@ sl_pp_version(const struct sl_pp_token_info *input, break; case SL_PP_NUMBER: - if (_parse_integer(input[i].data.number, version)) { - /* Expected version number. */ - return -1; + { + const char *num = sl_pp_context_cstr(context, input[i].data.number); + + if (!num) { + return -1; + } + if (_parse_integer(num, version)) { + /* Expected version number. */ + return -1; + } + i++; + found_number = 1; } - i++; - found_number = 1; break; default: diff --git a/src/glsl/pp/sl_pp_version.h b/src/glsl/pp/sl_pp_version.h index 7deee1a134..cee9f55bc6 100644 --- a/src/glsl/pp/sl_pp_version.h +++ b/src/glsl/pp/sl_pp_version.h @@ -28,11 +28,13 @@ #ifndef SL_PP_VERSION_H #define SL_PP_VERSION_H +#include "sl_pp_context.h" #include "sl_pp_token.h" int -sl_pp_version(const struct sl_pp_token_info *input, +sl_pp_version(struct sl_pp_context *context, + const struct sl_pp_token_info *input, unsigned int *version, unsigned int *tokens_eaten); -- cgit v1.2.3 From 3ce5e668180748e2eccd1a8d3931ab98c2919df3 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 17 Jun 2009 20:29:46 +0200 Subject: glsl: Simplify directive parser skeleton. --- src/glsl/pp/sl_pp_context.h | 2 +- src/glsl/pp/sl_pp_process.c | 229 +++++++++++++++++++++++++++----------------- src/glsl/pp/sl_pp_process.h | 1 + 3 files changed, 141 insertions(+), 91 deletions(-) (limited to 'src/glsl/pp/sl_pp_process.c') diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index 3a1e215625..e4686b89e3 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -49,4 +49,4 @@ const char * sl_pp_context_cstr(const struct sl_pp_context *context, int offset); -#endif /* SL_PP_VERSION_H */ +#endif /* SL_PP_CONTEXT_H */ diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index a97c750de4..1005c50105 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -29,117 +29,166 @@ #include "sl_pp_process.h" -enum process_state { - state_seek_hash, - state_seek_directive, - state_seek_newline, - state_expand +static void +skip_whitespace(const struct sl_pp_token_info *input, + unsigned int *pi) +{ + while (input[*pi].token == SL_PP_WHITESPACE) { + (*pi)++; + } +} + + +struct 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) +{ + if (state->out_len >= state->out_max) { + unsigned int new_max = state->out_max; + + if (new_max < 0x100) { + new_max = 0x100; + } else if (new_max < 0x10000) { + new_max *= 2; + } else { + new_max += 0x10000; + } + + state->out = realloc(state->out, new_max * sizeof(struct sl_pp_token_info)); + if (!state->out) { + return -1; + } + state->out_max = new_max; + } + + state->out[state->out_len++] = *token; + return 0; +} + + int sl_pp_process(struct sl_pp_context *context, const struct sl_pp_token_info *input, struct sl_pp_token_info **output) { unsigned int i = 0; - enum process_state state = state_seek_hash; - struct sl_pp_token_info *out = NULL; - unsigned int out_len = 0; - unsigned int out_max = 0; - - for (;;) { - struct sl_pp_token_info info; - int info_valid = 0; - - switch (input[i].token) { - case SL_PP_WHITESPACE: - /* Drop whitespace alltogether at this point. */ - i++; - break; + int found_eof = 0; + struct process_state state; + + memset(&state, 0, sizeof(state)); - case SL_PP_NEWLINE: - case SL_PP_EOF: - /* Preserve newline just for the sake of line numbering. */ - info = input[i]; - info_valid = 1; + while (!found_eof) { + skip_whitespace(input, &i); + if (input[i].token == SL_PP_HASH) { i++; - /* Restart directive parsing. */ - state = state_seek_hash; - break; + skip_whitespace(input, &i); + switch (input[i].token) { + case SL_PP_IDENTIFIER: + { + const char *name; + int found_eol = 0; + + name = sl_pp_context_cstr(context, input[i].data.identifier); + i++; + skip_whitespace(input, &i); + + while (!found_eol) { + switch (input[i].token) { + case SL_PP_WHITESPACE: + /* Drop whitespace all together at this point. */ + i++; + break; + + case SL_PP_NEWLINE: + /* Preserve newline just for the sake of line numbering. */ + if (out_token(&state, &input[i])) { + return -1; + } + i++; + found_eol = 1; + break; + + case SL_PP_EOF: + if (out_token(&state, &input[i])) { + return -1; + } + i++; + found_eof = 1; + found_eol = 1; + break; + + default: + i++; + } + } + } + break; - case SL_PP_HASH: - if (state == state_seek_hash) { + case SL_PP_NEWLINE: + /* Empty directive. */ + if (out_token(&state, &input[i])) { + return -1; + } i++; - state = state_seek_directive; - } else { - /* Error: unexpected token. */ - return -1; - } - break; + break; - case SL_PP_IDENTIFIER: - if (state == state_seek_hash) { - info = input[i]; - info_valid = 1; - i++; - state = state_expand; - } else if (state == state_seek_directive) { - i++; - state = state_seek_newline; - } else if (state == state_expand) { - info = input[i]; - info_valid = 1; - i++; - } else { + case SL_PP_EOF: + /* Empty directive. */ + if (out_token(&state, &input[i])) { + return -1; + } i++; - } - break; + found_eof = 1; + break; - default: - if (state == state_seek_hash) { - info = input[i]; - info_valid = 1; - i++; - state = state_expand; - } else if (state == state_seek_directive) { - /* Error: expected directive name. */ + default: return -1; - } else if (state == state_expand) { - info = input[i]; - info_valid = 1; - i++; - } else { - i++; } - } - - if (info_valid) { - if (out_len >= out_max) { - unsigned int new_max = out_max; - - if (new_max < 0x100) { - new_max = 0x100; - } else if (new_max < 0x10000) { - new_max *= 2; - } else { - new_max += 0x10000; + } else { + int found_eol = 0; + + while (!found_eol) { + switch (input[i].token) { + case SL_PP_WHITESPACE: + /* Drop whitespace all together at this point. */ + i++; + break; + + case SL_PP_NEWLINE: + /* Preserve newline just for the sake of line numbering. */ + if (out_token(&state, &input[i])) { + return -1; + } + i++; + found_eol = 1; + break; + + case SL_PP_EOF: + if (out_token(&state, &input[i])) { + return -1; + } + i++; + found_eof = 1; + found_eol = 1; + break; + + default: + if (out_token(&state, &input[i])) { + return -1; + } + i++; } - - out = realloc(out, new_max * sizeof(struct sl_pp_token_info)); - if (!out) { - return -1; - } - out_max = new_max; - } - - out[out_len++] = info; - - if (info.token == SL_PP_EOF) { - break; } } } - *output = out; + *output = state.out; return 0; } diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h index b71ee4466a..d6401de960 100644 --- a/src/glsl/pp/sl_pp_process.h +++ b/src/glsl/pp/sl_pp_process.h @@ -28,6 +28,7 @@ #ifndef SL_PP_PROCESS_H #define SL_PP_PROCESS_H +#include "sl_pp_context.h" #include "sl_pp_token.h" -- cgit v1.2.3 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/SConscript | 2 + src/glsl/pp/sl_pp_context.c | 1 + src/glsl/pp/sl_pp_context.h | 4 ++ src/glsl/pp/sl_pp_define.c | 156 ++++++++++++++++++++++++++++++++++++++++++++ src/glsl/pp/sl_pp_macro.c | 51 +++++++++++++++ src/glsl/pp/sl_pp_macro.h | 50 ++++++++++++++ src/glsl/pp/sl_pp_process.c | 29 ++++++-- src/glsl/pp/sl_pp_process.h | 8 +++ 8 files changed, 296 insertions(+), 5 deletions(-) create mode 100644 src/glsl/pp/sl_pp_define.c create mode 100644 src/glsl/pp/sl_pp_macro.c create mode 100644 src/glsl/pp/sl_pp_macro.h (limited to 'src/glsl/pp/sl_pp_process.c') diff --git a/src/glsl/pp/SConscript b/src/glsl/pp/SConscript index 3d4a1cb967..1fde3dfccf 100644 --- a/src/glsl/pp/SConscript +++ b/src/glsl/pp/SConscript @@ -9,6 +9,8 @@ glsl = env.StaticLibrary( target = 'glsl', source = [ 'sl_pp_context.c', + 'sl_pp_define.c', + 'sl_pp_macro.c', 'sl_pp_process.c', 'sl_pp_purify.c', 'sl_pp_token.c', diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index 71712de1fe..8722376ae5 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -39,6 +39,7 @@ void sl_pp_context_destroy(struct sl_pp_context *context) { free(context->cstr_pool); + sl_pp_macro_free(context->macro); } int diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index e4686b89e3..cb81f73ab9 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -28,11 +28,15 @@ #ifndef SL_PP_CONTEXT_H #define SL_PP_CONTEXT_H +#include "sl_pp_macro.h" + struct sl_pp_context { char *cstr_pool; unsigned int cstr_pool_max; unsigned int cstr_pool_len; + + struct sl_pp_macro *macro; }; void diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c new file mode 100644 index 0000000000..5ce0f0551b --- /dev/null +++ b/src/glsl/pp/sl_pp_define.c @@ -0,0 +1,156 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include +#include "sl_pp_process.h" + + +static void +skip_whitespace(const struct sl_pp_token_info *input, + unsigned int *first, + unsigned int last) +{ + while (*first < last && input[*first].token == SL_PP_WHITESPACE) { + (*first)++; + } +} + + +static int +_parse_formal_args(const struct sl_pp_token_info *input, + unsigned int *first, + unsigned int last, + struct sl_pp_macro *macro) +{ + struct sl_pp_macro_formal_arg **arg; + + skip_whitespace(input, first, last); + if (*first < last) { + if (input[*first].token == SL_PP_RPAREN) { + (*first)++; + return 0; + } + } else { + /* Expected either an identifier or `)'. */ + return -1; + } + + arg = ¯o->arg; + + for (;;) { + if (*first < last && input[*first].token != SL_PP_IDENTIFIER) { + /* Expected an identifier. */ + return -1; + } + + *arg = malloc(sizeof(struct sl_pp_macro_formal_arg)); + if (!*arg) { + return -1; + } + + (**arg).name = input[*first].data.identifier; + (*first)++; + + (**arg).next = NULL; + arg = &(**arg).next; + + skip_whitespace(input, first, last); + if (*first < last) { + if (input[*first].token == SL_PP_COMMA) { + (*first)++; + } else if (input[*first].token == SL_PP_RPAREN) { + (*first)++; + return 0; + } else { + /* Expected either `,' or `)'. */ + return -1; + } + } else { + /* Expected either `,' or `)'. */ + return -1; + } + } +} + + +int +sl_pp_process_define(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last, + struct sl_pp_macro *macro) +{ + macro->name = -1; + macro->arg = NULL; + macro->body = NULL; + macro->next = NULL; + + if (first < last && input[first].token == SL_PP_IDENTIFIER) { + macro->name = input[first].data.identifier; + first++; + } + + if (macro->name == -1) { + return -1; + } + + /* + * If there is no whitespace between macro name and left paren, a macro + * formal argument list follows. This is the only place where the presence + * of a whitespace matters and it's the only reason why we are dealing + * with whitespace at this level. + */ + if (first < last && input[first].token == SL_PP_LPAREN) { + first++; + if (_parse_formal_args(input, &first, last, macro)) { + return -1; + } + } + + /* Trim whitespace from the left side. */ + skip_whitespace(input, &first, last); + + /* Trom whitespace from the right side. */ + while (first < last && input[last - 1].token == SL_PP_WHITESPACE) { + last--; + } + + /* All that is left between first and last is the macro definition. */ + macro->body_len = last - first; + if (macro->body_len) { + macro->body = malloc(sizeof(struct sl_pp_token_info) * macro->body_len); + if (!macro->body) { + return -1; + } + + memcpy(macro->body, + &input[first], + sizeof(struct sl_pp_token_info) * macro->body_len); + } + + return 0; +} diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c new file mode 100644 index 0000000000..eed0978304 --- /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; + } +} diff --git a/src/glsl/pp/sl_pp_macro.h b/src/glsl/pp/sl_pp_macro.h new file mode 100644 index 0000000000..4ebbff5590 --- /dev/null +++ b/src/glsl/pp/sl_pp_macro.h @@ -0,0 +1,50 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#ifndef SL_PP_MACRO_H +#define SL_PP_MACRO_H + +#include "sl_pp_token.h" + + +struct sl_pp_macro_formal_arg { + int name; + struct sl_pp_macro_formal_arg *next; +}; + +struct sl_pp_macro { + int name; + 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); + +#endif /* SL_PP_MACRO_H */ diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index 1005c50105..2a375df71a 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -80,8 +80,10 @@ 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; + macro = &context->macro; memset(&state, 0, sizeof(state)); while (!found_eof) { @@ -94,18 +96,18 @@ sl_pp_process(struct sl_pp_context *context, { const char *name; int found_eol = 0; + unsigned int first; + unsigned int last; + /* Directive name. */ name = sl_pp_context_cstr(context, input[i].data.identifier); i++; skip_whitespace(input, &i); + first = i; + while (!found_eol) { switch (input[i].token) { - case SL_PP_WHITESPACE: - /* Drop whitespace all together at this point. */ - i++; - break; - case SL_PP_NEWLINE: /* Preserve newline just for the sake of line numbering. */ if (out_token(&state, &input[i])) { @@ -128,6 +130,23 @@ sl_pp_process(struct sl_pp_context *context, i++; } } + + last = i - 1; + + if (!strcmp(name, "define")) { + *macro = malloc(sizeof(struct sl_pp_macro)); + if (!*macro) { + return -1; + } + + if (sl_pp_process_define(context, input, first, last, *macro)) { + return -1; + } + + macro = &(**macro).next; + } else { + /* XXX: Ignore. */ + } } break; diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h index d6401de960..f7df9a2850 100644 --- a/src/glsl/pp/sl_pp_process.h +++ b/src/glsl/pp/sl_pp_process.h @@ -29,6 +29,7 @@ #define SL_PP_PROCESS_H #include "sl_pp_context.h" +#include "sl_pp_macro.h" #include "sl_pp_token.h" @@ -37,4 +38,11 @@ sl_pp_process(struct sl_pp_context *context, const struct sl_pp_token_info *input, struct sl_pp_token_info **output); +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); + #endif /* SL_PP_PROCESS_H */ -- 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_process.c') diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c index 5ce0f0551b..39d1435064 100644 --- a/src/glsl/pp/sl_pp_define.c +++ b/src/glsl/pp/sl_pp_define.c @@ -48,6 +48,8 @@ _parse_formal_args(const struct sl_pp_token_info *input, { struct sl_pp_macro_formal_arg **arg; + macro->num_args = 0; + skip_whitespace(input, first, last); if (*first < last) { if (input[*first].token == SL_PP_RPAREN) { @@ -78,6 +80,8 @@ _parse_formal_args(const struct sl_pp_token_info *input, (**arg).next = NULL; arg = &(**arg).next; + macro->num_args++; + skip_whitespace(input, first, last); if (*first < last) { if (input[*first].token == SL_PP_COMMA) { @@ -104,7 +108,12 @@ sl_pp_process_define(struct sl_pp_context *context, unsigned int last, struct sl_pp_macro *macro) { + unsigned int i; + unsigned int body_len; + unsigned int j; + macro->name = -1; + macro->num_args = -1; macro->arg = NULL; macro->body = NULL; macro->next = NULL; @@ -131,26 +140,25 @@ sl_pp_process_define(struct sl_pp_context *context, } } - /* Trim whitespace from the left side. */ - skip_whitespace(input, &first, last); + /* Calculate body size, trim out whitespace, make room for EOF. */ + body_len = 1; + for (i = first; i < last; i++) { + if (input[i].token != SL_PP_WHITESPACE) { + body_len++; + } + } - /* Trom whitespace from the right side. */ - while (first < last && input[last - 1].token == SL_PP_WHITESPACE) { - last--; + macro->body = malloc(sizeof(struct sl_pp_token_info) * body_len); + if (!macro->body) { + return -1; } - /* All that is left between first and last is the macro definition. */ - macro->body_len = last - first; - if (macro->body_len) { - macro->body = malloc(sizeof(struct sl_pp_token_info) * macro->body_len); - if (!macro->body) { - return -1; + for (j = 0, i = first; i < last; i++) { + if (input[i].token != SL_PP_WHITESPACE) { + macro->body[j++] = input[i]; } - - memcpy(macro->body, - &input[first], - sizeof(struct sl_pp_token_info) * macro->body_len); } + macro->body[j++].token = SL_PP_EOF; return 0; } diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index eed0978304..82591b9d77 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -27,8 +27,18 @@ #include #include "sl_pp_macro.h" +#include "sl_pp_process.h" +static void +skip_whitespace(const struct sl_pp_token_info *input, + unsigned int *pi) +{ + while (input[*pi].token == SL_PP_WHITESPACE) { + (*pi)++; + } +} + void sl_pp_macro_free(struct sl_pp_macro *macro) { @@ -49,3 +59,197 @@ sl_pp_macro_free(struct sl_pp_macro *macro) macro = next_macro; } } + +int +sl_pp_macro_expand(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int *pi, + struct sl_pp_macro *local, + struct sl_pp_process_state *state) +{ + int macro_name; + struct sl_pp_macro *macro = NULL; + struct sl_pp_macro *actual_arg = NULL; + unsigned int j; + + if (input[*pi].token != SL_PP_IDENTIFIER) { + return -1; + } + + macro_name = input[*pi].data.identifier; + + if (local) { + for (macro = local; macro; macro = macro->next) { + if (macro->name == macro_name) { + break; + } + } + } + + if (!macro) { + for (macro = context->macro; macro; macro = macro->next) { + if (macro->name == macro_name) { + break; + } + } + } + + if (!macro) { + if (sl_pp_process_out(state, &input[*pi])) { + return -1; + } + (*pi)++; + return 0; + } + + (*pi)++; + + if (macro->num_args >= 0) { + skip_whitespace(input, pi); + if (input[*pi].token != SL_PP_LPAREN) { + return -1; + } + (*pi)++; + skip_whitespace(input, pi); + } + + if (macro->num_args > 0) { + struct sl_pp_macro_formal_arg *formal_arg = macro->arg; + struct sl_pp_macro **pmacro = &actual_arg; + + for (j = 0; j < (unsigned int)macro->num_args; j++) { + unsigned int body_len; + unsigned int i; + int done = 0; + unsigned int paren_nesting = 0; + unsigned int k; + + *pmacro = malloc(sizeof(struct sl_pp_macro)); + if (!*pmacro) { + return -1; + } + + (**pmacro).name = formal_arg->name; + (**pmacro).num_args = -1; + (**pmacro).arg = NULL; + (**pmacro).body = NULL; + (**pmacro).next = NULL; + + body_len = 1; + for (i = *pi; !done; i++) { + switch (input[i].token) { + case SL_PP_WHITESPACE: + break; + + case SL_PP_COMMA: + if (!paren_nesting) { + if (j < (unsigned int)macro->num_args - 1) { + done = 1; + } else { + return -1; + } + } else { + body_len++; + } + break; + + case SL_PP_LPAREN: + paren_nesting++; + body_len++; + break; + + case SL_PP_RPAREN: + if (!paren_nesting) { + if (j == (unsigned int)macro->num_args - 1) { + done = 1; + } else { + return -1; + } + } else { + paren_nesting--; + body_len++; + } + break; + + case SL_PP_EOF: + return -1; + + default: + body_len++; + } + } + + (**pmacro).body = malloc(sizeof(struct sl_pp_token_info) * body_len); + if (!(**pmacro).body) { + return -1; + } + + for (done = 0, k = 0, i = *pi; !done; i++) { + switch (input[i].token) { + case SL_PP_WHITESPACE: + break; + + case SL_PP_COMMA: + if (!paren_nesting && j < (unsigned int)macro->num_args - 1) { + done = 1; + } else { + (**pmacro).body[k++] = input[i]; + } + break; + + case SL_PP_LPAREN: + paren_nesting++; + (**pmacro).body[k++] = input[i]; + break; + + case SL_PP_RPAREN: + if (!paren_nesting && j == (unsigned int)macro->num_args - 1) { + done = 1; + } else { + paren_nesting--; + (**pmacro).body[k++] = input[i]; + } + break; + + default: + (**pmacro).body[k++] = input[i]; + } + } + + (**pmacro).body[k++].token = SL_PP_EOF; + (*pi) = i; + + formal_arg = formal_arg->next; + pmacro = &(**pmacro).next; + } + } + + /* Right paren for non-empty argument list has already been eaten. */ + if (macro->num_args == 0) { + skip_whitespace(input, pi); + if (input[*pi].token != SL_PP_RPAREN) { + return -1; + } + (*pi)++; + } + + for (j = 0;;) { + switch (macro->body[j].token) { + case SL_PP_IDENTIFIER: + if (sl_pp_macro_expand(context, macro->body, &j, actual_arg, state)) { + return -1; + } + break; + + case SL_PP_EOF: + sl_pp_macro_free(actual_arg); + return 0; + + default: + if (sl_pp_process_out(state, ¯o->body[j])) { + return -1; + } + j++; + } + } +} diff --git a/src/glsl/pp/sl_pp_macro.h b/src/glsl/pp/sl_pp_macro.h index 4ebbff5590..eeb338eec4 100644 --- a/src/glsl/pp/sl_pp_macro.h +++ b/src/glsl/pp/sl_pp_macro.h @@ -38,13 +38,20 @@ struct sl_pp_macro_formal_arg { struct sl_pp_macro { int name; + int num_args; struct sl_pp_macro_formal_arg *arg; struct sl_pp_token_info *body; - unsigned int body_len; struct sl_pp_macro *next; }; void sl_pp_macro_free(struct sl_pp_macro *macro); +int +sl_pp_macro_expand(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int *pi, + struct sl_pp_macro *local, + struct sl_pp_process_state *state); + #endif /* SL_PP_MACRO_H */ diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index 2a375df71a..e930966604 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -39,16 +39,16 @@ skip_whitespace(const struct sl_pp_token_info *input, } -struct process_state { +struct sl_pp_process_state { struct sl_pp_token_info *out; unsigned int out_len; unsigned int out_max; }; -static int -out_token(struct process_state *state, - const struct sl_pp_token_info *token) +int +sl_pp_process_out(struct sl_pp_process_state *state, + const struct sl_pp_token_info *token) { if (state->out_len >= state->out_max) { unsigned int new_max = state->out_max; @@ -72,7 +72,6 @@ out_token(struct process_state *state, return 0; } - int sl_pp_process(struct sl_pp_context *context, const struct sl_pp_token_info *input, @@ -81,7 +80,7 @@ sl_pp_process(struct sl_pp_context *context, unsigned int i = 0; int found_eof = 0; struct sl_pp_macro **macro; - struct process_state state; + struct sl_pp_process_state state; macro = &context->macro; memset(&state, 0, sizeof(state)); @@ -110,7 +109,7 @@ sl_pp_process(struct sl_pp_context *context, switch (input[i].token) { case SL_PP_NEWLINE: /* Preserve newline just for the sake of line numbering. */ - if (out_token(&state, &input[i])) { + if (sl_pp_process_out(&state, &input[i])) { return -1; } i++; @@ -118,7 +117,7 @@ sl_pp_process(struct sl_pp_context *context, break; case SL_PP_EOF: - if (out_token(&state, &input[i])) { + if (sl_pp_process_out(&state, &input[i])) { return -1; } i++; @@ -152,7 +151,7 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_NEWLINE: /* Empty directive. */ - if (out_token(&state, &input[i])) { + if (sl_pp_process_out(&state, &input[i])) { return -1; } i++; @@ -160,7 +159,7 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_EOF: /* Empty directive. */ - if (out_token(&state, &input[i])) { + if (sl_pp_process_out(&state, &input[i])) { return -1; } i++; @@ -182,7 +181,7 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_NEWLINE: /* Preserve newline just for the sake of line numbering. */ - if (out_token(&state, &input[i])) { + if (sl_pp_process_out(&state, &input[i])) { return -1; } i++; @@ -190,7 +189,7 @@ sl_pp_process(struct sl_pp_context *context, break; case SL_PP_EOF: - if (out_token(&state, &input[i])) { + if (sl_pp_process_out(&state, &input[i])) { return -1; } i++; @@ -198,8 +197,14 @@ sl_pp_process(struct sl_pp_context *context, found_eol = 1; break; + case SL_PP_IDENTIFIER: + if (sl_pp_macro_expand(context, input, &i, NULL, &state)) { + return -1; + } + break; + default: - if (out_token(&state, &input[i])) { + if (sl_pp_process_out(&state, &input[i])) { return -1; } i++; diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h index f7df9a2850..37cdc4c9a7 100644 --- a/src/glsl/pp/sl_pp_process.h +++ b/src/glsl/pp/sl_pp_process.h @@ -33,6 +33,8 @@ #include "sl_pp_token.h" +struct sl_pp_process_state; + int sl_pp_process(struct sl_pp_context *context, const struct sl_pp_token_info *input, @@ -45,4 +47,8 @@ sl_pp_process_define(struct sl_pp_context *context, unsigned int last, struct sl_pp_macro *macro); +int +sl_pp_process_out(struct sl_pp_process_state *state, + const struct sl_pp_token_info *token); + #endif /* SL_PP_PROCESS_H */ -- cgit v1.2.3 From 2dad8ed9d68289ba25a4023da12fc5ddf6a621dd Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 22 Jun 2009 09:14:14 +0200 Subject: glsl: Centralise sl_pp_macro constructor. --- src/glsl/pp/sl_pp_define.c | 6 ------ src/glsl/pp/sl_pp_macro.c | 29 +++++++++++++++++++---------- src/glsl/pp/sl_pp_macro.h | 5 ++++- src/glsl/pp/sl_pp_process.c | 2 +- 4 files changed, 24 insertions(+), 18 deletions(-) (limited to 'src/glsl/pp/sl_pp_process.c') diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c index 39d1435064..e8a23fedcd 100644 --- a/src/glsl/pp/sl_pp_define.c +++ b/src/glsl/pp/sl_pp_define.c @@ -112,12 +112,6 @@ sl_pp_process_define(struct sl_pp_context *context, unsigned int body_len; unsigned int j; - macro->name = -1; - macro->num_args = -1; - macro->arg = NULL; - macro->body = NULL; - macro->next = NULL; - if (first < last && input[first].token == SL_PP_IDENTIFIER) { macro->name = input[first].data.identifier; first++; diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index 82591b9d77..0138270c67 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -30,13 +30,17 @@ #include "sl_pp_process.h" -static void -skip_whitespace(const struct sl_pp_token_info *input, - unsigned int *pi) +struct sl_pp_macro * +sl_pp_macro_new(void) { - while (input[*pi].token == SL_PP_WHITESPACE) { - (*pi)++; + struct sl_pp_macro *macro; + + macro = calloc(1, sizeof(struct sl_pp_macro)); + if (macro) { + macro->name = -1; + macro->num_args = -1; } + return macro; } void @@ -60,6 +64,15 @@ sl_pp_macro_free(struct sl_pp_macro *macro) } } +static void +skip_whitespace(const struct sl_pp_token_info *input, + unsigned int *pi) +{ + while (input[*pi].token == SL_PP_WHITESPACE) { + (*pi)++; + } +} + int sl_pp_macro_expand(struct sl_pp_context *context, const struct sl_pp_token_info *input, @@ -124,16 +137,12 @@ sl_pp_macro_expand(struct sl_pp_context *context, unsigned int paren_nesting = 0; unsigned int k; - *pmacro = malloc(sizeof(struct sl_pp_macro)); + *pmacro = sl_pp_macro_new(); if (!*pmacro) { return -1; } (**pmacro).name = formal_arg->name; - (**pmacro).num_args = -1; - (**pmacro).arg = NULL; - (**pmacro).body = NULL; - (**pmacro).next = NULL; body_len = 1; for (i = *pi; !done; i++) { diff --git a/src/glsl/pp/sl_pp_macro.h b/src/glsl/pp/sl_pp_macro.h index eeb338eec4..63edd21aa2 100644 --- a/src/glsl/pp/sl_pp_macro.h +++ b/src/glsl/pp/sl_pp_macro.h @@ -38,12 +38,15 @@ struct sl_pp_macro_formal_arg { struct sl_pp_macro { int name; - int num_args; + int num_args; /* -1 means no args, 0 means `()' */ struct sl_pp_macro_formal_arg *arg; struct sl_pp_token_info *body; struct sl_pp_macro *next; }; +struct sl_pp_macro * +sl_pp_macro_new(void); + void sl_pp_macro_free(struct sl_pp_macro *macro); diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index e930966604..baffaf2cd9 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -133,7 +133,7 @@ sl_pp_process(struct sl_pp_context *context, last = i - 1; if (!strcmp(name, "define")) { - *macro = malloc(sizeof(struct sl_pp_macro)); + *macro = sl_pp_macro_new(); if (!*macro) { return -1; } -- cgit v1.2.3 From 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_process.c') diff --git a/src/glsl/pp/SConscript b/src/glsl/pp/SConscript index 623d2362ce..c7718d1d8f 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 6d3076b869..1afe9a5d5e 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 56f7077750..e8200d55d7 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 0000000000..e331acc4cd --- /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 0138270c67..a8412f0651 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 63edd21aa2..476991d581 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 baffaf2cd9..441de9439c 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 37cdc4c9a7..cc934bd89c 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_process.c') diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index 1afe9a5d5e..50ec790cc5 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -33,6 +33,7 @@ void sl_pp_context_init(struct sl_pp_context *context) { memset(context, 0, sizeof(struct sl_pp_context)); + context->macro_tail = &context->macro; context->if_ptr = SL_PP_MAX_IF_NESTING; context->if_value = 1; } diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index e8200d55d7..1dbd10e30e 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -39,6 +39,7 @@ struct sl_pp_context { unsigned int cstr_pool_len; struct sl_pp_macro *macro; + struct sl_pp_macro **macro_tail; unsigned int if_stack[SL_PP_MAX_IF_NESTING]; unsigned int if_ptr; diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c index e8a23fedcd..0509646430 100644 --- a/src/glsl/pp/sl_pp_define.c +++ b/src/glsl/pp/sl_pp_define.c @@ -105,22 +105,42 @@ int sl_pp_process_define(struct sl_pp_context *context, const struct sl_pp_token_info *input, unsigned int first, - unsigned int last, - struct sl_pp_macro *macro) + unsigned int last) { + int macro_name = -1; + struct sl_pp_macro *macro; unsigned int i; unsigned int body_len; unsigned int j; if (first < last && input[first].token == SL_PP_IDENTIFIER) { - macro->name = input[first].data.identifier; + macro_name = input[first].data.identifier; first++; } - - if (macro->name == -1) { + if (macro_name == -1) { return -1; } + for (macro = context->macro; macro; macro = macro->next) { + if (macro->name == macro_name) { + break; + } + } + + if (!macro) { + macro = sl_pp_macro_new(); + if (!macro) { + return -1; + } + + *context->macro_tail = macro; + context->macro_tail = ¯o->next; + } else { + sl_pp_macro_reset(macro); + } + + macro->name = macro_name; + /* * If there is no whitespace between macro name and left paren, a macro * formal argument list follows. This is the only place where the presence diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index a8412f0651..a82c30cb16 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -30,6 +30,15 @@ #include "sl_pp_process.h" +static void +_macro_init(struct sl_pp_macro *macro) +{ + macro->name = -1; + macro->num_args = -1; + macro->arg = NULL; + macro->body = NULL; +} + struct sl_pp_macro * sl_pp_macro_new(void) { @@ -37,33 +46,45 @@ sl_pp_macro_new(void) macro = calloc(1, sizeof(struct sl_pp_macro)); if (macro) { - macro->name = -1; - macro->num_args = -1; + _macro_init(macro); } return macro; } +static void +_macro_destroy(struct sl_pp_macro *macro) +{ + struct sl_pp_macro_formal_arg *arg = macro->arg; + + while (arg) { + struct sl_pp_macro_formal_arg *next_arg = arg->next; + + free(arg); + arg = next_arg; + } + + free(macro->body); +} + void sl_pp_macro_free(struct sl_pp_macro *macro) { while (macro) { struct sl_pp_macro *next_macro = macro->next; - struct sl_pp_macro_formal_arg *arg = macro->arg; - - while (arg) { - struct sl_pp_macro_formal_arg *next_arg = arg->next; - - free(arg); - arg = next_arg; - } - - free(macro->body); + _macro_destroy(macro); free(macro); macro = next_macro; } } +void +sl_pp_macro_reset(struct sl_pp_macro *macro) +{ + _macro_destroy(macro); + _macro_init(macro); +} + static void skip_whitespace(const struct sl_pp_token_info *input, unsigned int *pi) diff --git a/src/glsl/pp/sl_pp_macro.h b/src/glsl/pp/sl_pp_macro.h index 476991d581..7af11c5ece 100644 --- a/src/glsl/pp/sl_pp_macro.h +++ b/src/glsl/pp/sl_pp_macro.h @@ -50,6 +50,9 @@ sl_pp_macro_new(void); void sl_pp_macro_free(struct sl_pp_macro *macro); +void +sl_pp_macro_reset(struct sl_pp_macro *macro); + int sl_pp_macro_expand(struct sl_pp_context *context, const struct sl_pp_token_info *input, diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index 441de9439c..4715eed2fc 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -71,10 +71,8 @@ sl_pp_process(struct sl_pp_context *context, { unsigned int i = 0; int found_eof = 0; - struct sl_pp_macro **macro; struct sl_pp_process_state state; - macro = &context->macro; memset(&state, 0, sizeof(state)); while (!found_eof) { @@ -126,16 +124,9 @@ sl_pp_process(struct sl_pp_context *context, if (!strcmp(name, "define")) { if (context->if_value) { - *macro = sl_pp_macro_new(); - if (!*macro) { + if (sl_pp_process_define(context, input, first, last)) { return -1; } - - if (sl_pp_process_define(context, input, first, last, *macro)) { - return -1; - } - - macro = &(**macro).next; } } else if (!strcmp(name, "if")) { if (sl_pp_process_if(context, input, first, last)) { diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h index cc934bd89c..66d61496a2 100644 --- a/src/glsl/pp/sl_pp_process.h +++ b/src/glsl/pp/sl_pp_process.h @@ -48,8 +48,7 @@ int sl_pp_process_define(struct sl_pp_context *context, const struct sl_pp_token_info *input, unsigned int first, - unsigned int last, - struct sl_pp_macro *macro); + unsigned int last); int sl_pp_process_if(struct sl_pp_context *context, -- cgit v1.2.3 From 3dc2b5f71c2a519409becb6c1f177b5981fbacf7 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 26 Jun 2009 12:48:14 +0200 Subject: glsl: Implement `undef' preprocessor directive. --- src/glsl/pp/sl_pp_define.c | 35 +++++++++++++++++++++++++++++++++++ src/glsl/pp/sl_pp_process.c | 22 +++++++++++++--------- src/glsl/pp/sl_pp_process.h | 6 ++++++ 3 files changed, 54 insertions(+), 9 deletions(-) (limited to 'src/glsl/pp/sl_pp_process.c') diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c index 0509646430..9bc9fb5359 100644 --- a/src/glsl/pp/sl_pp_define.c +++ b/src/glsl/pp/sl_pp_define.c @@ -176,3 +176,38 @@ sl_pp_process_define(struct sl_pp_context *context, return 0; } + + +int +sl_pp_process_undef(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last) +{ + int macro_name = -1; + struct sl_pp_macro **pmacro; + struct sl_pp_macro *macro; + + if (first < last && input[first].token == SL_PP_IDENTIFIER) { + macro_name = input[first].data.identifier; + } + if (macro_name == -1) { + return 0; + } + + for (pmacro = &context->macro; *pmacro; pmacro = &(**pmacro).next) { + if ((**pmacro).name == macro_name) { + break; + } + } + if (!*pmacro) { + return 0; + } + + macro = *pmacro; + *pmacro = macro->next; + macro->next = NULL; + sl_pp_macro_free(macro); + + return 0; +} diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index 4715eed2fc..c17a3ac7ce 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -122,13 +122,7 @@ sl_pp_process(struct sl_pp_context *context, last = i - 1; - if (!strcmp(name, "define")) { - if (context->if_value) { - if (sl_pp_process_define(context, input, first, last)) { - return -1; - } - } - } else if (!strcmp(name, "if")) { + if (!strcmp(name, "if")) { if (sl_pp_process_if(context, input, first, last)) { return -1; } @@ -152,8 +146,18 @@ sl_pp_process(struct sl_pp_context *context, if (sl_pp_process_endif(context, input, first, last)) { return -1; } - } else { - /* XXX: Ignore. */ + } else if (context->if_value) { + if (!strcmp(name, "define")) { + if (sl_pp_process_define(context, input, first, last)) { + return -1; + } + } else if (!strcmp(name, "undef")) { + if (sl_pp_process_undef(context, input, first, last)) { + return -1; + } + } else { + /* XXX: Ignore. */ + } } } break; diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h index 66d61496a2..61e67fef0b 100644 --- a/src/glsl/pp/sl_pp_process.h +++ b/src/glsl/pp/sl_pp_process.h @@ -50,6 +50,12 @@ sl_pp_process_define(struct sl_pp_context *context, unsigned int first, unsigned int last); +int +sl_pp_process_undef(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last); + int sl_pp_process_if(struct sl_pp_context *context, const struct sl_pp_token_info *input, -- cgit v1.2.3 From f9bd6f7152047e6230c85d76e412a5bb524e0413 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 4 Sep 2009 08:14:48 +0200 Subject: glsl: Implement `error' preprocessor directive. --- src/glsl/pp/SConscript | 1 + src/glsl/pp/sl_pp_context.c | 1 + src/glsl/pp/sl_pp_context.h | 4 + src/glsl/pp/sl_pp_error.c | 263 ++++++++++++++++++++++++++++++++++++++++++++ src/glsl/pp/sl_pp_process.c | 3 + src/glsl/pp/sl_pp_process.h | 6 + 6 files changed, 278 insertions(+) create mode 100644 src/glsl/pp/sl_pp_error.c (limited to 'src/glsl/pp/sl_pp_process.c') diff --git a/src/glsl/pp/SConscript b/src/glsl/pp/SConscript index c7718d1d8f..13fc230b96 100644 --- a/src/glsl/pp/SConscript +++ b/src/glsl/pp/SConscript @@ -10,6 +10,7 @@ glsl = env.StaticLibrary( source = [ 'sl_pp_context.c', 'sl_pp_define.c', + 'sl_pp_error.c', 'sl_pp_expression.c', 'sl_pp_if.c', 'sl_pp_macro.c', diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index 50ec790cc5..38d633baef 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -36,6 +36,7 @@ sl_pp_context_init(struct sl_pp_context *context) context->macro_tail = &context->macro; context->if_ptr = SL_PP_MAX_IF_NESTING; context->if_value = 1; + memset(context->error_msg, 0, sizeof(context->error_msg)); } void diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index 1dbd10e30e..65ce3e37b7 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -33,6 +33,8 @@ #define SL_PP_MAX_IF_NESTING 64 +#define SL_PP_MAX_ERROR_MSG 1024 + struct sl_pp_context { char *cstr_pool; unsigned int cstr_pool_max; @@ -44,6 +46,8 @@ struct sl_pp_context { unsigned int if_stack[SL_PP_MAX_IF_NESTING]; unsigned int if_ptr; int if_value; + + char error_msg[SL_PP_MAX_ERROR_MSG]; }; void diff --git a/src/glsl/pp/sl_pp_error.c b/src/glsl/pp/sl_pp_error.c new file mode 100644 index 0000000000..d42568d23d --- /dev/null +++ b/src/glsl/pp/sl_pp_error.c @@ -0,0 +1,263 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include +#include "sl_pp_process.h" + + +void +sl_pp_process_error(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last) +{ + unsigned int out_len = 0; + unsigned int i; + + for (i = first; i < last; i++) { + const char *s = NULL; + char buf[2]; + + switch (input[i].token) { + case SL_PP_WHITESPACE: + s = " "; + break; + + case SL_PP_NEWLINE: + s = "\n"; + break; + + case SL_PP_HASH: + s = "#"; + break; + + case SL_PP_COMMA: + s = ","; + break; + + case SL_PP_SEMICOLON: + s = ";"; + break; + + case SL_PP_LBRACE: + s = "{"; + break; + + case SL_PP_RBRACE: + s = "}"; + break; + + case SL_PP_LPAREN: + s = "("; + break; + + case SL_PP_RPAREN: + s = ")"; + break; + + case SL_PP_LBRACKET: + s = "["; + break; + + case SL_PP_RBRACKET: + s = "]"; + break; + + case SL_PP_DOT: + s = "."; + break; + + case SL_PP_INCREMENT: + s = "++"; + break; + + case SL_PP_ADDASSIGN: + s = "+="; + break; + + case SL_PP_PLUS: + s = "+"; + break; + + case SL_PP_DECREMENT: + s = "--"; + break; + + case SL_PP_SUBASSIGN: + s = "-="; + break; + + case SL_PP_MINUS: + s = "-"; + break; + + case SL_PP_BITNOT: + s = "~"; + break; + + case SL_PP_NOTEQUAL: + s = "!="; + break; + + case SL_PP_NOT: + s = "!"; + break; + + case SL_PP_MULASSIGN: + s = "*="; + break; + + case SL_PP_STAR: + s = "*"; + break; + + case SL_PP_DIVASSIGN: + s = "/="; + break; + + case SL_PP_SLASH: + s = "/"; + break; + + case SL_PP_MODASSIGN: + s = "%="; + break; + + case SL_PP_MODULO: + s = "%"; + break; + + case SL_PP_LSHIFTASSIGN: + s = "<<="; + break; + + case SL_PP_LSHIFT: + s = "<<"; + break; + + case SL_PP_LESSEQUAL: + s = "<="; + break; + + case SL_PP_LESS: + s = "<"; + break; + + case SL_PP_RSHIFTASSIGN: + s = ">>="; + break; + + case SL_PP_RSHIFT: + s = ">>"; + break; + + case SL_PP_GREATEREQUAL: + s = ">="; + break; + + case SL_PP_GREATER: + s = ">"; + break; + + case SL_PP_EQUAL: + s = "=="; + break; + + case SL_PP_ASSIGN: + s = "="; + break; + + case SL_PP_AND: + s = "&&"; + break; + + case SL_PP_BITANDASSIGN: + s = "&="; + break; + + case SL_PP_BITAND: + s = "&"; + break; + + case SL_PP_XOR: + s = "^^"; + break; + + case SL_PP_BITXORASSIGN: + s = "^="; + break; + + case SL_PP_BITXOR: + s = "^"; + break; + + case SL_PP_OR: + s = "||"; + break; + + case SL_PP_BITORASSIGN: + s = "|="; + break; + + case SL_PP_BITOR: + s = "|"; + break; + + case SL_PP_QUESTION: + s = "?"; + break; + + case SL_PP_COLON: + s = ":"; + break; + + case SL_PP_IDENTIFIER: + 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); + break; + + case SL_PP_OTHER: + buf[0] = input[i].data.other; + buf[1] = '\0'; + s = buf; + break; + + default: + strcpy(context->error_msg, "internal error"); + return; + } + + while (*s != '\0' && out_len < sizeof(context->error_msg) - 1) { + context->error_msg[out_len++] = *s++; + } + } + + context->error_msg[out_len] = '\0'; +} diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index c17a3ac7ce..117aa01688 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -151,6 +151,9 @@ sl_pp_process(struct sl_pp_context *context, if (sl_pp_process_define(context, input, first, last)) { return -1; } + } else if (!strcmp(name, "error")) { + sl_pp_process_error(context, input, first, last); + return -1; } else if (!strcmp(name, "undef")) { if (sl_pp_process_undef(context, input, first, last)) { return -1; diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h index 61e67fef0b..11a94921d8 100644 --- a/src/glsl/pp/sl_pp_process.h +++ b/src/glsl/pp/sl_pp_process.h @@ -92,6 +92,12 @@ sl_pp_process_endif(struct sl_pp_context *context, unsigned int first, unsigned int last); +void +sl_pp_process_error(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 0e046420e468bcb81301aa5a5e4de736a8b4844a Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 4 Sep 2009 10:48:51 +0200 Subject: glsl: Implement `pragma' preprocessor directive. Handle `optimize(on|off)' and `debug(on|off)' pragmas. --- src/glsl/pp/SConscript | 1 + src/glsl/pp/sl_pp_pragma.c | 106 ++++++++++++++++++++++++++++++++++++++++++++ src/glsl/pp/sl_pp_process.c | 4 ++ src/glsl/pp/sl_pp_process.h | 7 +++ src/glsl/pp/sl_pp_token.h | 4 ++ 5 files changed, 122 insertions(+) create mode 100644 src/glsl/pp/sl_pp_pragma.c (limited to 'src/glsl/pp/sl_pp_process.c') diff --git a/src/glsl/pp/SConscript b/src/glsl/pp/SConscript index 13fc230b96..0c1b4ac2e9 100644 --- a/src/glsl/pp/SConscript +++ b/src/glsl/pp/SConscript @@ -14,6 +14,7 @@ glsl = env.StaticLibrary( 'sl_pp_expression.c', 'sl_pp_if.c', 'sl_pp_macro.c', + 'sl_pp_pragma.c', 'sl_pp_process.c', 'sl_pp_purify.c', 'sl_pp_token.c', diff --git a/src/glsl/pp/sl_pp_pragma.c b/src/glsl/pp/sl_pp_pragma.c new file mode 100644 index 0000000000..059bc6f288 --- /dev/null +++ b/src/glsl/pp/sl_pp_pragma.c @@ -0,0 +1,106 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include +#include "sl_pp_process.h" + + +int +sl_pp_process_pragma(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last, + struct sl_pp_process_state *state) +{ + const char *pragma_name = NULL; + struct sl_pp_token_info out; + const char *arg_name = NULL; + + if (first < last && input[first].token == SL_PP_IDENTIFIER) { + pragma_name = sl_pp_context_cstr(context, input[first].data.identifier); + first++; + } + if (!pragma_name) { + return 0; + } + + if (!strcmp(pragma_name, "optimize")) { + out.token = SL_PP_PRAGMA_OPTIMIZE; + } else if (!strcmp(pragma_name, "debug")) { + out.token = SL_PP_PRAGMA_DEBUG; + } else { + return 0; + } + + while (first < last && input[first].token == SL_PP_WHITESPACE) { + first++; + } + + if (first < last && input[first].token == SL_PP_LPAREN) { + first++; + } else { + return 0; + } + + while (first < last && input[first].token == SL_PP_WHITESPACE) { + first++; + } + + if (first < last && input[first].token == SL_PP_IDENTIFIER) { + arg_name = sl_pp_context_cstr(context, input[first].data.identifier); + first++; + } + if (!arg_name) { + return 0; + } + + if (!strcmp(arg_name, "off")) { + out.data.pragma = 0; + } else if (!strcmp(arg_name, "on")) { + out.data.pragma = 1; + } else { + return 0; + } + + while (first < last && input[first].token == SL_PP_WHITESPACE) { + first++; + } + + if (first < last && input[first].token == SL_PP_RPAREN) { + first++; + } else { + return 0; + } + + /* Ignore the tokens that follow. */ + + if (sl_pp_process_out(state, &out)) { + return -1; + } + + return 0; +} diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index 117aa01688..62b73426c5 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -154,6 +154,10 @@ sl_pp_process(struct sl_pp_context *context, } else if (!strcmp(name, "error")) { sl_pp_process_error(context, input, first, last); return -1; + } else if (!strcmp(name, "pragma")) { + if (sl_pp_process_pragma(context, input, first, last, &state)) { + return -1; + } } else if (!strcmp(name, "undef")) { if (sl_pp_process_undef(context, input, first, last)) { return -1; diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h index 11a94921d8..9a29c03a70 100644 --- a/src/glsl/pp/sl_pp_process.h +++ b/src/glsl/pp/sl_pp_process.h @@ -98,6 +98,13 @@ sl_pp_process_error(struct sl_pp_context *context, unsigned int first, unsigned int last); +int +sl_pp_process_pragma(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last, + struct sl_pp_process_state *state); + int sl_pp_process_out(struct sl_pp_process_state *state, const struct sl_pp_token_info *token); diff --git a/src/glsl/pp/sl_pp_token.h b/src/glsl/pp/sl_pp_token.h index a53720be80..566274ea90 100644 --- a/src/glsl/pp/sl_pp_token.h +++ b/src/glsl/pp/sl_pp_token.h @@ -88,6 +88,9 @@ enum sl_pp_token { SL_PP_OTHER, + SL_PP_PRAGMA_OPTIMIZE, + SL_PP_PRAGMA_DEBUG, + SL_PP_EOF }; @@ -95,6 +98,7 @@ union sl_pp_token_data { int identifier; int number; char other; + int pragma; }; struct sl_pp_token_info { -- cgit v1.2.3 From 87d2de04fbb7d9ea8eae9c58f7c7fb842ffe06f6 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 4 Sep 2009 11:32:46 +0200 Subject: glsl: Implement `extension' preprocessor directive. No extensions supported. --- src/glsl/pp/SConscript | 1 + src/glsl/pp/sl_pp_extension.c | 129 ++++++++++++++++++++++++++++++++++++++++++ src/glsl/pp/sl_pp_process.c | 4 ++ src/glsl/pp/sl_pp_process.h | 7 +++ src/glsl/pp/sl_pp_token.h | 6 ++ 5 files changed, 147 insertions(+) create mode 100644 src/glsl/pp/sl_pp_extension.c (limited to 'src/glsl/pp/sl_pp_process.c') diff --git a/src/glsl/pp/SConscript b/src/glsl/pp/SConscript index 0c1b4ac2e9..dae8830eeb 100644 --- a/src/glsl/pp/SConscript +++ b/src/glsl/pp/SConscript @@ -12,6 +12,7 @@ glsl = env.StaticLibrary( 'sl_pp_define.c', 'sl_pp_error.c', 'sl_pp_expression.c', + 'sl_pp_extension.c', 'sl_pp_if.c', 'sl_pp_macro.c', 'sl_pp_pragma.c', diff --git a/src/glsl/pp/sl_pp_extension.c b/src/glsl/pp/sl_pp_extension.c new file mode 100644 index 0000000000..3d223a1a54 --- /dev/null +++ b/src/glsl/pp/sl_pp_extension.c @@ -0,0 +1,129 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include +#include "sl_pp_process.h" + + +int +sl_pp_process_extension(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last, + struct sl_pp_process_state *state) +{ + int all_extensions = -1; + const char *extension_name = NULL; + const char *behavior = NULL; + struct sl_pp_token_info out; + + all_extensions = sl_pp_context_add_unique_str(context, "all"); + if (all_extensions == -1) { + return -1; + } + + if (first < last && input[first].token == SL_PP_IDENTIFIER) { + extension_name = sl_pp_context_cstr(context, input[first].data.identifier); + first++; + } + if (!extension_name) { + strcpy(context->error_msg, "expected identifier after `#extension'"); + return -1; + } + + if (!strcmp(extension_name, "all")) { + out.data.extension = all_extensions; + } else { + out.data.extension = -1; + } + + while (first < last && input[first].token == SL_PP_WHITESPACE) { + first++; + } + + if (first < last && input[first].token == SL_PP_COLON) { + first++; + } else { + strcpy(context->error_msg, "expected `:' after extension name"); + return -1; + } + + while (first < last && input[first].token == SL_PP_WHITESPACE) { + first++; + } + + if (first < last && input[first].token == SL_PP_IDENTIFIER) { + behavior = sl_pp_context_cstr(context, input[first].data.identifier); + first++; + } + if (!behavior) { + strcpy(context->error_msg, "expected identifier after `:'"); + return -1; + } + + if (!strcmp(behavior, "require")) { + strcpy(context->error_msg, "unable to enable required extension"); + return -1; + } else if (!strcmp(behavior, "enable")) { + if (out.data.extension == all_extensions) { + strcpy(context->error_msg, "unable to enable all extensions"); + return -1; + } else { + return 0; + } + } else if (!strcmp(behavior, "warn")) { + if (out.data.extension == all_extensions) { + out.token = SL_PP_EXTENSION_WARN; + } else { + return 0; + } + } else if (!strcmp(behavior, "disable")) { + if (out.data.extension == all_extensions) { + out.token = SL_PP_EXTENSION_DISABLE; + } else { + return 0; + } + } else { + strcpy(context->error_msg, "unrecognised behavior name"); + return -1; + } + + while (first < last && input[first].token == SL_PP_WHITESPACE) { + first++; + } + + if (first < last) { + strcpy(context->error_msg, "expected end of line after behavior name"); + return -1; + } + + if (sl_pp_process_out(state, &out)) { + return -1; + } + + return 0; +} diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index 62b73426c5..be01f9139c 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -154,6 +154,10 @@ sl_pp_process(struct sl_pp_context *context, } else if (!strcmp(name, "error")) { sl_pp_process_error(context, input, first, last); return -1; + } else if (!strcmp(name, "extension")) { + if (sl_pp_process_extension(context, input, first, last, &state)) { + return -1; + } } else if (!strcmp(name, "pragma")) { if (sl_pp_process_pragma(context, input, first, last, &state)) { return -1; diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h index 9a29c03a70..5891866543 100644 --- a/src/glsl/pp/sl_pp_process.h +++ b/src/glsl/pp/sl_pp_process.h @@ -105,6 +105,13 @@ sl_pp_process_pragma(struct sl_pp_context *context, unsigned int last, struct sl_pp_process_state *state); +int +sl_pp_process_extension(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last, + struct sl_pp_process_state *state); + int sl_pp_process_out(struct sl_pp_process_state *state, const struct sl_pp_token_info *token); diff --git a/src/glsl/pp/sl_pp_token.h b/src/glsl/pp/sl_pp_token.h index 566274ea90..7b60183a04 100644 --- a/src/glsl/pp/sl_pp_token.h +++ b/src/glsl/pp/sl_pp_token.h @@ -91,6 +91,11 @@ enum sl_pp_token { SL_PP_PRAGMA_OPTIMIZE, SL_PP_PRAGMA_DEBUG, + SL_PP_EXTENSION_REQUIRE, + SL_PP_EXTENSION_ENABLE, + SL_PP_EXTENSION_WARN, + SL_PP_EXTENSION_DISABLE, + SL_PP_EOF }; @@ -99,6 +104,7 @@ union sl_pp_token_data { int number; char other; int pragma; + int extension; }; struct sl_pp_token_info { -- cgit v1.2.3 From ddd8ae7fbc643892b08ddf66c67bca36d42b53a6 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 4 Sep 2009 11:39:30 +0200 Subject: glsl: Output endof token after processing a directive. Some directives may output tokens as a result of their operation. --- src/glsl/pp/sl_pp_process.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/glsl/pp/sl_pp_process.c') diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index be01f9139c..18289790d1 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -87,6 +87,7 @@ sl_pp_process(struct sl_pp_context *context, 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); @@ -99,17 +100,13 @@ 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 (sl_pp_process_out(&state, &input[i])) { - return -1; - } + endof = input[i]; i++; found_eol = 1; break; case SL_PP_EOF: - if (sl_pp_process_out(&state, &input[i])) { - return -1; - } + endof = input[i]; i++; found_eof = 1; found_eol = 1; @@ -170,6 +167,10 @@ sl_pp_process(struct sl_pp_context *context, /* XXX: Ignore. */ } } + + if (sl_pp_process_out(&state, &endof)) { + return -1; + } } break; -- cgit v1.2.3 From bb8f38ea6f71179cd4adb0ca33c464716be17dcb Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 4 Sep 2009 11:58:19 +0200 Subject: glsl: Implement `line' preprocessor directive. --- src/glsl/pp/SConscript | 1 + src/glsl/pp/sl_pp_line.c | 95 +++++++++++++++++++++++++++++++++++++++++++++ src/glsl/pp/sl_pp_process.c | 7 +++- src/glsl/pp/sl_pp_process.h | 6 +++ 4 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 src/glsl/pp/sl_pp_line.c (limited to 'src/glsl/pp/sl_pp_process.c') diff --git a/src/glsl/pp/SConscript b/src/glsl/pp/SConscript index dae8830eeb..cc930380c2 100644 --- a/src/glsl/pp/SConscript +++ b/src/glsl/pp/SConscript @@ -14,6 +14,7 @@ glsl = env.StaticLibrary( 'sl_pp_expression.c', 'sl_pp_extension.c', 'sl_pp_if.c', + 'sl_pp_line.c', 'sl_pp_macro.c', 'sl_pp_pragma.c', 'sl_pp_process.c', diff --git a/src/glsl/pp/sl_pp_line.c b/src/glsl/pp/sl_pp_line.c new file mode 100644 index 0000000000..3300a4785b --- /dev/null +++ b/src/glsl/pp/sl_pp_line.c @@ -0,0 +1,95 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include +#include "sl_pp_process.h" + + +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 i; + struct sl_pp_process_state state; + int line_number = -1; + int file_number = -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++; + } + } + + 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'"); + free(state.out); + return -1; + } + + if (state.out_len > 1) { + 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"); + free(state.out); + return -1; + } + + if (state.out_len > 2) { + strcpy(context->error_msg, "expected end of line after file number"); + free(state.out); + return -1; + } + } + + free(state.out); + + /* TODO: Do something with line and file numbers. */ + + return 0; +} diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index 18289790d1..5479e8a868 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -155,6 +155,10 @@ sl_pp_process(struct sl_pp_context *context, if (sl_pp_process_extension(context, input, first, last, &state)) { return -1; } + } else if (!strcmp(name, "line")) { + if (sl_pp_process_line(context, input, first, last)) { + return -1; + } } else if (!strcmp(name, "pragma")) { if (sl_pp_process_pragma(context, input, first, last, &state)) { return -1; @@ -164,7 +168,8 @@ sl_pp_process(struct sl_pp_context *context, return -1; } } else { - /* XXX: Ignore. */ + strcpy(context->error_msg, "unrecognised directive name"); + return -1; } } diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h index 5891866543..6f90fbd3e7 100644 --- a/src/glsl/pp/sl_pp_process.h +++ b/src/glsl/pp/sl_pp_process.h @@ -112,6 +112,12 @@ sl_pp_process_extension(struct sl_pp_context *context, unsigned int last, struct sl_pp_process_state *state); +int +sl_pp_process_line(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 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_process.c') diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index 38d633baef..6aaf76828c 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 65ce3e37b7..d656648d0d 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 3300a4785b..b62af185bf 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 bacd468964..b6214f66ed 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 5479e8a868..c4d6efaed3 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 6f90fbd3e7..adc08c18ae 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 7b60183a04..b347e5cf7a 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 89c3cfa1a5..80f7e97101 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 d4638f5dce4cb2c873acafb289036fd59c7a3c78 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 16 Sep 2009 20:27:59 +0200 Subject: glsl/pp: Add more error messages. --- src/glsl/pp/sl_pp_process.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/glsl/pp/sl_pp_process.c') diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index c4d6efaed3..03a3051838 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -81,11 +81,13 @@ sl_pp_process(struct sl_pp_context *context, ti.token = SL_PP_LINE; ti.data.line = context->line - 1; if (sl_pp_process_out(&state, &ti)) { + strcpy(context->error_msg, "out of memory"); return -1; } ti.token = SL_PP_NEWLINE; if (sl_pp_process_out(&state, &ti)) { + strcpy(context->error_msg, "out of memory"); return -1; } } @@ -189,6 +191,7 @@ sl_pp_process(struct sl_pp_context *context, } if (sl_pp_process_out(&state, &endof)) { + strcpy(context->error_msg, "out of memory"); return -1; } context->line++; @@ -198,6 +201,7 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_NEWLINE: /* Empty directive. */ if (sl_pp_process_out(&state, &input[i])) { + strcpy(context->error_msg, "out of memory"); return -1; } context->line++; @@ -207,6 +211,7 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_EOF: /* Empty directive. */ if (sl_pp_process_out(&state, &input[i])) { + strcpy(context->error_msg, "out of memory"); return -1; } i++; @@ -214,6 +219,7 @@ sl_pp_process(struct sl_pp_context *context, break; default: + strcpy(context->error_msg, "expected a directive name"); return -1; } } else { @@ -229,6 +235,7 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_NEWLINE: /* Preserve newline just for the sake of line numbering. */ if (sl_pp_process_out(&state, &input[i])) { + strcpy(context->error_msg, "out of memory"); return -1; } context->line++; @@ -238,6 +245,7 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_EOF: if (sl_pp_process_out(&state, &input[i])) { + strcpy(context->error_msg, "out of memory"); return -1; } i++; @@ -254,6 +262,7 @@ sl_pp_process(struct sl_pp_context *context, default: if (context->if_value) { if (sl_pp_process_out(&state, &input[i])) { + strcpy(context->error_msg, "out of memory"); return -1; } } @@ -264,7 +273,7 @@ sl_pp_process(struct sl_pp_context *context, } if (context->if_ptr != SL_PP_MAX_IF_NESTING) { - /* #endif expected. */ + strcpy(context->error_msg, "expected `#endif' directive"); return -1; } -- 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_process.c') diff --git a/src/glsl/pp/sl_pp_dict.c b/src/glsl/pp/sl_pp_dict.c index 65b91d9e98..f2885c763d 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 ce138d98f5..ba82b389b2 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 44bbefa357..cf1c746d5f 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 7793562781..6772100847 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 1cd9fd8234..03269b63db 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 03a3051838..ab2f2d8eb4 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 6cd63f4925..814da46a67 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 9a1447d449209635e481c7f9bd02084864e17419 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 24 Sep 2009 08:43:05 +0200 Subject: glsl/pp: Store both line number and file index in a single token. --- src/glsl/pp/sl_pp_line.c | 31 ++++++++++--------------------- src/glsl/pp/sl_pp_process.c | 3 ++- src/glsl/pp/sl_pp_token.h | 7 ++++--- 3 files changed, 16 insertions(+), 25 deletions(-) (limited to 'src/glsl/pp/sl_pp_process.c') diff --git a/src/glsl/pp/sl_pp_line.c b/src/glsl/pp/sl_pp_line.c index e8f751003a..41ddaf6ba2 100644 --- a/src/glsl/pp/sl_pp_line.c +++ b/src/glsl/pp/sl_pp_line.c @@ -42,6 +42,7 @@ sl_pp_process_line(struct sl_pp_context *context, int line_number = -1; int file_number = -1; unsigned int line; + unsigned int file; memset(&state, 0, sizeof(state)); for (i = first; i < last;) { @@ -94,37 +95,25 @@ sl_pp_process_line(struct sl_pp_context *context, free(state.out); line = atoi(sl_pp_context_cstr(context, line_number)); + if (file_number != -1) { + file = atoi(sl_pp_context_cstr(context, file_number)); + } else { + file = context->file; + } - if (context->line != line) { + if (context->line != line || context->file != file) { struct sl_pp_token_info ti; ti.token = SL_PP_LINE; - ti.data.line = line; + ti.data.line.lineno = line; + ti.data.line.fileno = file; if (sl_pp_process_out(pstate, &ti)) { strcpy(context->error_msg, "out of memory"); return -1; } context->line = line; - } - - if (file_number != -1) { - unsigned int file; - - file = atoi(sl_pp_context_cstr(context, file_number)); - - 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)) { - strcpy(context->error_msg, "out of memory"); - return -1; - } - - context->file = file; - } + context->file = file; } return 0; diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index ab2f2d8eb4..67ed588818 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -79,7 +79,8 @@ sl_pp_process(struct sl_pp_context *context, struct sl_pp_token_info ti; ti.token = SL_PP_LINE; - ti.data.line = context->line - 1; + ti.data.line.lineno = context->line - 1; + ti.data.line.fileno = context->file; if (sl_pp_process_out(&state, &ti)) { strcpy(context->error_msg, "out of memory"); return -1; diff --git a/src/glsl/pp/sl_pp_token.h b/src/glsl/pp/sl_pp_token.h index 2a7b79ea3f..b1f3389b32 100644 --- a/src/glsl/pp/sl_pp_token.h +++ b/src/glsl/pp/sl_pp_token.h @@ -96,7 +96,6 @@ enum sl_pp_token { SL_PP_EXTENSION_DISABLE, SL_PP_LINE, - SL_PP_FILE, SL_PP_EOF }; @@ -108,8 +107,10 @@ union sl_pp_token_data { char other; int pragma; int extension; - unsigned int line; - unsigned int file; + union { + unsigned int lineno: 24; + unsigned int fileno: 8; + } line; }; struct sl_pp_token_info { -- cgit v1.2.3 From 7a95a3c7c4ba49ec174681c36951e3c0672df06c Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 24 Sep 2009 10:56:46 +0200 Subject: glsl/pp: Include missing headers. --- src/glsl/pp/sl_pp_context.c | 1 + src/glsl/pp/sl_pp_error.c | 1 + src/glsl/pp/sl_pp_expression.c | 1 + src/glsl/pp/sl_pp_extension.c | 1 + src/glsl/pp/sl_pp_if.c | 1 + src/glsl/pp/sl_pp_line.c | 1 + src/glsl/pp/sl_pp_pragma.c | 1 + src/glsl/pp/sl_pp_process.c | 2 ++ src/glsl/pp/sl_pp_token.c | 1 + src/glsl/pp/sl_pp_version.c | 1 + 10 files changed, 11 insertions(+) (limited to 'src/glsl/pp/sl_pp_process.c') diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index fd205de5d3..8ce189d955 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -26,6 +26,7 @@ **************************************************************************/ #include +#include #include "sl_pp_public.h" #include "sl_pp_context.h" diff --git a/src/glsl/pp/sl_pp_error.c b/src/glsl/pp/sl_pp_error.c index df9b191dfe..a9eeff98ba 100644 --- a/src/glsl/pp/sl_pp_error.c +++ b/src/glsl/pp/sl_pp_error.c @@ -26,6 +26,7 @@ **************************************************************************/ #include +#include #include "sl_pp_process.h" #include "sl_pp_public.h" diff --git a/src/glsl/pp/sl_pp_expression.c b/src/glsl/pp/sl_pp_expression.c index 3f6dfb5a6d..ec904787dd 100644 --- a/src/glsl/pp/sl_pp_expression.c +++ b/src/glsl/pp/sl_pp_expression.c @@ -26,6 +26,7 @@ **************************************************************************/ #include +#include #include "sl_pp_expression.h" #include "sl_pp_public.h" diff --git a/src/glsl/pp/sl_pp_extension.c b/src/glsl/pp/sl_pp_extension.c index 33193d03a8..4148fd9a5a 100644 --- a/src/glsl/pp/sl_pp_extension.c +++ b/src/glsl/pp/sl_pp_extension.c @@ -26,6 +26,7 @@ **************************************************************************/ #include +#include #include "sl_pp_process.h" diff --git a/src/glsl/pp/sl_pp_if.c b/src/glsl/pp/sl_pp_if.c index c8e958eab4..a0b3635dd5 100644 --- a/src/glsl/pp/sl_pp_if.c +++ b/src/glsl/pp/sl_pp_if.c @@ -26,6 +26,7 @@ **************************************************************************/ #include +#include #include "sl_pp_expression.h" #include "sl_pp_process.h" diff --git a/src/glsl/pp/sl_pp_line.c b/src/glsl/pp/sl_pp_line.c index 41ddaf6ba2..fc2dd89e68 100644 --- a/src/glsl/pp/sl_pp_line.c +++ b/src/glsl/pp/sl_pp_line.c @@ -26,6 +26,7 @@ **************************************************************************/ #include +#include #include "sl_pp_public.h" #include "sl_pp_process.h" diff --git a/src/glsl/pp/sl_pp_pragma.c b/src/glsl/pp/sl_pp_pragma.c index 03269b63db..489eb17b8e 100644 --- a/src/glsl/pp/sl_pp_pragma.c +++ b/src/glsl/pp/sl_pp_pragma.c @@ -26,6 +26,7 @@ **************************************************************************/ #include +#include #include "sl_pp_process.h" diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index 67ed588818..4b783e40b4 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -26,7 +26,9 @@ **************************************************************************/ #include +#include #include "sl_pp_process.h" +#include "sl_pp_public.h" static void diff --git a/src/glsl/pp/sl_pp_token.c b/src/glsl/pp/sl_pp_token.c index 99a32a6e67..f232dafc68 100644 --- a/src/glsl/pp/sl_pp_token.c +++ b/src/glsl/pp/sl_pp_token.c @@ -26,6 +26,7 @@ **************************************************************************/ #include +#include #include "sl_pp_context.h" #include "sl_pp_token.h" diff --git a/src/glsl/pp/sl_pp_version.c b/src/glsl/pp/sl_pp_version.c index adf3017bf2..db06523749 100644 --- a/src/glsl/pp/sl_pp_version.c +++ b/src/glsl/pp/sl_pp_version.c @@ -26,6 +26,7 @@ **************************************************************************/ #include +#include #include "sl_pp_public.h" #include "sl_pp_context.h" -- 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_process.c') diff --git a/src/glsl/pp/sl_pp_if.c b/src/glsl/pp/sl_pp_if.c index a0b3635dd5..6610bc69f3 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 fc2dd89e68..ed5acc697c 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 d6c32a0e78..29f1229dd7 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 e3ae2fc712..3ad3438236 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 4b783e40b4..e2adc2a021 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