VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/RedfishPkg/Library/HiiUtilityLib/HiiExpression.c@ 107064

Last change on this file since 107064 was 101291, checked in by vboxsync, 17 months ago

EFI/FirmwareNew: Make edk2-stable202308 build on all supported platforms (using gcc at least, msvc not tested yet), bugref:4643

  • Property svn:eol-style set to native
File size: 45.0 KB
Line 
1/** @file
2 The implementation of HII expression.
3
4 Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
6 Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
7
8 SPDX-License-Identifier: BSD-2-Clause-Patent
9
10**/
11#include "HiiInternal.h"
12
13//
14// Global stack used to evaluate boolean expressions
15//
16EFI_HII_VALUE *mOpCodeScopeStack = NULL;
17EFI_HII_VALUE *mOpCodeScopeStackEnd = NULL;
18EFI_HII_VALUE *mOpCodeScopeStackPointer = NULL;
19
20//
21// Stack used for Suppressif/grayoutif/disableif expression list.
22//
23HII_EXPRESSION **mFormExpressionStack = NULL;
24HII_EXPRESSION **mFormExpressionEnd = NULL;
25HII_EXPRESSION **mFormExpressionPointer = NULL;
26
27HII_EXPRESSION **mStatementExpressionStack = NULL;
28HII_EXPRESSION **mStatementExpressionEnd = NULL;
29HII_EXPRESSION **mStatementExpressionPointer = NULL;
30
31HII_EXPRESSION **mOptionExpressionStack = NULL;
32HII_EXPRESSION **mOptionExpressionEnd = NULL;
33HII_EXPRESSION **mOptionExpressionPointer = NULL;
34
35//
36// Stack used for the sub expresion in map expression.
37//
38EFI_HII_VALUE *mCurrentExpressionStack = NULL;
39EFI_HII_VALUE *mCurrentExpressionEnd = NULL;
40EFI_HII_VALUE *mCurrentExpressionPointer = NULL;
41
42//
43// Stack used for the map expression list.
44//
45EFI_HII_VALUE *mMapExpressionListStack = NULL;
46EFI_HII_VALUE *mMapExpressionListEnd = NULL;
47EFI_HII_VALUE *mMapExpressionListPointer = NULL;
48
49//
50// Stack used for dependency expression.
51//
52HII_DEPENDENCY_EXPRESSION **mExpressionDependencyStack = NULL;
53HII_DEPENDENCY_EXPRESSION **mExpressionDependencyEnd = NULL;
54HII_DEPENDENCY_EXPRESSION **mExpressionDependencyPointer = NULL;
55
56/**
57 Grow size of the stack.
58
59 This is an internal function.
60
61 @param Stack On input: old stack; On output: new stack
62 @param StackPtr On input: old stack pointer; On output: new stack
63 pointer
64 @param StackEnd On input: old stack end; On output: new stack end
65
66 @retval EFI_SUCCESS Grow stack success.
67 @retval EFI_OUT_OF_RESOURCES No enough memory for stack space.
68
69**/
70EFI_STATUS
71GrowStack (
72 IN OUT EFI_HII_VALUE **Stack,
73 IN OUT EFI_HII_VALUE **StackPtr,
74 IN OUT EFI_HII_VALUE **StackEnd
75 )
76{
77 UINTN Size;
78 EFI_HII_VALUE *NewStack;
79
80 Size = EXPRESSION_STACK_SIZE_INCREMENT;
81 if (*StackPtr != NULL) {
82 Size = Size + (*StackEnd - *Stack);
83 }
84
85 NewStack = AllocatePool (Size * sizeof (EFI_HII_VALUE));
86 if (NewStack == NULL) {
87 return EFI_OUT_OF_RESOURCES;
88 }
89
90 if (*StackPtr != NULL) {
91 //
92 // Copy from Old Stack to the New Stack
93 //
94 CopyMem (
95 NewStack,
96 *Stack,
97 (*StackEnd - *Stack) * sizeof (EFI_HII_VALUE)
98 );
99
100 //
101 // Free The Old Stack
102 //
103 FreePool (*Stack);
104 }
105
106 //
107 // Make the Stack pointer point to the old data in the new stack
108 //
109 *StackPtr = NewStack + (*StackPtr - *Stack);
110 *Stack = NewStack;
111 *StackEnd = NewStack + Size;
112
113 return EFI_SUCCESS;
114}
115
116/**
117 Push an element onto the Boolean Stack.
118
119 @param Stack On input: old stack; On output: new stack
120 @param StackPtr On input: old stack pointer; On output: new stack
121 pointer
122 @param StackEnd On input: old stack end; On output: new stack end
123 @param Data Data to push.
124
125 @retval EFI_SUCCESS Push stack success.
126
127**/
128EFI_STATUS
129PushStack (
130 IN OUT EFI_HII_VALUE **Stack,
131 IN OUT EFI_HII_VALUE **StackPtr,
132 IN OUT EFI_HII_VALUE **StackEnd,
133 IN EFI_HII_VALUE *Data
134 )
135{
136 EFI_STATUS Status;
137
138 //
139 // Check for a stack overflow condition
140 //
141 if (*StackPtr >= *StackEnd) {
142 //
143 // Grow the stack
144 //
145 Status = GrowStack (Stack, StackPtr, StackEnd);
146 if (EFI_ERROR (Status)) {
147 return Status;
148 }
149 }
150
151 //
152 // Push the item onto the stack
153 //
154 CopyMem (*StackPtr, Data, sizeof (EFI_HII_VALUE));
155 if (Data->Type == EFI_IFR_TYPE_BUFFER) {
156 (*StackPtr)->Buffer = AllocateCopyPool (Data->BufferLen, Data->Buffer);
157 if ((*StackPtr)->Buffer == NULL) {
158 return EFI_OUT_OF_RESOURCES;
159 }
160 }
161
162 *StackPtr = *StackPtr + 1;
163
164 return EFI_SUCCESS;
165}
166
167/**
168 Pop an element from the stack.
169
170 @param Stack On input: old stack
171 @param StackPtr On input: old stack pointer; On output: new stack pointer
172 @param Data Data to pop.
173
174 @retval EFI_SUCCESS The value was popped onto the stack.
175 @retval EFI_ACCESS_DENIED The pop operation underflowed the stack
176
177**/
178EFI_STATUS
179PopStack (
180 IN EFI_HII_VALUE *Stack,
181 IN OUT EFI_HII_VALUE **StackPtr,
182 OUT EFI_HII_VALUE *Data
183 )
184{
185 //
186 // Check for a stack underflow condition
187 //
188 if (*StackPtr == Stack) {
189 return EFI_ACCESS_DENIED;
190 }
191
192 //
193 // Pop the item off the stack
194 //
195 *StackPtr = *StackPtr - 1;
196 CopyMem (Data, *StackPtr, sizeof (EFI_HII_VALUE));
197 return EFI_SUCCESS;
198}
199
200/**
201 Reset stack pointer to begin of the stack.
202
203**/
204VOID
205ResetCurrentExpressionStack (
206 VOID
207 )
208{
209 mCurrentExpressionPointer = mCurrentExpressionStack;
210 mFormExpressionPointer = mFormExpressionStack;
211 mStatementExpressionPointer = mStatementExpressionStack;
212 mOptionExpressionPointer = mOptionExpressionStack;
213}
214
215/**
216 Push current expression onto the Stack
217
218 @param Pointer Pointer to current expression.
219
220 @retval EFI_SUCCESS The value was pushed onto the stack.
221 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
222
223**/
224EFI_STATUS
225PushCurrentExpression (
226 IN VOID *Pointer
227 )
228{
229 EFI_HII_VALUE Data;
230
231 Data.Type = EFI_IFR_TYPE_NUM_SIZE_64;
232 Data.Value.u64 = (UINT64)(UINTN)Pointer;
233
234 return PushStack (
235 &mCurrentExpressionStack,
236 &mCurrentExpressionPointer,
237 &mCurrentExpressionEnd,
238 &Data
239 );
240}
241
242/**
243 Pop current expression from the Stack
244
245 @param Pointer Pointer to current expression to be pop.
246
247 @retval EFI_SUCCESS The value was pushed onto the stack.
248 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
249
250**/
251EFI_STATUS
252PopCurrentExpression (
253 OUT VOID **Pointer
254 )
255{
256 EFI_STATUS Status;
257 EFI_HII_VALUE Data;
258
259 Status = PopStack (
260 mCurrentExpressionStack,
261 &mCurrentExpressionPointer,
262 &Data
263 );
264
265 *Pointer = (VOID *)(UINTN)Data.Value.u64;
266
267 return Status;
268}
269
270/**
271 Reset stack pointer to begin of the stack.
272
273**/
274VOID
275ResetMapExpressionListStack (
276 VOID
277 )
278{
279 mMapExpressionListPointer = mMapExpressionListStack;
280}
281
282/**
283 Grow size of the stack.
284
285 This is an internal function.
286
287 @param Stack On input: old stack; On output: new stack
288 @param StackPtr On input: old stack pointer; On output: new stack
289 pointer
290 @param StackEnd On input: old stack end; On output: new stack end
291 @param MemberSize The stack member size.
292
293 @retval EFI_SUCCESS Grow stack success.
294 @retval EFI_OUT_OF_RESOURCES No enough memory for stack space.
295
296**/
297EFI_STATUS
298GrowConditionalStack (
299 IN OUT HII_EXPRESSION ***Stack,
300 IN OUT HII_EXPRESSION ***StackPtr,
301 IN OUT HII_EXPRESSION ***StackEnd,
302 IN UINTN MemberSize
303 )
304{
305 UINTN Size;
306 HII_EXPRESSION **NewStack;
307
308 Size = EXPRESSION_STACK_SIZE_INCREMENT;
309 if (*StackPtr != NULL) {
310 Size = Size + (*StackEnd - *Stack);
311 }
312
313 NewStack = AllocatePool (Size * MemberSize);
314 if (NewStack == NULL) {
315 return EFI_OUT_OF_RESOURCES;
316 }
317
318 if (*StackPtr != NULL) {
319 //
320 // Copy from Old Stack to the New Stack
321 //
322 CopyMem (
323 NewStack,
324 *Stack,
325 (*StackEnd - *Stack) * MemberSize
326 );
327
328 //
329 // Free The Old Stack
330 //
331 FreePool (*Stack);
332 }
333
334 //
335 // Make the Stack pointer point to the old data in the new stack
336 //
337 *StackPtr = NewStack + (*StackPtr - *Stack);
338 *Stack = NewStack;
339 *StackEnd = NewStack + Size;
340
341 return EFI_SUCCESS;
342}
343
344/**
345 Push an element onto the Stack.
346
347 @param Stack On input: old stack; On output: new stack
348 @param StackPtr On input: old stack pointer; On output: new stack
349 pointer
350 @param StackEnd On input: old stack end; On output: new stack end
351 @param Data Data to push.
352
353 @retval EFI_SUCCESS Push stack success.
354
355**/
356EFI_STATUS
357PushConditionalStack (
358 IN OUT HII_EXPRESSION ***Stack,
359 IN OUT HII_EXPRESSION ***StackPtr,
360 IN OUT HII_EXPRESSION ***StackEnd,
361 IN HII_EXPRESSION **Data
362 )
363{
364 EFI_STATUS Status;
365
366 //
367 // Check for a stack overflow condition
368 //
369 if (*StackPtr >= *StackEnd) {
370 //
371 // Grow the stack
372 //
373 Status = GrowConditionalStack (Stack, StackPtr, StackEnd, sizeof (HII_EXPRESSION *));
374 if (EFI_ERROR (Status)) {
375 return Status;
376 }
377 }
378
379 //
380 // Push the item onto the stack
381 //
382 CopyMem (*StackPtr, Data, sizeof (HII_EXPRESSION *));
383 *StackPtr = *StackPtr + 1;
384
385 return EFI_SUCCESS;
386}
387
388/**
389 Pop an element from the stack.
390
391 @param Stack On input: old stack
392 @param StackPtr On input: old stack pointer; On output: new stack pointer
393 @param Data Data to pop.
394
395 @retval EFI_SUCCESS The value was popped onto the stack.
396 @retval EFI_ACCESS_DENIED The pop operation underflowed the stack
397
398**/
399EFI_STATUS
400PopConditionalStack (
401 IN HII_EXPRESSION **Stack,
402 IN OUT HII_EXPRESSION ***StackPtr,
403 OUT HII_EXPRESSION **Data
404 )
405{
406 //
407 // Check for a stack underflow condition
408 //
409 if (*StackPtr == Stack) {
410 return EFI_ACCESS_DENIED;
411 }
412
413 //
414 // Pop the item off the stack
415 //
416 *StackPtr = *StackPtr - 1;
417 CopyMem (Data, *StackPtr, sizeof (HII_EXPRESSION *));
418 return EFI_SUCCESS;
419}
420
421/**
422 Get the expression list count.
423
424 @param Level Which type this expression belong to. Form,
425 statement or option?
426
427 @retval >=0 The expression count
428 @retval -1 Input parameter error.
429
430**/
431INTN
432GetConditionalExpressionCount (
433 IN EXPRESS_LEVEL Level
434 )
435{
436 switch (Level) {
437 case ExpressForm:
438 return mFormExpressionPointer - mFormExpressionStack;
439 case ExpressStatement:
440 return mStatementExpressionPointer - mStatementExpressionStack;
441 case ExpressOption:
442 return mOptionExpressionPointer - mOptionExpressionStack;
443 default:
444 ASSERT (FALSE);
445 return -1;
446 }
447}
448
449/**
450 Get the expression Buffer pointer.
451
452 @param Level Which type this expression belong to. Form,
453 statement or option?
454
455 @retval The start pointer of the expression buffer or NULL.
456
457**/
458HII_EXPRESSION **
459GetConditionalExpressionList (
460 IN EXPRESS_LEVEL Level
461 )
462{
463 switch (Level) {
464 case ExpressForm:
465 return mFormExpressionStack;
466 case ExpressStatement:
467 return mStatementExpressionStack;
468 case ExpressOption:
469 return mOptionExpressionStack;
470 default:
471 ASSERT (FALSE);
472 return NULL;
473 }
474}
475
476/**
477 Push the expression options onto the Stack.
478
479 @param Pointer Pointer to the current expression.
480 @param Level Which type this expression belong to. Form,
481 statement or option?
482
483 @retval EFI_SUCCESS The value was pushed onto the stack.
484 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
485
486**/
487EFI_STATUS
488PushConditionalExpression (
489 IN HII_EXPRESSION *Pointer,
490 IN EXPRESS_LEVEL Level
491 )
492{
493 switch (Level) {
494 case ExpressForm:
495 return PushConditionalStack (
496 &mFormExpressionStack,
497 &mFormExpressionPointer,
498 &mFormExpressionEnd,
499 &Pointer
500 );
501 case ExpressStatement:
502 return PushConditionalStack (
503 &mStatementExpressionStack,
504 &mStatementExpressionPointer,
505 &mStatementExpressionEnd,
506 &Pointer
507 );
508 case ExpressOption:
509 return PushConditionalStack (
510 &mOptionExpressionStack,
511 &mOptionExpressionPointer,
512 &mOptionExpressionEnd,
513 &Pointer
514 );
515 default:
516 ASSERT (FALSE);
517 return EFI_INVALID_PARAMETER;
518 }
519}
520
521/**
522 Pop the expression options from the Stack
523
524 @param Level Which type this expression belong to. Form,
525 statement or option?
526
527 @retval EFI_SUCCESS The value was pushed onto the stack.
528 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
529
530**/
531EFI_STATUS
532PopConditionalExpression (
533 IN EXPRESS_LEVEL Level
534 )
535{
536 HII_EXPRESSION *Pointer;
537
538 switch (Level) {
539 case ExpressForm:
540 return PopConditionalStack (
541 mFormExpressionStack,
542 &mFormExpressionPointer,
543 &Pointer
544 );
545
546 case ExpressStatement:
547 return PopConditionalStack (
548 mStatementExpressionStack,
549 &mStatementExpressionPointer,
550 &Pointer
551 );
552
553 case ExpressOption:
554 return PopConditionalStack (
555 mOptionExpressionStack,
556 &mOptionExpressionPointer,
557 &Pointer
558 );
559
560 default:
561 ASSERT (FALSE);
562 return EFI_INVALID_PARAMETER;
563 }
564}
565
566/**
567 Push the list of map expression onto the Stack
568
569 @param Pointer Pointer to the list of map expression to be pushed.
570
571 @retval EFI_SUCCESS The value was pushed onto the stack.
572 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
573
574**/
575EFI_STATUS
576PushMapExpressionList (
577 IN VOID *Pointer
578 )
579{
580 EFI_HII_VALUE Data;
581
582 Data.Type = EFI_IFR_TYPE_NUM_SIZE_64;
583 Data.Value.u64 = (UINT64)(UINTN)Pointer;
584
585 return PushStack (
586 &mMapExpressionListStack,
587 &mMapExpressionListPointer,
588 &mMapExpressionListEnd,
589 &Data
590 );
591}
592
593/**
594 Pop the list of map expression from the Stack
595
596 @param Pointer Pointer to the list of map expression to be pop.
597
598 @retval EFI_SUCCESS The value was pushed onto the stack.
599 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
600
601**/
602EFI_STATUS
603PopMapExpressionList (
604 OUT VOID **Pointer
605 )
606{
607 EFI_STATUS Status;
608 EFI_HII_VALUE Data;
609
610 Status = PopStack (
611 mMapExpressionListStack,
612 &mMapExpressionListPointer,
613 &Data
614 );
615
616 *Pointer = (VOID *)(UINTN)Data.Value.u64;
617
618 return Status;
619}
620
621/**
622 Reset stack pointer to begin of the stack.
623
624**/
625VOID
626ResetScopeStack (
627 VOID
628 )
629{
630 mOpCodeScopeStackPointer = mOpCodeScopeStack;
631}
632
633/**
634 Push an Operand onto the Stack
635
636 @param Operand Operand to push.
637
638 @retval EFI_SUCCESS The value was pushed onto the stack.
639 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
640 stack.
641
642**/
643EFI_STATUS
644PushScope (
645 IN UINT8 Operand
646 )
647{
648 EFI_HII_VALUE Data;
649
650 Data.Type = EFI_IFR_TYPE_NUM_SIZE_8;
651 Data.Value.u8 = Operand;
652
653 return PushStack (
654 &mOpCodeScopeStack,
655 &mOpCodeScopeStackPointer,
656 &mOpCodeScopeStackEnd,
657 &Data
658 );
659}
660
661/**
662 Pop an Operand from the Stack
663
664 @param Operand Operand to pop.
665
666 @retval EFI_SUCCESS The value was pushed onto the stack.
667 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
668 stack.
669
670**/
671EFI_STATUS
672PopScope (
673 OUT UINT8 *Operand
674 )
675{
676 EFI_STATUS Status;
677 EFI_HII_VALUE Data;
678
679 Status = PopStack (
680 mOpCodeScopeStack,
681 &mOpCodeScopeStackPointer,
682 &Data
683 );
684
685 *Operand = Data.Value.u8;
686
687 return Status;
688}
689
690/**
691 Grow size of the stack for Expression Dependencies.
692
693 This is an internal function.
694
695 @param Stack On input: old stack; On output: new stack
696 @param StackPtr On input: old stack pointer; On output: new stack
697 pointer
698 @param StackEnd On input: old stack end; On output: new stack end
699
700 @retval EFI_SUCCESS Grow Dependency stack success.
701 @retval EFI_OUT_OF_RESOURCES No enough memory for stack space.
702
703**/
704EFI_STATUS
705GrowDependencyStack (
706 IN OUT HII_DEPENDENCY_EXPRESSION ***Stack,
707 IN OUT HII_DEPENDENCY_EXPRESSION ***StackPtr,
708 IN OUT HII_DEPENDENCY_EXPRESSION ***StackEnd
709 )
710{
711 UINTN Size;
712 HII_DEPENDENCY_EXPRESSION **NewStack;
713
714 Size = EXPRESSION_STACK_SIZE_INCREMENT;
715 if (*StackPtr != NULL) {
716 Size = Size + (*StackEnd - *Stack);
717 }
718
719 NewStack = AllocatePool (Size * sizeof (HII_DEPENDENCY_EXPRESSION *));
720 if (NewStack == NULL) {
721 return EFI_OUT_OF_RESOURCES;
722 }
723
724 if (*StackPtr != NULL) {
725 //
726 // Copy from Old Stack to the New Stack
727 //
728 CopyMem (
729 NewStack,
730 *Stack,
731 (*StackEnd - *Stack) * sizeof (HII_DEPENDENCY_EXPRESSION *)
732 );
733
734 //
735 // Free The Old Stack
736 //
737 FreePool (*Stack);
738 }
739
740 //
741 // Make the Stack pointer point to the old data in the new stack
742 //
743 *StackPtr = NewStack + (*StackPtr - *Stack);
744 *Stack = NewStack;
745 *StackEnd = NewStack + Size;
746
747 return EFI_SUCCESS;
748}
749
750/**
751 Push an element onto the Stack for Expression Dependencies.
752
753 @param Stack On input: old stack; On output: new stack
754 @param StackPtr On input: old stack pointer; On output: new stack
755 pointer
756 @param StackEnd On input: old stack end; On output: new stack end
757 @param Data Data to push.
758
759 @retval EFI_SUCCESS Push stack success.
760
761**/
762EFI_STATUS
763PushDependencyStack (
764 IN OUT HII_DEPENDENCY_EXPRESSION ***Stack,
765 IN OUT HII_DEPENDENCY_EXPRESSION ***StackPtr,
766 IN OUT HII_DEPENDENCY_EXPRESSION ***StackEnd,
767 IN HII_DEPENDENCY_EXPRESSION **Data
768 )
769{
770 EFI_STATUS Status;
771
772 //
773 // Check for a stack overflow condition
774 //
775 if (*StackPtr >= *StackEnd) {
776 //
777 // Grow the stack
778 //
779 Status = GrowDependencyStack (Stack, StackPtr, StackEnd);
780 if (EFI_ERROR (Status)) {
781 return Status;
782 }
783 }
784
785 //
786 // Push the item onto the stack
787 //
788 CopyMem (*StackPtr, Data, sizeof (HII_DEPENDENCY_EXPRESSION *));
789 *StackPtr = *StackPtr + 1;
790
791 return EFI_SUCCESS;
792}
793
794/**
795 Pop the Expression Dependency options from the Stack
796
797 @param Stack On input: old stack; On output: new stack
798 @param StackPtr On input: old stack pointer; On output: new stack
799 pointer
800 @param Data Data to push.
801
802 @retval EFI_SUCCESS The value was pushed onto the stack.
803 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
804
805**/
806EFI_STATUS
807PopDependencyStack (
808 IN HII_DEPENDENCY_EXPRESSION **Stack,
809 IN OUT HII_DEPENDENCY_EXPRESSION ***StackPtr,
810 OUT HII_DEPENDENCY_EXPRESSION **Data
811 )
812{
813 //
814 // Check for a stack underflow condition
815 //
816 if (*StackPtr == Stack) {
817 return EFI_ACCESS_DENIED;
818 }
819
820 //
821 // Pop the item off the stack
822 //
823 *StackPtr = *StackPtr - 1;
824 CopyMem (Data, *StackPtr, sizeof (HII_DEPENDENCY_EXPRESSION *));
825 return EFI_SUCCESS;
826}
827
828/**
829 Push the list of Expression Dependencies onto the Stack
830
831 @param Pointer Pointer to the list of map expression to be pushed.
832
833 @retval EFI_SUCCESS The value was pushed onto the stack.
834 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
835
836**/
837EFI_STATUS
838PushDependencyExpDes (
839 IN HII_DEPENDENCY_EXPRESSION **Pointer
840 )
841{
842 return PushDependencyStack (
843 &mExpressionDependencyStack,
844 &mExpressionDependencyPointer,
845 &mExpressionDependencyEnd,
846 Pointer
847 );
848}
849
850/**
851 Pop the list of Expression Dependencies from the Stack
852
853 @param Pointer Pointer to the list of map expression to be pop.
854
855 @retval EFI_SUCCESS The value was pushed onto the stack.
856 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
857
858**/
859EFI_STATUS
860PopDependencyExpDes (
861 OUT HII_DEPENDENCY_EXPRESSION **Pointer
862 )
863{
864 return PopDependencyStack (
865 mExpressionDependencyStack,
866 &mExpressionDependencyPointer,
867 Pointer
868 );
869}
870
871/**
872 Retrieve dependencies within an expression. These dependencies can express how
873 this expression will be evaluated.
874
875 @param[in,out] Expression Expression to retrieve dependencies.
876
877 @retval EFI_SUCCESS The dependencies were successfully retrieved.
878 @retval EFI_OUT_OF_RESOURCES There is not enough system memory.
879
880**/
881EFI_STATUS
882GetHiiExpressionDependency (
883 IN OUT HII_EXPRESSION *Expression
884 )
885{
886 EFI_STATUS Status;
887 LIST_ENTRY *Link;
888 HII_EXPRESSION_OPCODE *ExpressionOpCode;
889 HII_DEPENDENCY_EXPRESSION *DepExpressionOpCode;
890 LIST_ENTRY *SubExpressionLink;
891 HII_EXPRESSION *SubExpression;
892 UINT8 MapPairCount;
893
894 Link = GetFirstNode (&Expression->OpCodeListHead);
895 while (!IsNull (&Expression->OpCodeListHead, Link)) {
896 ExpressionOpCode = HII_EXPRESSION_OPCODE_FROM_LINK (Link);
897 Link = GetNextNode (&Expression->OpCodeListHead, Link);
898 Status = EFI_SUCCESS;
899
900 DepExpressionOpCode = (HII_DEPENDENCY_EXPRESSION *)AllocateZeroPool (sizeof (HII_DEPENDENCY_EXPRESSION));
901 if (DepExpressionOpCode == NULL) {
902 return EFI_OUT_OF_RESOURCES;
903 }
904
905 switch (ExpressionOpCode->Operand) {
906 //
907 // Constant
908 //
909 case EFI_IFR_FALSE_OP:
910 case EFI_IFR_ONE_OP:
911 case EFI_IFR_ONES_OP:
912 case EFI_IFR_TRUE_OP:
913 case EFI_IFR_UINT8_OP:
914 case EFI_IFR_UINT16_OP:
915 case EFI_IFR_UINT32_OP:
916 case EFI_IFR_UINT64_OP:
917 case EFI_IFR_UNDEFINED_OP:
918 case EFI_IFR_VERSION_OP:
919 case EFI_IFR_ZERO_OP:
920 DepExpressionOpCode->ConstantExp.Operand = ExpressionOpCode->Operand;
921 CopyMem (&DepExpressionOpCode->ConstantExp.Value, &ExpressionOpCode->ExtraData.Value, sizeof (EFI_HII_VALUE));
922 PushDependencyExpDes (&DepExpressionOpCode);
923 break;
924
925 //
926 // Built-in functions
927 //
928 case EFI_IFR_DUP_OP:
929 DepExpressionOpCode->DupExp.Operand = ExpressionOpCode->Operand;
930 PushDependencyExpDes (&DepExpressionOpCode);
931 break;
932
933 case EFI_IFR_EQ_ID_VAL_OP:
934 DepExpressionOpCode->EqIdValExp.Operand = ExpressionOpCode->Operand;
935 CopyMem (&DepExpressionOpCode->EqIdValExp.QuestionId, &ExpressionOpCode->ExtraData.EqIdValData.QuestionId, sizeof (EFI_QUESTION_ID));
936 CopyMem (&DepExpressionOpCode->EqIdValExp.Value, &ExpressionOpCode->ExtraData.EqIdValData.Value, sizeof (EFI_HII_VALUE));
937 PushDependencyExpDes (&DepExpressionOpCode);
938 break;
939
940 case EFI_IFR_EQ_ID_ID_OP:
941 DepExpressionOpCode->EqIdIdExp.Operand = ExpressionOpCode->Operand;
942 CopyMem (&DepExpressionOpCode->EqIdIdExp.QuestionId1, &ExpressionOpCode->ExtraData.EqIdIdData.QuestionId1, sizeof (EFI_QUESTION_ID));
943 CopyMem (&DepExpressionOpCode->EqIdIdExp.QuestionId2, &ExpressionOpCode->ExtraData.EqIdIdData.QuestionId2, sizeof (EFI_QUESTION_ID));
944 PushDependencyExpDes (&DepExpressionOpCode);
945 break;
946
947 case EFI_IFR_EQ_ID_VAL_LIST_OP:
948 DepExpressionOpCode->EqIdListExp.Operand = ExpressionOpCode->Operand;
949 DepExpressionOpCode->EqIdListExp.ListLength = ExpressionOpCode->ExtraData.EqIdListData.ListLength;
950 CopyMem (&DepExpressionOpCode->EqIdListExp.QuestionId, &ExpressionOpCode->ExtraData.EqIdListData.QuestionId, sizeof (EFI_QUESTION_ID));
951 PushDependencyExpDes (&DepExpressionOpCode);
952 DepExpressionOpCode->EqIdListExp.ValueList = AllocateCopyPool (
953 DepExpressionOpCode->EqIdListExp.ListLength * sizeof (UINT16),
954 ExpressionOpCode->ExtraData.EqIdListData.ValueList
955 );
956 if (DepExpressionOpCode->EqIdListExp.ValueList == NULL) {
957 return EFI_OUT_OF_RESOURCES;
958 }
959
960 PushDependencyExpDes (&DepExpressionOpCode);
961 break;
962
963 case EFI_IFR_GET_OP:
964 DepExpressionOpCode->GetExp.Operand = ExpressionOpCode->Operand;
965 DepExpressionOpCode->GetExp.VarStorage = ExpressionOpCode->ExtraData.GetSetData.VarStorage;
966 CopyMem (&DepExpressionOpCode->GetExp.VarStoreInfo.VarName, &ExpressionOpCode->ExtraData.GetSetData.VarStoreInfo.VarName, sizeof (EFI_STRING_ID));
967 CopyMem (&DepExpressionOpCode->GetExp.VarStoreInfo.VarOffset, &ExpressionOpCode->ExtraData.GetSetData.VarStoreInfo.VarOffset, sizeof (UINT16));
968 DepExpressionOpCode->GetExp.VarStoreInfo = ExpressionOpCode->ExtraData.GetSetData.VarStoreInfo;
969 if (ExpressionOpCode->ExtraData.GetSetData.ValueName != NULL) {
970 DepExpressionOpCode->GetExp.ValueName = (CHAR16 *)AllocateCopyPool (sizeof (ExpressionOpCode->ExtraData.GetSetData.ValueName), ExpressionOpCode->ExtraData.GetSetData.ValueName);
971 if (DepExpressionOpCode->GetExp.ValueName == NULL) {
972 return EFI_OUT_OF_RESOURCES;
973 }
974 }
975
976 DepExpressionOpCode->GetExp.ValueType = ExpressionOpCode->ExtraData.GetSetData.ValueType;
977 DepExpressionOpCode->GetExp.ValueWidth = ExpressionOpCode->ExtraData.GetSetData.ValueWidth;
978 PushDependencyExpDes (&DepExpressionOpCode);
979 break;
980
981 case EFI_IFR_QUESTION_REF1_OP:
982 DepExpressionOpCode->QuestionRef1Exp.Operand = ExpressionOpCode->Operand;
983 CopyMem (&DepExpressionOpCode->QuestionRef1Exp.QuestionId, &ExpressionOpCode->ExtraData.QuestionRef1Data.QuestionId, sizeof (EFI_QUESTION_ID));
984 PushDependencyExpDes (&DepExpressionOpCode);
985 break;
986
987 case EFI_IFR_RULE_REF_OP:
988 DepExpressionOpCode->RuleRefExp.Operand = ExpressionOpCode->Operand;
989 DepExpressionOpCode->RuleRefExp.RuleId = ExpressionOpCode->ExtraData.RuleId;
990 PushDependencyExpDes (&DepExpressionOpCode);
991 break;
992
993 case EFI_IFR_STRING_REF1_OP:
994 DepExpressionOpCode->StringRef1Exp.Operand = ExpressionOpCode->Operand;
995 CopyMem (&DepExpressionOpCode->StringRef1Exp.Value.Value.string, &ExpressionOpCode->ExtraData.Value.Value.string, sizeof (EFI_STRING_ID));
996 PushDependencyExpDes (&DepExpressionOpCode);
997 break;
998
999 case EFI_IFR_THIS_OP:
1000 DepExpressionOpCode->ThisExp.Operand = ExpressionOpCode->Operand;
1001 CopyMem (&DepExpressionOpCode->ThisExp.QuestionId, &ExpressionOpCode->ExtraData.QuestionRef1Data.QuestionId, sizeof (EFI_QUESTION_ID));
1002 PushDependencyExpDes (&DepExpressionOpCode);
1003 break;
1004
1005 case EFI_IFR_SECURITY_OP:
1006 DepExpressionOpCode->SecurityExp.Operand = ExpressionOpCode->Operand;
1007 CopyMem (&DepExpressionOpCode->SecurityExp.Permissions, &ExpressionOpCode->ExtraData.Guid, sizeof (EFI_GUID));
1008 PushDependencyExpDes (&DepExpressionOpCode);
1009 break;
1010
1011 //
1012 // unary-op
1013 //
1014 case EFI_IFR_LENGTH_OP:
1015 DepExpressionOpCode->LengthExp.Operand = ExpressionOpCode->Operand;
1016 PopDependencyExpDes (&DepExpressionOpCode->LengthExp.SubExpression);
1017 PushDependencyExpDes (&DepExpressionOpCode);
1018 break;
1019
1020 case EFI_IFR_NOT_OP:
1021 DepExpressionOpCode->NotExp.Operand = ExpressionOpCode->Operand;
1022 PopDependencyExpDes (&DepExpressionOpCode->NotExp.SubExpression);
1023 PushDependencyExpDes (&DepExpressionOpCode);
1024 break;
1025
1026 case EFI_IFR_BITWISE_NOT_OP:
1027 DepExpressionOpCode->BitWiseNotExp.Operand = ExpressionOpCode->Operand;
1028 PopDependencyExpDes (&DepExpressionOpCode->BitWiseNotExp.SubExpression);
1029 PushDependencyExpDes (&DepExpressionOpCode);
1030 break;
1031
1032 case EFI_IFR_QUESTION_REF2_OP:
1033 DepExpressionOpCode->QuestionRef2Exp.Operand = ExpressionOpCode->Operand;
1034 PopDependencyExpDes (&DepExpressionOpCode->QuestionRef2Exp.SubExpression);
1035 PushDependencyExpDes (&DepExpressionOpCode);
1036 break;
1037
1038 case EFI_IFR_QUESTION_REF3_OP:
1039 DepExpressionOpCode->QuestionRef3Exp.Operand = ExpressionOpCode->Operand;
1040 CopyMem (&DepExpressionOpCode->QuestionRef3Exp.DevicePath, &ExpressionOpCode->ExtraData.QuestionRef3Data.DevicePath, sizeof (EFI_DEVICE_PATH));
1041 CopyMem (&DepExpressionOpCode->QuestionRef3Exp.Guid, &ExpressionOpCode->ExtraData.QuestionRef3Data.Guid, sizeof (EFI_GUID));
1042 PopDependencyExpDes (&DepExpressionOpCode->QuestionRef3Exp.SubExpression);
1043 PushDependencyExpDes (&DepExpressionOpCode);
1044 break;
1045
1046 case EFI_IFR_SET_OP:
1047 DepExpressionOpCode->SetExp.Operand = ExpressionOpCode->Operand;
1048 DepExpressionOpCode->SetExp.VarStorage = ExpressionOpCode->ExtraData.GetSetData.VarStorage;
1049 CopyMem (&DepExpressionOpCode->SetExp.VarStoreInfo.VarName, &ExpressionOpCode->ExtraData.GetSetData.VarStoreInfo.VarName, sizeof (EFI_STRING_ID));
1050 CopyMem (&DepExpressionOpCode->SetExp.VarStoreInfo.VarOffset, &ExpressionOpCode->ExtraData.GetSetData.VarStoreInfo.VarOffset, sizeof (UINT16));
1051 DepExpressionOpCode->SetExp.VarStoreInfo = ExpressionOpCode->ExtraData.GetSetData.VarStoreInfo;
1052 if (ExpressionOpCode->ExtraData.GetSetData.ValueName != NULL) {
1053 DepExpressionOpCode->SetExp.ValueName = (CHAR16 *)AllocateCopyPool (sizeof (ExpressionOpCode->ExtraData.GetSetData.ValueName), ExpressionOpCode->ExtraData.GetSetData.ValueName);
1054 if (DepExpressionOpCode->SetExp.ValueName == NULL) {
1055 return EFI_OUT_OF_RESOURCES;
1056 }
1057 }
1058
1059 DepExpressionOpCode->SetExp.ValueType = ExpressionOpCode->ExtraData.GetSetData.ValueType;
1060 DepExpressionOpCode->SetExp.ValueWidth = ExpressionOpCode->ExtraData.GetSetData.ValueWidth;
1061 PopDependencyExpDes (&DepExpressionOpCode->SetExp.SubExpression);
1062 PushDependencyExpDes (&DepExpressionOpCode);
1063 break;
1064
1065 case EFI_IFR_STRING_REF2_OP:
1066 DepExpressionOpCode->StringRef2Exp.Operand = ExpressionOpCode->Operand;
1067 PopDependencyExpDes (&DepExpressionOpCode->StringRef2Exp.SubExpression);
1068 PushDependencyExpDes (&DepExpressionOpCode);
1069 break;
1070
1071 case EFI_IFR_TO_BOOLEAN_OP:
1072 DepExpressionOpCode->ToBooleanExp.Operand = ExpressionOpCode->Operand;
1073 PopDependencyExpDes (&DepExpressionOpCode->ToBooleanExp.SubExpression);
1074 PushDependencyExpDes (&DepExpressionOpCode);
1075 break;
1076
1077 case EFI_IFR_TO_STRING_OP:
1078 DepExpressionOpCode->ToStringExp.Operand = ExpressionOpCode->Operand;
1079 DepExpressionOpCode->ToStringExp.Format = ExpressionOpCode->ExtraData.Format;
1080 PopDependencyExpDes (&DepExpressionOpCode->ToStringExp.SubExpression);
1081 PushDependencyExpDes (&DepExpressionOpCode);
1082 break;
1083
1084 case EFI_IFR_TO_UINT_OP:
1085 DepExpressionOpCode->ToUintExp.Operand = ExpressionOpCode->Operand;
1086 PopDependencyExpDes (&DepExpressionOpCode->ToUintExp.SubExpression);
1087 PushDependencyExpDes (&DepExpressionOpCode);
1088 break;
1089
1090 case EFI_IFR_TO_LOWER_OP:
1091 DepExpressionOpCode->ToLowerExp.Operand = ExpressionOpCode->Operand;
1092 PopDependencyExpDes (&DepExpressionOpCode->ToLowerExp.SubExpression);
1093 PushDependencyExpDes (&DepExpressionOpCode);
1094 break;
1095
1096 case EFI_IFR_TO_UPPER_OP:
1097 DepExpressionOpCode->ToUpperExp.Operand = ExpressionOpCode->Operand;
1098 PopDependencyExpDes (&DepExpressionOpCode->ToUpperExp.SubExpression);
1099 PushDependencyExpDes (&DepExpressionOpCode);
1100 break;
1101
1102 //
1103 // binary-op
1104 //
1105 case EFI_IFR_ADD_OP:
1106 DepExpressionOpCode->AddExp.Operand = ExpressionOpCode->Operand;
1107 PopDependencyExpDes (&DepExpressionOpCode->AddExp.LeftHandExp);
1108 PopDependencyExpDes (&DepExpressionOpCode->AddExp.RightHandExp);
1109 PushDependencyExpDes (&DepExpressionOpCode);
1110 break;
1111
1112 case EFI_IFR_AND_OP:
1113 DepExpressionOpCode->AndExp.Operand = ExpressionOpCode->Operand;
1114 PopDependencyExpDes (&DepExpressionOpCode->AndExp.SubExpression1);
1115 PopDependencyExpDes (&DepExpressionOpCode->AndExp.SubExpression2);
1116 PushDependencyExpDes (&DepExpressionOpCode);
1117 break;
1118
1119 case EFI_IFR_BITWISE_AND_OP:
1120 DepExpressionOpCode->BitwiseAndExp.Operand = ExpressionOpCode->Operand;
1121 PopDependencyExpDes (&DepExpressionOpCode->BitwiseAndExp.SubExpression1);
1122 PopDependencyExpDes (&DepExpressionOpCode->BitwiseAndExp.SubExpression2);
1123 PushDependencyExpDes (&DepExpressionOpCode);
1124 break;
1125
1126 case EFI_IFR_BITWISE_OR_OP:
1127 DepExpressionOpCode->BitwiseOrExp.Operand = ExpressionOpCode->Operand;
1128 PopDependencyExpDes (&DepExpressionOpCode->BitwiseOrExp.SubExpression1);
1129 PopDependencyExpDes (&DepExpressionOpCode->BitwiseOrExp.SubExpression2);
1130 PushDependencyExpDes (&DepExpressionOpCode);
1131 break;
1132
1133 case EFI_IFR_CATENATE_OP:
1134 DepExpressionOpCode->CatenateExp.Operand = ExpressionOpCode->Operand;
1135 PopDependencyExpDes (&DepExpressionOpCode->CatenateExp.LeftStringExp);
1136 PopDependencyExpDes (&DepExpressionOpCode->CatenateExp.RightStringExp);
1137 PushDependencyExpDes (&DepExpressionOpCode);
1138 break;
1139
1140 case EFI_IFR_DIVIDE_OP:
1141 DepExpressionOpCode->DivExp.Operand = ExpressionOpCode->Operand;
1142 PopDependencyExpDes (&DepExpressionOpCode->DivExp.LeftHandExp);
1143 PopDependencyExpDes (&DepExpressionOpCode->DivExp.RightHandExp);
1144 PushDependencyExpDes (&DepExpressionOpCode);
1145 break;
1146
1147 case EFI_IFR_EQUAL_OP:
1148 DepExpressionOpCode->EqualExp.Operand = ExpressionOpCode->Operand;
1149 PopDependencyExpDes (&DepExpressionOpCode->EqualExp.SubExpression1);
1150 PopDependencyExpDes (&DepExpressionOpCode->EqualExp.SubExpression2);
1151 PushDependencyExpDes (&DepExpressionOpCode);
1152 break;
1153
1154 case EFI_IFR_GREATER_EQUAL_OP:
1155 DepExpressionOpCode->GreaterEqualExp.Operand = ExpressionOpCode->Operand;
1156 PopDependencyExpDes (&DepExpressionOpCode->GreaterEqualExp.LeftHandExp);
1157 PopDependencyExpDes (&DepExpressionOpCode->GreaterEqualExp.RightHandExp);
1158 PushDependencyExpDes (&DepExpressionOpCode);
1159 break;
1160
1161 case EFI_IFR_GREATER_THAN_OP:
1162 DepExpressionOpCode->GreaterThanExp.Operand = ExpressionOpCode->Operand;
1163 PopDependencyExpDes (&DepExpressionOpCode->GreaterThanExp.LeftHandExp);
1164 PopDependencyExpDes (&DepExpressionOpCode->GreaterThanExp.RightHandExp);
1165 PushDependencyExpDes (&DepExpressionOpCode);
1166 break;
1167
1168 case EFI_IFR_LESS_EQUAL_OP:
1169 DepExpressionOpCode->LessEqualExp.Operand = ExpressionOpCode->Operand;
1170 PopDependencyExpDes (&DepExpressionOpCode->LessEqualExp.LeftHandExp);
1171 PopDependencyExpDes (&DepExpressionOpCode->LessEqualExp.RightHandExp);
1172 PushDependencyExpDes (&DepExpressionOpCode);
1173 break;
1174
1175 case EFI_IFR_LESS_THAN_OP:
1176 DepExpressionOpCode->LessThanExp.Operand = ExpressionOpCode->Operand;
1177 PopDependencyExpDes (&DepExpressionOpCode->LessThanExp.LeftHandExp);
1178 PopDependencyExpDes (&DepExpressionOpCode->LessThanExp.RightHandExp);
1179 PushDependencyExpDes (&DepExpressionOpCode);
1180 break;
1181
1182 case EFI_IFR_MATCH_OP:
1183 DepExpressionOpCode->MatchExp.Operand = ExpressionOpCode->Operand;
1184 PopDependencyExpDes (&DepExpressionOpCode->MatchExp.PatternExp);
1185 PopDependencyExpDes (&DepExpressionOpCode->MatchExp.StringExp);
1186 PushDependencyExpDes (&DepExpressionOpCode);
1187 break;
1188
1189 case EFI_IFR_MATCH2_OP:
1190 DepExpressionOpCode->Match2Exp.Operand = ExpressionOpCode->Operand;
1191 CopyMem (&DepExpressionOpCode->Match2Exp.SyntaxType, &ExpressionOpCode->ExtraData.Guid, sizeof (EFI_GUID));
1192 PopDependencyExpDes (&DepExpressionOpCode->Match2Exp.PatternExp);
1193 PopDependencyExpDes (&DepExpressionOpCode->Match2Exp.StringExp);
1194 PushDependencyExpDes (&DepExpressionOpCode);
1195 break;
1196
1197 case EFI_IFR_MODULO_OP:
1198 DepExpressionOpCode->ModExp.Operand = ExpressionOpCode->Operand;
1199 PopDependencyExpDes (&DepExpressionOpCode->ModExp.LeftHandExp);
1200 PopDependencyExpDes (&DepExpressionOpCode->ModExp.RightHandExp);
1201 PushDependencyExpDes (&DepExpressionOpCode);
1202 break;
1203
1204 case EFI_IFR_MULTIPLY_OP:
1205 DepExpressionOpCode->MultExp.Operand = ExpressionOpCode->Operand;
1206 PopDependencyExpDes (&DepExpressionOpCode->MultExp.LeftHandExp);
1207 PopDependencyExpDes (&DepExpressionOpCode->MultExp.RightHandExp);
1208 PushDependencyExpDes (&DepExpressionOpCode);
1209 break;
1210
1211 case EFI_IFR_NOT_EQUAL_OP:
1212 DepExpressionOpCode->NotEqualExp.Operand = ExpressionOpCode->Operand;
1213 PopDependencyExpDes (&DepExpressionOpCode->NotEqualExp.SubExpression1);
1214 PopDependencyExpDes (&DepExpressionOpCode->NotEqualExp.SubExpression2);
1215 PushDependencyExpDes (&DepExpressionOpCode);
1216 break;
1217
1218 case EFI_IFR_OR_OP:
1219 DepExpressionOpCode->OrExp.Operand = ExpressionOpCode->Operand;
1220 PopDependencyExpDes (&DepExpressionOpCode->OrExp.SubExpression1);
1221 PopDependencyExpDes (&DepExpressionOpCode->OrExp.SubExpression2);
1222 PushDependencyExpDes (&DepExpressionOpCode);
1223 break;
1224
1225 case EFI_IFR_SHIFT_LEFT_OP:
1226 DepExpressionOpCode->ShiftLeftExp.Operand = ExpressionOpCode->Operand;
1227 PopDependencyExpDes (&DepExpressionOpCode->ShiftLeftExp.LeftHandExp);
1228 PopDependencyExpDes (&DepExpressionOpCode->ShiftLeftExp.RightHandExp);
1229 PushDependencyExpDes (&DepExpressionOpCode);
1230 break;
1231
1232 case EFI_IFR_SHIFT_RIGHT_OP:
1233 DepExpressionOpCode->ShiftRightExp.Operand = ExpressionOpCode->Operand;
1234 PopDependencyExpDes (&DepExpressionOpCode->ShiftRightExp.LeftHandExp);
1235 PopDependencyExpDes (&DepExpressionOpCode->ShiftRightExp.RightHandExp);
1236 PushDependencyExpDes (&DepExpressionOpCode);
1237 break;
1238
1239 case EFI_IFR_SUBTRACT_OP:
1240 DepExpressionOpCode->SubtractExp.Operand = ExpressionOpCode->Operand;
1241 PopDependencyExpDes (&DepExpressionOpCode->SubtractExp.LeftHandExp);
1242 PopDependencyExpDes (&DepExpressionOpCode->SubtractExp.RightHandExp);
1243 PushDependencyExpDes (&DepExpressionOpCode);
1244 break;
1245
1246 //
1247 // ternary-op
1248 //
1249 case EFI_IFR_CONDITIONAL_OP:
1250 DepExpressionOpCode->ConditionalExp.Operand = ExpressionOpCode->Operand;
1251 PopDependencyExpDes (&DepExpressionOpCode->ConditionalExp.CondTrueValExp);
1252 PopDependencyExpDes (&DepExpressionOpCode->ConditionalExp.CondFalseValExp);
1253 PopDependencyExpDes (&DepExpressionOpCode->ConditionalExp.ConditionExp);
1254 PushDependencyExpDes (&DepExpressionOpCode);
1255 break;
1256
1257 case EFI_IFR_FIND_OP:
1258 DepExpressionOpCode->FindExp.Operand = ExpressionOpCode->Operand;
1259 PopDependencyExpDes (&DepExpressionOpCode->FindExp.StringToSearchExp);
1260 PopDependencyExpDes (&DepExpressionOpCode->FindExp.StringToCompWithExp);
1261 PopDependencyExpDes (&DepExpressionOpCode->FindExp.IndexExp);
1262 PushDependencyExpDes (&DepExpressionOpCode);
1263 break;
1264
1265 case EFI_IFR_MID_OP:
1266 DepExpressionOpCode->MidExp.Operand = ExpressionOpCode->Operand;
1267 PopDependencyExpDes (&DepExpressionOpCode->MidExp.StringOrBufferExp);
1268 PopDependencyExpDes (&DepExpressionOpCode->MidExp.IndexExp);
1269 PopDependencyExpDes (&DepExpressionOpCode->MidExp.LengthExp);
1270 PushDependencyExpDes (&DepExpressionOpCode);
1271 break;
1272
1273 case EFI_IFR_TOKEN_OP:
1274 DepExpressionOpCode->TokenExp.Operand = ExpressionOpCode->Operand;
1275 PopDependencyExpDes (&DepExpressionOpCode->TokenExp.StringToSearchExp);
1276 PopDependencyExpDes (&DepExpressionOpCode->TokenExp.DelimiterExp);
1277 PopDependencyExpDes (&DepExpressionOpCode->TokenExp.IndexExp);
1278 PushDependencyExpDes (&DepExpressionOpCode);
1279 break;
1280
1281 case EFI_IFR_SPAN_OP:
1282 DepExpressionOpCode->SpanExp.Operand = ExpressionOpCode->Operand;
1283 PopDependencyExpDes (&DepExpressionOpCode->SpanExp.StringToSearchExp);
1284 PopDependencyExpDes (&DepExpressionOpCode->SpanExp.CharsetExp);
1285 PopDependencyExpDes (&DepExpressionOpCode->SpanExp.IndexExp);
1286 PushDependencyExpDes (&DepExpressionOpCode);
1287 break;
1288
1289 //
1290 // Map
1291 //
1292 case EFI_IFR_MAP_OP:
1293 //
1294 // Go through map expression list.
1295 //
1296 DepExpressionOpCode->MapExp.Operand = ExpressionOpCode->Operand;
1297 MapPairCount = 0;
1298 SubExpressionLink = GetFirstNode (&ExpressionOpCode->MapExpressionList);
1299 while (!IsNull (&ExpressionOpCode->MapExpressionList, SubExpressionLink)) {
1300 MapPairCount++;
1301 SubExpressionLink = GetNextNode (&ExpressionOpCode->MapExpressionList, SubExpressionLink);
1302 if (IsNull (&ExpressionOpCode->MapExpressionList, SubExpressionLink)) {
1303 Status = EFI_INVALID_PARAMETER;
1304 goto Done;
1305 }
1306
1307 //
1308 // Goto the first expression on next pair.
1309 //
1310 SubExpressionLink = GetNextNode (&ExpressionOpCode->MapExpressionList, SubExpressionLink);
1311 }
1312
1313 DepExpressionOpCode->MapExp.ExpPair = (HII_DEPENDENCY_EXPRESSION_PAIR *)AllocateZeroPool (
1314 MapPairCount * sizeof (HII_DEPENDENCY_EXPRESSION_PAIR)
1315 );
1316 if (DepExpressionOpCode->MapExp.ExpPair == NULL) {
1317 Status = EFI_OUT_OF_RESOURCES;
1318 goto Done;
1319 }
1320
1321 DepExpressionOpCode->MapExp.ExpPairNo = MapPairCount;
1322 MapPairCount = 0;
1323 PopDependencyExpDes (&DepExpressionOpCode->MapExp.SubExp);
1324
1325 //
1326 // Go through map expression list.
1327 //
1328 SubExpressionLink = GetFirstNode (&ExpressionOpCode->MapExpressionList);
1329 while (!IsNull (&ExpressionOpCode->MapExpressionList, SubExpressionLink)) {
1330 SubExpression = HII_EXPRESSION_FROM_LINK (SubExpressionLink);
1331 //
1332 // Get the first expression description in this pair.
1333 //
1334 GetHiiExpressionDependency (SubExpression);
1335 DepExpressionOpCode->MapExp.ExpPair[MapPairCount].MatchExp = SubExpression->RootDependencyExp;
1336
1337 //
1338 // Get the second expression description in this pair.
1339 //
1340 SubExpressionLink = GetNextNode (&ExpressionOpCode->MapExpressionList, SubExpressionLink);
1341 SubExpression = HII_EXPRESSION_FROM_LINK (SubExpressionLink);
1342 GetHiiExpressionDependency (SubExpression);
1343 DepExpressionOpCode->MapExp.ExpPair[MapPairCount].ReturnExp = SubExpression->RootDependencyExp;
1344 //
1345 // Goto the first expression on next pair.
1346 //
1347 SubExpressionLink = GetNextNode (&ExpressionOpCode->MapExpressionList, SubExpressionLink);
1348 MapPairCount++;
1349 }
1350
1351 PushDependencyExpDes (&DepExpressionOpCode);
1352 break;
1353
1354 default:
1355 break;
1356 }
1357 }
1358
1359 PopDependencyExpDes (&Expression->RootDependencyExp);
1360
1361Done:
1362 return Status;
1363}
1364
1365/**
1366 Return the result of the expression list. Check the expression list and
1367 return the highest priority express result.
1368 Priority: DisableIf > SuppressIf > GrayOutIf > FALSE
1369
1370 @param[in] ExpList The input expression list.
1371 @param[in] Evaluate Whether need to evaluate the expression first.
1372 @param[in] FormSet FormSet associated with this expression.
1373 @param[in] Form Form associated with this expression.
1374
1375 @retval EXPRESS_RESULT Return the higher priority express result.
1376 DisableIf > SuppressIf > GrayOutIf > FALSE
1377
1378**/
1379EXPRESS_RESULT
1380EvaluateExpressionList (
1381 IN HII_EXPRESSION_LIST *ExpList,
1382 IN BOOLEAN Evaluate,
1383 IN HII_FORMSET *FormSet OPTIONAL,
1384 IN HII_FORM *Form OPTIONAL
1385 )
1386{
1387 UINTN Index;
1388 EXPRESS_RESULT ReturnVal;
1389 EXPRESS_RESULT CompareOne;
1390 EFI_STATUS Status;
1391
1392 if (ExpList == NULL) {
1393 return ExpressFalse;
1394 }
1395
1396 ASSERT (ExpList->Signature == HII_EXPRESSION_LIST_SIGNATURE);
1397 Index = 0;
1398
1399 //
1400 // Check whether need to evaluate the expression first.
1401 //
1402 if (Evaluate) {
1403 while (ExpList->Count > Index) {
1404 Status = EvaluateHiiExpression (FormSet, Form, ExpList->Expression[Index++]);
1405 if (EFI_ERROR (Status)) {
1406 return ExpressFalse;
1407 }
1408 }
1409 }
1410
1411 //
1412 // Run the list of expressions.
1413 //
1414 ReturnVal = ExpressFalse;
1415 for (Index = 0; Index < ExpList->Count; Index++) {
1416 if (IsHiiValueTrue (&ExpList->Expression[Index]->Result)) {
1417 switch (ExpList->Expression[Index]->Type) {
1418 case EFI_HII_EXPRESSION_SUPPRESS_IF:
1419 CompareOne = ExpressSuppress;
1420 break;
1421
1422 case EFI_HII_EXPRESSION_GRAY_OUT_IF:
1423 CompareOne = ExpressGrayOut;
1424 break;
1425
1426 case EFI_HII_EXPRESSION_DISABLE_IF:
1427 CompareOne = ExpressDisable;
1428 break;
1429
1430 default:
1431 return ExpressFalse;
1432 }
1433
1434 ReturnVal = ReturnVal < CompareOne ? CompareOne : ReturnVal;
1435 }
1436 }
1437
1438 return ReturnVal;
1439}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette