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