summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
diff options
context:
space:
mode:
authorydong10 <ydong10@6f19259b-4bc3-4df7-8a09-765794883524>2012-01-31 07:17:42 +0000
committerydong10 <ydong10@6f19259b-4bc3-4df7-8a09-765794883524>2012-01-31 07:17:42 +0000
commit31585af434890ea0db774b6c5fa827ac354bee60 (patch)
tree2e5d0123b06f99f0632966b3b06dffa7f995ecb8 /MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
parent4641e70095e19616fe318d6753baf3dc11dbf569 (diff)
downloadedk2-platforms-31585af434890ea0db774b6c5fa827ac354bee60.tar.xz
Enable nest for suppressif/grayoutif/diableif for form/question/option.
Signed-off-by: ydong10 Reviewed-by: lgao4 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12972 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdeModulePkg/Universal/SetupBrowserDxe/Expression.c')
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Expression.c383
1 files changed, 382 insertions, 1 deletions
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;
}
@@ -268,6 +284,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
@param Pointer Pointer to the list of map expression to be pushed.
@@ -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;
+}