]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Compatibility/FrameworkHiiOnUefiHiiThunk/UefiIfrParserExpression.c
Maintainers.txt: Remove EdkCompatibilityPkg information
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiOnUefiHiiThunk / UefiIfrParserExpression.c
1 /** @file
2
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
8
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.
11
12 Module Name:
13
14 Expression.c
15
16 Abstract:
17
18 Expression evaluation.
19
20
21 **/
22 #include <PiDxe.h>
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>
30
31 #include "UefiIfrParser.h"
32
33 //
34 // Global stack used to evaluate boolean expresions
35 //
36 EFI_HII_VALUE *mOpCodeScopeStack = NULL;
37 EFI_HII_VALUE *mOpCodeScopeStackEnd = NULL;
38 EFI_HII_VALUE *mOpCodeScopeStackPointer = NULL;
39
40 EFI_HII_VALUE *mExpressionEvaluationStack = NULL;
41 EFI_HII_VALUE *mExpressionEvaluationStackEnd = NULL;
42 EFI_HII_VALUE *mExpressionEvaluationStackPointer = NULL;
43
44 #define EXPRESSION_STACK_SIZE_INCREMENT 0x100
45
46
47 /**
48 Grow size of the stack
49
50 @param Stack On input: old stack; On output: new stack
51 @param StackPtr On input: old stack pointer; On output: new stack
52 pointer
53 @param StackEnd On input: old stack end; On output: new stack end
54
55 @retval EFI_SUCCESS Grow stack success.
56 @retval EFI_OUT_OF_RESOURCES No enough memory for stack space.
57
58 **/
59 EFI_STATUS
60 GrowStack (
61 IN OUT EFI_HII_VALUE **Stack,
62 IN OUT EFI_HII_VALUE **StackPtr,
63 IN OUT EFI_HII_VALUE **StackEnd
64 )
65 {
66 UINTN Size;
67 EFI_HII_VALUE *NewStack;
68
69 Size = EXPRESSION_STACK_SIZE_INCREMENT;
70 if (*StackPtr != NULL) {
71 Size = Size + (*StackEnd - *Stack);
72 }
73
74 NewStack = AllocatePool (Size * sizeof (EFI_HII_VALUE));
75 if (NewStack == NULL) {
76 return EFI_OUT_OF_RESOURCES;
77 }
78
79 if (*StackPtr != NULL) {
80 //
81 // Copy from Old Stack to the New Stack
82 //
83 CopyMem (
84 NewStack,
85 *Stack,
86 (*StackEnd - *Stack) * sizeof (EFI_HII_VALUE)
87 );
88
89 //
90 // Free The Old Stack
91 //
92 gBS->FreePool (*Stack);
93 }
94
95 //
96 // Make the Stack pointer point to the old data in the new stack
97 //
98 *StackPtr = NewStack + (*StackPtr - *Stack);
99 *Stack = NewStack;
100 *StackEnd = NewStack + Size;
101
102 return EFI_SUCCESS;
103 }
104
105
106 /**
107 Push an element onto the Boolean Stack
108
109 @param Stack On input: old stack; On output: new stack
110 @param StackPtr On input: old stack pointer; On output: new stack
111 pointer
112 @param StackEnd On input: old stack end; On output: new stack end
113 @param Data Data to push.
114
115 @retval EFI_SUCCESS Push stack success.
116
117 **/
118 EFI_STATUS
119 PushStack (
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
124 )
125 {
126 EFI_STATUS Status;
127
128 //
129 // Check for a stack overflow condition
130 //
131 if (*StackPtr >= *StackEnd) {
132 //
133 // Grow the stack
134 //
135 Status = GrowStack (Stack, StackPtr, StackEnd);
136 if (EFI_ERROR (Status)) {
137 return Status;
138 }
139 }
140
141 //
142 // Push the item onto the stack
143 //
144 CopyMem (*StackPtr, Data, sizeof (EFI_HII_VALUE));
145 *StackPtr = *StackPtr + 1;
146
147 return EFI_SUCCESS;
148 }
149
150
151 /**
152 Pop an element from the stack.
153
154 @param Stack On input: old stack; On output: new stack
155 @param StackPtr On input: old stack pointer; On output: new stack
156 pointer
157 @param StackEnd On input: old stack end; On output: new stack end
158 @param Data Data to pop.
159
160 @retval EFI_SUCCESS The value was popped onto the stack.
161 @retval EFI_ACCESS_DENIED The pop operation underflowed the stack
162
163 **/
164 EFI_STATUS
165 PopStack (
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
170 )
171 {
172 //
173 // Check for a stack underflow condition
174 //
175 if (*StackPtr == *Stack) {
176 return EFI_ACCESS_DENIED;
177 }
178
179 //
180 // Pop the item off the stack
181 //
182 *StackPtr = *StackPtr - 1;
183 CopyMem (Data, *StackPtr, sizeof (EFI_HII_VALUE));
184 return EFI_SUCCESS;
185 }
186
187 /**
188 Reset stack pointer to begin of the stack.
189
190 **/
191 VOID
192 ResetScopeStack (
193 VOID
194 )
195 {
196 mOpCodeScopeStackPointer = mOpCodeScopeStack;
197 }
198
199
200 /**
201 Push an Operand onto the Stack
202
203 @param Operand Operand to push.
204
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
207 stack.
208
209 **/
210 EFI_STATUS
211 PushScope (
212 IN UINT8 Operand
213 )
214 {
215 EFI_HII_VALUE Data;
216
217 Data.Type = EFI_IFR_TYPE_NUM_SIZE_8;
218 Data.Value.u8 = Operand;
219
220 return PushStack (
221 &mOpCodeScopeStack,
222 &mOpCodeScopeStackPointer,
223 &mOpCodeScopeStackEnd,
224 &Data
225 );
226 }
227
228
229 /**
230 Pop an Operand from the Stack
231
232 @param Operand Operand to pop.
233
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
236 stack.
237
238 **/
239 EFI_STATUS
240 PopScope (
241 OUT UINT8 *Operand
242 )
243 {
244 EFI_STATUS Status;
245 EFI_HII_VALUE Data;
246
247 Status = PopStack (
248 &mOpCodeScopeStack,
249 &mOpCodeScopeStackPointer,
250 &mOpCodeScopeStackEnd,
251 &Data
252 );
253
254 *Operand = Data.Value.u8;
255
256 return Status;
257 }
258
259
260 /**
261 Reset stack pointer to begin of the stack.
262
263 **/
264 VOID
265 ResetExpressionStack (
266 VOID
267 )
268 {
269 mExpressionEvaluationStackPointer = mExpressionEvaluationStack;
270 }
271
272
273 /**
274 Push an Expression value onto the Stack
275
276 @param Value Expression value to push.
277
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
280 stack.
281
282 **/
283 EFI_STATUS
284 PushExpression (
285 IN EFI_HII_VALUE *Value
286 )
287 {
288 return PushStack (
289 &mExpressionEvaluationStack,
290 &mExpressionEvaluationStackPointer,
291 &mExpressionEvaluationStackEnd,
292 Value
293 );
294 }
295
296
297 /**
298 Pop an Expression value from the stack.
299
300 @param Value Expression value to pop.
301
302 @retval EFI_SUCCESS The value was popped onto the stack.
303 @retval EFI_ACCESS_DENIED The pop operation underflowed the stack
304
305 **/
306 EFI_STATUS
307 PopExpression (
308 OUT EFI_HII_VALUE *Value
309 )
310 {
311 return PopStack (
312 &mExpressionEvaluationStack,
313 &mExpressionEvaluationStackPointer,
314 &mExpressionEvaluationStackEnd,
315 Value
316 );
317 }
318
319 /**
320 Zero extend integer/boolean/date/time to UINT64 for comparing.
321
322 @param Value HII Value to be converted.
323
324 @return None.
325
326 **/
327 VOID
328 ExtendValueToU64 (
329 IN EFI_HII_VALUE *Value
330 )
331 {
332 UINT64 Temp;
333
334 Temp = 0;
335 switch (Value->Type) {
336 case EFI_IFR_TYPE_NUM_SIZE_8:
337 Temp = Value->Value.u8;
338 break;
339
340 case EFI_IFR_TYPE_NUM_SIZE_16:
341 Temp = Value->Value.u16;
342 break;
343
344 case EFI_IFR_TYPE_NUM_SIZE_32:
345 Temp = Value->Value.u32;
346 break;
347
348 case EFI_IFR_TYPE_BOOLEAN:
349 Temp = Value->Value.b;
350 break;
351
352 case EFI_IFR_TYPE_TIME:
353 Temp = Value->Value.u32 & 0xffffff;
354 break;
355
356 case EFI_IFR_TYPE_DATE:
357 Temp = Value->Value.u32;
358 break;
359
360 default:
361 return;
362 }
363
364 Value->Value.u64 = Temp;
365 }