]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Boolean.c
Partially make EdkModulePkg pass intel IPF compiler with /W4 /WX switched on.
[mirror_edk2.git] / EdkModulePkg / Universal / UserInterface / SetupBrowser / Dxe / Boolean.c
CommitLineData
878ddf1f 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 Boolean.c\r
15\r
16Abstract:\r
17\r
18 This routine will evaluate the IFR inconsistency data to determine if\r
19 something is a valid entry for a particular expression\r
20\r
21--*/\r
22\r
23#include "Setup.h"\r
24#include "Ui.h"\r
25\r
26//\r
27// Global stack used to evaluate boolean expresions\r
28//\r
29BOOLEAN *mBooleanEvaluationStack = (BOOLEAN) 0;\r
30BOOLEAN *mBooleanEvaluationStackEnd = (BOOLEAN) 0;\r
31\r
32STATIC\r
33VOID\r
34GrowBooleanStack (\r
35 IN OUT BOOLEAN **Stack,\r
36 IN UINTN StackSizeInBoolean\r
37 )\r
38/*++\r
39\r
40Routine Description:\r
41\r
42 Grow size of the boolean stack\r
43\r
44Arguments:\r
45\r
46 Stack - Old stack on the way in and new stack on the way out\r
47\r
48 StackSizeInBoolean - New size of the stack\r
49\r
50Returns:\r
51\r
52 NONE \r
53\r
54--*/\r
55{\r
56 BOOLEAN *NewStack;\r
57\r
58 NewStack = AllocatePool (StackSizeInBoolean * sizeof (BOOLEAN));\r
59 ASSERT (NewStack != NULL);\r
60\r
61 if (*Stack != NULL) {\r
62 //\r
63 // Copy to Old Stack to the New Stack\r
64 //\r
65 CopyMem (\r
66 NewStack,\r
67 mBooleanEvaluationStack,\r
68 (mBooleanEvaluationStackEnd - mBooleanEvaluationStack) * sizeof (BOOLEAN)\r
69 );\r
70\r
71 //\r
72 // Make the Stack pointer point to the old data in the new stack\r
73 //\r
74 *Stack = NewStack + (*Stack - mBooleanEvaluationStack);\r
75\r
76 //\r
77 // Free The Old Stack\r
78 //\r
79 gBS->FreePool (mBooleanEvaluationStack);\r
80 }\r
81\r
82 mBooleanEvaluationStack = NewStack;\r
83 mBooleanEvaluationStackEnd = NewStack + StackSizeInBoolean;\r
84}\r
85\r
1cc8ee78 86STATIC\r
878ddf1f 87VOID\r
88InitializeBooleanEvaluator (\r
89 VOID\r
90 )\r
91/*++\r
92\r
93Routine Description:\r
94\r
95 Allocate a global stack for boolean processing.\r
96\r
97Arguments:\r
98\r
99 NONE \r
100\r
101Returns:\r
102\r
103 NONE \r
104\r
105--*/\r
106{\r
107 BOOLEAN *NullStack;\r
108\r
109 NullStack = NULL;\r
110 GrowBooleanStack (&NullStack, 0x1000);\r
111}\r
112\r
113STATIC\r
114VOID\r
115PushBool (\r
116 IN OUT BOOLEAN **Stack,\r
117 IN BOOLEAN BoolResult\r
118 )\r
119/*++\r
120\r
121Routine Description:\r
122\r
123 Push an element onto the Boolean Stack\r
124\r
125Arguments:\r
126\r
127 Stack - Current stack location.\r
128 BoolResult - BOOLEAN to push.\r
129\r
130Returns:\r
131\r
132 None.\r
133\r
134--*/\r
135{\r
136 CopyMem (*Stack, &BoolResult, sizeof (BOOLEAN));\r
137 *Stack += 1;\r
138\r
139 if (*Stack >= mBooleanEvaluationStackEnd) {\r
140 //\r
141 // If we run out of stack space make a new one that is 2X as big. Copy\r
142 // the old data into the new stack and update Stack to point to the old\r
143 // data in the new stack.\r
144 //\r
145 GrowBooleanStack (\r
146 Stack,\r
147 (mBooleanEvaluationStackEnd - mBooleanEvaluationStack) * sizeof (BOOLEAN) * 2\r
148 );\r
149 }\r
150}\r
151\r
152STATIC\r
153BOOLEAN\r
154PopBool (\r
155 IN OUT BOOLEAN **Stack\r
156 )\r
157/*++\r
158\r
159Routine Description:\r
160\r
161 Pop an element from the Boolean stack.\r
162\r
163Arguments:\r
164\r
165 Stack - Current stack location\r
166\r
167Returns:\r
168\r
169 Top of the BOOLEAN stack.\r
170\r
171--*/\r
172{\r
173 BOOLEAN ReturnValue;\r
174\r
175 *Stack -= 1;\r
176 CopyMem (&ReturnValue, *Stack, sizeof (BOOLEAN));\r
177 return ReturnValue;\r
178}\r
179\r
1cc8ee78 180STATIC\r
878ddf1f 181EFI_STATUS\r
182GrowBooleanExpression (\r
183 IN EFI_INCONSISTENCY_DATA *InconsistentTags,\r
184 OUT VOID **BooleanExpression,\r
185 IN OUT UINTN *BooleanExpressionLength\r
186 )\r
187{\r
188 UINT8 *NewExpression;\r
189\r
190 NewExpression = AllocatePool (*BooleanExpressionLength + sizeof (EFI_INCONSISTENCY_DATA));\r
191 ASSERT (NewExpression != NULL);\r
192\r
193 if (*BooleanExpression != NULL) {\r
194 //\r
195 // Copy Old buffer to the New buffer\r
196 //\r
197 CopyMem (NewExpression, *BooleanExpression, *BooleanExpressionLength);\r
198\r
199 CopyMem (&NewExpression[*BooleanExpressionLength], InconsistentTags, sizeof (EFI_INCONSISTENCY_DATA));\r
200\r
201 //\r
202 // Free The Old buffer\r
203 //\r
204 gBS->FreePool (*BooleanExpression);\r
205 } else {\r
206 //\r
207 // Copy data into new buffer\r
208 //\r
209 CopyMem (NewExpression, InconsistentTags, sizeof (EFI_INCONSISTENCY_DATA));\r
210 }\r
211\r
212 *BooleanExpressionLength = *BooleanExpressionLength + sizeof (EFI_INCONSISTENCY_DATA);\r
213 *BooleanExpression = (VOID *) NewExpression;\r
214 return EFI_SUCCESS;\r
215}\r
216\r
1cc8ee78 217STATIC\r
878ddf1f 218VOID\r
219CreateBooleanExpression (\r
220 IN EFI_FILE_FORM_TAGS *FileFormTags,\r
221 IN UINT16 Value,\r
222 IN UINT16 Id,\r
223 IN BOOLEAN Complex,\r
224 OUT VOID **BooleanExpression,\r
225 OUT UINTN *BooleanExpressionLength\r
226 )\r
227/*++\r
228\r
229Routine Description:\r
230\r
231Arguments:\r
232\r
233Returns:\r
234\r
235--*/\r
236{\r
237 UINTN Count;\r
238 EFI_INCONSISTENCY_DATA *InconsistentTags;\r
239 EFI_INCONSISTENCY_DATA FakeInconsistentTags;\r
240\r
241 InconsistentTags = FileFormTags->InconsistentTags;\r
242\r
243 //\r
244 // Did we run into a question that contains the Id we are looking for?\r
245 //\r
246 for (Count = 0; InconsistentTags->Operand != 0xFF; Count++) {\r
247\r
248 //\r
249 // Reserve INVALID_OFFSET_VALUE - 1 for TURE and FALSE, because we need to treat them as well\r
250 // as ideqid etc. but they have no coresponding id, so we reserve this value.\r
251 //\r
252 if (InconsistentTags->QuestionId1 == Id ||\r
253 InconsistentTags->QuestionId1 == INVALID_OFFSET_VALUE - 1) {\r
254 //\r
255 // If !Complex - means evaluate a single if/endif expression\r
256 //\r
257 if (!Complex) {\r
258 //\r
259 // If the ConsistencyId does not match the expression we are looking for\r
260 // skip to the next consistency database entry\r
261 //\r
262 if (InconsistentTags->ConsistencyId != Value) {\r
263 goto NextEntry;\r
264 }\r
265 }\r
266 //\r
267 // We need to rewind to the beginning of the Inconsistent expression\r
268 //\r
269 for (;\r
270 (InconsistentTags->Operand != EFI_IFR_INCONSISTENT_IF_OP) &&\r
271 (InconsistentTags->Operand != EFI_IFR_GRAYOUT_IF_OP) &&\r
272 (InconsistentTags->Operand != EFI_IFR_SUPPRESS_IF_OP);\r
273 ) {\r
274 InconsistentTags = InconsistentTags->Previous;\r
275 }\r
276 //\r
277 // Store the consistency check expression, ensure the next for loop starts at the op-code afterwards\r
278 //\r
279 GrowBooleanExpression (InconsistentTags, BooleanExpression, BooleanExpressionLength);\r
280 InconsistentTags = InconsistentTags->Next;\r
281\r
282 //\r
283 // Keep growing until we hit the End expression op-code or we hit the beginning of another\r
284 // consistency check like grayout/suppress\r
285 //\r
286 for (;\r
287 InconsistentTags->Operand != EFI_IFR_END_IF_OP &&\r
288 InconsistentTags->Operand != EFI_IFR_GRAYOUT_IF_OP &&\r
289 InconsistentTags->Operand != EFI_IFR_SUPPRESS_IF_OP;\r
290 ) {\r
291 GrowBooleanExpression (InconsistentTags, BooleanExpression, BooleanExpressionLength);\r
292 InconsistentTags = InconsistentTags->Next;\r
293 }\r
294 //\r
295 // Store the EndExpression Op-code\r
296 //\r
297 GrowBooleanExpression (InconsistentTags, BooleanExpression, BooleanExpressionLength);\r
298 }\r
299\r
300NextEntry:\r
301 if (InconsistentTags->Next != NULL) {\r
302 //\r
303 // Skip to next entry\r
304 //\r
305 InconsistentTags = InconsistentTags->Next;\r
306 }\r
307 }\r
308\r
309 FakeInconsistentTags.Operand = 0;\r
310\r
311 //\r
312 // Add one last expression which will signify we have definitely hit the end\r
313 //\r
314 GrowBooleanExpression (&FakeInconsistentTags, BooleanExpression, BooleanExpressionLength);\r
315}\r
316\r
1cc8ee78 317STATIC\r
878ddf1f 318EFI_STATUS\r
319BooleanVariableWorker (\r
320 IN CHAR16 *VariableName,\r
321 IN EFI_VARIABLE_DEFINITION *VariableDefinition,\r
322 IN BOOLEAN *StackPtr,\r
323 IN OUT UINTN *SizeOfVariable,\r
324 IN OUT VOID **VariableData\r
325 )\r
326/*++\r
327\r
328Routine Description:\r
329\r
330\r
331Arguments:\r
332\r
333Returns:\r
334\r
335--*/\r
336{\r
337 EFI_STATUS Status;\r
338\r
339 Status = gRT->GetVariable (\r
340 VariableName,\r
341 &VariableDefinition->Guid,\r
342 NULL,\r
343 SizeOfVariable,\r
344 *VariableData\r
345 );\r
346\r
347 if (EFI_ERROR (Status)) {\r
348\r
349 if (Status == EFI_BUFFER_TOO_SMALL) {\r
350 *VariableData = AllocatePool (*SizeOfVariable);\r
351 ASSERT (*VariableData != NULL);\r
352\r
353 Status = gRT->GetVariable (\r
354 VariableName,\r
355 &VariableDefinition->Guid,\r
356 NULL,\r
357 SizeOfVariable,\r
358 *VariableData\r
359 );\r
360 }\r
361\r
362 if (Status == EFI_NOT_FOUND) {\r
363 //\r
364 // This is a serious flaw, we must have some standard result if a variable\r
365 // is not found. Our default behavior must either be return a TRUE or FALSE\r
366 // since there is nothing else we can really do. Therefore, my crystal ball\r
367 // says I will return a FALSE\r
368 //\r
369 PushBool (&StackPtr, FALSE);\r
370 }\r
371 }\r
372\r
373 return Status;\r
374}\r
375\r
1cc8ee78 376STATIC\r
878ddf1f 377UINT8\r
378PredicateIfrType (\r
379 IN EFI_INCONSISTENCY_DATA *Iterator\r
380 )\r
381/*++\r
382\r
383Routine Description:\r
384 This routine is for the purpose of predicate whether the Ifr is generated by a VfrCompiler greater than or equal to 1.88 or\r
385 less than 1.88 which is legacy.\r
386\r
387Arguments:\r
388 Iterator - The pointer to inconsistency tags\r
389\r
390Returns:\r
391\r
392 0x2 - If IFR is not legacy\r
393\r
394 0x1 - If IFR is legacy\r
395\r
396--*/\r
397{\r
398 //\r
399 // legacy Ifr cover the states:\r
400 // Not ...\r
401 // Operand Opcode Operand\r
402 //\r
403 // while Operand means ideqval, TRUE, or other what can be evaluated to True or False,\r
404 // and Opcode means AND or OR.\r
405 //\r
406 if (Iterator->Operand == EFI_IFR_NOT_OP ||\r
407 Iterator->Operand == 0) {\r
408 return 0x1;\r
409 } else if (Iterator->Operand == EFI_IFR_EQ_VAR_VAL_OP ||\r
410 Iterator->Operand == EFI_IFR_EQ_ID_VAL_OP ||\r
411 Iterator->Operand == EFI_IFR_EQ_ID_ID_OP ||\r
412 Iterator->Operand == EFI_IFR_EQ_ID_LIST_OP) {\r
413 Iterator++;\r
414 if (Iterator->Operand == EFI_IFR_AND_OP ||\r
415 Iterator->Operand == EFI_IFR_OR_OP) {\r
416 Iterator--;\r
417 return 0x1;\r
418 }\r
419 Iterator--;\r
420 }\r
421 return 0x2;\r
422}\r
423\r
1cc8ee78 424STATIC\r
878ddf1f 425VOID\r
426PostOrderEvaluate (\r
427 IN EFI_FILE_FORM_TAGS *FileFormTags,\r
428 IN UINT16 Width,\r
429 IN OUT EFI_INCONSISTENCY_DATA **PIterator,\r
430 IN OUT BOOLEAN **StackPtr\r
431 )\r
432/*++\r
433\r
434Routine Description:\r
435 PostOrderEvaluate is used for Ifr generated by VfrCompiler greater than or equal to 1.88,\r
436 which generate Operand Operand Opcode type Ifr.\r
437 PostOrderEvaluete only evaluate boolean expression part, not suppressif/grayoutif. TRUE,\r
438 FALSE, >=, >, (, ) are supported.\r
439\r
440Arguments:\r
441\r
442 FileFormTags - The pointer to the tags of the form\r
443\r
444 Width - Width of Operand, recognized every iteration\r
445\r
446 PIterator - The pointer to inconsistency tags\r
447\r
448 StackPtr - The pointer to the evaluation stack\r
449\r
450Returns:\r
451\r
452 TRUE - If value is valid\r
453\r
454 FALSE - If value is not valid\r
455\r
456--*/\r
457{\r
458 BOOLEAN Operator;\r
459 BOOLEAN Operator2;\r
460 UINT16 *MapBuffer;\r
461 UINT16 *MapBuffer2;\r
462 UINT16 MapValue;\r
463 UINT16 MapValue2;\r
464 UINTN SizeOfVariable;\r
273bbd31 465 CHAR16 VariableName[MAXIMUM_VALUE_CHARACTERS];\r
878ddf1f 466 VOID *VariableData;\r
467 EFI_VARIABLE_DEFINITION *VariableDefinition;\r
468 EFI_STATUS Status;\r
469 UINTN Index;\r
470 BOOLEAN PushValue;\r
471\r
472 Operator = FALSE;\r
473 Operator2 = FALSE;\r
474 MapBuffer = NULL;\r
475 MapBuffer2 = NULL;\r
476 MapValue = 0;\r
477 MapValue2 = 0;\r
478 VariableData = NULL;\r
479\r
480 while (TRUE) {\r
481 if ((*PIterator)->Operand == 0) {\r
482 return;\r
483 }\r
484\r
485 Width = (*PIterator)->Width;\r
486\r
487 // \r
488 // Because INVALID_OFFSET_VALUE - 1 is reserved for TRUE or FALSE, omit them.\r
489 //\r
490 if ((*PIterator)->QuestionId1 != INVALID_OFFSET_VALUE &&\r
491 (*PIterator)->QuestionId1 != INVALID_OFFSET_VALUE - 1) {\r
492 ExtractNvValue (FileFormTags, (*PIterator)->VariableNumber, Width, (*PIterator)->QuestionId1, (VOID **) &MapBuffer);\r
493 ExtractNvValue (FileFormTags, (*PIterator)->VariableNumber2, Width, (*PIterator)->QuestionId2, (VOID **) &MapBuffer2);\r
494 if (MapBuffer != NULL) {\r
495 if (Width == 2) {\r
496 MapValue = *MapBuffer;\r
497 } else {\r
498 MapValue = (UINT8) *MapBuffer;\r
499 }\r
500\r
501 gBS->FreePool (MapBuffer);\r
502 }\r
503\r
504 if (MapBuffer2 != NULL) {\r
505 if (Width == 2) {\r
506 MapValue2 = *MapBuffer2;\r
507 } else {\r
508 MapValue2 = (UINT8) *MapBuffer2;\r
509 }\r
510\r
511 gBS->FreePool (MapBuffer2);\r
512 }\r
513 }\r
514\r
515 switch ((*PIterator)->Operand) {\r
516 case EFI_IFR_EQ_VAR_VAL_OP:\r
517 UnicodeValueToString (\r
518 VariableName, \r
519 FALSE, \r
520 (UINTN) (*PIterator)->QuestionId1, \r
273bbd31 521 (sizeof (VariableName) / sizeof (VariableName[0])) - 1\r
878ddf1f 522 );\r
523\r
524 SizeOfVariable = 0;\r
525\r
526 ExtractRequestedNvMap (FileFormTags, (*PIterator)->VariableNumber, &VariableDefinition);\r
527\r
528 Status = BooleanVariableWorker (\r
529 VariableName,\r
530 VariableDefinition,\r
531 *StackPtr,\r
532 &SizeOfVariable,\r
533 &VariableData\r
534 );\r
535\r
536 if (!EFI_ERROR (Status)) {\r
537 if (SizeOfVariable == 1) {\r
538 CopyMem (&MapValue, VariableData, 1);\r
539 } else {\r
540 CopyMem (&MapValue, VariableData, 2);\r
541 }\r
542\r
543 //\r
544 // Do operation after knowing the compare operator.\r
545 //\r
546 MapValue2 = (*PIterator)->Value;\r
547 (*PIterator)++;\r
548 if ((*PIterator)->Operand == EFI_IFR_GT_OP) {\r
549 PushValue = (BOOLEAN) (MapValue > MapValue2);\r
550 } else if ((*PIterator)->Operand == EFI_IFR_GE_OP) {\r
551 PushValue = (BOOLEAN) (MapValue >= MapValue2);\r
552 } else {\r
553 (*PIterator)--;\r
554 PushValue = (BOOLEAN) (MapValue == MapValue2);\r
555 }\r
556 PushBool (StackPtr, PushValue);\r
557 }\r
558\r
559 break;\r
560\r
561 case EFI_IFR_EQ_ID_VAL_OP:\r
562 //\r
563 // Do operation after knowing the compare operator.\r
564 //\r
565 MapValue2 = (*PIterator)->Value;\r
566 (*PIterator)++;\r
567 if ((*PIterator)->Operand == EFI_IFR_GT_OP) {\r
568 PushValue = (BOOLEAN) (MapValue > MapValue2);\r
569 } else if ((*PIterator)->Operand == EFI_IFR_GE_OP) {\r
570 PushValue = (BOOLEAN) (MapValue >= MapValue2);\r
571 } else {\r
572 (*PIterator)--;\r
573 PushValue = (BOOLEAN) (MapValue == MapValue2);\r
574 }\r
575 PushBool (StackPtr, PushValue);\r
576 break;\r
577\r
578 case EFI_IFR_EQ_ID_ID_OP:\r
579 //\r
580 // Do operation after knowing the compare operator.\r
581 //\r
582 (*PIterator)++;\r
583 if ((*PIterator)->Operand == EFI_IFR_GT_OP) {\r
584 PushValue = (BOOLEAN) (MapValue > MapValue2);\r
585 } else if ((*PIterator)->Operand == EFI_IFR_GE_OP) {\r
586 PushValue = (BOOLEAN) (MapValue >= MapValue2);\r
587 } else {\r
588 (*PIterator)--;\r
589 PushValue = (BOOLEAN) (MapValue == MapValue2);\r
590 }\r
591 PushBool (StackPtr, PushValue);\r
592 break;\r
593\r
594 case EFI_IFR_EQ_ID_LIST_OP:\r
595 for (Index = 0; Index < (*PIterator)->ListLength; Index++) {\r
596 Operator = (BOOLEAN) (MapValue == (*PIterator)->ValueList[Index]);\r
597 if (Operator) {\r
598 break;\r
599 }\r
600 }\r
601\r
602 PushBool (StackPtr, Operator);\r
603 break;\r
604\r
605 case EFI_IFR_TRUE_OP:\r
606 PushBool (StackPtr, TRUE);\r
607 break;\r
608\r
609 case EFI_IFR_FALSE_OP:\r
610 PushBool (StackPtr, FALSE);\r
611 break;\r
612\r
613 case EFI_IFR_AND_OP:\r
614 Operator = PopBool (StackPtr);\r
615 Operator2 = PopBool (StackPtr);\r
616 PushBool (StackPtr, (BOOLEAN) (Operator && Operator2));\r
617 break;\r
618 case EFI_IFR_OR_OP:\r
619 Operator = PopBool (StackPtr);\r
620 Operator2 = PopBool (StackPtr);\r
621 PushBool (StackPtr, (BOOLEAN) (Operator || Operator2));\r
622 break;\r
623 case EFI_IFR_NOT_OP:\r
624 Operator = PopBool (StackPtr);\r
1cc8ee78 625 PushBool (StackPtr, (BOOLEAN) (!Operator));\r
878ddf1f 626 break;\r
627\r
628 case EFI_IFR_SUPPRESS_IF_OP:\r
629 case EFI_IFR_GRAYOUT_IF_OP:\r
630 case EFI_IFR_INCONSISTENT_IF_OP:\r
631 default:\r
632 //\r
633 // Return to the previous tag if runs out of boolean expression.\r
634 //\r
635 (*PIterator)--;\r
636 return;\r
637 }\r
638 (*PIterator)++;\r
639 }\r
640}\r
641\r
642BOOLEAN\r
643ValueIsNotValid (\r
644 IN BOOLEAN Complex,\r
645 IN UINT16 Value,\r
646 IN EFI_TAG *Tag,\r
647 IN EFI_FILE_FORM_TAGS *FileFormTags,\r
648 IN STRING_REF *PopUp\r
649 )\r
650/*++\r
651\r
652Routine Description:\r
653\r
654\r
655Arguments:\r
656\r
657Returns:\r
658\r
659 TRUE - If value is valid\r
660\r
661 FALSE - If value is not valid\r
662\r
663--*/\r
664{\r
665 BOOLEAN *StackPtr;\r
666 EFI_INCONSISTENCY_DATA *Iterator;\r
667 BOOLEAN Operator;\r
668 BOOLEAN Operator2;\r
669 UINTN Index;\r
670 VOID *BooleanExpression;\r
671 UINTN BooleanExpressionLength;\r
672 BOOLEAN NotOperator;\r
673 BOOLEAN OrOperator;\r
674 BOOLEAN AndOperator;\r
675 BOOLEAN ArtificialEnd;\r
676 UINT16 *MapBuffer;\r
677 UINT16 *MapBuffer2;\r
678 UINT16 MapValue;\r
679 UINT16 MapValue2;\r
680 UINTN SizeOfVariable;\r
273bbd31 681 CHAR16 VariableName[MAXIMUM_VALUE_CHARACTERS];\r
878ddf1f 682 VOID *VariableData;\r
683 EFI_STATUS Status;\r
684 UINT16 Id;\r
685 UINT16 Width;\r
686 EFI_VARIABLE_DEFINITION *VariableDefinition;\r
687 BOOLEAN CosmeticConsistency;\r
688 UINT8 IsLegacy;\r
689\r
690 VariableData = NULL;\r
691 BooleanExpressionLength = 0;\r
692 BooleanExpression = NULL;\r
693 Operator = FALSE;\r
694 ArtificialEnd = FALSE;\r
695 CosmeticConsistency = TRUE;\r
696 IsLegacy = 0;\r
697\r
698 Id = Tag->Id;\r
699 if (Tag->StorageWidth == 1) {\r
700 Width = 1;\r
701 } else {\r
702 Width = 2;\r
703 }\r
704 CreateBooleanExpression (FileFormTags, Value, Id, Complex, &BooleanExpression, &BooleanExpressionLength);\r
705\r
706 if (mBooleanEvaluationStack == 0) {\r
707 InitializeBooleanEvaluator ();\r
708 }\r
709\r
710 if (BooleanExpression == NULL) {\r
711 return FALSE;\r
712 }\r
713\r
714 StackPtr = mBooleanEvaluationStack;\r
715 Iterator = BooleanExpression;\r
716 MapBuffer = NULL;\r
717 MapBuffer2 = NULL;\r
718 MapValue = 0;\r
719 MapValue2 = 0;\r
720\r
721 while (TRUE) {\r
722 NotOperator = FALSE;\r
723 OrOperator = FALSE;\r
724 AndOperator = FALSE;\r
725\r
726 if (Iterator->Operand == 0) {\r
727 return Operator;\r
728 }\r
729\r
730 // \r
731 // Because INVALID_OFFSET_VALUE - 1 is reserved for TRUE or FALSE, omit them.\r
732 //\r
733 if (Iterator->QuestionId1 != INVALID_OFFSET_VALUE &&\r
734 Iterator->QuestionId1 != INVALID_OFFSET_VALUE-1) {\r
735 ExtractNvValue (FileFormTags, Iterator->VariableNumber, Width, Iterator->QuestionId1, (VOID **) &MapBuffer);\r
736 ExtractNvValue (FileFormTags, Iterator->VariableNumber2, Width, Iterator->QuestionId2, (VOID **) &MapBuffer2);\r
737 if (MapBuffer != NULL) {\r
738 if (Width == 2) {\r
739 MapValue = *MapBuffer;\r
740 } else {\r
741 MapValue = (UINT8) *MapBuffer;\r
742 }\r
743\r
744 gBS->FreePool (MapBuffer);\r
745 }\r
746\r
747 if (MapBuffer2 != NULL) {\r
748 if (Width == 2) {\r
749 MapValue2 = *MapBuffer2;\r
750 } else {\r
751 MapValue2 = (UINT8) *MapBuffer2;\r
752 }\r
753\r
754 gBS->FreePool (MapBuffer2);\r
755 }\r
756 }\r
757\r
758 switch (Iterator->Operand) {\r
759 case EFI_IFR_SUPPRESS_IF_OP:\r
760 //\r
761 // Must have hit a suppress followed by a grayout or vice-versa\r
762 //\r
763 if (ArtificialEnd) {\r
764 ArtificialEnd = FALSE;\r
765 Operator = PopBool (&StackPtr);\r
766 if (Operator) {\r
767 Tag->Suppress = TRUE;\r
768 }\r
769\r
770 return Operator;\r
771 }\r
772\r
773 ArtificialEnd = TRUE;\r
774 *PopUp = Iterator->Popup;\r
775 break;\r
776\r
777 case EFI_IFR_GRAYOUT_IF_OP:\r
778 //\r
779 // Must have hit a suppress followed by a grayout or vice-versa\r
780 //\r
781 if (ArtificialEnd) {\r
782 ArtificialEnd = FALSE;\r
783 Operator = PopBool (&StackPtr);\r
784 if (Operator) {\r
785 Tag->GrayOut = TRUE;\r
786 }\r
787\r
788 return Operator;\r
789 }\r
790\r
791 ArtificialEnd = TRUE;\r
792 *PopUp = Iterator->Popup;\r
793 break;\r
794\r
795 case EFI_IFR_INCONSISTENT_IF_OP:\r
796 CosmeticConsistency = FALSE;\r
797 *PopUp = Iterator->Popup;\r
798 break;\r
799\r
800 //\r
801 // In the case of external variable values, we must read the variable which is\r
802 // named by the human readable version of the OpCode->VariableId and the guid of the formset\r
803 //\r
804 case EFI_IFR_EQ_VAR_VAL_OP:\r
805 //\r
806 // To check whether Ifr is legacy. Once every boolean expression.\r
807 //\r
808 if (IsLegacy == 0) {\r
809 IsLegacy = PredicateIfrType (Iterator);\r
810 }\r
811 if (IsLegacy == 0x2) {\r
812 PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);\r
813 break;\r
814 }\r
815\r
816 UnicodeValueToString (\r
817 VariableName, \r
818 FALSE, \r
819 (UINTN) Iterator->QuestionId1, \r
273bbd31 820 (sizeof (VariableName) / sizeof (VariableName[0])) - 1\r
878ddf1f 821 );\r
822\r
823 SizeOfVariable = 0;\r
824\r
825 ExtractRequestedNvMap (FileFormTags, Iterator->VariableNumber, &VariableDefinition);\r
826\r
827 Status = BooleanVariableWorker (\r
828 VariableName,\r
829 VariableDefinition,\r
830 StackPtr,\r
831 &SizeOfVariable,\r
832 &VariableData\r
833 );\r
834\r
835 if (!EFI_ERROR (Status)) {\r
836 if (SizeOfVariable == 1) {\r
837 CopyMem (&MapValue, VariableData, 1);\r
838 } else {\r
839 CopyMem (&MapValue, VariableData, 2);\r
840 }\r
841\r
842 PushBool (&StackPtr, (BOOLEAN) (MapValue == Iterator->Value));\r
843 }\r
844\r
845 break;\r
846\r
847 case EFI_IFR_EQ_ID_VAL_OP:\r
848 //\r
849 // To check whether Ifr is legacy. Once every boolean expression.\r
850 //\r
851 if (IsLegacy == 0) {\r
852 IsLegacy = PredicateIfrType (Iterator);\r
853 }\r
854 if (IsLegacy == 0x2) {\r
855 PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);\r
856 break;\r
857 }\r
858\r
859 PushBool (&StackPtr, (BOOLEAN) (MapValue == Iterator->Value));\r
860 break;\r
861\r
862 case EFI_IFR_EQ_ID_ID_OP:\r
863 //\r
864 // To check whether Ifr is legacy. Once every boolean expression.\r
865 //\r
866 if (IsLegacy == 0) {\r
867 IsLegacy = PredicateIfrType (Iterator);\r
868 }\r
869 if (IsLegacy == 0x2) {\r
870 PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);\r
871 break;\r
872 }\r
873\r
874 PushBool (&StackPtr, (BOOLEAN) (MapValue == MapValue2));\r
875 break;\r
876\r
877 case EFI_IFR_EQ_ID_LIST_OP:\r
878 //\r
879 // To check whether Ifr is legacy. Once every boolean expression.\r
880 //\r
881 if (IsLegacy == 0) {\r
882 IsLegacy = PredicateIfrType (Iterator);\r
883 }\r
884 if (IsLegacy == 0x2) {\r
885 PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);\r
886 break;\r
887 }\r
888\r
889 for (Index = 0; Index < Iterator->ListLength; Index++) {\r
890 Operator = (BOOLEAN) (MapValue == Iterator->ValueList[Index]);\r
891 if (Operator) {\r
892 break;\r
893 }\r
894 }\r
895\r
896 PushBool (&StackPtr, Operator);\r
897 break;\r
898\r
899 case EFI_IFR_AND_OP:\r
900 Iterator++;\r
901 if (Iterator->Operand == EFI_IFR_NOT_OP) {\r
902 NotOperator = TRUE;\r
903 Iterator++;\r
904 }\r
905\r
906 if (Iterator->QuestionId1 != INVALID_OFFSET_VALUE) {\r
907 ExtractNvValue (FileFormTags, Iterator->VariableNumber, Width, Iterator->QuestionId1, (VOID **) &MapBuffer);\r
908 ExtractNvValue (FileFormTags, Iterator->VariableNumber2, Width, Iterator->QuestionId2, (VOID **) &MapBuffer2);\r
909 if (MapBuffer != NULL) {\r
910 if (Width == 2) {\r
911 MapValue = *MapBuffer;\r
912 } else {\r
913 MapValue = (UINT8) *MapBuffer;\r
914 }\r
915\r
916 gBS->FreePool (MapBuffer);\r
917 }\r
918\r
919 if (MapBuffer2 != NULL) {\r
920 if (Width == 2) {\r
921 MapValue2 = *MapBuffer2;\r
922 } else {\r
923 MapValue2 = (UINT8) *MapBuffer2;\r
924 }\r
925\r
926 gBS->FreePool (MapBuffer2);\r
927 }\r
928 }\r
929\r
930 switch (Iterator->Operand) {\r
931 case EFI_IFR_EQ_ID_VAL_OP:\r
932 //\r
933 // If Not - flip the results\r
934 //\r
935 if (NotOperator) {\r
936 Operator = (BOOLEAN)!(MapValue == Iterator->Value);\r
937 } else {\r
938 Operator = (BOOLEAN) (MapValue == Iterator->Value);\r
939 }\r
940\r
941 PushBool (&StackPtr, Operator);\r
942 break;\r
943\r
944 //\r
945 // In the case of external variable values, we must read the variable which is\r
946 // named by the human readable version of the OpCode->VariableId and the guid of the formset\r
947 //\r
948 case EFI_IFR_EQ_VAR_VAL_OP:\r
949 UnicodeValueToString (\r
950 VariableName, \r
951 FALSE, \r
952 (UINTN) Iterator->QuestionId1, \r
273bbd31 953 (sizeof (VariableName) / sizeof (VariableName[0])) - 1\r
878ddf1f 954 );\r
955\r
956 SizeOfVariable = 0;\r
957\r
958 ExtractRequestedNvMap (FileFormTags, Iterator->VariableNumber, &VariableDefinition);\r
959\r
960 Status = BooleanVariableWorker (\r
961 VariableName,\r
962 VariableDefinition,\r
963 StackPtr,\r
964 &SizeOfVariable,\r
965 &VariableData\r
966 );\r
967\r
968 if (!EFI_ERROR (Status)) {\r
969 if (SizeOfVariable == 1) {\r
970 CopyMem (&MapValue, VariableData, 1);\r
971 } else {\r
972 CopyMem (&MapValue, VariableData, 2);\r
973 }\r
974 //\r
975 // If Not - flip the results\r
976 //\r
977 if (NotOperator) {\r
978 PushBool (&StackPtr, (BOOLEAN)!(MapValue == Iterator->Value));\r
979 } else {\r
980 PushBool (&StackPtr, (BOOLEAN) (MapValue == Iterator->Value));\r
981 }\r
982 }\r
983 break;\r
984\r
985 case EFI_IFR_EQ_ID_ID_OP:\r
986 //\r
987 // If Not - flip the results\r
988 //\r
989 if (NotOperator) {\r
990 Operator = (BOOLEAN)!(MapValue == MapValue2);\r
991 } else {\r
992 Operator = (BOOLEAN) (MapValue == MapValue2);\r
993 }\r
994\r
995 PushBool (&StackPtr, Operator);\r
996 break;\r
997\r
998 case EFI_IFR_EQ_ID_LIST_OP:\r
999 for (Index = 0; Index < Iterator->ListLength; Index++) {\r
1000 //\r
1001 // If Not - flip the results\r
1002 //\r
1003 if (NotOperator) {\r
1004 Operator = (BOOLEAN)!(MapValue == Iterator->ValueList[Index]);\r
1005 } else {\r
1006 Operator = (BOOLEAN) (MapValue == Iterator->ValueList[Index]);\r
1007 }\r
1008 //\r
1009 // If We are trying to make sure that MapValue != Item[x], keep looking through\r
1010 // the list to make sure we don't equal any other items\r
1011 //\r
1012 if (Operator && NotOperator) {\r
1013 continue;\r
1014 }\r
1015 //\r
1016 // If MapValue == Item, then we have succeeded (first found is good enough)\r
1017 //\r
1018 if (Operator) {\r
1019 break;\r
1020 }\r
1021 }\r
1022\r
1023 PushBool (&StackPtr, Operator);\r
1024 break;\r
1025\r
1026 default:\r
1027 return FALSE;\r
1028 }\r
1029\r
1030 Operator = PopBool (&StackPtr);\r
1031 Operator2 = PopBool (&StackPtr);\r
1032 PushBool (&StackPtr, (BOOLEAN) (Operator && Operator2));\r
1033 break;\r
1034\r
1035 case EFI_IFR_OR_OP:\r
1036 Iterator++;\r
1037 if (Iterator->Operand == EFI_IFR_NOT_OP) {\r
1038 NotOperator = TRUE;\r
1039 Iterator++;\r
1040 }\r
1041\r
1042 if (Iterator->QuestionId1 != INVALID_OFFSET_VALUE) {\r
1043 ExtractNvValue (FileFormTags, Iterator->VariableNumber, Width, Iterator->QuestionId1, (VOID **) &MapBuffer);\r
1044 ExtractNvValue (FileFormTags, Iterator->VariableNumber2, Width, Iterator->QuestionId2, (VOID **) &MapBuffer2);\r
1045 if (MapBuffer != NULL) {\r
1046 if (Width == 2) {\r
1047 MapValue = *MapBuffer;\r
1048 } else {\r
1049 MapValue = (UINT8) *MapBuffer;\r
1050 }\r
1051\r
1052 gBS->FreePool (MapBuffer);\r
1053 }\r
1054\r
1055 if (MapBuffer2 != NULL) {\r
1056 if (Width == 2) {\r
1057 MapValue2 = *MapBuffer2;\r
1058 } else {\r
1059 MapValue2 = (UINT8) *MapBuffer2;\r
1060 }\r
1061\r
1062 gBS->FreePool (MapBuffer2);\r
1063 }\r
1064 }\r
1065\r
1066 switch (Iterator->Operand) {\r
1067 case EFI_IFR_EQ_ID_VAL_OP:\r
1068 //\r
1069 // If Not - flip the results\r
1070 //\r
1071 if (NotOperator) {\r
1072 Operator = (BOOLEAN)!(MapValue == Iterator->Value);\r
1073 } else {\r
1074 Operator = (BOOLEAN) (MapValue == Iterator->Value);\r
1075 }\r
1076\r
1077 PushBool (&StackPtr, Operator);\r
1078 break;\r
1079\r
1080 //\r
1081 // In the case of external variable values, we must read the variable which is\r
1082 // named by the human readable version of the OpCode->VariableId and the guid of the formset\r
1083 //\r
1084 case EFI_IFR_EQ_VAR_VAL_OP:\r
1085 UnicodeValueToString (\r
1086 VariableName, \r
1087 FALSE, \r
1088 (UINTN) Iterator->QuestionId1, \r
273bbd31 1089 (sizeof (VariableName) / sizeof (VariableName[0])) - 1\r
878ddf1f 1090 );\r
1091\r
1092 SizeOfVariable = 0;\r
1093\r
1094 ExtractRequestedNvMap (FileFormTags, Iterator->VariableNumber, &VariableDefinition);\r
1095\r
1096 Status = BooleanVariableWorker (\r
1097 VariableName,\r
1098 VariableDefinition,\r
1099 StackPtr,\r
1100 &SizeOfVariable,\r
1101 &VariableData\r
1102 );\r
1103\r
1104 if (!EFI_ERROR (Status)) {\r
1105 if (SizeOfVariable == 1) {\r
1106 CopyMem (&MapValue, VariableData, 1);\r
1107 } else {\r
1108 CopyMem (&MapValue, VariableData, 2);\r
1109 }\r
1110 //\r
1111 // If Not - flip the results\r
1112 //\r
1113 if (NotOperator) {\r
1114 PushBool (&StackPtr, (BOOLEAN)!(MapValue == Iterator->Value));\r
1115 } else {\r
1116 PushBool (&StackPtr, (BOOLEAN) (MapValue == Iterator->Value));\r
1117 }\r
1118 }\r
1119 break;\r
1120\r
1121 case EFI_IFR_EQ_ID_ID_OP:\r
1122 //\r
1123 // If Not - flip the results\r
1124 //\r
1125 if (NotOperator) {\r
1126 Operator = (BOOLEAN)!(MapValue == MapValue2);\r
1127 } else {\r
1128 Operator = (BOOLEAN) (MapValue == MapValue2);\r
1129 }\r
1130\r
1131 PushBool (&StackPtr, Operator);\r
1132 break;\r
1133\r
1134 case EFI_IFR_EQ_ID_LIST_OP:\r
1135 for (Index = 0; Index < Iterator->ListLength; Index++) {\r
1136 //\r
1137 // If Not - flip the results\r
1138 //\r
1139 if (NotOperator) {\r
1140 Operator = (BOOLEAN)!(MapValue == Iterator->ValueList[Index]);\r
1141 } else {\r
1142 Operator = (BOOLEAN) (MapValue == Iterator->ValueList[Index]);\r
1143 }\r
1144 //\r
1145 // If We are trying to make sure that MapValue != Item[x], keep looking through\r
1146 // the list to make sure we don't equal any other items\r
1147 //\r
1148 if (Operator && NotOperator) {\r
1149 continue;\r
1150 }\r
1151 //\r
1152 // If MapValue == Item, then we have succeeded (first found is good enough)\r
1153 //\r
1154 if (Operator) {\r
1155 break;\r
1156 }\r
1157 }\r
1158\r
1159 PushBool (&StackPtr, Operator);\r
1160 break;\r
1161\r
1162 default:\r
1163 return FALSE;\r
1164 }\r
1165\r
1166 Operator = PopBool (&StackPtr);\r
1167 Operator2 = PopBool (&StackPtr);\r
1168 PushBool (&StackPtr, (BOOLEAN) (Operator || Operator2));\r
1169 break;\r
1170\r
1171 case EFI_IFR_NOT_OP:\r
1172 //\r
1173 // To check whether Ifr is legacy. Once every boolean expression.\r
1174 //\r
1175 if (IsLegacy == 0) {\r
1176 IsLegacy = PredicateIfrType (Iterator);\r
1177 }\r
1178 if (IsLegacy == 0x2) {\r
1179 PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);\r
1180 break;\r
1181 }\r
1182\r
1183 //\r
1184 // I don't need to set the NotOperator (I know that I have to NOT this in this case\r
1185 //\r
1186 Iterator++;\r
1187\r
1188 if (Iterator->Operand == EFI_IFR_OR_OP) {\r
1189 OrOperator = TRUE;\r
1190 Iterator++;\r
1191 }\r
1192\r
1193 if (Iterator->Operand == EFI_IFR_AND_OP) {\r
1194 AndOperator = TRUE;\r
1195 Iterator++;\r
1196 }\r
1197\r
1198 if (Iterator->QuestionId1 != INVALID_OFFSET_VALUE) {\r
1199 ExtractNvValue (FileFormTags, Iterator->VariableNumber, Width, Iterator->QuestionId1, (VOID **) &MapBuffer);\r
1200 ExtractNvValue (FileFormTags, Iterator->VariableNumber2, Width, Iterator->QuestionId2, (VOID **) &MapBuffer2);\r
1201 if (MapBuffer != NULL) {\r
1202 if (Width == 2) {\r
1203 MapValue = *MapBuffer;\r
1204 } else {\r
1205 MapValue = (UINT8) *MapBuffer;\r
1206 }\r
1207\r
1208 gBS->FreePool (MapBuffer);\r
1209 }\r
1210\r
1211 if (MapBuffer2 != NULL) {\r
1212 if (Width == 2) {\r
1213 MapValue2 = *MapBuffer2;\r
1214 } else {\r
1215 MapValue2 = (UINT8) *MapBuffer2;\r
1216 }\r
1217\r
1218 gBS->FreePool (MapBuffer2);\r
1219 }\r
1220 }\r
1221\r
1222 switch (Iterator->Operand) {\r
1223 case EFI_IFR_EQ_ID_VAL_OP:\r
1224 Operator = (BOOLEAN)!(MapValue == Iterator->Value);\r
1225 PushBool (&StackPtr, Operator);\r
1226 break;\r
1227\r
1228 //\r
1229 // In the case of external variable values, we must read the variable which is\r
1230 // named by the human readable version of the OpCode->VariableId and the guid of the formset\r
1231 //\r
1232 case EFI_IFR_EQ_VAR_VAL_OP:\r
1233 UnicodeValueToString (\r
1234 VariableName, \r
1235 FALSE, \r
1236 (UINTN) Iterator->QuestionId1, \r
273bbd31 1237 (sizeof (VariableName) / sizeof (VariableName[0])) - 1\r
878ddf1f 1238 );\r
1239\r
1240 SizeOfVariable = 0;\r
1241\r
1242 ExtractRequestedNvMap (FileFormTags, Iterator->VariableNumber, &VariableDefinition);\r
1243\r
1244 Status = BooleanVariableWorker (\r
1245 VariableName,\r
1246 VariableDefinition,\r
1247 StackPtr,\r
1248 &SizeOfVariable,\r
1249 &VariableData\r
1250 );\r
1251\r
1252 if (!EFI_ERROR (Status)) {\r
1253 if (SizeOfVariable == 1) {\r
1254 CopyMem (&MapValue, VariableData, 1);\r
1255 } else {\r
1256 CopyMem (&MapValue, VariableData, 2);\r
1257 }\r
1258\r
1259 PushBool (&StackPtr, (BOOLEAN)!(MapValue == Iterator->Value));\r
1260 }\r
1261 break;\r
1262\r
1263 case EFI_IFR_EQ_ID_ID_OP:\r
1264 Operator = (BOOLEAN)!(MapValue == MapValue2);\r
1265 PushBool (&StackPtr, Operator);\r
1266 break;\r
1267\r
1268 case EFI_IFR_EQ_ID_LIST_OP:\r
1269 for (Index = 0; Index < Iterator->ListLength; Index++) {\r
1270 Operator = (BOOLEAN)!(MapValue == Iterator->ValueList[Index]);\r
1271 if (Operator) {\r
1272 continue;\r
1273 }\r
1274 }\r
1275\r
1276 PushBool (&StackPtr, Operator);\r
1277 break;\r
1278\r
1279 default:\r
1280 return FALSE;\r
1281 }\r
1282\r
1283 Operator = PopBool (&StackPtr);\r
1284 Operator2 = PopBool (&StackPtr);\r
1285\r
1286 if (OrOperator) {\r
1287 PushBool (&StackPtr, (BOOLEAN) (Operator || Operator2));\r
1288 }\r
1289\r
1290 if (AndOperator) {\r
1291 PushBool (&StackPtr, (BOOLEAN) (Operator && Operator2));\r
1292 }\r
1293\r
1294 if (!OrOperator && !AndOperator) {\r
1295 PushBool (&StackPtr, Operator);\r
1296 }\r
1297 break;\r
1298 \r
1299 case EFI_IFR_TRUE_OP:\r
1300 //\r
1301 // To check whether Ifr is legacy. Once every boolean expression.\r
1302 //\r
1303 if (IsLegacy == 0) {\r
1304 IsLegacy = PredicateIfrType (Iterator);\r
1305 }\r
1306 if (IsLegacy == 0x2) {\r
1307 PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);\r
1308 break;\r
1309 }\r
1310 break;\r
1311\r
1312 case EFI_IFR_FALSE_OP:\r
1313 //\r
1314 // To check whether Ifr is legacy. Once every boolean expression.\r
1315 //\r
1316 if (IsLegacy == 0) {\r
1317 IsLegacy = PredicateIfrType (Iterator);\r
1318 }\r
1319 if (IsLegacy == 0x2) {\r
1320 PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);\r
1321 break;\r
1322 }\r
1323 break;\r
1324\r
1325 case EFI_IFR_END_IF_OP:\r
1326 Operator = PopBool (&StackPtr);\r
1327 //\r
1328 // If there is an error, return, otherwise keep looking - there might\r
1329 // be another test that causes an error\r
1330 //\r
1331 if (Operator) {\r
1332 if (Complex && CosmeticConsistency) {\r
1333 return EFI_SUCCESS;\r
1334 } else {\r
1335 return Operator;\r
1336 }\r
1337 } else {\r
1338 //\r
1339 // If not doing a global consistency check, the endif is the REAL terminator of this operation\r
1340 // This is used for grayout/suppress operations. InconsistentIf is a global operation so the EndIf is\r
1341 // not the end-all be-all of terminators.\r
1342 //\r
1343 if (!Complex) {\r
1344 return Operator;\r
1345 }\r
1346 break;\r
1347 }\r
1348\r
1349 default:\r
1350 //\r
1351 // Must have hit a non-consistency related op-code after a suppress/grayout\r
1352 //\r
1353 if (ArtificialEnd) {\r
1354 ArtificialEnd = FALSE;\r
1355 Operator = PopBool (&StackPtr);\r
1356 return Operator;\r
1357 }\r
1358\r
1cc8ee78 1359 goto Done;\r
878ddf1f 1360 }\r
1361\r
1362 Iterator++;\r
1363 }\r
1364\r
1cc8ee78 1365Done:\r
878ddf1f 1366 return FALSE;\r
1367}\r