+++ /dev/null
-/** @file\r
-\r
-Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- Expression.c\r
-\r
-Abstract:\r
-\r
- Expression evaluation.\r
-\r
-\r
-**/\r
-#include <PiDxe.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/PrintLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Protocol/UnicodeCollation.h>\r
- \r
-#include "UefiIfrParser.h"\r
-\r
-//\r
-// Global stack used to evaluate boolean expresions\r
-//\r
-EFI_HII_VALUE *mOpCodeScopeStack = NULL;\r
-EFI_HII_VALUE *mOpCodeScopeStackEnd = NULL;\r
-EFI_HII_VALUE *mOpCodeScopeStackPointer = NULL;\r
-\r
-EFI_HII_VALUE *mExpressionEvaluationStack = NULL;\r
-EFI_HII_VALUE *mExpressionEvaluationStackEnd = NULL;\r
-EFI_HII_VALUE *mExpressionEvaluationStackPointer = NULL;\r
-\r
-#define EXPRESSION_STACK_SIZE_INCREMENT 0x100\r
-\r
-\r
-/**\r
- Grow size of 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
-\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
-GrowStack (\r
- IN OUT EFI_HII_VALUE **Stack,\r
- IN OUT EFI_HII_VALUE **StackPtr,\r
- IN OUT EFI_HII_VALUE **StackEnd\r
- )\r
-{\r
- UINTN Size;\r
- EFI_HII_VALUE *NewStack;\r
-\r
- Size = EXPRESSION_STACK_SIZE_INCREMENT;\r
- if (*StackPtr != NULL) {\r
- Size = Size + (*StackEnd - *Stack);\r
- }\r
-\r
- NewStack = AllocatePool (Size * sizeof (EFI_HII_VALUE));\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) * sizeof (EFI_HII_VALUE)\r
- );\r
-\r
- //\r
- // Free The Old Stack\r
- //\r
- gBS->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
-/**\r
- Push an element onto the Boolean 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
-PushStack (\r
- IN OUT EFI_HII_VALUE **Stack,\r
- IN OUT EFI_HII_VALUE **StackPtr,\r
- IN OUT EFI_HII_VALUE **StackEnd,\r
- IN EFI_HII_VALUE *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 = GrowStack (Stack, StackPtr, StackEnd);\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 (EFI_HII_VALUE));\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; 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 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
-PopStack (\r
- IN OUT EFI_HII_VALUE **Stack,\r
- IN OUT EFI_HII_VALUE **StackPtr,\r
- IN OUT EFI_HII_VALUE **StackEnd,\r
- OUT EFI_HII_VALUE *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 (EFI_HII_VALUE));\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Reset stack pointer to begin of the stack.\r
-\r
-**/\r
-VOID\r
-ResetScopeStack (\r
- VOID\r
- )\r
-{\r
- mOpCodeScopeStackPointer = mOpCodeScopeStack;\r
-}\r
-\r
-\r
-/**\r
- Push an Operand onto the Stack\r
-\r
- @param Operand Operand to push.\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\r
- stack.\r
-\r
-**/\r
-EFI_STATUS\r
-PushScope (\r
- IN UINT8 Operand\r
- )\r
-{\r
- EFI_HII_VALUE Data;\r
-\r
- Data.Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
- Data.Value.u8 = Operand;\r
-\r
- return PushStack (\r
- &mOpCodeScopeStack,\r
- &mOpCodeScopeStackPointer,\r
- &mOpCodeScopeStackEnd,\r
- &Data\r
- );\r
-}\r
-\r
-\r
-/**\r
- Pop an Operand from the Stack\r
-\r
- @param Operand Operand to pop.\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\r
- stack.\r
-\r
-**/\r
-EFI_STATUS\r
-PopScope (\r
- OUT UINT8 *Operand\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HII_VALUE Data;\r
-\r
- Status = PopStack (\r
- &mOpCodeScopeStack,\r
- &mOpCodeScopeStackPointer,\r
- &mOpCodeScopeStackEnd,\r
- &Data\r
- );\r
-\r
- *Operand = Data.Value.u8;\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Reset stack pointer to begin of the stack.\r
-\r
-**/\r
-VOID\r
-ResetExpressionStack (\r
- VOID\r
- )\r
-{\r
- mExpressionEvaluationStackPointer = mExpressionEvaluationStack;\r
-}\r
-\r
-\r
-/**\r
- Push an Expression value onto the Stack\r
-\r
- @param Value Expression value to push.\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\r
- stack.\r
-\r
-**/\r
-EFI_STATUS\r
-PushExpression (\r
- IN EFI_HII_VALUE *Value\r
- )\r
-{\r
- return PushStack (\r
- &mExpressionEvaluationStack,\r
- &mExpressionEvaluationStackPointer,\r
- &mExpressionEvaluationStackEnd,\r
- Value\r
- );\r
-}\r
-\r
-\r
-/**\r
- Pop an Expression value from the stack.\r
-\r
- @param Value Expression value 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
-PopExpression (\r
- OUT EFI_HII_VALUE *Value\r
- )\r
-{\r
- return PopStack (\r
- &mExpressionEvaluationStack,\r
- &mExpressionEvaluationStackPointer,\r
- &mExpressionEvaluationStackEnd,\r
- Value\r
- );\r
-}\r
-\r
-/**\r
- Zero extend integer/boolean/date/time to UINT64 for comparing.\r
-\r
- @param Value HII Value to be converted.\r
-\r
- @return None.\r
-\r
-**/\r
-VOID\r
-ExtendValueToU64 (\r
- IN EFI_HII_VALUE *Value\r
- )\r
-{\r
- UINT64 Temp;\r
-\r
- Temp = 0;\r
- switch (Value->Type) {\r
- case EFI_IFR_TYPE_NUM_SIZE_8:\r
- Temp = Value->Value.u8;\r
- break;\r
-\r
- case EFI_IFR_TYPE_NUM_SIZE_16:\r
- Temp = Value->Value.u16;\r
- break;\r
-\r
- case EFI_IFR_TYPE_NUM_SIZE_32:\r
- Temp = Value->Value.u32;\r
- break;\r
-\r
- case EFI_IFR_TYPE_BOOLEAN:\r
- Temp = Value->Value.b;\r
- break;\r
-\r
- case EFI_IFR_TYPE_TIME:\r
- Temp = Value->Value.u32 & 0xffffff;\r
- break;\r
-\r
- case EFI_IFR_TYPE_DATE:\r
- Temp = Value->Value.u32;\r
- break;\r
-\r
- default:\r
- return;\r
- }\r
-\r
- Value->Value.u64 = Temp;\r
-}\r