3 Copyright (c) 2007, Intel Corporation
4 All rights reserved. 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 StackPtr 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.
62 IN OUT EFI_HII_VALUE
**Stack
,
63 IN OUT EFI_HII_VALUE
**StackPtr
,
64 IN OUT EFI_HII_VALUE
**StackEnd
68 EFI_HII_VALUE
*NewStack
;
70 Size
= EXPRESSION_STACK_SIZE_INCREMENT
;
71 if (*StackPtr
!= NULL
) {
72 Size
= Size
+ (*StackEnd
- *Stack
);
75 NewStack
= AllocatePool (Size
* sizeof (EFI_HII_VALUE
));
76 if (NewStack
== NULL
) {
77 return EFI_OUT_OF_RESOURCES
;
80 if (*StackPtr
!= NULL
) {
82 // Copy from Old Stack to the New Stack
87 (*StackEnd
- *Stack
) * sizeof (EFI_HII_VALUE
)
93 gBS
->FreePool (*Stack
);
97 // Make the Stack pointer point to the old data in the new stack
99 *StackPtr
= NewStack
+ (*StackPtr
- *Stack
);
101 *StackEnd
= NewStack
+ Size
;
108 Push an element onto the Boolean Stack
110 @param Stack On input: old stack; On output: new stack
111 @param StackPtr On input: old stack pointer; On output: new stack
113 @param StackPtr On input: old stack end; On output: new stack end
114 @param Data Data to push.
116 @retval EFI_SUCCESS Push stack success.
121 IN OUT EFI_HII_VALUE
**Stack
,
122 IN OUT EFI_HII_VALUE
**StackPtr
,
123 IN OUT EFI_HII_VALUE
**StackEnd
,
124 IN EFI_HII_VALUE
*Data
130 // Check for a stack overflow condition
132 if (*StackPtr
>= *StackEnd
) {
136 Status
= GrowStack (Stack
, StackPtr
, StackEnd
);
137 if (EFI_ERROR (Status
)) {
143 // Push the item onto the stack
145 CopyMem (*StackPtr
, Data
, sizeof (EFI_HII_VALUE
));
146 *StackPtr
= *StackPtr
+ 1;
153 Pop an element from the stack.
155 @param Stack On input: old stack; On output: new stack
156 @param StackPtr On input: old stack pointer; On output: new stack
158 @param StackPtr On input: old stack end; On output: new stack end
159 @param Data Data to pop.
161 @retval EFI_SUCCESS The value was popped onto the stack.
162 @retval EFI_ACCESS_DENIED The pop operation underflowed the stack
167 IN OUT EFI_HII_VALUE
**Stack
,
168 IN OUT EFI_HII_VALUE
**StackPtr
,
169 IN OUT EFI_HII_VALUE
**StackEnd
,
170 OUT EFI_HII_VALUE
*Data
174 // Check for a stack underflow condition
176 if (*StackPtr
== *Stack
) {
177 return EFI_ACCESS_DENIED
;
181 // Pop the item off the stack
183 *StackPtr
= *StackPtr
- 1;
184 CopyMem (Data
, *StackPtr
, sizeof (EFI_HII_VALUE
));
189 Reset stack pointer to begin of the stack.
201 mOpCodeScopeStackPointer
= mOpCodeScopeStack
;
206 Push an Operand onto the Stack
208 @param Operand Operand to push.
210 @retval EFI_SUCCESS The value was pushed onto the stack.
211 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
222 Data
.Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
223 Data
.Value
.u8
= Operand
;
227 &mOpCodeScopeStackPointer
,
228 &mOpCodeScopeStackEnd
,
235 Pop an Operand from the Stack
237 @param Operand Operand to pop.
239 @retval EFI_SUCCESS The value was pushed onto the stack.
240 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
254 &mOpCodeScopeStackPointer
,
255 &mOpCodeScopeStackEnd
,
259 *Operand
= Data
.Value
.u8
;
266 Reset stack pointer to begin of the stack.
274 ResetExpressionStack (
278 mExpressionEvaluationStackPointer
= mExpressionEvaluationStack
;
283 Push an Expression value onto the Stack
285 @param Value Expression value to push.
287 @retval EFI_SUCCESS The value was pushed onto the stack.
288 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
294 IN EFI_HII_VALUE
*Value
298 &mExpressionEvaluationStack
,
299 &mExpressionEvaluationStackPointer
,
300 &mExpressionEvaluationStackEnd
,
307 Pop an Expression value from the stack.
309 @param Value Expression value to pop.
311 @retval EFI_SUCCESS The value was popped onto the stack.
312 @retval EFI_ACCESS_DENIED The pop operation underflowed the stack
317 OUT EFI_HII_VALUE
*Value
321 &mExpressionEvaluationStack
,
322 &mExpressionEvaluationStackPointer
,
323 &mExpressionEvaluationStackEnd
,
329 Zero extend integer/boolean/date/time to UINT64 for comparing.
331 @param Value HII Value to be converted.
338 IN EFI_HII_VALUE
*Value
344 switch (Value
->Type
) {
345 case EFI_IFR_TYPE_NUM_SIZE_8
:
346 Temp
= Value
->Value
.u8
;
349 case EFI_IFR_TYPE_NUM_SIZE_16
:
350 Temp
= Value
->Value
.u16
;
353 case EFI_IFR_TYPE_NUM_SIZE_32
:
354 Temp
= Value
->Value
.u32
;
357 case EFI_IFR_TYPE_BOOLEAN
:
358 Temp
= Value
->Value
.b
;
361 case EFI_IFR_TYPE_TIME
:
362 Temp
= Value
->Value
.u32
& 0xffffff;
365 case EFI_IFR_TYPE_DATE
:
366 Temp
= Value
->Value
.u32
;
373 Value
->Value
.u64
= Temp
;