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