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