]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellLevel1CommandsLib/If.c
Add CryptoPkg (from UDK2010.UP3)
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel1CommandsLib / If.c
CommitLineData
a405b86d 1/** @file\r
2 Main file for If and else shell level 1 function.\r
3\r
4 Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "UefiShellLevel1CommandsLib.h"\r
16#include <Library/PrintLib.h>\r
17\r
18\r
19\r
20\r
21typedef enum {\r
22 END_TAG_OR,\r
23 END_TAG_AND,\r
24 END_TAG_THEN,\r
25 END_TAG_MAX\r
26} END_TAG_TYPE;\r
27\r
28typedef enum {\r
29 OPERATOR_GT,\r
30 OPERATOR_LT,\r
31 OPERATOR_EQ,\r
32 OPERATOR_NE,\r
33 OPERATOR_GE,\r
34 OPERATOR_LE,\r
35 OPERATOR_UGT,\r
36 OPERATOR_ULT,\r
37 OPERATOR_UGE,\r
38 OPERATOR_ULE,\r
39 OPERATOR_MAX\r
40} BIN_OPERATOR_TYPE;\r
41\r
42BOOLEAN\r
43EFIAPI\r
44IsNextFragment (\r
45 IN CONST CHAR16 **Statement,\r
46 IN CONST CHAR16 *Fragment\r
47 )\r
48{\r
49 CHAR16 *Tester;\r
50\r
51 Tester = NULL;\r
52\r
53 Tester = StrnCatGrow(&Tester, NULL, *Statement, StrLen(Fragment));\r
54 ASSERT(Tester != NULL);\r
55 Tester[StrLen(Fragment)] = CHAR_NULL;\r
56 if (gUnicodeCollation->StriColl(\r
57 gUnicodeCollation,\r
58 (CHAR16*)Fragment,\r
59 Tester) == 0) {\r
60 //\r
61 // increment the string pointer to the end of what we found and then chop off spaces...\r
62 //\r
63 *Statement+=StrLen(Fragment);\r
64 while (*Statement[0] == L' ') {\r
1ca79586 65 (*Statement)++;\r
a405b86d 66 }\r
67 FreePool(Tester);\r
68 return (TRUE);\r
69 }\r
70 FreePool(Tester);\r
71 return (FALSE);\r
72}\r
73\r
74BOOLEAN\r
75EFIAPI\r
76IsValidProfile (\r
77 IN CONST CHAR16 *String\r
78 )\r
79{\r
80 CONST CHAR16 *ProfilesString;\r
81 CONST CHAR16 *TempLocation;\r
82\r
83 ProfilesString = ShellGetEnvironmentVariable(L"profiles");\r
84 TempLocation = StrStr(ProfilesString, String);\r
85 if ((TempLocation != NULL) && (*(TempLocation-1) == L';') && (*(TempLocation+StrLen(String)) == L';')) {\r
86 return (TRUE);\r
87 }\r
88 return (FALSE);\r
89}\r
90\r
91BOOLEAN\r
92EFIAPI\r
93TestOperation (\r
94 IN CONST CHAR16 *Compare1,\r
95 IN CONST CHAR16 *Compare2,\r
96 IN CONST BIN_OPERATOR_TYPE BinOp,\r
97 IN CONST BOOLEAN CaseInsensitive,\r
98 IN CONST BOOLEAN ForceStringCompare\r
99 )\r
100{\r
101 INTN Cmp1;\r
102 INTN Cmp2;\r
103\r
104 //\r
105 // "Compare1 BinOp Compare2"\r
106 //\r
107 switch (BinOp) {\r
108 case OPERATOR_UGT:\r
109 case OPERATOR_GT:\r
110 if (ForceStringCompare || !ShellIsHexOrDecimalNumber(Compare1, FALSE, FALSE) || !ShellIsHexOrDecimalNumber(Compare2, FALSE, FALSE)) {\r
111 //\r
112 // string compare\r
113 //\r
114 if ((CaseInsensitive && StringNoCaseCompare(&Compare1, &Compare2) > 0) || (StringCompare(&Compare1, &Compare2) > 0)) {\r
115 return (TRUE);\r
116 }\r
117 } else {\r
118 //\r
119 // numeric compare\r
120 //\r
121 if (Compare1[0] == L'-') {\r
122 Cmp1 = 0 - (INTN)StrDecimalToUintn(Compare1+1);\r
123 } else {\r
124 Cmp1 = (INTN)StrDecimalToUintn(Compare1);\r
125 }\r
126 if (Compare2[0] == L'-') {\r
127 Cmp2 = 0 - (INTN)StrDecimalToUintn(Compare2+1);\r
128 } else {\r
129 Cmp2 = (INTN)StrDecimalToUintn(Compare2);\r
130 }\r
131 if (BinOp == OPERATOR_GT) {\r
132 if (Cmp1 > Cmp2) {\r
133 return (TRUE);\r
134 }\r
135 } else {\r
136 if ((UINTN)Cmp1 > (UINTN)Cmp2) {\r
137 return (TRUE);\r
138 }\r
139 }\r
140 }\r
141 return (FALSE);\r
142 break;\r
143 case OPERATOR_ULT:\r
144 case OPERATOR_LT:\r
145 if (ForceStringCompare || !ShellIsHexOrDecimalNumber(Compare1, FALSE, FALSE) || !ShellIsHexOrDecimalNumber(Compare2, FALSE, FALSE)) {\r
146 //\r
147 // string compare\r
148 //\r
149 if ((CaseInsensitive && StringNoCaseCompare(&Compare1, &Compare2) < 0) || (StringCompare(&Compare1, &Compare2) < 0)) {\r
150 return (TRUE);\r
151 }\r
152 } else {\r
153 //\r
154 // numeric compare\r
155 //\r
156 if (Compare1[0] == L'-') {\r
157 Cmp1 = 0 - (INTN)StrDecimalToUintn(Compare1+1);\r
158 } else {\r
159 Cmp1 = (INTN)StrDecimalToUintn(Compare1);\r
160 }\r
161 if (Compare2[0] == L'-') {\r
162 Cmp2 = 0 - (INTN)StrDecimalToUintn(Compare2+1);\r
163 } else {\r
164 Cmp2 = (INTN)StrDecimalToUintn(Compare2);\r
165 }\r
166 if (BinOp == OPERATOR_LT) {\r
167 if (Cmp1 < Cmp2) {\r
168 return (TRUE);\r
169 }\r
170 } else {\r
171 if ((UINTN)Cmp1 < (UINTN)Cmp2) {\r
172 return (TRUE);\r
173 }\r
174 }\r
175\r
176 }\r
177 return (FALSE);\r
178 break;\r
179 case OPERATOR_EQ:\r
180 if (ForceStringCompare || !ShellIsHexOrDecimalNumber(Compare1, FALSE, FALSE) || !ShellIsHexOrDecimalNumber(Compare2, FALSE, FALSE)) {\r
181 //\r
182 // string compare\r
183 //\r
184 if ((CaseInsensitive && StringNoCaseCompare(&Compare1, &Compare2) == 0) || (StringCompare(&Compare1, &Compare2) == 0)) {\r
185 return (TRUE);\r
186 }\r
187 } else {\r
188 //\r
189 // numeric compare\r
190 //\r
191 if (Compare1[0] == L'-') {\r
192 Cmp1 = 0 - (INTN)ShellStrToUintn(Compare1+1);\r
193 } else {\r
194 Cmp1 = (INTN)ShellStrToUintn(Compare1);\r
195 }\r
196 if (Compare2[0] == L'-') {\r
197 Cmp2 = 0 - (INTN)ShellStrToUintn(Compare2+1);\r
198 } else {\r
199 Cmp2 = (INTN)ShellStrToUintn(Compare2);\r
200 }\r
201 if (Cmp1 == Cmp2) {\r
202 return (TRUE);\r
203 }\r
204 }\r
205 return (FALSE);\r
206 break;\r
207 case OPERATOR_NE:\r
208 if (ForceStringCompare || !ShellIsHexOrDecimalNumber(Compare1, FALSE, FALSE) || !ShellIsHexOrDecimalNumber(Compare2, FALSE, FALSE)) {\r
209 //\r
210 // string compare\r
211 //\r
212 if ((CaseInsensitive && StringNoCaseCompare(&Compare1, &Compare2) != 0) || (StringCompare(&Compare1, &Compare2) != 0)) {\r
213 return (TRUE);\r
214 }\r
215 } else {\r
216 //\r
217 // numeric compare\r
218 //\r
219 if (Compare1[0] == L'-') {\r
220 Cmp1 = 0 - (INTN)StrDecimalToUintn(Compare1+1);\r
221 } else {\r
222 Cmp1 = (INTN)StrDecimalToUintn(Compare1);\r
223 }\r
224 if (Compare2[0] == L'-') {\r
225 Cmp2 = 0 - (INTN)StrDecimalToUintn(Compare2+1);\r
226 } else {\r
227 Cmp2 = (INTN)StrDecimalToUintn(Compare2);\r
228 }\r
229 if (Cmp1 != Cmp2) {\r
230 return (TRUE);\r
231 }\r
232 }\r
233 return (FALSE);\r
234 break;\r
235 case OPERATOR_UGE:\r
236 case OPERATOR_GE:\r
237 if (ForceStringCompare || !ShellIsHexOrDecimalNumber(Compare1, FALSE, FALSE) || !ShellIsHexOrDecimalNumber(Compare2, FALSE, FALSE)) {\r
238 //\r
239 // string compare\r
240 //\r
241 if ((CaseInsensitive && StringNoCaseCompare(&Compare1, &Compare2) >= 0) || (StringCompare(&Compare1, &Compare2) >= 0)) {\r
242 return (TRUE);\r
243 }\r
244 } else {\r
245 //\r
246 // numeric compare\r
247 //\r
248 if (Compare1[0] == L'-') {\r
249 Cmp1 = 0 - (INTN)StrDecimalToUintn(Compare1+1);\r
250 } else {\r
251 Cmp1 = (INTN)StrDecimalToUintn(Compare1);\r
252 }\r
253 if (Compare2[0] == L'-') {\r
254 Cmp2 = 0 - (INTN)StrDecimalToUintn(Compare2+1);\r
255 } else {\r
256 Cmp2 = (INTN)StrDecimalToUintn(Compare2);\r
257 }\r
258 if (BinOp == OPERATOR_GE) {\r
259 if (Cmp1 >= Cmp2) {\r
260 return (TRUE);\r
261 }\r
262 } else {\r
263 if ((UINTN)Cmp1 >= (UINTN)Cmp2) {\r
264 return (TRUE);\r
265 }\r
266 }\r
267 }\r
268 return (FALSE);\r
269 break;\r
270 case OPERATOR_LE:\r
271 case OPERATOR_ULE:\r
272 if (ForceStringCompare || !ShellIsHexOrDecimalNumber(Compare1, FALSE, FALSE) || !ShellIsHexOrDecimalNumber(Compare2, FALSE, FALSE)) {\r
273 //\r
274 // string compare\r
275 //\r
276 if ((CaseInsensitive && StringNoCaseCompare(&Compare1, &Compare2) <= 0) || (StringCompare(&Compare1, &Compare2) <= 0)) {\r
277 return (TRUE);\r
278 }\r
279 } else {\r
280 //\r
281 // numeric compare\r
282 //\r
283 if (Compare1[0] == L'-') {\r
284 Cmp1 = 0 - (INTN)StrDecimalToUintn(Compare1+1);\r
285 } else {\r
286 Cmp1 = (INTN)StrDecimalToUintn(Compare1);\r
287 }\r
288 if (Compare2[0] == L'-') {\r
289 Cmp2 = 0 - (INTN)StrDecimalToUintn(Compare2+1);\r
290 } else {\r
291 Cmp2 = (INTN)StrDecimalToUintn(Compare2);\r
292 }\r
293 if (BinOp == OPERATOR_LE) {\r
294 if (Cmp1 <= Cmp2) {\r
295 return (TRUE);\r
296 }\r
297 } else {\r
298 if ((UINTN)Cmp1 <= (UINTN)Cmp2) {\r
299 return (TRUE);\r
300 }\r
301 }\r
302 }\r
303 return (FALSE);\r
304 break;\r
e9723321 305 default:\r
306 ASSERT(FALSE);\r
307 return (FALSE);\r
a405b86d 308 }\r
a405b86d 309}\r
310\r
311EFI_STATUS\r
312EFIAPI\r
313ProcessStatement (\r
314 IN OUT BOOLEAN *PassingState,\r
315 IN UINTN StartParameterNumber,\r
316 IN UINTN EndParameterNumber,\r
317 IN CONST END_TAG_TYPE OperatorToUse,\r
318 IN CONST BOOLEAN CaseInsensitive,\r
319 IN CONST BOOLEAN ForceStringCompare\r
320 )\r
321{\r
322 EFI_STATUS Status;\r
323 BOOLEAN OperationResult;\r
324 BOOLEAN NotPresent;\r
325 CHAR16 *StatementWalker;\r
326 BIN_OPERATOR_TYPE BinOp;\r
327 CHAR16 *Compare1;\r
328 CHAR16 *Compare2;\r
329 CHAR16 HexString[20];\r
330 CHAR16 *TempSpot;\r
331\r
332 ASSERT((END_TAG_TYPE)OperatorToUse != END_TAG_THEN);\r
333\r
334 Status = EFI_SUCCESS;\r
335 BinOp = OPERATOR_MAX;\r
336 OperationResult = FALSE;\r
337 StatementWalker = gEfiShellParametersProtocol->Argv[StartParameterNumber];\r
338 if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"not")) {\r
339 NotPresent = TRUE;\r
340 StatementWalker = gEfiShellParametersProtocol->Argv[++StartParameterNumber];\r
341 } else {\r
342 NotPresent = FALSE;\r
343 }\r
344\r
345 //\r
346 // now check for 'boolfunc' operators\r
347 //\r
348 if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"isint")) {\r
349 if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && StatementWalker[StrLen(StatementWalker)-1] == L')') {\r
350 StatementWalker[StrLen(StatementWalker)-1] = CHAR_NULL;\r
351 OperationResult = ShellIsHexOrDecimalNumber(StatementWalker, FALSE, FALSE);\r
352 } else {\r
353 Status = EFI_INVALID_PARAMETER;\r
354 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"isint");\r
355 }\r
356 } else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"exists") || IsNextFragment((CONST CHAR16**)(&StatementWalker), L"exist")) {\r
357 if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && StatementWalker[StrLen(StatementWalker)-1] == L')') {\r
358 StatementWalker[StrLen(StatementWalker)-1] = CHAR_NULL;\r
359 //\r
360 // is what remains a file in CWD???\r
361 //\r
362 OperationResult = (BOOLEAN)(ShellFileExists(StatementWalker)==EFI_SUCCESS);\r
363 } else if (StatementWalker[0] == CHAR_NULL && StartParameterNumber+1 == EndParameterNumber) {\r
364 OperationResult = (BOOLEAN)(ShellFileExists(gEfiShellParametersProtocol->Argv[++StartParameterNumber])==EFI_SUCCESS);\r
365 } else {\r
366 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"exist(s)");\r
367 Status = EFI_INVALID_PARAMETER;\r
368 }\r
369 } else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"available")) {\r
370 if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && StatementWalker[StrLen(StatementWalker)-1] == L')') {\r
371 StatementWalker[StrLen(StatementWalker)-1] = CHAR_NULL;\r
372 //\r
373 // is what remains a file in the CWD or path???\r
374 //\r
375 OperationResult = (BOOLEAN)(ShellIsFileInPath(StatementWalker)==EFI_SUCCESS);\r
376 } else {\r
377 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"available");\r
378 Status = EFI_INVALID_PARAMETER;\r
379 }\r
380 } else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"profile")) {\r
381 if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && StatementWalker[StrLen(StatementWalker)-1] == L')') {\r
382 //\r
383 // Chop off that ')'\r
384 //\r
385 StatementWalker[StrLen(StatementWalker)-1] = CHAR_NULL;\r
386 OperationResult = IsValidProfile(StatementWalker);\r
387 } else {\r
388 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"profile");\r
389 Status = EFI_INVALID_PARAMETER;\r
390 }\r
391 } else if (StartParameterNumber+1 >= EndParameterNumber) {\r
392 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[StartParameterNumber]);\r
393 Status = EFI_INVALID_PARAMETER;\r
394 } else {\r
395 //\r
396 // must be 'item binop item' style\r
397 //\r
398 Compare1 = NULL;\r
399 Compare2 = NULL;\r
400 BinOp = OPERATOR_MAX;\r
401\r
402 //\r
403 // get the first item\r
404 //\r
405 StatementWalker = gEfiShellParametersProtocol->Argv[StartParameterNumber];\r
406 if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"efierror")) {\r
407 TempSpot = StrStr(StatementWalker, L")");\r
408 if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && TempSpot != NULL) {\r
409 *TempSpot = CHAR_NULL;\r
410 if (ShellIsHexOrDecimalNumber(StatementWalker, FALSE, FALSE)) {\r
411 UnicodeSPrint(HexString, sizeof(HexString), L"0x%x", ShellStrToUintn(StatementWalker)|MAX_BIT);\r
412 ASSERT(Compare1 == NULL);\r
413 Compare1 = StrnCatGrow(&Compare1, NULL, HexString, 0);\r
414 StatementWalker += StrLen(StatementWalker) + 1;\r
415 } else {\r
416 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"efierror");\r
417 Status = EFI_INVALID_PARAMETER;\r
418 }\r
419 } else {\r
420 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"efierror");\r
421 Status = EFI_INVALID_PARAMETER;\r
422 }\r
423 } else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"pierror")) {\r
424 TempSpot = StrStr(StatementWalker, L")");\r
425 if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && TempSpot != NULL) {\r
426 *TempSpot = CHAR_NULL;\r
427 if (ShellIsHexOrDecimalNumber(StatementWalker, FALSE, FALSE)) {\r
428 UnicodeSPrint(HexString, sizeof(HexString), L"0x%x", ShellStrToUintn(StatementWalker)|MAX_BIT|(MAX_BIT>>2));\r
429 ASSERT(Compare1 == NULL);\r
430 Compare1 = StrnCatGrow(&Compare1, NULL, HexString, 0);\r
431 StatementWalker += StrLen(StatementWalker) + 1;\r
432 } else {\r
433 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"pierror");\r
434 Status = EFI_INVALID_PARAMETER;\r
435 }\r
436 } else {\r
437 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"pierror");\r
438 Status = EFI_INVALID_PARAMETER;\r
439 }\r
440 } else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"oemerror")) {\r
441 TempSpot = StrStr(StatementWalker, L")");\r
442 if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && TempSpot != NULL) {\r
443 TempSpot = CHAR_NULL;\r
444 if (ShellIsHexOrDecimalNumber(StatementWalker, FALSE, FALSE)) {\r
445 UnicodeSPrint(HexString, sizeof(HexString), L"0x%x", ShellStrToUintn(StatementWalker)|MAX_BIT|(MAX_BIT>>1));\r
446 ASSERT(Compare1 == NULL);\r
447 Compare1 = StrnCatGrow(&Compare1, NULL, HexString, 0);\r
448 StatementWalker += StrLen(StatementWalker) + 1;\r
449 } else {\r
450 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"oemerror");\r
451 Status = EFI_INVALID_PARAMETER;\r
452 }\r
453 } else {\r
454 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"oemerror");\r
455 Status = EFI_INVALID_PARAMETER;\r
456 }\r
457 } else {\r
458 ASSERT(Compare1 == NULL);\r
459 if (EndParameterNumber - StartParameterNumber > 2) {\r
460 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_STARTING), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[StartParameterNumber+2]);\r
461 Status = EFI_INVALID_PARAMETER;\r
462 } else {\r
463 //\r
464 // must be a raw string\r
465 //\r
466 Compare1 = StrnCatGrow(&Compare1, NULL, StatementWalker, 0);\r
467 }\r
468 }\r
469\r
470 //\r
471 // get the operator\r
472 //\r
473 ASSERT(StartParameterNumber+1<EndParameterNumber);\r
474 StatementWalker = gEfiShellParametersProtocol->Argv[StartParameterNumber+1];\r
475 if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"gt")) {\r
476 BinOp = OPERATOR_GT;\r
477 } else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"lt")) {\r
478 BinOp = OPERATOR_LT;\r
479 } else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"eq")) {\r
480 BinOp = OPERATOR_EQ;\r
481 } else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"ne")) {\r
482 BinOp = OPERATOR_NE;\r
483 } else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"ge")) {\r
484 BinOp = OPERATOR_GE;\r
485 } else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"le")) {\r
486 BinOp = OPERATOR_LE;\r
487 } else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"==")) {\r
488 BinOp = OPERATOR_EQ;\r
489 } else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"ugt")) {\r
490 BinOp = OPERATOR_UGT;\r
491 } else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"ult")) {\r
492 BinOp = OPERATOR_ULT;\r
493 } else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"uge")) {\r
494 BinOp = OPERATOR_UGE;\r
495 } else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"ule")) {\r
496 BinOp = OPERATOR_ULE;\r
497 } else {\r
498 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_INVALID_BINOP), gShellLevel1HiiHandle, StatementWalker);\r
499 Status = EFI_INVALID_PARAMETER;\r
500 }\r
501\r
502 //\r
503 // get the second item\r
504 //\r
505 ASSERT(StartParameterNumber+2<=EndParameterNumber);\r
506 StatementWalker = gEfiShellParametersProtocol->Argv[StartParameterNumber+2];\r
507 if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"efierror")) {\r
508 TempSpot = StrStr(StatementWalker, L")");\r
509 if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && TempSpot != NULL) {\r
510 TempSpot = CHAR_NULL;\r
511 if (ShellIsHexOrDecimalNumber(StatementWalker, FALSE, FALSE)) {\r
512 UnicodeSPrint(HexString, sizeof(HexString), L"0x%x", ShellStrToUintn(StatementWalker)|MAX_BIT);\r
513 ASSERT(Compare2 == NULL);\r
514 Compare2 = StrnCatGrow(&Compare2, NULL, HexString, 0);\r
515 StatementWalker += StrLen(StatementWalker) + 1;\r
516 } else {\r
517 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"efierror");\r
518 Status = EFI_INVALID_PARAMETER;\r
519 }\r
520 } else {\r
521 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"efierror");\r
522 Status = EFI_INVALID_PARAMETER;\r
523 }\r
524 //\r
525 // can this be collapsed into the above?\r
526 //\r
527 } else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"pierror")) {\r
528 TempSpot = StrStr(StatementWalker, L")");\r
529 if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && TempSpot != NULL) {\r
530 TempSpot = CHAR_NULL;\r
531 if (ShellIsHexOrDecimalNumber(StatementWalker, FALSE, FALSE)) {\r
532 UnicodeSPrint(HexString, sizeof(HexString), L"0x%x", ShellStrToUintn(StatementWalker)|MAX_BIT|(MAX_BIT>>2));\r
533 ASSERT(Compare2 == NULL);\r
534 Compare2 = StrnCatGrow(&Compare2, NULL, HexString, 0);\r
535 StatementWalker += StrLen(StatementWalker) + 1;\r
536 } else {\r
537 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"pierror");\r
538 Status = EFI_INVALID_PARAMETER;\r
539 }\r
540 } else {\r
541 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"pierror");\r
542 Status = EFI_INVALID_PARAMETER;\r
543 }\r
544 } else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"oemerror")) {\r
545 TempSpot = StrStr(StatementWalker, L")");\r
546 if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && TempSpot != NULL) {\r
547 TempSpot = CHAR_NULL;\r
548 if (ShellIsHexOrDecimalNumber(StatementWalker, FALSE, FALSE)) {\r
549 UnicodeSPrint(HexString, sizeof(HexString), L"0x%x", ShellStrToUintn(StatementWalker)|MAX_BIT|(MAX_BIT>>1));\r
550 ASSERT(Compare2 == NULL);\r
551 Compare2 = StrnCatGrow(&Compare2, NULL, HexString, 0);\r
552 StatementWalker += StrLen(StatementWalker) + 1;\r
553 } else {\r
554 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"oemerror");\r
555 Status = EFI_INVALID_PARAMETER;\r
556 }\r
557 } else {\r
558 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"oemerror");\r
559 Status = EFI_INVALID_PARAMETER;\r
560 }\r
561 } else {\r
562 //\r
563 // must be a raw string\r
564 //\r
565 ASSERT(Compare2 == NULL);\r
566 Compare2 = StrnCatGrow(&Compare2, NULL, StatementWalker, 0);\r
567 }\r
568\r
569 if (Compare1 != NULL && Compare2 != NULL && BinOp != OPERATOR_MAX) {\r
570 OperationResult = TestOperation(Compare1, Compare2, BinOp, CaseInsensitive, ForceStringCompare);\r
571 }\r
572\r
573 SHELL_FREE_NON_NULL(Compare1);\r
574 SHELL_FREE_NON_NULL(Compare2);\r
575 }\r
576\r
577 //\r
578 // done processing do result...\r
579 //\r
580\r
581 if (!EFI_ERROR(Status)) {\r
582 if (NotPresent) {\r
583 OperationResult = (BOOLEAN)(!OperationResult);\r
584 }\r
585 switch(OperatorToUse) {\r
586 case END_TAG_OR:\r
587 *PassingState = (BOOLEAN)(*PassingState || OperationResult);\r
588 break;\r
589 case END_TAG_AND:\r
590 *PassingState = (BOOLEAN)(*PassingState && OperationResult);\r
591 break;\r
592 case END_TAG_MAX:\r
593 *PassingState = (BOOLEAN)(OperationResult);\r
594 break;\r
595 default:\r
596 ASSERT(FALSE);\r
597 }\r
598 }\r
599 return (Status);\r
600}\r
601\r
602BOOLEAN\r
603EFIAPI\r
604BuildNextStatement (\r
605 IN UINTN ParameterNumber,\r
606 OUT UINTN *EndParameter,\r
607 OUT END_TAG_TYPE *EndTag\r
608 )\r
609{\r
610 CHAR16 *Buffer;\r
611 UINTN BufferSize;\r
612\r
613 *EndTag = END_TAG_MAX;\r
614\r
615 for(Buffer = NULL, BufferSize = 0\r
616 ; ParameterNumber < gEfiShellParametersProtocol->Argc\r
617 ; ParameterNumber++\r
618 ) {\r
619 if (gUnicodeCollation->StriColl(\r
620 gUnicodeCollation,\r
621 gEfiShellParametersProtocol->Argv[ParameterNumber],\r
622 L"or") == 0) {\r
623 *EndParameter = ParameterNumber - 1;\r
624 *EndTag = END_TAG_OR;\r
625 break;\r
626 } else if (gUnicodeCollation->StriColl(\r
627 gUnicodeCollation,\r
628 gEfiShellParametersProtocol->Argv[ParameterNumber],\r
629 L"and") == 0) {\r
630 *EndParameter = ParameterNumber - 1;\r
631 *EndTag = END_TAG_AND;\r
632 break;\r
633 } else if (gUnicodeCollation->StriColl(\r
634 gUnicodeCollation,\r
635 gEfiShellParametersProtocol->Argv[ParameterNumber],\r
636 L"then") == 0) {\r
637 *EndParameter = ParameterNumber - 1;\r
638 *EndTag = END_TAG_THEN;\r
639 break;\r
640 }\r
641 }\r
642 if (*EndTag == END_TAG_MAX) {\r
643 return (FALSE);\r
644 }\r
645 return (TRUE);\r
646}\r
647\r
648BOOLEAN\r
649EFIAPI\r
650MoveToTagSpecial (\r
651 IN SCRIPT_FILE *ScriptFile\r
652 )\r
653{\r
654 SCRIPT_COMMAND_LIST *CommandNode;\r
655 BOOLEAN Found;\r
656 UINTN TargetCount;\r
657 CHAR16 *CommandName;\r
658 CHAR16 *CommandWalker;\r
659 CHAR16 *TempLocation;\r
660\r
661 TargetCount = 1;\r
662 Found = FALSE;\r
663\r
664 if (ScriptFile == NULL) {\r
665 return FALSE;\r
666 }\r
667\r
668 for (CommandNode = (SCRIPT_COMMAND_LIST *)GetNextNode(&ScriptFile->CommandList, &ScriptFile->CurrentCommand->Link), Found = FALSE\r
669 ; !IsNull(&ScriptFile->CommandList, &CommandNode->Link) && !Found\r
670 ; CommandNode = (SCRIPT_COMMAND_LIST *)GetNextNode(&ScriptFile->CommandList, &CommandNode->Link)\r
671 ){\r
672\r
673 //\r
674 // get just the first part of the command line...\r
675 //\r
676 CommandName = NULL;\r
677 CommandName = StrnCatGrow(&CommandName, NULL, CommandNode->Cl, 0);\r
678 CommandWalker = CommandName;\r
679 while (CommandWalker[0] == L' ') {\r
680 CommandWalker++;\r
681 }\r
682 TempLocation = StrStr(CommandWalker, L" ");\r
683\r
684 if (TempLocation != NULL) {\r
685 *TempLocation = CHAR_NULL;\r
686 }\r
687\r
688 //\r
689 // did we find a nested item ?\r
690 //\r
691 if (gUnicodeCollation->StriColl(\r
692 gUnicodeCollation,\r
693 (CHAR16*)CommandWalker,\r
694 L"If") == 0) {\r
695 TargetCount++;\r
696 } else if (TargetCount == 1 && gUnicodeCollation->StriColl(\r
697 gUnicodeCollation,\r
698 (CHAR16*)CommandWalker,\r
699 (CHAR16*)L"else") == 0) {\r
700 //\r
701 // else can only decrement the last part... not an nested if\r
702 // hence the TargetCount compare added\r
703 //\r
704 TargetCount--;\r
705 } else if (gUnicodeCollation->StriColl(\r
706 gUnicodeCollation,\r
707 (CHAR16*)CommandWalker,\r
708 (CHAR16*)L"endif") == 0) {\r
709 TargetCount--;\r
710 }\r
711 if (TargetCount == 0) {\r
712 ScriptFile->CurrentCommand = (SCRIPT_COMMAND_LIST *)GetNextNode(&ScriptFile->CommandList, &CommandNode->Link);\r
713 Found = TRUE;\r
714 }\r
715\r
716 //\r
717 // Free the memory for this loop...\r
718 //\r
719 SHELL_FREE_NON_NULL(CommandName);\r
720 }\r
721 return (Found);\r
722}\r
723\r
724EFI_STATUS\r
725EFIAPI\r
726PerformResultOperation (\r
727 IN CONST BOOLEAN Result\r
728 )\r
729{\r
730 if (Result || MoveToTagSpecial(ShellCommandGetCurrentScriptFile())) {\r
731 return (EFI_SUCCESS);\r
732 }\r
733 return (EFI_NOT_FOUND);\r
734}\r
735\r
736/**\r
737 Function for 'if' command.\r
738\r
739 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
740 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
741**/\r
742SHELL_STATUS\r
743EFIAPI\r
744ShellCommandRunIf (\r
745 IN EFI_HANDLE ImageHandle,\r
746 IN EFI_SYSTEM_TABLE *SystemTable\r
747 )\r
748{\r
749 EFI_STATUS Status;\r
750 SHELL_STATUS ShellStatus;\r
751 BOOLEAN CaseInsensitive;\r
752 BOOLEAN ForceString;\r
753 UINTN CurrentParameter;\r
754 UINTN EndParameter;\r
755 BOOLEAN CurrentValue;\r
756 END_TAG_TYPE Ending;\r
757 END_TAG_TYPE PreviousEnding;\r
758\r
759\r
760 Status = CommandInit();\r
761 ASSERT_EFI_ERROR(Status);\r
762\r
763 if (!gEfiShellProtocol->BatchIsActive()) {\r
764 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"If");\r
765 return (SHELL_UNSUPPORTED);\r
766 }\r
767\r
768 if (gEfiShellParametersProtocol->Argc < 3) {\r
769 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel1HiiHandle);\r
770 return (SHELL_INVALID_PARAMETER);\r
771 }\r
772\r
773 //\r
774 // Make sure that an End exists.\r
775 //\r
776 if (!MoveToTag(GetNextNode, L"endif", L"if", NULL, ShellCommandGetCurrentScriptFile(), TRUE, TRUE, FALSE)) {\r
777 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"EnfIf", L"If", ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);\r
778 return (SHELL_DEVICE_ERROR);\r
779 }\r
780\r
781 //\r
782 // initialize the shell lib (we must be in non-auto-init...)\r
783 //\r
784 Status = ShellInitialize();\r
785 ASSERT_EFI_ERROR(Status);\r
786\r
787 CurrentParameter = 1;\r
788 EndParameter = 0;\r
789\r
790 if (gUnicodeCollation->StriColl(\r
791 gUnicodeCollation,\r
792 gEfiShellParametersProtocol->Argv[1],\r
793 L"/i") == 0 ||\r
794 gUnicodeCollation->StriColl(\r
795 gUnicodeCollation,\r
796 gEfiShellParametersProtocol->Argv[2],\r
797 L"/i") == 0 ||\r
798 (gEfiShellParametersProtocol->Argc > 3 && gUnicodeCollation->StriColl(\r
799 gUnicodeCollation,\r
800 gEfiShellParametersProtocol->Argv[3],\r
801 L"/i") == 0)) {\r
802 CaseInsensitive = TRUE;\r
803 CurrentParameter++;\r
804 } else {\r
805 CaseInsensitive = FALSE;\r
806 }\r
807 if (gUnicodeCollation->StriColl(\r
808 gUnicodeCollation,\r
809 gEfiShellParametersProtocol->Argv[1],\r
810 L"/s") == 0 ||\r
811 gUnicodeCollation->StriColl(\r
812 gUnicodeCollation,\r
813 gEfiShellParametersProtocol->Argv[2],\r
814 L"/s") == 0 ||\r
815 (gEfiShellParametersProtocol->Argc > 3 && gUnicodeCollation->StriColl(\r
816 gUnicodeCollation,\r
817 gEfiShellParametersProtocol->Argv[3],\r
818 L"/s") == 0)) {\r
819 ForceString = TRUE;\r
820 CurrentParameter++;\r
821 } else {\r
822 ForceString = FALSE;\r
823 }\r
824\r
825 for ( ShellStatus = SHELL_SUCCESS, CurrentValue = FALSE, Ending = END_TAG_MAX\r
826 ; CurrentParameter < gEfiShellParametersProtocol->Argc && ShellStatus == SHELL_SUCCESS\r
827 ; CurrentParameter++) {\r
828 if (gUnicodeCollation->StriColl(\r
829 gUnicodeCollation,\r
830 gEfiShellParametersProtocol->Argv[CurrentParameter],\r
831 L"then") == 0) {\r
832 //\r
833 // we are at the then\r
834 //\r
835 if (CurrentParameter+1 != gEfiShellParametersProtocol->Argc) {\r
836 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TEXT_AFTER_THEN), gShellLevel1HiiHandle);\r
837 ShellStatus = SHELL_INVALID_PARAMETER;\r
838 } else {\r
839 Status = PerformResultOperation(CurrentValue);\r
840 if (EFI_ERROR(Status)) {\r
841 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_AFTER_BAD), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[CurrentParameter]);\r
842 ShellStatus = SHELL_INVALID_PARAMETER;\r
843 }\r
844 }\r
845 } else {\r
846 PreviousEnding = Ending;\r
847 //\r
848 // build up the next statement for analysis\r
849 //\r
850 if (!BuildNextStatement(CurrentParameter, &EndParameter, &Ending)) {\r
851 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"Then", L"If", ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);\r
852 ShellStatus = SHELL_INVALID_PARAMETER;\r
853 } else {\r
854 //\r
855 // Analyze the statement\r
856 //\r
857 Status = ProcessStatement(&CurrentValue, CurrentParameter, EndParameter, PreviousEnding, CaseInsensitive, ForceString);\r
858 if (EFI_ERROR(Status)) {\r
859// ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_STARTING), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[CurrentParameter]);\r
860 ShellStatus = SHELL_INVALID_PARAMETER;\r
861 } else {\r
862 //\r
863 // Optomize to get out of the loop early...\r
864 //\r
865 if ((Ending == END_TAG_OR && CurrentValue) || (Ending == END_TAG_AND && !CurrentValue)) {\r
866 Status = PerformResultOperation(CurrentValue);\r
867 if (EFI_ERROR(Status)) {\r
868 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_AFTER_BAD), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[CurrentParameter]);\r
869 ShellStatus = SHELL_INVALID_PARAMETER;\r
870 }\r
871 break;\r
872 }\r
873 }\r
874 }\r
875 if (ShellStatus == SHELL_SUCCESS){\r
876 CurrentParameter = EndParameter;\r
877 //\r
878 // Skip over the or or and parameter.\r
879 //\r
880 if (Ending == END_TAG_OR || Ending == END_TAG_AND) {\r
881 CurrentParameter++;\r
882 }\r
883 }\r
884 }\r
885 }\r
886 return (ShellStatus);\r
887}\r
888\r
889/**\r
890 Function for 'else' command.\r
891\r
892 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
893 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
894**/\r
895SHELL_STATUS\r
896EFIAPI\r
897ShellCommandRunElse (\r
898 IN EFI_HANDLE ImageHandle,\r
899 IN EFI_SYSTEM_TABLE *SystemTable\r
900 )\r
901{\r
902 ASSERT_EFI_ERROR(CommandInit());\r
903\r
904 if (gEfiShellParametersProtocol->Argc > 1) {\r
905 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel1HiiHandle);\r
906 return (SHELL_INVALID_PARAMETER);\r
907 }\r
908\r
909 if (!gEfiShellProtocol->BatchIsActive()) {\r
910 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"Else");\r
911 return (SHELL_UNSUPPORTED);\r
912 }\r
913\r
914\r
915 if (!MoveToTag(GetPreviousNode, L"if", L"endif", NULL, ShellCommandGetCurrentScriptFile(), FALSE, TRUE, FALSE)) {\r
916 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"If", L"Else", ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);\r
917 return (SHELL_DEVICE_ERROR);\r
918 }\r
919 if (!MoveToTag(GetPreviousNode, L"if", L"else", NULL, ShellCommandGetCurrentScriptFile(), FALSE, TRUE, FALSE)) {\r
920 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"If", L"Else", ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);\r
921 return (SHELL_DEVICE_ERROR);\r
922 }\r
923\r
924 if (!MoveToTag(GetNextNode, L"endif", L"if", NULL, ShellCommandGetCurrentScriptFile(), FALSE, FALSE, FALSE)) {\r
925 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"EndIf", "Else", ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);\r
926 return (SHELL_DEVICE_ERROR);\r
927 }\r
928\r
929 return (SHELL_SUCCESS);\r
930}\r
931\r
932/**\r
933 Function for 'endif' command.\r
934\r
935 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
936 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
937**/\r
938SHELL_STATUS\r
939EFIAPI\r
940ShellCommandRunEndIf (\r
941 IN EFI_HANDLE ImageHandle,\r
942 IN EFI_SYSTEM_TABLE *SystemTable\r
943 )\r
944{\r
945 ASSERT_EFI_ERROR(CommandInit());\r
946\r
947 if (gEfiShellParametersProtocol->Argc > 1) {\r
948 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel1HiiHandle);\r
949 return (SHELL_INVALID_PARAMETER);\r
950 }\r
951\r
952 if (!gEfiShellProtocol->BatchIsActive()) {\r
953 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"Endif");\r
954 return (SHELL_UNSUPPORTED);\r
955 }\r
956\r
957 if (!MoveToTag(GetPreviousNode, L"if", L"endif", NULL, ShellCommandGetCurrentScriptFile(), FALSE, TRUE, FALSE)) {\r
958 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"If", L"EndIf", ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);\r
959 return (SHELL_DEVICE_ERROR);\r
960 }\r
961\r
962 return (SHELL_SUCCESS);\r
963}\r