3 Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Expression evaluation.
23 #include <Library/BaseLib.h>
24 #include <Library/BaseMemoryLib.h>
25 #include <Library/DebugLib.h>
26 #include <Library/MemoryAllocationLib.h>
27 #include <Library/PrintLib.h>
28 #include <Library/UefiBootServicesTableLib.h>
29 #include <Protocol/UnicodeCollation.h>
31 #include "UefiIfrParser.h"
34 // Global stack used to evaluate boolean expresions
36 EFI_HII_VALUE
*mOpCodeScopeStack
= NULL
;
37 EFI_HII_VALUE
*mOpCodeScopeStackEnd
= NULL
;
38 EFI_HII_VALUE
*mOpCodeScopeStackPointer
= NULL
;
40 EFI_HII_VALUE
*mExpressionEvaluationStack
= NULL
;
41 EFI_HII_VALUE
*mExpressionEvaluationStackEnd
= NULL
;
42 EFI_HII_VALUE
*mExpressionEvaluationStackPointer
= NULL
;
44 #define EXPRESSION_STACK_SIZE_INCREMENT 0x100
48 Grow size of the stack
50 @param Stack On input: old stack; On output: new stack
51 @param StackPtr On input: old stack pointer; On output: new stack
53 @param StackEnd On input: old stack end; On output: new stack end
55 @retval EFI_SUCCESS Grow stack success.
56 @retval EFI_OUT_OF_RESOURCES No enough memory for stack space.
61 IN OUT EFI_HII_VALUE
**Stack
,
62 IN OUT EFI_HII_VALUE
**StackPtr
,
63 IN OUT EFI_HII_VALUE
**StackEnd
67 EFI_HII_VALUE
*NewStack
;
69 Size
= EXPRESSION_STACK_SIZE_INCREMENT
;
70 if (*StackPtr
!= NULL
) {
71 Size
= Size
+ (*StackEnd
- *Stack
);
74 NewStack
= AllocatePool (Size
* sizeof (EFI_HII_VALUE
));
75 if (NewStack
== NULL
) {
76 return EFI_OUT_OF_RESOURCES
;
79 if (*StackPtr
!= NULL
) {
81 // Copy from Old Stack to the New Stack
86 (*StackEnd
- *Stack
) * sizeof (EFI_HII_VALUE
)
92 gBS
->FreePool (*Stack
);
96 // Make the Stack pointer point to the old data in the new stack
98 *StackPtr
= NewStack
+ (*StackPtr
- *Stack
);
100 *StackEnd
= NewStack
+ Size
;
107 Push an element onto the Boolean Stack
109 @param Stack On input: old stack; On output: new stack
110 @param StackPtr On input: old stack pointer; On output: new stack
112 @param StackEnd On input: old stack end; On output: new stack end
113 @param Data Data to push.
115 @retval EFI_SUCCESS Push stack success.
120 IN OUT EFI_HII_VALUE
**Stack
,
121 IN OUT EFI_HII_VALUE
**StackPtr
,
122 IN OUT EFI_HII_VALUE
**StackEnd
,
123 IN EFI_HII_VALUE
*Data
129 // Check for a stack overflow condition
131 if (*StackPtr
>= *StackEnd
) {
135 Status
= GrowStack (Stack
, StackPtr
, StackEnd
);
136 if (EFI_ERROR (Status
)) {
142 // Push the item onto the stack
144 CopyMem (*StackPtr
, Data
, sizeof (EFI_HII_VALUE
));
145 *StackPtr
= *StackPtr
+ 1;
152 Pop an element from the stack.
154 @param Stack On input: old stack; On output: new stack
155 @param StackPtr On input: old stack pointer; On output: new stack
157 @param StackEnd On input: old stack end; On output: new stack end
158 @param Data Data to pop.
160 @retval EFI_SUCCESS The value was popped onto the stack.
161 @retval EFI_ACCESS_DENIED The pop operation underflowed the stack
166 IN OUT EFI_HII_VALUE
**Stack
,
167 IN OUT EFI_HII_VALUE
**StackPtr
,
168 IN OUT EFI_HII_VALUE
**StackEnd
,
169 OUT EFI_HII_VALUE
*Data
173 // Check for a stack underflow condition
175 if (*StackPtr
== *Stack
) {
176 return EFI_ACCESS_DENIED
;
180 // Pop the item off the stack
182 *StackPtr
= *StackPtr
- 1;
183 CopyMem (Data
, *StackPtr
, sizeof (EFI_HII_VALUE
));
188 Reset stack pointer to begin of the stack.
196 mOpCodeScopeStackPointer
= mOpCodeScopeStack
;
201 Push an Operand onto the Stack
203 @param Operand Operand to push.
205 @retval EFI_SUCCESS The value was pushed onto the stack.
206 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
217 Data
.Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
218 Data
.Value
.u8
= Operand
;
222 &mOpCodeScopeStackPointer
,
223 &mOpCodeScopeStackEnd
,
230 Pop an Operand from the Stack
232 @param Operand Operand to pop.
234 @retval EFI_SUCCESS The value was pushed onto the stack.
235 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
249 &mOpCodeScopeStackPointer
,
250 &mOpCodeScopeStackEnd
,
254 *Operand
= Data
.Value
.u8
;
261 Reset stack pointer to begin of the stack.
265 ResetExpressionStack (
269 mExpressionEvaluationStackPointer
= mExpressionEvaluationStack
;
274 Push an Expression value onto the Stack
276 @param Value Expression value to push.
278 @retval EFI_SUCCESS The value was pushed onto the stack.
279 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
285 IN EFI_HII_VALUE
*Value
289 &mExpressionEvaluationStack
,
290 &mExpressionEvaluationStackPointer
,
291 &mExpressionEvaluationStackEnd
,
298 Pop an Expression value from the stack.
300 @param Value Expression value to pop.
302 @retval EFI_SUCCESS The value was popped onto the stack.
303 @retval EFI_ACCESS_DENIED The pop operation underflowed the stack
308 OUT EFI_HII_VALUE
*Value
312 &mExpressionEvaluationStack
,
313 &mExpressionEvaluationStackPointer
,
314 &mExpressionEvaluationStackEnd
,
320 Zero extend integer/boolean/date/time to UINT64 for comparing.
322 @param Value HII Value to be converted.
329 IN EFI_HII_VALUE
*Value
335 switch (Value
->Type
) {
336 case EFI_IFR_TYPE_NUM_SIZE_8
:
337 Temp
= Value
->Value
.u8
;
340 case EFI_IFR_TYPE_NUM_SIZE_16
:
341 Temp
= Value
->Value
.u16
;
344 case EFI_IFR_TYPE_NUM_SIZE_32
:
345 Temp
= Value
->Value
.u32
;
348 case EFI_IFR_TYPE_BOOLEAN
:
349 Temp
= Value
->Value
.b
;
352 case EFI_IFR_TYPE_TIME
:
353 Temp
= Value
->Value
.u32
& 0xffffff;
356 case EFI_IFR_TYPE_DATE
:
357 Temp
= Value
->Value
.u32
;
364 Value
->Value
.u64
= Temp
;