From 0bbf59c3052a7b4f6f8330985317adce2bfd0fef Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 11 Jun 2009 14:04:39 +0200 Subject: glsl: Add preprocessor purifier. --- src/glsl/pp/SConscript | 21 +++++ src/glsl/pp/sl_pp_purify.c | 204 +++++++++++++++++++++++++++++++++++++++++++++ src/glsl/pp/sl_pp_purify.h | 41 +++++++++ 3 files changed, 266 insertions(+) create mode 100644 src/glsl/pp/SConscript create mode 100644 src/glsl/pp/sl_pp_purify.c create mode 100644 src/glsl/pp/sl_pp_purify.h (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/SConscript b/src/glsl/pp/SConscript new file mode 100644 index 00000000000..08f202e2367 --- /dev/null +++ b/src/glsl/pp/SConscript @@ -0,0 +1,21 @@ +Import('*') + +if env['platform'] not in ['windows']: + Return() + +env = env.Clone() + +glsl = env.StaticLibrary( + target = 'glsl', + source = [ + 'sl_pp_purify.c', + ], +) + +env = env.Clone() + +if env['platform'] == 'windows': + env.PrependUnique(LIBS = [ + 'user32', + ]) +env.Prepend(LIBS = [glsl]) diff --git a/src/glsl/pp/sl_pp_purify.c b/src/glsl/pp/sl_pp_purify.c new file mode 100644 index 00000000000..7fbfc78d426 --- /dev/null +++ b/src/glsl/pp/sl_pp_purify.c @@ -0,0 +1,204 @@ +/************************************************************************** + * + * 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_purify.h" + + +/* + * Preprocessor purifier performs the following tasks. + * - Convert all variants of newlines into a Unix newline. + * - Merge continued lines into a single long line. + * - Remove line comments and replace block comments with whitespace. + */ + + +static unsigned int +_purify_newline(const char *input, + char *out) +{ + if (input[0] == '\n') { + *out = '\n'; + if (input[1] == '\r') { + /* + * The GLSL spec is not explicit about whether this + * combination is a valid newline or not. + * Let's assume it is acceptable. + */ + return 2; + } + return 1; + } + if (input[0] == '\r') { + *out = '\n'; + if (input[1] == '\n') { + return 2; + } + return 1; + } + *out = input[0]; + return 1; +} + + +static unsigned int +_purify_backslash(const char *input, + char *out) +{ + unsigned int eaten = 0; + + for (;;) { + if (input[0] == '\\') { + char next; + unsigned int next_eaten; + + eaten++; + input++; + + next_eaten = _purify_newline(input, &next); + if (next == '\n') { + /* + * If this is really a line continuation sequence, eat + * it and do not exit the loop. + */ + eaten += next_eaten; + input += next_eaten; + } else { + /* + * It is an error to put anything between a backslash + * and a newline and still expect it to behave like a line + * continuation sequence. + * Even if it is an innocent whitespace. + */ + *out = '\\'; + break; + } + } else { + eaten += _purify_newline(input, out); + break; + } + } + return eaten; +} + + +static unsigned int +_purify_comment(const char *input, + char *out) +{ + unsigned int eaten; + char curr; + + eaten = _purify_backslash(input, &curr); + input += eaten; + if (curr == '/') { + char next; + unsigned int next_eaten; + + next_eaten = _purify_backslash(input, &next); + if (next == '/') { + eaten += next_eaten; + input += next_eaten; + + /* Replace a line comment with either a newline or nil. */ + for (;;) { + next_eaten = _purify_backslash(input, &next); + eaten += next_eaten; + input += next_eaten; + if (next == '\n' || next == '\0') { + *out = next; + return eaten; + } + } + } else if (next == '*') { + eaten += next_eaten; + input += next_eaten; + + /* Replace a block comment with a whitespace. */ + for (;;) { + next_eaten = _purify_backslash(input, &next); + eaten += next_eaten; + input += next_eaten; + while (next == '*') { + next_eaten = _purify_backslash(input, &next); + eaten += next_eaten; + input += next_eaten; + if (next == '/') { + *out = ' '; + return eaten; + } + } + } + } + } + *out = curr; + return eaten; +} + + +int +sl_pp_purify(const char *input, + const struct sl_pp_purify_options *options, + char **output) +{ + char *out = NULL; + unsigned int out_len = 0; + unsigned int out_max = 0; + + for (;;) { + char c; + + input += _purify_comment(input, &c); + + 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); + if (!out) { + return -1; + } + out_max = new_max; + } + + out[out_len++] = c; + + if (c == '\0') { + break; + } + } + + *output = out; + return 0; +} diff --git a/src/glsl/pp/sl_pp_purify.h b/src/glsl/pp/sl_pp_purify.h new file mode 100644 index 00000000000..011b117937e --- /dev/null +++ b/src/glsl/pp/sl_pp_purify.h @@ -0,0 +1,41 @@ +/************************************************************************** + * + * 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_PURIFY_H +#define SL_PP_PURIFY_H + +struct sl_pp_purify_options { + unsigned int preserve_columns:1; + unsigned int tab_width:4; +}; + +int +sl_pp_purify(const char *input, + const struct sl_pp_purify_options *options, + char **output); + +#endif /* SL_PP_PURIFY_H */ -- cgit v1.2.3 From 121769eeb314ea580a3292309332ebbf0a409b3c Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 11 Jun 2009 18:56:10 +0200 Subject: glsl: Add a purify command-line tool. --- src/SConscript | 1 + src/glsl/apps/SConscript | 18 ++++++++++ src/glsl/apps/purify.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++ src/glsl/pp/SConscript | 9 +---- 4 files changed, 113 insertions(+), 8 deletions(-) create mode 100644 src/glsl/apps/SConscript create mode 100644 src/glsl/apps/purify.c (limited to 'src/glsl/pp') diff --git a/src/SConscript b/src/SConscript index 1ece895c63a..28105f71917 100644 --- a/src/SConscript +++ b/src/SConscript @@ -2,6 +2,7 @@ Import('*') SConscript('gallium/SConscript') SConscript('glsl/pp/SConscript') +SConscript('glsl/apps/SConscript') if 'mesa' in env['statetrackers']: SConscript('mesa/SConscript') diff --git a/src/glsl/apps/SConscript b/src/glsl/apps/SConscript new file mode 100644 index 00000000000..d68e6b23b35 --- /dev/null +++ b/src/glsl/apps/SConscript @@ -0,0 +1,18 @@ +Import('*') + +if env['platform'] not in ['windows']: + Return() + +env = env.Clone() + +if env['platform'] == 'windows': + env.PrependUnique(LIBS = [ + 'user32', + ]) + +env.Prepend(LIBS = [glsl]) + +env.Program( + target = 'purify', + source = ['purify.c'], +) diff --git a/src/glsl/apps/purify.c b/src/glsl/apps/purify.c new file mode 100644 index 00000000000..7dff8aea456 --- /dev/null +++ b/src/glsl/apps/purify.c @@ -0,0 +1,93 @@ +/************************************************************************** + * + * 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 "../pp/sl_pp_purify.h" + + +int +main(int argc, + char *argv[]) +{ + FILE *in; + long size; + char *inbuf; + struct sl_pp_purify_options options; + char *outbuf; + FILE *out; + + if (argc != 3) { + return 1; + } + + in = fopen(argv[1], "rb"); + if (!in) { + return 1; + } + + fseek(in, 0, SEEK_END); + size = ftell(in); + fseek(in, 0, SEEK_SET); + + inbuf = malloc(size + 1); + if (!inbuf) { + fclose(in); + return 1; + } + + if (fread(inbuf, 1, size, in) != size) { + free(inbuf); + fclose(in); + return 1; + } + inbuf[size] = '\0'; + + fclose(in); + + memset(&options, 0, sizeof(options)); + + if (sl_pp_purify(inbuf, &options, &outbuf)) { + free(inbuf); + return 1; + } + + free(inbuf); + + out = fopen(argv[2], "wb"); + if (!out) { + free(outbuf); + return 1; + } + + fwrite(outbuf, 1, strlen(outbuf), out); + + free(outbuf); + fclose(out); + + return 0; +} diff --git a/src/glsl/pp/SConscript b/src/glsl/pp/SConscript index 08f202e2367..ac58a3e5fd2 100644 --- a/src/glsl/pp/SConscript +++ b/src/glsl/pp/SConscript @@ -11,11 +11,4 @@ glsl = env.StaticLibrary( 'sl_pp_purify.c', ], ) - -env = env.Clone() - -if env['platform'] == 'windows': - env.PrependUnique(LIBS = [ - 'user32', - ]) -env.Prepend(LIBS = [glsl]) +Export('glsl') -- cgit v1.2.3 From 2c9a627b48119b3cafc9fb25239fe929bc4cf8d8 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 12 Jun 2009 12:57:29 +0200 Subject: glsl: Add a preprocessor tokeniser. --- src/glsl/pp/SConscript | 1 + src/glsl/pp/sl_pp_token.c | 401 ++++++++++++++++++++++++++++++++++++++++++++++ src/glsl/pp/sl_pp_token.h | 107 +++++++++++++ 3 files changed, 509 insertions(+) create mode 100644 src/glsl/pp/sl_pp_token.c create mode 100644 src/glsl/pp/sl_pp_token.h (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/SConscript b/src/glsl/pp/SConscript index ac58a3e5fd2..a08f5cf6321 100644 --- a/src/glsl/pp/SConscript +++ b/src/glsl/pp/SConscript @@ -9,6 +9,7 @@ glsl = env.StaticLibrary( target = 'glsl', source = [ 'sl_pp_purify.c', + 'sl_pp_token.c', ], ) Export('glsl') diff --git a/src/glsl/pp/sl_pp_token.c b/src/glsl/pp/sl_pp_token.c new file mode 100644 index 00000000000..6402c6a95b2 --- /dev/null +++ b/src/glsl/pp/sl_pp_token.c @@ -0,0 +1,401 @@ +/************************************************************************** + * + * 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_directive.h" +#include "sl_pp_token.h" + + +static int +_tokenise_identifier(const char **pinput, + struct sl_pp_token_info *info) +{ + const char *input = *pinput; + char identifier[256]; /* XXX: Remove this artifical limit. */ + unsigned int i = 0; + + info->token = SL_PP_IDENTIFIER; + info->data.identifier = NULL; + + identifier[i++] = *input++; + while ((*input >= 'a' && *input <= 'z') || + (*input >= 'A' && *input <= 'Z') || + (*input >= '0' && *input <= '9') || + (*input == '_')) { + if (i >= sizeof(identifier) - 1) { + return -1; + } + identifier[i++] = *input++; + } + identifier[i++] = '\0'; + + info->data.identifier = malloc(i); + if (!info->data.identifier) { + return -1; + } + memcpy(info->data.identifier, identifier, i); + + *pinput = input; + return 0; +} + + +static int +_tokenise_number(const char **pinput, + struct sl_pp_token_info *info) +{ + const char *input = *pinput; + char number[256]; /* XXX: Remove this artifical limit. */ + unsigned int i = 0; + + info->token = SL_PP_NUMBER; + info->data.number = NULL; + + number[i++] = *input++; + while ((*input >= '0' && *input <= '9') || + (*input >= 'a' && *input <= 'f') || + (*input >= 'A' && *input <= 'F') || + (*input == 'x') || + (*input == 'X') || + (*input == '+') || + (*input == '-') || + (*input == '.')) { + if (i >= sizeof(number) - 1) { + return -1; + } + number[i++] = *input++; + } + number[i++] = '\0'; + + info->data.number = malloc(i); + if (!info->data.number) { + return -1; + } + memcpy(info->data.number, number, i); + + *pinput = input; + return 0; +} + + +int +sl_pp_tokenise(const char *input, + struct sl_pp_token_info **output) +{ + struct sl_pp_token_info *out = NULL; + unsigned int out_len = 0; + unsigned int out_max = 0; + + for (;;) { + struct sl_pp_token_info info; + + switch (*input) { + case ' ': + case '\t': + input++; + info.token = SL_PP_WHITESPACE; + break; + + case '\n': + input++; + info.token = SL_PP_NEWLINE; + break; + + case '#': + input++; + info.token = SL_PP_HASH; + break; + + case ',': + input++; + info.token = SL_PP_COMMA; + break; + + case ';': + input++; + info.token = SL_PP_SEMICOLON; + break; + + case '{': + input++; + info.token = SL_PP_LBRACE; + break; + + case '}': + input++; + info.token = SL_PP_RBRACE; + break; + + case '(': + input++; + info.token = SL_PP_LPAREN; + break; + + case ')': + input++; + info.token = SL_PP_RPAREN; + break; + + case '[': + input++; + info.token = SL_PP_LBRACKET; + break; + + case ']': + input++; + info.token = SL_PP_RBRACKET; + break; + + case '.': + if (input[1] >= '0' && input[1] <= '9') { + if (_tokenise_number(&input, &info)) { + free(out); + return -1; + } + } else { + input++; + info.token = SL_PP_DOT; + } + break; + + case '+': + input++; + if (*input == '+') { + input++; + info.token = SL_PP_INCREMENT; + } else if (*input == '=') { + input++; + info.token = SL_PP_ADDASSIGN; + } else { + info.token = SL_PP_PLUS; + } + break; + + case '-': + input++; + if (*input == '-') { + input++; + info.token = SL_PP_DECREMENT; + } else if (*input == '=') { + input++; + info.token = SL_PP_SUBASSIGN; + } else { + info.token = SL_PP_MINUS; + } + break; + + case '~': + input++; + info.token = SL_PP_BITNOT; + break; + + case '!': + input++; + if (*input == '=') { + input++; + info.token = SL_PP_NOTEQUAL; + } else { + info.token = SL_PP_NOT; + } + break; + + case '*': + input++; + if (*input == '=') { + input++; + info.token = SL_PP_MULASSIGN; + } else { + info.token = SL_PP_STAR; + } + break; + + case '/': + input++; + if (*input == '=') { + input++; + info.token = SL_PP_DIVASSIGN; + } else { + info.token = SL_PP_SLASH; + } + break; + + case '%': + input++; + if (*input == '=') { + input++; + info.token = SL_PP_MODASSIGN; + } else { + info.token = SL_PP_MODULO; + } + break; + + case '<': + input++; + if (*input == '<') { + input++; + if (*input == '=') { + input++; + info.token = SL_PP_LSHIFTASSIGN; + } else { + info.token = SL_PP_LSHIFT; + } + } else if (*input == '=') { + input++; + info.token = SL_PP_LESSEQUAL; + } else { + info.token = SL_PP_LESS; + } + break; + + case '>': + input++; + if (*input == '>') { + input++; + if (*input == '=') { + input++; + info.token = SL_PP_RSHIFTASSIGN; + } else { + info.token = SL_PP_RSHIFT; + } + } else if (*input == '=') { + input++; + info.token = SL_PP_GREATEREQUAL; + } else { + info.token = SL_PP_GREATER; + } + break; + + case '=': + input++; + if (*input == '=') { + input++; + info.token = SL_PP_EQUAL; + } else { + info.token = SL_PP_ASSIGN; + } + break; + + case '&': + input++; + if (*input == '&') { + input++; + info.token = SL_PP_AND; + } else if (*input == '=') { + input++; + info.token = SL_PP_BITANDASSIGN; + } else { + info.token = SL_PP_BITAND; + } + break; + + case '^': + input++; + if (*input == '^') { + input++; + info.token = SL_PP_XOR; + } else if (*input == '=') { + input++; + info.token = SL_PP_BITXORASSIGN; + } else { + info.token = SL_PP_BITXOR; + } + break; + + case '|': + input++; + if (*input == '|') { + input++; + info.token = SL_PP_OR; + } else if (*input == '=') { + input++; + info.token = SL_PP_BITORASSIGN; + } else { + info.token = SL_PP_BITOR; + } + break; + + case '?': + input++; + info.token = SL_PP_QUESTION; + break; + + case ':': + input++; + info.token = SL_PP_COLON; + break; + + case '\0': + info.token = SL_PP_EOF; + break; + + default: + if ((*input >= 'a' && *input <= 'z') || + (*input >= 'A' && *input <= 'Z') || + (*input == '_')) { + if (_tokenise_identifier(&input, &info)) { + free(out); + return -1; + } + } else if (*input >= '0' && *input <= '9') { + if (_tokenise_number(&input, &info)) { + free(out); + return -1; + } + } else { + info.data.other = *input++; + info.token = SL_PP_OTHER; + } + } + + 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; + } + + out[out_len++] = info; + + if (info.token == SL_PP_EOF) { + break; + } + } + + *output = out; + return 0; +} diff --git a/src/glsl/pp/sl_pp_token.h b/src/glsl/pp/sl_pp_token.h new file mode 100644 index 00000000000..5e7fae7d29c --- /dev/null +++ b/src/glsl/pp/sl_pp_token.h @@ -0,0 +1,107 @@ +/************************************************************************** + * + * 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_TOKEN_H +#define SL_PP_TOKEN_H + + +enum sl_pp_token { + SL_PP_WHITESPACE, + SL_PP_NEWLINE, + SL_PP_HASH, /* # */ + + SL_PP_COMMA, /* , */ + SL_PP_SEMICOLON, /* ; */ + SL_PP_LBRACE, /* { */ + SL_PP_RBRACE, /* } */ + SL_PP_LPAREN, /* ( */ + SL_PP_RPAREN, /* ) */ + SL_PP_LBRACKET, /* [ */ + SL_PP_RBRACKET, /* ] */ + SL_PP_DOT, /* . */ + SL_PP_INCREMENT, /* ++ */ + SL_PP_ADDASSIGN, /* += */ + SL_PP_PLUS, /* + */ + SL_PP_DECREMENT, /* -- */ + SL_PP_SUBASSIGN, /* -= */ + SL_PP_MINUS, /* - */ + SL_PP_BITNOT, /* ~ */ + SL_PP_NOTEQUAL, /* != */ + SL_PP_NOT, /* ! */ + SL_PP_MULASSIGN, /* *= */ + SL_PP_STAR, /* * */ + SL_PP_DIVASSIGN, /* /= */ + SL_PP_SLASH, /* / */ + SL_PP_MODASSIGN, /* %= */ + SL_PP_MODULO, /* % */ + SL_PP_LSHIFTASSIGN, /* <<= */ + SL_PP_LSHIFT, /* << */ + SL_PP_LESSEQUAL, /* <= */ + SL_PP_LESS, /* < */ + SL_PP_RSHIFTASSIGN, /* >>= */ + SL_PP_RSHIFT, /* >> */ + SL_PP_GREATEREQUAL, /* >= */ + SL_PP_GREATER, /* > */ + SL_PP_EQUAL, /* == */ + SL_PP_ASSIGN, /* = */ + SL_PP_AND, /* && */ + SL_PP_BITANDASSIGN, /* &= */ + SL_PP_BITAND, /* & */ + SL_PP_XOR, /* ^^ */ + SL_PP_BITXORASSIGN, /* ^= */ + SL_PP_BITXOR, /* ^ */ + SL_PP_OR, /* || */ + SL_PP_BITORASSIGN, /* |= */ + SL_PP_BITOR, /* | */ + SL_PP_QUESTION, /* ? */ + SL_PP_COLON, /* : */ + + SL_PP_IDENTIFIER, + + SL_PP_NUMBER, + + SL_PP_OTHER, + + SL_PP_EOF +}; + +union sl_pp_token_data { + char *identifier; + char *number; + char other; +}; + +struct sl_pp_token_info { + enum sl_pp_token token; + union sl_pp_token_data data; +}; + +int +sl_pp_tokenise(const char *input, + struct sl_pp_token_info **output); + +#endif /* SL_PP_TOKEN_H */ -- cgit v1.2.3 From 229e72956ca6844647bd64d864716b8e21aff89b Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 13 Jun 2009 13:43:22 +0200 Subject: glsl: Parse optional version directive. --- src/glsl/pp/SConscript | 1 + src/glsl/pp/sl_pp_version.c | 150 ++++++++++++++++++++++++++++++++++++++++++++ src/glsl/pp/sl_pp_version.h | 39 ++++++++++++ 3 files changed, 190 insertions(+) create mode 100644 src/glsl/pp/sl_pp_version.c create mode 100644 src/glsl/pp/sl_pp_version.h (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/SConscript b/src/glsl/pp/SConscript index a08f5cf6321..0bc519759d0 100644 --- a/src/glsl/pp/SConscript +++ b/src/glsl/pp/SConscript @@ -10,6 +10,7 @@ glsl = env.StaticLibrary( source = [ 'sl_pp_purify.c', 'sl_pp_token.c', + 'sl_pp_version.c', ], ) Export('glsl') diff --git a/src/glsl/pp/sl_pp_version.c b/src/glsl/pp/sl_pp_version.c new file mode 100644 index 00000000000..f4b4b829d1e --- /dev/null +++ b/src/glsl/pp/sl_pp_version.c @@ -0,0 +1,150 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "sl_pp_version.h" + + +static int +_parse_integer(const char *input, + unsigned int *number) +{ + unsigned int n = 0; + + while (*input >= '0' && *input <= '9') { + if (n * 10 < n) { + /* Overflow. */ + return -1; + } + + n = n * 10 + (*input++ - '0'); + } + + if (*input != '\0') { + /* Invalid decimal number. */ + return -1; + } + + *number = n; + return 0; +} + + +int +sl_pp_version(const struct sl_pp_token_info *input, + unsigned int *version, + unsigned int *tokens_eaten) +{ + unsigned int i = 0; + int found_hash = 0; + int found_version = 0; + int found_number = 0; + + /* Default values if `#version' is not present. */ + *version = 110; + *tokens_eaten = 0; + + /* Skip whitespace and newlines and seek for hash. */ + while (!found_hash) { + switch (input[i].token) { + case SL_PP_WHITESPACE: + case SL_PP_NEWLINE: + i++; + break; + + case SL_PP_HASH: + i++; + found_hash = 1; + break; + + default: + return 0; + } + } + + /* Skip whitespace and seek for `version'. */ + while (!found_version) { + switch (input[i].token) { + case SL_PP_WHITESPACE: + i++; + break; + + case SL_PP_IDENTIFIER: + if (strcmp(input[i].data.identifier, "version")) { + return 0; + } + i++; + found_version = 1; + break; + + default: + return 0; + } + } + + /* Skip whitespace and seek for version number. */ + while (!found_number) { + switch (input[i].token) { + case SL_PP_WHITESPACE: + i++; + break; + + case SL_PP_NUMBER: + if (_parse_integer(input[i].data.number, version)) { + /* Expected version number. */ + return -1; + } + i++; + found_number = 1; + break; + + default: + /* Expected version number. */ + return -1; + } + } + + /* Skip whitespace and seek for either newline or eof. */ + for (;;) { + switch (input[i].token) { + case SL_PP_WHITESPACE: + i++; + break; + + case SL_PP_NEWLINE: + case SL_PP_EOF: + i++; + *tokens_eaten = i; + return 0; + + default: + /* Expected end of line. */ + return -1; + } + } + + /* Should not get here. */ +} diff --git a/src/glsl/pp/sl_pp_version.h b/src/glsl/pp/sl_pp_version.h new file mode 100644 index 00000000000..7deee1a1349 --- /dev/null +++ b/src/glsl/pp/sl_pp_version.h @@ -0,0 +1,39 @@ +/************************************************************************** + * + * 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_VERSION_H +#define SL_PP_VERSION_H + +#include "sl_pp_token.h" + + +int +sl_pp_version(const struct sl_pp_token_info *input, + unsigned int *version, + unsigned int *tokens_eaten); + +#endif /* SL_PP_VERSION_H */ -- cgit v1.2.3 From 474f754282c06014fa0f687c08f4e97323166f83 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 13 Jun 2009 13:50:45 +0200 Subject: glsl: Raise an error on an unfinished comment block. --- src/glsl/pp/sl_pp_purify.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_purify.c b/src/glsl/pp/sl_pp_purify.c index 7fbfc78d426..ded4dc8963b 100644 --- a/src/glsl/pp/sl_pp_purify.c +++ b/src/glsl/pp/sl_pp_purify.c @@ -152,6 +152,9 @@ _purify_comment(const char *input, return eaten; } } + if (next == '\0') { + return 0; + } } } } @@ -171,8 +174,13 @@ sl_pp_purify(const char *input, for (;;) { char c; + unsigned int eaten; - input += _purify_comment(input, &c); + eaten = _purify_comment(input, &c); + if (!eaten) { + return -1; + } + input += eaten; if (out_len >= out_max) { unsigned int new_max = out_max; -- cgit v1.2.3 From b4e92367f33c8bdd14337ced63abe82685f08cb3 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 15 Jun 2009 09:50:48 +0200 Subject: glsl: Allow for multiple version statements. --- src/glsl/pp/sl_pp_version.c | 144 +++++++++++++++++++++++--------------------- 1 file changed, 76 insertions(+), 68 deletions(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_version.c b/src/glsl/pp/sl_pp_version.c index f4b4b829d1e..e743a098417 100644 --- a/src/glsl/pp/sl_pp_version.c +++ b/src/glsl/pp/sl_pp_version.c @@ -59,90 +59,98 @@ sl_pp_version(const struct sl_pp_token_info *input, unsigned int *tokens_eaten) { unsigned int i = 0; - int found_hash = 0; - int found_version = 0; - int found_number = 0; /* Default values if `#version' is not present. */ *version = 110; *tokens_eaten = 0; - /* Skip whitespace and newlines and seek for hash. */ - while (!found_hash) { - switch (input[i].token) { - case SL_PP_WHITESPACE: - case SL_PP_NEWLINE: - i++; - break; - - case SL_PP_HASH: - i++; - found_hash = 1; - break; - - default: - return 0; + /* There can be multiple `#version' directives present. + * Accept the value of the last one. + */ + for (;;) { + int found_hash = 0; + int found_version = 0; + int found_number = 0; + int found_end = 0; + + /* Skip whitespace and newlines and seek for hash. */ + while (!found_hash) { + switch (input[i].token) { + case SL_PP_WHITESPACE: + case SL_PP_NEWLINE: + i++; + break; + + case SL_PP_HASH: + i++; + found_hash = 1; + break; + + default: + return 0; + } } - } - /* Skip whitespace and seek for `version'. */ - while (!found_version) { - switch (input[i].token) { - case SL_PP_WHITESPACE: - i++; - break; - - case SL_PP_IDENTIFIER: - if (strcmp(input[i].data.identifier, "version")) { + /* Skip whitespace and seek for `version'. */ + while (!found_version) { + switch (input[i].token) { + case SL_PP_WHITESPACE: + i++; + break; + + case SL_PP_IDENTIFIER: + if (strcmp(input[i].data.identifier, "version")) { + return 0; + } + i++; + found_version = 1; + break; + + default: return 0; } - i++; - found_version = 1; - break; - - default: - return 0; } - } - - /* Skip whitespace and seek for version number. */ - while (!found_number) { - switch (input[i].token) { - case SL_PP_WHITESPACE: - i++; - break; - case SL_PP_NUMBER: - if (_parse_integer(input[i].data.number, version)) { + /* Skip whitespace and seek for version number. */ + while (!found_number) { + switch (input[i].token) { + case SL_PP_WHITESPACE: + i++; + break; + + case SL_PP_NUMBER: + if (_parse_integer(input[i].data.number, version)) { + /* Expected version number. */ + return -1; + } + i++; + found_number = 1; + break; + + default: /* Expected version number. */ return -1; } - i++; - found_number = 1; - break; - - default: - /* Expected version number. */ - return -1; } - } - /* Skip whitespace and seek for either newline or eof. */ - for (;;) { - switch (input[i].token) { - case SL_PP_WHITESPACE: - i++; - break; - - case SL_PP_NEWLINE: - case SL_PP_EOF: - i++; - *tokens_eaten = i; - return 0; - - default: - /* Expected end of line. */ - return -1; + /* Skip whitespace and seek for either newline or eof. */ + while (!found_end) { + switch (input[i].token) { + case SL_PP_WHITESPACE: + i++; + break; + + case SL_PP_NEWLINE: + case SL_PP_EOF: + i++; + *tokens_eaten = i; + found_end = 1; + break; + + default: + /* Expected end of line. */ + return -1; + } } } -- cgit v1.2.3 From 5d26deef981d201573252125a8a106b87f66a73c Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 15 Jun 2009 10:44:57 +0200 Subject: glsl: Remove bogus sl_pp_directive.h include. --- src/glsl/pp/sl_pp_token.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_token.c b/src/glsl/pp/sl_pp_token.c index 6402c6a95b2..4001fe54c8b 100644 --- a/src/glsl/pp/sl_pp_token.c +++ b/src/glsl/pp/sl_pp_token.c @@ -26,7 +26,6 @@ **************************************************************************/ #include -#include "sl_pp_directive.h" #include "sl_pp_token.h" -- cgit v1.2.3 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/SConscript | 1 + src/glsl/pp/sl_pp_process.c | 157 ++++++++++++++++++++++++++++++++++++++++++++ src/glsl/pp/sl_pp_process.h | 38 +++++++++++ 3 files changed, 196 insertions(+) create mode 100644 src/glsl/pp/sl_pp_process.c create mode 100644 src/glsl/pp/sl_pp_process.h (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/SConscript b/src/glsl/pp/SConscript index 0bc519759d0..0be21147946 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_process.c', 'sl_pp_purify.c', 'sl_pp_token.c', 'sl_pp_version.c', diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c new file mode 100644 index 00000000000..56b8fab52a0 --- /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; +} diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h new file mode 100644 index 00000000000..6e930ca567a --- /dev/null +++ b/src/glsl/pp/sl_pp_process.h @@ -0,0 +1,38 @@ +/************************************************************************** + * + * 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_PROCESS_H +#define SL_PP_PROCESS_H + +#include "sl_pp_token.h" + + +int +sl_pp_process(const struct sl_pp_token_info *input, + struct sl_pp_token_info **output); + +#endif /* SL_PP_PROCESS_H */ -- 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') diff --git a/src/glsl/apps/process.c b/src/glsl/apps/process.c index 6e2828aa411..abcf1a92b83 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 2631b829986..b5092ba35f6 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 b49395ba97f..c56ae9dde9a 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 0be21147946..3d4a1cb967c 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 00000000000..71712de1fe2 --- /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 00000000000..3a1e215625c --- /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 56b8fab52a0..a97c750de46 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 6e930ca567a..b71ee4466a1 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 4001fe54c8b..e200b961aaf 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 5e7fae7d29c..c801804ae6e 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 e743a098417..89c3cfa1a5b 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 7deee1a1349..cee9f55bc6c 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') diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index 3a1e215625c..e4686b89e33 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 a97c750de46..1005c501050 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 b71ee4466a1..d6401de960e 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') diff --git a/src/glsl/pp/SConscript b/src/glsl/pp/SConscript index 3d4a1cb967c..1fde3dfccf3 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 71712de1fe2..8722376ae52 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 e4686b89e33..cb81f73ab9e 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 00000000000..5ce0f0551b8 --- /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 00000000000..eed09783040 --- /dev/null +++ b/src/glsl/pp/sl_pp_macro.c @@ -0,0 +1,51 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include +#include "sl_pp_macro.h" + + +void +sl_pp_macro_free(struct sl_pp_macro *macro) +{ + while (macro) { + struct sl_pp_macro *next_macro = macro->next; + struct sl_pp_macro_formal_arg *arg = macro->arg; + + while (arg) { + struct sl_pp_macro_formal_arg *next_arg = arg->next; + + free(arg); + arg = next_arg; + } + + free(macro->body); + + free(macro); + macro = next_macro; + } +} diff --git a/src/glsl/pp/sl_pp_macro.h b/src/glsl/pp/sl_pp_macro.h new file mode 100644 index 00000000000..4ebbff55906 --- /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 1005c501050..2a375df71a4 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 d6401de960e..f7df9a2850a 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 5e8e3cddae9b2797cfa525c643c701debe2f4c04 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 21 Jun 2009 17:03:15 +0200 Subject: glsl: Rename sl_pp_context_add_str to sl_pp_context_add_unique_str. Return the same offset for same strings. Allows to compare strings by comparing their's offsets. --- src/glsl/pp/sl_pp_context.c | 20 +++++++++++++++++--- src/glsl/pp/sl_pp_context.h | 4 ++-- src/glsl/pp/sl_pp_token.c | 4 ++-- src/glsl/pp/sl_pp_token.h | 2 ++ 4 files changed, 23 insertions(+), 7 deletions(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index 8722376ae52..6d3076b8697 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -43,14 +43,28 @@ sl_pp_context_destroy(struct sl_pp_context *context) } int -sl_pp_context_add_str(struct sl_pp_context *context, - const char *str) +sl_pp_context_add_unique_str(struct sl_pp_context *context, + const char *str) { unsigned int size; - unsigned int offset; + unsigned int offset = 0; size = strlen(str) + 1; + /* Find out if this is a unique string. */ + while (offset < context->cstr_pool_len) { + const char *str2; + unsigned int size2; + + str2 = &context->cstr_pool[offset]; + size2 = strlen(str2) + 1; + if (size == size2 && !memcmp(str, str2, size - 1)) { + return offset; + } + + offset += size2; + } + 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); diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index cb81f73ab9e..56f70777507 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -46,8 +46,8 @@ void sl_pp_context_destroy(struct sl_pp_context *context); int -sl_pp_context_add_str(struct sl_pp_context *context, - const char *str); +sl_pp_context_add_unique_str(struct sl_pp_context *context, + const char *str); const char * sl_pp_context_cstr(const struct sl_pp_context *context, diff --git a/src/glsl/pp/sl_pp_token.c b/src/glsl/pp/sl_pp_token.c index e200b961aaf..68c8fbe2ec4 100644 --- a/src/glsl/pp/sl_pp_token.c +++ b/src/glsl/pp/sl_pp_token.c @@ -53,7 +53,7 @@ _tokenise_identifier(struct sl_pp_context *context, } identifier[i++] = '\0'; - info->data.identifier = sl_pp_context_add_str(context, identifier); + info->data.identifier = sl_pp_context_add_unique_str(context, identifier); if (info->data.identifier == -1) { return -1; } @@ -91,7 +91,7 @@ _tokenise_number(struct sl_pp_context *context, } number[i++] = '\0'; - info->data.number = sl_pp_context_add_str(context, number); + info->data.number = sl_pp_context_add_unique_str(context, number); if (info->data.number == -1) { return -1; } diff --git a/src/glsl/pp/sl_pp_token.h b/src/glsl/pp/sl_pp_token.h index c801804ae6e..a53720be802 100644 --- a/src/glsl/pp/sl_pp_token.h +++ b/src/glsl/pp/sl_pp_token.h @@ -28,6 +28,8 @@ #ifndef SL_PP_TOKEN_H #define SL_PP_TOKEN_H +#include "sl_pp_context.h" + enum sl_pp_token { SL_PP_WHITESPACE, -- 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') diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c index 5ce0f0551b8..39d14350641 100644 --- a/src/glsl/pp/sl_pp_define.c +++ b/src/glsl/pp/sl_pp_define.c @@ -48,6 +48,8 @@ _parse_formal_args(const struct sl_pp_token_info *input, { struct sl_pp_macro_formal_arg **arg; + macro->num_args = 0; + skip_whitespace(input, first, last); if (*first < last) { if (input[*first].token == SL_PP_RPAREN) { @@ -78,6 +80,8 @@ _parse_formal_args(const struct sl_pp_token_info *input, (**arg).next = NULL; arg = &(**arg).next; + macro->num_args++; + skip_whitespace(input, first, last); if (*first < last) { if (input[*first].token == SL_PP_COMMA) { @@ -104,7 +108,12 @@ sl_pp_process_define(struct sl_pp_context *context, unsigned int last, struct sl_pp_macro *macro) { + unsigned int i; + unsigned int body_len; + unsigned int j; + macro->name = -1; + macro->num_args = -1; macro->arg = NULL; macro->body = NULL; macro->next = NULL; @@ -131,26 +140,25 @@ sl_pp_process_define(struct sl_pp_context *context, } } - /* Trim whitespace from the left side. */ - skip_whitespace(input, &first, last); + /* Calculate body size, trim out whitespace, make room for EOF. */ + body_len = 1; + for (i = first; i < last; i++) { + if (input[i].token != SL_PP_WHITESPACE) { + body_len++; + } + } - /* Trom whitespace from the right side. */ - while (first < last && input[last - 1].token == SL_PP_WHITESPACE) { - last--; + macro->body = malloc(sizeof(struct sl_pp_token_info) * body_len); + if (!macro->body) { + return -1; } - /* All that is left between first and last is the macro definition. */ - macro->body_len = last - first; - if (macro->body_len) { - macro->body = malloc(sizeof(struct sl_pp_token_info) * macro->body_len); - if (!macro->body) { - return -1; + for (j = 0, i = first; i < last; i++) { + if (input[i].token != SL_PP_WHITESPACE) { + macro->body[j++] = input[i]; } - - memcpy(macro->body, - &input[first], - sizeof(struct sl_pp_token_info) * macro->body_len); } + macro->body[j++].token = SL_PP_EOF; return 0; } diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index eed09783040..82591b9d77d 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -27,8 +27,18 @@ #include #include "sl_pp_macro.h" +#include "sl_pp_process.h" +static void +skip_whitespace(const struct sl_pp_token_info *input, + unsigned int *pi) +{ + while (input[*pi].token == SL_PP_WHITESPACE) { + (*pi)++; + } +} + void sl_pp_macro_free(struct sl_pp_macro *macro) { @@ -49,3 +59,197 @@ sl_pp_macro_free(struct sl_pp_macro *macro) macro = next_macro; } } + +int +sl_pp_macro_expand(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int *pi, + struct sl_pp_macro *local, + struct sl_pp_process_state *state) +{ + int macro_name; + struct sl_pp_macro *macro = NULL; + struct sl_pp_macro *actual_arg = NULL; + unsigned int j; + + if (input[*pi].token != SL_PP_IDENTIFIER) { + return -1; + } + + macro_name = input[*pi].data.identifier; + + if (local) { + for (macro = local; macro; macro = macro->next) { + if (macro->name == macro_name) { + break; + } + } + } + + if (!macro) { + for (macro = context->macro; macro; macro = macro->next) { + if (macro->name == macro_name) { + break; + } + } + } + + if (!macro) { + if (sl_pp_process_out(state, &input[*pi])) { + return -1; + } + (*pi)++; + return 0; + } + + (*pi)++; + + if (macro->num_args >= 0) { + skip_whitespace(input, pi); + if (input[*pi].token != SL_PP_LPAREN) { + return -1; + } + (*pi)++; + skip_whitespace(input, pi); + } + + if (macro->num_args > 0) { + struct sl_pp_macro_formal_arg *formal_arg = macro->arg; + struct sl_pp_macro **pmacro = &actual_arg; + + for (j = 0; j < (unsigned int)macro->num_args; j++) { + unsigned int body_len; + unsigned int i; + int done = 0; + unsigned int paren_nesting = 0; + unsigned int k; + + *pmacro = malloc(sizeof(struct sl_pp_macro)); + if (!*pmacro) { + return -1; + } + + (**pmacro).name = formal_arg->name; + (**pmacro).num_args = -1; + (**pmacro).arg = NULL; + (**pmacro).body = NULL; + (**pmacro).next = NULL; + + body_len = 1; + for (i = *pi; !done; i++) { + switch (input[i].token) { + case SL_PP_WHITESPACE: + break; + + case SL_PP_COMMA: + if (!paren_nesting) { + if (j < (unsigned int)macro->num_args - 1) { + done = 1; + } else { + return -1; + } + } else { + body_len++; + } + break; + + case SL_PP_LPAREN: + paren_nesting++; + body_len++; + break; + + case SL_PP_RPAREN: + if (!paren_nesting) { + if (j == (unsigned int)macro->num_args - 1) { + done = 1; + } else { + return -1; + } + } else { + paren_nesting--; + body_len++; + } + break; + + case SL_PP_EOF: + return -1; + + default: + body_len++; + } + } + + (**pmacro).body = malloc(sizeof(struct sl_pp_token_info) * body_len); + if (!(**pmacro).body) { + return -1; + } + + for (done = 0, k = 0, i = *pi; !done; i++) { + switch (input[i].token) { + case SL_PP_WHITESPACE: + break; + + case SL_PP_COMMA: + if (!paren_nesting && j < (unsigned int)macro->num_args - 1) { + done = 1; + } else { + (**pmacro).body[k++] = input[i]; + } + break; + + case SL_PP_LPAREN: + paren_nesting++; + (**pmacro).body[k++] = input[i]; + break; + + case SL_PP_RPAREN: + if (!paren_nesting && j == (unsigned int)macro->num_args - 1) { + done = 1; + } else { + paren_nesting--; + (**pmacro).body[k++] = input[i]; + } + break; + + default: + (**pmacro).body[k++] = input[i]; + } + } + + (**pmacro).body[k++].token = SL_PP_EOF; + (*pi) = i; + + formal_arg = formal_arg->next; + pmacro = &(**pmacro).next; + } + } + + /* Right paren for non-empty argument list has already been eaten. */ + if (macro->num_args == 0) { + skip_whitespace(input, pi); + if (input[*pi].token != SL_PP_RPAREN) { + return -1; + } + (*pi)++; + } + + for (j = 0;;) { + switch (macro->body[j].token) { + case SL_PP_IDENTIFIER: + if (sl_pp_macro_expand(context, macro->body, &j, actual_arg, state)) { + return -1; + } + break; + + case SL_PP_EOF: + sl_pp_macro_free(actual_arg); + return 0; + + default: + if (sl_pp_process_out(state, ¯o->body[j])) { + return -1; + } + j++; + } + } +} diff --git a/src/glsl/pp/sl_pp_macro.h b/src/glsl/pp/sl_pp_macro.h index 4ebbff55906..eeb338eec45 100644 --- a/src/glsl/pp/sl_pp_macro.h +++ b/src/glsl/pp/sl_pp_macro.h @@ -38,13 +38,20 @@ struct sl_pp_macro_formal_arg { struct sl_pp_macro { int name; + int num_args; struct sl_pp_macro_formal_arg *arg; struct sl_pp_token_info *body; - unsigned int body_len; struct sl_pp_macro *next; }; void sl_pp_macro_free(struct sl_pp_macro *macro); +int +sl_pp_macro_expand(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int *pi, + struct sl_pp_macro *local, + struct sl_pp_process_state *state); + #endif /* SL_PP_MACRO_H */ diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index 2a375df71a4..e930966604c 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -39,16 +39,16 @@ skip_whitespace(const struct sl_pp_token_info *input, } -struct process_state { +struct sl_pp_process_state { struct sl_pp_token_info *out; unsigned int out_len; unsigned int out_max; }; -static int -out_token(struct process_state *state, - const struct sl_pp_token_info *token) +int +sl_pp_process_out(struct sl_pp_process_state *state, + const struct sl_pp_token_info *token) { if (state->out_len >= state->out_max) { unsigned int new_max = state->out_max; @@ -72,7 +72,6 @@ out_token(struct process_state *state, return 0; } - int sl_pp_process(struct sl_pp_context *context, const struct sl_pp_token_info *input, @@ -81,7 +80,7 @@ sl_pp_process(struct sl_pp_context *context, unsigned int i = 0; int found_eof = 0; struct sl_pp_macro **macro; - struct process_state state; + struct sl_pp_process_state state; macro = &context->macro; memset(&state, 0, sizeof(state)); @@ -110,7 +109,7 @@ sl_pp_process(struct sl_pp_context *context, switch (input[i].token) { case SL_PP_NEWLINE: /* Preserve newline just for the sake of line numbering. */ - if (out_token(&state, &input[i])) { + if (sl_pp_process_out(&state, &input[i])) { return -1; } i++; @@ -118,7 +117,7 @@ sl_pp_process(struct sl_pp_context *context, break; case SL_PP_EOF: - if (out_token(&state, &input[i])) { + if (sl_pp_process_out(&state, &input[i])) { return -1; } i++; @@ -152,7 +151,7 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_NEWLINE: /* Empty directive. */ - if (out_token(&state, &input[i])) { + if (sl_pp_process_out(&state, &input[i])) { return -1; } i++; @@ -160,7 +159,7 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_EOF: /* Empty directive. */ - if (out_token(&state, &input[i])) { + if (sl_pp_process_out(&state, &input[i])) { return -1; } i++; @@ -182,7 +181,7 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_NEWLINE: /* Preserve newline just for the sake of line numbering. */ - if (out_token(&state, &input[i])) { + if (sl_pp_process_out(&state, &input[i])) { return -1; } i++; @@ -190,7 +189,7 @@ sl_pp_process(struct sl_pp_context *context, break; case SL_PP_EOF: - if (out_token(&state, &input[i])) { + if (sl_pp_process_out(&state, &input[i])) { return -1; } i++; @@ -198,8 +197,14 @@ sl_pp_process(struct sl_pp_context *context, found_eol = 1; break; + case SL_PP_IDENTIFIER: + if (sl_pp_macro_expand(context, input, &i, NULL, &state)) { + return -1; + } + break; + default: - if (out_token(&state, &input[i])) { + if (sl_pp_process_out(&state, &input[i])) { return -1; } i++; diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h index f7df9a2850a..37cdc4c9a78 100644 --- a/src/glsl/pp/sl_pp_process.h +++ b/src/glsl/pp/sl_pp_process.h @@ -33,6 +33,8 @@ #include "sl_pp_token.h" +struct sl_pp_process_state; + int sl_pp_process(struct sl_pp_context *context, const struct sl_pp_token_info *input, @@ -45,4 +47,8 @@ sl_pp_process_define(struct sl_pp_context *context, unsigned int last, struct sl_pp_macro *macro); +int +sl_pp_process_out(struct sl_pp_process_state *state, + const struct sl_pp_token_info *token); + #endif /* SL_PP_PROCESS_H */ -- cgit v1.2.3 From 2dad8ed9d68289ba25a4023da12fc5ddf6a621dd Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 22 Jun 2009 09:14:14 +0200 Subject: glsl: Centralise sl_pp_macro constructor. --- src/glsl/pp/sl_pp_define.c | 6 ------ src/glsl/pp/sl_pp_macro.c | 29 +++++++++++++++++++---------- src/glsl/pp/sl_pp_macro.h | 5 ++++- src/glsl/pp/sl_pp_process.c | 2 +- 4 files changed, 24 insertions(+), 18 deletions(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c index 39d14350641..e8a23fedcd8 100644 --- a/src/glsl/pp/sl_pp_define.c +++ b/src/glsl/pp/sl_pp_define.c @@ -112,12 +112,6 @@ sl_pp_process_define(struct sl_pp_context *context, unsigned int body_len; unsigned int j; - macro->name = -1; - macro->num_args = -1; - macro->arg = NULL; - macro->body = NULL; - macro->next = NULL; - if (first < last && input[first].token == SL_PP_IDENTIFIER) { macro->name = input[first].data.identifier; first++; diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index 82591b9d77d..0138270c67b 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -30,13 +30,17 @@ #include "sl_pp_process.h" -static void -skip_whitespace(const struct sl_pp_token_info *input, - unsigned int *pi) +struct sl_pp_macro * +sl_pp_macro_new(void) { - while (input[*pi].token == SL_PP_WHITESPACE) { - (*pi)++; + struct sl_pp_macro *macro; + + macro = calloc(1, sizeof(struct sl_pp_macro)); + if (macro) { + macro->name = -1; + macro->num_args = -1; } + return macro; } void @@ -60,6 +64,15 @@ sl_pp_macro_free(struct sl_pp_macro *macro) } } +static void +skip_whitespace(const struct sl_pp_token_info *input, + unsigned int *pi) +{ + while (input[*pi].token == SL_PP_WHITESPACE) { + (*pi)++; + } +} + int sl_pp_macro_expand(struct sl_pp_context *context, const struct sl_pp_token_info *input, @@ -124,16 +137,12 @@ sl_pp_macro_expand(struct sl_pp_context *context, unsigned int paren_nesting = 0; unsigned int k; - *pmacro = malloc(sizeof(struct sl_pp_macro)); + *pmacro = sl_pp_macro_new(); if (!*pmacro) { return -1; } (**pmacro).name = formal_arg->name; - (**pmacro).num_args = -1; - (**pmacro).arg = NULL; - (**pmacro).body = NULL; - (**pmacro).next = NULL; body_len = 1; for (i = *pi; !done; i++) { diff --git a/src/glsl/pp/sl_pp_macro.h b/src/glsl/pp/sl_pp_macro.h index eeb338eec45..63edd21aa24 100644 --- a/src/glsl/pp/sl_pp_macro.h +++ b/src/glsl/pp/sl_pp_macro.h @@ -38,12 +38,15 @@ struct sl_pp_macro_formal_arg { struct sl_pp_macro { int name; - int num_args; + int num_args; /* -1 means no args, 0 means `()' */ struct sl_pp_macro_formal_arg *arg; struct sl_pp_token_info *body; struct sl_pp_macro *next; }; +struct sl_pp_macro * +sl_pp_macro_new(void); + void sl_pp_macro_free(struct sl_pp_macro *macro); diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index e930966604c..baffaf2cd95 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -133,7 +133,7 @@ sl_pp_process(struct sl_pp_context *context, last = i - 1; if (!strcmp(name, "define")) { - *macro = malloc(sizeof(struct sl_pp_macro)); + *macro = sl_pp_macro_new(); if (!*macro) { return -1; } -- cgit v1.2.3 From 3bb446ba6e890bc3f60a34318a5a0fe860e53cbb Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 26 Jun 2009 10:59:25 +0200 Subject: glsl: Add expression interpreter. --- src/glsl/pp/SConscript | 1 + src/glsl/pp/sl_pp_expression.c | 407 +++++++++++++++++++++++++++++++++++++++++ src/glsl/pp/sl_pp_expression.h | 40 ++++ 3 files changed, 448 insertions(+) create mode 100644 src/glsl/pp/sl_pp_expression.c create mode 100644 src/glsl/pp/sl_pp_expression.h (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/SConscript b/src/glsl/pp/SConscript index 1fde3dfccf3..623d2362ce0 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_expression.c', 'sl_pp_macro.c', 'sl_pp_process.c', 'sl_pp_purify.c', diff --git a/src/glsl/pp/sl_pp_expression.c b/src/glsl/pp/sl_pp_expression.c new file mode 100644 index 00000000000..a692430abbf --- /dev/null +++ b/src/glsl/pp/sl_pp_expression.c @@ -0,0 +1,407 @@ +/************************************************************************** + * + * 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" + + +struct parse_context { + struct sl_pp_context *context; + const struct sl_pp_token_info *input; +}; + +static int +_parse_or(struct parse_context *ctx, + int *result); + +static int +_parse_primary(struct parse_context *ctx, + int *result) +{ + if (ctx->input->token == SL_PP_NUMBER) { + *result = atoi(sl_pp_context_cstr(ctx->context, ctx->input->data.number)); + ctx->input++; + } else { + if (ctx->input->token != SL_PP_LPAREN) { + return -1; + } + ctx->input++; + if (_parse_or(ctx, result)) { + return -1; + } + if (ctx->input->token != SL_PP_RPAREN) { + return -1; + } + ctx->input++; + } + return 0; +} + +static int +_parse_unary(struct parse_context *ctx, + int *result) +{ + if (!_parse_primary(ctx, result)) { + return 0; + } + + switch (ctx->input->token) { + case SL_PP_PLUS: + ctx->input++; + if (_parse_unary(ctx, result)) { + return -1; + } + *result = +*result; + break; + + case SL_PP_MINUS: + ctx->input++; + if (_parse_unary(ctx, result)) { + return -1; + } + *result = -*result; + break; + + case SL_PP_NOT: + ctx->input++; + if (_parse_unary(ctx, result)) { + return -1; + } + *result = !*result; + break; + + case SL_PP_BITNOT: + ctx->input++; + if (_parse_unary(ctx, result)) { + return -1; + } + *result = ~*result; + break; + + default: + return -1; + } + + return 0; +} + +static int +_parse_multiplicative(struct parse_context *ctx, + int *result) +{ + if (_parse_unary(ctx, result)) { + return -1; + } + for (;;) { + int right; + + switch (ctx->input->token) { + case SL_PP_STAR: + ctx->input++; + if (_parse_unary(ctx, &right)) { + return -1; + } + *result = *result * right; + break; + + case SL_PP_SLASH: + ctx->input++; + if (_parse_unary(ctx, &right)) { + return -1; + } + *result = *result / right; + break; + + case SL_PP_MODULO: + ctx->input++; + if (_parse_unary(ctx, &right)) { + return -1; + } + *result = *result % right; + break; + + default: + return 0; + } + } +} + +static int +_parse_additive(struct parse_context *ctx, + int *result) +{ + if (_parse_multiplicative(ctx, result)) { + return -1; + } + for (;;) { + int right; + + switch (ctx->input->token) { + case SL_PP_PLUS: + ctx->input++; + if (_parse_multiplicative(ctx, &right)) { + return -1; + } + *result = *result + right; + break; + + case SL_PP_MINUS: + ctx->input++; + if (_parse_multiplicative(ctx, &right)) { + return -1; + } + *result = *result - right; + break; + + default: + return 0; + } + } +} + +static int +_parse_shift(struct parse_context *ctx, + int *result) +{ + if (_parse_additive(ctx, result)) { + return -1; + } + for (;;) { + int right; + + switch (ctx->input->token) { + case SL_PP_LSHIFT: + ctx->input++; + if (_parse_additive(ctx, &right)) { + return -1; + } + *result = *result << right; + break; + + case SL_PP_RSHIFT: + ctx->input++; + if (_parse_additive(ctx, &right)) { + return -1; + } + *result = *result >> right; + break; + + default: + return 0; + } + } +} + +static int +_parse_relational(struct parse_context *ctx, + int *result) +{ + if (_parse_shift(ctx, result)) { + return -1; + } + for (;;) { + int right; + + switch (ctx->input->token) { + case SL_PP_LESSEQUAL: + ctx->input++; + if (_parse_shift(ctx, &right)) { + return -1; + } + *result = *result <= right; + break; + + case SL_PP_GREATEREQUAL: + ctx->input++; + if (_parse_shift(ctx, &right)) { + return -1; + } + *result = *result >= right; + break; + + case SL_PP_LESS: + ctx->input++; + if (_parse_shift(ctx, &right)) { + return -1; + } + *result = *result < right; + break; + + case SL_PP_GREATER: + ctx->input++; + if (_parse_shift(ctx, &right)) { + return -1; + } + *result = *result > right; + break; + + default: + return 0; + } + } +} + +static int +_parse_equality(struct parse_context *ctx, + int *result) +{ + if (_parse_relational(ctx, result)) { + return -1; + } + for (;;) { + int right; + + switch (ctx->input->token) { + case SL_PP_EQUAL: + ctx->input++; + if (_parse_relational(ctx, &right)) { + return -1; + } + *result = *result == right; + break; + + case SL_PP_NOTEQUAL: + ctx->input++; + if (_parse_relational(ctx, &right)) { + return -1; + } + *result = *result != right; + break; + + default: + return 0; + } + } +} + +static int +_parse_bitand(struct parse_context *ctx, + int *result) +{ + if (_parse_equality(ctx, result)) { + return -1; + } + while (ctx->input->token == SL_PP_BITAND) { + int right; + + ctx->input++; + if (_parse_equality(ctx, &right)) { + return -1; + } + *result = *result & right; + } + return 0; +} + +static int +_parse_xor(struct parse_context *ctx, + int *result) +{ + if (_parse_bitand(ctx, result)) { + return -1; + } + while (ctx->input->token == SL_PP_XOR) { + int right; + + ctx->input++; + if (_parse_bitand(ctx, &right)) { + return -1; + } + *result = *result ^ right; + } + return 0; +} + +static int +_parse_bitor(struct parse_context *ctx, + int *result) +{ + if (_parse_xor(ctx, result)) { + return -1; + } + while (ctx->input->token == SL_PP_BITOR) { + int right; + + ctx->input++; + if (_parse_xor(ctx, &right)) { + return -1; + } + *result = *result | right; + } + return 0; +} + +static int +_parse_and(struct parse_context *ctx, + int *result) +{ + if (_parse_bitor(ctx, result)) { + return -1; + } + while (ctx->input->token == SL_PP_AND) { + int right; + + ctx->input++; + if (_parse_bitor(ctx, &right)) { + return -1; + } + *result = *result && right; + } + return 0; +} + +static int +_parse_or(struct parse_context *ctx, + int *result) +{ + if (_parse_and(ctx, result)) { + return -1; + } + while (ctx->input->token == SL_PP_OR) { + int right; + + ctx->input++; + if (_parse_and(ctx, &right)) { + return -1; + } + *result = *result || right; + } + return 0; +} + +int +sl_pp_execute_expression(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + int *result) +{ + struct parse_context ctx; + + ctx.context = context; + ctx.input = input; + + return _parse_or(&ctx, result); +} diff --git a/src/glsl/pp/sl_pp_expression.h b/src/glsl/pp/sl_pp_expression.h new file mode 100644 index 00000000000..377d5b4cbd9 --- /dev/null +++ b/src/glsl/pp/sl_pp_expression.h @@ -0,0 +1,40 @@ +/************************************************************************** + * + * 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_EXPRESSION_H +#define SL_PP_EXPRESSION_H + +#include "sl_pp_context.h" +#include "sl_pp_token.h" + + +int +sl_pp_execute_expression(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + int *result); + +#endif /* SL_PP_EXPRESSION_H */ -- 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') diff --git a/src/glsl/pp/SConscript b/src/glsl/pp/SConscript index 623d2362ce0..c7718d1d8fd 100644 --- a/src/glsl/pp/SConscript +++ b/src/glsl/pp/SConscript @@ -11,6 +11,7 @@ glsl = env.StaticLibrary( 'sl_pp_context.c', 'sl_pp_define.c', 'sl_pp_expression.c', + 'sl_pp_if.c', 'sl_pp_macro.c', 'sl_pp_process.c', 'sl_pp_purify.c', diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index 6d3076b8697..1afe9a5d5e0 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -33,6 +33,8 @@ void sl_pp_context_init(struct sl_pp_context *context) { memset(context, 0, sizeof(struct sl_pp_context)); + context->if_ptr = SL_PP_MAX_IF_NESTING; + context->if_value = 1; } void diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index 56f70777507..e8200d55d7f 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -31,12 +31,18 @@ #include "sl_pp_macro.h" +#define SL_PP_MAX_IF_NESTING 64 + struct sl_pp_context { char *cstr_pool; unsigned int cstr_pool_max; unsigned int cstr_pool_len; struct sl_pp_macro *macro; + + unsigned int if_stack[SL_PP_MAX_IF_NESTING]; + unsigned int if_ptr; + int if_value; }; void diff --git a/src/glsl/pp/sl_pp_if.c b/src/glsl/pp/sl_pp_if.c new file mode 100644 index 00000000000..e331acc4cd5 --- /dev/null +++ b/src/glsl/pp/sl_pp_if.c @@ -0,0 +1,276 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include +#include "sl_pp_expression.h" +#include "sl_pp_process.h" + + +static int +_evaluate_if_stack(struct sl_pp_context *context) +{ + unsigned int i; + + for (i = context->if_ptr; i < SL_PP_MAX_IF_NESTING; i++) { + if (!(context->if_stack[i] & 1)) { + return 0; + } + } + return 1; +} + +static int +_parse_if(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last) +{ + unsigned int i; + struct sl_pp_process_state state; + struct sl_pp_token_info eof; + int result; + + if (!context->if_ptr) { + /* #if nesting too deep. */ + return -1; + } + + memset(&state, 0, sizeof(state)); + for (i = first; i < last;) { + switch (input[i].token) { + case SL_PP_WHITESPACE: + i++; + break; + + case SL_PP_IDENTIFIER: + if (sl_pp_macro_expand(context, input, &i, NULL, &state, 0)) { + free(state.out); + return -1; + } + break; + + default: + if (sl_pp_process_out(&state, &input[i])) { + free(state.out); + return -1; + } + i++; + } + } + + eof.token = SL_PP_EOF; + if (sl_pp_process_out(&state, &eof)) { + free(state.out); + return -1; + } + + if (sl_pp_execute_expression(context, state.out, &result)) { + free(state.out); + return -1; + } + + free(state.out); + + context->if_ptr--; + context->if_stack[context->if_ptr] = result ? 1 : 0; + context->if_value = _evaluate_if_stack(context); + + return 0; +} + +static int +_parse_else(struct sl_pp_context *context) +{ + if (context->if_ptr == SL_PP_MAX_IF_NESTING) { + /* No matching #if. */ + return -1; + } + + /* Bit b1 indicates we already went through #else. */ + if (context->if_stack[context->if_ptr] & 2) { + /* No matching #if. */ + return -1; + } + + /* Invert current condition value and mark that we are in the #else block. */ + context->if_stack[context->if_ptr] = (1 - (context->if_stack[context->if_ptr] & 1)) | 2; + context->if_value = _evaluate_if_stack(context); + + return 0; +} + +int +sl_pp_process_if(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last) +{ + return _parse_if(context, input, first, last); +} + +int +sl_pp_process_ifdef(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last) +{ + unsigned int i; + + if (!context->if_ptr) { + /* #if nesting too deep. */ + return -1; + } + + for (i = first; i < last; i++) { + switch (input[i].token) { + case SL_PP_IDENTIFIER: + { + struct sl_pp_macro *macro; + int macro_name = input[i].data.identifier; + int defined = 0; + + for (macro = context->macro; macro; macro = macro->next) { + if (macro->name == macro_name) { + defined = 1; + break; + } + } + + context->if_ptr--; + context->if_stack[context->if_ptr] = defined ? 1 : 0; + context->if_value = _evaluate_if_stack(context); + } + return 0; + + case SL_PP_WHITESPACE: + break; + + default: + /* Expected an identifier. */ + return -1; + } + } + + /* Expected an identifier. */ + return -1; +} + +int +sl_pp_process_ifndef(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last) +{ + unsigned int i; + + if (!context->if_ptr) { + /* #if nesting too deep. */ + return -1; + } + + for (i = first; i < last; i++) { + switch (input[i].token) { + case SL_PP_IDENTIFIER: + { + struct sl_pp_macro *macro; + int macro_name = input[i].data.identifier; + int defined = 0; + + for (macro = context->macro; macro; macro = macro->next) { + if (macro->name == macro_name) { + defined = 1; + break; + } + } + + context->if_ptr--; + context->if_stack[context->if_ptr] = defined ? 0 : 1; + context->if_value = _evaluate_if_stack(context); + } + return 0; + + case SL_PP_WHITESPACE: + break; + + default: + /* Expected an identifier. */ + return -1; + } + } + + /* Expected an identifier. */ + return -1; +} + +int +sl_pp_process_elif(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last) +{ + if (_parse_else(context)) { + return -1; + } + + if (context->if_stack[context->if_ptr] & 1) { + context->if_ptr++; + if (_parse_if(context, input, first, last)) { + return -1; + } + } + + /* We are still in the #if block. */ + context->if_stack[context->if_ptr] = context->if_stack[context->if_ptr] & ~2; + + return 0; +} + +int +sl_pp_process_else(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last) +{ + return _parse_else(context); +} + +int +sl_pp_process_endif(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last) +{ + if (context->if_ptr == SL_PP_MAX_IF_NESTING) { + /* No matching #if. */ + return -1; + } + + context->if_ptr++; + context->if_value = _evaluate_if_stack(context); + + return 0; +} diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index 0138270c67b..a8412f0651c 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -78,7 +78,8 @@ sl_pp_macro_expand(struct sl_pp_context *context, const struct sl_pp_token_info *input, unsigned int *pi, struct sl_pp_macro *local, - struct sl_pp_process_state *state) + struct sl_pp_process_state *state, + int mute) { int macro_name; struct sl_pp_macro *macro = NULL; @@ -108,8 +109,10 @@ sl_pp_macro_expand(struct sl_pp_context *context, } if (!macro) { - if (sl_pp_process_out(state, &input[*pi])) { - return -1; + if (!mute) { + if (sl_pp_process_out(state, &input[*pi])) { + return -1; + } } (*pi)++; return 0; @@ -244,8 +247,15 @@ sl_pp_macro_expand(struct sl_pp_context *context, for (j = 0;;) { switch (macro->body[j].token) { + case SL_PP_NEWLINE: + if (sl_pp_process_out(state, ¯o->body[j])) { + return -1; + } + j++; + break; + case SL_PP_IDENTIFIER: - if (sl_pp_macro_expand(context, macro->body, &j, actual_arg, state)) { + if (sl_pp_macro_expand(context, macro->body, &j, actual_arg, state, mute)) { return -1; } break; @@ -255,8 +265,10 @@ sl_pp_macro_expand(struct sl_pp_context *context, return 0; default: - if (sl_pp_process_out(state, ¯o->body[j])) { - return -1; + if (!mute) { + if (sl_pp_process_out(state, ¯o->body[j])) { + return -1; + } } j++; } diff --git a/src/glsl/pp/sl_pp_macro.h b/src/glsl/pp/sl_pp_macro.h index 63edd21aa24..476991d581d 100644 --- a/src/glsl/pp/sl_pp_macro.h +++ b/src/glsl/pp/sl_pp_macro.h @@ -55,6 +55,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, const struct sl_pp_token_info *input, unsigned int *pi, struct sl_pp_macro *local, - struct sl_pp_process_state *state); + struct sl_pp_process_state *state, + int mute); #endif /* SL_PP_MACRO_H */ diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index baffaf2cd95..441de9439c5 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -38,14 +38,6 @@ skip_whitespace(const struct sl_pp_token_info *input, } } - -struct sl_pp_process_state { - struct sl_pp_token_info *out; - unsigned int out_len; - unsigned int out_max; -}; - - int sl_pp_process_out(struct sl_pp_process_state *state, const struct sl_pp_token_info *token) @@ -133,16 +125,42 @@ sl_pp_process(struct sl_pp_context *context, last = i - 1; if (!strcmp(name, "define")) { - *macro = sl_pp_macro_new(); - if (!*macro) { + if (context->if_value) { + *macro = sl_pp_macro_new(); + if (!*macro) { + return -1; + } + + if (sl_pp_process_define(context, input, first, last, *macro)) { + return -1; + } + + macro = &(**macro).next; + } + } else if (!strcmp(name, "if")) { + if (sl_pp_process_if(context, input, first, last)) { return -1; } - - if (sl_pp_process_define(context, input, first, last, *macro)) { + } else if (!strcmp(name, "ifdef")) { + if (sl_pp_process_ifdef(context, input, first, last)) { + return -1; + } + } else if (!strcmp(name, "ifndef")) { + if (sl_pp_process_ifndef(context, input, first, last)) { + return -1; + } + } else if (!strcmp(name, "elif")) { + if (sl_pp_process_elif(context, input, first, last)) { + return -1; + } + } else if (!strcmp(name, "else")) { + if (sl_pp_process_else(context, input, first, last)) { + return -1; + } + } else if (!strcmp(name, "endif")) { + if (sl_pp_process_endif(context, input, first, last)) { return -1; } - - macro = &(**macro).next; } else { /* XXX: Ignore. */ } @@ -198,14 +216,16 @@ sl_pp_process(struct sl_pp_context *context, break; case SL_PP_IDENTIFIER: - if (sl_pp_macro_expand(context, input, &i, NULL, &state)) { + if (sl_pp_macro_expand(context, input, &i, NULL, &state, !context->if_value)) { return -1; } break; default: - if (sl_pp_process_out(&state, &input[i])) { - return -1; + if (context->if_value) { + if (sl_pp_process_out(&state, &input[i])) { + return -1; + } } i++; } @@ -213,6 +233,11 @@ sl_pp_process(struct sl_pp_context *context, } } + if (context->if_ptr != SL_PP_MAX_IF_NESTING) { + /* #endif expected. */ + return -1; + } + *output = state.out; return 0; } diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h index 37cdc4c9a78..cc934bd89c5 100644 --- a/src/glsl/pp/sl_pp_process.h +++ b/src/glsl/pp/sl_pp_process.h @@ -33,7 +33,11 @@ #include "sl_pp_token.h" -struct sl_pp_process_state; +struct sl_pp_process_state { + struct sl_pp_token_info *out; + unsigned int out_len; + unsigned int out_max; +}; int sl_pp_process(struct sl_pp_context *context, @@ -47,6 +51,42 @@ sl_pp_process_define(struct sl_pp_context *context, unsigned int last, struct sl_pp_macro *macro); +int +sl_pp_process_if(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last); + +int +sl_pp_process_ifdef(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last); + +int +sl_pp_process_ifndef(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last); + +int +sl_pp_process_elif(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last); + +int +sl_pp_process_else(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last); + +int +sl_pp_process_endif(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int first, + unsigned int last); + int sl_pp_process_out(struct sl_pp_process_state *state, const struct sl_pp_token_info *token); -- cgit v1.2.3 From 153b179862411e9de14d26bbcff16bc81f1edc91 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 26 Jun 2009 11:53:13 +0200 Subject: glsl: Handle `defined' preprocessor operator. --- src/glsl/pp/sl_pp_if.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 3 deletions(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_if.c b/src/glsl/pp/sl_pp_if.c index e331acc4cd5..90b80512375 100644 --- a/src/glsl/pp/sl_pp_if.c +++ b/src/glsl/pp/sl_pp_if.c @@ -30,6 +30,70 @@ #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)++; + } +} + +static int +_parse_defined(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int *pi, + struct sl_pp_process_state *state) +{ + int parens = 0; + int macro_name; + struct sl_pp_macro *macro; + int defined = 0; + struct sl_pp_token_info result; + + skip_whitespace(input, pi); + if (input[*pi].token == SL_PP_LPAREN) { + (*pi)++; + skip_whitespace(input, pi); + parens = 1; + } + + if (input[*pi].token != SL_PP_IDENTIFIER) { + /* Identifier expected. */ + return -1; + } + + macro_name = input[*pi].data.identifier; + for (macro = context->macro; macro; macro = macro->next) { + if (macro->name == macro_name) { + defined = 1; + break; + } + } + (*pi)++; + + if (parens) { + skip_whitespace(input, pi); + if (input[*pi].token != SL_PP_RPAREN) { + /* `)' expected */ + return -1; + } + (*pi)++; + } + + result.token = SL_PP_NUMBER; + if (defined) { + result.data.number = sl_pp_context_add_unique_str(context, "1"); + } else { + result.data.number = sl_pp_context_add_unique_str(context, "0"); + } + if (result.data.number == -1) { + return -1; + } + + return sl_pp_process_out(state, &result); +} + static int _evaluate_if_stack(struct sl_pp_context *context) { @@ -67,9 +131,21 @@ _parse_if(struct sl_pp_context *context, break; case SL_PP_IDENTIFIER: - if (sl_pp_macro_expand(context, input, &i, NULL, &state, 0)) { - free(state.out); - return -1; + { + 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; + } + } } break; -- 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') diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index 1afe9a5d5e0..50ec790cc50 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -33,6 +33,7 @@ void sl_pp_context_init(struct sl_pp_context *context) { memset(context, 0, sizeof(struct sl_pp_context)); + context->macro_tail = &context->macro; context->if_ptr = SL_PP_MAX_IF_NESTING; context->if_value = 1; } diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index e8200d55d7f..1dbd10e30ee 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -39,6 +39,7 @@ struct sl_pp_context { unsigned int cstr_pool_len; struct sl_pp_macro *macro; + struct sl_pp_macro **macro_tail; unsigned int if_stack[SL_PP_MAX_IF_NESTING]; unsigned int if_ptr; diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c index e8a23fedcd8..0509646430a 100644 --- a/src/glsl/pp/sl_pp_define.c +++ b/src/glsl/pp/sl_pp_define.c @@ -105,22 +105,42 @@ int sl_pp_process_define(struct sl_pp_context *context, const struct sl_pp_token_info *input, unsigned int first, - unsigned int last, - struct sl_pp_macro *macro) + unsigned int last) { + int macro_name = -1; + struct sl_pp_macro *macro; unsigned int i; unsigned int body_len; unsigned int j; if (first < last && input[first].token == SL_PP_IDENTIFIER) { - macro->name = input[first].data.identifier; + macro_name = input[first].data.identifier; first++; } - - if (macro->name == -1) { + if (macro_name == -1) { return -1; } + for (macro = context->macro; macro; macro = macro->next) { + if (macro->name == macro_name) { + break; + } + } + + if (!macro) { + macro = sl_pp_macro_new(); + if (!macro) { + return -1; + } + + *context->macro_tail = macro; + context->macro_tail = ¯o->next; + } else { + sl_pp_macro_reset(macro); + } + + macro->name = macro_name; + /* * If there is no whitespace between macro name and left paren, a macro * formal argument list follows. This is the only place where the presence diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index a8412f0651c..a82c30cb167 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -30,6 +30,15 @@ #include "sl_pp_process.h" +static void +_macro_init(struct sl_pp_macro *macro) +{ + macro->name = -1; + macro->num_args = -1; + macro->arg = NULL; + macro->body = NULL; +} + struct sl_pp_macro * sl_pp_macro_new(void) { @@ -37,33 +46,45 @@ sl_pp_macro_new(void) macro = calloc(1, sizeof(struct sl_pp_macro)); if (macro) { - macro->name = -1; - macro->num_args = -1; + _macro_init(macro); } return macro; } +static void +_macro_destroy(struct sl_pp_macro *macro) +{ + struct sl_pp_macro_formal_arg *arg = macro->arg; + + while (arg) { + struct sl_pp_macro_formal_arg *next_arg = arg->next; + + free(arg); + arg = next_arg; + } + + free(macro->body); +} + void sl_pp_macro_free(struct sl_pp_macro *macro) { while (macro) { struct sl_pp_macro *next_macro = macro->next; - struct sl_pp_macro_formal_arg *arg = macro->arg; - - while (arg) { - struct sl_pp_macro_formal_arg *next_arg = arg->next; - - free(arg); - arg = next_arg; - } - - free(macro->body); + _macro_destroy(macro); free(macro); macro = next_macro; } } +void +sl_pp_macro_reset(struct sl_pp_macro *macro) +{ + _macro_destroy(macro); + _macro_init(macro); +} + static void skip_whitespace(const struct sl_pp_token_info *input, unsigned int *pi) diff --git a/src/glsl/pp/sl_pp_macro.h b/src/glsl/pp/sl_pp_macro.h index 476991d581d..7af11c5ece7 100644 --- a/src/glsl/pp/sl_pp_macro.h +++ b/src/glsl/pp/sl_pp_macro.h @@ -50,6 +50,9 @@ sl_pp_macro_new(void); void sl_pp_macro_free(struct sl_pp_macro *macro); +void +sl_pp_macro_reset(struct sl_pp_macro *macro); + int sl_pp_macro_expand(struct sl_pp_context *context, const struct sl_pp_token_info *input, diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index 441de9439c5..4715eed2fcd 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -71,10 +71,8 @@ sl_pp_process(struct sl_pp_context *context, { unsigned int i = 0; int found_eof = 0; - struct sl_pp_macro **macro; struct sl_pp_process_state state; - macro = &context->macro; memset(&state, 0, sizeof(state)); while (!found_eof) { @@ -126,16 +124,9 @@ sl_pp_process(struct sl_pp_context *context, if (!strcmp(name, "define")) { if (context->if_value) { - *macro = sl_pp_macro_new(); - if (!*macro) { + if (sl_pp_process_define(context, input, first, last)) { return -1; } - - if (sl_pp_process_define(context, input, first, last, *macro)) { - return -1; - } - - macro = &(**macro).next; } } else if (!strcmp(name, "if")) { if (sl_pp_process_if(context, input, first, last)) { diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h index cc934bd89c5..66d61496a2d 100644 --- a/src/glsl/pp/sl_pp_process.h +++ b/src/glsl/pp/sl_pp_process.h @@ -48,8 +48,7 @@ int sl_pp_process_define(struct sl_pp_context *context, const struct sl_pp_token_info *input, unsigned int first, - unsigned int last, - struct sl_pp_macro *macro); + unsigned int last); int sl_pp_process_if(struct sl_pp_context *context, -- cgit v1.2.3 From 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') diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c index 0509646430a..9bc9fb53599 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 4715eed2fcd..c17a3ac7ce8 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 66d61496a2d..61e67fef0b7 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') diff --git a/src/glsl/pp/SConscript b/src/glsl/pp/SConscript index c7718d1d8fd..13fc230b96e 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 50ec790cc50..38d633baeff 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 1dbd10e30ee..65ce3e37b7b 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 00000000000..d42568d23dc --- /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 c17a3ac7ce8..117aa01688d 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 61e67fef0b7..11a94921d82 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') diff --git a/src/glsl/pp/SConscript b/src/glsl/pp/SConscript index 13fc230b96e..0c1b4ac2e99 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 00000000000..059bc6f2886 --- /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 117aa01688d..62b73426c5f 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 11a94921d82..9a29c03a701 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 a53720be802..566274ea90e 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') diff --git a/src/glsl/pp/SConscript b/src/glsl/pp/SConscript index 0c1b4ac2e99..dae8830eeb6 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 00000000000..3d223a1a548 --- /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 62b73426c5f..be01f9139c1 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 9a29c03a701..58918665434 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 566274ea90e..7b60183a041 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') diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index be01f9139c1..18289790d19 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') diff --git a/src/glsl/pp/SConscript b/src/glsl/pp/SConscript index dae8830eeb6..cc930380c21 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 00000000000..3300a4785ba --- /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 18289790d19..5479e8a8683 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 58918665434..6f90fbd3e77 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 e8afc6558909d9503a83c8cc184a2e2bb008746b Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 4 Sep 2009 13:30:40 +0200 Subject: glsl: Implement predefinded macros. The values are hardcoded: __LINE__ = 1, __FILE__ = 0 and __VERSION__ = 110. --- src/glsl/pp/sl_pp_macro.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index a82c30cb167..bacd468964c 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -26,6 +26,7 @@ **************************************************************************/ #include +#include #include "sl_pp_macro.h" #include "sl_pp_process.h" @@ -94,6 +95,21 @@ skip_whitespace(const struct sl_pp_token_info *input, } } +static int +_out_number(struct sl_pp_context *context, + struct sl_pp_process_state *state, + unsigned int number) +{ + char buf[32]; + struct sl_pp_token_info ti; + + sprintf(buf, "%u", number); + + ti.token = SL_PP_NUMBER; + ti.data.number = sl_pp_context_add_unique_str(context, buf); + return sl_pp_process_out(state, &ti); +} + int sl_pp_macro_expand(struct sl_pp_context *context, const struct sl_pp_token_info *input, @@ -103,6 +119,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, int mute) { int macro_name; + const char *macro_str; struct sl_pp_macro *macro = NULL; struct sl_pp_macro *actual_arg = NULL; unsigned int j; @@ -112,6 +129,30 @@ sl_pp_macro_expand(struct sl_pp_context *context, } macro_name = input[*pi].data.identifier; + macro_str = sl_pp_context_cstr(context, macro_name); + + /* TODO: Having the following built-ins hardcoded is a bit lame. */ + if (!strcmp(macro_str, "__LINE__")) { + if (!mute && _out_number(context, state, 1)) { + return -1; + } + (*pi)++; + return 0; + } + if (!strcmp(macro_str, "__FILE__")) { + if (!mute && _out_number(context, state, 0)) { + return -1; + } + (*pi)++; + return 0; + } + if (!strcmp(macro_str, "__VERSION__")) { + if (!mute && _out_number(context, state, 110)) { + return -1; + } + (*pi)++; + return 0; + } if (local) { for (macro = local; macro; macro = macro->next) { -- cgit v1.2.3 From 0d9c5eafeb35fdd2e5009ba0b397d1acdfbd3205 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 4 Sep 2009 15:11:58 +0200 Subject: glsl: Preserve newline inside comment blocks. --- src/glsl/pp/sl_pp_purify.c | 89 ++++++++++++++++++++++++++++++---------------- 1 file changed, 58 insertions(+), 31 deletions(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_purify.c b/src/glsl/pp/sl_pp_purify.c index ded4dc8963b..3fb91430f37 100644 --- a/src/glsl/pp/sl_pp_purify.c +++ b/src/glsl/pp/sl_pp_purify.c @@ -106,9 +106,44 @@ _purify_backslash(const char *input, } +struct out_buf { + char *out; + unsigned int len; + unsigned int capacity; +}; + + +static int +_out_buf_putc(struct out_buf *obuf, + char c) +{ + if (obuf->len >= obuf->capacity) { + unsigned int new_max = obuf->capacity; + + if (new_max < 0x100) { + new_max = 0x100; + } else if (new_max < 0x10000) { + new_max *= 2; + } else { + new_max += 0x10000; + } + + obuf->out = realloc(obuf->out, new_max); + if (!obuf->out) { + return -1; + } + obuf->capacity = new_max; + } + + obuf->out[obuf->len++] = c; + + return 0; +} + + static unsigned int _purify_comment(const char *input, - char *out) + struct out_buf *obuf) { unsigned int eaten; char curr; @@ -130,7 +165,9 @@ _purify_comment(const char *input, eaten += next_eaten; input += next_eaten; if (next == '\n' || next == '\0') { - *out = next; + if (_out_buf_putc(obuf, next)) { + return 0; + } return eaten; } } @@ -148,17 +185,26 @@ _purify_comment(const char *input, eaten += next_eaten; input += next_eaten; if (next == '/') { - *out = ' '; + if (_out_buf_putc(obuf, ' ')) { + return 0; + } return eaten; } } + if (next == '\n') { + if (_out_buf_putc(obuf, '\n')) { + return 0; + } + } if (next == '\0') { return 0; } } } } - *out = curr; + if (_out_buf_putc(obuf, curr)) { + return 0; + } return eaten; } @@ -168,45 +214,26 @@ sl_pp_purify(const char *input, const struct sl_pp_purify_options *options, char **output) { - char *out = NULL; - unsigned int out_len = 0; - unsigned int out_max = 0; + struct out_buf obuf; + + obuf.out = NULL; + obuf.len = 0; + obuf.capacity = 0; for (;;) { - char c; unsigned int eaten; - eaten = _purify_comment(input, &c); + eaten = _purify_comment(input, &obuf); if (!eaten) { return -1; } input += eaten; - 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); - if (!out) { - return -1; - } - out_max = new_max; - } - - out[out_len++] = c; - - if (c == '\0') { + if (obuf.out[obuf.len - 1] == '\0') { break; } } - *output = out; + *output = obuf.out; return 0; } -- 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') diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index 38d633baeff..6aaf76828cc 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -37,6 +37,7 @@ sl_pp_context_init(struct sl_pp_context *context) context->if_ptr = SL_PP_MAX_IF_NESTING; context->if_value = 1; memset(context->error_msg, 0, sizeof(context->error_msg)); + context->line = 1; } void diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index 65ce3e37b7b..d656648d0dc 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -48,6 +48,8 @@ struct sl_pp_context { int if_value; char error_msg[SL_PP_MAX_ERROR_MSG]; + + unsigned int line; }; void diff --git a/src/glsl/pp/sl_pp_line.c b/src/glsl/pp/sl_pp_line.c index 3300a4785ba..b62af185bf5 100644 --- a/src/glsl/pp/sl_pp_line.c +++ b/src/glsl/pp/sl_pp_line.c @@ -29,16 +29,44 @@ #include "sl_pp_process.h" +static int +_parse_integer(const char *input, + unsigned int *number) +{ + unsigned int n = 0; + + while (*input >= '0' && *input <= '9') { + if (n * 10 < n) { + /* Overflow. */ + return -1; + } + + n = n * 10 + (*input++ - '0'); + } + + if (*input != '\0') { + /* Invalid decimal number. */ + return -1; + } + + *number = n; + return 0; +} + + int sl_pp_process_line(struct sl_pp_context *context, const struct sl_pp_token_info *input, unsigned int first, - unsigned int last) + unsigned int last, + struct sl_pp_process_state *pstate) { unsigned int i; struct sl_pp_process_state state; int line_number = -1; int file_number = -1; + const char *str; + unsigned int line; memset(&state, 0, sizeof(state)); for (i = first; i < last;) { @@ -89,7 +117,22 @@ sl_pp_process_line(struct sl_pp_context *context, free(state.out); - /* TODO: Do something with line and file numbers. */ + str = sl_pp_context_cstr(context, line_number); + if (_parse_integer(str, &line)) { + return -1; + } + + if (context->line != line) { + struct sl_pp_token_info ti; + + ti.token = SL_PP_LINE; + ti.data.line = line; + if (sl_pp_process_out(pstate, &ti)) { + return -1; + } + } + + /* TODO: Do something with the file number. */ return 0; } diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index bacd468964c..b6214f66edc 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -131,14 +131,14 @@ sl_pp_macro_expand(struct sl_pp_context *context, macro_name = input[*pi].data.identifier; macro_str = sl_pp_context_cstr(context, macro_name); - /* TODO: Having the following built-ins hardcoded is a bit lame. */ if (!strcmp(macro_str, "__LINE__")) { - if (!mute && _out_number(context, state, 1)) { + if (!mute && _out_number(context, state, context->line)) { return -1; } (*pi)++; return 0; } + /* TODO: Having the following built-ins hardcoded is a bit lame. */ if (!strcmp(macro_str, "__FILE__")) { if (!mute && _out_number(context, state, 0)) { return -1; diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index 5479e8a8683..c4d6efaed38 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -75,6 +75,21 @@ sl_pp_process(struct sl_pp_context *context, memset(&state, 0, sizeof(state)); + if (context->line > 1) { + struct sl_pp_token_info ti; + + ti.token = SL_PP_LINE; + ti.data.line = context->line - 1; + if (sl_pp_process_out(&state, &ti)) { + return -1; + } + + ti.token = SL_PP_NEWLINE; + if (sl_pp_process_out(&state, &ti)) { + return -1; + } + } + while (!found_eof) { skip_whitespace(input, &i); if (input[i].token == SL_PP_HASH) { @@ -156,7 +171,7 @@ sl_pp_process(struct sl_pp_context *context, return -1; } } else if (!strcmp(name, "line")) { - if (sl_pp_process_line(context, input, first, last)) { + if (sl_pp_process_line(context, input, first, last, &state)) { return -1; } } else if (!strcmp(name, "pragma")) { @@ -176,6 +191,7 @@ sl_pp_process(struct sl_pp_context *context, if (sl_pp_process_out(&state, &endof)) { return -1; } + context->line++; } break; @@ -184,6 +200,7 @@ sl_pp_process(struct sl_pp_context *context, if (sl_pp_process_out(&state, &input[i])) { return -1; } + context->line++; i++; break; @@ -214,6 +231,7 @@ sl_pp_process(struct sl_pp_context *context, if (sl_pp_process_out(&state, &input[i])) { return -1; } + context->line++; i++; found_eol = 1; break; diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h index 6f90fbd3e77..adc08c18ae3 100644 --- a/src/glsl/pp/sl_pp_process.h +++ b/src/glsl/pp/sl_pp_process.h @@ -116,7 +116,8 @@ int sl_pp_process_line(struct sl_pp_context *context, const struct sl_pp_token_info *input, unsigned int first, - unsigned int last); + unsigned int last, + struct sl_pp_process_state *state); int sl_pp_process_out(struct sl_pp_process_state *state, diff --git a/src/glsl/pp/sl_pp_token.h b/src/glsl/pp/sl_pp_token.h index 7b60183a041..b347e5cf7a9 100644 --- a/src/glsl/pp/sl_pp_token.h +++ b/src/glsl/pp/sl_pp_token.h @@ -96,6 +96,8 @@ enum sl_pp_token { SL_PP_EXTENSION_WARN, SL_PP_EXTENSION_DISABLE, + SL_PP_LINE, + SL_PP_EOF }; @@ -105,6 +107,7 @@ union sl_pp_token_data { char other; int pragma; int extension; + unsigned int line; }; struct sl_pp_token_info { diff --git a/src/glsl/pp/sl_pp_version.c b/src/glsl/pp/sl_pp_version.c index 89c3cfa1a5b..80f7e971016 100644 --- a/src/glsl/pp/sl_pp_version.c +++ b/src/glsl/pp/sl_pp_version.c @@ -60,6 +60,7 @@ sl_pp_version(struct sl_pp_context *context, unsigned int *tokens_eaten) { unsigned int i = 0; + unsigned int line = context->line; /* Default values if `#version' is not present. */ *version = 110; @@ -77,8 +78,10 @@ sl_pp_version(struct sl_pp_context *context, /* Skip whitespace and newlines and seek for hash. */ while (!found_hash) { switch (input[i].token) { - case SL_PP_WHITESPACE: case SL_PP_NEWLINE: + line++; + /* pass thru */ + case SL_PP_WHITESPACE: i++; break; @@ -156,9 +159,12 @@ sl_pp_version(struct sl_pp_context *context, break; case SL_PP_NEWLINE: + line++; + /* pass thru */ case SL_PP_EOF: i++; *tokens_eaten = i; + context->line = line; found_end = 1; break; -- cgit v1.2.3 From 2d2d6384448baae3c04eced3373d96907def4e13 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 4 Sep 2009 15:20:31 +0200 Subject: glsl: Actually respect the hash-line directive. --- src/glsl/pp/sl_pp_line.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_line.c b/src/glsl/pp/sl_pp_line.c index b62af185bf5..9b9f45dcedd 100644 --- a/src/glsl/pp/sl_pp_line.c +++ b/src/glsl/pp/sl_pp_line.c @@ -130,6 +130,8 @@ sl_pp_process_line(struct sl_pp_context *context, if (sl_pp_process_out(pstate, &ti)) { return -1; } + + context->line = line; } /* TODO: Do something with the file number. */ -- cgit v1.2.3 From a64ba93aab6de7ee2ceb70f39cf2dbe794940c97 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 4 Sep 2009 15:27:08 +0200 Subject: glsl: Handle file numbering. --- src/glsl/pp/sl_pp_context.c | 1 + src/glsl/pp/sl_pp_context.h | 1 + src/glsl/pp/sl_pp_line.c | 21 ++++++++++++++++++++- src/glsl/pp/sl_pp_macro.c | 3 +-- src/glsl/pp/sl_pp_token.h | 2 ++ 5 files changed, 25 insertions(+), 3 deletions(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index 6aaf76828cc..2fca3791a26 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -38,6 +38,7 @@ sl_pp_context_init(struct sl_pp_context *context) context->if_value = 1; memset(context->error_msg, 0, sizeof(context->error_msg)); context->line = 1; + context->file = 0; } void diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index d656648d0dc..c7e6770f449 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -50,6 +50,7 @@ struct sl_pp_context { char error_msg[SL_PP_MAX_ERROR_MSG]; unsigned int line; + unsigned int file; }; void diff --git a/src/glsl/pp/sl_pp_line.c b/src/glsl/pp/sl_pp_line.c index 9b9f45dcedd..a56417a8610 100644 --- a/src/glsl/pp/sl_pp_line.c +++ b/src/glsl/pp/sl_pp_line.c @@ -134,7 +134,26 @@ sl_pp_process_line(struct sl_pp_context *context, context->line = line; } - /* TODO: Do something with the file number. */ + if (file_number != -1) { + unsigned int file; + + str = sl_pp_context_cstr(context, file_number); + if (_parse_integer(str, &file)) { + return -1; + } + + if (context->file != file) { + struct sl_pp_token_info ti; + + ti.token = SL_PP_FILE; + ti.data.file = file; + if (sl_pp_process_out(pstate, &ti)) { + return -1; + } + + context->file = file; + } + } return 0; } diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index b6214f66edc..d14c9825557 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -138,9 +138,8 @@ sl_pp_macro_expand(struct sl_pp_context *context, (*pi)++; return 0; } - /* TODO: Having the following built-ins hardcoded is a bit lame. */ if (!strcmp(macro_str, "__FILE__")) { - if (!mute && _out_number(context, state, 0)) { + if (!mute && _out_number(context, state, context->file)) { return -1; } (*pi)++; diff --git a/src/glsl/pp/sl_pp_token.h b/src/glsl/pp/sl_pp_token.h index b347e5cf7a9..59019593839 100644 --- a/src/glsl/pp/sl_pp_token.h +++ b/src/glsl/pp/sl_pp_token.h @@ -97,6 +97,7 @@ enum sl_pp_token { SL_PP_EXTENSION_DISABLE, SL_PP_LINE, + SL_PP_FILE, SL_PP_EOF }; @@ -108,6 +109,7 @@ union sl_pp_token_data { int pragma; int extension; unsigned int line; + unsigned int file; }; struct sl_pp_token_info { -- cgit v1.2.3 From 5ad89377522061775b467d84bf6dc14305cccfbf Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 7 Sep 2009 10:01:11 +0200 Subject: glsl: Add error messages for version parser. --- src/glsl/pp/sl_pp_version.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_version.c b/src/glsl/pp/sl_pp_version.c index 80f7e971016..82acdd1d5a4 100644 --- a/src/glsl/pp/sl_pp_version.c +++ b/src/glsl/pp/sl_pp_version.c @@ -137,7 +137,7 @@ sl_pp_version(struct sl_pp_context *context, return -1; } if (_parse_integer(num, version)) { - /* Expected version number. */ + strcpy(context->error_msg, "expected version number after `#version'"); return -1; } i++; @@ -146,7 +146,7 @@ sl_pp_version(struct sl_pp_context *context, break; default: - /* Expected version number. */ + strcpy(context->error_msg, "expected version number after `#version'"); return -1; } } @@ -169,7 +169,7 @@ sl_pp_version(struct sl_pp_context *context, break; default: - /* Expected end of line. */ + strcpy(context->error_msg, "expected end of line after version number"); return -1; } } -- cgit v1.2.3 From a67f32289a6e22daa2665310f4a8f26979f7ed60 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 14 Sep 2009 13:07:25 +0200 Subject: glsl/pp: Add a dictionary to a context. --- src/glsl/pp/SConscript | 1 + src/glsl/pp/sl_pp_context.c | 10 +++++++- src/glsl/pp/sl_pp_context.h | 4 +++- src/glsl/pp/sl_pp_dict.c | 56 +++++++++++++++++++++++++++++++++++++++++++++ src/glsl/pp/sl_pp_dict.h | 46 +++++++++++++++++++++++++++++++++++++ 5 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 src/glsl/pp/sl_pp_dict.c create mode 100644 src/glsl/pp/sl_pp_dict.h (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/SConscript b/src/glsl/pp/SConscript index cc930380c21..621db1e765c 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_dict.c', 'sl_pp_error.c', 'sl_pp_expression.c', 'sl_pp_extension.c', diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index 2fca3791a26..88a002c1c73 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -29,16 +29,24 @@ #include "sl_pp_context.h" -void +int sl_pp_context_init(struct sl_pp_context *context) { memset(context, 0, sizeof(struct sl_pp_context)); + + if (sl_pp_dict_init(context)) { + sl_pp_context_destroy(context); + return -1; + } + 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)); context->line = 1; context->file = 0; + + return 0; } void diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index c7e6770f449..5826f9448d0 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -28,6 +28,7 @@ #ifndef SL_PP_CONTEXT_H #define SL_PP_CONTEXT_H +#include "sl_pp_dict.h" #include "sl_pp_macro.h" @@ -39,6 +40,7 @@ struct sl_pp_context { char *cstr_pool; unsigned int cstr_pool_max; unsigned int cstr_pool_len; + struct sl_pp_dict dict; struct sl_pp_macro *macro; struct sl_pp_macro **macro_tail; @@ -53,7 +55,7 @@ struct sl_pp_context { unsigned int file; }; -void +int sl_pp_context_init(struct sl_pp_context *context); void diff --git a/src/glsl/pp/sl_pp_dict.c b/src/glsl/pp/sl_pp_dict.c new file mode 100644 index 00000000000..65b91d9e989 --- /dev/null +++ b/src/glsl/pp/sl_pp_dict.c @@ -0,0 +1,56 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "sl_pp_context.h" +#include "sl_pp_dict.h" + + +#define ADD_NAME_STR(CTX, NAME, STR)\ + do {\ + (CTX)->dict.NAME = sl_pp_context_add_unique_str((CTX), (STR));\ + if ((CTX)->dict.NAME == -1) {\ + return -1;\ + }\ + } while (0) + +#define ADD_NAME(CTX, NAME) ADD_NAME_STR(CTX, NAME, #NAME) + + +int +sl_pp_dict_init(struct sl_pp_context *context) +{ + ADD_NAME(context, all); + ADD_NAME_STR(context, _GL_ARB_draw_buffers, "GL_ARB_draw_buffers"); + ADD_NAME_STR(context, _GL_ARB_texture_rectangle, "GL_ARB_texture_rectangle"); + + ADD_NAME(context, require); + ADD_NAME(context, enable); + ADD_NAME(context, warn); + ADD_NAME(context, disable); + + return 0; +} diff --git a/src/glsl/pp/sl_pp_dict.h b/src/glsl/pp/sl_pp_dict.h new file mode 100644 index 00000000000..ce138d98f51 --- /dev/null +++ b/src/glsl/pp/sl_pp_dict.h @@ -0,0 +1,46 @@ +/************************************************************************** + * + * 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_DICT_H +#define SL_PP_DICT_H + +struct sl_pp_dict { + int all; + int _GL_ARB_draw_buffers; + int _GL_ARB_texture_rectangle; + + int require; + int enable; + int warn; + int disable; +}; + + +int +sl_pp_dict_init(struct sl_pp_context *context); + +#endif /* SL_PP_DICT_H */ -- cgit v1.2.3 From 0f302b60fd6d43a47e208979d0677e09f4a802fc Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 14 Sep 2009 13:09:36 +0200 Subject: glsl/pp: Support GL_ARB_draw_buffers and GL_ARB_texture_rectangle. --- src/glsl/pp/sl_pp_extension.c | 83 +++++++++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 34 deletions(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_extension.c b/src/glsl/pp/sl_pp_extension.c index 3d223a1a548..33193d03a8c 100644 --- a/src/glsl/pp/sl_pp_extension.c +++ b/src/glsl/pp/sl_pp_extension.c @@ -36,86 +36,101 @@ sl_pp_process_extension(struct sl_pp_context *context, unsigned int last, struct sl_pp_process_state *state) { - int all_extensions = -1; - const char *extension_name = NULL; - const char *behavior = NULL; + int extensions[] = { + context->dict.all, + context->dict._GL_ARB_draw_buffers, + context->dict._GL_ARB_texture_rectangle, + -1 + }; + int extension_name = -1; + int *ext; + int behavior = -1; struct sl_pp_token_info out; - all_extensions = sl_pp_context_add_unique_str(context, "all"); - if (all_extensions == -1) { - return -1; - } - + /* Grab the extension name. */ if (first < last && input[first].token == SL_PP_IDENTIFIER) { - extension_name = sl_pp_context_cstr(context, input[first].data.identifier); + extension_name = input[first].data.identifier; first++; } - if (!extension_name) { + if (extension_name == -1) { 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; + /* Make sure the extension is supported. */ + out.data.extension = -1; + for (ext = extensions; *ext != -1; ext++) { + if (extension_name == *ext) { + out.data.extension = extension_name; + break; + } } + /* Grab the colon separating the extension name and behavior. */ 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++; } + /* Grab the behavior name. */ if (first < last && input[first].token == SL_PP_IDENTIFIER) { - behavior = sl_pp_context_cstr(context, input[first].data.identifier); + behavior = input[first].data.identifier; first++; } - if (!behavior) { + if (behavior == -1) { 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"); + if (behavior == context->dict.require) { + if (out.data.extension == -1) { + strcpy(context->error_msg, "the required extension is not supported"); + return -1; + } + if (out.data.extension == context->dict.all) { + strcpy(context->error_msg, "invalid behavior for `all' extension: `require'"); return -1; - } else { + } + out.token = SL_PP_EXTENSION_REQUIRE; + } else if (behavior == context->dict.enable) { + if (out.data.extension == -1) { + /* Warning: the extension cannot be enabled. */ return 0; } - } else if (!strcmp(behavior, "warn")) { - if (out.data.extension == all_extensions) { - out.token = SL_PP_EXTENSION_WARN; - } else { + if (out.data.extension == context->dict.all) { + strcpy(context->error_msg, "invalid behavior for `all' extension: `enable'"); + return -1; + } + out.token = SL_PP_EXTENSION_ENABLE; + } else if (behavior == context->dict.warn) { + if (out.data.extension == -1) { + /* Warning: the extension is not supported. */ return 0; } - } else if (!strcmp(behavior, "disable")) { - if (out.data.extension == all_extensions) { - out.token = SL_PP_EXTENSION_DISABLE; - } else { + out.token = SL_PP_EXTENSION_WARN; + } else if (behavior == context->dict.disable) { + if (out.data.extension == -1) { + /* Warning: the extension is not supported. */ return 0; } + out.token = SL_PP_EXTENSION_DISABLE; } else { strcpy(context->error_msg, "unrecognised behavior name"); return -1; } + /* Grab the end of line. */ 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; -- 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') diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index c4d6efaed38..03a3051838f 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 de0753e4cb64792d257ad3799932a77321fc3c49 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 16 Sep 2009 20:40:02 +0200 Subject: glsl/pp: Add more error messages. --- src/glsl/pp/sl_pp_token.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_token.c b/src/glsl/pp/sl_pp_token.c index 68c8fbe2ec4..95fe4f7d85e 100644 --- a/src/glsl/pp/sl_pp_token.c +++ b/src/glsl/pp/sl_pp_token.c @@ -47,6 +47,7 @@ _tokenise_identifier(struct sl_pp_context *context, (*input >= '0' && *input <= '9') || (*input == '_')) { if (i >= sizeof(identifier) - 1) { + strcpy(context->error_msg, "out of memory"); return -1; } identifier[i++] = *input++; @@ -85,6 +86,7 @@ _tokenise_number(struct sl_pp_context *context, (*input == '-') || (*input == '.')) { if (i >= sizeof(number) - 1) { + strcpy(context->error_msg, "out of memory"); return -1; } number[i++] = *input++; @@ -384,6 +386,7 @@ sl_pp_tokenise(struct sl_pp_context *context, out = realloc(out, new_max * sizeof(struct sl_pp_token_info)); if (!out) { + strcpy(context->error_msg, "out of memory"); return -1; } out_max = new_max; -- cgit v1.2.3 From a7382628f2ed5a2886a1828dd847d75bf8e9b38e Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 16 Sep 2009 21:51:12 +0200 Subject: glsl/pp: Validate numbers. --- src/glsl/pp/sl_pp_token.c | 250 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 227 insertions(+), 23 deletions(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_token.c b/src/glsl/pp/sl_pp_token.c index 95fe4f7d85e..a6a2bb27485 100644 --- a/src/glsl/pp/sl_pp_token.c +++ b/src/glsl/pp/sl_pp_token.c @@ -29,6 +29,13 @@ #include "sl_pp_token.h" +static int +_is_identifier_char(char c) +{ + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_'; +} + + static int _tokenise_identifier(struct sl_pp_context *context, const char **pinput, @@ -42,10 +49,7 @@ _tokenise_identifier(struct sl_pp_context *context, info->data.identifier = -1; identifier[i++] = *input++; - while ((*input >= 'a' && *input <= 'z') || - (*input >= 'A' && *input <= 'Z') || - (*input >= '0' && *input <= '9') || - (*input == '_')) { + while (_is_identifier_char(*input)) { if (i >= sizeof(identifier) - 1) { strcpy(context->error_msg, "out of memory"); return -1; @@ -64,41 +68,241 @@ _tokenise_identifier(struct sl_pp_context *context, } +/* + * Return the number of consecutive decimal digits in the input stream. + */ +static unsigned int +_parse_float_digits(const char *input) +{ + unsigned int eaten = 0; + + while (input[eaten] >= '0' && input[eaten] <= '9') { + eaten++; + } + return eaten; +} + + +/* + * Try to match one of the following patterns for the fractional part + * of a floating point number. + * + * digits . [digits] + * . digits + * + * Return 0 if the pattern could not be matched, otherwise the number + * of eaten characters from the input stream. + */ +static unsigned int +_parse_float_frac(const char *input) +{ + unsigned int eaten; + + if (input[0] == '.') { + eaten = _parse_float_digits(&input[1]); + if (eaten) { + return eaten + 1; + } + return 0; + } + + eaten = _parse_float_digits(input); + if (eaten && input[eaten] == '.') { + unsigned int trailing; + + trailing = _parse_float_digits(&input[eaten + 1]); + if (trailing) { + return eaten + trailing + 1; + } + return eaten + 1; + } + + return 0; +} + + +/* + * Try to match the following pattern for the exponential part + * of a floating point number. + * + * (e|E) [(+|-)] digits + * + * Return 0 if the pattern could not be matched, otherwise the number + * of eaten characters from the input stream. + */ +static unsigned int +_parse_float_exp(const char *input) +{ + unsigned int eaten, digits; + + if (input[0] != 'e' && input[0] != 'E') { + return 0; + } + + if (input[1] == '-' || input[1] == '+') { + eaten = 2; + } else { + eaten = 1; + } + + digits = _parse_float_digits(&input[eaten]); + if (!digits) { + return 0; + } + + return eaten + digits; +} + + +/* + * Try to match one of the following patterns for a floating point number. + * + * fract [exp] [(f|F)] + * digits exp [(f|F)] + * + * Return 0 if the pattern could not be matched, otherwise the number + * of eaten characters from the input stream. + */ +static unsigned int +_parse_float(const char *input) +{ + unsigned int eaten; + + eaten = _parse_float_frac(input); + if (eaten) { + unsigned int exponent; + + exponent = _parse_float_exp(&input[eaten]); + if (exponent) { + eaten += exponent; + } + + if (input[eaten] == 'f' || input[eaten] == 'F') { + eaten++; + } + + return eaten; + } + + eaten = _parse_float_digits(input); + if (eaten) { + unsigned int exponent; + + exponent = _parse_float_exp(&input[eaten]); + if (exponent) { + eaten += exponent; + + if (input[eaten] == 'f' || input[eaten] == 'F') { + eaten++; + } + + return eaten; + } + } + + return 0; +} + + +static unsigned int +_parse_hex(const char *input) +{ + unsigned int n; + + if (input[0] != '0') { + return 0; + } + + if (input[1] != 'x' && input[1] != 'X') { + return 0; + } + + n = 2; + while ((input[n] >= '0' && input[n] <= '9') || + (input[n] >= 'a' && input[n] <= 'f') || + (input[n] >= 'A' && input[n] <= 'F')) { + n++; + } + + if (n > 2) { + return n; + } + + return 0; +} + + +static unsigned int +_parse_oct(const char *input) +{ + unsigned int n; + + if (input[0] != '0') { + return 0; + } + + n = 1; + while ((input[n] >= '0' && input[n] <= '7')) { + n++; + } + + return n; +} + + +static unsigned int +_parse_dec(const char *input) +{ + unsigned int n = 0; + + while ((input[n] >= '0' && input[n] <= '9')) { + n++; + } + + return n; +} + + static int _tokenise_number(struct sl_pp_context *context, const char **pinput, struct sl_pp_token_info *info) { const char *input = *pinput; + unsigned int eaten; char number[256]; /* XXX: Remove this artifical limit. */ - unsigned int i = 0; - info->token = SL_PP_NUMBER; - info->data.number = -1; - - number[i++] = *input++; - while ((*input >= '0' && *input <= '9') || - (*input >= 'a' && *input <= 'f') || - (*input >= 'A' && *input <= 'F') || - (*input == 'x') || - (*input == 'X') || - (*input == '+') || - (*input == '-') || - (*input == '.')) { - if (i >= sizeof(number) - 1) { - strcpy(context->error_msg, "out of memory"); - return -1; + eaten = _parse_float(input); + if (!eaten) { + eaten = _parse_hex(input); + if (!eaten) { + eaten = _parse_oct(input); + if (!eaten) { + eaten = _parse_dec(input); + } } - number[i++] = *input++; } - number[i++] = '\0'; + if (!eaten || _is_identifier_char(input[eaten])) { + strcpy(context->error_msg, "expected a number"); + return -1; + } + + if (eaten > sizeof(number) - 1) { + strcpy(context->error_msg, "out of memory"); + return -1; + } + + memcpy(number, input, eaten); + number[eaten] = '\0'; + + info->token = SL_PP_NUMBER; info->data.number = sl_pp_context_add_unique_str(context, number); if (info->data.number == -1) { return -1; } - *pinput = input; + *pinput = input + eaten; return 0; } -- cgit v1.2.3 From 0ddf41d34d511b339e0bb5a59673765f1bf0b3a5 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 17 Sep 2009 11:51:35 +0200 Subject: glsl/pp: Add remaining error messages. --- src/glsl/pp/sl_pp_context.c | 1 + src/glsl/pp/sl_pp_context.h | 2 +- src/glsl/pp/sl_pp_define.c | 19 ++++++++++++------ src/glsl/pp/sl_pp_expression.c | 2 ++ src/glsl/pp/sl_pp_if.c | 35 +++++++++++++++++++------------- src/glsl/pp/sl_pp_line.c | 45 ++++++++---------------------------------- src/glsl/pp/sl_pp_macro.c | 18 ++++++++++++++++- src/glsl/pp/sl_pp_pragma.c | 1 + src/glsl/pp/sl_pp_version.c | 42 ++++----------------------------------- 9 files changed, 68 insertions(+), 97 deletions(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index 88a002c1c73..b196d8102a0 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -85,6 +85,7 @@ sl_pp_context_add_unique_str(struct sl_pp_context *context, } if (!context->cstr_pool) { + strcpy(context->error_msg, "out of memory"); return -1; } diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index 5826f9448d0..8bed1420454 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -47,7 +47,7 @@ struct sl_pp_context { unsigned int if_stack[SL_PP_MAX_IF_NESTING]; unsigned int if_ptr; - int if_value; + unsigned int if_value; char error_msg[SL_PP_MAX_ERROR_MSG]; diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c index 9bc9fb53599..391178aa696 100644 --- a/src/glsl/pp/sl_pp_define.c +++ b/src/glsl/pp/sl_pp_define.c @@ -41,7 +41,8 @@ skip_whitespace(const struct sl_pp_token_info *input, static int -_parse_formal_args(const struct sl_pp_token_info *input, +_parse_formal_args(struct sl_pp_context *context, + const struct sl_pp_token_info *input, unsigned int *first, unsigned int last, struct sl_pp_macro *macro) @@ -57,7 +58,7 @@ _parse_formal_args(const struct sl_pp_token_info *input, return 0; } } else { - /* Expected either an identifier or `)'. */ + strcpy(context->error_msg, "expected either an identifier or `)'"); return -1; } @@ -65,12 +66,13 @@ _parse_formal_args(const struct sl_pp_token_info *input, for (;;) { if (*first < last && input[*first].token != SL_PP_IDENTIFIER) { - /* Expected an identifier. */ + strcpy(context->error_msg, "expected an identifier"); return -1; } *arg = malloc(sizeof(struct sl_pp_macro_formal_arg)); if (!*arg) { + strcpy(context->error_msg, "out of memory"); return -1; } @@ -90,14 +92,16 @@ _parse_formal_args(const struct sl_pp_token_info *input, (*first)++; return 0; } else { - /* Expected either `,' or `)'. */ + strcpy(context->error_msg, "expected either `,' or `)'"); return -1; } } else { - /* Expected either `,' or `)'. */ + strcpy(context->error_msg, "expected either `,' or `)'"); return -1; } } + + /* Should not gete here. */ } @@ -118,6 +122,7 @@ sl_pp_process_define(struct sl_pp_context *context, first++; } if (macro_name == -1) { + strcpy(context->error_msg, "expected an identifier"); return -1; } @@ -130,6 +135,7 @@ sl_pp_process_define(struct sl_pp_context *context, if (!macro) { macro = sl_pp_macro_new(); if (!macro) { + strcpy(context->error_msg, "out of memory"); return -1; } @@ -149,7 +155,7 @@ sl_pp_process_define(struct sl_pp_context *context, */ if (first < last && input[first].token == SL_PP_LPAREN) { first++; - if (_parse_formal_args(input, &first, last, macro)) { + if (_parse_formal_args(context, input, &first, last, macro)) { return -1; } } @@ -164,6 +170,7 @@ sl_pp_process_define(struct sl_pp_context *context, macro->body = malloc(sizeof(struct sl_pp_token_info) * body_len); if (!macro->body) { + strcpy(context->error_msg, "out of memory"); return -1; } diff --git a/src/glsl/pp/sl_pp_expression.c b/src/glsl/pp/sl_pp_expression.c index a692430abbf..6b2329ed1a7 100644 --- a/src/glsl/pp/sl_pp_expression.c +++ b/src/glsl/pp/sl_pp_expression.c @@ -47,6 +47,7 @@ _parse_primary(struct parse_context *ctx, ctx->input++; } else { if (ctx->input->token != SL_PP_LPAREN) { + strcpy(ctx->context->error_msg, "expected `('"); return -1; } ctx->input++; @@ -54,6 +55,7 @@ _parse_primary(struct parse_context *ctx, return -1; } if (ctx->input->token != SL_PP_RPAREN) { + strcpy(ctx->context->error_msg, "expected `)'"); return -1; } ctx->input++; diff --git a/src/glsl/pp/sl_pp_if.c b/src/glsl/pp/sl_pp_if.c index 90b80512375..44bbefa3577 100644 --- a/src/glsl/pp/sl_pp_if.c +++ b/src/glsl/pp/sl_pp_if.c @@ -59,7 +59,7 @@ _parse_defined(struct sl_pp_context *context, } if (input[*pi].token != SL_PP_IDENTIFIER) { - /* Identifier expected. */ + strcpy(context->error_msg, "expected an identifier"); return -1; } @@ -75,7 +75,7 @@ _parse_defined(struct sl_pp_context *context, if (parens) { skip_whitespace(input, pi); if (input[*pi].token != SL_PP_RPAREN) { - /* `)' expected */ + strcpy(context->error_msg, "expected `)'"); return -1; } (*pi)++; @@ -91,10 +91,15 @@ _parse_defined(struct sl_pp_context *context, return -1; } - return sl_pp_process_out(state, &result); + if (sl_pp_process_out(state, &result)) { + strcpy(context->error_msg, "out of memory"); + return -1; + } + + return 0; } -static int +static unsigned int _evaluate_if_stack(struct sl_pp_context *context) { unsigned int i; @@ -119,7 +124,7 @@ _parse_if(struct sl_pp_context *context, int result; if (!context->if_ptr) { - /* #if nesting too deep. */ + strcpy(context->error_msg, "`#if' nesting too deep"); return -1; } @@ -151,6 +156,7 @@ _parse_if(struct sl_pp_context *context, default: if (sl_pp_process_out(&state, &input[i])) { + strcpy(context->error_msg, "out of memory"); free(state.out); return -1; } @@ -160,6 +166,7 @@ _parse_if(struct sl_pp_context *context, eof.token = SL_PP_EOF; if (sl_pp_process_out(&state, &eof)) { + strcpy(context->error_msg, "out of memory"); free(state.out); return -1; } @@ -182,13 +189,13 @@ static int _parse_else(struct sl_pp_context *context) { if (context->if_ptr == SL_PP_MAX_IF_NESTING) { - /* No matching #if. */ + strcpy(context->error_msg, "no matching `#if'"); return -1; } /* Bit b1 indicates we already went through #else. */ if (context->if_stack[context->if_ptr] & 2) { - /* No matching #if. */ + strcpy(context->error_msg, "no matching `#if'"); return -1; } @@ -217,7 +224,7 @@ sl_pp_process_ifdef(struct sl_pp_context *context, unsigned int i; if (!context->if_ptr) { - /* #if nesting too deep. */ + strcpy(context->error_msg, "`#if' nesting too deep"); return -1; } @@ -246,12 +253,12 @@ sl_pp_process_ifdef(struct sl_pp_context *context, break; default: - /* Expected an identifier. */ + strcpy(context->error_msg, "expected an identifier"); return -1; } } - /* Expected an identifier. */ + strcpy(context->error_msg, "expected an identifier"); return -1; } @@ -264,7 +271,7 @@ sl_pp_process_ifndef(struct sl_pp_context *context, unsigned int i; if (!context->if_ptr) { - /* #if nesting too deep. */ + strcpy(context->error_msg, "`#if' nesting too deep"); return -1; } @@ -293,12 +300,12 @@ sl_pp_process_ifndef(struct sl_pp_context *context, break; default: - /* Expected an identifier. */ + strcpy(context->error_msg, "expected an identifier"); return -1; } } - /* Expected an identifier. */ + strcpy(context->error_msg, "expected an identifier"); return -1; } @@ -341,7 +348,7 @@ sl_pp_process_endif(struct sl_pp_context *context, unsigned int last) { if (context->if_ptr == SL_PP_MAX_IF_NESTING) { - /* No matching #if. */ + strcpy(context->error_msg, "no matching `#if'"); return -1; } diff --git a/src/glsl/pp/sl_pp_line.c b/src/glsl/pp/sl_pp_line.c index a56417a8610..c38f4b0f2e6 100644 --- a/src/glsl/pp/sl_pp_line.c +++ b/src/glsl/pp/sl_pp_line.c @@ -29,31 +29,6 @@ #include "sl_pp_process.h" -static int -_parse_integer(const char *input, - unsigned int *number) -{ - unsigned int n = 0; - - while (*input >= '0' && *input <= '9') { - if (n * 10 < n) { - /* Overflow. */ - return -1; - } - - n = n * 10 + (*input++ - '0'); - } - - if (*input != '\0') { - /* Invalid decimal number. */ - return -1; - } - - *number = n; - return 0; -} - - int sl_pp_process_line(struct sl_pp_context *context, const struct sl_pp_token_info *input, @@ -65,7 +40,6 @@ sl_pp_process_line(struct sl_pp_context *context, struct sl_pp_process_state state; int line_number = -1; int file_number = -1; - const char *str; unsigned int line; memset(&state, 0, sizeof(state)); @@ -84,6 +58,7 @@ sl_pp_process_line(struct sl_pp_context *context, default: if (sl_pp_process_out(&state, &input[i])) { + strcpy(context->error_msg, "out of memory"); free(state.out); return -1; } @@ -94,7 +69,7 @@ sl_pp_process_line(struct sl_pp_context *context, if (state.out_len > 0 && state.out[0].token == SL_PP_NUMBER) { line_number = state.out[0].data.number; } else { - strcpy(context->error_msg, "expected number after `#line'"); + strcpy(context->error_msg, "expected a number after `#line'"); free(state.out); return -1; } @@ -103,13 +78,13 @@ sl_pp_process_line(struct sl_pp_context *context, if (state.out[1].token == SL_PP_NUMBER) { file_number = state.out[1].data.number; } else { - strcpy(context->error_msg, "expected number after line number"); + strcpy(context->error_msg, "expected a number after line number"); free(state.out); return -1; } if (state.out_len > 2) { - strcpy(context->error_msg, "expected end of line after file number"); + strcpy(context->error_msg, "expected an end of line after file number"); free(state.out); return -1; } @@ -117,10 +92,7 @@ sl_pp_process_line(struct sl_pp_context *context, free(state.out); - str = sl_pp_context_cstr(context, line_number); - if (_parse_integer(str, &line)) { - return -1; - } + line = atoi(sl_pp_context_cstr(context, line_number)); if (context->line != line) { struct sl_pp_token_info ti; @@ -128,6 +100,7 @@ sl_pp_process_line(struct sl_pp_context *context, ti.token = SL_PP_LINE; ti.data.line = line; if (sl_pp_process_out(pstate, &ti)) { + strcpy(context->error_msg, "out of memory"); return -1; } @@ -137,10 +110,7 @@ sl_pp_process_line(struct sl_pp_context *context, if (file_number != -1) { unsigned int file; - str = sl_pp_context_cstr(context, file_number); - if (_parse_integer(str, &file)) { - return -1; - } + file_number = atoi(sl_pp_context_cstr(context, file_number)); if (context->file != file) { struct sl_pp_token_info ti; @@ -148,6 +118,7 @@ sl_pp_process_line(struct sl_pp_context *context, ti.token = SL_PP_FILE; ti.data.file = file; if (sl_pp_process_out(pstate, &ti)) { + strcpy(context->error_msg, "out of memory"); return -1; } diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index d14c9825557..7793562781f 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -107,7 +107,12 @@ _out_number(struct sl_pp_context *context, ti.token = SL_PP_NUMBER; ti.data.number = sl_pp_context_add_unique_str(context, buf); - return sl_pp_process_out(state, &ti); + if (sl_pp_process_out(state, &ti)) { + strcpy(context->error_msg, "out of memory"); + return -1; + } + + return 0; } int @@ -125,6 +130,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, unsigned int j; if (input[*pi].token != SL_PP_IDENTIFIER) { + strcpy(context->error_msg, "expected an identifier"); return -1; } @@ -172,6 +178,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, if (!macro) { if (!mute) { if (sl_pp_process_out(state, &input[*pi])) { + strcpy(context->error_msg, "out of memory"); return -1; } } @@ -184,6 +191,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, if (macro->num_args >= 0) { skip_whitespace(input, pi); if (input[*pi].token != SL_PP_LPAREN) { + strcpy(context->error_msg, "expected `('"); return -1; } (*pi)++; @@ -203,6 +211,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, *pmacro = sl_pp_macro_new(); if (!*pmacro) { + strcpy(context->error_msg, "out of memory"); return -1; } @@ -219,6 +228,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, if (j < (unsigned int)macro->num_args - 1) { done = 1; } else { + strcpy(context->error_msg, "too many actual macro arguments"); return -1; } } else { @@ -236,6 +246,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, if (j == (unsigned int)macro->num_args - 1) { done = 1; } else { + strcpy(context->error_msg, "too few actual macro arguments"); return -1; } } else { @@ -245,6 +256,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, break; case SL_PP_EOF: + strcpy(context->error_msg, "too few actual macro arguments"); return -1; default: @@ -254,6 +266,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, (**pmacro).body = malloc(sizeof(struct sl_pp_token_info) * body_len); if (!(**pmacro).body) { + strcpy(context->error_msg, "out of memory"); return -1; } @@ -301,6 +314,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, if (macro->num_args == 0) { skip_whitespace(input, pi); if (input[*pi].token != SL_PP_RPAREN) { + strcpy(context->error_msg, "expected `)'"); return -1; } (*pi)++; @@ -310,6 +324,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, switch (macro->body[j].token) { case SL_PP_NEWLINE: if (sl_pp_process_out(state, ¯o->body[j])) { + strcpy(context->error_msg, "out of memory"); return -1; } j++; @@ -328,6 +343,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, default: if (!mute) { if (sl_pp_process_out(state, ¯o->body[j])) { + strcpy(context->error_msg, "out of memory"); return -1; } } diff --git a/src/glsl/pp/sl_pp_pragma.c b/src/glsl/pp/sl_pp_pragma.c index 059bc6f2886..1cd9fd82348 100644 --- a/src/glsl/pp/sl_pp_pragma.c +++ b/src/glsl/pp/sl_pp_pragma.c @@ -99,6 +99,7 @@ sl_pp_process_pragma(struct sl_pp_context *context, /* Ignore the tokens that follow. */ if (sl_pp_process_out(state, &out)) { + strcpy(context->error_msg, "out of memory"); return -1; } diff --git a/src/glsl/pp/sl_pp_version.c b/src/glsl/pp/sl_pp_version.c index 82acdd1d5a4..6cd63f4925c 100644 --- a/src/glsl/pp/sl_pp_version.c +++ b/src/glsl/pp/sl_pp_version.c @@ -25,34 +25,10 @@ * **************************************************************************/ +#include #include "sl_pp_version.h" -static int -_parse_integer(const char *input, - unsigned int *number) -{ - unsigned int n = 0; - - while (*input >= '0' && *input <= '9') { - if (n * 10 < n) { - /* Overflow. */ - return -1; - } - - n = n * 10 + (*input++ - '0'); - } - - if (*input != '\0') { - /* Invalid decimal number. */ - return -1; - } - - *number = n; - return 0; -} - - int sl_pp_version(struct sl_pp_context *context, const struct sl_pp_token_info *input, @@ -130,19 +106,9 @@ sl_pp_version(struct sl_pp_context *context, break; case SL_PP_NUMBER: - { - const char *num = sl_pp_context_cstr(context, input[i].data.number); - - if (!num) { - return -1; - } - if (_parse_integer(num, version)) { - strcpy(context->error_msg, "expected version number after `#version'"); - return -1; - } - i++; - found_number = 1; - } + *version = atoi(sl_pp_context_cstr(context, input[i].data.number)); + i++; + found_number = 1; break; default: -- cgit v1.2.3 From ce8f486156f5c4b28b51954ea862675275c38f6d Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 17 Sep 2009 12:12:34 +0200 Subject: slang/pp: Use a dictionary for the remaining string literals. --- src/glsl/pp/sl_pp_dict.c | 27 +++++++++++++++++++++++++++ src/glsl/pp/sl_pp_dict.h | 27 +++++++++++++++++++++++++++ src/glsl/pp/sl_pp_if.c | 24 ++++++++++-------------- src/glsl/pp/sl_pp_macro.c | 8 +++----- src/glsl/pp/sl_pp_pragma.c | 20 ++++++++++---------- src/glsl/pp/sl_pp_process.c | 28 ++++++++++++++-------------- src/glsl/pp/sl_pp_version.c | 15 ++++----------- 7 files changed, 95 insertions(+), 54 deletions(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_dict.c b/src/glsl/pp/sl_pp_dict.c index 65b91d9e989..f2885c763d7 100644 --- a/src/glsl/pp/sl_pp_dict.c +++ b/src/glsl/pp/sl_pp_dict.c @@ -52,5 +52,32 @@ sl_pp_dict_init(struct sl_pp_context *context) ADD_NAME(context, warn); ADD_NAME(context, disable); + ADD_NAME(context, defined); + + ADD_NAME_STR(context, ___LINE__, "__LINE__"); + ADD_NAME_STR(context, ___FILE__, "__FILE__"); + ADD_NAME(context, __VERSION__); + + ADD_NAME(context, optimize); + ADD_NAME(context, debug); + + ADD_NAME(context, off); + ADD_NAME(context, on); + + ADD_NAME(context, define); + ADD_NAME(context, elif); + ADD_NAME_STR(context, _else, "else"); + ADD_NAME(context, endif); + ADD_NAME(context, error); + ADD_NAME(context, extension); + ADD_NAME_STR(context, _if, "if"); + ADD_NAME(context, ifdef); + ADD_NAME(context, ifndef); + ADD_NAME(context, line); + ADD_NAME(context, pragma); + ADD_NAME(context, undef); + + ADD_NAME(context, version); + return 0; } diff --git a/src/glsl/pp/sl_pp_dict.h b/src/glsl/pp/sl_pp_dict.h index ce138d98f51..ba82b389b23 100644 --- a/src/glsl/pp/sl_pp_dict.h +++ b/src/glsl/pp/sl_pp_dict.h @@ -37,6 +37,33 @@ struct sl_pp_dict { int enable; int warn; int disable; + + int defined; + + int ___LINE__; + int ___FILE__; + int __VERSION__; + + int optimize; + int debug; + + int off; + int on; + + int define; + int elif; + int _else; + int endif; + int error; + int extension; + int _if; + int ifdef; + int ifndef; + int line; + int pragma; + int undef; + + int version; }; diff --git a/src/glsl/pp/sl_pp_if.c b/src/glsl/pp/sl_pp_if.c index 44bbefa3577..cf1c746d5f6 100644 --- a/src/glsl/pp/sl_pp_if.c +++ b/src/glsl/pp/sl_pp_if.c @@ -136,20 +136,16 @@ _parse_if(struct sl_pp_context *context, break; case SL_PP_IDENTIFIER: - { - const char *id = sl_pp_context_cstr(context, input[i].data.identifier); - - if (!strcmp(id, "defined")) { - i++; - if (_parse_defined(context, input, &i, &state)) { - free(state.out); - return -1; - } - } else { - if (sl_pp_macro_expand(context, input, &i, NULL, &state, 0)) { - free(state.out); - return -1; - } + if (input[i].data.identifier == context->dict.defined) { + i++; + if (_parse_defined(context, input, &i, &state)) { + free(state.out); + return -1; + } + } else { + if (sl_pp_macro_expand(context, input, &i, NULL, &state, 0)) { + free(state.out); + return -1; } } break; diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index 7793562781f..6772100847b 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -124,7 +124,6 @@ sl_pp_macro_expand(struct sl_pp_context *context, int mute) { int macro_name; - const char *macro_str; struct sl_pp_macro *macro = NULL; struct sl_pp_macro *actual_arg = NULL; unsigned int j; @@ -135,23 +134,22 @@ sl_pp_macro_expand(struct sl_pp_context *context, } macro_name = input[*pi].data.identifier; - macro_str = sl_pp_context_cstr(context, macro_name); - if (!strcmp(macro_str, "__LINE__")) { + if (macro_name == context->dict.___LINE__) { if (!mute && _out_number(context, state, context->line)) { return -1; } (*pi)++; return 0; } - if (!strcmp(macro_str, "__FILE__")) { + if (macro_name == context->dict.___FILE__) { if (!mute && _out_number(context, state, context->file)) { return -1; } (*pi)++; return 0; } - if (!strcmp(macro_str, "__VERSION__")) { + if (macro_name == context->dict.__VERSION__) { if (!mute && _out_number(context, state, 110)) { return -1; } diff --git a/src/glsl/pp/sl_pp_pragma.c b/src/glsl/pp/sl_pp_pragma.c index 1cd9fd82348..03269b63db7 100644 --- a/src/glsl/pp/sl_pp_pragma.c +++ b/src/glsl/pp/sl_pp_pragma.c @@ -36,21 +36,21 @@ sl_pp_process_pragma(struct sl_pp_context *context, unsigned int last, struct sl_pp_process_state *state) { - const char *pragma_name = NULL; + int pragma_name = -1; struct sl_pp_token_info out; - const char *arg_name = NULL; + int arg_name = -1; if (first < last && input[first].token == SL_PP_IDENTIFIER) { - pragma_name = sl_pp_context_cstr(context, input[first].data.identifier); + pragma_name = input[first].data.identifier; first++; } - if (!pragma_name) { + if (pragma_name == -1) { return 0; } - if (!strcmp(pragma_name, "optimize")) { + if (pragma_name == context->dict.optimize) { out.token = SL_PP_PRAGMA_OPTIMIZE; - } else if (!strcmp(pragma_name, "debug")) { + } else if (pragma_name == context->dict.debug) { out.token = SL_PP_PRAGMA_DEBUG; } else { return 0; @@ -71,16 +71,16 @@ sl_pp_process_pragma(struct sl_pp_context *context, } if (first < last && input[first].token == SL_PP_IDENTIFIER) { - arg_name = sl_pp_context_cstr(context, input[first].data.identifier); + arg_name = input[first].data.identifier; first++; } - if (!arg_name) { + if (arg_name == -1) { return 0; } - if (!strcmp(arg_name, "off")) { + if (arg_name == context->dict.off) { out.data.pragma = 0; - } else if (!strcmp(arg_name, "on")) { + } else if (arg_name == context->dict.on) { out.data.pragma = 1; } else { return 0; diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index 03a3051838f..ab2f2d8eb45 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -100,14 +100,14 @@ sl_pp_process(struct sl_pp_context *context, switch (input[i].token) { case SL_PP_IDENTIFIER: { - const char *name; + int name; int found_eol = 0; unsigned int first; unsigned int last; struct sl_pp_token_info endof; /* Directive name. */ - name = sl_pp_context_cstr(context, input[i].data.identifier); + name = input[i].data.identifier; i++; skip_whitespace(input, &i); @@ -136,51 +136,51 @@ sl_pp_process(struct sl_pp_context *context, last = i - 1; - if (!strcmp(name, "if")) { + if (name == context->dict._if) { if (sl_pp_process_if(context, input, first, last)) { return -1; } - } else if (!strcmp(name, "ifdef")) { + } else if (name == context->dict.ifdef) { if (sl_pp_process_ifdef(context, input, first, last)) { return -1; } - } else if (!strcmp(name, "ifndef")) { + } else if (name == context->dict.ifndef) { if (sl_pp_process_ifndef(context, input, first, last)) { return -1; } - } else if (!strcmp(name, "elif")) { + } else if (name == context->dict.elif) { if (sl_pp_process_elif(context, input, first, last)) { return -1; } - } else if (!strcmp(name, "else")) { + } else if (name == context->dict._else) { if (sl_pp_process_else(context, input, first, last)) { return -1; } - } else if (!strcmp(name, "endif")) { + } else if (name == context->dict.endif) { if (sl_pp_process_endif(context, input, first, last)) { return -1; } } else if (context->if_value) { - if (!strcmp(name, "define")) { + if (name == context->dict.define) { if (sl_pp_process_define(context, input, first, last)) { return -1; } - } else if (!strcmp(name, "error")) { + } else if (name == context->dict.error) { sl_pp_process_error(context, input, first, last); return -1; - } else if (!strcmp(name, "extension")) { + } else if (name == context->dict.extension) { if (sl_pp_process_extension(context, input, first, last, &state)) { return -1; } - } else if (!strcmp(name, "line")) { + } else if (name == context->dict.line) { if (sl_pp_process_line(context, input, first, last, &state)) { return -1; } - } else if (!strcmp(name, "pragma")) { + } else if (name == context->dict.pragma) { if (sl_pp_process_pragma(context, input, first, last, &state)) { return -1; } - } else if (!strcmp(name, "undef")) { + } else if (name == context->dict.undef) { if (sl_pp_process_undef(context, input, first, last)) { return -1; } diff --git a/src/glsl/pp/sl_pp_version.c b/src/glsl/pp/sl_pp_version.c index 6cd63f4925c..814da46a672 100644 --- a/src/glsl/pp/sl_pp_version.c +++ b/src/glsl/pp/sl_pp_version.c @@ -79,18 +79,11 @@ sl_pp_version(struct sl_pp_context *context, break; case SL_PP_IDENTIFIER: - { - const char *id = sl_pp_context_cstr(context, input[i].data.identifier); - - if (!id) { - return -1; - } - if (strcmp(id, "version")) { - return 0; - } - i++; - found_version = 1; + if (input[i].data.identifier != context->dict.version) { + return 0; } + i++; + found_version = 1; break; default: -- cgit v1.2.3 From 4fcda5000eed29b7c2ba70506ae34b209239eec6 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 17 Sep 2009 12:14:12 +0200 Subject: slang/pp: Fix file number parsing. --- src/glsl/pp/sl_pp_line.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_line.c b/src/glsl/pp/sl_pp_line.c index c38f4b0f2e6..504c20ebcdd 100644 --- a/src/glsl/pp/sl_pp_line.c +++ b/src/glsl/pp/sl_pp_line.c @@ -110,7 +110,7 @@ sl_pp_process_line(struct sl_pp_context *context, if (file_number != -1) { unsigned int file; - file_number = atoi(sl_pp_context_cstr(context, file_number)); + file = atoi(sl_pp_context_cstr(context, file_number)); if (context->file != file) { struct sl_pp_token_info ti; -- cgit v1.2.3 From 90daefd1c474a6e0502df5053b581987c12b8673 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 17 Sep 2009 12:33:26 +0200 Subject: glsl/pp: Add a TODO for FEATURE_es2_glsl. --- src/glsl/pp/sl_pp_macro.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index 6772100847b..878b22ed9c3 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -157,6 +157,11 @@ sl_pp_macro_expand(struct sl_pp_context *context, return 0; } + /* TODO: For FEATURE_es2_glsl, expand to 1 the following symbols. + * GL_ES + * GL_FRAGMENT_PRECISION_HIGH + */ + if (local) { for (macro = local; macro; macro = macro->next) { if (macro->name == macro_name) { -- cgit v1.2.3 From 95956bb8cb9513c429b9749426720be94f4cf5a8 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 18 Sep 2009 11:19:25 +0200 Subject: glsl/pp: Define a public interface for external modules. Make sl_pp_context struct opaque. Move all public declarations to sl_pp_public.h. --- src/glsl/pp/sl_pp_context.c | 29 ++++++++++++++++----- src/glsl/pp/sl_pp_context.h | 10 ------- src/glsl/pp/sl_pp_line.c | 1 + src/glsl/pp/sl_pp_process.h | 5 ---- src/glsl/pp/sl_pp_public.h | 63 +++++++++++++++++++++++++++++++++++++++++++++ src/glsl/pp/sl_pp_token.c | 1 + src/glsl/pp/sl_pp_token.h | 2 -- src/glsl/pp/sl_pp_version.c | 3 ++- src/glsl/pp/sl_pp_version.h | 41 ----------------------------- 9 files changed, 89 insertions(+), 66 deletions(-) create mode 100644 src/glsl/pp/sl_pp_public.h delete mode 100644 src/glsl/pp/sl_pp_version.h (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index b196d8102a0..fd205de5d32 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -26,17 +26,23 @@ **************************************************************************/ #include +#include "sl_pp_public.h" #include "sl_pp_context.h" -int -sl_pp_context_init(struct sl_pp_context *context) +struct sl_pp_context * +sl_pp_context_create(void) { - memset(context, 0, sizeof(struct sl_pp_context)); + struct sl_pp_context *context; + + context = calloc(1, sizeof(struct sl_pp_context)); + if (!context) { + return NULL; + } if (sl_pp_dict_init(context)) { sl_pp_context_destroy(context); - return -1; + return NULL; } context->macro_tail = &context->macro; @@ -46,14 +52,23 @@ sl_pp_context_init(struct sl_pp_context *context) context->line = 1; context->file = 0; - return 0; + return context; } void sl_pp_context_destroy(struct sl_pp_context *context) { - free(context->cstr_pool); - sl_pp_macro_free(context->macro); + if (context) { + free(context->cstr_pool); + sl_pp_macro_free(context->macro); + free(context); + } +} + +const char * +sl_pp_context_error_message(const struct sl_pp_context *context) +{ + return context->error_msg; } int diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index 8bed1420454..6b8cc2f960d 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -55,18 +55,8 @@ struct sl_pp_context { unsigned int file; }; -int -sl_pp_context_init(struct sl_pp_context *context); - -void -sl_pp_context_destroy(struct sl_pp_context *context); - int sl_pp_context_add_unique_str(struct sl_pp_context *context, const char *str); -const char * -sl_pp_context_cstr(const struct sl_pp_context *context, - int offset); - #endif /* SL_PP_CONTEXT_H */ diff --git a/src/glsl/pp/sl_pp_line.c b/src/glsl/pp/sl_pp_line.c index 504c20ebcdd..cab0262686c 100644 --- a/src/glsl/pp/sl_pp_line.c +++ b/src/glsl/pp/sl_pp_line.c @@ -26,6 +26,7 @@ **************************************************************************/ #include +#include "sl_pp_public.h" #include "sl_pp_process.h" diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h index adc08c18ae3..24311bab603 100644 --- a/src/glsl/pp/sl_pp_process.h +++ b/src/glsl/pp/sl_pp_process.h @@ -39,11 +39,6 @@ struct sl_pp_process_state { unsigned int out_max; }; -int -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, diff --git a/src/glsl/pp/sl_pp_public.h b/src/glsl/pp/sl_pp_public.h new file mode 100644 index 00000000000..b1d92d02a7a --- /dev/null +++ b/src/glsl/pp/sl_pp_public.h @@ -0,0 +1,63 @@ +/************************************************************************** + * + * 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_PUBLIC_H +#define SL_PP_PUBLIC_H + + +struct sl_pp_context; + + +#include "sl_pp_purify.h" +#include "sl_pp_token.h" + + +struct sl_pp_context * +sl_pp_context_create(void); + +void +sl_pp_context_destroy(struct sl_pp_context *context); + +const char * +sl_pp_context_error_message(const struct sl_pp_context *context); + +const char * +sl_pp_context_cstr(const struct sl_pp_context *context, + int offset); + +int +sl_pp_version(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + unsigned int *version, + unsigned int *tokens_eaten); + +int +sl_pp_process(struct sl_pp_context *context, + const struct sl_pp_token_info *input, + struct sl_pp_token_info **output); + +#endif /* SL_PP_PUBLIC_H */ diff --git a/src/glsl/pp/sl_pp_token.c b/src/glsl/pp/sl_pp_token.c index a6a2bb27485..3a7ffe7db15 100644 --- a/src/glsl/pp/sl_pp_token.c +++ b/src/glsl/pp/sl_pp_token.c @@ -26,6 +26,7 @@ **************************************************************************/ #include +#include "sl_pp_context.h" #include "sl_pp_token.h" diff --git a/src/glsl/pp/sl_pp_token.h b/src/glsl/pp/sl_pp_token.h index 59019593839..4131be6bdad 100644 --- a/src/glsl/pp/sl_pp_token.h +++ b/src/glsl/pp/sl_pp_token.h @@ -28,8 +28,6 @@ #ifndef SL_PP_TOKEN_H #define SL_PP_TOKEN_H -#include "sl_pp_context.h" - enum sl_pp_token { SL_PP_WHITESPACE, diff --git a/src/glsl/pp/sl_pp_version.c b/src/glsl/pp/sl_pp_version.c index 814da46a672..825967d4c10 100644 --- a/src/glsl/pp/sl_pp_version.c +++ b/src/glsl/pp/sl_pp_version.c @@ -26,7 +26,8 @@ **************************************************************************/ #include -#include "sl_pp_version.h" +#include "sl_pp_public.h" +#include "sl_pp_context.h" int diff --git a/src/glsl/pp/sl_pp_version.h b/src/glsl/pp/sl_pp_version.h deleted file mode 100644 index cee9f55bc6c..00000000000 --- a/src/glsl/pp/sl_pp_version.h +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************** - * - * 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_VERSION_H -#define SL_PP_VERSION_H - -#include "sl_pp_context.h" -#include "sl_pp_token.h" - - -int -sl_pp_version(struct sl_pp_context *context, - const struct sl_pp_token_info *input, - unsigned int *version, - unsigned int *tokens_eaten); - -#endif /* SL_PP_VERSION_H */ -- cgit v1.2.3 From 0481e85af7195e13c30580afba233a80feeee740 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 22 Sep 2009 12:51:08 +0200 Subject: glsl/pp: Differentiate between integer and floating-point number tokens. --- src/glsl/pp/sl_pp_error.c | 8 ++++++-- src/glsl/pp/sl_pp_expression.c | 4 ++-- src/glsl/pp/sl_pp_if.c | 8 ++++---- src/glsl/pp/sl_pp_line.c | 8 ++++---- src/glsl/pp/sl_pp_macro.c | 4 ++-- src/glsl/pp/sl_pp_token.c | 19 +++++++++++++++---- src/glsl/pp/sl_pp_token.h | 6 ++++-- src/glsl/pp/sl_pp_version.c | 4 ++-- 8 files changed, 39 insertions(+), 22 deletions(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_error.c b/src/glsl/pp/sl_pp_error.c index d42568d23dc..e591f4beef9 100644 --- a/src/glsl/pp/sl_pp_error.c +++ b/src/glsl/pp/sl_pp_error.c @@ -239,8 +239,12 @@ sl_pp_process_error(struct sl_pp_context *context, s = sl_pp_context_cstr(context, input[i].data.identifier); break; - case SL_PP_NUMBER: - s = sl_pp_context_cstr(context, input[i].data.number); + case SL_PP_UINT: + s = sl_pp_context_cstr(context, input[i].data._uint); + break; + + case SL_PP_FLOAT: + s = sl_pp_context_cstr(context, input[i].data._float); break; case SL_PP_OTHER: diff --git a/src/glsl/pp/sl_pp_expression.c b/src/glsl/pp/sl_pp_expression.c index 6b2329ed1a7..5093ef6cc9d 100644 --- a/src/glsl/pp/sl_pp_expression.c +++ b/src/glsl/pp/sl_pp_expression.c @@ -42,8 +42,8 @@ static int _parse_primary(struct parse_context *ctx, int *result) { - if (ctx->input->token == SL_PP_NUMBER) { - *result = atoi(sl_pp_context_cstr(ctx->context, ctx->input->data.number)); + if (ctx->input->token == SL_PP_UINT) { + *result = atoi(sl_pp_context_cstr(ctx->context, ctx->input->data._uint)); ctx->input++; } else { if (ctx->input->token != SL_PP_LPAREN) { diff --git a/src/glsl/pp/sl_pp_if.c b/src/glsl/pp/sl_pp_if.c index cf1c746d5f6..5fa27fcf053 100644 --- a/src/glsl/pp/sl_pp_if.c +++ b/src/glsl/pp/sl_pp_if.c @@ -81,13 +81,13 @@ _parse_defined(struct sl_pp_context *context, (*pi)++; } - result.token = SL_PP_NUMBER; + result.token = SL_PP_UINT; if (defined) { - result.data.number = sl_pp_context_add_unique_str(context, "1"); + result.data._uint = sl_pp_context_add_unique_str(context, "1"); } else { - result.data.number = sl_pp_context_add_unique_str(context, "0"); + result.data._uint = sl_pp_context_add_unique_str(context, "0"); } - if (result.data.number == -1) { + if (result.data._uint == -1) { return -1; } diff --git a/src/glsl/pp/sl_pp_line.c b/src/glsl/pp/sl_pp_line.c index cab0262686c..e8f751003ac 100644 --- a/src/glsl/pp/sl_pp_line.c +++ b/src/glsl/pp/sl_pp_line.c @@ -67,8 +67,8 @@ sl_pp_process_line(struct sl_pp_context *context, } } - if (state.out_len > 0 && state.out[0].token == SL_PP_NUMBER) { - line_number = state.out[0].data.number; + if (state.out_len > 0 && state.out[0].token == SL_PP_UINT) { + line_number = state.out[0].data._uint; } else { strcpy(context->error_msg, "expected a number after `#line'"); free(state.out); @@ -76,8 +76,8 @@ sl_pp_process_line(struct sl_pp_context *context, } if (state.out_len > 1) { - if (state.out[1].token == SL_PP_NUMBER) { - file_number = state.out[1].data.number; + if (state.out[1].token == SL_PP_UINT) { + file_number = state.out[1].data._uint; } else { strcpy(context->error_msg, "expected a number after line number"); free(state.out); diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index 878b22ed9c3..3956ba3b574 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -105,8 +105,8 @@ _out_number(struct sl_pp_context *context, sprintf(buf, "%u", number); - ti.token = SL_PP_NUMBER; - ti.data.number = sl_pp_context_add_unique_str(context, buf); + ti.token = SL_PP_UINT; + ti.data._uint = sl_pp_context_add_unique_str(context, buf); if (sl_pp_process_out(state, &ti)) { strcpy(context->error_msg, "out of memory"); return -1; diff --git a/src/glsl/pp/sl_pp_token.c b/src/glsl/pp/sl_pp_token.c index 3a7ffe7db15..99a32a6e671 100644 --- a/src/glsl/pp/sl_pp_token.c +++ b/src/glsl/pp/sl_pp_token.c @@ -271,6 +271,7 @@ _tokenise_number(struct sl_pp_context *context, { const char *input = *pinput; unsigned int eaten; + unsigned int is_float = 0; char number[256]; /* XXX: Remove this artifical limit. */ eaten = _parse_float(input); @@ -282,6 +283,8 @@ _tokenise_number(struct sl_pp_context *context, eaten = _parse_dec(input); } } + } else { + is_float = 1; } if (!eaten || _is_identifier_char(input[eaten])) { @@ -297,10 +300,18 @@ _tokenise_number(struct sl_pp_context *context, memcpy(number, input, eaten); number[eaten] = '\0'; - info->token = SL_PP_NUMBER; - info->data.number = sl_pp_context_add_unique_str(context, number); - if (info->data.number == -1) { - return -1; + if (is_float) { + info->token = SL_PP_FLOAT; + info->data._float = sl_pp_context_add_unique_str(context, number); + if (info->data._float == -1) { + return -1; + } + } else { + info->token = SL_PP_UINT; + info->data._uint = sl_pp_context_add_unique_str(context, number); + if (info->data._uint == -1) { + return -1; + } } *pinput = input + eaten; diff --git a/src/glsl/pp/sl_pp_token.h b/src/glsl/pp/sl_pp_token.h index 4131be6bdad..2a7b79ea3f7 100644 --- a/src/glsl/pp/sl_pp_token.h +++ b/src/glsl/pp/sl_pp_token.h @@ -82,7 +82,8 @@ enum sl_pp_token { SL_PP_IDENTIFIER, - SL_PP_NUMBER, + SL_PP_UINT, + SL_PP_FLOAT, SL_PP_OTHER, @@ -102,7 +103,8 @@ enum sl_pp_token { union sl_pp_token_data { int identifier; - int number; + int _uint; + int _float; char other; int pragma; int extension; diff --git a/src/glsl/pp/sl_pp_version.c b/src/glsl/pp/sl_pp_version.c index 825967d4c10..adf3017bf21 100644 --- a/src/glsl/pp/sl_pp_version.c +++ b/src/glsl/pp/sl_pp_version.c @@ -99,8 +99,8 @@ sl_pp_version(struct sl_pp_context *context, i++; break; - case SL_PP_NUMBER: - *version = atoi(sl_pp_context_cstr(context, input[i].data.number)); + case SL_PP_UINT: + *version = atoi(sl_pp_context_cstr(context, input[i].data._uint)); i++; found_number = 1; break; -- cgit v1.2.3 From 32966991c629fa43818f42912deb9deca913ef60 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 23 Sep 2009 09:33:12 +0200 Subject: glsl/pp: Check for reserved macro names. --- src/glsl/pp/sl_pp_define.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c index 391178aa696..d18a7ee2895 100644 --- a/src/glsl/pp/sl_pp_define.c +++ b/src/glsl/pp/sl_pp_define.c @@ -26,7 +26,9 @@ **************************************************************************/ #include +#include #include "sl_pp_process.h" +#include "sl_pp_public.h" static void @@ -126,6 +128,20 @@ sl_pp_process_define(struct sl_pp_context *context, return -1; } + /* Check for reserved macro names */ + { + const char *name = sl_pp_context_cstr(context, macro_name); + + if (strstr(name, "__")) { + strcpy(context->error_msg, "macro names containing `__' are reserved"); + return 1; + } + if (name[0] == 'G' && name[1] == 'L' && name[2] == '_') { + strcpy(context->error_msg, "macro names prefixed with `GL_' are reserved"); + return 1; + } + } + for (macro = context->macro; macro; macro = macro->next) { if (macro->name == macro_name) { break; -- cgit v1.2.3 From 2f89e1a5a18c4c3c88d4e7613cbfc0f85a5fcfc9 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 23 Sep 2009 09:37:37 +0200 Subject: glsl/pp: Add `0' and `1' to dictionary. --- src/glsl/pp/sl_pp_dict.c | 3 +++ src/glsl/pp/sl_pp_dict.h | 3 +++ src/glsl/pp/sl_pp_if.c | 9 +-------- 3 files changed, 7 insertions(+), 8 deletions(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_dict.c b/src/glsl/pp/sl_pp_dict.c index f2885c763d7..0e1fa368577 100644 --- a/src/glsl/pp/sl_pp_dict.c +++ b/src/glsl/pp/sl_pp_dict.c @@ -79,5 +79,8 @@ sl_pp_dict_init(struct sl_pp_context *context) ADD_NAME(context, version); + ADD_NAME_STR(context, _0, "0"); + ADD_NAME_STR(context, _1, "1"); + return 0; } diff --git a/src/glsl/pp/sl_pp_dict.h b/src/glsl/pp/sl_pp_dict.h index ba82b389b23..683752e000a 100644 --- a/src/glsl/pp/sl_pp_dict.h +++ b/src/glsl/pp/sl_pp_dict.h @@ -64,6 +64,9 @@ struct sl_pp_dict { int undef; int version; + + int _0; + int _1; }; diff --git a/src/glsl/pp/sl_pp_if.c b/src/glsl/pp/sl_pp_if.c index 5fa27fcf053..c8e958eab49 100644 --- a/src/glsl/pp/sl_pp_if.c +++ b/src/glsl/pp/sl_pp_if.c @@ -82,14 +82,7 @@ _parse_defined(struct sl_pp_context *context, } result.token = SL_PP_UINT; - if (defined) { - result.data._uint = sl_pp_context_add_unique_str(context, "1"); - } else { - result.data._uint = sl_pp_context_add_unique_str(context, "0"); - } - if (result.data._uint == -1) { - return -1; - } + result.data._uint = (defined ? context->dict._1 : context->dict._0); if (sl_pp_process_out(state, &result)) { strcpy(context->error_msg, "out of memory"); -- cgit v1.2.3 From 1ed1dc8b4197ef5a6b0b1fab6ef0694f379642d8 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 23 Sep 2009 09:40:24 +0200 Subject: glsl/pp: Include missing headers. --- src/glsl/pp/sl_pp_error.c | 1 + src/glsl/pp/sl_pp_expression.c | 1 + 2 files changed, 2 insertions(+) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_error.c b/src/glsl/pp/sl_pp_error.c index e591f4beef9..df9b191dfeb 100644 --- a/src/glsl/pp/sl_pp_error.c +++ b/src/glsl/pp/sl_pp_error.c @@ -27,6 +27,7 @@ #include #include "sl_pp_process.h" +#include "sl_pp_public.h" void diff --git a/src/glsl/pp/sl_pp_expression.c b/src/glsl/pp/sl_pp_expression.c index 5093ef6cc9d..3f6dfb5a6d3 100644 --- a/src/glsl/pp/sl_pp_expression.c +++ b/src/glsl/pp/sl_pp_expression.c @@ -27,6 +27,7 @@ #include #include "sl_pp_expression.h" +#include "sl_pp_public.h" struct parse_context { -- 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') diff --git a/src/glsl/pp/sl_pp_line.c b/src/glsl/pp/sl_pp_line.c index e8f751003ac..41ddaf6ba25 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 ab2f2d8eb45..67ed5888187 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 2a7b79ea3f7..b1f3389b32c 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 a58360dbc2ee1ef919ecd50bd46cb57a151b8550 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 24 Sep 2009 09:04:15 +0200 Subject: glsl/pp: Use struct instead of union. --- src/glsl/pp/sl_pp_token.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_token.h b/src/glsl/pp/sl_pp_token.h index b1f3389b32c..cece30b62dd 100644 --- a/src/glsl/pp/sl_pp_token.h +++ b/src/glsl/pp/sl_pp_token.h @@ -107,7 +107,7 @@ union sl_pp_token_data { char other; int pragma; int extension; - union { + struct { unsigned int lineno: 24; unsigned int fileno: 8; } line; -- cgit v1.2.3 From e1eed5670246e08119ed7e4afa5313e7717b8128 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 24 Sep 2009 10:56:01 +0200 Subject: glsl/pp: Allow builds on all platforms. --- src/glsl/pp/SConscript | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/SConscript b/src/glsl/pp/SConscript index 621db1e765c..5bd615c8d7f 100644 --- a/src/glsl/pp/SConscript +++ b/src/glsl/pp/SConscript @@ -1,8 +1,5 @@ Import('*') -if env['platform'] not in ['windows']: - Return() - env = env.Clone() glsl = env.StaticLibrary( -- 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') diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index fd205de5d32..8ce189d955c 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 df9b191dfeb..a9eeff98ba5 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 3f6dfb5a6d3..ec904787dd7 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 33193d03a8c..4148fd9a5a3 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 c8e958eab49..a0b3635dd5a 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 41ddaf6ba25..fc2dd89e68b 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 03269b63db7..489eb17b8eb 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 67ed5888187..4b783e40b4d 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 99a32a6e671..f232dafc682 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 adf3017bf21..db06523749c 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 69fec23251740c3071ffc3fefc8981599bdb22ef Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 24 Sep 2009 10:57:32 +0200 Subject: glsl/pp: Avoid using `__VERSION__' as an identifier. --- src/glsl/pp/sl_pp_dict.c | 2 +- src/glsl/pp/sl_pp_dict.h | 5 ++++- src/glsl/pp/sl_pp_macro.c | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_dict.c b/src/glsl/pp/sl_pp_dict.c index 0e1fa368577..82fb9127b50 100644 --- a/src/glsl/pp/sl_pp_dict.c +++ b/src/glsl/pp/sl_pp_dict.c @@ -56,7 +56,7 @@ sl_pp_dict_init(struct sl_pp_context *context) ADD_NAME_STR(context, ___LINE__, "__LINE__"); ADD_NAME_STR(context, ___FILE__, "__FILE__"); - ADD_NAME(context, __VERSION__); + ADD_NAME_STR(context, ___VERSION__, "__VERSION__"); ADD_NAME(context, optimize); ADD_NAME(context, debug); diff --git a/src/glsl/pp/sl_pp_dict.h b/src/glsl/pp/sl_pp_dict.h index 683752e000a..49f0e0bf9fa 100644 --- a/src/glsl/pp/sl_pp_dict.h +++ b/src/glsl/pp/sl_pp_dict.h @@ -28,6 +28,9 @@ #ifndef SL_PP_DICT_H #define SL_PP_DICT_H + +struct sl_pp_context; + struct sl_pp_dict { int all; int _GL_ARB_draw_buffers; @@ -42,7 +45,7 @@ struct sl_pp_dict { int ___LINE__; int ___FILE__; - int __VERSION__; + int ___VERSION__; int optimize; int debug; diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index 3956ba3b574..a4e78861d69 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -27,6 +27,7 @@ #include #include +#include #include "sl_pp_macro.h" #include "sl_pp_process.h" @@ -149,7 +150,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, (*pi)++; return 0; } - if (macro_name == context->dict.__VERSION__) { + if (macro_name == context->dict.___VERSION__) { if (!mute && _out_number(context, state, 110)) { return -1; } -- cgit v1.2.3 From 92e33569f39a2fa9061a0c35c233c1db33820033 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 24 Sep 2009 10:57:55 +0200 Subject: glsl/pp: Add forward decls to silence gcc warnings. --- src/glsl/pp/sl_pp_macro.h | 3 +++ src/glsl/pp/sl_pp_token.h | 2 ++ 2 files changed, 5 insertions(+) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_macro.h b/src/glsl/pp/sl_pp_macro.h index 7af11c5ece7..e3ae2fc7125 100644 --- a/src/glsl/pp/sl_pp_macro.h +++ b/src/glsl/pp/sl_pp_macro.h @@ -31,6 +31,9 @@ #include "sl_pp_token.h" +struct sl_pp_context; +struct sl_pp_process_state; + struct sl_pp_macro_formal_arg { int name; struct sl_pp_macro_formal_arg *next; diff --git a/src/glsl/pp/sl_pp_token.h b/src/glsl/pp/sl_pp_token.h index cece30b62dd..29c7571711e 100644 --- a/src/glsl/pp/sl_pp_token.h +++ b/src/glsl/pp/sl_pp_token.h @@ -29,6 +29,8 @@ #define SL_PP_TOKEN_H +struct sl_pp_context; + enum sl_pp_token { SL_PP_WHITESPACE, SL_PP_NEWLINE, -- cgit v1.2.3 From c4bd6ccde8241d6a5eb631c713ba79db51163701 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 28 Sep 2009 11:30:15 +0200 Subject: glsl/pp: Expand macro actual arguments before pasting into its body. --- src/glsl/pp/sl_pp_macro.c | 102 ++++++++++++++++++++++++---------------------- 1 file changed, 53 insertions(+), 49 deletions(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index a4e78861d69..d6c32a0e782 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -136,6 +136,9 @@ sl_pp_macro_expand(struct sl_pp_context *context, macro_name = input[*pi].data.identifier; + /* First look for predefined macros. + */ + if (macro_name == context->dict.___LINE__) { if (!mute && _out_number(context, state, context->line)) { return -1; @@ -207,55 +210,73 @@ sl_pp_macro_expand(struct sl_pp_context *context, struct sl_pp_macro **pmacro = &actual_arg; for (j = 0; j < (unsigned int)macro->num_args; j++) { - unsigned int body_len; + struct sl_pp_process_state arg_state; unsigned int i; int done = 0; unsigned int paren_nesting = 0; - unsigned int k; - - *pmacro = sl_pp_macro_new(); - if (!*pmacro) { - strcpy(context->error_msg, "out of memory"); - return -1; - } + struct sl_pp_token_info eof; - (**pmacro).name = formal_arg->name; + memset(&arg_state, 0, sizeof(arg_state)); - body_len = 1; - for (i = *pi; !done; i++) { + for (i = *pi; !done;) { switch (input[i].token) { case SL_PP_WHITESPACE: + i++; break; case SL_PP_COMMA: if (!paren_nesting) { if (j < (unsigned int)macro->num_args - 1) { done = 1; + i++; } else { strcpy(context->error_msg, "too many actual macro arguments"); return -1; } } else { - body_len++; + if (sl_pp_process_out(&arg_state, &input[i])) { + strcpy(context->error_msg, "out of memory"); + free(arg_state.out); + return -1; + } + i++; } break; case SL_PP_LPAREN: paren_nesting++; - body_len++; + if (sl_pp_process_out(&arg_state, &input[i])) { + strcpy(context->error_msg, "out of memory"); + free(arg_state.out); + return -1; + } + i++; break; case SL_PP_RPAREN: if (!paren_nesting) { if (j == (unsigned int)macro->num_args - 1) { done = 1; + i++; } else { strcpy(context->error_msg, "too few actual macro arguments"); return -1; } } else { paren_nesting--; - body_len++; + if (sl_pp_process_out(&arg_state, &input[i])) { + strcpy(context->error_msg, "out of memory"); + free(arg_state.out); + return -1; + } + i++; + } + break; + + case SL_PP_IDENTIFIER: + if (sl_pp_macro_expand(context, input, &i, local, &arg_state, 0)) { + free(arg_state.out); + return -1; } break; @@ -264,50 +285,33 @@ sl_pp_macro_expand(struct sl_pp_context *context, return -1; default: - body_len++; + if (sl_pp_process_out(&arg_state, &input[i])) { + strcpy(context->error_msg, "out of memory"); + free(arg_state.out); + return -1; + } + i++; } } - (**pmacro).body = malloc(sizeof(struct sl_pp_token_info) * body_len); - if (!(**pmacro).body) { + (*pi) = i; + + eof.token = SL_PP_EOF; + if (sl_pp_process_out(&arg_state, &eof)) { strcpy(context->error_msg, "out of memory"); + free(arg_state.out); return -1; } - for (done = 0, k = 0, i = *pi; !done; i++) { - switch (input[i].token) { - case SL_PP_WHITESPACE: - break; - - case SL_PP_COMMA: - if (!paren_nesting && j < (unsigned int)macro->num_args - 1) { - done = 1; - } else { - (**pmacro).body[k++] = input[i]; - } - break; - - case SL_PP_LPAREN: - paren_nesting++; - (**pmacro).body[k++] = input[i]; - break; - - case SL_PP_RPAREN: - if (!paren_nesting && j == (unsigned int)macro->num_args - 1) { - done = 1; - } else { - paren_nesting--; - (**pmacro).body[k++] = input[i]; - } - break; - - default: - (**pmacro).body[k++] = input[i]; - } + *pmacro = sl_pp_macro_new(); + if (!*pmacro) { + strcpy(context->error_msg, "out of memory"); + free(arg_state.out); + return -1; } - (**pmacro).body[k++].token = SL_PP_EOF; - (*pi) = i; + (**pmacro).name = formal_arg->name; + (**pmacro).body = arg_state.out; formal_arg = formal_arg->next; pmacro = &(**pmacro).next; -- cgit v1.2.3 From d37f7694b60d3dad8daf9e2af4e509c15b996553 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 10 Nov 2009 00:15:33 +0100 Subject: glsl/pp: Have sl_pp_purify() return error msg/line no. --- src/glsl/pp/sl_pp_purify.c | 56 +++++++++++++++++++++++++++++++++++++--------- src/glsl/pp/sl_pp_purify.h | 5 ++++- 2 files changed, 50 insertions(+), 11 deletions(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_purify.c b/src/glsl/pp/sl_pp_purify.c index 3fb91430f37..272da1e6ea9 100644 --- a/src/glsl/pp/sl_pp_purify.c +++ b/src/glsl/pp/sl_pp_purify.c @@ -26,6 +26,8 @@ **************************************************************************/ #include +#include +#include #include "sl_pp_purify.h" @@ -39,10 +41,12 @@ static unsigned int _purify_newline(const char *input, - char *out) + char *out, + unsigned int *current_line) { if (input[0] == '\n') { *out = '\n'; + (*current_line)++; if (input[1] == '\r') { /* * The GLSL spec is not explicit about whether this @@ -55,6 +59,7 @@ _purify_newline(const char *input, } if (input[0] == '\r') { *out = '\n'; + (*current_line)++; if (input[1] == '\n') { return 2; } @@ -67,7 +72,8 @@ _purify_newline(const char *input, static unsigned int _purify_backslash(const char *input, - char *out) + char *out, + unsigned int *current_line) { unsigned int eaten = 0; @@ -75,11 +81,12 @@ _purify_backslash(const char *input, if (input[0] == '\\') { char next; unsigned int next_eaten; + unsigned int next_line = *current_line; eaten++; input++; - next_eaten = _purify_newline(input, &next); + next_eaten = _purify_newline(input, &next, &next_line); if (next == '\n') { /* * If this is really a line continuation sequence, eat @@ -87,6 +94,7 @@ _purify_backslash(const char *input, */ eaten += next_eaten; input += next_eaten; + *current_line = next_line; } else { /* * It is an error to put anything between a backslash @@ -98,7 +106,7 @@ _purify_backslash(const char *input, break; } } else { - eaten += _purify_newline(input, out); + eaten += _purify_newline(input, out, current_line); break; } } @@ -110,9 +118,25 @@ struct out_buf { char *out; unsigned int len; unsigned int capacity; + unsigned int current_line; + char *errormsg; + unsigned int cberrormsg; }; +static void +_report_error(struct out_buf *obuf, + const char *msg, + ...) +{ + va_list args; + + va_start(args, msg); + vsnprintf(obuf->errormsg, obuf->cberrormsg, msg, args); + va_end(args); +} + + static int _out_buf_putc(struct out_buf *obuf, char c) @@ -130,6 +154,7 @@ _out_buf_putc(struct out_buf *obuf, obuf->out = realloc(obuf->out, new_max); if (!obuf->out) { + _report_error(obuf, "out of memory"); return -1; } obuf->capacity = new_max; @@ -148,20 +173,22 @@ _purify_comment(const char *input, unsigned int eaten; char curr; - eaten = _purify_backslash(input, &curr); + eaten = _purify_backslash(input, &curr, &obuf->current_line); input += eaten; if (curr == '/') { char next; unsigned int next_eaten; + unsigned int next_line = obuf->current_line; - next_eaten = _purify_backslash(input, &next); + next_eaten = _purify_backslash(input, &next, &next_line); if (next == '/') { eaten += next_eaten; input += next_eaten; + obuf->current_line = next_line; /* Replace a line comment with either a newline or nil. */ for (;;) { - next_eaten = _purify_backslash(input, &next); + next_eaten = _purify_backslash(input, &next, &obuf->current_line); eaten += next_eaten; input += next_eaten; if (next == '\n' || next == '\0') { @@ -174,14 +201,15 @@ _purify_comment(const char *input, } else if (next == '*') { eaten += next_eaten; input += next_eaten; + obuf->current_line = next_line; /* Replace a block comment with a whitespace. */ for (;;) { - next_eaten = _purify_backslash(input, &next); + next_eaten = _purify_backslash(input, &next, &obuf->current_line); eaten += next_eaten; input += next_eaten; while (next == '*') { - next_eaten = _purify_backslash(input, &next); + next_eaten = _purify_backslash(input, &next, &obuf->current_line); eaten += next_eaten; input += next_eaten; if (next == '/') { @@ -197,6 +225,7 @@ _purify_comment(const char *input, } } if (next == '\0') { + _report_error(obuf, "expected `*/' but end of translation unit found"); return 0; } } @@ -212,19 +241,26 @@ _purify_comment(const char *input, int sl_pp_purify(const char *input, const struct sl_pp_purify_options *options, - char **output) + char **output, + char *errormsg, + unsigned int cberrormsg, + unsigned int *errorline) { struct out_buf obuf; obuf.out = NULL; obuf.len = 0; obuf.capacity = 0; + obuf.current_line = 1; + obuf.errormsg = errormsg; + obuf.cberrormsg = cberrormsg; for (;;) { unsigned int eaten; eaten = _purify_comment(input, &obuf); if (!eaten) { + *errorline = obuf.current_line; return -1; } input += eaten; diff --git a/src/glsl/pp/sl_pp_purify.h b/src/glsl/pp/sl_pp_purify.h index 011b117937e..88ea9c9e7a7 100644 --- a/src/glsl/pp/sl_pp_purify.h +++ b/src/glsl/pp/sl_pp_purify.h @@ -36,6 +36,9 @@ struct sl_pp_purify_options { int sl_pp_purify(const char *input, const struct sl_pp_purify_options *options, - char **output); + char **output, + char *errormsg, + unsigned int cberrormsg, + unsigned int *errorline); #endif /* SL_PP_PURIFY_H */ -- cgit v1.2.3 From d44cebd1ee7b3e461e264150a28c9d49a0f69f8f Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 10 Nov 2009 20:49:45 +0100 Subject: glsl/pp: Add sl_pp_purify_getc(). --- src/glsl/pp/sl_pp_purify.c | 201 +++++++++++++++++++++++++-------------------- src/glsl/pp/sl_pp_purify.h | 19 +++++ 2 files changed, 133 insertions(+), 87 deletions(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_purify.c b/src/glsl/pp/sl_pp_purify.c index 272da1e6ea9..b50f8192517 100644 --- a/src/glsl/pp/sl_pp_purify.c +++ b/src/glsl/pp/sl_pp_purify.c @@ -114,130 +114,150 @@ _purify_backslash(const char *input, } -struct out_buf { - char *out; - unsigned int len; - unsigned int capacity; - unsigned int current_line; - char *errormsg; - unsigned int cberrormsg; -}; - - static void -_report_error(struct out_buf *obuf, +_report_error(char *buf, + unsigned int cbbuf, const char *msg, ...) { va_list args; va_start(args, msg); - vsnprintf(obuf->errormsg, obuf->cberrormsg, msg, args); + vsnprintf(buf, cbbuf, msg, args); va_end(args); } -static int -_out_buf_putc(struct out_buf *obuf, - char c) +void +sl_pp_purify_state_init(struct sl_pp_purify_state *state, + const char *input, + const struct sl_pp_purify_options *options) { - if (obuf->len >= obuf->capacity) { - unsigned int new_max = obuf->capacity; + state->options = *options; + state->input = input; + state->current_line = 1; + state->inside_c_comment = 0; +} - if (new_max < 0x100) { - new_max = 0x100; - } else if (new_max < 0x10000) { - new_max *= 2; - } else { - new_max += 0x10000; - } - obuf->out = realloc(obuf->out, new_max); - if (!obuf->out) { - _report_error(obuf, "out of memory"); - return -1; +unsigned int +_purify_comment(struct sl_pp_purify_state *state, + char *output, + unsigned int *current_line, + char *errormsg, + unsigned int cberrormsg) +{ + for (;;) { + unsigned int eaten; + char next; + + eaten = _purify_backslash(state->input, &next, current_line); + state->input += eaten; + while (next == '*') { + eaten = _purify_backslash(state->input, &next, current_line); + state->input += eaten; + if (next == '/') { + *output = ' '; + state->inside_c_comment = 0; + return 1; + } + } + if (next == '\n') { + *output = '\n'; + state->inside_c_comment = 1; + return 1; + } + if (next == '\0') { + _report_error(errormsg, cberrormsg, "expected `*/' but end of translation unit found"); + return 0; } - obuf->capacity = new_max; } - - obuf->out[obuf->len++] = c; - - return 0; } -static unsigned int -_purify_comment(const char *input, - struct out_buf *obuf) +unsigned int +sl_pp_purify_getc(struct sl_pp_purify_state *state, + char *output, + unsigned int *current_line, + char *errormsg, + unsigned int cberrormsg) { unsigned int eaten; - char curr; - eaten = _purify_backslash(input, &curr, &obuf->current_line); - input += eaten; - if (curr == '/') { + if (state->inside_c_comment) { + return _purify_comment(state, output, current_line, errormsg, cberrormsg); + } + + eaten = _purify_backslash(state->input, output, current_line); + state->input += eaten; + if (*output == '/') { char next; - unsigned int next_eaten; - unsigned int next_line = obuf->current_line; + unsigned int next_line = *current_line; - next_eaten = _purify_backslash(input, &next, &next_line); + eaten = _purify_backslash(state->input, &next, &next_line); if (next == '/') { - eaten += next_eaten; - input += next_eaten; - obuf->current_line = next_line; + state->input += eaten; + *current_line = next_line; /* Replace a line comment with either a newline or nil. */ for (;;) { - next_eaten = _purify_backslash(input, &next, &obuf->current_line); - eaten += next_eaten; - input += next_eaten; + eaten = _purify_backslash(state->input, &next, current_line); + state->input += eaten; if (next == '\n' || next == '\0') { - if (_out_buf_putc(obuf, next)) { - return 0; - } + *output = next; return eaten; } } } else if (next == '*') { - eaten += next_eaten; - input += next_eaten; - obuf->current_line = next_line; + state->input += eaten; + *current_line = next_line; - /* Replace a block comment with a whitespace. */ - for (;;) { - next_eaten = _purify_backslash(input, &next, &obuf->current_line); - eaten += next_eaten; - input += next_eaten; - while (next == '*') { - next_eaten = _purify_backslash(input, &next, &obuf->current_line); - eaten += next_eaten; - input += next_eaten; - if (next == '/') { - if (_out_buf_putc(obuf, ' ')) { - return 0; - } - return eaten; - } - } - if (next == '\n') { - if (_out_buf_putc(obuf, '\n')) { - return 0; - } - } - if (next == '\0') { - _report_error(obuf, "expected `*/' but end of translation unit found"); - return 0; - } - } + return _purify_comment(state, output, current_line, errormsg, cberrormsg); } } - if (_out_buf_putc(obuf, curr)) { - return 0; - } return eaten; } +struct out_buf { + char *out; + unsigned int len; + unsigned int capacity; + unsigned int current_line; + char *errormsg; + unsigned int cberrormsg; +}; + + +static int +_out_buf_putc(struct out_buf *obuf, + char c) +{ + if (obuf->len >= obuf->capacity) { + unsigned int new_max = obuf->capacity; + + if (new_max < 0x100) { + new_max = 0x100; + } else if (new_max < 0x10000) { + new_max *= 2; + } else { + new_max += 0x10000; + } + + obuf->out = realloc(obuf->out, new_max); + if (!obuf->out) { + _report_error(obuf->errormsg, obuf->cberrormsg, "out of memory"); + return -1; + } + obuf->capacity = new_max; + } + + obuf->out[obuf->len++] = c; + + return 0; +} + + int sl_pp_purify(const char *input, const struct sl_pp_purify_options *options, @@ -247,6 +267,7 @@ sl_pp_purify(const char *input, unsigned int *errorline) { struct out_buf obuf; + struct sl_pp_purify_state state; obuf.out = NULL; obuf.len = 0; @@ -255,17 +276,23 @@ sl_pp_purify(const char *input, obuf.errormsg = errormsg; obuf.cberrormsg = cberrormsg; + sl_pp_purify_state_init(&state, input, options); + for (;;) { unsigned int eaten; + char c; - eaten = _purify_comment(input, &obuf); + eaten = sl_pp_purify_getc(&state, &c, &obuf.current_line, errormsg, cberrormsg); if (!eaten) { *errorline = obuf.current_line; return -1; } - input += eaten; + if (_out_buf_putc(&obuf, c)) { + *errorline = obuf.current_line; + return -1; + } - if (obuf.out[obuf.len - 1] == '\0') { + if (c == '\0') { break; } } diff --git a/src/glsl/pp/sl_pp_purify.h b/src/glsl/pp/sl_pp_purify.h index 88ea9c9e7a7..c0f55cbfd89 100644 --- a/src/glsl/pp/sl_pp_purify.h +++ b/src/glsl/pp/sl_pp_purify.h @@ -41,4 +41,23 @@ sl_pp_purify(const char *input, unsigned int cberrormsg, unsigned int *errorline); +struct sl_pp_purify_state { + struct sl_pp_purify_options options; + const char *input; + unsigned int current_line; + unsigned int inside_c_comment:1; +}; + +void +sl_pp_purify_state_init(struct sl_pp_purify_state *state, + const char *input, + const struct sl_pp_purify_options *options); + +unsigned int +sl_pp_purify_getc(struct sl_pp_purify_state *state, + char *output, + unsigned int *current_line, + char *errormsg, + unsigned int cberrormsg); + #endif /* SL_PP_PURIFY_H */ -- cgit v1.2.3 From 547ac2869b1e1bbdbf8e51cd40d50e6ab0f4f9f1 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 17 Nov 2009 09:06:53 +0100 Subject: glsl/pp: Fix macro formal argument parsing, more descriptive error msgs. --- src/glsl/pp/sl_pp_define.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c index d18a7ee2895..e004c9f95b9 100644 --- a/src/glsl/pp/sl_pp_define.c +++ b/src/glsl/pp/sl_pp_define.c @@ -60,7 +60,7 @@ _parse_formal_args(struct sl_pp_context *context, return 0; } } else { - strcpy(context->error_msg, "expected either an identifier or `)'"); + strcpy(context->error_msg, "expected either macro formal argument or `)'"); return -1; } @@ -68,7 +68,7 @@ _parse_formal_args(struct sl_pp_context *context, for (;;) { if (*first < last && input[*first].token != SL_PP_IDENTIFIER) { - strcpy(context->error_msg, "expected an identifier"); + strcpy(context->error_msg, "expected macro formal argument"); return -1; } @@ -90,6 +90,7 @@ _parse_formal_args(struct sl_pp_context *context, if (*first < last) { if (input[*first].token == SL_PP_COMMA) { (*first)++; + skip_whitespace(input, first, last); } else if (input[*first].token == SL_PP_RPAREN) { (*first)++; return 0; @@ -124,7 +125,7 @@ sl_pp_process_define(struct sl_pp_context *context, first++; } if (macro_name == -1) { - strcpy(context->error_msg, "expected an identifier"); + strcpy(context->error_msg, "expected macro name"); return -1; } -- cgit v1.2.3 From 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') diff --git a/src/glsl/pp/sl_pp_if.c b/src/glsl/pp/sl_pp_if.c index a0b3635dd5a..6610bc69f3c 100644 --- a/src/glsl/pp/sl_pp_if.c +++ b/src/glsl/pp/sl_pp_if.c @@ -137,7 +137,7 @@ _parse_if(struct sl_pp_context *context, return -1; } } else { - if (sl_pp_macro_expand(context, input, &i, NULL, &state, 0)) { + if (sl_pp_macro_expand(context, input, &i, NULL, &state, sl_pp_macro_expand_unknown_to_0)) { free(state.out); return -1; } diff --git a/src/glsl/pp/sl_pp_line.c b/src/glsl/pp/sl_pp_line.c index fc2dd89e68b..ed5acc697ce 100644 --- a/src/glsl/pp/sl_pp_line.c +++ b/src/glsl/pp/sl_pp_line.c @@ -53,7 +53,7 @@ sl_pp_process_line(struct sl_pp_context *context, break; case SL_PP_IDENTIFIER: - if (sl_pp_macro_expand(context, input, &i, NULL, &state, 0)) { + if (sl_pp_macro_expand(context, input, &i, NULL, &state, sl_pp_macro_expand_normal)) { free(state.out); return -1; } diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index d6c32a0e782..29f1229dd7d 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -28,6 +28,7 @@ #include #include #include +#include "sl_pp_public.h" #include "sl_pp_macro.h" #include "sl_pp_process.h" @@ -122,8 +123,9 @@ sl_pp_macro_expand(struct sl_pp_context *context, unsigned int *pi, struct sl_pp_macro *local, struct sl_pp_process_state *state, - int mute) + enum sl_pp_macro_expand_behaviour behaviour) { + int mute = (behaviour == sl_pp_macro_expand_mute); int macro_name; struct sl_pp_macro *macro = NULL; struct sl_pp_macro *actual_arg = NULL; @@ -183,7 +185,12 @@ sl_pp_macro_expand(struct sl_pp_context *context, } if (!macro) { - if (!mute) { + if (behaviour == sl_pp_macro_expand_unknown_to_0) { + if (_out_number(context, state, 0)) { + strcpy(context->error_msg, "out of memory"); + return -1; + } + } else if (!mute) { if (sl_pp_process_out(state, &input[*pi])) { strcpy(context->error_msg, "out of memory"); return -1; @@ -274,7 +281,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, break; case SL_PP_IDENTIFIER: - if (sl_pp_macro_expand(context, input, &i, local, &arg_state, 0)) { + if (sl_pp_macro_expand(context, input, &i, local, &arg_state, sl_pp_macro_expand_normal)) { free(arg_state.out); return -1; } @@ -339,7 +346,7 @@ sl_pp_macro_expand(struct sl_pp_context *context, break; case SL_PP_IDENTIFIER: - if (sl_pp_macro_expand(context, macro->body, &j, actual_arg, state, mute)) { + if (sl_pp_macro_expand(context, macro->body, &j, actual_arg, state, behaviour)) { return -1; } break; diff --git a/src/glsl/pp/sl_pp_macro.h b/src/glsl/pp/sl_pp_macro.h index e3ae2fc7125..3ad3438236a 100644 --- a/src/glsl/pp/sl_pp_macro.h +++ b/src/glsl/pp/sl_pp_macro.h @@ -56,12 +56,18 @@ sl_pp_macro_free(struct sl_pp_macro *macro); void sl_pp_macro_reset(struct sl_pp_macro *macro); +enum sl_pp_macro_expand_behaviour { + sl_pp_macro_expand_normal, + sl_pp_macro_expand_mute, + sl_pp_macro_expand_unknown_to_0 +}; + int sl_pp_macro_expand(struct sl_pp_context *context, const struct sl_pp_token_info *input, unsigned int *pi, struct sl_pp_macro *local, struct sl_pp_process_state *state, - int mute); + enum sl_pp_macro_expand_behaviour behaviour); #endif /* SL_PP_MACRO_H */ diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index 4b783e40b4d..e2adc2a0215 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -257,7 +257,8 @@ sl_pp_process(struct sl_pp_context *context, break; case SL_PP_IDENTIFIER: - if (sl_pp_macro_expand(context, input, &i, NULL, &state, !context->if_value)) { + if (sl_pp_macro_expand(context, input, &i, NULL, &state, + context->if_value ? sl_pp_macro_expand_normal : sl_pp_macro_expand_mute)) { return -1; } break; -- cgit v1.2.3 From abe1f332983e5c70d75b5ae83f06c0dfdd081a26 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 21 Nov 2009 20:41:48 +0100 Subject: glsl/pp: Do purification and tokenisation in a single step. --- src/glsl/pp/sl_pp_context.c | 7 + src/glsl/pp/sl_pp_context.h | 11 +- src/glsl/pp/sl_pp_dict.c | 1 + src/glsl/pp/sl_pp_public.h | 4 + src/glsl/pp/sl_pp_token.c | 844 ++++++++++++++++++++++++++++---------------- src/glsl/pp/sl_pp_token.h | 1 + 6 files changed, 561 insertions(+), 307 deletions(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index 8ce189d955c..134588d9066 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -46,6 +46,12 @@ sl_pp_context_create(void) return NULL; } + context->getc_buf = malloc(64 * sizeof(char)); + if (!context->getc_buf) { + sl_pp_context_destroy(context); + return NULL; + } + context->macro_tail = &context->macro; context->if_ptr = SL_PP_MAX_IF_NESTING; context->if_value = 1; @@ -62,6 +68,7 @@ sl_pp_context_destroy(struct sl_pp_context *context) if (context) { free(context->cstr_pool); sl_pp_macro_free(context->macro); + free(context->getc_buf); free(context); } } diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index 6b8cc2f960d..569a2d735b9 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -30,6 +30,7 @@ #include "sl_pp_dict.h" #include "sl_pp_macro.h" +#include "sl_pp_purify.h" #define SL_PP_MAX_IF_NESTING 64 @@ -53,10 +54,12 @@ struct sl_pp_context { unsigned int line; unsigned int file; -}; -int -sl_pp_context_add_unique_str(struct sl_pp_context *context, - const char *str); + struct sl_pp_purify_state pure; + + char *getc_buf; + unsigned int getc_buf_size; + unsigned int getc_buf_capacity; +}; #endif /* SL_PP_CONTEXT_H */ diff --git a/src/glsl/pp/sl_pp_dict.c b/src/glsl/pp/sl_pp_dict.c index 82fb9127b50..2dd77a69e90 100644 --- a/src/glsl/pp/sl_pp_dict.c +++ b/src/glsl/pp/sl_pp_dict.c @@ -25,6 +25,7 @@ * **************************************************************************/ +#include "sl_pp_public.h" #include "sl_pp_context.h" #include "sl_pp_dict.h" diff --git a/src/glsl/pp/sl_pp_public.h b/src/glsl/pp/sl_pp_public.h index b1d92d02a7a..8317c7e378a 100644 --- a/src/glsl/pp/sl_pp_public.h +++ b/src/glsl/pp/sl_pp_public.h @@ -45,6 +45,10 @@ sl_pp_context_destroy(struct sl_pp_context *context); const char * sl_pp_context_error_message(const struct sl_pp_context *context); +int +sl_pp_context_add_unique_str(struct sl_pp_context *context, + const char *str); + const char * sl_pp_context_cstr(const struct sl_pp_context *context, int offset); diff --git a/src/glsl/pp/sl_pp_token.c b/src/glsl/pp/sl_pp_token.c index f232dafc682..03f2f09cfd6 100644 --- a/src/glsl/pp/sl_pp_token.c +++ b/src/glsl/pp/sl_pp_token.c @@ -25,12 +25,106 @@ * **************************************************************************/ +#include #include #include +#include "sl_pp_public.h" #include "sl_pp_context.h" #include "sl_pp_token.h" +#define PURE_ERROR 256 + +int +_pure_getc(struct sl_pp_context *context) +{ + char c; + unsigned int current_line; + + if (context->getc_buf_size) { + return context->getc_buf[--context->getc_buf_size]; + } + + if (sl_pp_purify_getc(&context->pure, &c, ¤t_line, context->error_msg, sizeof(context->error_msg)) == 0) { + return PURE_ERROR; + } + return c; +} + + +void +_pure_ungetc(struct sl_pp_context *context, + int c) +{ + assert(c != PURE_ERROR); + + if (context->getc_buf_size == context->getc_buf_capacity) { + context->getc_buf_capacity += 64; + context->getc_buf = realloc(context->getc_buf, context->getc_buf_capacity * sizeof(char)); + assert(context->getc_buf); + } + + context->getc_buf[context->getc_buf_size++] = (char)c; +} + + +struct lookahead_state { + char buf[256]; + unsigned int pos; + struct sl_pp_context *context; +}; + + +static void +_lookahead_init(struct lookahead_state *lookahead, + struct sl_pp_context *context) +{ + lookahead->pos = 0; + lookahead->context = context; +} + + +static unsigned int +_lookahead_tell(const struct lookahead_state *lookahead) +{ + return lookahead->pos; +} + + +static const void * +_lookahead_buf(const struct lookahead_state *lookahead) +{ + return lookahead->buf; +} + + +static void +_lookahead_revert(struct lookahead_state *lookahead, + unsigned int pos) +{ + assert(pos <= lookahead->pos); + + while (lookahead->pos > pos) { + _pure_ungetc(lookahead->context, lookahead->buf[--lookahead->pos]); + } +} + + +static int +_lookahead_getc(struct lookahead_state *lookahead) +{ + int c; + + assert(lookahead->pos < sizeof(lookahead->buf) / sizeof(lookahead->buf[0])); + + c = _pure_getc(lookahead->context); + if (c != PURE_ERROR) { + lookahead->buf[lookahead->pos++] = (char)c; + } + return c; +} + + static int _is_identifier_char(char c) { @@ -40,32 +134,51 @@ _is_identifier_char(char c) static int _tokenise_identifier(struct sl_pp_context *context, - const char **pinput, - struct sl_pp_token_info *info) + struct sl_pp_token_info *out) { - const char *input = *pinput; + int c; char identifier[256]; /* XXX: Remove this artifical limit. */ unsigned int i = 0; - info->token = SL_PP_IDENTIFIER; - info->data.identifier = -1; + out->token = SL_PP_IDENTIFIER; + out->data.identifier = -1; - identifier[i++] = *input++; - while (_is_identifier_char(*input)) { - if (i >= sizeof(identifier) - 1) { - strcpy(context->error_msg, "out of memory"); + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + identifier[i++] = (char)c; + for (;;) { + c = _pure_getc(context); + if (c == PURE_ERROR) { return -1; } - identifier[i++] = *input++; + + if (_is_identifier_char((char)c)) { + if (i >= sizeof(identifier) / sizeof(char) - 1) { + strcpy(context->error_msg, "out of memory"); + _pure_ungetc(context, c); + while (i) { + _pure_ungetc(context, identifier[--i]); + } + return -1; + } + identifier[i++] = (char)c; + } else { + _pure_ungetc(context, c); + break; + } } - identifier[i++] = '\0'; + identifier[i] = '\0'; - info->data.identifier = sl_pp_context_add_unique_str(context, identifier); - if (info->data.identifier == -1) { + out->data.identifier = sl_pp_context_add_unique_str(context, identifier); + if (out->data.identifier == -1) { + while (i) { + _pure_ungetc(context, identifier[--i]); + } return -1; } - *pinput = input; return 0; } @@ -74,12 +187,18 @@ _tokenise_identifier(struct sl_pp_context *context, * Return the number of consecutive decimal digits in the input stream. */ static unsigned int -_parse_float_digits(const char *input) +_parse_float_digits(struct lookahead_state *lookahead) { - unsigned int eaten = 0; + unsigned int eaten; + + for (eaten = 0;; eaten++) { + unsigned int pos = _lookahead_tell(lookahead); + char c = _lookahead_getc(lookahead); - while (input[eaten] >= '0' && input[eaten] <= '9') { - eaten++; + if (c < '0' || c > '9') { + _lookahead_revert(lookahead, pos); + break; + } } return eaten; } @@ -96,29 +215,33 @@ _parse_float_digits(const char *input) * of eaten characters from the input stream. */ static unsigned int -_parse_float_frac(const char *input) +_parse_float_frac(struct lookahead_state *lookahead) { + unsigned int pos; + int c; unsigned int eaten; - if (input[0] == '.') { - eaten = _parse_float_digits(&input[1]); + pos = _lookahead_tell(lookahead); + c = _lookahead_getc(lookahead); + if (c == '.') { + eaten = _parse_float_digits(lookahead); if (eaten) { return eaten + 1; } + _lookahead_revert(lookahead, pos); return 0; } - eaten = _parse_float_digits(input); - if (eaten && input[eaten] == '.') { - unsigned int trailing; - - trailing = _parse_float_digits(&input[eaten + 1]); - if (trailing) { - return eaten + trailing + 1; + _lookahead_revert(lookahead, pos); + eaten = _parse_float_digits(lookahead); + if (eaten) { + c = _lookahead_getc(lookahead); + if (c == '.') { + return eaten + 1 + _parse_float_digits(lookahead); } - return eaten + 1; } + _lookahead_revert(lookahead, pos); return 0; } @@ -133,22 +256,31 @@ _parse_float_frac(const char *input) * of eaten characters from the input stream. */ static unsigned int -_parse_float_exp(const char *input) +_parse_float_exp(struct lookahead_state *lookahead) { + unsigned int pos, pos2; + int c; unsigned int eaten, digits; - if (input[0] != 'e' && input[0] != 'E') { + pos = _lookahead_tell(lookahead); + c = _lookahead_getc(lookahead); + if (c != 'e' && c != 'E') { + _lookahead_revert(lookahead, pos); return 0; } - if (input[1] == '-' || input[1] == '+') { + pos2 = _lookahead_tell(lookahead); + c = _lookahead_getc(lookahead); + if (c == '-' || c == '+') { eaten = 2; } else { + _lookahead_revert(lookahead, pos2); eaten = 1; } - digits = _parse_float_digits(&input[eaten]); + digits = _parse_float_digits(lookahead); if (!digits) { + _lookahead_revert(lookahead, pos); return 0; } @@ -166,86 +298,117 @@ _parse_float_exp(const char *input) * of eaten characters from the input stream. */ static unsigned int -_parse_float(const char *input) +_parse_float(struct lookahead_state *lookahead) { unsigned int eaten; - eaten = _parse_float_frac(input); + eaten = _parse_float_frac(lookahead); if (eaten) { - unsigned int exponent; + unsigned int pos; + int c; - exponent = _parse_float_exp(&input[eaten]); - if (exponent) { - eaten += exponent; - } + eaten += _parse_float_exp(lookahead); - if (input[eaten] == 'f' || input[eaten] == 'F') { + pos = _lookahead_tell(lookahead); + c = _lookahead_getc(lookahead); + if (c == 'f' || c == 'F') { eaten++; + } else { + _lookahead_revert(lookahead, pos); } return eaten; } - eaten = _parse_float_digits(input); + eaten = _parse_float_digits(lookahead); if (eaten) { unsigned int exponent; - exponent = _parse_float_exp(&input[eaten]); + exponent = _parse_float_exp(lookahead); if (exponent) { + unsigned int pos; + int c; + eaten += exponent; - if (input[eaten] == 'f' || input[eaten] == 'F') { + pos = _lookahead_tell(lookahead); + c = _lookahead_getc(lookahead); + if (c == 'f' || c == 'F') { eaten++; + } else { + _lookahead_revert(lookahead, pos); } return eaten; } } + _lookahead_revert(lookahead, 0); return 0; } static unsigned int -_parse_hex(const char *input) +_parse_hex(struct lookahead_state *lookahead) { + int c; unsigned int n; - if (input[0] != '0') { + c = _lookahead_getc(lookahead); + if (c != '0') { + _lookahead_revert(lookahead, 0); return 0; } - if (input[1] != 'x' && input[1] != 'X') { + c = _lookahead_getc(lookahead); + if (c != 'x' && c != 'X') { + _lookahead_revert(lookahead, 0); return 0; } - n = 2; - while ((input[n] >= '0' && input[n] <= '9') || - (input[n] >= 'a' && input[n] <= 'f') || - (input[n] >= 'A' && input[n] <= 'F')) { - n++; + for (n = 2;;) { + unsigned int pos = _lookahead_tell(lookahead); + + c = _lookahead_getc(lookahead); + if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { + n++; + } else { + _lookahead_revert(lookahead, pos); + break; + } } if (n > 2) { return n; } + _lookahead_revert(lookahead, 0); return 0; } static unsigned int -_parse_oct(const char *input) +_parse_oct(struct lookahead_state *lookahead) { + int c; unsigned int n; - if (input[0] != '0') { + c = _lookahead_getc(lookahead); + if (c != '0') { + _lookahead_revert(lookahead, 0); return 0; } - n = 1; - while ((input[n] >= '0' && input[n] <= '7')) { - n++; + for (n = 1;;) { + unsigned int pos = _lookahead_tell(lookahead); + + c = _lookahead_getc(lookahead); + if ((c >= '0' && c <= '7')) { + n++; + } else { + _lookahead_revert(lookahead, pos); + break; + } } return n; @@ -253,12 +416,20 @@ _parse_oct(const char *input) static unsigned int -_parse_dec(const char *input) +_parse_dec(struct lookahead_state *lookahead) { unsigned int n = 0; - while ((input[n] >= '0' && input[n] <= '9')) { - n++; + for (;;) { + unsigned int pos = _lookahead_tell(lookahead); + int c = _lookahead_getc(lookahead); + + if ((c >= '0' && c <= '9')) { + n++; + } else { + _lookahead_revert(lookahead, pos); + break; + } } return n; @@ -267,327 +438,394 @@ _parse_dec(const char *input) static int _tokenise_number(struct sl_pp_context *context, - const char **pinput, - struct sl_pp_token_info *info) + struct sl_pp_token_info *out) { - const char *input = *pinput; + struct lookahead_state lookahead; unsigned int eaten; unsigned int is_float = 0; + unsigned int pos; + int c; char number[256]; /* XXX: Remove this artifical limit. */ - eaten = _parse_float(input); + _lookahead_init(&lookahead, context); + + eaten = _parse_float(&lookahead); if (!eaten) { - eaten = _parse_hex(input); + eaten = _parse_hex(&lookahead); if (!eaten) { - eaten = _parse_oct(input); + eaten = _parse_oct(&lookahead); if (!eaten) { - eaten = _parse_dec(input); + eaten = _parse_dec(&lookahead); } } } else { is_float = 1; } - if (!eaten || _is_identifier_char(input[eaten])) { + if (!eaten) { strcpy(context->error_msg, "expected a number"); return -1; } + pos = _lookahead_tell(&lookahead); + c = _lookahead_getc(&lookahead); + _lookahead_revert(&lookahead, pos); + + if (_is_identifier_char(c)) { + strcpy(context->error_msg, "expected a number"); + _lookahead_revert(&lookahead, 0); + return -1; + } + if (eaten > sizeof(number) - 1) { strcpy(context->error_msg, "out of memory"); + _lookahead_revert(&lookahead, 0); return -1; } - memcpy(number, input, eaten); + assert(_lookahead_tell(&lookahead) == eaten); + + memcpy(number, _lookahead_buf(&lookahead), eaten); number[eaten] = '\0'; if (is_float) { - info->token = SL_PP_FLOAT; - info->data._float = sl_pp_context_add_unique_str(context, number); - if (info->data._float == -1) { + out->token = SL_PP_FLOAT; + out->data._float = sl_pp_context_add_unique_str(context, number); + if (out->data._float == -1) { + _lookahead_revert(&lookahead, 0); return -1; } } else { - info->token = SL_PP_UINT; - info->data._uint = sl_pp_context_add_unique_str(context, number); - if (info->data._uint == -1) { + out->token = SL_PP_UINT; + out->data._uint = sl_pp_context_add_unique_str(context, number); + if (out->data._uint == -1) { + _lookahead_revert(&lookahead, 0); return -1; } } - *pinput = input + eaten; return 0; } int -sl_pp_tokenise(struct sl_pp_context *context, - const char *input, - struct sl_pp_token_info **output) +sl_pp_token_get(struct sl_pp_context *context, + struct sl_pp_token_info *out) { - struct sl_pp_token_info *out = NULL; - unsigned int out_len = 0; - unsigned int out_max = 0; + int c = _pure_getc(context); - for (;;) { - struct sl_pp_token_info info; + switch (c) { + case ' ': + case '\t': + out->token = SL_PP_WHITESPACE; + break; - switch (*input) { - case ' ': - case '\t': - input++; - info.token = SL_PP_WHITESPACE; - break; + case '\n': + out->token = SL_PP_NEWLINE; + break; - case '\n': - input++; - info.token = SL_PP_NEWLINE; - break; + case '#': + out->token = SL_PP_HASH; + break; - case '#': - input++; - info.token = SL_PP_HASH; - break; + case ',': + out->token = SL_PP_COMMA; + break; - case ',': - input++; - info.token = SL_PP_COMMA; - break; + case ';': + out->token = SL_PP_SEMICOLON; + break; - case ';': - input++; - info.token = SL_PP_SEMICOLON; - break; + case '{': + out->token = SL_PP_LBRACE; + break; - case '{': - input++; - info.token = SL_PP_LBRACE; - break; + case '}': + out->token = SL_PP_RBRACE; + break; - case '}': - input++; - info.token = SL_PP_RBRACE; - break; + case '(': + out->token = SL_PP_LPAREN; + break; - case '(': - input++; - info.token = SL_PP_LPAREN; - break; + case ')': + out->token = SL_PP_RPAREN; + break; - case ')': - input++; - info.token = SL_PP_RPAREN; - break; + case '[': + out->token = SL_PP_LBRACKET; + break; - case '[': - input++; - info.token = SL_PP_LBRACKET; - break; + case ']': + out->token = SL_PP_RBRACKET; + break; - case ']': - input++; - info.token = SL_PP_RBRACKET; - break; + case '.': + { + int c2 = _pure_getc(context); - case '.': - if (input[1] >= '0' && input[1] <= '9') { - if (_tokenise_number(context, &input, &info)) { - free(out); + if (c2 == PURE_ERROR) { + return -1; + } + if (c2 >= '0' && c2 <= '9') { + _pure_ungetc(context, c2); + _pure_ungetc(context, c); + if (_tokenise_number(context, out)) { return -1; } } else { - input++; - info.token = SL_PP_DOT; + _pure_ungetc(context, c2); + out->token = SL_PP_DOT; } - break; + } + break; - case '+': - input++; - if (*input == '+') { - input++; - info.token = SL_PP_INCREMENT; - } else if (*input == '=') { - input++; - info.token = SL_PP_ADDASSIGN; - } else { - info.token = SL_PP_PLUS; - } - break; + case '+': + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + if (c == '+') { + out->token = SL_PP_INCREMENT; + } else if (c == '=') { + out->token = SL_PP_ADDASSIGN; + } else { + _pure_ungetc(context, c); + out->token = SL_PP_PLUS; + } + break; - case '-': - input++; - if (*input == '-') { - input++; - info.token = SL_PP_DECREMENT; - } else if (*input == '=') { - input++; - info.token = SL_PP_SUBASSIGN; - } else { - info.token = SL_PP_MINUS; - } - break; + case '-': + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + if (c == '-') { + out->token = SL_PP_DECREMENT; + } else if (c == '=') { + out->token = SL_PP_SUBASSIGN; + } else { + _pure_ungetc(context, c); + out->token = SL_PP_MINUS; + } + break; - case '~': - input++; - info.token = SL_PP_BITNOT; - break; + case '~': + out->token = SL_PP_BITNOT; + break; - case '!': - input++; - if (*input == '=') { - input++; - info.token = SL_PP_NOTEQUAL; - } else { - info.token = SL_PP_NOT; - } - break; + case '!': + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + if (c == '=') { + out->token = SL_PP_NOTEQUAL; + } else { + _pure_ungetc(context, c); + out->token = SL_PP_NOT; + } + break; - case '*': - input++; - if (*input == '=') { - input++; - info.token = SL_PP_MULASSIGN; - } else { - info.token = SL_PP_STAR; - } - break; + case '*': + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + if (c == '=') { + out->token = SL_PP_MULASSIGN; + } else { + _pure_ungetc(context, c); + out->token = SL_PP_STAR; + } + break; - case '/': - input++; - if (*input == '=') { - input++; - info.token = SL_PP_DIVASSIGN; - } else { - info.token = SL_PP_SLASH; - } - break; + case '/': + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + if (c == '=') { + out->token = SL_PP_DIVASSIGN; + } else { + _pure_ungetc(context, c); + out->token = SL_PP_SLASH; + } + break; - case '%': - input++; - if (*input == '=') { - input++; - info.token = SL_PP_MODASSIGN; - } else { - info.token = SL_PP_MODULO; - } - break; + case '%': + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + if (c == '=') { + out->token = SL_PP_MODASSIGN; + } else { + _pure_ungetc(context, c); + out->token = SL_PP_MODULO; + } + break; - case '<': - input++; - if (*input == '<') { - input++; - if (*input == '=') { - input++; - info.token = SL_PP_LSHIFTASSIGN; - } else { - info.token = SL_PP_LSHIFT; - } - } else if (*input == '=') { - input++; - info.token = SL_PP_LESSEQUAL; - } else { - info.token = SL_PP_LESS; + case '<': + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + if (c == '<') { + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; } - break; - - case '>': - input++; - if (*input == '>') { - input++; - if (*input == '=') { - input++; - info.token = SL_PP_RSHIFTASSIGN; - } else { - info.token = SL_PP_RSHIFT; - } - } else if (*input == '=') { - input++; - info.token = SL_PP_GREATEREQUAL; + if (c == '=') { + out->token = SL_PP_LSHIFTASSIGN; } else { - info.token = SL_PP_GREATER; + _pure_ungetc(context, c); + out->token = SL_PP_LSHIFT; } - break; + } else if (c == '=') { + out->token = SL_PP_LESSEQUAL; + } else { + _pure_ungetc(context, c); + out->token = SL_PP_LESS; + } + break; - case '=': - input++; - if (*input == '=') { - input++; - info.token = SL_PP_EQUAL; - } else { - info.token = SL_PP_ASSIGN; + case '>': + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + if (c == '>') { + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; } - break; - - case '&': - input++; - if (*input == '&') { - input++; - info.token = SL_PP_AND; - } else if (*input == '=') { - input++; - info.token = SL_PP_BITANDASSIGN; + if (c == '=') { + out->token = SL_PP_RSHIFTASSIGN; } else { - info.token = SL_PP_BITAND; + _pure_ungetc(context, c); + out->token = SL_PP_RSHIFT; } - break; + } else if (c == '=') { + out->token = SL_PP_GREATEREQUAL; + } else { + _pure_ungetc(context, c); + out->token = SL_PP_GREATER; + } + break; - case '^': - input++; - if (*input == '^') { - input++; - info.token = SL_PP_XOR; - } else if (*input == '=') { - input++; - info.token = SL_PP_BITXORASSIGN; - } else { - info.token = SL_PP_BITXOR; - } - break; + case '=': + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + if (c == '=') { + out->token = SL_PP_EQUAL; + } else { + _pure_ungetc(context, c); + out->token = SL_PP_ASSIGN; + } + break; - case '|': - input++; - if (*input == '|') { - input++; - info.token = SL_PP_OR; - } else if (*input == '=') { - input++; - info.token = SL_PP_BITORASSIGN; - } else { - info.token = SL_PP_BITOR; - } - break; + case '&': + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + if (c == '&') { + out->token = SL_PP_AND; + } else if (c == '=') { + out->token = SL_PP_BITANDASSIGN; + } else { + _pure_ungetc(context, c); + out->token = SL_PP_BITAND; + } + break; - case '?': - input++; - info.token = SL_PP_QUESTION; - break; + case '^': + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + if (c == '^') { + out->token = SL_PP_XOR; + } else if (c == '=') { + out->token = SL_PP_BITXORASSIGN; + } else { + _pure_ungetc(context, c); + out->token = SL_PP_BITXOR; + } + break; - case ':': - input++; - info.token = SL_PP_COLON; - break; + case '|': + c = _pure_getc(context); + if (c == PURE_ERROR) { + return -1; + } + if (c == '|') { + out->token = SL_PP_OR; + } else if (c == '=') { + out->token = SL_PP_BITORASSIGN; + } else { + _pure_ungetc(context, c); + out->token = SL_PP_BITOR; + } + break; - case '\0': - info.token = SL_PP_EOF; - break; + case '?': + out->token = SL_PP_QUESTION; + break; - default: - if ((*input >= 'a' && *input <= 'z') || - (*input >= 'A' && *input <= 'Z') || - (*input == '_')) { - if (_tokenise_identifier(context, &input, &info)) { - free(out); - return -1; - } - } else if (*input >= '0' && *input <= '9') { - if (_tokenise_number(context, &input, &info)) { - free(out); - return -1; - } - } else { - info.data.other = *input++; - info.token = SL_PP_OTHER; + case ':': + out->token = SL_PP_COLON; + break; + + case '\0': + out->token = SL_PP_EOF; + break; + + case PURE_ERROR: + return -1; + + default: + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_') { + _pure_ungetc(context, c); + if (_tokenise_identifier(context, out)) { + return -1; } + } else if (c >= '0' && c <= '9') { + _pure_ungetc(context, c); + if (_tokenise_number(context, out)) { + return -1; + } + } else { + out->data.other = c; + out->token = SL_PP_OTHER; + } + } + + return 0; +} + + +int +sl_pp_tokenise(struct sl_pp_context *context, + const char *input, + const struct sl_pp_purify_options *options, + struct sl_pp_token_info **output) +{ + struct sl_pp_token_info *out = NULL; + unsigned int out_len = 0; + unsigned int out_max = 0; + + sl_pp_purify_state_init(&context->pure, input, options); + + for (;;) { + struct sl_pp_token_info info; + + if (sl_pp_token_get(context, &info)) { + free(out); + return -1; } if (out_len >= out_max) { diff --git a/src/glsl/pp/sl_pp_token.h b/src/glsl/pp/sl_pp_token.h index 29c7571711e..7a8fa2f1b9d 100644 --- a/src/glsl/pp/sl_pp_token.h +++ b/src/glsl/pp/sl_pp_token.h @@ -123,6 +123,7 @@ struct sl_pp_token_info { int sl_pp_tokenise(struct sl_pp_context *context, const char *input, + const struct sl_pp_purify_options *options, struct sl_pp_token_info **output); #endif /* SL_PP_TOKEN_H */ -- cgit v1.2.3 From 068596c9a7e8d330ffdff8ad8700bd6093b5bdea Mon Sep 17 00:00:00 2001 From: michal Date: Thu, 10 Dec 2009 01:03:15 +0100 Subject: Build mesa glsl with make. Still don't know how to add glsl to mesa dependencies. --- Makefile | 4 +++ configs/default | 2 +- src/glsl/Makefile | 15 ++++++++++ src/glsl/Makefile.template | 50 +++++++++++++++++++++++++++++++ src/glsl/apps/Makefile | 42 ++++++++++++++++++++++++++ src/glsl/cl/Makefile | 13 ++++++++ src/glsl/pp/Makefile | 26 ++++++++++++++++ src/mesa/Makefile | 15 +++++++--- src/mesa/shader/slang/library/Makefile | 55 +++++++++++----------------------- 9 files changed, 179 insertions(+), 43 deletions(-) create mode 100644 src/glsl/Makefile create mode 100644 src/glsl/Makefile.template create mode 100644 src/glsl/apps/Makefile create mode 100644 src/glsl/cl/Makefile create mode 100644 src/glsl/pp/Makefile (limited to 'src/glsl/pp') diff --git a/Makefile b/Makefile index ea00e811b77..0f759d86dfe 100644 --- a/Makefile +++ b/Makefile @@ -225,6 +225,10 @@ MAIN_FILES = \ $(DIRECTORY)/include/GL/vms_x_fix.h \ $(DIRECTORY)/include/GL/wglext.h \ $(DIRECTORY)/include/GL/wmesa.h \ + $(DIRECTORY)/src/glsl/Makefile \ + $(DIRECTORY)/src/glsl/*/Makefile \ + $(DIRECTORY)/src/glsl/*/SConscript \ + $(DIRECTORY)/src/glsl/*/*.[ch] \ $(DIRECTORY)/src/Makefile \ $(DIRECTORY)/src/mesa/Makefile* \ $(DIRECTORY)/src/mesa/sources.mak \ diff --git a/configs/default b/configs/default index cb3ca1046f4..f3659312040 100644 --- a/configs/default +++ b/configs/default @@ -83,7 +83,7 @@ MOTIF_CFLAGS = -I/usr/include/Motif1.2 # Directories to build LIB_DIR = lib -SRC_DIRS = mesa gallium egl gallium/winsys glu glut/glx glew glw +SRC_DIRS = glsl mesa gallium egl gallium/winsys glu glut/glx glew glw GLU_DIRS = sgi DRIVER_DIRS = x11 osmesa # Which subdirs under $(TOP)/progs/ to enter: diff --git a/src/glsl/Makefile b/src/glsl/Makefile new file mode 100644 index 00000000000..ca7f2d2ac7d --- /dev/null +++ b/src/glsl/Makefile @@ -0,0 +1,15 @@ +# src/glsl/Makefile + +TOP = ../.. + +include $(TOP)/configs/current + +SUBDIRS = pp cl apps + +default install clean: + @for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE) $@) || exit 1; \ + fi \ + done + diff --git a/src/glsl/Makefile.template b/src/glsl/Makefile.template new file mode 100644 index 00000000000..974987a0a04 --- /dev/null +++ b/src/glsl/Makefile.template @@ -0,0 +1,50 @@ +# src/glsl/Makefile.template + +# Template makefile for glsl libraries. +# +# Usage: +# The minimum that the including makefile needs to define +# is TOP, LIBNAME and one of of the *_SOURCES. +# +# Optional defines: +# LIBRARY_INCLUDES are appended to the list of includes directories. +# LIBRARY_DEFINES is not used for makedepend, but for compilation. + + +### Basic defines ### + +OBJECTS = $(C_SOURCES:.c=.o) + +INCLUDES = \ + -I. \ + $(LIBRARY_INCLUDES) + + +##### TARGETS ##### + +default: depend lib$(LIBNAME).a + +lib$(LIBNAME).a: $(OBJECTS) Makefile $(TOP)/src/glsl/Makefile.template + $(MKLIB) -o $(LIBNAME) -static $(OBJECTS) + +depend: $(C_SOURCES) + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) $(C_SOURCES) 2> /dev/null + +# Remove .o and backup files +clean: + rm -f $(OBJECTS) lib$(LIBNAME).a depend depend.bak + +# Dummy target +install: + @echo -n "" + + +##### RULES ##### + +.c.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(LIBRARY_DEFINES) $< -o $@ + +-include depend + diff --git a/src/glsl/apps/Makefile b/src/glsl/apps/Makefile new file mode 100644 index 00000000000..c80fcb9d974 --- /dev/null +++ b/src/glsl/apps/Makefile @@ -0,0 +1,42 @@ +# src/glsl/apps/Makefile + +TOP = ../../.. + +include $(TOP)/configs/current + +LIBS = \ + $(TOP)/src/glsl/pp/libglslpp.a \ + $(TOP)/src/glsl/cl/libglslcl.a + +SOURCES = \ + compile.c \ + process.c \ + purify.c \ + tokenise.c \ + version.c + +APPS = $(SOURCES:%.c=%) + +INCLUDES = -I. + + +##### RULES ##### + +.SUFFIXES: +.SUFFIXES: .c + +.c: + $(APP_CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@ + +.c.o: + $(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ + + +##### TARGETS ##### + +default: $(APPS) + +clean: + -rm -f $(APPS) + -rm -f *.o + diff --git a/src/glsl/cl/Makefile b/src/glsl/cl/Makefile new file mode 100644 index 00000000000..04a52df8c33 --- /dev/null +++ b/src/glsl/cl/Makefile @@ -0,0 +1,13 @@ +#src/glsl/cl/Makefile + +TOP = ../../.. + +include $(TOP)/configs/current + +LIBNAME = glslcl + +C_SOURCES = \ + sl_cl_parse.c + +include ../Makefile.template + diff --git a/src/glsl/pp/Makefile b/src/glsl/pp/Makefile new file mode 100644 index 00000000000..819079f6258 --- /dev/null +++ b/src/glsl/pp/Makefile @@ -0,0 +1,26 @@ +#src/glsl/pp/Makefile + +TOP = ../../.. + +include $(TOP)/configs/current + +LIBNAME = glslpp + +C_SOURCES = \ + sl_pp_context.c \ + sl_pp_define.c \ + sl_pp_dict.c \ + sl_pp_error.c \ + 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 \ + sl_pp_purify.c \ + sl_pp_token.c \ + sl_pp_version.c + +include ../Makefile.template + diff --git a/src/mesa/Makefile b/src/mesa/Makefile index 8300b301441..67cac2d2480 100644 --- a/src/mesa/Makefile +++ b/src/mesa/Makefile @@ -19,10 +19,10 @@ include sources.mak -# Default: build dependencies, then asm_subdirs, then convenience -# libs (.a) and finally the device drivers: -default: depend asm_subdirs libmesa.a libmesagallium.a libglapi.a \ - driver_subdirs +# Default: build dependencies, then asm_subdirs, GLSL built-in lib, +# then convenience libs (.a) and finally the device drivers: +default: depend asm_subdirs glsl_builtin libmesa.a libmesagallium.a \ + libglapi.a driver_subdirs @@ -63,6 +63,12 @@ asm_subdirs: fi +###################################################################### +# GLSL built-in library +glsl_builtin: + (cd shader/slang/library && $(MAKE)) || exit 1 ; + + ###################################################################### # Dependency generation @@ -156,6 +162,7 @@ clean: -rm -f depend depend.bak libmesa.a libglapi.a -rm -f drivers/*/*.o -rm -f *.pc + -rm -f shader/slang/library/*_gc.h -@cd drivers/dri && $(MAKE) clean -@cd drivers/x11 && $(MAKE) clean -@cd drivers/osmesa && $(MAKE) clean diff --git a/src/mesa/shader/slang/library/Makefile b/src/mesa/shader/slang/library/Makefile index 5033d887c5b..c6964512bfe 100644 --- a/src/mesa/shader/slang/library/Makefile +++ b/src/mesa/shader/slang/library/Makefile @@ -4,9 +4,7 @@ TOP = ../../../../.. include $(TOP)/configs/current -INCDIR = $(TOP)/include - -LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) +GLSL_CL = $(TOP)/src/glsl/apps/compile # # targets @@ -14,32 +12,13 @@ LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) .PHONY: default clean -default: syntax builtin +default: builtin clean: - -rm -f syn_to_c gc_to_bin *_syn.h *_gc.h - -syntax: slang_shader_syn.h + -rm -f *_gc.h builtin: builtin_110 builtin_120 -# -# executables -# - -syn_to_c: syn_to_c.c - $(CC) syn_to_c.c -o syn_to_c - -gc_to_bin: gc_to_bin.c slang_shader_syn.h - $(CC) gc_to_bin.c -o gc_to_bin - -# -# syntax scripts -# - -slang_shader_syn.h: syn_to_c slang_shader.syn - ./syn_to_c slang_shader.syn > slang_shader_syn.h - # # builtin library sources # @@ -49,24 +28,24 @@ builtin_110: slang_common_builtin_gc.h slang_core_gc.h slang_fragment_builtin_gc builtin_120: slang_120_core_gc.h slang_builtin_120_common_gc.h slang_builtin_120_fragment_gc.h -slang_120_core_gc.h: gc_to_bin slang_120_core.gc - ./gc_to_bin 1 slang_120_core.gc slang_120_core_gc.h +slang_120_core_gc.h: slang_120_core.gc + $(GLSL_CL) fragment slang_120_core.gc slang_120_core_gc.h -slang_builtin_120_common_gc.h: gc_to_bin slang_builtin_120_common.gc - ./gc_to_bin 1 slang_builtin_120_common.gc slang_builtin_120_common_gc.h +slang_builtin_120_common_gc.h: slang_builtin_120_common.gc + $(GLSL_CL) fragment slang_builtin_120_common.gc slang_builtin_120_common_gc.h -slang_builtin_120_fragment_gc.h: gc_to_bin slang_builtin_120_fragment.gc - ./gc_to_bin 1 slang_builtin_120_fragment.gc slang_builtin_120_fragment_gc.h +slang_builtin_120_fragment_gc.h: slang_builtin_120_fragment.gc + $(GLSL_CL) fragment slang_builtin_120_fragment.gc slang_builtin_120_fragment_gc.h -slang_common_builtin_gc.h: gc_to_bin slang_common_builtin.gc - ./gc_to_bin 1 slang_common_builtin.gc slang_common_builtin_gc.h +slang_common_builtin_gc.h: slang_common_builtin.gc + $(GLSL_CL) fragment slang_common_builtin.gc slang_common_builtin_gc.h -slang_core_gc.h: gc_to_bin slang_core.gc - ./gc_to_bin 1 slang_core.gc slang_core_gc.h +slang_core_gc.h: slang_core.gc + $(GLSL_CL) fragment slang_core.gc slang_core_gc.h -slang_fragment_builtin_gc.h: gc_to_bin slang_fragment_builtin.gc - ./gc_to_bin 1 slang_fragment_builtin.gc slang_fragment_builtin_gc.h +slang_fragment_builtin_gc.h: slang_fragment_builtin.gc + $(GLSL_CL) fragment slang_fragment_builtin.gc slang_fragment_builtin_gc.h -slang_vertex_builtin_gc.h: gc_to_bin slang_vertex_builtin.gc - ./gc_to_bin 2 slang_vertex_builtin.gc slang_vertex_builtin_gc.h +slang_vertex_builtin_gc.h: slang_vertex_builtin.gc + $(GLSL_CL) vertex slang_vertex_builtin.gc slang_vertex_builtin_gc.h -- cgit v1.2.3 From 91e164b3d0b1d36bfdf369266ae7e1ab396f1ba2 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 10 Dec 2009 12:38:22 +0100 Subject: glsl/pp: Add sl_pp_context_add_extension(). This way third parties are able to add supported extension strings. --- src/glsl/pp/sl_pp_context.h | 10 +++++++++ src/glsl/pp/sl_pp_dict.c | 2 -- src/glsl/pp/sl_pp_dict.h | 2 -- src/glsl/pp/sl_pp_extension.c | 49 ++++++++++++++++++++++++++++++++----------- src/glsl/pp/sl_pp_macro.c | 12 +++++++++++ src/glsl/pp/sl_pp_public.h | 5 +++++ 6 files changed, 64 insertions(+), 16 deletions(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index 569a2d735b9..5e3ae72fdfa 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -37,6 +37,13 @@ #define SL_PP_MAX_ERROR_MSG 1024 +#define SL_PP_MAX_EXTENSIONS 16 + +struct sl_pp_extension { + int name; /*< VENDOR_extension_name */ + int name_string; /*< GL_VENDOR_extension_name */ +}; + struct sl_pp_context { char *cstr_pool; unsigned int cstr_pool_max; @@ -46,6 +53,9 @@ struct sl_pp_context { struct sl_pp_macro *macro; struct sl_pp_macro **macro_tail; + struct sl_pp_extension extensions[SL_PP_MAX_EXTENSIONS]; + unsigned int num_extensions; + unsigned int if_stack[SL_PP_MAX_IF_NESTING]; unsigned int if_ptr; unsigned int if_value; diff --git a/src/glsl/pp/sl_pp_dict.c b/src/glsl/pp/sl_pp_dict.c index 2dd77a69e90..062139e6ac0 100644 --- a/src/glsl/pp/sl_pp_dict.c +++ b/src/glsl/pp/sl_pp_dict.c @@ -45,8 +45,6 @@ int sl_pp_dict_init(struct sl_pp_context *context) { ADD_NAME(context, all); - ADD_NAME_STR(context, _GL_ARB_draw_buffers, "GL_ARB_draw_buffers"); - ADD_NAME_STR(context, _GL_ARB_texture_rectangle, "GL_ARB_texture_rectangle"); ADD_NAME(context, require); ADD_NAME(context, enable); diff --git a/src/glsl/pp/sl_pp_dict.h b/src/glsl/pp/sl_pp_dict.h index 49f0e0bf9fa..875217bd309 100644 --- a/src/glsl/pp/sl_pp_dict.h +++ b/src/glsl/pp/sl_pp_dict.h @@ -33,8 +33,6 @@ struct sl_pp_context; struct sl_pp_dict { int all; - int _GL_ARB_draw_buffers; - int _GL_ARB_texture_rectangle; int require; int enable; diff --git a/src/glsl/pp/sl_pp_extension.c b/src/glsl/pp/sl_pp_extension.c index 4148fd9a5a3..67b24404d4d 100644 --- a/src/glsl/pp/sl_pp_extension.c +++ b/src/glsl/pp/sl_pp_extension.c @@ -28,8 +28,34 @@ #include #include #include "sl_pp_process.h" +#include "sl_pp_public.h" +int +sl_pp_context_add_extension(struct sl_pp_context *context, + const char *name, + const char *name_string) +{ + struct sl_pp_extension ext; + + if (context->num_extensions == SL_PP_MAX_EXTENSIONS) { + return -1; + } + + ext.name = sl_pp_context_add_unique_str(context, name); + if (ext.name == -1) { + return -1; + } + + ext.name_string = sl_pp_context_add_unique_str(context, name_string); + if (ext.name_string == -1) { + return -1; + } + + context->extensions[context->num_extensions++] = ext; + return 0; +} + int sl_pp_process_extension(struct sl_pp_context *context, const struct sl_pp_token_info *input, @@ -37,14 +63,7 @@ sl_pp_process_extension(struct sl_pp_context *context, unsigned int last, struct sl_pp_process_state *state) { - int extensions[] = { - context->dict.all, - context->dict._GL_ARB_draw_buffers, - context->dict._GL_ARB_texture_rectangle, - -1 - }; int extension_name = -1; - int *ext; int behavior = -1; struct sl_pp_token_info out; @@ -59,11 +78,17 @@ sl_pp_process_extension(struct sl_pp_context *context, } /* Make sure the extension is supported. */ - out.data.extension = -1; - for (ext = extensions; *ext != -1; ext++) { - if (extension_name == *ext) { - out.data.extension = extension_name; - break; + if (extension_name == context->dict.all) { + out.data.extension = extension_name; + } else { + unsigned int i; + + out.data.extension = -1; + for (i = 0; i < context->num_extensions; i++) { + if (extension_name == context->extensions[i].name_string) { + out.data.extension = extension_name; + break; + } } } diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index 29f1229dd7d..05466c9a7c3 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -163,6 +163,18 @@ sl_pp_macro_expand(struct sl_pp_context *context, return 0; } + /* Replace extension names with 1. + */ + for (j = 0; j < context->num_extensions; j++) { + if (macro_name == context->extensions[j].name) { + if (!mute && _out_number(context, state, 1)) { + return -1; + } + (*pi)++; + return 0; + } + } + /* TODO: For FEATURE_es2_glsl, expand to 1 the following symbols. * GL_ES * GL_FRAGMENT_PRECISION_HIGH diff --git a/src/glsl/pp/sl_pp_public.h b/src/glsl/pp/sl_pp_public.h index 8317c7e378a..20f208975e4 100644 --- a/src/glsl/pp/sl_pp_public.h +++ b/src/glsl/pp/sl_pp_public.h @@ -45,6 +45,11 @@ sl_pp_context_destroy(struct sl_pp_context *context); const char * sl_pp_context_error_message(const struct sl_pp_context *context); +int +sl_pp_context_add_extension(struct sl_pp_context *context, + const char *name, + const char *name_string); + int sl_pp_context_add_unique_str(struct sl_pp_context *context, const char *str); -- cgit v1.2.3 From 22200bcafcc77ecdca0127ac72d68e75e2ad7aee Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 10 Dec 2009 12:58:21 +0100 Subject: glsl/pp: Add support for user-defined macros. --- src/glsl/pp/sl_pp_context.c | 25 +++++++++++++++++++++++++ src/glsl/pp/sl_pp_context.h | 10 ++++++++++ src/glsl/pp/sl_pp_macro.c | 17 +++++++++++++++++ src/glsl/pp/sl_pp_public.h | 5 +++++ 4 files changed, 57 insertions(+) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index 134588d9066..afc1b84d16a 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -79,6 +79,31 @@ sl_pp_context_error_message(const struct sl_pp_context *context) return context->error_msg; } +int +sl_pp_context_add_predefined(struct sl_pp_context *context, + const char *name, + const char *value) +{ + struct sl_pp_predefined pre; + + if (context->num_predefined == SL_PP_MAX_PREDEFINED) { + return -1; + } + + pre.name = sl_pp_context_add_unique_str(context, name); + if (pre.name == -1) { + return -1; + } + + pre.value = sl_pp_context_add_unique_str(context, value); + if (pre.value == -1) { + return -1; + } + + context->predefined[context->num_predefined++] = pre; + return 0; +} + int sl_pp_context_add_unique_str(struct sl_pp_context *context, const char *str) diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index 5e3ae72fdfa..d95d29e275c 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -39,11 +39,18 @@ #define SL_PP_MAX_EXTENSIONS 16 +#define SL_PP_MAX_PREDEFINED 16 + struct sl_pp_extension { int name; /*< VENDOR_extension_name */ int name_string; /*< GL_VENDOR_extension_name */ }; +struct sl_pp_predefined { + int name; + int value; +}; + struct sl_pp_context { char *cstr_pool; unsigned int cstr_pool_max; @@ -56,6 +63,9 @@ struct sl_pp_context { struct sl_pp_extension extensions[SL_PP_MAX_EXTENSIONS]; unsigned int num_extensions; + struct sl_pp_predefined predefined[SL_PP_MAX_PREDEFINED]; + unsigned int num_predefined; + unsigned int if_stack[SL_PP_MAX_IF_NESTING]; unsigned int if_ptr; unsigned int if_value; diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index 05466c9a7c3..08b44c7cbe4 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -163,6 +163,23 @@ sl_pp_macro_expand(struct sl_pp_context *context, return 0; } + for (j = 0; j < context->num_predefined; j++) { + if (macro_name == context->predefined[j].name) { + if (!mute) { + struct sl_pp_token_info ti; + + ti.token = SL_PP_UINT; + ti.data._uint = context->predefined[j].value; + if (sl_pp_process_out(state, &ti)) { + strcpy(context->error_msg, "out of memory"); + return -1; + } + } + (*pi)++; + return 0; + } + } + /* Replace extension names with 1. */ for (j = 0; j < context->num_extensions; j++) { diff --git a/src/glsl/pp/sl_pp_public.h b/src/glsl/pp/sl_pp_public.h index 20f208975e4..076903649cd 100644 --- a/src/glsl/pp/sl_pp_public.h +++ b/src/glsl/pp/sl_pp_public.h @@ -50,6 +50,11 @@ sl_pp_context_add_extension(struct sl_pp_context *context, const char *name, const char *name_string); +int +sl_pp_context_add_predefined(struct sl_pp_context *context, + const char *name, + const char *value); + int sl_pp_context_add_unique_str(struct sl_pp_context *context, const char *str); -- cgit v1.2.3 From 52271c5345fedcb5b30736d69e4944889dda234c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 10 Dec 2009 08:25:16 -0700 Subject: glsl/pp: declare sl_pp_purify_options to silence warning --- src/glsl/pp/sl_pp_token.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_token.h b/src/glsl/pp/sl_pp_token.h index 7a8fa2f1b9d..ba9834a9f24 100644 --- a/src/glsl/pp/sl_pp_token.h +++ b/src/glsl/pp/sl_pp_token.h @@ -120,6 +120,8 @@ struct sl_pp_token_info { union sl_pp_token_data data; }; +struct sl_pp_purify_options; + int sl_pp_tokenise(struct sl_pp_context *context, const char *input, -- cgit v1.2.3 From 0d654a7f2cf173723eee930d2e5b9a1dd0140aaf Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 10 Dec 2009 08:25:35 -0700 Subject: glsl/pp: make some functions static --- src/glsl/pp/sl_pp_token.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_token.c b/src/glsl/pp/sl_pp_token.c index 03f2f09cfd6..e9a60b6c508 100644 --- a/src/glsl/pp/sl_pp_token.c +++ b/src/glsl/pp/sl_pp_token.c @@ -35,7 +35,7 @@ #define PURE_ERROR 256 -int +static int _pure_getc(struct sl_pp_context *context) { char c; @@ -52,7 +52,7 @@ _pure_getc(struct sl_pp_context *context) } -void +static void _pure_ungetc(struct sl_pp_context *context, int c) { @@ -508,7 +508,7 @@ _tokenise_number(struct sl_pp_context *context, } -int +static int sl_pp_token_get(struct sl_pp_context *context, struct sl_pp_token_info *out) { -- cgit v1.2.3 From 491f384c3958067e6c4c994041f5d8d413b806bc Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Thu, 10 Dec 2009 16:29:04 +0000 Subject: scons: Get GLSL code building correctly when cross compiling. This is quite messy. GLSL code has to be built twice: one for the host OS, another for the target OS. --- SConstruct | 19 +++++++++ src/SConscript | 4 +- src/gallium/winsys/gdi/SConscript | 2 +- src/glsl/SConscript | 68 ++++++++++++++++++++++++++++++++ src/glsl/apps/SConscript | 36 ----------------- src/glsl/cl/SConscript | 11 ------ src/glsl/pp/SConscript | 24 ----------- src/mesa/shader/slang/library/SConscript | 8 ++++ 8 files changed, 97 insertions(+), 75 deletions(-) create mode 100644 src/glsl/SConscript delete mode 100644 src/glsl/apps/SConscript delete mode 100644 src/glsl/cl/SConscript delete mode 100644 src/glsl/pp/SConscript (limited to 'src/glsl/pp') diff --git a/SConstruct b/SConstruct index e9baab0947b..e71fcd673a0 100644 --- a/SConstruct +++ b/SConstruct @@ -160,6 +160,25 @@ Export('env') # TODO: Build several variants at the same time? # http://www.scons.org/wiki/SimultaneousVariantBuilds +if env['platform'] != common.default_platform: + # GLSL code has to be built twice -- one for the host OS, another for the target OS... + + host_env = Environment( + # options are ignored + # default tool is used + toolpath = ['#scons'], + ENV = os.environ, + ) + + host_env['platform'] = common.default_platform + + SConscript( + 'src/glsl/SConscript', + variant_dir = env['build'] + '/host', + duplicate = 0, # http://www.scons.org/doc/0.97/HTML/scons-user/x2261.html + exports={'env':host_env}, + ) + SConscript( 'src/SConscript', variant_dir = env['build'], diff --git a/src/SConscript b/src/SConscript index f7fac33790b..6083fcbec98 100644 --- a/src/SConscript +++ b/src/SConscript @@ -1,8 +1,6 @@ Import('*') -SConscript('glsl/pp/SConscript') -SConscript('glsl/cl/SConscript') -SConscript('glsl/apps/SConscript') +SConscript('glsl/SConscript') SConscript('gallium/SConscript') if 'mesa' in env['statetrackers']: diff --git a/src/gallium/winsys/gdi/SConscript b/src/gallium/winsys/gdi/SConscript index 5b6364a01df..9fbe9e800c3 100644 --- a/src/gallium/winsys/gdi/SConscript +++ b/src/gallium/winsys/gdi/SConscript @@ -39,5 +39,5 @@ if env['platform'] == 'windows': env.SharedLibrary( target ='opengl32', source = sources, - LIBS = wgl + glapi + mesa + drivers + auxiliaries + glsl + glslcl + env['LIBS'], + LIBS = wgl + glapi + mesa + drivers + auxiliaries + glsl + env['LIBS'], ) diff --git a/src/glsl/SConscript b/src/glsl/SConscript new file mode 100644 index 00000000000..6f1f81b199a --- /dev/null +++ b/src/glsl/SConscript @@ -0,0 +1,68 @@ +import common + +Import('*') + +env = env.Clone() + +sources = [ + 'pp/sl_pp_context.c', + 'pp/sl_pp_define.c', + 'pp/sl_pp_dict.c', + 'pp/sl_pp_error.c', + 'pp/sl_pp_expression.c', + 'pp/sl_pp_extension.c', + 'pp/sl_pp_if.c', + 'pp/sl_pp_line.c', + 'pp/sl_pp_macro.c', + 'pp/sl_pp_pragma.c', + 'pp/sl_pp_process.c', + 'pp/sl_pp_purify.c', + 'pp/sl_pp_token.c', + 'pp/sl_pp_version.c', + 'cl/sl_cl_parse.c', +] + +glsl = env.StaticLibrary( + target = 'glsl', + source = sources, +) + +Export('glsl') + +env = env.Clone() + +if env['platform'] == 'windows': + env.PrependUnique(LIBS = [ + 'user32', + ]) + +env.Prepend(LIBS = [glsl]) + +env.Program( + target = 'purify', + source = ['apps/purify.c'], +) + +env.Program( + target = 'tokenise', + source = ['apps/tokenise.c'], +) + +env.Program( + target = 'version', + source = ['apps/version.c'], +) + +env.Program( + target = 'process', + source = ['apps/process.c'], +) + +glsl_compile = env.Program( + target = 'compile', + source = ['apps/compile.c'], +) + +if env['platform'] == common.default_platform: + # Only export the GLSL compiler when building for the host platform + Export('glsl_compile') diff --git a/src/glsl/apps/SConscript b/src/glsl/apps/SConscript deleted file mode 100644 index 4c81b3be956..00000000000 --- a/src/glsl/apps/SConscript +++ /dev/null @@ -1,36 +0,0 @@ -Import('*') - -env = env.Clone() - -if env['platform'] == 'windows': - env.PrependUnique(LIBS = [ - 'user32', - ]) - -env.Prepend(LIBS = [glsl, glslcl]) - -env.Program( - target = 'purify', - source = ['purify.c'], -) - -env.Program( - target = 'tokenise', - source = ['tokenise.c'], -) - -env.Program( - target = 'version', - source = ['version.c'], -) - -env.Program( - target = 'process', - source = ['process.c'], -) - -glsl_compile = env.Program( - target = 'compile', - source = ['compile.c'], -) -Export('glsl_compile') diff --git a/src/glsl/cl/SConscript b/src/glsl/cl/SConscript deleted file mode 100644 index 9a4e4c15b6d..00000000000 --- a/src/glsl/cl/SConscript +++ /dev/null @@ -1,11 +0,0 @@ -Import('*') - -env = env.Clone() - -glslcl = env.StaticLibrary( - target = 'glslcl', - source = [ - 'sl_cl_parse.c', - ], -) -Export('glslcl') diff --git a/src/glsl/pp/SConscript b/src/glsl/pp/SConscript deleted file mode 100644 index 5bd615c8d7f..00000000000 --- a/src/glsl/pp/SConscript +++ /dev/null @@ -1,24 +0,0 @@ -Import('*') - -env = env.Clone() - -glsl = env.StaticLibrary( - target = 'glsl', - source = [ - 'sl_pp_context.c', - 'sl_pp_define.c', - 'sl_pp_dict.c', - 'sl_pp_error.c', - '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', - 'sl_pp_purify.c', - 'sl_pp_token.c', - 'sl_pp_version.c', - ], -) -Export('glsl') diff --git a/src/mesa/shader/slang/library/SConscript b/src/mesa/shader/slang/library/SConscript index 8b3fd03b6bc..ef131146be5 100644 --- a/src/mesa/shader/slang/library/SConscript +++ b/src/mesa/shader/slang/library/SConscript @@ -5,13 +5,21 @@ Import('*') env = env.Clone() +# See also http://www.scons.org/wiki/UsingCodeGenerators + +def glsl_compile_emitter(target, source, env): + env.Depends(target, glsl_compile) + return (target, source) + bld_frag = Builder( action = glsl_compile[0].abspath + ' fragment $SOURCE $TARGET', + emitter = glsl_compile_emitter, suffix = '.gc', src_suffix = '_gc.h') bld_vert = Builder( action = glsl_compile[0].abspath + ' vertex $SOURCE $TARGET', + emitter = glsl_compile_emitter, suffix = '.gc', src_suffix = '_gc.h') -- cgit v1.2.3 From e9aa65d2b751f81fecd365fd6a550562417a3ec2 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 19 Dec 2009 09:55:27 +0100 Subject: glsl/pp: Report correct error line for purify and tokeniser errors. --- src/glsl/pp/sl_pp_context.c | 14 ++++++++++++++ src/glsl/pp/sl_pp_context.h | 1 + src/glsl/pp/sl_pp_public.h | 5 +++++ src/glsl/pp/sl_pp_token.c | 3 +-- 4 files changed, 21 insertions(+), 2 deletions(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index afc1b84d16a..2ce50790313 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -56,6 +56,7 @@ sl_pp_context_create(void) context->if_ptr = SL_PP_MAX_IF_NESTING; context->if_value = 1; memset(context->error_msg, 0, sizeof(context->error_msg)); + context->error_line = 1; context->line = 1; context->file = 0; @@ -79,6 +80,19 @@ sl_pp_context_error_message(const struct sl_pp_context *context) return context->error_msg; } +void +sl_pp_context_error_position(const struct sl_pp_context *context, + unsigned int *file, + unsigned int *line) +{ + if (file) { + *file = 0; + } + if (line) { + *line = context->error_line; + } +} + int sl_pp_context_add_predefined(struct sl_pp_context *context, const char *name, diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index d95d29e275c..fa939143e9a 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -71,6 +71,7 @@ struct sl_pp_context { unsigned int if_value; char error_msg[SL_PP_MAX_ERROR_MSG]; + unsigned int error_line; unsigned int line; unsigned int file; diff --git a/src/glsl/pp/sl_pp_public.h b/src/glsl/pp/sl_pp_public.h index 076903649cd..9d0a08ca457 100644 --- a/src/glsl/pp/sl_pp_public.h +++ b/src/glsl/pp/sl_pp_public.h @@ -45,6 +45,11 @@ sl_pp_context_destroy(struct sl_pp_context *context); const char * sl_pp_context_error_message(const struct sl_pp_context *context); +void +sl_pp_context_error_position(const struct sl_pp_context *context, + unsigned int *file, + unsigned int *line); + int sl_pp_context_add_extension(struct sl_pp_context *context, const char *name, diff --git a/src/glsl/pp/sl_pp_token.c b/src/glsl/pp/sl_pp_token.c index e9a60b6c508..d1abbd5257c 100644 --- a/src/glsl/pp/sl_pp_token.c +++ b/src/glsl/pp/sl_pp_token.c @@ -39,13 +39,12 @@ static int _pure_getc(struct sl_pp_context *context) { char c; - unsigned int current_line; if (context->getc_buf_size) { return context->getc_buf[--context->getc_buf_size]; } - if (sl_pp_purify_getc(&context->pure, &c, ¤t_line, context->error_msg, sizeof(context->error_msg)) == 0) { + if (sl_pp_purify_getc(&context->pure, &c, &context->error_line, context->error_msg, sizeof(context->error_msg)) == 0) { return PURE_ERROR; } return c; -- cgit v1.2.3 From 7631dca25bd390901036b48709e243db961d3a1f Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 19 Dec 2009 11:03:47 +0100 Subject: glsl/pp: Remove outdated TODO. Already implemented in mesa compiler using predefined symbols. --- src/glsl/pp/sl_pp_macro.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index 08b44c7cbe4..335142fc615 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -192,11 +192,6 @@ sl_pp_macro_expand(struct sl_pp_context *context, } } - /* TODO: For FEATURE_es2_glsl, expand to 1 the following symbols. - * GL_ES - * GL_FRAGMENT_PRECISION_HIGH - */ - if (local) { for (macro = local; macro; macro = macro->next) { if (macro->name == macro_name) { -- cgit v1.2.3 From d696cb279d80ccddebcb28ef6b6284bc6bb9430f Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 20 Dec 2009 13:50:16 +0100 Subject: glsl/pp: Do processing inline with tokenisation. --- src/glsl/pp/sl_pp_context.c | 14 ++- src/glsl/pp/sl_pp_context.h | 3 + src/glsl/pp/sl_pp_if.c | 79 ++++++++------- src/glsl/pp/sl_pp_line.c | 25 +++-- src/glsl/pp/sl_pp_macro.c | 203 +++++++++++++++++++++------------------ src/glsl/pp/sl_pp_macro.h | 3 +- src/glsl/pp/sl_pp_process.c | 158 +++++++++++++++--------------- src/glsl/pp/sl_pp_process.h | 12 +-- src/glsl/pp/sl_pp_public.h | 8 +- src/glsl/pp/sl_pp_token.c | 8 +- src/glsl/pp/sl_pp_token.h | 6 +- src/glsl/pp/sl_pp_token_util.h | 211 +++++++++++++++++++++++++++++++++++++++++ src/glsl/pp/sl_pp_version.c | 63 ++++++++---- 13 files changed, 524 insertions(+), 269 deletions(-) create mode 100644 src/glsl/pp/sl_pp_token_util.h (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index 2ce50790313..c1cef41bceb 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -32,7 +32,8 @@ struct sl_pp_context * -sl_pp_context_create(void) +sl_pp_context_create(const char *input, + const struct sl_pp_purify_options *options) { struct sl_pp_context *context; @@ -46,12 +47,18 @@ sl_pp_context_create(void) return NULL; } - context->getc_buf = malloc(64 * sizeof(char)); + context->getc_buf_capacity = 64; + context->getc_buf = malloc(context->getc_buf_capacity * sizeof(char)); if (!context->getc_buf) { sl_pp_context_destroy(context); return NULL; } + if (sl_pp_token_buffer_init(&context->tokens, context)) { + sl_pp_context_destroy(context); + return NULL; + } + context->macro_tail = &context->macro; context->if_ptr = SL_PP_MAX_IF_NESTING; context->if_value = 1; @@ -60,6 +67,8 @@ sl_pp_context_create(void) context->line = 1; context->file = 0; + sl_pp_purify_state_init(&context->pure, input, options); + return context; } @@ -70,6 +79,7 @@ sl_pp_context_destroy(struct sl_pp_context *context) free(context->cstr_pool); sl_pp_macro_free(context->macro); free(context->getc_buf); + sl_pp_token_buffer_destroy(&context->tokens); free(context); } } diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index fa939143e9a..5e1c5630483 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -31,6 +31,7 @@ #include "sl_pp_dict.h" #include "sl_pp_macro.h" #include "sl_pp_purify.h" +#include "sl_pp_token_util.h" #define SL_PP_MAX_IF_NESTING 64 @@ -81,6 +82,8 @@ struct sl_pp_context { char *getc_buf; unsigned int getc_buf_size; unsigned int getc_buf_capacity; + + struct sl_pp_token_buffer tokens; }; #endif /* SL_PP_CONTEXT_H */ diff --git a/src/glsl/pp/sl_pp_if.c b/src/glsl/pp/sl_pp_if.c index 6610bc69f3c..f12f0f142c6 100644 --- a/src/glsl/pp/sl_pp_if.c +++ b/src/glsl/pp/sl_pp_if.c @@ -31,55 +31,50 @@ #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)++; - } -} - static int _parse_defined(struct sl_pp_context *context, - const struct sl_pp_token_info *input, - unsigned int *pi, + struct sl_pp_token_buffer *buffer, struct sl_pp_process_state *state) { + struct sl_pp_token_info input; int parens = 0; int macro_name; struct sl_pp_macro *macro; int defined = 0; struct sl_pp_token_info result; - skip_whitespace(input, pi); - if (input[*pi].token == SL_PP_LPAREN) { - (*pi)++; - skip_whitespace(input, pi); + if (sl_pp_token_buffer_skip_white(buffer, &input)) { + return -1; + } + + if (input.token == SL_PP_LPAREN) { + if (sl_pp_token_buffer_skip_white(buffer, &input)) { + return -1; + } parens = 1; } - if (input[*pi].token != SL_PP_IDENTIFIER) { + if (input.token != SL_PP_IDENTIFIER) { strcpy(context->error_msg, "expected an identifier"); return -1; } - macro_name = input[*pi].data.identifier; + macro_name = input.data.identifier; for (macro = context->macro; macro; macro = macro->next) { if (macro->name == macro_name) { defined = 1; break; } } - (*pi)++; if (parens) { - skip_whitespace(input, pi); - if (input[*pi].token != SL_PP_RPAREN) { + if (sl_pp_token_buffer_skip_white(buffer, &input)) { + return -1; + } + if (input.token != SL_PP_RPAREN) { strcpy(context->error_msg, "expected `)'"); return -1; } - (*pi)++; } result.token = SL_PP_UINT; @@ -108,12 +103,10 @@ _evaluate_if_stack(struct sl_pp_context *context) static int _parse_if(struct sl_pp_context *context, - const struct sl_pp_token_info *input, - unsigned int first, - unsigned int last) + struct sl_pp_token_buffer *buffer) { - unsigned int i; struct sl_pp_process_state state; + int found_end = 0; struct sl_pp_token_info eof; int result; @@ -123,34 +116,40 @@ _parse_if(struct sl_pp_context *context, } memset(&state, 0, sizeof(state)); - for (i = first; i < last;) { - switch (input[i].token) { + while (!found_end) { + struct sl_pp_token_info input; + + sl_pp_token_buffer_get(buffer, &input); + switch (input.token) { case SL_PP_WHITESPACE: - i++; break; case SL_PP_IDENTIFIER: - if (input[i].data.identifier == context->dict.defined) { - i++; - if (_parse_defined(context, input, &i, &state)) { + if (input.data.identifier == context->dict.defined) { + if (_parse_defined(context, buffer, &state)) { free(state.out); return -1; } } else { - if (sl_pp_macro_expand(context, input, &i, NULL, &state, sl_pp_macro_expand_unknown_to_0)) { + sl_pp_token_buffer_unget(buffer, &input); + if (sl_pp_macro_expand(context, buffer, NULL, &state, sl_pp_macro_expand_unknown_to_0)) { free(state.out); return -1; } } break; + case SL_PP_NEWLINE: + case SL_PP_EOF: + found_end = 1; + break; + default: - if (sl_pp_process_out(&state, &input[i])) { + if (sl_pp_process_out(&state, &input)) { strcpy(context->error_msg, "out of memory"); free(state.out); return -1; } - i++; } } @@ -198,11 +197,9 @@ _parse_else(struct sl_pp_context *context) int sl_pp_process_if(struct sl_pp_context *context, - const struct sl_pp_token_info *input, - unsigned int first, - unsigned int last) + struct sl_pp_token_buffer *buffer) { - return _parse_if(context, input, first, last); + return _parse_if(context, buffer); } int @@ -301,9 +298,7 @@ sl_pp_process_ifndef(struct sl_pp_context *context, int sl_pp_process_elif(struct sl_pp_context *context, - const struct sl_pp_token_info *input, - unsigned int first, - unsigned int last) + struct sl_pp_token_buffer *buffer) { if (_parse_else(context)) { return -1; @@ -311,7 +306,7 @@ sl_pp_process_elif(struct sl_pp_context *context, if (context->if_stack[context->if_ptr] & 1) { context->if_ptr++; - if (_parse_if(context, input, first, last)) { + if (_parse_if(context, buffer)) { return -1; } } diff --git a/src/glsl/pp/sl_pp_line.c b/src/glsl/pp/sl_pp_line.c index ed5acc697ce..87987fc2baf 100644 --- a/src/glsl/pp/sl_pp_line.c +++ b/src/glsl/pp/sl_pp_line.c @@ -33,39 +33,44 @@ int sl_pp_process_line(struct sl_pp_context *context, - const struct sl_pp_token_info *input, - unsigned int first, - unsigned int last, + struct sl_pp_token_buffer *buffer, struct sl_pp_process_state *pstate) { - unsigned int i; struct sl_pp_process_state state; + int found_end = 0; int line_number = -1; int file_number = -1; unsigned int line; unsigned int file; memset(&state, 0, sizeof(state)); - for (i = first; i < last;) { - switch (input[i].token) { + while (!found_end) { + struct sl_pp_token_info input; + + sl_pp_token_buffer_get(buffer, &input); + switch (input.token) { case SL_PP_WHITESPACE: - i++; break; case SL_PP_IDENTIFIER: - if (sl_pp_macro_expand(context, input, &i, NULL, &state, sl_pp_macro_expand_normal)) { + sl_pp_token_buffer_unget(buffer, &input); + if (sl_pp_macro_expand(context, buffer, NULL, &state, sl_pp_macro_expand_normal)) { free(state.out); return -1; } break; + case SL_PP_NEWLINE: + case SL_PP_EOF: + found_end = 1; + break; + default: - if (sl_pp_process_out(&state, &input[i])) { + if (sl_pp_process_out(&state, &input)) { strcpy(context->error_msg, "out of memory"); free(state.out); return -1; } - i++; } } diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index 335142fc615..c98ab6559a6 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -88,15 +88,6 @@ sl_pp_macro_reset(struct sl_pp_macro *macro) _macro_init(macro); } -static void -skip_whitespace(const struct sl_pp_token_info *input, - unsigned int *pi) -{ - while (input[*pi].token == SL_PP_WHITESPACE) { - (*pi)++; - } -} - static int _out_number(struct sl_pp_context *context, struct sl_pp_process_state *state, @@ -119,24 +110,28 @@ _out_number(struct sl_pp_context *context, int sl_pp_macro_expand(struct sl_pp_context *context, - const struct sl_pp_token_info *input, - unsigned int *pi, + struct sl_pp_token_buffer *tokens, struct sl_pp_macro *local, struct sl_pp_process_state *state, enum sl_pp_macro_expand_behaviour behaviour) { int mute = (behaviour == sl_pp_macro_expand_mute); + struct sl_pp_token_info input; 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) { + if (sl_pp_token_buffer_get(tokens, &input)) { + return -1; + } + + if (input.token != SL_PP_IDENTIFIER) { strcpy(context->error_msg, "expected an identifier"); return -1; } - macro_name = input[*pi].data.identifier; + macro_name = input.data.identifier; /* First look for predefined macros. */ @@ -145,21 +140,18 @@ sl_pp_macro_expand(struct sl_pp_context *context, if (!mute && _out_number(context, state, context->line)) { return -1; } - (*pi)++; return 0; } if (macro_name == context->dict.___FILE__) { if (!mute && _out_number(context, state, context->file)) { return -1; } - (*pi)++; return 0; } if (macro_name == context->dict.___VERSION__) { if (!mute && _out_number(context, state, 110)) { return -1; } - (*pi)++; return 0; } @@ -175,7 +167,6 @@ sl_pp_macro_expand(struct sl_pp_context *context, return -1; } } - (*pi)++; return 0; } } @@ -187,7 +178,6 @@ sl_pp_macro_expand(struct sl_pp_context *context, if (!mute && _out_number(context, state, 1)) { return -1; } - (*pi)++; return 0; } } @@ -215,25 +205,26 @@ sl_pp_macro_expand(struct sl_pp_context *context, return -1; } } else if (!mute) { - if (sl_pp_process_out(state, &input[*pi])) { + if (sl_pp_process_out(state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } } - (*pi)++; return 0; } - (*pi)++; - if (macro->num_args >= 0) { - skip_whitespace(input, pi); - if (input[*pi].token != SL_PP_LPAREN) { + if (sl_pp_token_buffer_skip_white(tokens, &input)) { + return -1; + } + if (input.token != SL_PP_LPAREN) { strcpy(context->error_msg, "expected `('"); return -1; } - (*pi)++; - skip_whitespace(input, pi); + if (sl_pp_token_buffer_skip_white(tokens, &input)) { + return -1; + } + sl_pp_token_buffer_unget(tokens, &input); } if (macro->num_args > 0) { @@ -242,103 +233,85 @@ sl_pp_macro_expand(struct sl_pp_context *context, for (j = 0; j < (unsigned int)macro->num_args; j++) { struct sl_pp_process_state arg_state; - unsigned int i; int done = 0; unsigned int paren_nesting = 0; struct sl_pp_token_info eof; memset(&arg_state, 0, sizeof(arg_state)); - for (i = *pi; !done;) { - switch (input[i].token) { + while (!done) { + if (sl_pp_token_buffer_get(tokens, &input)) { + goto fail_arg; + } + switch (input.token) { case SL_PP_WHITESPACE: - i++; break; case SL_PP_COMMA: if (!paren_nesting) { if (j < (unsigned int)macro->num_args - 1) { done = 1; - i++; } else { strcpy(context->error_msg, "too many actual macro arguments"); - return -1; + goto fail_arg; } } else { - if (sl_pp_process_out(&arg_state, &input[i])) { + if (sl_pp_process_out(&arg_state, &input)) { strcpy(context->error_msg, "out of memory"); - free(arg_state.out); - return -1; + goto fail_arg; } - i++; } break; case SL_PP_LPAREN: paren_nesting++; - if (sl_pp_process_out(&arg_state, &input[i])) { - strcpy(context->error_msg, "out of memory"); - free(arg_state.out); - return -1; + if (sl_pp_process_out(&arg_state, &input)) { + goto oom_arg; } - i++; break; case SL_PP_RPAREN: if (!paren_nesting) { if (j == (unsigned int)macro->num_args - 1) { done = 1; - i++; } else { strcpy(context->error_msg, "too few actual macro arguments"); - return -1; + goto fail_arg; } } else { paren_nesting--; - if (sl_pp_process_out(&arg_state, &input[i])) { - strcpy(context->error_msg, "out of memory"); - free(arg_state.out); - return -1; + if (sl_pp_process_out(&arg_state, &input)) { + goto oom_arg; } - i++; } break; case SL_PP_IDENTIFIER: - if (sl_pp_macro_expand(context, input, &i, local, &arg_state, sl_pp_macro_expand_normal)) { - free(arg_state.out); - return -1; + sl_pp_token_buffer_unget(tokens, &input); + if (sl_pp_macro_expand(context, tokens, local, &arg_state, sl_pp_macro_expand_normal)) { + goto fail_arg; } break; case SL_PP_EOF: strcpy(context->error_msg, "too few actual macro arguments"); - return -1; + goto fail_arg; default: - if (sl_pp_process_out(&arg_state, &input[i])) { - strcpy(context->error_msg, "out of memory"); - free(arg_state.out); - return -1; + if (sl_pp_process_out(&arg_state, &input)) { + goto oom_arg; } - i++; } } - (*pi) = i; - eof.token = SL_PP_EOF; if (sl_pp_process_out(&arg_state, &eof)) { - strcpy(context->error_msg, "out of memory"); - free(arg_state.out); - return -1; + goto oom_arg; } *pmacro = sl_pp_macro_new(); if (!*pmacro) { - strcpy(context->error_msg, "out of memory"); - free(arg_state.out); - return -1; + goto oom_arg; } (**pmacro).name = formal_arg->name; @@ -346,47 +319,95 @@ sl_pp_macro_expand(struct sl_pp_context *context, formal_arg = formal_arg->next; pmacro = &(**pmacro).next; + + continue; + +oom_arg: + strcpy(context->error_msg, "out of memory"); +fail_arg: + free(arg_state.out); + goto fail; } } /* 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) { + if (sl_pp_token_buffer_skip_white(tokens, &input)) { + goto fail; + } + if (input.token != SL_PP_RPAREN) { strcpy(context->error_msg, "expected `)'"); - return -1; + goto fail; } - (*pi)++; } - for (j = 0;;) { - switch (macro->body[j].token) { - case SL_PP_NEWLINE: - if (sl_pp_process_out(state, ¯o->body[j])) { - strcpy(context->error_msg, "out of memory"); - return -1; - } - j++; - break; + /* XXX: This is all wrong, we should be ungetting all tokens + * back to the main token buffer. + */ + { + struct sl_pp_token_buffer buffer; - case SL_PP_IDENTIFIER: - if (sl_pp_macro_expand(context, macro->body, &j, actual_arg, state, behaviour)) { - return -1; - } - break; + /* Seek to the end. + */ + for (j = 0; macro->body[j].token != SL_PP_EOF; j++) { + } + j++; + + /* Create a context-less token buffer since we are not going to underrun + * its internal buffer. + */ + if (sl_pp_token_buffer_init(&buffer, NULL)) { + strcpy(context->error_msg, "out of memory"); + goto fail; + } - case SL_PP_EOF: - sl_pp_macro_free(actual_arg); - return 0; + /* Unget the tokens in reverse order so later they will be fetched correctly. + */ + for (; j > 0; j--) { + sl_pp_token_buffer_unget(&buffer, ¯o->body[j - 1]); + } - default: - if (!mute) { - if (sl_pp_process_out(state, ¯o->body[j])) { + /* Expand. + */ + for (;;) { + struct sl_pp_token_info input; + + sl_pp_token_buffer_get(&buffer, &input); + switch (input.token) { + case SL_PP_NEWLINE: + if (sl_pp_process_out(state, &input)) { strcpy(context->error_msg, "out of memory"); - return -1; + sl_pp_token_buffer_destroy(&buffer); + goto fail; + } + break; + + case SL_PP_IDENTIFIER: + sl_pp_token_buffer_unget(&buffer, &input); + if (sl_pp_macro_expand(context, &buffer, actual_arg, state, behaviour)) { + sl_pp_token_buffer_destroy(&buffer); + goto fail; + } + break; + + case SL_PP_EOF: + sl_pp_token_buffer_destroy(&buffer); + sl_pp_macro_free(actual_arg); + return 0; + + default: + if (!mute) { + if (sl_pp_process_out(state, &input)) { + strcpy(context->error_msg, "out of memory"); + sl_pp_token_buffer_destroy(&buffer); + goto fail; + } } } - j++; } } + +fail: + sl_pp_macro_free(actual_arg); + return -1; } diff --git a/src/glsl/pp/sl_pp_macro.h b/src/glsl/pp/sl_pp_macro.h index 3ad3438236a..2967baf3375 100644 --- a/src/glsl/pp/sl_pp_macro.h +++ b/src/glsl/pp/sl_pp_macro.h @@ -64,8 +64,7 @@ enum sl_pp_macro_expand_behaviour { int sl_pp_macro_expand(struct sl_pp_context *context, - const struct sl_pp_token_info *input, - unsigned int *pi, + struct sl_pp_token_buffer *tokens, struct sl_pp_macro *local, struct sl_pp_process_state *state, enum sl_pp_macro_expand_behaviour behaviour); diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index e2adc2a0215..6dcd0ab4015 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -31,15 +31,6 @@ #include "sl_pp_public.h" -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_process_out(struct sl_pp_process_state *state, const struct sl_pp_token_info *token) @@ -68,12 +59,10 @@ sl_pp_process_out(struct sl_pp_process_state *state, 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; - int found_eof = 0; struct sl_pp_process_state state; + int found_eof = 0; memset(&state, 0, sizeof(state)); @@ -96,103 +85,113 @@ sl_pp_process(struct sl_pp_context *context, } while (!found_eof) { - skip_whitespace(input, &i); - if (input[i].token == SL_PP_HASH) { - i++; - skip_whitespace(input, &i); - switch (input[i].token) { + struct sl_pp_token_info input; + + if (sl_pp_token_buffer_skip_white(&context->tokens, &input)) { + return -1; + } + if (input.token == SL_PP_HASH) { + if (sl_pp_token_buffer_skip_white(&context->tokens, &input)) { + return -1; + } + switch (input.token) { case SL_PP_IDENTIFIER: { int name; int found_eol = 0; - unsigned int first; - unsigned int last; struct sl_pp_token_info endof; + struct sl_pp_token_peek peek; + int result; /* Directive name. */ - name = input[i].data.identifier; - i++; - skip_whitespace(input, &i); + name = input.data.identifier; - first = i; + if (sl_pp_token_buffer_skip_white(&context->tokens, &input)) { + return -1; + } + sl_pp_token_buffer_unget(&context->tokens, &input); + + if (sl_pp_token_peek_init(&peek, &context->tokens)) { + return -1; + } while (!found_eol) { - switch (input[i].token) { + if (sl_pp_token_peek_get(&peek, &input)) { + sl_pp_token_peek_destroy(&peek); + return -1; + } + switch (input.token) { case SL_PP_NEWLINE: /* Preserve newline just for the sake of line numbering. */ - endof = input[i]; - i++; + endof = input; found_eol = 1; break; case SL_PP_EOF: - endof = input[i]; - i++; + endof = input; found_eof = 1; found_eol = 1; break; - - default: - i++; } } - last = i - 1; - if (name == context->dict._if) { - if (sl_pp_process_if(context, input, first, last)) { - return -1; + struct sl_pp_token_buffer buffer; + + result = sl_pp_token_peek_to_buffer(&peek, &buffer); + if (result == 0) { + result = sl_pp_process_if(context, &buffer); + sl_pp_token_buffer_destroy(&buffer); } } else if (name == context->dict.ifdef) { - if (sl_pp_process_ifdef(context, input, first, last)) { - return -1; - } + result = sl_pp_process_ifdef(context, peek.tokens, 0, peek.size - 1); } else if (name == context->dict.ifndef) { - if (sl_pp_process_ifndef(context, input, first, last)) { - return -1; - } + result = sl_pp_process_ifndef(context, peek.tokens, 0, peek.size - 1); } else if (name == context->dict.elif) { - if (sl_pp_process_elif(context, input, first, last)) { - return -1; + struct sl_pp_token_buffer buffer; + + result = sl_pp_token_peek_to_buffer(&peek, &buffer); + if (result == 0) { + result = sl_pp_process_elif(context, &buffer); + sl_pp_token_buffer_destroy(&buffer); } } else if (name == context->dict._else) { - if (sl_pp_process_else(context, input, first, last)) { - return -1; - } + result = sl_pp_process_else(context, peek.tokens, 0, peek.size - 1); } else if (name == context->dict.endif) { - if (sl_pp_process_endif(context, input, first, last)) { - return -1; - } + result = sl_pp_process_endif(context, peek.tokens, 0, peek.size - 1); } else if (context->if_value) { if (name == context->dict.define) { - if (sl_pp_process_define(context, input, first, last)) { - return -1; - } + result = sl_pp_process_define(context, peek.tokens, 0, peek.size - 1); } else if (name == context->dict.error) { - sl_pp_process_error(context, input, first, last); - return -1; + sl_pp_process_error(context, peek.tokens, 0, peek.size - 1); + result = -1; } else if (name == context->dict.extension) { - if (sl_pp_process_extension(context, input, first, last, &state)) { - return -1; - } + result = sl_pp_process_extension(context, peek.tokens, 0, peek.size - 1, &state); } else if (name == context->dict.line) { - if (sl_pp_process_line(context, input, first, last, &state)) { - return -1; + struct sl_pp_token_buffer buffer; + + result = sl_pp_token_peek_to_buffer(&peek, &buffer); + if (result == 0) { + result = sl_pp_process_line(context, &buffer, &state); + sl_pp_token_buffer_destroy(&buffer); } } else if (name == context->dict.pragma) { - if (sl_pp_process_pragma(context, input, first, last, &state)) { - return -1; - } + result = sl_pp_process_pragma(context, peek.tokens, 0, peek.size - 1, &state); } else if (name == context->dict.undef) { - if (sl_pp_process_undef(context, input, first, last)) { - return -1; - } + result = sl_pp_process_undef(context, peek.tokens, 0, peek.size - 1); } else { strcpy(context->error_msg, "unrecognised directive name"); - return -1; + result = -1; } } + sl_pp_token_peek_commit(&peek); + sl_pp_token_peek_destroy(&peek); + + if (result) { + return result; + } + if (sl_pp_process_out(&state, &endof)) { strcpy(context->error_msg, "out of memory"); return -1; @@ -203,21 +202,19 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_NEWLINE: /* Empty directive. */ - if (sl_pp_process_out(&state, &input[i])) { + if (sl_pp_process_out(&state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } context->line++; - i++; break; case SL_PP_EOF: /* Empty directive. */ - if (sl_pp_process_out(&state, &input[i])) { + if (sl_pp_process_out(&state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } - i++; found_eof = 1; break; @@ -228,36 +225,40 @@ sl_pp_process(struct sl_pp_context *context, } else { int found_eol = 0; + sl_pp_token_buffer_unget(&context->tokens, &input); + while (!found_eol) { - switch (input[i].token) { + if (sl_pp_token_buffer_get(&context->tokens, &input)) { + return -1; + } + + switch (input.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 (sl_pp_process_out(&state, &input[i])) { + if (sl_pp_process_out(&state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } context->line++; - i++; found_eol = 1; break; case SL_PP_EOF: - if (sl_pp_process_out(&state, &input[i])) { + if (sl_pp_process_out(&state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } - i++; found_eof = 1; found_eol = 1; break; case SL_PP_IDENTIFIER: - if (sl_pp_macro_expand(context, input, &i, NULL, &state, + sl_pp_token_buffer_unget(&context->tokens, &input); + if (sl_pp_macro_expand(context, &context->tokens, NULL, &state, context->if_value ? sl_pp_macro_expand_normal : sl_pp_macro_expand_mute)) { return -1; } @@ -265,12 +266,11 @@ sl_pp_process(struct sl_pp_context *context, default: if (context->if_value) { - if (sl_pp_process_out(&state, &input[i])) { + if (sl_pp_process_out(&state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } } - i++; } } } diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h index 24311bab603..31defd911a3 100644 --- a/src/glsl/pp/sl_pp_process.h +++ b/src/glsl/pp/sl_pp_process.h @@ -53,9 +53,7 @@ sl_pp_process_undef(struct sl_pp_context *context, int sl_pp_process_if(struct sl_pp_context *context, - const struct sl_pp_token_info *input, - unsigned int first, - unsigned int last); + struct sl_pp_token_buffer *input); int sl_pp_process_ifdef(struct sl_pp_context *context, @@ -71,9 +69,7 @@ sl_pp_process_ifndef(struct sl_pp_context *context, int sl_pp_process_elif(struct sl_pp_context *context, - const struct sl_pp_token_info *input, - unsigned int first, - unsigned int last); + struct sl_pp_token_buffer *buffer); int sl_pp_process_else(struct sl_pp_context *context, @@ -109,9 +105,7 @@ sl_pp_process_extension(struct sl_pp_context *context, int sl_pp_process_line(struct sl_pp_context *context, - const struct sl_pp_token_info *input, - unsigned int first, - unsigned int last, + struct sl_pp_token_buffer *buffer, struct sl_pp_process_state *state); int diff --git a/src/glsl/pp/sl_pp_public.h b/src/glsl/pp/sl_pp_public.h index 9d0a08ca457..309a70c07ff 100644 --- a/src/glsl/pp/sl_pp_public.h +++ b/src/glsl/pp/sl_pp_public.h @@ -37,7 +37,8 @@ struct sl_pp_context; struct sl_pp_context * -sl_pp_context_create(void); +sl_pp_context_create(const char *input, + const struct sl_pp_purify_options *options); void sl_pp_context_destroy(struct sl_pp_context *context); @@ -70,13 +71,10 @@ sl_pp_context_cstr(const struct sl_pp_context *context, int sl_pp_version(struct sl_pp_context *context, - const struct sl_pp_token_info *input, - unsigned int *version, - unsigned int *tokens_eaten); + unsigned int *version); int sl_pp_process(struct sl_pp_context *context, - const struct sl_pp_token_info *input, struct sl_pp_token_info **output); #endif /* SL_PP_PUBLIC_H */ diff --git a/src/glsl/pp/sl_pp_token.c b/src/glsl/pp/sl_pp_token.c index d1abbd5257c..a7089787005 100644 --- a/src/glsl/pp/sl_pp_token.c +++ b/src/glsl/pp/sl_pp_token.c @@ -507,7 +507,7 @@ _tokenise_number(struct sl_pp_context *context, } -static int +int sl_pp_token_get(struct sl_pp_context *context, struct sl_pp_token_info *out) { @@ -809,20 +809,16 @@ sl_pp_token_get(struct sl_pp_context *context, int sl_pp_tokenise(struct sl_pp_context *context, - const char *input, - const struct sl_pp_purify_options *options, struct sl_pp_token_info **output) { struct sl_pp_token_info *out = NULL; unsigned int out_len = 0; unsigned int out_max = 0; - sl_pp_purify_state_init(&context->pure, input, options); - for (;;) { struct sl_pp_token_info info; - if (sl_pp_token_get(context, &info)) { + if (sl_pp_token_buffer_get(&context->tokens, &info)) { free(out); return -1; } diff --git a/src/glsl/pp/sl_pp_token.h b/src/glsl/pp/sl_pp_token.h index ba9834a9f24..a12b1934018 100644 --- a/src/glsl/pp/sl_pp_token.h +++ b/src/glsl/pp/sl_pp_token.h @@ -122,10 +122,12 @@ struct sl_pp_token_info { struct sl_pp_purify_options; +int +sl_pp_token_get(struct sl_pp_context *context, + struct sl_pp_token_info *out); + int sl_pp_tokenise(struct sl_pp_context *context, - const char *input, - const struct sl_pp_purify_options *options, struct sl_pp_token_info **output); #endif /* SL_PP_TOKEN_H */ diff --git a/src/glsl/pp/sl_pp_token_util.h b/src/glsl/pp/sl_pp_token_util.h new file mode 100644 index 00000000000..1685d243a5b --- /dev/null +++ b/src/glsl/pp/sl_pp_token_util.h @@ -0,0 +1,211 @@ +/************************************************************************** + * + * 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_TOKEN_UTIL_H +#define SL_PP_TOKEN_UTIL_H + +#include +#include +#include "sl_pp_token.h" + + +struct sl_pp_context; + +/* + * A token buffer allows one to get and unget a token + * from a preprocessor context. + */ +struct sl_pp_token_buffer { + struct sl_pp_context *context; + unsigned int size; + unsigned int capacity; + struct sl_pp_token_info *tokens; +}; + +static int +sl_pp_token_buffer_init(struct sl_pp_token_buffer *buffer, + struct sl_pp_context *context) +{ + buffer->context = context; + buffer->size = 0; + buffer->capacity = 64; + buffer->tokens = malloc(buffer->capacity * sizeof(struct sl_pp_token_info)); + if (!buffer->tokens) { + return -1; + } + return 0; +} + +static void +sl_pp_token_buffer_destroy(struct sl_pp_token_buffer *buffer) +{ + free(buffer->tokens); +} + +static int +sl_pp_token_buffer_get(struct sl_pp_token_buffer *buffer, + struct sl_pp_token_info *out) +{ + /* Pop from stack first if not empty. */ + if (buffer->size) { + *out = buffer->tokens[--buffer->size]; + return 0; + } + + assert(buffer->context); + return sl_pp_token_get(buffer->context, out); +} + +static void +sl_pp_token_buffer_unget(struct sl_pp_token_buffer *buffer, + const struct sl_pp_token_info *in) +{ + /* Resize if needed. */ + if (buffer->size == buffer->capacity) { + buffer->capacity += 64; + buffer->tokens = realloc(buffer->tokens, + buffer->capacity * sizeof(struct sl_pp_token_info)); + assert(buffer->tokens); + } + + /* Push token on stack. */ + buffer->tokens[buffer->size++] = *in; +} + +static int +sl_pp_token_buffer_skip_white(struct sl_pp_token_buffer *buffer, + struct sl_pp_token_info *out) +{ + if (sl_pp_token_buffer_get(buffer, out)) { + return -1; + } + + while (out->token == SL_PP_WHITESPACE) { + if (sl_pp_token_buffer_get(buffer, out)) { + return -1; + } + } + + return 0; +} + + +/* + * A token peek allows one to get a number of tokens from a buffer + * and then either commit the operation or abort it, + * effectively ungetting the peeked tokens. + */ +struct sl_pp_token_peek { + struct sl_pp_token_buffer *buffer; + unsigned int size; + unsigned int capacity; + struct sl_pp_token_info *tokens; +}; + +static int +sl_pp_token_peek_init(struct sl_pp_token_peek *peek, + struct sl_pp_token_buffer *buffer) +{ + peek->buffer = buffer; + peek->size = 0; + peek->capacity = 64; + peek->tokens = malloc(peek->capacity * sizeof(struct sl_pp_token_info)); + if (!peek->tokens) { + return -1; + } + return 0; +} + +static void +sl_pp_token_peek_destroy(struct sl_pp_token_peek *peek) +{ + /* Abort. */ + while (peek->size) { + sl_pp_token_buffer_unget(peek->buffer, &peek->tokens[--peek->size]); + } + free(peek->tokens); +} + +static int +sl_pp_token_peek_get(struct sl_pp_token_peek *peek, + struct sl_pp_token_info *out) +{ + /* Get token from buffer. */ + if (sl_pp_token_buffer_get(peek->buffer, out)) { + return -1; + } + + /* Save it. */ + if (peek->size == peek->capacity) { + peek->capacity += 64; + peek->tokens = realloc(peek->tokens, + peek->capacity * sizeof(struct sl_pp_token_info)); + assert(peek->tokens); + } + peek->tokens[peek->size++] = *out; + return 0; +} + +static void +sl_pp_token_peek_commit(struct sl_pp_token_peek *peek) +{ + peek->size = 0; +} + +static int +sl_pp_token_peek_to_buffer(const struct sl_pp_token_peek *peek, + struct sl_pp_token_buffer *buffer) +{ + unsigned int i; + + if (sl_pp_token_buffer_init(buffer, NULL)) { + return -1; + } + for (i = peek->size; i > 0; i--) { + sl_pp_token_buffer_unget(buffer, &peek->tokens[i - 1]); + } + return 0; +} + +static int +sl_pp_token_peek_skip_white(struct sl_pp_token_peek *peek, + struct sl_pp_token_info *out) +{ + if (sl_pp_token_peek_get(peek, out)) { + return -1; + } + + while (out->token == SL_PP_WHITESPACE) { + if (sl_pp_token_peek_get(peek, out)) { + return -1; + } + } + + return 0; +} + +#endif /* SL_PP_TOKEN_UTIL_H */ diff --git a/src/glsl/pp/sl_pp_version.c b/src/glsl/pp/sl_pp_version.c index db06523749c..3c995b77501 100644 --- a/src/glsl/pp/sl_pp_version.c +++ b/src/glsl/pp/sl_pp_version.c @@ -33,21 +33,23 @@ int sl_pp_version(struct sl_pp_context *context, - const struct sl_pp_token_info *input, - unsigned int *version, - unsigned int *tokens_eaten) + unsigned int *version) { - unsigned int i = 0; + struct sl_pp_token_peek peek; unsigned int line = context->line; /* Default values if `#version' is not present. */ *version = 110; - *tokens_eaten = 0; + + if (sl_pp_token_peek_init(&peek, &context->tokens)) { + return -1; + } /* There can be multiple `#version' directives present. * Accept the value of the last one. */ for (;;) { + struct sl_pp_token_info input; int found_hash = 0; int found_version = 0; int found_number = 0; @@ -55,82 +57,101 @@ sl_pp_version(struct sl_pp_context *context, /* Skip whitespace and newlines and seek for hash. */ while (!found_hash) { - switch (input[i].token) { + if (sl_pp_token_peek_get(&peek, &input)) { + sl_pp_token_peek_destroy(&peek); + return -1; + } + + switch (input.token) { case SL_PP_NEWLINE: line++; - /* pass thru */ + break; + case SL_PP_WHITESPACE: - i++; break; case SL_PP_HASH: - i++; found_hash = 1; break; default: + sl_pp_token_peek_destroy(&peek); return 0; } } /* Skip whitespace and seek for `version'. */ while (!found_version) { - switch (input[i].token) { + if (sl_pp_token_peek_get(&peek, &input)) { + sl_pp_token_peek_destroy(&peek); + return -1; + } + + switch (input.token) { case SL_PP_WHITESPACE: - i++; break; case SL_PP_IDENTIFIER: - if (input[i].data.identifier != context->dict.version) { + if (input.data.identifier != context->dict.version) { + sl_pp_token_peek_destroy(&peek); return 0; } - i++; found_version = 1; break; default: + sl_pp_token_peek_destroy(&peek); return 0; } } + sl_pp_token_peek_commit(&peek); + /* Skip whitespace and seek for version number. */ while (!found_number) { - switch (input[i].token) { + if (sl_pp_token_buffer_get(&context->tokens, &input)) { + sl_pp_token_peek_destroy(&peek); + return -1; + } + + switch (input.token) { case SL_PP_WHITESPACE: - i++; break; case SL_PP_UINT: - *version = atoi(sl_pp_context_cstr(context, input[i].data._uint)); - i++; + *version = atoi(sl_pp_context_cstr(context, input.data._uint)); found_number = 1; break; default: strcpy(context->error_msg, "expected version number after `#version'"); + sl_pp_token_peek_destroy(&peek); return -1; } } /* Skip whitespace and seek for either newline or eof. */ while (!found_end) { - switch (input[i].token) { + if (sl_pp_token_buffer_get(&context->tokens, &input)) { + sl_pp_token_peek_destroy(&peek); + return -1; + } + + switch (input.token) { case SL_PP_WHITESPACE: - i++; break; case SL_PP_NEWLINE: line++; /* pass thru */ case SL_PP_EOF: - i++; - *tokens_eaten = i; context->line = line; found_end = 1; break; default: strcpy(context->error_msg, "expected end of line after version number"); + sl_pp_token_peek_destroy(&peek); return -1; } } -- cgit v1.2.3 From d801c296c602d04055b02b3be2f1369bfe1092b7 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 20 Dec 2009 21:11:16 +0100 Subject: glsl: Do syntax parsing inline with processing. --- src/glsl/cl/sl_cl_parse.c | 151 ++++++++++++++++++++++++++++++++++++------ src/glsl/cl/sl_cl_parse.h | 1 - src/glsl/pp/sl_pp_context.c | 3 + src/glsl/pp/sl_pp_context.h | 3 + src/glsl/pp/sl_pp_define.c | 1 + src/glsl/pp/sl_pp_error.c | 1 + src/glsl/pp/sl_pp_extension.c | 1 + src/glsl/pp/sl_pp_line.c | 1 + src/glsl/pp/sl_pp_macro.c | 1 + src/glsl/pp/sl_pp_pragma.c | 1 + src/glsl/pp/sl_pp_process.c | 116 +++++++++++++++++++++----------- src/glsl/pp/sl_pp_process.h | 3 +- src/glsl/pp/sl_pp_public.h | 4 ++ 13 files changed, 225 insertions(+), 62 deletions(-) (limited to 'src/glsl/pp') diff --git a/src/glsl/cl/sl_cl_parse.c b/src/glsl/cl/sl_cl_parse.c index a9db65c7ad7..5dddf434e15 100644 --- a/src/glsl/cl/sl_cl_parse.c +++ b/src/glsl/cl/sl_cl_parse.c @@ -321,10 +321,13 @@ struct parse_dict { struct parse_context { struct sl_pp_context *context; - const struct sl_pp_token_info *input; struct parse_dict dict; + struct sl_pp_token_info *tokens; + unsigned int tokens_read; + unsigned int tokens_cap; + unsigned char *out_buf; unsigned int out_cap; @@ -332,6 +335,7 @@ struct parse_context { unsigned int parsing_builtin; char error[256]; + int process_error; }; @@ -366,7 +370,7 @@ _update(struct parse_context *ctx, static void _error(struct parse_context *ctx, - char *msg) + const char *msg) { if (ctx->error[0] == '\0') { strcpy(ctx->error, msg); @@ -374,12 +378,96 @@ _error(struct parse_context *ctx, } +static const struct sl_pp_token_info * +_fetch_token(struct parse_context *ctx, + unsigned int pos) +{ + if (ctx->process_error) { + return NULL; + } + + while (pos >= ctx->tokens_read) { + if (ctx->tokens_read == ctx->tokens_cap) { + ctx->tokens_cap += 1024; + ctx->tokens = realloc(ctx->tokens, + ctx->tokens_cap * sizeof(struct sl_pp_token_info)); + if (!ctx->tokens) { + _error(ctx, "out of memory"); + ctx->process_error = 1; + return NULL; + } + } + if (sl_pp_process_get(ctx->context, &ctx->tokens[ctx->tokens_read])) { + _error(ctx, sl_pp_context_error_message(ctx->context)); + ctx->process_error = 1; + return NULL; + } + switch (ctx->tokens[ctx->tokens_read].token) { + case SL_PP_COMMA: + case SL_PP_SEMICOLON: + case SL_PP_LBRACE: + case SL_PP_RBRACE: + case SL_PP_LPAREN: + case SL_PP_RPAREN: + case SL_PP_LBRACKET: + case SL_PP_RBRACKET: + case SL_PP_DOT: + case SL_PP_INCREMENT: + case SL_PP_ADDASSIGN: + case SL_PP_PLUS: + case SL_PP_DECREMENT: + case SL_PP_SUBASSIGN: + case SL_PP_MINUS: + case SL_PP_BITNOT: + case SL_PP_NOTEQUAL: + case SL_PP_NOT: + case SL_PP_MULASSIGN: + case SL_PP_STAR: + case SL_PP_DIVASSIGN: + case SL_PP_SLASH: + case SL_PP_MODASSIGN: + case SL_PP_MODULO: + case SL_PP_LSHIFTASSIGN: + case SL_PP_LSHIFT: + case SL_PP_LESSEQUAL: + case SL_PP_LESS: + case SL_PP_RSHIFTASSIGN: + case SL_PP_RSHIFT: + case SL_PP_GREATEREQUAL: + case SL_PP_GREATER: + case SL_PP_EQUAL: + case SL_PP_ASSIGN: + case SL_PP_AND: + case SL_PP_BITANDASSIGN: + case SL_PP_BITAND: + case SL_PP_XOR: + case SL_PP_BITXORASSIGN: + case SL_PP_BITXOR: + case SL_PP_OR: + case SL_PP_BITORASSIGN: + case SL_PP_BITOR: + case SL_PP_QUESTION: + case SL_PP_COLON: + case SL_PP_IDENTIFIER: + case SL_PP_UINT: + case SL_PP_FLOAT: + case SL_PP_EOF: + ctx->tokens_read++; + break; + } + } + return &ctx->tokens[pos]; +} + + static int _parse_token(struct parse_context *ctx, enum sl_pp_token token, struct parse_state *ps) { - if (ctx->input[ps->in].token == token) { + const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in); + + if (input && input->token == token) { ps->in++; return 0; } @@ -392,8 +480,9 @@ _parse_id(struct parse_context *ctx, int id, struct parse_state *ps) { - if (ctx->input[ps->in].token == SL_PP_IDENTIFIER && - ctx->input[ps->in].data.identifier == id) { + const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in); + + if (input && input->token == SL_PP_IDENTIFIER && input->data.identifier == id) { ps->in++; return 0; } @@ -405,8 +494,10 @@ static int _parse_identifier(struct parse_context *ctx, struct parse_state *ps) { - if (ctx->input[ps->in].token == SL_PP_IDENTIFIER) { - const char *cstr = sl_pp_context_cstr(ctx->context, ctx->input[ps->in].data.identifier); + const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in); + + if (input && input->token == SL_PP_IDENTIFIER) { + const char *cstr = sl_pp_context_cstr(ctx->context, input->data.identifier); do { _emit(ctx, &ps->out, *cstr); @@ -422,8 +513,10 @@ static int _parse_float(struct parse_context *ctx, struct parse_state *ps) { - if (ctx->input[ps->in].token == SL_PP_FLOAT) { - const char *cstr = sl_pp_context_cstr(ctx->context, ctx->input[ps->in].data._float); + const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in); + + if (input && input->token == SL_PP_FLOAT) { + const char *cstr = sl_pp_context_cstr(ctx->context, input->data._float); _emit(ctx, &ps->out, 1); do { @@ -440,8 +533,10 @@ static int _parse_uint(struct parse_context *ctx, struct parse_state *ps) { - if (ctx->input[ps->in].token == SL_PP_UINT) { - const char *cstr = sl_pp_context_cstr(ctx->context, ctx->input[ps->in].data._uint); + const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in); + + if (input && input->token == SL_PP_UINT) { + const char *cstr = sl_pp_context_cstr(ctx->context, input->data._uint); _emit(ctx, &ps->out, 1); do { @@ -614,13 +709,14 @@ _parse_type_qualifier(struct parse_context *ctx, struct parse_state *ps) { struct parse_state p = *ps; + const struct sl_pp_token_info *input = _fetch_token(ctx, p.in); unsigned int e = _emit(ctx, &p.out, 0); int id; - if (ctx->input[p.in].token != SL_PP_IDENTIFIER) { + if (!input || input->token != SL_PP_IDENTIFIER) { return -1; } - id = ctx->input[p.in].data.identifier; + id = input->data.identifier; if (id == ctx->dict._const) { _update(ctx, e, TYPE_QUALIFIER_CONST); @@ -771,6 +867,7 @@ _parse_type_specifier_nonarray(struct parse_context *ctx, { struct parse_state p = *ps; unsigned int e = _emit(ctx, &p.out, 0); + const struct sl_pp_token_info *input; int id; if (_parse_struct_specifier(ctx, &p) == 0) { @@ -779,10 +876,11 @@ _parse_type_specifier_nonarray(struct parse_context *ctx, return 0; } - if (ctx->input[p.in].token != SL_PP_IDENTIFIER) { + input = _fetch_token(ctx, p.in); + if (!input || input->token != SL_PP_IDENTIFIER) { return -1; } - id = ctx->input[p.in].data.identifier; + id = input->data.identifier; if (id == ctx->dict._void) { _update(ctx, e, TYPE_SPECIFIER_VOID); @@ -1696,13 +1794,14 @@ static int _parse_precision(struct parse_context *ctx, struct parse_state *ps) { + const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in); int id; unsigned int precision; - if (ctx->input[ps->in].token != SL_PP_IDENTIFIER) { + if (!input || input->token != SL_PP_IDENTIFIER) { return -1; } - id = ctx->input[ps->in].data.identifier; + id = input->data.identifier; if (id == ctx->dict.lowp) { precision = PRECISION_LOW; @@ -1724,13 +1823,14 @@ static int _parse_prectype(struct parse_context *ctx, struct parse_state *ps) { + const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in); int id; unsigned int type; - if (ctx->input[ps->in].token != SL_PP_IDENTIFIER) { + if (!input || input->token != SL_PP_IDENTIFIER) { return -1; } - id = ctx->input[ps->in].data.identifier; + id = input->data.identifier; if (id == ctx->dict._int) { type = TYPE_SPECIFIER_INT; @@ -2607,7 +2707,6 @@ _parse_translation_unit(struct parse_context *ctx, int sl_cl_compile(struct sl_pp_context *context, - const struct sl_pp_token_info *input, unsigned int shader_type, unsigned int parsing_builtin, unsigned char **output, @@ -2619,7 +2718,6 @@ sl_cl_compile(struct sl_pp_context *context, struct parse_state ps; ctx.context = context; - ctx.input = input; ADD_NAME_STR(ctx, _void, "void"); ADD_NAME_STR(ctx, _float, "float"); @@ -2699,16 +2797,27 @@ sl_cl_compile(struct sl_pp_context *context, ctx.parsing_builtin = 1; ctx.error[0] = '\0'; + ctx.process_error = 0; + + ctx.tokens_cap = 1024; + ctx.tokens_read = 0; + ctx.tokens = malloc(ctx.tokens_cap * sizeof(struct sl_pp_token_info)); + if (!ctx.tokens) { + strncpy(error, "out of memory", cberror); + return -1; + } ps.in = 0; ps.out = 0; if (_parse_translation_unit(&ctx, &ps)) { strncpy(error, ctx.error, cberror); + free(ctx.tokens); return -1; } *output = ctx.out_buf; *cboutput = ps.out; + free(ctx.tokens); return 0; } diff --git a/src/glsl/cl/sl_cl_parse.h b/src/glsl/cl/sl_cl_parse.h index 23a0d5fee00..dd5791d5901 100644 --- a/src/glsl/cl/sl_cl_parse.h +++ b/src/glsl/cl/sl_cl_parse.h @@ -30,7 +30,6 @@ int sl_cl_compile(struct sl_pp_context *context, - const struct sl_pp_token_info *input, unsigned int shader_type, unsigned int parsing_builtin, unsigned char **output, diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index c1cef41bceb..74a9bdddfdc 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -69,6 +69,8 @@ sl_pp_context_create(const char *input, sl_pp_purify_state_init(&context->pure, input, options); + memset(&context->process_state, 0, sizeof(context->process_state)); + return context; } @@ -80,6 +82,7 @@ sl_pp_context_destroy(struct sl_pp_context *context) sl_pp_macro_free(context->macro); free(context->getc_buf); sl_pp_token_buffer_destroy(&context->tokens); + free(context->process_state.out); free(context); } } diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index 5e1c5630483..3eada380cd1 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -30,6 +30,7 @@ #include "sl_pp_dict.h" #include "sl_pp_macro.h" +#include "sl_pp_process.h" #include "sl_pp_purify.h" #include "sl_pp_token_util.h" @@ -84,6 +85,8 @@ struct sl_pp_context { unsigned int getc_buf_capacity; struct sl_pp_token_buffer tokens; + + struct sl_pp_process_state process_state; }; #endif /* SL_PP_CONTEXT_H */ diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c index e004c9f95b9..808a6a0d4f1 100644 --- a/src/glsl/pp/sl_pp_define.c +++ b/src/glsl/pp/sl_pp_define.c @@ -27,6 +27,7 @@ #include #include +#include "sl_pp_context.h" #include "sl_pp_process.h" #include "sl_pp_public.h" diff --git a/src/glsl/pp/sl_pp_error.c b/src/glsl/pp/sl_pp_error.c index a9eeff98ba5..b628e37ce83 100644 --- a/src/glsl/pp/sl_pp_error.c +++ b/src/glsl/pp/sl_pp_error.c @@ -27,6 +27,7 @@ #include #include +#include "sl_pp_context.h" #include "sl_pp_process.h" #include "sl_pp_public.h" diff --git a/src/glsl/pp/sl_pp_extension.c b/src/glsl/pp/sl_pp_extension.c index 67b24404d4d..8af5731e840 100644 --- a/src/glsl/pp/sl_pp_extension.c +++ b/src/glsl/pp/sl_pp_extension.c @@ -27,6 +27,7 @@ #include #include +#include "sl_pp_context.h" #include "sl_pp_process.h" #include "sl_pp_public.h" diff --git a/src/glsl/pp/sl_pp_line.c b/src/glsl/pp/sl_pp_line.c index 87987fc2baf..6f7e9eb562c 100644 --- a/src/glsl/pp/sl_pp_line.c +++ b/src/glsl/pp/sl_pp_line.c @@ -27,6 +27,7 @@ #include #include +#include "sl_pp_context.h" #include "sl_pp_public.h" #include "sl_pp_process.h" diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index c98ab6559a6..9f520b8fc53 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -28,6 +28,7 @@ #include #include #include +#include "sl_pp_context.h" #include "sl_pp_public.h" #include "sl_pp_macro.h" #include "sl_pp_process.h" diff --git a/src/glsl/pp/sl_pp_pragma.c b/src/glsl/pp/sl_pp_pragma.c index 489eb17b8eb..caf4c63f657 100644 --- a/src/glsl/pp/sl_pp_pragma.c +++ b/src/glsl/pp/sl_pp_pragma.c @@ -27,6 +27,7 @@ #include #include +#include "sl_pp_context.h" #include "sl_pp_process.h" diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index 6dcd0ab4015..563ea948e70 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -27,6 +27,7 @@ #include #include +#include "sl_pp_context.h" #include "sl_pp_process.h" #include "sl_pp_public.h" @@ -58,34 +59,47 @@ sl_pp_process_out(struct sl_pp_process_state *state, } int -sl_pp_process(struct sl_pp_context *context, - struct sl_pp_token_info **output) +sl_pp_process_get(struct sl_pp_context *context, + struct sl_pp_token_info *output) { - struct sl_pp_process_state state; - int found_eof = 0; - - memset(&state, 0, sizeof(state)); - - if (context->line > 1) { - struct sl_pp_token_info ti; - - ti.token = SL_PP_LINE; - ti.data.line.lineno = context->line - 1; - ti.data.line.fileno = context->file; - if (sl_pp_process_out(&state, &ti)) { - strcpy(context->error_msg, "out of memory"); - return -1; - } + if (!context->process_state.out) { + if (context->line > 1) { + struct sl_pp_token_info ti; + + ti.token = SL_PP_LINE; + ti.data.line.lineno = context->line - 1; + ti.data.line.fileno = context->file; + if (sl_pp_process_out(&context->process_state, &ti)) { + strcpy(context->error_msg, "out of memory"); + return -1; + } - ti.token = SL_PP_NEWLINE; - if (sl_pp_process_out(&state, &ti)) { - strcpy(context->error_msg, "out of memory"); - return -1; + ti.token = SL_PP_NEWLINE; + if (sl_pp_process_out(&context->process_state, &ti)) { + strcpy(context->error_msg, "out of memory"); + return -1; + } } } - while (!found_eof) { + for (;;) { struct sl_pp_token_info input; + int found_eof = 0; + + if (context->process_state.out_len) { + *output = context->process_state.out[0]; + + if (context->process_state.out_len > 1) { + unsigned int i; + + for (i = 1; i < context->process_state.out_len; i++) { + context->process_state.out[i - 1] = context->process_state.out[i]; + } + } + context->process_state.out_len--; + + return 0; + } if (sl_pp_token_buffer_skip_white(&context->tokens, &input)) { return -1; @@ -101,7 +115,7 @@ sl_pp_process(struct sl_pp_context *context, int found_eol = 0; struct sl_pp_token_info endof; struct sl_pp_token_peek peek; - int result; + int result = 0; /* Directive name. */ name = input.data.identifier; @@ -166,17 +180,17 @@ sl_pp_process(struct sl_pp_context *context, sl_pp_process_error(context, peek.tokens, 0, peek.size - 1); result = -1; } else if (name == context->dict.extension) { - result = sl_pp_process_extension(context, peek.tokens, 0, peek.size - 1, &state); + result = sl_pp_process_extension(context, peek.tokens, 0, peek.size - 1, &context->process_state); } else if (name == context->dict.line) { struct sl_pp_token_buffer buffer; result = sl_pp_token_peek_to_buffer(&peek, &buffer); if (result == 0) { - result = sl_pp_process_line(context, &buffer, &state); + result = sl_pp_process_line(context, &buffer, &context->process_state); sl_pp_token_buffer_destroy(&buffer); } } else if (name == context->dict.pragma) { - result = sl_pp_process_pragma(context, peek.tokens, 0, peek.size - 1, &state); + result = sl_pp_process_pragma(context, peek.tokens, 0, peek.size - 1, &context->process_state); } else if (name == context->dict.undef) { result = sl_pp_process_undef(context, peek.tokens, 0, peek.size - 1); } else { @@ -192,7 +206,7 @@ sl_pp_process(struct sl_pp_context *context, return result; } - if (sl_pp_process_out(&state, &endof)) { + if (sl_pp_process_out(&context->process_state, &endof)) { strcpy(context->error_msg, "out of memory"); return -1; } @@ -202,7 +216,7 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_NEWLINE: /* Empty directive. */ - if (sl_pp_process_out(&state, &input)) { + if (sl_pp_process_out(&context->process_state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } @@ -211,7 +225,7 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_EOF: /* Empty directive. */ - if (sl_pp_process_out(&state, &input)) { + if (sl_pp_process_out(&context->process_state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } @@ -239,7 +253,7 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_NEWLINE: /* Preserve newline just for the sake of line numbering. */ - if (sl_pp_process_out(&state, &input)) { + if (sl_pp_process_out(&context->process_state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } @@ -248,7 +262,7 @@ sl_pp_process(struct sl_pp_context *context, break; case SL_PP_EOF: - if (sl_pp_process_out(&state, &input)) { + if (sl_pp_process_out(&context->process_state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } @@ -258,7 +272,7 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_IDENTIFIER: sl_pp_token_buffer_unget(&context->tokens, &input); - if (sl_pp_macro_expand(context, &context->tokens, NULL, &state, + if (sl_pp_macro_expand(context, &context->tokens, NULL, &context->process_state, context->if_value ? sl_pp_macro_expand_normal : sl_pp_macro_expand_mute)) { return -1; } @@ -266,7 +280,7 @@ sl_pp_process(struct sl_pp_context *context, default: if (context->if_value) { - if (sl_pp_process_out(&state, &input)) { + if (sl_pp_process_out(&context->process_state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } @@ -274,13 +288,37 @@ sl_pp_process(struct sl_pp_context *context, } } } - } - if (context->if_ptr != SL_PP_MAX_IF_NESTING) { - strcpy(context->error_msg, "expected `#endif' directive"); - return -1; + if (found_eof) { + if (context->if_ptr != SL_PP_MAX_IF_NESTING) { + strcpy(context->error_msg, "expected `#endif' directive"); + return -1; + } + } } +} - *output = state.out; - return 0; +int +sl_pp_process(struct sl_pp_context *context, + struct sl_pp_token_info **output) +{ + struct sl_pp_process_state state; + + memset(&state, 0, sizeof(state)); + for (;;) { + struct sl_pp_token_info input; + + if (sl_pp_process_get(context, &input)) { + free(state.out); + return -1; + } + if (sl_pp_process_out(&state, &input)) { + free(state.out); + return -1; + } + if (input.token == SL_PP_EOF) { + *output = state.out; + return 0; + } + } } diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h index 31defd911a3..fe6ff0d4648 100644 --- a/src/glsl/pp/sl_pp_process.h +++ b/src/glsl/pp/sl_pp_process.h @@ -28,11 +28,12 @@ #ifndef SL_PP_PROCESS_H #define SL_PP_PROCESS_H -#include "sl_pp_context.h" #include "sl_pp_macro.h" #include "sl_pp_token.h" +struct sl_pp_context; + struct sl_pp_process_state { struct sl_pp_token_info *out; unsigned int out_len; diff --git a/src/glsl/pp/sl_pp_public.h b/src/glsl/pp/sl_pp_public.h index 309a70c07ff..12528d6f8d1 100644 --- a/src/glsl/pp/sl_pp_public.h +++ b/src/glsl/pp/sl_pp_public.h @@ -73,6 +73,10 @@ int sl_pp_version(struct sl_pp_context *context, unsigned int *version); +int +sl_pp_process_get(struct sl_pp_context *context, + struct sl_pp_token_info *output); + int sl_pp_process(struct sl_pp_context *context, struct sl_pp_token_info **output); -- cgit v1.2.3 From 55c43ee3158e5e83dcf51a7d6eaa35d4314c0833 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 21 Dec 2009 09:10:21 +1000 Subject: glsl: make stack compile. it would be nice if this stuff would be test built on mesa's primary platform with mesa's primary build system. Signed-off-by: Dave Airlie --- src/glsl/pp/sl_pp_macro.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_macro.h b/src/glsl/pp/sl_pp_macro.h index 2967baf3375..1d210681091 100644 --- a/src/glsl/pp/sl_pp_macro.h +++ b/src/glsl/pp/sl_pp_macro.h @@ -33,6 +33,7 @@ struct sl_pp_context; struct sl_pp_process_state; +struct sl_pp_token_buffer; struct sl_pp_macro_formal_arg { int name; -- cgit v1.2.3 From cdd25ab8cfa407d85f9efd78c97aa575aee94d28 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 23 Dec 2009 15:56:31 +0000 Subject: glsl/pp: quieten compiler about missing case statements --- src/glsl/pp/sl_pp_process.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/glsl/pp') diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index 563ea948e70..f89986dd8ef 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -146,6 +146,9 @@ sl_pp_process_get(struct sl_pp_context *context, found_eof = 1; found_eol = 1; break; + + default: + break; } } -- cgit v1.2.3 From b2a615e3cdd0b48f985a9405cd90bdb3e841eeef Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 23 Dec 2009 15:57:06 +0000 Subject: glsl/pp: move static functions out of header file --- src/glsl/SConscript | 1 + src/glsl/pp/Makefile | 1 + src/glsl/pp/sl_pp_token_util.c | 182 +++++++++++++++++++++++++++++++++++++++++ src/glsl/pp/sl_pp_token_util.h | 170 +++++++------------------------------- 4 files changed, 215 insertions(+), 139 deletions(-) create mode 100644 src/glsl/pp/sl_pp_token_util.c (limited to 'src/glsl/pp') diff --git a/src/glsl/SConscript b/src/glsl/SConscript index 6f1f81b199a..101487df910 100644 --- a/src/glsl/SConscript +++ b/src/glsl/SConscript @@ -18,6 +18,7 @@ sources = [ 'pp/sl_pp_process.c', 'pp/sl_pp_purify.c', 'pp/sl_pp_token.c', + 'pp/sl_pp_token_util.c', 'pp/sl_pp_version.c', 'cl/sl_cl_parse.c', ] diff --git a/src/glsl/pp/Makefile b/src/glsl/pp/Makefile index 819079f6258..fda1c4202ba 100644 --- a/src/glsl/pp/Makefile +++ b/src/glsl/pp/Makefile @@ -20,6 +20,7 @@ C_SOURCES = \ sl_pp_process.c \ sl_pp_purify.c \ sl_pp_token.c \ + sl_pp_token_util.c \ sl_pp_version.c include ../Makefile.template diff --git a/src/glsl/pp/sl_pp_token_util.c b/src/glsl/pp/sl_pp_token_util.c new file mode 100644 index 00000000000..c85263d9a11 --- /dev/null +++ b/src/glsl/pp/sl_pp_token_util.c @@ -0,0 +1,182 @@ +/************************************************************************** + * + * 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_token_util.h" + + +int +sl_pp_token_buffer_init(struct sl_pp_token_buffer *buffer, + struct sl_pp_context *context) +{ + buffer->context = context; + buffer->size = 0; + buffer->capacity = 64; + buffer->tokens = malloc(buffer->capacity * sizeof(struct sl_pp_token_info)); + if (!buffer->tokens) { + return -1; + } + return 0; +} + +void +sl_pp_token_buffer_destroy(struct sl_pp_token_buffer *buffer) +{ + free(buffer->tokens); +} + +int +sl_pp_token_buffer_get(struct sl_pp_token_buffer *buffer, + struct sl_pp_token_info *out) +{ + /* Pop from stack first if not empty. */ + if (buffer->size) { + *out = buffer->tokens[--buffer->size]; + return 0; + } + + assert(buffer->context); + return sl_pp_token_get(buffer->context, out); +} + +void +sl_pp_token_buffer_unget(struct sl_pp_token_buffer *buffer, + const struct sl_pp_token_info *in) +{ + /* Resize if needed. */ + if (buffer->size == buffer->capacity) { + buffer->capacity += 64; + buffer->tokens = realloc(buffer->tokens, + buffer->capacity * sizeof(struct sl_pp_token_info)); + assert(buffer->tokens); + } + + /* Push token on stack. */ + buffer->tokens[buffer->size++] = *in; +} + +int +sl_pp_token_buffer_skip_white(struct sl_pp_token_buffer *buffer, + struct sl_pp_token_info *out) +{ + if (sl_pp_token_buffer_get(buffer, out)) { + return -1; + } + + while (out->token == SL_PP_WHITESPACE) { + if (sl_pp_token_buffer_get(buffer, out)) { + return -1; + } + } + + return 0; +} + + + +int +sl_pp_token_peek_init(struct sl_pp_token_peek *peek, + struct sl_pp_token_buffer *buffer) +{ + peek->buffer = buffer; + peek->size = 0; + peek->capacity = 64; + peek->tokens = malloc(peek->capacity * sizeof(struct sl_pp_token_info)); + if (!peek->tokens) { + return -1; + } + return 0; +} + +void +sl_pp_token_peek_destroy(struct sl_pp_token_peek *peek) +{ + /* Abort. */ + while (peek->size) { + sl_pp_token_buffer_unget(peek->buffer, &peek->tokens[--peek->size]); + } + free(peek->tokens); +} + +int +sl_pp_token_peek_get(struct sl_pp_token_peek *peek, + struct sl_pp_token_info *out) +{ + /* Get token from buffer. */ + if (sl_pp_token_buffer_get(peek->buffer, out)) { + return -1; + } + + /* Save it. */ + if (peek->size == peek->capacity) { + peek->capacity += 64; + peek->tokens = realloc(peek->tokens, + peek->capacity * sizeof(struct sl_pp_token_info)); + assert(peek->tokens); + } + peek->tokens[peek->size++] = *out; + return 0; +} + +void +sl_pp_token_peek_commit(struct sl_pp_token_peek *peek) +{ + peek->size = 0; +} + +int +sl_pp_token_peek_to_buffer(const struct sl_pp_token_peek *peek, + struct sl_pp_token_buffer *buffer) +{ + unsigned int i; + + if (sl_pp_token_buffer_init(buffer, NULL)) { + return -1; + } + for (i = peek->size; i > 0; i--) { + sl_pp_token_buffer_unget(buffer, &peek->tokens[i - 1]); + } + return 0; +} + +int +sl_pp_token_peek_skip_white(struct sl_pp_token_peek *peek, + struct sl_pp_token_info *out) +{ + if (sl_pp_token_peek_get(peek, out)) { + return -1; + } + + while (out->token == SL_PP_WHITESPACE) { + if (sl_pp_token_peek_get(peek, out)) { + return -1; + } + } + + return 0; +} diff --git a/src/glsl/pp/sl_pp_token_util.h b/src/glsl/pp/sl_pp_token_util.h index 1685d243a5b..2a668ad0a84 100644 --- a/src/glsl/pp/sl_pp_token_util.h +++ b/src/glsl/pp/sl_pp_token_util.h @@ -46,72 +46,24 @@ struct sl_pp_token_buffer { struct sl_pp_token_info *tokens; }; -static int +int sl_pp_token_buffer_init(struct sl_pp_token_buffer *buffer, - struct sl_pp_context *context) -{ - buffer->context = context; - buffer->size = 0; - buffer->capacity = 64; - buffer->tokens = malloc(buffer->capacity * sizeof(struct sl_pp_token_info)); - if (!buffer->tokens) { - return -1; - } - return 0; -} - -static void -sl_pp_token_buffer_destroy(struct sl_pp_token_buffer *buffer) -{ - free(buffer->tokens); -} - -static int + struct sl_pp_context *context); + +void +sl_pp_token_buffer_destroy(struct sl_pp_token_buffer *buffer); + +int sl_pp_token_buffer_get(struct sl_pp_token_buffer *buffer, - struct sl_pp_token_info *out) -{ - /* Pop from stack first if not empty. */ - if (buffer->size) { - *out = buffer->tokens[--buffer->size]; - return 0; - } - - assert(buffer->context); - return sl_pp_token_get(buffer->context, out); -} - -static void -sl_pp_token_buffer_unget(struct sl_pp_token_buffer *buffer, - const struct sl_pp_token_info *in) -{ - /* Resize if needed. */ - if (buffer->size == buffer->capacity) { - buffer->capacity += 64; - buffer->tokens = realloc(buffer->tokens, - buffer->capacity * sizeof(struct sl_pp_token_info)); - assert(buffer->tokens); - } - - /* Push token on stack. */ - buffer->tokens[buffer->size++] = *in; -} - -static int -sl_pp_token_buffer_skip_white(struct sl_pp_token_buffer *buffer, - struct sl_pp_token_info *out) -{ - if (sl_pp_token_buffer_get(buffer, out)) { - return -1; - } + struct sl_pp_token_info *out); - while (out->token == SL_PP_WHITESPACE) { - if (sl_pp_token_buffer_get(buffer, out)) { - return -1; - } - } +void +sl_pp_token_buffer_unget(struct sl_pp_token_buffer *buffer, + const struct sl_pp_token_info *in); - return 0; -} +int +sl_pp_token_buffer_skip_white(struct sl_pp_token_buffer *buffer, + struct sl_pp_token_info *out); /* @@ -126,86 +78,26 @@ struct sl_pp_token_peek { struct sl_pp_token_info *tokens; }; -static int +int sl_pp_token_peek_init(struct sl_pp_token_peek *peek, - struct sl_pp_token_buffer *buffer) -{ - peek->buffer = buffer; - peek->size = 0; - peek->capacity = 64; - peek->tokens = malloc(peek->capacity * sizeof(struct sl_pp_token_info)); - if (!peek->tokens) { - return -1; - } - return 0; -} - -static void -sl_pp_token_peek_destroy(struct sl_pp_token_peek *peek) -{ - /* Abort. */ - while (peek->size) { - sl_pp_token_buffer_unget(peek->buffer, &peek->tokens[--peek->size]); - } - free(peek->tokens); -} - -static int + struct sl_pp_token_buffer *buffer); + +void +sl_pp_token_peek_destroy(struct sl_pp_token_peek *peek); + +int sl_pp_token_peek_get(struct sl_pp_token_peek *peek, - struct sl_pp_token_info *out) -{ - /* Get token from buffer. */ - if (sl_pp_token_buffer_get(peek->buffer, out)) { - return -1; - } - - /* Save it. */ - if (peek->size == peek->capacity) { - peek->capacity += 64; - peek->tokens = realloc(peek->tokens, - peek->capacity * sizeof(struct sl_pp_token_info)); - assert(peek->tokens); - } - peek->tokens[peek->size++] = *out; - return 0; -} - -static void -sl_pp_token_peek_commit(struct sl_pp_token_peek *peek) -{ - peek->size = 0; -} - -static int + struct sl_pp_token_info *out); + +void +sl_pp_token_peek_commit(struct sl_pp_token_peek *peek); + +int sl_pp_token_peek_to_buffer(const struct sl_pp_token_peek *peek, - struct sl_pp_token_buffer *buffer) -{ - unsigned int i; - - if (sl_pp_token_buffer_init(buffer, NULL)) { - return -1; - } - for (i = peek->size; i > 0; i--) { - sl_pp_token_buffer_unget(buffer, &peek->tokens[i - 1]); - } - return 0; -} - -static int + struct sl_pp_token_buffer *buffer); + +int sl_pp_token_peek_skip_white(struct sl_pp_token_peek *peek, - struct sl_pp_token_info *out) -{ - if (sl_pp_token_peek_get(peek, out)) { - return -1; - } - - while (out->token == SL_PP_WHITESPACE) { - if (sl_pp_token_peek_get(peek, out)) { - return -1; - } - } - - return 0; -} + struct sl_pp_token_info *out); #endif /* SL_PP_TOKEN_UTIL_H */ -- cgit v1.2.3