summaryrefslogtreecommitdiffstats
path: root/RedfishPkg/Library/HiiUtilityLib/HiiExpression.c
diff options
context:
space:
mode:
Diffstat (limited to 'RedfishPkg/Library/HiiUtilityLib/HiiExpression.c')
-rw-r--r--RedfishPkg/Library/HiiUtilityLib/HiiExpression.c1439
1 files changed, 1439 insertions, 0 deletions
diff --git a/RedfishPkg/Library/HiiUtilityLib/HiiExpression.c b/RedfishPkg/Library/HiiUtilityLib/HiiExpression.c
new file mode 100644
index 0000000000..c36c241642
--- /dev/null
+++ b/RedfishPkg/Library/HiiUtilityLib/HiiExpression.c
@@ -0,0 +1,1439 @@
+/** @file
+ The implementation of HII expression.
+
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
+ Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "HiiInternal.h"
+
+//
+// Global stack used to evaluate boolean expressions
+//
+EFI_HII_VALUE *mOpCodeScopeStack = NULL;
+EFI_HII_VALUE *mOpCodeScopeStackEnd = NULL;
+EFI_HII_VALUE *mOpCodeScopeStackPointer = NULL;
+
+//
+// Stack used for Suppressif/grayoutif/disableif expression list.
+//
+HII_EXPRESSION **mFormExpressionStack = NULL;
+HII_EXPRESSION **mFormExpressionEnd = NULL;
+HII_EXPRESSION **mFormExpressionPointer = NULL;
+
+HII_EXPRESSION **mStatementExpressionStack = NULL;
+HII_EXPRESSION **mStatementExpressionEnd = NULL;
+HII_EXPRESSION **mStatementExpressionPointer = NULL;
+
+HII_EXPRESSION **mOptionExpressionStack = NULL;
+HII_EXPRESSION **mOptionExpressionEnd = NULL;
+HII_EXPRESSION **mOptionExpressionPointer = NULL;
+
+//
+// Stack used for the sub expresion in map expression.
+//
+EFI_HII_VALUE *mCurrentExpressionStack = NULL;
+EFI_HII_VALUE *mCurrentExpressionEnd = NULL;
+EFI_HII_VALUE *mCurrentExpressionPointer = NULL;
+
+//
+// Stack used for the map expression list.
+//
+EFI_HII_VALUE *mMapExpressionListStack = NULL;
+EFI_HII_VALUE *mMapExpressionListEnd = NULL;
+EFI_HII_VALUE *mMapExpressionListPointer = NULL;
+
+//
+// Stack used for dependency expression.
+//
+HII_DEPENDENCY_EXPRESSION **mExpressionDependencyStack = NULL;
+HII_DEPENDENCY_EXPRESSION **mExpressionDependencyEnd = NULL;
+HII_DEPENDENCY_EXPRESSION **mExpressionDependencyPointer = NULL;
+
+/**
+ Grow size of the stack.
+
+ This is an internal function.
+
+ @param Stack On input: old stack; On output: new stack
+ @param StackPtr On input: old stack pointer; On output: new stack
+ pointer
+ @param StackEnd On input: old stack end; On output: new stack end
+
+ @retval EFI_SUCCESS Grow stack success.
+ @retval EFI_OUT_OF_RESOURCES No enough memory for stack space.
+
+**/
+EFI_STATUS
+GrowStack (
+ IN OUT EFI_HII_VALUE **Stack,
+ IN OUT EFI_HII_VALUE **StackPtr,
+ IN OUT EFI_HII_VALUE **StackEnd
+ )
+{
+ UINTN Size;
+ EFI_HII_VALUE *NewStack;
+
+ Size = EXPRESSION_STACK_SIZE_INCREMENT;
+ if (*StackPtr != NULL) {
+ Size = Size + (*StackEnd - *Stack);
+ }
+
+ NewStack = AllocatePool (Size * sizeof (EFI_HII_VALUE));
+ if (NewStack == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (*StackPtr != NULL) {
+ //
+ // Copy from Old Stack to the New Stack
+ //
+ CopyMem (
+ NewStack,
+ *Stack,
+ (*StackEnd - *Stack) * sizeof (EFI_HII_VALUE)
+ );
+
+ //
+ // Free The Old Stack
+ //
+ FreePool (*Stack);
+ }
+
+ //
+ // Make the Stack pointer point to the old data in the new stack
+ //
+ *StackPtr = NewStack + (*StackPtr - *Stack);
+ *Stack = NewStack;
+ *StackEnd = NewStack + Size;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Push an element onto the Boolean Stack.
+
+ @param Stack On input: old stack; On output: new stack
+ @param StackPtr On input: old stack pointer; On output: new stack
+ pointer
+ @param StackEnd On input: old stack end; On output: new stack end
+ @param Data Data to push.
+
+ @retval EFI_SUCCESS Push stack success.
+
+**/
+EFI_STATUS
+PushStack (
+ IN OUT EFI_HII_VALUE **Stack,
+ IN OUT EFI_HII_VALUE **StackPtr,
+ IN OUT EFI_HII_VALUE **StackEnd,
+ IN EFI_HII_VALUE *Data
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Check for a stack overflow condition
+ //
+ if (*StackPtr >= *StackEnd) {
+ //
+ // Grow the stack
+ //
+ Status = GrowStack (Stack, StackPtr, StackEnd);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ //
+ // Push the item onto the stack
+ //
+ CopyMem (*StackPtr, Data, sizeof (EFI_HII_VALUE));
+ if (Data->Type == EFI_IFR_TYPE_BUFFER) {
+ (*StackPtr)->Buffer = AllocateCopyPool (Data->BufferLen, Data->Buffer);
+ if ((*StackPtr)->Buffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+
+ *StackPtr = *StackPtr + 1;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Pop an element from the stack.
+
+ @param Stack On input: old stack
+ @param StackPtr On input: old stack pointer; On output: new stack pointer
+ @param Data Data to pop.
+
+ @retval EFI_SUCCESS The value was popped onto the stack.
+ @retval EFI_ACCESS_DENIED The pop operation underflowed the stack
+
+**/
+EFI_STATUS
+PopStack (
+ IN EFI_HII_VALUE *Stack,
+ IN OUT EFI_HII_VALUE **StackPtr,
+ OUT EFI_HII_VALUE *Data
+ )
+{
+ //
+ // Check for a stack underflow condition
+ //
+ if (*StackPtr == Stack) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ //
+ // Pop the item off the stack
+ //
+ *StackPtr = *StackPtr - 1;
+ CopyMem (Data, *StackPtr, sizeof (EFI_HII_VALUE));
+ return EFI_SUCCESS;
+}
+
+/**
+ Reset stack pointer to begin of the stack.
+
+**/
+VOID
+ResetCurrentExpressionStack (
+ VOID
+ )
+{
+ mCurrentExpressionPointer = mCurrentExpressionStack;
+ mFormExpressionPointer = mFormExpressionStack;
+ mStatementExpressionPointer = mStatementExpressionStack;
+ mOptionExpressionPointer = mOptionExpressionStack;
+}
+
+/**
+ Push current expression onto the Stack
+
+ @param Pointer Pointer to current expression.
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
+
+**/
+EFI_STATUS
+PushCurrentExpression (
+ IN VOID *Pointer
+ )
+{
+ EFI_HII_VALUE Data;
+
+ Data.Type = EFI_IFR_TYPE_NUM_SIZE_64;
+ Data.Value.u64 = (UINT64)(UINTN)Pointer;
+
+ return PushStack (
+ &mCurrentExpressionStack,
+ &mCurrentExpressionPointer,
+ &mCurrentExpressionEnd,
+ &Data
+ );
+}
+
+/**
+ Pop current expression from the Stack
+
+ @param Pointer Pointer to current expression to be pop.
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
+
+**/
+EFI_STATUS
+PopCurrentExpression (
+ OUT VOID **Pointer
+ )
+{
+ EFI_STATUS Status;
+ EFI_HII_VALUE Data;
+
+ Status = PopStack (
+ mCurrentExpressionStack,
+ &mCurrentExpressionPointer,
+ &Data
+ );
+
+ *Pointer = (VOID *)(UINTN)Data.Value.u64;
+
+ return Status;
+}
+
+/**
+ Reset stack pointer to begin of the stack.
+
+**/
+VOID
+ResetMapExpressionListStack (
+ VOID
+ )
+{
+ mMapExpressionListPointer = mMapExpressionListStack;
+}
+
+/**
+ Grow size of the stack.
+
+ This is an internal function.
+
+ @param Stack On input: old stack; On output: new stack
+ @param StackPtr On input: old stack pointer; On output: new stack
+ pointer
+ @param StackEnd On input: old stack end; On output: new stack end
+ @param MemberSize The stack member size.
+
+ @retval EFI_SUCCESS Grow stack success.
+ @retval EFI_OUT_OF_RESOURCES No enough memory for stack space.
+
+**/
+EFI_STATUS
+GrowConditionalStack (
+ IN OUT HII_EXPRESSION ***Stack,
+ IN OUT HII_EXPRESSION ***StackPtr,
+ IN OUT HII_EXPRESSION ***StackEnd,
+ IN UINTN MemberSize
+ )
+{
+ UINTN Size;
+ HII_EXPRESSION **NewStack;
+
+ Size = EXPRESSION_STACK_SIZE_INCREMENT;
+ if (*StackPtr != NULL) {
+ Size = Size + (*StackEnd - *Stack);
+ }
+
+ NewStack = AllocatePool (Size * MemberSize);
+ if (NewStack == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (*StackPtr != NULL) {
+ //
+ // Copy from Old Stack to the New Stack
+ //
+ CopyMem (
+ NewStack,
+ *Stack,
+ (*StackEnd - *Stack) * MemberSize
+ );
+
+ //
+ // Free The Old Stack
+ //
+ FreePool (*Stack);
+ }
+
+ //
+ // Make the Stack pointer point to the old data in the new stack
+ //
+ *StackPtr = NewStack + (*StackPtr - *Stack);
+ *Stack = NewStack;
+ *StackEnd = NewStack + Size;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Push an element onto the Stack.
+
+ @param Stack On input: old stack; On output: new stack
+ @param StackPtr On input: old stack pointer; On output: new stack
+ pointer
+ @param StackEnd On input: old stack end; On output: new stack end
+ @param Data Data to push.
+
+ @retval EFI_SUCCESS Push stack success.
+
+**/
+EFI_STATUS
+PushConditionalStack (
+ IN OUT HII_EXPRESSION ***Stack,
+ IN OUT HII_EXPRESSION ***StackPtr,
+ IN OUT HII_EXPRESSION ***StackEnd,
+ IN HII_EXPRESSION **Data
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Check for a stack overflow condition
+ //
+ if (*StackPtr >= *StackEnd) {
+ //
+ // Grow the stack
+ //
+ Status = GrowConditionalStack (Stack, StackPtr, StackEnd, sizeof (HII_EXPRESSION *));
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ //
+ // Push the item onto the stack
+ //
+ CopyMem (*StackPtr, Data, sizeof (HII_EXPRESSION *));
+ *StackPtr = *StackPtr + 1;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Pop an element from the stack.
+
+ @param Stack On input: old stack
+ @param StackPtr On input: old stack pointer; On output: new stack pointer
+ @param Data Data to pop.
+
+ @retval EFI_SUCCESS The value was popped onto the stack.
+ @retval EFI_ACCESS_DENIED The pop operation underflowed the stack
+
+**/
+EFI_STATUS
+PopConditionalStack (
+ IN HII_EXPRESSION **Stack,
+ IN OUT HII_EXPRESSION ***StackPtr,
+ OUT HII_EXPRESSION **Data
+ )
+{
+ //
+ // Check for a stack underflow condition
+ //
+ if (*StackPtr == Stack) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ //
+ // Pop the item off the stack
+ //
+ *StackPtr = *StackPtr - 1;
+ CopyMem (Data, *StackPtr, sizeof (HII_EXPRESSION *));
+ return EFI_SUCCESS;
+}
+
+/**
+ Get the expression list count.
+
+ @param Level Which type this expression belong to. Form,
+ statement or option?
+
+ @retval >=0 The expression count
+ @retval -1 Input parameter error.
+
+**/
+INTN
+GetConditionalExpressionCount (
+ IN EXPRESS_LEVEL Level
+ )
+{
+ switch (Level) {
+ case ExpressForm:
+ return mFormExpressionPointer - mFormExpressionStack;
+ case ExpressStatement:
+ return mStatementExpressionPointer - mStatementExpressionStack;
+ case ExpressOption:
+ return mOptionExpressionPointer - mOptionExpressionStack;
+ default:
+ ASSERT (FALSE);
+ return -1;
+ }
+}
+
+/**
+ Get the expression Buffer pointer.
+
+ @param Level Which type this expression belong to. Form,
+ statement or option?
+
+ @retval The start pointer of the expression buffer or NULL.
+
+**/
+HII_EXPRESSION **
+GetConditionalExpressionList (
+ IN EXPRESS_LEVEL Level
+ )
+{
+ switch (Level) {
+ case ExpressForm:
+ return mFormExpressionStack;
+ case ExpressStatement:
+ return mStatementExpressionStack;
+ case ExpressOption:
+ return mOptionExpressionStack;
+ default:
+ ASSERT (FALSE);
+ return NULL;
+ }
+}
+
+/**
+ Push the expression options onto the Stack.
+
+ @param Pointer Pointer to the current expression.
+ @param Level Which type this expression belong to. Form,
+ statement or option?
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
+
+**/
+EFI_STATUS
+PushConditionalExpression (
+ IN HII_EXPRESSION *Pointer,
+ IN EXPRESS_LEVEL Level
+ )
+{
+ switch (Level) {
+ case ExpressForm:
+ return PushConditionalStack (
+ &mFormExpressionStack,
+ &mFormExpressionPointer,
+ &mFormExpressionEnd,
+ &Pointer
+ );
+ case ExpressStatement:
+ return PushConditionalStack (
+ &mStatementExpressionStack,
+ &mStatementExpressionPointer,
+ &mStatementExpressionEnd,
+ &Pointer
+ );
+ case ExpressOption:
+ return PushConditionalStack (
+ &mOptionExpressionStack,
+ &mOptionExpressionPointer,
+ &mOptionExpressionEnd,
+ &Pointer
+ );
+ default:
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+}
+
+/**
+ Pop the expression options from the Stack
+
+ @param Level Which type this expression belong to. Form,
+ statement or option?
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
+
+**/
+EFI_STATUS
+PopConditionalExpression (
+ IN EXPRESS_LEVEL Level
+ )
+{
+ HII_EXPRESSION *Pointer;
+
+ switch (Level) {
+ case ExpressForm:
+ return PopConditionalStack (
+ mFormExpressionStack,
+ &mFormExpressionPointer,
+ &Pointer
+ );
+
+ case ExpressStatement:
+ return PopConditionalStack (
+ mStatementExpressionStack,
+ &mStatementExpressionPointer,
+ &Pointer
+ );
+
+ case ExpressOption:
+ return PopConditionalStack (
+ mOptionExpressionStack,
+ &mOptionExpressionPointer,
+ &Pointer
+ );
+
+ default:
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+}
+
+/**
+ Push the list of map expression onto the Stack
+
+ @param Pointer Pointer to the list of map expression to be pushed.
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
+
+**/
+EFI_STATUS
+PushMapExpressionList (
+ IN VOID *Pointer
+ )
+{
+ EFI_HII_VALUE Data;
+
+ Data.Type = EFI_IFR_TYPE_NUM_SIZE_64;
+ Data.Value.u64 = (UINT64)(UINTN)Pointer;
+
+ return PushStack (
+ &mMapExpressionListStack,
+ &mMapExpressionListPointer,
+ &mMapExpressionListEnd,
+ &Data
+ );
+}
+
+/**
+ Pop the list of map expression from the Stack
+
+ @param Pointer Pointer to the list of map expression to be pop.
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
+
+**/
+EFI_STATUS
+PopMapExpressionList (
+ OUT VOID **Pointer
+ )
+{
+ EFI_STATUS Status;
+ EFI_HII_VALUE Data;
+
+ Status = PopStack (
+ mMapExpressionListStack,
+ &mMapExpressionListPointer,
+ &Data
+ );
+
+ *Pointer = (VOID *)(UINTN)Data.Value.u64;
+
+ return Status;
+}
+
+/**
+ Reset stack pointer to begin of the stack.
+
+**/
+VOID
+ResetScopeStack (
+ VOID
+ )
+{
+ mOpCodeScopeStackPointer = mOpCodeScopeStack;
+}
+
+/**
+ Push an Operand onto the Stack
+
+ @param Operand Operand to push.
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
+ stack.
+
+**/
+EFI_STATUS
+PushScope (
+ IN UINT8 Operand
+ )
+{
+ EFI_HII_VALUE Data;
+
+ Data.Type = EFI_IFR_TYPE_NUM_SIZE_8;
+ Data.Value.u8 = Operand;
+
+ return PushStack (
+ &mOpCodeScopeStack,
+ &mOpCodeScopeStackPointer,
+ &mOpCodeScopeStackEnd,
+ &Data
+ );
+}
+
+/**
+ Pop an Operand from the Stack
+
+ @param Operand Operand to pop.
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
+ stack.
+
+**/
+EFI_STATUS
+PopScope (
+ OUT UINT8 *Operand
+ )
+{
+ EFI_STATUS Status;
+ EFI_HII_VALUE Data;
+
+ Status = PopStack (
+ mOpCodeScopeStack,
+ &mOpCodeScopeStackPointer,
+ &Data
+ );
+
+ *Operand = Data.Value.u8;
+
+ return Status;
+}
+
+/**
+ Grow size of the stack for Expression Dependencies.
+
+ This is an internal function.
+
+ @param Stack On input: old stack; On output: new stack
+ @param StackPtr On input: old stack pointer; On output: new stack
+ pointer
+ @param StackEnd On input: old stack end; On output: new stack end
+
+ @retval EFI_SUCCESS Grow Dependency stack success.
+ @retval EFI_OUT_OF_RESOURCES No enough memory for stack space.
+
+**/
+EFI_STATUS
+GrowDependencyStack (
+ IN OUT HII_DEPENDENCY_EXPRESSION ***Stack,
+ IN OUT HII_DEPENDENCY_EXPRESSION ***StackPtr,
+ IN OUT HII_DEPENDENCY_EXPRESSION ***StackEnd
+ )
+{
+ UINTN Size;
+ HII_DEPENDENCY_EXPRESSION **NewStack;
+
+ Size = EXPRESSION_STACK_SIZE_INCREMENT;
+ if (*StackPtr != NULL) {
+ Size = Size + (*StackEnd - *Stack);
+ }
+
+ NewStack = AllocatePool (Size * sizeof (HII_DEPENDENCY_EXPRESSION *));
+ if (NewStack == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (*StackPtr != NULL) {
+ //
+ // Copy from Old Stack to the New Stack
+ //
+ CopyMem (
+ NewStack,
+ *Stack,
+ (*StackEnd - *Stack) * sizeof (HII_DEPENDENCY_EXPRESSION *)
+ );
+
+ //
+ // Free The Old Stack
+ //
+ FreePool (*Stack);
+ }
+
+ //
+ // Make the Stack pointer point to the old data in the new stack
+ //
+ *StackPtr = NewStack + (*StackPtr - *Stack);
+ *Stack = NewStack;
+ *StackEnd = NewStack + Size;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Push an element onto the Stack for Expression Dependencies.
+
+ @param Stack On input: old stack; On output: new stack
+ @param StackPtr On input: old stack pointer; On output: new stack
+ pointer
+ @param StackEnd On input: old stack end; On output: new stack end
+ @param Data Data to push.
+
+ @retval EFI_SUCCESS Push stack success.
+
+**/
+EFI_STATUS
+PushDependencyStack (
+ IN OUT HII_DEPENDENCY_EXPRESSION ***Stack,
+ IN OUT HII_DEPENDENCY_EXPRESSION ***StackPtr,
+ IN OUT HII_DEPENDENCY_EXPRESSION ***StackEnd,
+ IN HII_DEPENDENCY_EXPRESSION **Data
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Check for a stack overflow condition
+ //
+ if (*StackPtr >= *StackEnd) {
+ //
+ // Grow the stack
+ //
+ Status = GrowDependencyStack (Stack, StackPtr, StackEnd);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ //
+ // Push the item onto the stack
+ //
+ CopyMem (*StackPtr, Data, sizeof (HII_DEPENDENCY_EXPRESSION *));
+ *StackPtr = *StackPtr + 1;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Pop the Expression Dependency options from the Stack
+
+ @param Stack On input: old stack; On output: new stack
+ @param StackPtr On input: old stack pointer; On output: new stack
+ pointer
+ @param Data Data to push.
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
+
+**/
+EFI_STATUS
+PopDependencyStack (
+ IN HII_DEPENDENCY_EXPRESSION **Stack,
+ IN OUT HII_DEPENDENCY_EXPRESSION ***StackPtr,
+ OUT HII_DEPENDENCY_EXPRESSION **Data
+ )
+{
+ //
+ // Check for a stack underflow condition
+ //
+ if (*StackPtr == Stack) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ //
+ // Pop the item off the stack
+ //
+ *StackPtr = *StackPtr - 1;
+ CopyMem (Data, *StackPtr, sizeof (HII_DEPENDENCY_EXPRESSION *));
+ return EFI_SUCCESS;
+}
+
+/**
+ Push the list of Expression Dependencies onto the Stack
+
+ @param Pointer Pointer to the list of map expression to be pushed.
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
+
+**/
+EFI_STATUS
+PushDependencyExpDes (
+ IN HII_DEPENDENCY_EXPRESSION **Pointer
+ )
+{
+ return PushDependencyStack (
+ &mExpressionDependencyStack,
+ &mExpressionDependencyPointer,
+ &mExpressionDependencyEnd,
+ Pointer
+ );
+}
+
+/**
+ Pop the list of Expression Dependencies from the Stack
+
+ @param Pointer Pointer to the list of map expression to be pop.
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
+
+**/
+EFI_STATUS
+PopDependencyExpDes (
+ OUT HII_DEPENDENCY_EXPRESSION **Pointer
+ )
+{
+ return PopDependencyStack (
+ mExpressionDependencyStack,
+ &mExpressionDependencyPointer,
+ Pointer
+ );
+}
+
+/**
+ Retrieve dependencies within an expression. These dependencies can express how
+ this expression will be evaluated.
+
+ @param[in,out] Expression Expression to retrieve dependencies.
+
+ @retval EFI_SUCCESS The dependencies were successfully retrieved.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory.
+
+**/
+EFI_STATUS
+GetHiiExpressionDependency (
+ IN OUT HII_EXPRESSION *Expression
+ )
+{
+ EFI_STATUS Status;
+ LIST_ENTRY *Link;
+ HII_EXPRESSION_OPCODE *ExpressionOpCode;
+ HII_DEPENDENCY_EXPRESSION *DepExpressionOpCode;
+ LIST_ENTRY *SubExpressionLink;
+ HII_EXPRESSION *SubExpression;
+ UINT8 MapPairCount;
+
+ Link = GetFirstNode (&Expression->OpCodeListHead);
+ while (!IsNull (&Expression->OpCodeListHead, Link)) {
+ ExpressionOpCode = HII_EXPRESSION_OPCODE_FROM_LINK (Link);
+ Link = GetNextNode (&Expression->OpCodeListHead, Link);
+ Status = EFI_SUCCESS;
+
+ DepExpressionOpCode = (HII_DEPENDENCY_EXPRESSION *)AllocateZeroPool (sizeof (HII_DEPENDENCY_EXPRESSION));
+ if (DepExpressionOpCode == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ switch (ExpressionOpCode->Operand) {
+ //
+ // Constant
+ //
+ case EFI_IFR_FALSE_OP:
+ case EFI_IFR_ONE_OP:
+ case EFI_IFR_ONES_OP:
+ case EFI_IFR_TRUE_OP:
+ case EFI_IFR_UINT8_OP:
+ case EFI_IFR_UINT16_OP:
+ case EFI_IFR_UINT32_OP:
+ case EFI_IFR_UINT64_OP:
+ case EFI_IFR_UNDEFINED_OP:
+ case EFI_IFR_VERSION_OP:
+ case EFI_IFR_ZERO_OP:
+ DepExpressionOpCode->ConstantExp.Operand = ExpressionOpCode->Operand;
+ CopyMem (&DepExpressionOpCode->ConstantExp.Value, &ExpressionOpCode->ExtraData.Value, sizeof (EFI_HII_VALUE));
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ //
+ // Built-in functions
+ //
+ case EFI_IFR_DUP_OP:
+ DepExpressionOpCode->DupExp.Operand = ExpressionOpCode->Operand;
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_EQ_ID_VAL_OP:
+ DepExpressionOpCode->EqIdValExp.Operand = ExpressionOpCode->Operand;
+ CopyMem (&DepExpressionOpCode->EqIdValExp.QuestionId, &ExpressionOpCode->ExtraData.EqIdValData.QuestionId, sizeof (EFI_QUESTION_ID));
+ CopyMem (&DepExpressionOpCode->EqIdValExp.Value, &ExpressionOpCode->ExtraData.EqIdValData.Value, sizeof (EFI_HII_VALUE));
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_EQ_ID_ID_OP:
+ DepExpressionOpCode->EqIdIdExp.Operand = ExpressionOpCode->Operand;
+ CopyMem (&DepExpressionOpCode->EqIdIdExp.QuestionId1, &ExpressionOpCode->ExtraData.EqIdIdData.QuestionId1, sizeof (EFI_QUESTION_ID));
+ CopyMem (&DepExpressionOpCode->EqIdIdExp.QuestionId2, &ExpressionOpCode->ExtraData.EqIdIdData.QuestionId2, sizeof (EFI_QUESTION_ID));
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_EQ_ID_VAL_LIST_OP:
+ DepExpressionOpCode->EqIdListExp.Operand = ExpressionOpCode->Operand;
+ DepExpressionOpCode->EqIdListExp.ListLength = ExpressionOpCode->ExtraData.EqIdListData.ListLength;
+ CopyMem (&DepExpressionOpCode->EqIdListExp.QuestionId, &ExpressionOpCode->ExtraData.EqIdListData.QuestionId, sizeof (EFI_QUESTION_ID));
+ PushDependencyExpDes (&DepExpressionOpCode);
+ DepExpressionOpCode->EqIdListExp.ValueList = AllocateCopyPool (
+ DepExpressionOpCode->EqIdListExp.ListLength * sizeof (UINT16),
+ ExpressionOpCode->ExtraData.EqIdListData.ValueList
+ );
+ if (DepExpressionOpCode->EqIdListExp.ValueList == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_GET_OP:
+ DepExpressionOpCode->GetExp.Operand = ExpressionOpCode->Operand;
+ DepExpressionOpCode->GetExp.VarStorage = ExpressionOpCode->ExtraData.GetSetData.VarStorage;
+ CopyMem (&DepExpressionOpCode->GetExp.VarStoreInfo.VarName, &ExpressionOpCode->ExtraData.GetSetData.VarStoreInfo.VarName, sizeof (EFI_STRING_ID));
+ CopyMem (&DepExpressionOpCode->GetExp.VarStoreInfo.VarOffset, &ExpressionOpCode->ExtraData.GetSetData.VarStoreInfo.VarOffset, sizeof (UINT16));
+ DepExpressionOpCode->GetExp.VarStoreInfo = ExpressionOpCode->ExtraData.GetSetData.VarStoreInfo;
+ if (ExpressionOpCode->ExtraData.GetSetData.ValueName != NULL) {
+ DepExpressionOpCode->GetExp.ValueName = (CHAR16 *)AllocateCopyPool (sizeof (ExpressionOpCode->ExtraData.GetSetData.ValueName), ExpressionOpCode->ExtraData.GetSetData.ValueName);
+ if (DepExpressionOpCode->GetExp.ValueName == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+
+ DepExpressionOpCode->GetExp.ValueType = ExpressionOpCode->ExtraData.GetSetData.ValueType;
+ DepExpressionOpCode->GetExp.ValueWidth = ExpressionOpCode->ExtraData.GetSetData.ValueWidth;
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_QUESTION_REF1_OP:
+ DepExpressionOpCode->QuestionRef1Exp.Operand = ExpressionOpCode->Operand;
+ CopyMem (&DepExpressionOpCode->QuestionRef1Exp.QuestionId, &ExpressionOpCode->ExtraData.QuestionRef1Data.QuestionId, sizeof (EFI_QUESTION_ID));
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_RULE_REF_OP:
+ DepExpressionOpCode->RuleRefExp.Operand = ExpressionOpCode->Operand;
+ DepExpressionOpCode->RuleRefExp.RuleId = ExpressionOpCode->ExtraData.RuleId;
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_STRING_REF1_OP:
+ DepExpressionOpCode->StringRef1Exp.Operand = ExpressionOpCode->Operand;
+ CopyMem (&DepExpressionOpCode->StringRef1Exp.Value.Value.string, &ExpressionOpCode->ExtraData.Value.Value.string, sizeof (EFI_STRING_ID));
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_THIS_OP:
+ DepExpressionOpCode->ThisExp.Operand = ExpressionOpCode->Operand;
+ CopyMem (&DepExpressionOpCode->ThisExp.QuestionId, &ExpressionOpCode->ExtraData.QuestionRef1Data.QuestionId, sizeof (EFI_QUESTION_ID));
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_SECURITY_OP:
+ DepExpressionOpCode->SecurityExp.Operand = ExpressionOpCode->Operand;
+ CopyMem (&DepExpressionOpCode->SecurityExp.Permissions, &ExpressionOpCode->ExtraData.Guid, sizeof (EFI_GUID));
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ //
+ // unary-op
+ //
+ case EFI_IFR_LENGTH_OP:
+ DepExpressionOpCode->LengthExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->LengthExp.SubExpression);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_NOT_OP:
+ DepExpressionOpCode->NotExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->NotExp.SubExpression);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_BITWISE_NOT_OP:
+ DepExpressionOpCode->BitWiseNotExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->BitWiseNotExp.SubExpression);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_QUESTION_REF2_OP:
+ DepExpressionOpCode->QuestionRef2Exp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->QuestionRef2Exp.SubExpression);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_QUESTION_REF3_OP:
+ DepExpressionOpCode->QuestionRef3Exp.Operand = ExpressionOpCode->Operand;
+ CopyMem (&DepExpressionOpCode->QuestionRef3Exp.DevicePath, &ExpressionOpCode->ExtraData.QuestionRef3Data.DevicePath, sizeof (EFI_DEVICE_PATH));
+ CopyMem (&DepExpressionOpCode->QuestionRef3Exp.Guid, &ExpressionOpCode->ExtraData.QuestionRef3Data.Guid, sizeof (EFI_GUID));
+ PopDependencyExpDes (&DepExpressionOpCode->QuestionRef3Exp.SubExpression);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_SET_OP:
+ DepExpressionOpCode->SetExp.Operand = ExpressionOpCode->Operand;
+ DepExpressionOpCode->SetExp.VarStorage = ExpressionOpCode->ExtraData.GetSetData.VarStorage;
+ CopyMem (&DepExpressionOpCode->SetExp.VarStoreInfo.VarName, &ExpressionOpCode->ExtraData.GetSetData.VarStoreInfo.VarName, sizeof (EFI_STRING_ID));
+ CopyMem (&DepExpressionOpCode->SetExp.VarStoreInfo.VarOffset, &ExpressionOpCode->ExtraData.GetSetData.VarStoreInfo.VarOffset, sizeof (UINT16));
+ DepExpressionOpCode->SetExp.VarStoreInfo = ExpressionOpCode->ExtraData.GetSetData.VarStoreInfo;
+ if (ExpressionOpCode->ExtraData.GetSetData.ValueName != NULL) {
+ DepExpressionOpCode->SetExp.ValueName = (CHAR16 *)AllocateCopyPool (sizeof (ExpressionOpCode->ExtraData.GetSetData.ValueName), ExpressionOpCode->ExtraData.GetSetData.ValueName);
+ if (DepExpressionOpCode->SetExp.ValueName == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+
+ DepExpressionOpCode->SetExp.ValueType = ExpressionOpCode->ExtraData.GetSetData.ValueType;
+ DepExpressionOpCode->SetExp.ValueWidth = ExpressionOpCode->ExtraData.GetSetData.ValueWidth;
+ PopDependencyExpDes (&DepExpressionOpCode->SetExp.SubExpression);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_STRING_REF2_OP:
+ DepExpressionOpCode->StringRef2Exp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->StringRef2Exp.SubExpression);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_TO_BOOLEAN_OP:
+ DepExpressionOpCode->ToBooleanExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->ToBooleanExp.SubExpression);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_TO_STRING_OP:
+ DepExpressionOpCode->ToStringExp.Operand = ExpressionOpCode->Operand;
+ DepExpressionOpCode->ToStringExp.Format = ExpressionOpCode->ExtraData.Format;
+ PopDependencyExpDes (&DepExpressionOpCode->ToStringExp.SubExpression);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_TO_UINT_OP:
+ DepExpressionOpCode->ToUintExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->ToUintExp.SubExpression);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_TO_LOWER_OP:
+ DepExpressionOpCode->ToLowerExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->ToLowerExp.SubExpression);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_TO_UPPER_OP:
+ DepExpressionOpCode->ToUpperExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->ToUpperExp.SubExpression);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ //
+ // binary-op
+ //
+ case EFI_IFR_ADD_OP:
+ DepExpressionOpCode->AddExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->AddExp.LeftHandExp);
+ PopDependencyExpDes (&DepExpressionOpCode->AddExp.RightHandExp);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_AND_OP:
+ DepExpressionOpCode->AndExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->AndExp.SubExpression1);
+ PopDependencyExpDes (&DepExpressionOpCode->AndExp.SubExpression2);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_BITWISE_AND_OP:
+ DepExpressionOpCode->BitwiseAndExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->BitwiseAndExp.SubExpression1);
+ PopDependencyExpDes (&DepExpressionOpCode->BitwiseAndExp.SubExpression2);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_BITWISE_OR_OP:
+ DepExpressionOpCode->BitwiseOrExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->BitwiseOrExp.SubExpression1);
+ PopDependencyExpDes (&DepExpressionOpCode->BitwiseOrExp.SubExpression2);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_CATENATE_OP:
+ DepExpressionOpCode->CatenateExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->CatenateExp.LeftStringExp);
+ PopDependencyExpDes (&DepExpressionOpCode->CatenateExp.RightStringExp);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_DIVIDE_OP:
+ DepExpressionOpCode->DivExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->DivExp.LeftHandExp);
+ PopDependencyExpDes (&DepExpressionOpCode->DivExp.RightHandExp);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_EQUAL_OP:
+ DepExpressionOpCode->EqualExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->EqualExp.SubExpression1);
+ PopDependencyExpDes (&DepExpressionOpCode->EqualExp.SubExpression2);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_GREATER_EQUAL_OP:
+ DepExpressionOpCode->GreaterEqualExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->GreaterEqualExp.LeftHandExp);
+ PopDependencyExpDes (&DepExpressionOpCode->GreaterEqualExp.RightHandExp);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_GREATER_THAN_OP:
+ DepExpressionOpCode->GreaterThanExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->GreaterThanExp.LeftHandExp);
+ PopDependencyExpDes (&DepExpressionOpCode->GreaterThanExp.RightHandExp);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_LESS_EQUAL_OP:
+ DepExpressionOpCode->LessEqualExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->LessEqualExp.LeftHandExp);
+ PopDependencyExpDes (&DepExpressionOpCode->LessEqualExp.RightHandExp);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_LESS_THAN_OP:
+ DepExpressionOpCode->LessThanExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->LessThanExp.LeftHandExp);
+ PopDependencyExpDes (&DepExpressionOpCode->LessThanExp.RightHandExp);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_MATCH_OP:
+ DepExpressionOpCode->MatchExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->MatchExp.PatternExp);
+ PopDependencyExpDes (&DepExpressionOpCode->MatchExp.StringExp);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_MATCH2_OP:
+ DepExpressionOpCode->Match2Exp.Operand = ExpressionOpCode->Operand;
+ CopyMem (&DepExpressionOpCode->Match2Exp.SyntaxType, &ExpressionOpCode->ExtraData.Guid, sizeof (EFI_GUID));
+ PopDependencyExpDes (&DepExpressionOpCode->Match2Exp.PatternExp);
+ PopDependencyExpDes (&DepExpressionOpCode->Match2Exp.StringExp);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_MODULO_OP:
+ DepExpressionOpCode->ModExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->ModExp.LeftHandExp);
+ PopDependencyExpDes (&DepExpressionOpCode->ModExp.RightHandExp);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_MULTIPLY_OP:
+ DepExpressionOpCode->MultExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->MultExp.LeftHandExp);
+ PopDependencyExpDes (&DepExpressionOpCode->MultExp.RightHandExp);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_NOT_EQUAL_OP:
+ DepExpressionOpCode->NotEqualExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->NotEqualExp.SubExpression1);
+ PopDependencyExpDes (&DepExpressionOpCode->NotEqualExp.SubExpression2);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_OR_OP:
+ DepExpressionOpCode->OrExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->OrExp.SubExpression1);
+ PopDependencyExpDes (&DepExpressionOpCode->OrExp.SubExpression2);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_SHIFT_LEFT_OP:
+ DepExpressionOpCode->ShiftLeftExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->ShiftLeftExp.LeftHandExp);
+ PopDependencyExpDes (&DepExpressionOpCode->ShiftLeftExp.RightHandExp);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_SHIFT_RIGHT_OP:
+ DepExpressionOpCode->ShiftRightExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->ShiftRightExp.LeftHandExp);
+ PopDependencyExpDes (&DepExpressionOpCode->ShiftRightExp.RightHandExp);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_SUBTRACT_OP:
+ DepExpressionOpCode->SubtractExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->SubtractExp.LeftHandExp);
+ PopDependencyExpDes (&DepExpressionOpCode->SubtractExp.RightHandExp);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ //
+ // ternary-op
+ //
+ case EFI_IFR_CONDITIONAL_OP:
+ DepExpressionOpCode->ConditionalExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->ConditionalExp.CondTrueValExp);
+ PopDependencyExpDes (&DepExpressionOpCode->ConditionalExp.CondFalseValExp);
+ PopDependencyExpDes (&DepExpressionOpCode->ConditionalExp.ConditionExp);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_FIND_OP:
+ DepExpressionOpCode->FindExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->FindExp.StringToSearchExp);
+ PopDependencyExpDes (&DepExpressionOpCode->FindExp.StringToCompWithExp);
+ PopDependencyExpDes (&DepExpressionOpCode->FindExp.IndexExp);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_MID_OP:
+ DepExpressionOpCode->MidExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->MidExp.StringOrBufferExp);
+ PopDependencyExpDes (&DepExpressionOpCode->MidExp.IndexExp);
+ PopDependencyExpDes (&DepExpressionOpCode->MidExp.LengthExp);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_TOKEN_OP:
+ DepExpressionOpCode->TokenExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->TokenExp.StringToSearchExp);
+ PopDependencyExpDes (&DepExpressionOpCode->TokenExp.DelimiterExp);
+ PopDependencyExpDes (&DepExpressionOpCode->TokenExp.IndexExp);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ case EFI_IFR_SPAN_OP:
+ DepExpressionOpCode->SpanExp.Operand = ExpressionOpCode->Operand;
+ PopDependencyExpDes (&DepExpressionOpCode->SpanExp.StringToSearchExp);
+ PopDependencyExpDes (&DepExpressionOpCode->SpanExp.CharsetExp);
+ PopDependencyExpDes (&DepExpressionOpCode->SpanExp.IndexExp);
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ //
+ // Map
+ //
+ case EFI_IFR_MAP_OP:
+ //
+ // Go through map expression list.
+ //
+ DepExpressionOpCode->MapExp.Operand = ExpressionOpCode->Operand;
+ MapPairCount = 0;
+ SubExpressionLink = GetFirstNode (&ExpressionOpCode->MapExpressionList);
+ while (!IsNull (&ExpressionOpCode->MapExpressionList, SubExpressionLink)) {
+ MapPairCount++;
+ SubExpressionLink = GetNextNode (&ExpressionOpCode->MapExpressionList, SubExpressionLink);
+ if (IsNull (&ExpressionOpCode->MapExpressionList, SubExpressionLink)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+
+ //
+ // Goto the first expression on next pair.
+ //
+ SubExpressionLink = GetNextNode (&ExpressionOpCode->MapExpressionList, SubExpressionLink);
+ }
+
+ DepExpressionOpCode->MapExp.ExpPair = (HII_DEPENDENCY_EXPRESSION_PAIR *)AllocateZeroPool (
+ MapPairCount * sizeof (HII_DEPENDENCY_EXPRESSION_PAIR)
+ );
+ if (DepExpressionOpCode->MapExp.ExpPair == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ DepExpressionOpCode->MapExp.ExpPairNo = MapPairCount;
+ MapPairCount = 0;
+ PopDependencyExpDes (&DepExpressionOpCode->MapExp.SubExp);
+
+ //
+ // Go through map expression list.
+ //
+ SubExpressionLink = GetFirstNode (&ExpressionOpCode->MapExpressionList);
+ while (!IsNull (&ExpressionOpCode->MapExpressionList, SubExpressionLink)) {
+ SubExpression = HII_EXPRESSION_FROM_LINK (SubExpressionLink);
+ //
+ // Get the first expression description in this pair.
+ //
+ GetHiiExpressionDependency (SubExpression);
+ DepExpressionOpCode->MapExp.ExpPair[MapPairCount].MatchExp = SubExpression->RootDependencyExp;
+
+ //
+ // Get the second expression description in this pair.
+ //
+ SubExpressionLink = GetNextNode (&ExpressionOpCode->MapExpressionList, SubExpressionLink);
+ SubExpression = HII_EXPRESSION_FROM_LINK (SubExpressionLink);
+ GetHiiExpressionDependency (SubExpression);
+ DepExpressionOpCode->MapExp.ExpPair[MapPairCount].ReturnExp = SubExpression->RootDependencyExp;
+ //
+ // Goto the first expression on next pair.
+ //
+ SubExpressionLink = GetNextNode (&ExpressionOpCode->MapExpressionList, SubExpressionLink);
+ MapPairCount++;
+ }
+
+ PushDependencyExpDes (&DepExpressionOpCode);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ PopDependencyExpDes (&Expression->RootDependencyExp);
+
+Done:
+ return Status;
+}
+
+/**
+ Return the result of the expression list. Check the expression list and
+ return the highest priority express result.
+ Priority: DisableIf > SuppressIf > GrayOutIf > FALSE
+
+ @param[in] ExpList The input expression list.
+ @param[in] Evaluate Whether need to evaluate the expression first.
+ @param[in] FormSet FormSet associated with this expression.
+ @param[in] Form Form associated with this expression.
+
+ @retval EXPRESS_RESULT Return the higher priority express result.
+ DisableIf > SuppressIf > GrayOutIf > FALSE
+
+**/
+EXPRESS_RESULT
+EvaluateExpressionList (
+ IN HII_EXPRESSION_LIST *ExpList,
+ IN BOOLEAN Evaluate,
+ IN HII_FORMSET *FormSet OPTIONAL,
+ IN HII_FORM *Form OPTIONAL
+ )
+{
+ UINTN Index;
+ EXPRESS_RESULT ReturnVal;
+ EXPRESS_RESULT CompareOne;
+ EFI_STATUS Status;
+
+ if (ExpList == NULL) {
+ return ExpressFalse;
+ }
+
+ ASSERT (ExpList->Signature == HII_EXPRESSION_LIST_SIGNATURE);
+ Index = 0;
+
+ //
+ // Check whether need to evaluate the expression first.
+ //
+ if (Evaluate) {
+ while (ExpList->Count > Index) {
+ Status = EvaluateHiiExpression (FormSet, Form, ExpList->Expression[Index++]);
+ if (EFI_ERROR (Status)) {
+ return ExpressFalse;
+ }
+ }
+ }
+
+ //
+ // Run the list of expressions.
+ //
+ ReturnVal = ExpressFalse;
+ for (Index = 0; Index < ExpList->Count; Index++) {
+ if (IsHiiValueTrue (&ExpList->Expression[Index]->Result)) {
+ switch (ExpList->Expression[Index]->Type) {
+ case EFI_HII_EXPRESSION_SUPPRESS_IF:
+ CompareOne = ExpressSuppress;
+ break;
+
+ case EFI_HII_EXPRESSION_GRAY_OUT_IF:
+ CompareOne = ExpressGrayOut;
+ break;
+
+ case EFI_HII_EXPRESSION_DISABLE_IF:
+ CompareOne = ExpressDisable;
+ break;
+
+ default:
+ return ExpressFalse;
+ }
+
+ ReturnVal = ReturnVal < CompareOne ? CompareOne : ReturnVal;
+ }
+ }
+
+ return ReturnVal;
+}