2 Main file for If and else shell level 1 function.
4 (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "UefiShellLevel1CommandsLib.h"
11 #include <Library/PrintLib.h>
25 OperatorGreatorOrEqual
,
27 OperatorUnisgnedGreaterThan
,
28 OperatorUnsignedLessThan
,
29 OperatorUnsignedGreaterOrEqual
,
30 OperatorUnsignedLessOrEqual
,
35 Extract the next fragment, if there is one.
37 @param[in, out] Statement The current remaining statement.
38 @param[in] Fragment The current fragment.
39 @param[out] Match TRUE when there is another Fragment in Statement,
42 @retval EFI_SUCCESS The match operation is performed successfully.
43 @retval EFI_OUT_OF_RESOURCES Out of resources.
47 IN OUT CONST CHAR16
**Statement
,
48 IN CONST CHAR16
*Fragment
,
56 Tester
= StrnCatGrow(&Tester
, NULL
, *Statement
, StrLen(Fragment
));
58 return EFI_OUT_OF_RESOURCES
;
60 Tester
[StrLen(Fragment
)] = CHAR_NULL
;
61 if (gUnicodeCollation
->StriColl(
66 // increment the string pointer to the end of what we found and then chop off spaces...
68 *Statement
+=StrLen(Fragment
);
69 while (*Statement
[0] == L
' ') {
81 Determine if String represents a valid profile.
83 @param[in] String The pointer to the string to test.
85 @retval TRUE String is a valid profile.
86 @retval FALSE String is not a valid profile.
90 IN CONST CHAR16
*String
93 CONST CHAR16
*ProfilesString
;
94 CONST CHAR16
*TempLocation
;
96 ProfilesString
= ShellGetEnvironmentVariable(L
"profiles");
97 ASSERT(ProfilesString
!= NULL
);
98 TempLocation
= StrStr(ProfilesString
, String
);
99 if ((TempLocation
!= NULL
) && (*(TempLocation
-1) == L
';') && (*(TempLocation
+StrLen(String
)) == L
';')) {
106 Do a comparison between 2 things.
108 @param[in] Compare1 The first item to compare.
109 @param[in] Compare2 The second item to compare.
110 @param[in] BinOp The type of comparison to perform.
111 @param[in] CaseInsensitive TRUE to do non-case comparison, FALSE otherwise.
112 @param[in] ForceStringCompare TRUE to force string comparison, FALSE otherwise.
114 @return The result of the comparison.
118 IN CONST CHAR16
*Compare1
,
119 IN CONST CHAR16
*Compare2
,
120 IN CONST BIN_OPERATOR_TYPE BinOp
,
121 IN CONST BOOLEAN CaseInsensitive
,
122 IN CONST BOOLEAN ForceStringCompare
129 // "Compare1 BinOp Compare2"
132 case OperatorUnisgnedGreaterThan
:
133 case OperatorGreaterThan
:
134 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
138 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) > 0) || (StringCompare(&Compare1
, &Compare2
) > 0)) {
145 if (Compare1
[0] == L
'-') {
146 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
148 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
150 if (Compare2
[0] == L
'-') {
151 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
153 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
155 if (BinOp
== OperatorGreaterThan
) {
160 if ((UINTN
)Cmp1
> (UINTN
)Cmp2
) {
166 case OperatorUnsignedLessThan
:
167 case OperatorLessThan
:
168 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
172 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) < 0) || (StringCompare(&Compare1
, &Compare2
) < 0)) {
179 if (Compare1
[0] == L
'-') {
180 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
182 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
184 if (Compare2
[0] == L
'-') {
185 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
187 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
189 if (BinOp
== OperatorLessThan
) {
194 if ((UINTN
)Cmp1
< (UINTN
)Cmp2
) {
202 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
206 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) == 0) || (StringCompare(&Compare1
, &Compare2
) == 0)) {
213 if (Compare1
[0] == L
'-') {
214 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
216 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
218 if (Compare2
[0] == L
'-') {
219 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
221 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
228 case OperatorNotEqual
:
229 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
233 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) != 0) || (StringCompare(&Compare1
, &Compare2
) != 0)) {
240 if (Compare1
[0] == L
'-') {
241 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
243 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
245 if (Compare2
[0] == L
'-') {
246 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
248 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
255 case OperatorUnsignedGreaterOrEqual
:
256 case OperatorGreatorOrEqual
:
257 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
261 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) >= 0) || (StringCompare(&Compare1
, &Compare2
) >= 0)) {
268 if (Compare1
[0] == L
'-') {
269 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
271 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
273 if (Compare2
[0] == L
'-') {
274 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
276 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
278 if (BinOp
== OperatorGreatorOrEqual
) {
283 if ((UINTN
)Cmp1
>= (UINTN
)Cmp2
) {
289 case OperatorLessOrEqual
:
290 case OperatorUnsignedLessOrEqual
:
291 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
295 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) <= 0) || (StringCompare(&Compare1
, &Compare2
) <= 0)) {
302 if (Compare1
[0] == L
'-') {
303 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
305 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
307 if (Compare2
[0] == L
'-') {
308 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
310 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
312 if (BinOp
== OperatorLessOrEqual
) {
317 if ((UINTN
)Cmp1
<= (UINTN
)Cmp2
) {
330 Process an if statement and determine if its is valid or not.
332 @param[in, out] PassingState Opon entry, the current state. Upon exit,
334 @param[in] StartParameterNumber The number of the first parameter of
336 @param[in] EndParameterNumber The number of the final parameter of
338 @param[in] OperatorToUse The type of termination operator.
339 @param[in] CaseInsensitive TRUE for case insensitive, FALSE otherwise.
340 @param[in] ForceStringCompare TRUE for all string based, FALSE otherwise.
342 @retval EFI_INVALID_PARAMETER A parameter was invalid.
343 @retval EFI_SUCCESS The operation was successful.
347 IN OUT BOOLEAN
*PassingState
,
348 IN UINTN StartParameterNumber
,
349 IN UINTN EndParameterNumber
,
350 IN CONST END_TAG_TYPE OperatorToUse
,
351 IN CONST BOOLEAN CaseInsensitive
,
352 IN CONST BOOLEAN ForceStringCompare
356 BOOLEAN OperationResult
;
358 CHAR16
*StatementWalker
;
359 BIN_OPERATOR_TYPE BinOp
;
362 CHAR16 HexString
[20];
366 ASSERT((END_TAG_TYPE
)OperatorToUse
!= EndTagThen
);
368 Status
= EFI_SUCCESS
;
370 OperationResult
= FALSE
;
372 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
];
373 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"not", &Match
)) && Match
) {
375 StatementWalker
= gEfiShellParametersProtocol
->Argv
[++StartParameterNumber
];
381 // now check for 'boolfunc' operators
383 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"isint", &Match
)) && Match
) {
384 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
385 && StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
386 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
387 OperationResult
= ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
);
389 Status
= EFI_INVALID_PARAMETER
;
390 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"isint");
392 } else if ((!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"exists", &Match
)) && Match
) ||
393 (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"exist", &Match
)) && Match
)) {
394 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&&
395 StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
396 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
398 // is what remains a file in CWD???
400 OperationResult
= (BOOLEAN
)(ShellFileExists(StatementWalker
)==EFI_SUCCESS
);
401 } else if (StatementWalker
[0] == CHAR_NULL
&& StartParameterNumber
+1 == EndParameterNumber
) {
402 OperationResult
= (BOOLEAN
)(ShellFileExists(gEfiShellParametersProtocol
->Argv
[++StartParameterNumber
])==EFI_SUCCESS
);
404 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"exist(s)");
405 Status
= EFI_INVALID_PARAMETER
;
407 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"available", &Match
)) && Match
) {
408 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&&
409 StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
410 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
412 // is what remains a file in the CWD or path???
414 OperationResult
= (BOOLEAN
)(ShellIsFileInPath(StatementWalker
)==EFI_SUCCESS
);
416 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"available");
417 Status
= EFI_INVALID_PARAMETER
;
419 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"profile", &Match
)) && Match
) {
420 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&&
421 StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
425 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
426 OperationResult
= IsValidProfile(StatementWalker
);
428 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"profile");
429 Status
= EFI_INVALID_PARAMETER
;
431 } else if (StartParameterNumber
+1 >= EndParameterNumber
) {
432 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[StartParameterNumber
]);
433 Status
= EFI_INVALID_PARAMETER
;
436 // must be 'item binop item' style
443 // get the first item
445 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
];
446 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"efierror", &Match
)) && Match
) {
447 TempSpot
= StrStr(StatementWalker
, L
")");
448 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&& TempSpot
!= NULL
) {
449 *TempSpot
= CHAR_NULL
;
450 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
451 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
);
452 ASSERT(Compare1
== NULL
);
453 Compare1
= StrnCatGrow(&Compare1
, NULL
, HexString
, 0);
454 StatementWalker
+= StrLen(StatementWalker
) + 1;
456 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
457 Status
= EFI_INVALID_PARAMETER
;
460 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
461 Status
= EFI_INVALID_PARAMETER
;
463 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"pierror", &Match
)) && Match
) {
464 TempSpot
= StrStr(StatementWalker
, L
")");
465 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&& TempSpot
!= NULL
) {
466 *TempSpot
= CHAR_NULL
;
467 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
468 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>2));
469 ASSERT(Compare1
== NULL
);
470 Compare1
= StrnCatGrow(&Compare1
, NULL
, HexString
, 0);
471 StatementWalker
+= StrLen(StatementWalker
) + 1;
473 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
474 Status
= EFI_INVALID_PARAMETER
;
477 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
478 Status
= EFI_INVALID_PARAMETER
;
480 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"oemerror", &Match
)) && Match
) {
481 TempSpot
= StrStr(StatementWalker
, L
")");
482 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&& TempSpot
!= NULL
) {
483 TempSpot
= CHAR_NULL
;
484 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
485 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>1));
486 ASSERT(Compare1
== NULL
);
487 Compare1
= StrnCatGrow(&Compare1
, NULL
, HexString
, 0);
488 StatementWalker
+= StrLen(StatementWalker
) + 1;
490 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
491 Status
= EFI_INVALID_PARAMETER
;
494 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
495 Status
= EFI_INVALID_PARAMETER
;
498 ASSERT(Compare1
== NULL
);
499 if (EndParameterNumber
- StartParameterNumber
> 2) {
500 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_STARTING
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+2]);
501 Status
= EFI_INVALID_PARAMETER
;
504 // must be a raw string
506 Compare1
= StrnCatGrow(&Compare1
, NULL
, StatementWalker
, 0);
513 ASSERT(StartParameterNumber
+1<EndParameterNumber
);
514 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+1];
515 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"gt", &Match
)) && Match
) {
516 BinOp
= OperatorGreaterThan
;
517 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"lt", &Match
)) && Match
) {
518 BinOp
= OperatorLessThan
;
519 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"eq", &Match
)) && Match
) {
520 BinOp
= OperatorEqual
;
521 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ne", &Match
)) && Match
) {
522 BinOp
= OperatorNotEqual
;
523 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ge", &Match
)) && Match
) {
524 BinOp
= OperatorGreatorOrEqual
;
525 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"le", &Match
)) && Match
) {
526 BinOp
= OperatorLessOrEqual
;
527 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"==", &Match
)) && Match
) {
528 BinOp
= OperatorEqual
;
529 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ugt", &Match
)) && Match
) {
530 BinOp
= OperatorUnisgnedGreaterThan
;
531 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ult", &Match
)) && Match
) {
532 BinOp
= OperatorUnsignedLessThan
;
533 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"uge", &Match
)) && Match
) {
534 BinOp
= OperatorUnsignedGreaterOrEqual
;
535 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ule", &Match
)) && Match
) {
536 BinOp
= OperatorUnsignedLessOrEqual
;
538 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_INVALID_BINOP
), gShellLevel1HiiHandle
, StatementWalker
);
539 Status
= EFI_INVALID_PARAMETER
;
543 // get the second item
545 ASSERT(StartParameterNumber
+2<=EndParameterNumber
);
546 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+2];
547 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"efierror", &Match
)) && Match
) {
548 TempSpot
= StrStr(StatementWalker
, L
")");
549 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&& TempSpot
!= NULL
) {
550 TempSpot
= CHAR_NULL
;
551 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
552 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
);
553 ASSERT(Compare2
== NULL
);
554 Compare2
= StrnCatGrow(&Compare2
, NULL
, HexString
, 0);
555 StatementWalker
+= StrLen(StatementWalker
) + 1;
557 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
558 Status
= EFI_INVALID_PARAMETER
;
561 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
562 Status
= EFI_INVALID_PARAMETER
;
565 // can this be collapsed into the above?
567 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"pierror", &Match
)) && Match
) {
568 TempSpot
= StrStr(StatementWalker
, L
")");
569 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&& TempSpot
!= NULL
) {
570 TempSpot
= CHAR_NULL
;
571 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
572 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>2));
573 ASSERT(Compare2
== NULL
);
574 Compare2
= StrnCatGrow(&Compare2
, NULL
, HexString
, 0);
575 StatementWalker
+= StrLen(StatementWalker
) + 1;
577 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
578 Status
= EFI_INVALID_PARAMETER
;
581 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
582 Status
= EFI_INVALID_PARAMETER
;
584 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"oemerror", &Match
)) && Match
) {
585 TempSpot
= StrStr(StatementWalker
, L
")");
586 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&& TempSpot
!= NULL
) {
587 TempSpot
= CHAR_NULL
;
588 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
589 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>1));
590 ASSERT(Compare2
== NULL
);
591 Compare2
= StrnCatGrow(&Compare2
, NULL
, HexString
, 0);
592 StatementWalker
+= StrLen(StatementWalker
) + 1;
594 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
595 Status
= EFI_INVALID_PARAMETER
;
598 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
599 Status
= EFI_INVALID_PARAMETER
;
603 // must be a raw string
605 ASSERT(Compare2
== NULL
);
606 Compare2
= StrnCatGrow(&Compare2
, NULL
, StatementWalker
, 0);
609 if (Compare1
!= NULL
&& Compare2
!= NULL
&& BinOp
!= OperatorMax
) {
610 OperationResult
= TestOperation(Compare1
, Compare2
, BinOp
, CaseInsensitive
, ForceStringCompare
);
613 SHELL_FREE_NON_NULL(Compare1
);
614 SHELL_FREE_NON_NULL(Compare2
);
618 // done processing do result...
621 if (!EFI_ERROR(Status
)) {
623 OperationResult
= (BOOLEAN
)(!OperationResult
);
625 switch(OperatorToUse
) {
627 *PassingState
= (BOOLEAN
)(*PassingState
|| OperationResult
);
630 *PassingState
= (BOOLEAN
)(*PassingState
&& OperationResult
);
633 *PassingState
= (BOOLEAN
)(OperationResult
);
643 Break up the next part of the if statement (until the next 'and', 'or', or 'then').
645 @param[in] ParameterNumber The current parameter number.
646 @param[out] EndParameter Upon successful return, will point to the
647 parameter to start the next iteration with.
648 @param[out] EndTag Upon successful return, will point to the
649 type that was found at the end of this statement.
651 @retval TRUE A valid statement was found.
652 @retval FALSE A valid statement was not found.
656 IN UINTN ParameterNumber
,
657 OUT UINTN
*EndParameter
,
658 OUT END_TAG_TYPE
*EndTag
664 ; ParameterNumber
< gEfiShellParametersProtocol
->Argc
667 if (gUnicodeCollation
->StriColl(
669 gEfiShellParametersProtocol
->Argv
[ParameterNumber
],
671 *EndParameter
= ParameterNumber
- 1;
674 } else if (gUnicodeCollation
->StriColl(
676 gEfiShellParametersProtocol
->Argv
[ParameterNumber
],
678 *EndParameter
= ParameterNumber
- 1;
681 } else if (gUnicodeCollation
->StriColl(
683 gEfiShellParametersProtocol
->Argv
[ParameterNumber
],
685 *EndParameter
= ParameterNumber
- 1;
686 *EndTag
= EndTagThen
;
690 if (*EndTag
== EndTagMax
) {
697 Move the script file pointer to a different place in the script file.
698 This one is special since it handles the if/else/endif syntax.
700 @param[in] ScriptFile The script file from GetCurrnetScriptFile().
702 @retval TRUE The move target was found and the move was successful.
703 @retval FALSE Something went wrong.
707 IN SCRIPT_FILE
*ScriptFile
710 SCRIPT_COMMAND_LIST
*CommandNode
;
714 CHAR16
*CommandWalker
;
715 CHAR16
*TempLocation
;
720 if (ScriptFile
== NULL
) {
724 for (CommandNode
= (SCRIPT_COMMAND_LIST
*)GetNextNode(&ScriptFile
->CommandList
, &ScriptFile
->CurrentCommand
->Link
), Found
= FALSE
725 ; !IsNull(&ScriptFile
->CommandList
, &CommandNode
->Link
) && !Found
726 ; CommandNode
= (SCRIPT_COMMAND_LIST
*)GetNextNode(&ScriptFile
->CommandList
, &CommandNode
->Link
)
730 // get just the first part of the command line...
733 CommandName
= StrnCatGrow(&CommandName
, NULL
, CommandNode
->Cl
, 0);
734 if (CommandName
== NULL
) {
737 CommandWalker
= CommandName
;
740 // Skip leading spaces and tabs.
742 while ((CommandWalker
[0] == L
' ') || (CommandWalker
[0] == L
'\t')) {
745 TempLocation
= StrStr(CommandWalker
, L
" ");
747 if (TempLocation
!= NULL
) {
748 *TempLocation
= CHAR_NULL
;
752 // did we find a nested item ?
754 if (gUnicodeCollation
->StriColl(
756 (CHAR16
*)CommandWalker
,
759 } else if (TargetCount
== 1 && gUnicodeCollation
->StriColl(
761 (CHAR16
*)CommandWalker
,
762 (CHAR16
*)L
"else") == 0) {
764 // else can only decrement the last part... not an nested if
765 // hence the TargetCount compare added
768 } else if (gUnicodeCollation
->StriColl(
770 (CHAR16
*)CommandWalker
,
771 (CHAR16
*)L
"endif") == 0) {
774 if (TargetCount
== 0) {
775 ScriptFile
->CurrentCommand
= (SCRIPT_COMMAND_LIST
*)GetNextNode(&ScriptFile
->CommandList
, &CommandNode
->Link
);
780 // Free the memory for this loop...
782 SHELL_FREE_NON_NULL(CommandName
);
788 Deal with the result of the if operation.
790 @param[in] Result The result of the if.
792 @retval EFI_SUCCESS The operation was successful.
793 @retval EFI_NOT_FOUND The ending tag could not be found.
796 PerformResultOperation (
797 IN CONST BOOLEAN Result
800 if (Result
|| MoveToTagSpecial(ShellCommandGetCurrentScriptFile())) {
801 return (EFI_SUCCESS
);
803 return (EFI_NOT_FOUND
);
807 Function for 'if' command.
809 @param[in] ImageHandle Handle to the Image (NULL if Internal).
810 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
815 IN EFI_HANDLE ImageHandle
,
816 IN EFI_SYSTEM_TABLE
*SystemTable
820 SHELL_STATUS ShellStatus
;
821 BOOLEAN CaseInsensitive
;
823 UINTN CurrentParameter
;
825 BOOLEAN CurrentValue
;
827 END_TAG_TYPE PreviousEnding
;
828 SCRIPT_FILE
*CurrentScriptFile
;
830 Status
= CommandInit();
831 ASSERT_EFI_ERROR(Status
);
833 if (!gEfiShellProtocol
->BatchIsActive()) {
834 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"if");
835 return (SHELL_UNSUPPORTED
);
838 if (gEfiShellParametersProtocol
->Argc
< 3) {
839 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel1HiiHandle
, L
"if");
840 return (SHELL_INVALID_PARAMETER
);
844 // Make sure that an End exists.
846 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
847 if (!MoveToTag(GetNextNode
, L
"endif", L
"if", NULL
, CurrentScriptFile
, TRUE
, TRUE
, FALSE
)) {
852 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
853 gShellLevel1HiiHandle
,
856 CurrentScriptFile
!=NULL
857 && CurrentScriptFile
->CurrentCommand
!=NULL
858 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
859 return (SHELL_DEVICE_ERROR
);
863 // initialize the shell lib (we must be in non-auto-init...)
865 Status
= ShellInitialize();
866 ASSERT_EFI_ERROR(Status
);
868 CurrentParameter
= 1;
871 if (gUnicodeCollation
->StriColl(
873 gEfiShellParametersProtocol
->Argv
[1],
875 gUnicodeCollation
->StriColl(
877 gEfiShellParametersProtocol
->Argv
[2],
879 (gEfiShellParametersProtocol
->Argc
> 3 && gUnicodeCollation
->StriColl(
881 gEfiShellParametersProtocol
->Argv
[3],
883 CaseInsensitive
= TRUE
;
886 CaseInsensitive
= FALSE
;
888 if (gUnicodeCollation
->StriColl(
890 gEfiShellParametersProtocol
->Argv
[1],
892 gUnicodeCollation
->StriColl(
894 gEfiShellParametersProtocol
->Argv
[2],
896 (gEfiShellParametersProtocol
->Argc
> 3 && gUnicodeCollation
->StriColl(
898 gEfiShellParametersProtocol
->Argv
[3],
906 for ( ShellStatus
= SHELL_SUCCESS
, CurrentValue
= FALSE
, Ending
= EndTagMax
907 ; CurrentParameter
< gEfiShellParametersProtocol
->Argc
&& ShellStatus
== SHELL_SUCCESS
908 ; CurrentParameter
++) {
909 if (gUnicodeCollation
->StriColl(
911 gEfiShellParametersProtocol
->Argv
[CurrentParameter
],
914 // we are at the then
916 if (CurrentParameter
+1 != gEfiShellParametersProtocol
->Argc
) {
917 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_TEXT_AFTER_THEN
), gShellLevel1HiiHandle
, L
"if");
918 ShellStatus
= SHELL_INVALID_PARAMETER
;
920 Status
= PerformResultOperation(CurrentValue
);
921 if (EFI_ERROR(Status
)) {
922 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_AFTER_BAD
), gShellLevel1HiiHandle
, L
"if", gEfiShellParametersProtocol
->Argv
[CurrentParameter
]);
923 ShellStatus
= SHELL_INVALID_PARAMETER
;
927 PreviousEnding
= Ending
;
929 // build up the next statement for analysis
931 if (!BuildNextStatement(CurrentParameter
, &EndParameter
, &Ending
)) {
932 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
937 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
938 gShellLevel1HiiHandle
,
941 CurrentScriptFile
!=NULL
942 && CurrentScriptFile
->CurrentCommand
!=NULL
943 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
944 ShellStatus
= SHELL_INVALID_PARAMETER
;
947 // Analyze the statement
949 Status
= ProcessStatement(&CurrentValue
, CurrentParameter
, EndParameter
, PreviousEnding
, CaseInsensitive
, ForceString
);
950 if (EFI_ERROR(Status
)) {
951 // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_STARTING), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[CurrentParameter]);
952 ShellStatus
= SHELL_INVALID_PARAMETER
;
955 // Optomize to get out of the loop early...
957 if ((Ending
== EndTagOr
&& CurrentValue
) || (Ending
== EndTagAnd
&& !CurrentValue
)) {
958 Status
= PerformResultOperation(CurrentValue
);
959 if (EFI_ERROR(Status
)) {
960 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_AFTER_BAD
), gShellLevel1HiiHandle
, L
"if", gEfiShellParametersProtocol
->Argv
[CurrentParameter
]);
961 ShellStatus
= SHELL_INVALID_PARAMETER
;
967 if (ShellStatus
== SHELL_SUCCESS
){
968 CurrentParameter
= EndParameter
;
970 // Skip over the or or and parameter.
972 if (Ending
== EndTagOr
|| Ending
== EndTagAnd
) {
978 return (ShellStatus
);
982 Function for 'else' command.
984 @param[in] ImageHandle Handle to the Image (NULL if Internal).
985 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
989 ShellCommandRunElse (
990 IN EFI_HANDLE ImageHandle
,
991 IN EFI_SYSTEM_TABLE
*SystemTable
995 SCRIPT_FILE
*CurrentScriptFile
;
997 Status
= CommandInit ();
998 ASSERT_EFI_ERROR (Status
);
1000 if (gEfiShellParametersProtocol
->Argc
> 1) {
1001 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel1HiiHandle
, L
"if");
1002 return (SHELL_INVALID_PARAMETER
);
1005 if (!gEfiShellProtocol
->BatchIsActive()) {
1006 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"Else");
1007 return (SHELL_UNSUPPORTED
);
1010 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
1012 if (!MoveToTag(GetPreviousNode
, L
"if", L
"endif", NULL
, CurrentScriptFile
, FALSE
, TRUE
, FALSE
)) {
1017 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1018 gShellLevel1HiiHandle
,
1021 CurrentScriptFile
!=NULL
1022 && CurrentScriptFile
->CurrentCommand
!=NULL
1023 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1024 return (SHELL_DEVICE_ERROR
);
1026 if (!MoveToTag(GetPreviousNode
, L
"if", L
"else", NULL
, CurrentScriptFile
, FALSE
, TRUE
, FALSE
)) {
1031 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1032 gShellLevel1HiiHandle
,
1035 CurrentScriptFile
!=NULL
1036 && CurrentScriptFile
->CurrentCommand
!=NULL
1037 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1038 return (SHELL_DEVICE_ERROR
);
1041 if (!MoveToTag(GetNextNode
, L
"endif", L
"if", NULL
, CurrentScriptFile
, FALSE
, FALSE
, FALSE
)) {
1046 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1047 gShellLevel1HiiHandle
,
1050 CurrentScriptFile
!=NULL
1051 && CurrentScriptFile
->CurrentCommand
!=NULL
1052 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1053 return (SHELL_DEVICE_ERROR
);
1056 return (SHELL_SUCCESS
);
1060 Function for 'endif' command.
1062 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1063 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1067 ShellCommandRunEndIf (
1068 IN EFI_HANDLE ImageHandle
,
1069 IN EFI_SYSTEM_TABLE
*SystemTable
1073 SCRIPT_FILE
*CurrentScriptFile
;
1075 Status
= CommandInit ();
1076 ASSERT_EFI_ERROR (Status
);
1078 if (gEfiShellParametersProtocol
->Argc
> 1) {
1079 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel1HiiHandle
, L
"if");
1080 return (SHELL_INVALID_PARAMETER
);
1083 if (!gEfiShellProtocol
->BatchIsActive()) {
1084 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"Endif");
1085 return (SHELL_UNSUPPORTED
);
1088 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
1089 if (!MoveToTag(GetPreviousNode
, L
"if", L
"endif", NULL
, CurrentScriptFile
, FALSE
, TRUE
, FALSE
)) {
1094 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1095 gShellLevel1HiiHandle
,
1098 CurrentScriptFile
!=NULL
1099 && CurrentScriptFile
->CurrentCommand
!=NULL
1100 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1101 return (SHELL_DEVICE_ERROR
);
1104 return (SHELL_SUCCESS
);