mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-03-11 17:50:32 +01:00
glsl/pp: Fix handling of if/elif/else cases.
Once if/elif evalutes to true, all subsequent conditions are always false.
This commit is contained in:
parent
b90f265fbf
commit
ee67167358
2 changed files with 28 additions and 11 deletions
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue