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