summaryrefslogtreecommitdiffstats
path: root/src/glsl
diff options
context:
space:
mode:
Diffstat (limited to 'src/glsl')
-rw-r--r--src/glsl/pp/sl_pp_if.c82
1 files changed, 79 insertions, 3 deletions
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;