From: Michal Krol Date: Mon, 15 Feb 2010 20:33:22 +0000 (+0100) Subject: glsl/pp: Fix handling of if/elif/else cases. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ee67167358e91e9ffde8aa9e5b96e5def4c16904;p=mesa.git glsl/pp: Fix handling of if/elif/else cases. Once if/elif evalutes to true, all subsequent conditions are always false. --- diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index 983a09c02af..b5419bc056b 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -53,6 +53,15 @@ struct sl_pp_predefined { int value; }; +union sl_pp_if_state { + struct { + unsigned int condition:1; + unsigned int went_thru_else:1; + unsigned int had_true_cond:1; + } u; + unsigned int value; +}; + struct sl_pp_context { char *cstr_pool; unsigned int cstr_pool_max; @@ -68,7 +77,7 @@ struct sl_pp_context { struct sl_pp_predefined predefined[SL_PP_MAX_PREDEFINED]; unsigned int num_predefined; - unsigned int if_stack[SL_PP_MAX_IF_NESTING]; + union sl_pp_if_state if_stack[SL_PP_MAX_IF_NESTING]; unsigned int if_ptr; unsigned int if_value; diff --git a/src/glsl/pp/sl_pp_if.c b/src/glsl/pp/sl_pp_if.c index 272c3a23cce..e233999ca8d 100644 --- a/src/glsl/pp/sl_pp_if.c +++ b/src/glsl/pp/sl_pp_if.c @@ -108,7 +108,7 @@ _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)) { + if (!context->if_stack[i].u.condition) { return 0; } } @@ -182,7 +182,8 @@ _parse_if(struct sl_pp_context *context, free(state.out); context->if_ptr--; - context->if_stack[context->if_ptr] = result ? 1 : 0; + context->if_stack[context->if_ptr].value = 0; + context->if_stack[context->if_ptr].u.condition = result ? 1 : 0; context->if_value = _evaluate_if_stack(context); return 0; @@ -191,19 +192,24 @@ _parse_if(struct sl_pp_context *context, static int _parse_else(struct sl_pp_context *context) { + union sl_pp_if_state *state = &context->if_stack[context->if_ptr]; + if (context->if_ptr == SL_PP_MAX_IF_NESTING) { 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) { + if (state->u.went_thru_else) { strcpy(context->error_msg, "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; + /* Once we had a true condition, the subsequent #elifs should always be false. */ + state->u.had_true_cond |= state->u.condition; + + /* Update current condition value and mark that we are in the #else block. */ + state->u.condition = !(state->u.had_true_cond | state->u.condition); + state->u.went_thru_else = 1; context->if_value = _evaluate_if_stack(context); return 0; @@ -233,7 +239,8 @@ sl_pp_process_ifdef(struct sl_pp_context *context, switch (input[i].token) { case SL_PP_IDENTIFIER: context->if_ptr--; - context->if_stack[context->if_ptr] = _macro_is_defined(context, input[i].data.identifier); + context->if_stack[context->if_ptr].value = 0; + context->if_stack[context->if_ptr].u.condition = _macro_is_defined(context, input[i].data.identifier); context->if_value = _evaluate_if_stack(context); return 0; @@ -267,7 +274,8 @@ sl_pp_process_ifndef(struct sl_pp_context *context, switch (input[i].token) { case SL_PP_IDENTIFIER: context->if_ptr--; - context->if_stack[context->if_ptr] = !_macro_is_defined(context, input[i].data.identifier); + context->if_stack[context->if_ptr].value = 0; + context->if_stack[context->if_ptr].u.condition = !_macro_is_defined(context, input[i].data.identifier); context->if_value = _evaluate_if_stack(context); return 0; @@ -292,7 +300,7 @@ sl_pp_process_elif(struct sl_pp_context *context, return -1; } - if (context->if_stack[context->if_ptr] & 1) { + if (context->if_stack[context->if_ptr].u.condition) { context->if_ptr++; if (_parse_if(context, buffer)) { return -1; @@ -300,7 +308,7 @@ sl_pp_process_elif(struct sl_pp_context *context, } /* We are still in the #if block. */ - context->if_stack[context->if_ptr] = context->if_stack[context->if_ptr] & ~2; + context->if_stack[context->if_ptr].u.went_thru_else = 0; return 0; }