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