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