diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c b/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
index 1420f91828..37dd6a0f61 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
@@ -34,6 +34,19 @@ EFI_HII_VALUE *mMapExpressionListStack = NULL;
EFI_HII_VALUE *mMapExpressionListEnd = NULL;
EFI_HII_VALUE *mMapExpressionListPointer = NULL;
+FORM_EXPRESSION **mFormExpressionStack = NULL;
+FORM_EXPRESSION **mFormExpressionEnd = NULL;
+FORM_EXPRESSION **mFormExpressionPointer = NULL;
+
+FORM_EXPRESSION **mStatementExpressionStack = NULL;
+FORM_EXPRESSION **mStatementExpressionEnd = NULL;
+FORM_EXPRESSION **mStatementExpressionPointer = NULL;
+
+FORM_EXPRESSION **mOptionExpressionStack = NULL;
+FORM_EXPRESSION **mOptionExpressionEnd = NULL;
+FORM_EXPRESSION **mOptionExpressionPointer = NULL;
+
+
//
// Unicode collation protocol interface
//
@@ -194,7 +207,10 @@ ResetCurrentExpressionStack (
VOID
)
{
- mCurrentExpressionPointer = mCurrentExpressionStack;
+ mCurrentExpressionPointer = mCurrentExpressionStack;
+ mFormExpressionPointer = mFormExpressionStack;
+ mStatementExpressionPointer = mStatementExpressionStack;
+ mOptionExpressionPointer = mOptionExpressionStack;
}
@@ -267,6 +283,294 @@ ResetMapExpressionListStack (
}
+/**
+ 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 FORM_EXPRESSION ***Stack,
+ IN OUT FORM_EXPRESSION ***StackPtr,
+ IN OUT FORM_EXPRESSION ***StackEnd,
+ IN UINTN MemberSize
+ )
+{
+ UINTN Size;
+ FORM_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 FORM_EXPRESSION ***Stack,
+ IN OUT FORM_EXPRESSION ***StackPtr,
+ IN OUT FORM_EXPRESSION ***StackEnd,
+ IN FORM_EXPRESSION **Data
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Check for a stack overflow condition
+ //
+ if (*StackPtr >= *StackEnd) {
+ //
+ // Grow the stack
+ //
+ Status = GrowConditionalStack (Stack, StackPtr, StackEnd, sizeof (FORM_EXPRESSION *));
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ //
+ // Push the item onto the stack
+ //
+ CopyMem (*StackPtr, Data, sizeof (FORM_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 FORM_EXPRESSION **Stack,
+ IN OUT FORM_EXPRESSION ***StackPtr,
+ OUT FORM_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 (FORM_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.
+
+**/
+FORM_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 FORM_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
+ )
+{
+ FORM_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
@@ -2868,3 +3172,80 @@ 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 ExpList The input expression list.
+ @param Evaluate Whether need to evaluate the expression first.
+ @param FormSet FormSet associated with this expression.
+ @param Form Form associated with this expression.
+
+ @retval EXPRESS_RESULT Return the higher priority express result.
+ DisableIf > SuppressIf > GrayOutIf > FALSE
+
+**/
+EXPRESS_RESULT
+EvaluateExpressionList (
+ IN FORM_EXPRESSION_LIST *ExpList,
+ IN BOOLEAN Evaluate,
+ IN FORM_BROWSER_FORMSET *FormSet, OPTIONAL
+ IN FORM_BROWSER_FORM *Form OPTIONAL
+ )
+{
+ UINTN Index;
+ EXPRESS_RESULT ReturnVal;
+ EXPRESS_RESULT CompareOne;
+ EFI_STATUS Status;
+
+ if (ExpList == NULL) {
+ return ExpressFalse;
+ }
+
+ ASSERT(ExpList->Signature == FORM_EXPRESSION_LIST_SIGNATURE);
+ Index = 0;
+
+ //
+ // Check whether need to evaluate the expression first.
+ //
+ if (Evaluate) {
+ while (ExpList->Count > Index) {
+ Status = EvaluateExpression (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 (ExpList->Expression[Index]->Result.Type == EFI_IFR_TYPE_BOOLEAN &&
+ ExpList->Expression[Index]->Result.Value.b) {
+ 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;
+}
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
index a2befcb661..2cd666fc70 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
@@ -18,13 +18,6 @@ UINT16 mStatementIndex;
UINT16 mExpressionOpCodeIndex;
BOOLEAN mInScopeSubtitle;
-BOOLEAN mInScopeSuppress;
-BOOLEAN mInScopeGrayOut;
-BOOLEAN mInScopeDisable;
-FORM_EXPRESSION *mSuppressExpression;
-FORM_EXPRESSION *mGrayOutExpression;
-FORM_EXPRESSION *mDisableExpression;
-
/**
Initialize Statement header members.
@@ -44,6 +37,7 @@ CreateStatement (
{
FORM_BROWSER_STATEMENT *Statement;
EFI_IFR_STATEMENT_HEADER *StatementHdr;
+ INTN ConditionalExprCount;
if (Form == NULL) {
//
@@ -68,17 +62,18 @@ CreateStatement (
CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));
CopyMem (&Statement->Help, &StatementHdr->Help, sizeof (EFI_STRING_ID));
- if (mInScopeSuppress) {
- Statement->SuppressExpression = mSuppressExpression;
- }
-
- if (mInScopeGrayOut) {
- Statement->GrayOutExpression = mGrayOutExpression;
- }
-
-
- if (mInScopeDisable) {
- Statement->DisableExpression = mDisableExpression;
+ ConditionalExprCount = GetConditionalExpressionCount(ExpressStatement);
+ if (ConditionalExprCount > 0) {
+ //
+ // Form is inside of suppressif
+ //
+
+ Statement->Expression = (FORM_EXPRESSION_LIST *) AllocatePool(
+ (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
+ ASSERT (Statement->Expression != NULL);
+ Statement->Expression->Count = (UINTN) ConditionalExprCount;
+ Statement->Expression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
+ CopyMem (Statement->Expression->Expression, GetConditionalExpressionList(ExpressStatement), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
}
Statement->InSubtitle = mInScopeSubtitle;
@@ -629,6 +624,9 @@ DestroyStatement (
while (!IsListEmpty (&Statement->OptionListHead)) {
Link = GetFirstNode (&Statement->OptionListHead);
Option = QUESTION_OPTION_FROM_LINK (Link);
+ if (Option->SuppressExpression != NULL) {
+ FreePool (Option->SuppressExpression);
+ }
RemoveEntryList (&Option->Link);
FreePool (Option);
@@ -656,6 +654,10 @@ DestroyStatement (
DestroyExpression (Expression);
}
+ if (Statement->Expression != NULL) {
+ FreePool (Statement->Expression);
+ }
+
if (Statement->VariableName != NULL) {
FreePool (Statement->VariableName);
}
@@ -723,6 +725,10 @@ DestroyForm (
FreePool (ConfigInfo);
}
+ if (Form->SuppressExpression != NULL) {
+ FreePool (Form->SuppressExpression);
+ }
+
//
// Free this Form
//
@@ -931,10 +937,6 @@ ParseOpCodes (
EFI_IMAGE_ID *ImageId;
BOOLEAN SuppressForQuestion;
BOOLEAN SuppressForOption;
- BOOLEAN InScopeOptionSuppress;
- FORM_EXPRESSION *OptionSuppressExpression;
- BOOLEAN InScopeFormSuppress;
- FORM_EXPRESSION *FormSuppressExpression;
UINT16 DepthOfDisable;
BOOLEAN OpCodeDisabled;
BOOLEAN SingleOpCodeExpression;
@@ -946,15 +948,13 @@ ParseOpCodes (
FORMSET_STORAGE *VarStorage;
LIST_ENTRY *MapExpressionList;
EFI_VARSTORE_ID TempVarstoreId;
+ BOOLEAN InScopeDisable;
+ INTN ConditionalExprCount;
mInScopeSubtitle = FALSE;
SuppressForQuestion = FALSE;
SuppressForOption = FALSE;
- InScopeFormSuppress = FALSE;
- mInScopeSuppress = FALSE;
- InScopeOptionSuppress = FALSE;
- mInScopeGrayOut = FALSE;
- mInScopeDisable = FALSE;
+ InScopeDisable = FALSE;
DepthOfDisable = 0;
OpCodeDisabled = FALSE;
SingleOpCodeExpression = FALSE;
@@ -962,8 +962,6 @@ ParseOpCodes (
CurrentExpression = NULL;
CurrentDefault = NULL;
CurrentOption = NULL;
- OptionSuppressExpression = NULL;
- FormSuppressExpression = NULL;
ImageId = NULL;
MapMethod = NULL;
MapScopeDepth = 0;
@@ -971,6 +969,7 @@ ParseOpCodes (
VarStorage = NULL;
MapExpressionList = NULL;
TempVarstoreId = 0;
+ ConditionalExprCount = 0;
//
// Get the number of Statements and Expressions
@@ -1032,7 +1031,7 @@ ParseOpCodes (
if (ScopeOpCode == EFI_IFR_DISABLE_IF_OP) {
if (DepthOfDisable == 0) {
- mInScopeDisable = FALSE;
+ InScopeDisable = FALSE;
OpCodeDisabled = FALSE;
} else {
DepthOfDisable--;
@@ -1288,7 +1287,7 @@ ParseOpCodes (
//
SingleOpCodeExpression = FALSE;
- if (mInScopeDisable && CurrentForm == NULL) {
+ if (InScopeDisable && CurrentForm == NULL) {
//
// This is DisableIf expression for Form, it should be a constant expression
//
@@ -1351,11 +1350,17 @@ ParseOpCodes (
CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));
CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));
- if (InScopeFormSuppress) {
+ ConditionalExprCount = GetConditionalExpressionCount(ExpressForm);
+ if ( ConditionalExprCount > 0) {
//
// Form is inside of suppressif
//
- CurrentForm->SuppressExpression = FormSuppressExpression;
+ CurrentForm->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(
+ (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
+ ASSERT (CurrentForm->SuppressExpression != NULL);
+ CurrentForm->SuppressExpression->Count = (UINTN) ConditionalExprCount;
+ CurrentForm->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
+ CopyMem (CurrentForm->SuppressExpression->Expression, GetConditionalExpressionList(ExpressForm), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
}
if (Scope != 0) {
@@ -1410,11 +1415,17 @@ ParseOpCodes (
CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
}
- if (InScopeFormSuppress) {
+ ConditionalExprCount = GetConditionalExpressionCount(ExpressForm);
+ if ( ConditionalExprCount > 0) {
//
// Form is inside of suppressif
//
- CurrentForm->SuppressExpression = FormSuppressExpression;
+ CurrentForm->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(
+ (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
+ ASSERT (CurrentForm->SuppressExpression != NULL);
+ CurrentForm->SuppressExpression->Count = (UINTN) ConditionalExprCount;
+ CurrentForm->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
+ CopyMem (CurrentForm->SuppressExpression->Expression, GetConditionalExpressionList(ExpressForm), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
}
if (Scope != 0) {
@@ -1799,8 +1810,17 @@ ParseOpCodes (
CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));
ExtendValueToU64 (&CurrentOption->Value);
- if (InScopeOptionSuppress) {
- CurrentOption->SuppressExpression = OptionSuppressExpression;
+ ConditionalExprCount = GetConditionalExpressionCount(ExpressOption);
+ if ( ConditionalExprCount > 0) {
+ //
+ // Form is inside of suppressif
+ //
+ CurrentOption->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(
+ (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
+ ASSERT (CurrentOption->SuppressExpression != NULL);
+ CurrentOption->SuppressExpression->Count = (UINTN) ConditionalExprCount;
+ CurrentOption->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
+ CopyMem (CurrentOption->SuppressExpression->Expression, GetConditionalExpressionList(ExpressOption), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
}
//
@@ -1892,14 +1912,11 @@ ParseOpCodes (
}
if (SuppressForOption) {
- InScopeOptionSuppress = TRUE;
- OptionSuppressExpression = CurrentExpression;
+ PushConditionalExpression(CurrentExpression, ExpressOption);
} else if (SuppressForQuestion) {
- mInScopeSuppress = TRUE;
- mSuppressExpression = CurrentExpression;
+ PushConditionalExpression(CurrentExpression, ExpressStatement);
} else {
- InScopeFormSuppress = TRUE;
- FormSuppressExpression = CurrentExpression;
+ PushConditionalExpression(CurrentExpression, ExpressForm);
}
//
@@ -1918,9 +1935,7 @@ ParseOpCodes (
CurrentExpression = CreateExpression (CurrentForm);
CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;
InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
-
- mInScopeGrayOut = TRUE;
- mGrayOutExpression = CurrentExpression;
+ PushConditionalExpression(CurrentExpression, ExpressStatement);
//
// Take a look at next OpCode to see whether current expression consists
@@ -1947,12 +1962,11 @@ ParseOpCodes (
// This is DisableIf for Question, enqueue it to Form expression list
//
InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
+ PushConditionalExpression(CurrentExpression, ExpressStatement);
}
- mDisableExpression = CurrentExpression;
- mInScopeDisable = TRUE;
- OpCodeDisabled = FALSE;
-
+ OpCodeDisabled = FALSE;
+ InScopeDisable = TRUE;
//
// Take a look at next OpCode to see whether current expression consists
// of single OpCode
@@ -2235,20 +2249,23 @@ ParseOpCodes (
case EFI_IFR_SUPPRESS_IF_OP:
if (SuppressForOption) {
- InScopeOptionSuppress = FALSE;
+ PopConditionalExpression(ExpressOption);
} else if (SuppressForQuestion) {
- mInScopeSuppress = FALSE;
+ PopConditionalExpression(ExpressStatement);
} else {
- InScopeFormSuppress = FALSE;
+ PopConditionalExpression(ExpressForm);
}
break;
case EFI_IFR_GRAY_OUT_IF_OP:
- mInScopeGrayOut = FALSE;
+ PopConditionalExpression(ExpressStatement);
break;
case EFI_IFR_DISABLE_IF_OP:
- mInScopeDisable = FALSE;
+ if (CurrentForm != NULL) {
+ PopConditionalExpression(ExpressStatement);
+ }
+ InScopeDisable = FALSE;
OpCodeDisabled = FALSE;
break;
@@ -2280,7 +2297,7 @@ ParseOpCodes (
default:
if (IsExpressionOpCode (ScopeOpCode)) {
- if (mInScopeDisable && CurrentForm == NULL) {
+ if (InScopeDisable && CurrentForm == NULL) {
//
// This is DisableIf expression for Form, it should be a constant expression
//
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/InputHandler.c b/MdeModulePkg/Universal/SetupBrowserDxe/InputHandler.c
index 2522d16deb..c9da7a311a 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/InputHandler.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/InputHandler.c
@@ -1,7 +1,7 @@
/** @file
Implementation for handling user input from the User Interfaces.
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -1005,7 +1005,7 @@ GetSelectionInputPopUp (
RemoveEntryList (&OneOfOption->Link);
if ((OneOfOption->SuppressExpression != NULL) &&
- (OneOfOption->SuppressExpression->Result.Value.b)) {
+ EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) != ExpressFalse) {
//
// This option is suppressed, insert to tail
//
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c b/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
index 2ba2165971..28ed0348ed 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
@@ -1,7 +1,7 @@
/** @file
Utility functions for UI presentation.
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -468,7 +468,6 @@ DisplayForm (
CHAR16 *StringPtr;
UINT16 MenuItemCount;
EFI_HII_HANDLE Handle;
- BOOLEAN Suppress;
EFI_SCREEN_DESCRIPTOR LocalScreen;
UINT16 Width;
UINTN ArrayEntry;
@@ -521,17 +520,7 @@ DisplayForm (
while (!IsNull (&Selection->Form->StatementListHead, Link)) {
Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
- if (Statement->SuppressExpression != NULL) {
- Suppress = Statement->SuppressExpression->Result.Value.b;
- } else {
- Suppress = FALSE;
- }
-
- if (Statement->DisableExpression != NULL) {
- Suppress = (BOOLEAN) (Suppress || Statement->DisableExpression->Result.Value.b);
- }
-
- if (!Suppress) {
+ if (EvaluateExpressionList(Statement->Expression, FALSE, NULL, NULL) <= ExpressGrayOut) {
StringPtr = GetToken (Statement->Prompt, Handle);
ASSERT (StringPtr != NULL);
@@ -1220,11 +1209,8 @@ ProcessCallBackFunction (
//
// Check whether Statement is disabled.
//
- if (Statement->DisableExpression != NULL) {
- Status = EvaluateExpression (Selection->FormSet, Selection->Form, Statement->DisableExpression);
- if (!EFI_ERROR (Status) &&
- (Statement->DisableExpression->Result.Type == EFI_IFR_TYPE_BOOLEAN) &&
- (Statement->DisableExpression->Result.Value.b)) {
+ if (Statement->Expression != NULL) {
+ if (EvaluateExpressionList(Statement->Expression, TRUE, Selection->FormSet, Selection->Form) == ExpressDisable) {
continue;
}
}
@@ -1424,13 +1410,7 @@ SetupBrowser (
// Check Form is suppressed.
//
if (Selection->Form->SuppressExpression != NULL) {
- Status = EvaluateExpression (Selection->FormSet, Selection->Form, Selection->Form->SuppressExpression);
- if (EFI_ERROR (Status) || (Selection->Form->SuppressExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN)) {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
- }
-
- if (Selection->Form->SuppressExpression->Result.Value.b) {
+ if (EvaluateExpressionList(Selection->Form->SuppressExpression, TRUE, Selection->FormSet, Selection->Form) == ExpressSuppress) {
//
// Form is suppressed.
//
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/ProcessOptions.c b/MdeModulePkg/Universal/SetupBrowserDxe/ProcessOptions.c
index 1ce139cbb0..81d3280145 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/ProcessOptions.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/ProcessOptions.c
@@ -2,7 +2,7 @@
Implementation for handling the User Interface option processing.
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -491,7 +491,7 @@ ProcessOptions (
Suppress = FALSE;
if ((OneOfOption->SuppressExpression != NULL) &&
- (OneOfOption->SuppressExpression->Result.Value.b)) {
+ (EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) == ExpressSuppress)) {
//
// This option is suppressed
//
@@ -548,7 +548,7 @@ ProcessOptions (
Option = QUESTION_OPTION_FROM_LINK (Link);
if ((Option->SuppressExpression == NULL) ||
- !Option->SuppressExpression->Result.Value.b) {
+ (EvaluateExpressionList(Option->SuppressExpression, FALSE, NULL, NULL) == ExpressFalse)) {
CopyMem (QuestionValue, &Option->Value, sizeof (EFI_HII_VALUE));
SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);
UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
@@ -564,7 +564,7 @@ ProcessOptions (
}
if ((OneOfOption->SuppressExpression != NULL) &&
- (OneOfOption->SuppressExpression->Result.Value.b)) {
+ ((EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) == ExpressSuppress))) {
//
// This option is suppressed
//
@@ -583,7 +583,7 @@ ProcessOptions (
OneOfOption = QUESTION_OPTION_FROM_LINK (Link);
if ((OneOfOption->SuppressExpression == NULL) ||
- !OneOfOption->SuppressExpression->Result.Value.b) {
+ (EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) == ExpressFalse)) {
Suppress = FALSE;
CopyMem (QuestionValue, &OneOfOption->Value, sizeof (EFI_HII_VALUE));
SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
index 6b169cd0a1..b1eb88f4db 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
@@ -1,7 +1,7 @@
/** @file
Entry and initialization module for the browser.
-Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -3016,9 +3016,8 @@ ExtractDefault (
//
// If Question is disabled, don't reset it to default
//
- if (Question->DisableExpression != NULL) {
- Status = EvaluateExpression (FormSet, Form, Question->DisableExpression);
- if (!EFI_ERROR (Status) && Question->DisableExpression->Result.Value.b) {
+ if (Question->Expression != NULL) {
+ if (EvaluateExpressionList(Question->Expression, TRUE, FormSet, Form) == ExpressDisable) {
continue;
}
}
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h
index 214102c213..6a5ddf1f2b 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h
@@ -1,7 +1,7 @@
/** @file
Private MACRO, structure and function definitions for Setup Browser module.
-Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -299,6 +299,14 @@ typedef struct {
#define FORM_EXPRESSION_FROM_LINK(a) CR (a, FORM_EXPRESSION, Link, FORM_EXPRESSION_SIGNATURE)
+#define FORM_EXPRESSION_LIST_SIGNATURE SIGNATURE_32 ('F', 'E', 'X', 'R')
+
+typedef struct {
+ UINTN Signature;
+ UINTN Count;
+ FORM_EXPRESSION *Expression[1]; // Array[Count] of expressions
+} FORM_EXPRESSION_LIST;
+
#define QUESTION_DEFAULT_SIGNATURE SIGNATURE_32 ('Q', 'D', 'F', 'T')
typedef struct {
@@ -316,19 +324,33 @@ typedef struct {
#define QUESTION_OPTION_SIGNATURE SIGNATURE_32 ('Q', 'O', 'P', 'T')
typedef struct {
- UINTN Signature;
- LIST_ENTRY Link;
+ UINTN Signature;
+ LIST_ENTRY Link;
- EFI_STRING_ID Text;
- UINT8 Flags;
- EFI_HII_VALUE Value;
- EFI_IMAGE_ID ImageId;
+ EFI_STRING_ID Text;
+ UINT8 Flags;
+ EFI_HII_VALUE Value;
+ EFI_IMAGE_ID ImageId;
- FORM_EXPRESSION *SuppressExpression; // Non-NULL indicates nested inside of SuppressIf
+ FORM_EXPRESSION_LIST *SuppressExpression; // Non-NULL indicates nested inside of SuppressIf
} QUESTION_OPTION;
#define QUESTION_OPTION_FROM_LINK(a) CR (a, QUESTION_OPTION, Link, QUESTION_OPTION_SIGNATURE)
+typedef enum {
+ ExpressFalse = 0,
+ ExpressGrayOut,
+ ExpressSuppress,
+ ExpressDisable
+} EXPRESS_RESULT;
+
+typedef enum {
+ ExpressNone = 0,
+ ExpressForm,
+ ExpressStatement,
+ ExpressOption
+} EXPRESS_LEVEL;
+
#define FORM_BROWSER_STATEMENT_SIGNATURE SIGNATURE_32 ('F', 'S', 'T', 'A')
typedef struct {
@@ -390,9 +412,7 @@ typedef struct {
LIST_ENTRY InconsistentListHead;// nested inconsistent expression list (FORM_EXPRESSION)
LIST_ENTRY NoSubmitListHead; // nested nosubmit expression list (FORM_EXPRESSION)
- FORM_EXPRESSION *GrayOutExpression; // nesting inside of GrayOutIf
- FORM_EXPRESSION *SuppressExpression; // nesting inside of SuppressIf
- FORM_EXPRESSION *DisableExpression; // nesting inside of DisableIf
+ FORM_EXPRESSION_LIST *Expression; // nesting inside of GrayOutIf/DisableIf/SuppressIf
FORM_EXPRESSION *ReadExpression; // nested EFI_IFR_READ, provide this question value by read expression.
FORM_EXPRESSION *WriteExpression; // nested EFI_IFR_WRITE, evaluate write expression after this question value is set.
@@ -417,24 +437,24 @@ typedef struct {
#define STANDARD_MAP_FORM_TYPE 0x01
typedef struct {
- UINTN Signature;
- LIST_ENTRY Link;
+ UINTN Signature;
+ LIST_ENTRY Link;
- UINT16 FormId; // FormId of normal form or formmap form.
- EFI_STRING_ID FormTitle; // FormTile of normal form, or FormMapMethod title of formmap form.
- UINT16 FormType; // Specific form type for the different form.
+ UINT16 FormId; // FormId of normal form or formmap form.
+ EFI_STRING_ID FormTitle; // FormTile of normal form, or FormMapMethod title of formmap form.
+ UINT16 FormType; // Specific form type for the different form.
- EFI_IMAGE_ID ImageId;
+ EFI_IMAGE_ID ImageId;
- BOOLEAN ModalForm; // Whether this is a modal form.
- BOOLEAN Locked; // Whether this form is locked.
+ BOOLEAN ModalForm; // Whether this is a modal form.
+ BOOLEAN Locked; // Whether this form is locked.
- BOOLEAN NvUpdateRequired; // Whether this form has NV update request.
+ BOOLEAN NvUpdateRequired; // Whether this form has NV update request.
- LIST_ENTRY ExpressionListHead; // List of Expressions (FORM_EXPRESSION)
- LIST_ENTRY StatementListHead; // List of Statements and Questions (FORM_BROWSER_STATEMENT)
- LIST_ENTRY ConfigRequestHead; // List of configreques for all storage.
- FORM_EXPRESSION *SuppressExpression; // nesting inside of SuppressIf
+ LIST_ENTRY ExpressionListHead; // List of Expressions (FORM_EXPRESSION)
+ LIST_ENTRY StatementListHead; // List of Statements and Questions (FORM_BROWSER_STATEMENT)
+ LIST_ENTRY ConfigRequestHead; // List of configreques for all storage.
+ FORM_EXPRESSION_LIST *SuppressExpression; // nesting inside of SuppressIf
} FORM_BROWSER_FORM;
#define FORM_BROWSER_FORM_FROM_LINK(a) CR (a, FORM_BROWSER_FORM, Link, FORM_BROWSER_FORM_SIGNATURE)
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c
index 01909e4649..7c6a032f8b 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c
@@ -1,7 +1,7 @@
/** @file
Utility functions for User Interface functions.
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -731,8 +731,10 @@ UiAddMenuOption (
}
MenuOption->Sequence = Index;
- if (Statement->GrayOutExpression != NULL) {
- MenuOption->GrayOut = Statement->GrayOutExpression->Result.Value.b;
+ if (EvaluateExpressionList(Statement->Expression, FALSE, NULL, NULL) == ExpressGrayOut ) {
+ MenuOption->GrayOut = TRUE;
+ } else {
+ MenuOption->GrayOut = FALSE;
}
//
@@ -1999,12 +2001,7 @@ ProcessGotoOpCode (
RefForm = IdToForm (Selection->FormSet, Statement->HiiValue.Value.ref.FormId);
if ((RefForm != NULL) && (RefForm->SuppressExpression != NULL)) {
- Status = EvaluateExpression (Selection->FormSet, RefForm, RefForm->SuppressExpression);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- if (RefForm->SuppressExpression->Result.Value.b) {
+ if (EvaluateExpressionList(RefForm->SuppressExpression, TRUE, Selection->FormSet, RefForm) != ExpressFalse) {
//
// Form is suppressed.
//
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.h b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.h
index 92783182f9..fb84aabfe8 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.h
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.h
@@ -1,7 +1,7 @@
/** @file
Private structure, MACRO and function definitions for User Interface related functionalities.
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -741,6 +741,67 @@ ResetScopeStack (
VOID
);
+/**
+ 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 FORM_EXPRESSION *Pointer,
+ IN EXPRESS_LEVEL Level
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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.
+
+**/
+FORM_EXPRESSION **
+GetConditionalExpressionList (
+ IN EXPRESS_LEVEL Level
+ );
+
+/**
+ 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
+ );
+
/**
Push an Operand onto the Stack
@@ -935,4 +996,28 @@ EvaluateExpression (
IN OUT FORM_EXPRESSION *Expression
);
+/**
+ Return the result of the expression list. Check the expression list and
+ return the highest priority express result.
+ Priority: DisableIf > SuppressIf > GrayOutIf > FALSE
+
+ @param ExpList The input expression list.
+ @param Evaluate Whether need to evaluate the expression first.
+ @param FormSet FormSet associated with this expression. Only
+ needed when Evaluate is TRUE
+ @param Form Form associated with this expression. Only
+ needed when Evaluate is TRUE
+
+ @retval EXPRESS_RESULT Return the higher priority express result.
+ DisableIf > SuppressIf > GrayOutIf > FALSE
+
+**/
+EXPRESS_RESULT
+EvaluateExpressionList (
+ IN FORM_EXPRESSION_LIST *ExpList,
+ IN BOOLEAN Evaluate,
+ IN FORM_BROWSER_FORMSET *FormSet, OPTIONAL
+ IN FORM_BROWSER_FORM *Form OPTIONAL
+ );
+
#endif // _UI_H