EFI_HII_VALUE *mMapExpressionListEnd = NULL;\r
EFI_HII_VALUE *mMapExpressionListPointer = NULL;\r
\r
+FORM_EXPRESSION **mFormExpressionStack = NULL;\r
+FORM_EXPRESSION **mFormExpressionEnd = NULL;\r
+FORM_EXPRESSION **mFormExpressionPointer = NULL;\r
+\r
+FORM_EXPRESSION **mStatementExpressionStack = NULL;\r
+FORM_EXPRESSION **mStatementExpressionEnd = NULL;\r
+FORM_EXPRESSION **mStatementExpressionPointer = NULL;\r
+\r
+FORM_EXPRESSION **mOptionExpressionStack = NULL;\r
+FORM_EXPRESSION **mOptionExpressionEnd = NULL;\r
+FORM_EXPRESSION **mOptionExpressionPointer = NULL;\r
+\r
+\r
//\r
// Unicode collation protocol interface\r
//\r
VOID\r
)\r
{\r
- mCurrentExpressionPointer = mCurrentExpressionStack;\r
+ mCurrentExpressionPointer = mCurrentExpressionStack;\r
+ mFormExpressionPointer = mFormExpressionStack;\r
+ mStatementExpressionPointer = mStatementExpressionStack;\r
+ mOptionExpressionPointer = mOptionExpressionStack; \r
}\r
\r
\r
}\r
\r
\r
+/**\r
+ Grow size of the stack.\r
+\r
+ This is an internal function.\r
+\r
+ @param Stack On input: old stack; On output: new stack\r
+ @param StackPtr On input: old stack pointer; On output: new stack\r
+ pointer\r
+ @param StackEnd On input: old stack end; On output: new stack end\r
+ @param MemberSize The stack member size.\r
+ \r
+ @retval EFI_SUCCESS Grow stack success.\r
+ @retval EFI_OUT_OF_RESOURCES No enough memory for stack space.\r
+\r
+**/\r
+EFI_STATUS\r
+GrowConditionalStack (\r
+ IN OUT FORM_EXPRESSION ***Stack,\r
+ IN OUT FORM_EXPRESSION ***StackPtr,\r
+ IN OUT FORM_EXPRESSION ***StackEnd,\r
+ IN UINTN MemberSize\r
+ )\r
+{\r
+ UINTN Size;\r
+ FORM_EXPRESSION **NewStack;\r
+\r
+ Size = EXPRESSION_STACK_SIZE_INCREMENT;\r
+ if (*StackPtr != NULL) {\r
+ Size = Size + (*StackEnd - *Stack);\r
+ }\r
+\r
+ NewStack = AllocatePool (Size * MemberSize);\r
+ if (NewStack == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ if (*StackPtr != NULL) {\r
+ //\r
+ // Copy from Old Stack to the New Stack\r
+ //\r
+ CopyMem (\r
+ NewStack,\r
+ *Stack,\r
+ (*StackEnd - *Stack) * MemberSize\r
+ );\r
+\r
+ //\r
+ // Free The Old Stack\r
+ //\r
+ FreePool (*Stack);\r
+ }\r
+\r
+ //\r
+ // Make the Stack pointer point to the old data in the new stack\r
+ //\r
+ *StackPtr = NewStack + (*StackPtr - *Stack);\r
+ *Stack = NewStack;\r
+ *StackEnd = NewStack + Size;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Push an element onto the Stack.\r
+\r
+ @param Stack On input: old stack; On output: new stack\r
+ @param StackPtr On input: old stack pointer; On output: new stack\r
+ pointer\r
+ @param StackEnd On input: old stack end; On output: new stack end\r
+ @param Data Data to push.\r
+\r
+ @retval EFI_SUCCESS Push stack success.\r
+\r
+**/\r
+EFI_STATUS\r
+PushConditionalStack (\r
+ IN OUT FORM_EXPRESSION ***Stack,\r
+ IN OUT FORM_EXPRESSION ***StackPtr,\r
+ IN OUT FORM_EXPRESSION ***StackEnd,\r
+ IN FORM_EXPRESSION **Data\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Check for a stack overflow condition\r
+ //\r
+ if (*StackPtr >= *StackEnd) {\r
+ //\r
+ // Grow the stack\r
+ //\r
+ Status = GrowConditionalStack (Stack, StackPtr, StackEnd, sizeof (FORM_EXPRESSION *));\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Push the item onto the stack\r
+ //\r
+ CopyMem (*StackPtr, Data, sizeof (FORM_EXPRESSION *)); \r
+ *StackPtr = *StackPtr + 1;\r
+\r
+ return EFI_SUCCESS;\r
+\r
+}\r
+\r
+/**\r
+ Pop an element from the stack.\r
+\r
+ @param Stack On input: old stack\r
+ @param StackPtr On input: old stack pointer; On output: new stack pointer\r
+ @param Data Data to pop.\r
+\r
+ @retval EFI_SUCCESS The value was popped onto the stack.\r
+ @retval EFI_ACCESS_DENIED The pop operation underflowed the stack\r
+\r
+**/\r
+EFI_STATUS\r
+PopConditionalStack (\r
+ IN FORM_EXPRESSION **Stack,\r
+ IN OUT FORM_EXPRESSION ***StackPtr,\r
+ OUT FORM_EXPRESSION **Data\r
+ )\r
+{\r
+ //\r
+ // Check for a stack underflow condition\r
+ //\r
+ if (*StackPtr == Stack) {\r
+ return EFI_ACCESS_DENIED;\r
+ }\r
+\r
+ //\r
+ // Pop the item off the stack\r
+ //\r
+ *StackPtr = *StackPtr - 1;\r
+ CopyMem (Data, *StackPtr, sizeof (FORM_EXPRESSION *));\r
+ return EFI_SUCCESS;\r
+\r
+}\r
+\r
+/**\r
+ Get the expression list count.\r
+ \r
+ @param Level Which type this expression belong to. Form, \r
+ statement or option?\r
+\r
+ @retval >=0 The expression count\r
+ @retval -1 Input parameter error.\r
+\r
+**/\r
+INTN \r
+GetConditionalExpressionCount (\r
+ IN EXPRESS_LEVEL Level\r
+ )\r
+{\r
+ switch (Level) {\r
+ case ExpressForm:\r
+ return mFormExpressionPointer - mFormExpressionStack;\r
+ case ExpressStatement:\r
+ return mStatementExpressionPointer - mStatementExpressionStack;\r
+ case ExpressOption:\r
+ return mOptionExpressionPointer - mOptionExpressionStack;\r
+ default:\r
+ ASSERT (FALSE);\r
+ return -1;\r
+ } \r
+}\r
+\r
+/**\r
+ Get the expression Buffer pointer.\r
+ \r
+ @param Level Which type this expression belong to. Form, \r
+ statement or option?\r
+\r
+ @retval The start pointer of the expression buffer or NULL.\r
+\r
+**/\r
+FORM_EXPRESSION **\r
+GetConditionalExpressionList (\r
+ IN EXPRESS_LEVEL Level\r
+ )\r
+{\r
+ switch (Level) {\r
+ case ExpressForm:\r
+ return mFormExpressionStack;\r
+ case ExpressStatement:\r
+ return mStatementExpressionStack;\r
+ case ExpressOption:\r
+ return mOptionExpressionStack;\r
+ default:\r
+ ASSERT (FALSE);\r
+ return NULL;\r
+ } \r
+}\r
+\r
+\r
+/**\r
+ Push the expression options onto the Stack.\r
+\r
+ @param Pointer Pointer to the current expression.\r
+ @param Level Which type this expression belong to. Form, \r
+ statement or option?\r
+\r
+ @retval EFI_SUCCESS The value was pushed onto the stack.\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.\r
+\r
+**/\r
+EFI_STATUS\r
+PushConditionalExpression (\r
+ IN FORM_EXPRESSION *Pointer,\r
+ IN EXPRESS_LEVEL Level\r
+ )\r
+{\r
+ switch (Level) {\r
+ case ExpressForm:\r
+ return PushConditionalStack (\r
+ &mFormExpressionStack,\r
+ &mFormExpressionPointer,\r
+ &mFormExpressionEnd,\r
+ &Pointer\r
+ );\r
+ case ExpressStatement:\r
+ return PushConditionalStack (\r
+ &mStatementExpressionStack,\r
+ &mStatementExpressionPointer,\r
+ &mStatementExpressionEnd,\r
+ &Pointer\r
+ );\r
+ case ExpressOption:\r
+ return PushConditionalStack (\r
+ &mOptionExpressionStack,\r
+ &mOptionExpressionPointer,\r
+ &mOptionExpressionEnd,\r
+ &Pointer\r
+ );\r
+ default:\r
+ ASSERT (FALSE);\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+}\r
+\r
+/**\r
+ Pop the expression options from the Stack\r
+\r
+ @param Level Which type this expression belong to. Form, \r
+ statement or option?\r
+\r
+ @retval EFI_SUCCESS The value was pushed onto the stack.\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.\r
+\r
+**/\r
+EFI_STATUS\r
+PopConditionalExpression (\r
+ IN EXPRESS_LEVEL Level\r
+ )\r
+{\r
+ FORM_EXPRESSION *Pointer;\r
+\r
+ switch (Level) {\r
+ case ExpressForm:\r
+ return PopConditionalStack (\r
+ mFormExpressionStack,\r
+ &mFormExpressionPointer,\r
+ &Pointer\r
+ );\r
+\r
+ case ExpressStatement:\r
+ return PopConditionalStack (\r
+ mStatementExpressionStack,\r
+ &mStatementExpressionPointer,\r
+ &Pointer\r
+ );\r
+\r
+ case ExpressOption:\r
+ return PopConditionalStack (\r
+ mOptionExpressionStack,\r
+ &mOptionExpressionPointer,\r
+ &Pointer\r
+ );\r
+\r
+ default:\r
+ ASSERT (FALSE);\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+}\r
+\r
+\r
/**\r
Push the list of map expression onto the Stack\r
\r
\r
return Status;\r
}\r
+\r
+/**\r
+ Return the result of the expression list. Check the expression list and \r
+ return the highest priority express result. \r
+ Priority: DisableIf > SuppressIf > GrayOutIf > FALSE\r
+\r
+ @param ExpList The input expression list.\r
+ @param Evaluate Whether need to evaluate the expression first.\r
+ @param FormSet FormSet associated with this expression.\r
+ @param Form Form associated with this expression. \r
+\r
+ @retval EXPRESS_RESULT Return the higher priority express result. \r
+ DisableIf > SuppressIf > GrayOutIf > FALSE\r
+\r
+**/\r
+EXPRESS_RESULT \r
+EvaluateExpressionList (\r
+ IN FORM_EXPRESSION_LIST *ExpList,\r
+ IN BOOLEAN Evaluate,\r
+ IN FORM_BROWSER_FORMSET *FormSet, OPTIONAL\r
+ IN FORM_BROWSER_FORM *Form OPTIONAL\r
+ )\r
+{\r
+ UINTN Index;\r
+ EXPRESS_RESULT ReturnVal;\r
+ EXPRESS_RESULT CompareOne;\r
+ EFI_STATUS Status;\r
+\r
+ if (ExpList == NULL) {\r
+ return ExpressFalse;\r
+ }\r
+\r
+ ASSERT(ExpList->Signature == FORM_EXPRESSION_LIST_SIGNATURE);\r
+ Index = 0;\r
+\r
+ //\r
+ // Check whether need to evaluate the expression first.\r
+ //\r
+ if (Evaluate) { \r
+ while (ExpList->Count > Index) {\r
+ Status = EvaluateExpression (FormSet, Form, ExpList->Expression[Index++]);\r
+ if (EFI_ERROR (Status)) {\r
+ return ExpressFalse;\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // Run the list of expressions.\r
+ //\r
+ ReturnVal = ExpressFalse;\r
+ for (Index = 0; Index < ExpList->Count; Index++) {\r
+ if (ExpList->Expression[Index]->Result.Type == EFI_IFR_TYPE_BOOLEAN &&\r
+ ExpList->Expression[Index]->Result.Value.b) {\r
+ switch (ExpList->Expression[Index]->Type) {\r
+ case EFI_HII_EXPRESSION_SUPPRESS_IF:\r
+ CompareOne = ExpressSuppress;\r
+ break;\r
+\r
+ case EFI_HII_EXPRESSION_GRAY_OUT_IF:\r
+ CompareOne = ExpressGrayOut;\r
+ break;\r
+\r
+ case EFI_HII_EXPRESSION_DISABLE_IF:\r
+ CompareOne = ExpressDisable;\r
+ break;\r
+\r
+ default:\r
+ return ExpressFalse; \r
+ }\r
+\r
+ ReturnVal = ReturnVal < CompareOne ? CompareOne : ReturnVal;\r
+ }\r
+ }\r
+ \r
+ return ReturnVal;\r
+}\r