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
;
61 Tester
[StrLen (Fragment
)] = CHAR_NULL
;
62 if (gUnicodeCollation
->StriColl (
69 // increment the string pointer to the end of what we found and then chop off spaces...
71 *Statement
+= StrLen (Fragment
);
72 while (*Statement
[0] == L
' ') {
86 Determine if String represents a valid profile.
88 @param[in] String The pointer to the string to test.
90 @retval TRUE String is a valid profile.
91 @retval FALSE String is not a valid profile.
95 IN CONST CHAR16
*String
98 CONST CHAR16
*ProfilesString
;
99 CONST CHAR16
*TempLocation
;
101 ProfilesString
= ShellGetEnvironmentVariable (L
"profiles");
102 ASSERT (ProfilesString
!= NULL
);
103 TempLocation
= StrStr (ProfilesString
, String
);
104 if ((TempLocation
!= NULL
) && (*(TempLocation
-1) == L
';') && (*(TempLocation
+StrLen (String
)) == L
';')) {
112 Do a comparison between 2 things.
114 @param[in] Compare1 The first item to compare.
115 @param[in] Compare2 The second item to compare.
116 @param[in] BinOp The type of comparison to perform.
117 @param[in] CaseInsensitive TRUE to do non-case comparison, FALSE otherwise.
118 @param[in] ForceStringCompare TRUE to force string comparison, FALSE otherwise.
120 @return The result of the comparison.
124 IN CONST CHAR16
*Compare1
,
125 IN CONST CHAR16
*Compare2
,
126 IN CONST BIN_OPERATOR_TYPE BinOp
,
127 IN CONST BOOLEAN CaseInsensitive
,
128 IN CONST BOOLEAN ForceStringCompare
135 // "Compare1 BinOp Compare2"
138 case OperatorUnisgnedGreaterThan
:
139 case OperatorGreaterThan
:
140 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber (Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber (Compare2
, FALSE
, FALSE
)) {
144 if ((CaseInsensitive
&& (StringNoCaseCompare (&Compare1
, &Compare2
) > 0)) || (StringCompare (&Compare1
, &Compare2
) > 0)) {
151 if (Compare1
[0] == L
'-') {
152 Cmp1
= 0 - (INTN
)ShellStrToUintn (Compare1
+1);
154 Cmp1
= (INTN
)ShellStrToUintn (Compare1
);
157 if (Compare2
[0] == L
'-') {
158 Cmp2
= 0 - (INTN
)ShellStrToUintn (Compare2
+1);
160 Cmp2
= (INTN
)ShellStrToUintn (Compare2
);
163 if (BinOp
== OperatorGreaterThan
) {
168 if ((UINTN
)Cmp1
> (UINTN
)Cmp2
) {
175 case OperatorUnsignedLessThan
:
176 case OperatorLessThan
:
177 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber (Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber (Compare2
, FALSE
, FALSE
)) {
181 if ((CaseInsensitive
&& (StringNoCaseCompare (&Compare1
, &Compare2
) < 0)) || (StringCompare (&Compare1
, &Compare2
) < 0)) {
188 if (Compare1
[0] == L
'-') {
189 Cmp1
= 0 - (INTN
)ShellStrToUintn (Compare1
+1);
191 Cmp1
= (INTN
)ShellStrToUintn (Compare1
);
194 if (Compare2
[0] == L
'-') {
195 Cmp2
= 0 - (INTN
)ShellStrToUintn (Compare2
+1);
197 Cmp2
= (INTN
)ShellStrToUintn (Compare2
);
200 if (BinOp
== OperatorLessThan
) {
205 if ((UINTN
)Cmp1
< (UINTN
)Cmp2
) {
213 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber (Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber (Compare2
, FALSE
, FALSE
)) {
217 if ((CaseInsensitive
&& (StringNoCaseCompare (&Compare1
, &Compare2
) == 0)) || (StringCompare (&Compare1
, &Compare2
) == 0)) {
224 if (Compare1
[0] == L
'-') {
225 Cmp1
= 0 - (INTN
)ShellStrToUintn (Compare1
+1);
227 Cmp1
= (INTN
)ShellStrToUintn (Compare1
);
230 if (Compare2
[0] == L
'-') {
231 Cmp2
= 0 - (INTN
)ShellStrToUintn (Compare2
+1);
233 Cmp2
= (INTN
)ShellStrToUintn (Compare2
);
242 case OperatorNotEqual
:
243 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber (Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber (Compare2
, FALSE
, FALSE
)) {
247 if ((CaseInsensitive
&& (StringNoCaseCompare (&Compare1
, &Compare2
) != 0)) || (StringCompare (&Compare1
, &Compare2
) != 0)) {
254 if (Compare1
[0] == L
'-') {
255 Cmp1
= 0 - (INTN
)ShellStrToUintn (Compare1
+1);
257 Cmp1
= (INTN
)ShellStrToUintn (Compare1
);
260 if (Compare2
[0] == L
'-') {
261 Cmp2
= 0 - (INTN
)ShellStrToUintn (Compare2
+1);
263 Cmp2
= (INTN
)ShellStrToUintn (Compare2
);
272 case OperatorUnsignedGreaterOrEqual
:
273 case OperatorGreatorOrEqual
:
274 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber (Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber (Compare2
, FALSE
, FALSE
)) {
278 if ((CaseInsensitive
&& (StringNoCaseCompare (&Compare1
, &Compare2
) >= 0)) || (StringCompare (&Compare1
, &Compare2
) >= 0)) {
285 if (Compare1
[0] == L
'-') {
286 Cmp1
= 0 - (INTN
)ShellStrToUintn (Compare1
+1);
288 Cmp1
= (INTN
)ShellStrToUintn (Compare1
);
291 if (Compare2
[0] == L
'-') {
292 Cmp2
= 0 - (INTN
)ShellStrToUintn (Compare2
+1);
294 Cmp2
= (INTN
)ShellStrToUintn (Compare2
);
297 if (BinOp
== OperatorGreatorOrEqual
) {
302 if ((UINTN
)Cmp1
>= (UINTN
)Cmp2
) {
309 case OperatorLessOrEqual
:
310 case OperatorUnsignedLessOrEqual
:
311 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber (Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber (Compare2
, FALSE
, FALSE
)) {
315 if ((CaseInsensitive
&& (StringNoCaseCompare (&Compare1
, &Compare2
) <= 0)) || (StringCompare (&Compare1
, &Compare2
) <= 0)) {
322 if (Compare1
[0] == L
'-') {
323 Cmp1
= 0 - (INTN
)ShellStrToUintn (Compare1
+1);
325 Cmp1
= (INTN
)ShellStrToUintn (Compare1
);
328 if (Compare2
[0] == L
'-') {
329 Cmp2
= 0 - (INTN
)ShellStrToUintn (Compare2
+1);
331 Cmp2
= (INTN
)ShellStrToUintn (Compare2
);
334 if (BinOp
== OperatorLessOrEqual
) {
339 if ((UINTN
)Cmp1
<= (UINTN
)Cmp2
) {
353 Process an if statement and determine if its is valid or not.
355 @param[in, out] PassingState Opon entry, the current state. Upon exit,
357 @param[in] StartParameterNumber The number of the first parameter of
359 @param[in] EndParameterNumber The number of the final parameter of
361 @param[in] OperatorToUse The type of termination operator.
362 @param[in] CaseInsensitive TRUE for case insensitive, FALSE otherwise.
363 @param[in] ForceStringCompare TRUE for all string based, FALSE otherwise.
365 @retval EFI_INVALID_PARAMETER A parameter was invalid.
366 @retval EFI_SUCCESS The operation was successful.
370 IN OUT BOOLEAN
*PassingState
,
371 IN UINTN StartParameterNumber
,
372 IN UINTN EndParameterNumber
,
373 IN CONST END_TAG_TYPE OperatorToUse
,
374 IN CONST BOOLEAN CaseInsensitive
,
375 IN CONST BOOLEAN ForceStringCompare
379 BOOLEAN OperationResult
;
381 CHAR16
*StatementWalker
;
382 BIN_OPERATOR_TYPE BinOp
;
385 CHAR16 HexString
[20];
389 ASSERT ((END_TAG_TYPE
)OperatorToUse
!= EndTagThen
);
391 Status
= EFI_SUCCESS
;
393 OperationResult
= FALSE
;
395 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
];
396 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"not", &Match
)) && Match
) {
398 StatementWalker
= gEfiShellParametersProtocol
->Argv
[++StartParameterNumber
];
404 // now check for 'boolfunc' operators
406 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"isint", &Match
)) && Match
) {
407 if ( !EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
408 && (StatementWalker
[StrLen (StatementWalker
)-1] == L
')'))
410 StatementWalker
[StrLen (StatementWalker
)-1] = CHAR_NULL
;
411 OperationResult
= ShellIsHexOrDecimalNumber (StatementWalker
, FALSE
, FALSE
);
413 Status
= EFI_INVALID_PARAMETER
;
414 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"isint");
416 } else if ((!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"exists", &Match
)) && Match
) ||
417 (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"exist", &Match
)) && Match
))
419 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&&
420 (StatementWalker
[StrLen (StatementWalker
)-1] == L
')'))
422 StatementWalker
[StrLen (StatementWalker
)-1] = CHAR_NULL
;
424 // is what remains a file in CWD???
426 OperationResult
= (BOOLEAN
)(ShellFileExists (StatementWalker
) == EFI_SUCCESS
);
427 } else if ((StatementWalker
[0] == CHAR_NULL
) && (StartParameterNumber
+1 == EndParameterNumber
)) {
428 OperationResult
= (BOOLEAN
)(ShellFileExists (gEfiShellParametersProtocol
->Argv
[++StartParameterNumber
]) == EFI_SUCCESS
);
430 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"exist(s)");
431 Status
= EFI_INVALID_PARAMETER
;
433 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"available", &Match
)) && Match
) {
434 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&&
435 (StatementWalker
[StrLen (StatementWalker
)-1] == L
')'))
437 StatementWalker
[StrLen (StatementWalker
)-1] = CHAR_NULL
;
439 // is what remains a file in the CWD or path???
441 OperationResult
= (BOOLEAN
)(ShellIsFileInPath (StatementWalker
) == EFI_SUCCESS
);
443 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"available");
444 Status
= EFI_INVALID_PARAMETER
;
446 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"profile", &Match
)) && Match
) {
447 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&&
448 (StatementWalker
[StrLen (StatementWalker
)-1] == L
')'))
453 StatementWalker
[StrLen (StatementWalker
)-1] = CHAR_NULL
;
454 OperationResult
= IsValidProfile (StatementWalker
);
456 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"profile");
457 Status
= EFI_INVALID_PARAMETER
;
459 } else if (StartParameterNumber
+1 >= EndParameterNumber
) {
460 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[StartParameterNumber
]);
461 Status
= EFI_INVALID_PARAMETER
;
464 // must be 'item binop item' style
471 // get the first item
473 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
];
474 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"efierror", &Match
)) && Match
) {
475 TempSpot
= StrStr (StatementWalker
, L
")");
476 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&& (TempSpot
!= NULL
)) {
477 *TempSpot
= CHAR_NULL
;
478 if (ShellIsHexOrDecimalNumber (StatementWalker
, FALSE
, FALSE
)) {
479 UnicodeSPrint (HexString
, sizeof (HexString
), L
"0x%x", ShellStrToUintn (StatementWalker
)|MAX_BIT
);
480 ASSERT (Compare1
== NULL
);
481 Compare1
= StrnCatGrow (&Compare1
, NULL
, HexString
, 0);
482 StatementWalker
+= StrLen (StatementWalker
) + 1;
484 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
485 Status
= EFI_INVALID_PARAMETER
;
488 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
489 Status
= EFI_INVALID_PARAMETER
;
491 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"pierror", &Match
)) && Match
) {
492 TempSpot
= StrStr (StatementWalker
, L
")");
493 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&& (TempSpot
!= NULL
)) {
494 *TempSpot
= CHAR_NULL
;
495 if (ShellIsHexOrDecimalNumber (StatementWalker
, FALSE
, FALSE
)) {
496 UnicodeSPrint (HexString
, sizeof (HexString
), L
"0x%x", ShellStrToUintn (StatementWalker
)|MAX_BIT
|(MAX_BIT
>>2));
497 ASSERT (Compare1
== NULL
);
498 Compare1
= StrnCatGrow (&Compare1
, NULL
, HexString
, 0);
499 StatementWalker
+= StrLen (StatementWalker
) + 1;
501 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
502 Status
= EFI_INVALID_PARAMETER
;
505 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
506 Status
= EFI_INVALID_PARAMETER
;
508 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"oemerror", &Match
)) && Match
) {
509 TempSpot
= StrStr (StatementWalker
, L
")");
510 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&& (TempSpot
!= NULL
)) {
511 TempSpot
= CHAR_NULL
;
512 if (ShellIsHexOrDecimalNumber (StatementWalker
, FALSE
, FALSE
)) {
513 UnicodeSPrint (HexString
, sizeof (HexString
), L
"0x%x", ShellStrToUintn (StatementWalker
)|MAX_BIT
|(MAX_BIT
>>1));
514 ASSERT (Compare1
== NULL
);
515 Compare1
= StrnCatGrow (&Compare1
, NULL
, HexString
, 0);
516 StatementWalker
+= StrLen (StatementWalker
) + 1;
518 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
519 Status
= EFI_INVALID_PARAMETER
;
522 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
523 Status
= EFI_INVALID_PARAMETER
;
526 ASSERT (Compare1
== NULL
);
527 if (EndParameterNumber
- StartParameterNumber
> 2) {
528 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_STARTING
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+2]);
529 Status
= EFI_INVALID_PARAMETER
;
532 // must be a raw string
534 Compare1
= StrnCatGrow (&Compare1
, NULL
, StatementWalker
, 0);
541 ASSERT (StartParameterNumber
+1 < EndParameterNumber
);
542 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+1];
543 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"gt", &Match
)) && Match
) {
544 BinOp
= OperatorGreaterThan
;
545 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"lt", &Match
)) && Match
) {
546 BinOp
= OperatorLessThan
;
547 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"eq", &Match
)) && Match
) {
548 BinOp
= OperatorEqual
;
549 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"ne", &Match
)) && Match
) {
550 BinOp
= OperatorNotEqual
;
551 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"ge", &Match
)) && Match
) {
552 BinOp
= OperatorGreatorOrEqual
;
553 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"le", &Match
)) && Match
) {
554 BinOp
= OperatorLessOrEqual
;
555 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"==", &Match
)) && Match
) {
556 BinOp
= OperatorEqual
;
557 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"ugt", &Match
)) && Match
) {
558 BinOp
= OperatorUnisgnedGreaterThan
;
559 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"ult", &Match
)) && Match
) {
560 BinOp
= OperatorUnsignedLessThan
;
561 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"uge", &Match
)) && Match
) {
562 BinOp
= OperatorUnsignedGreaterOrEqual
;
563 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"ule", &Match
)) && Match
) {
564 BinOp
= OperatorUnsignedLessOrEqual
;
566 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_INVALID_BINOP
), gShellLevel1HiiHandle
, StatementWalker
);
567 Status
= EFI_INVALID_PARAMETER
;
571 // get the second item
573 ASSERT (StartParameterNumber
+2 <= EndParameterNumber
);
574 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+2];
575 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"efierror", &Match
)) && Match
) {
576 TempSpot
= StrStr (StatementWalker
, L
")");
577 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&& (TempSpot
!= NULL
)) {
578 TempSpot
= CHAR_NULL
;
579 if (ShellIsHexOrDecimalNumber (StatementWalker
, FALSE
, FALSE
)) {
580 UnicodeSPrint (HexString
, sizeof (HexString
), L
"0x%x", ShellStrToUintn (StatementWalker
)|MAX_BIT
);
581 ASSERT (Compare2
== NULL
);
582 Compare2
= StrnCatGrow (&Compare2
, NULL
, HexString
, 0);
583 StatementWalker
+= StrLen (StatementWalker
) + 1;
585 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
586 Status
= EFI_INVALID_PARAMETER
;
589 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
590 Status
= EFI_INVALID_PARAMETER
;
594 // can this be collapsed into the above?
596 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"pierror", &Match
)) && Match
) {
597 TempSpot
= StrStr (StatementWalker
, L
")");
598 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&& (TempSpot
!= NULL
)) {
599 TempSpot
= CHAR_NULL
;
600 if (ShellIsHexOrDecimalNumber (StatementWalker
, FALSE
, FALSE
)) {
601 UnicodeSPrint (HexString
, sizeof (HexString
), L
"0x%x", ShellStrToUintn (StatementWalker
)|MAX_BIT
|(MAX_BIT
>>2));
602 ASSERT (Compare2
== NULL
);
603 Compare2
= StrnCatGrow (&Compare2
, NULL
, HexString
, 0);
604 StatementWalker
+= StrLen (StatementWalker
) + 1;
606 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
607 Status
= EFI_INVALID_PARAMETER
;
610 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
611 Status
= EFI_INVALID_PARAMETER
;
613 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"oemerror", &Match
)) && Match
) {
614 TempSpot
= StrStr (StatementWalker
, L
")");
615 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&& (TempSpot
!= NULL
)) {
616 TempSpot
= CHAR_NULL
;
617 if (ShellIsHexOrDecimalNumber (StatementWalker
, FALSE
, FALSE
)) {
618 UnicodeSPrint (HexString
, sizeof (HexString
), L
"0x%x", ShellStrToUintn (StatementWalker
)|MAX_BIT
|(MAX_BIT
>>1));
619 ASSERT (Compare2
== NULL
);
620 Compare2
= StrnCatGrow (&Compare2
, NULL
, HexString
, 0);
621 StatementWalker
+= StrLen (StatementWalker
) + 1;
623 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
624 Status
= EFI_INVALID_PARAMETER
;
627 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
628 Status
= EFI_INVALID_PARAMETER
;
632 // must be a raw string
634 ASSERT (Compare2
== NULL
);
635 Compare2
= StrnCatGrow (&Compare2
, NULL
, StatementWalker
, 0);
638 if ((Compare1
!= NULL
) && (Compare2
!= NULL
) && (BinOp
!= OperatorMax
)) {
639 OperationResult
= TestOperation (Compare1
, Compare2
, BinOp
, CaseInsensitive
, ForceStringCompare
);
642 SHELL_FREE_NON_NULL (Compare1
);
643 SHELL_FREE_NON_NULL (Compare2
);
647 // done processing do result...
650 if (!EFI_ERROR (Status
)) {
652 OperationResult
= (BOOLEAN
)(!OperationResult
);
655 switch (OperatorToUse
) {
657 *PassingState
= (BOOLEAN
)(*PassingState
|| OperationResult
);
660 *PassingState
= (BOOLEAN
)(*PassingState
&& OperationResult
);
663 *PassingState
= (BOOLEAN
)(OperationResult
);
674 Break up the next part of the if statement (until the next 'and', 'or', or 'then').
676 @param[in] ParameterNumber The current parameter number.
677 @param[out] EndParameter Upon successful return, will point to the
678 parameter to start the next iteration with.
679 @param[out] EndTag Upon successful return, will point to the
680 type that was found at the end of this statement.
682 @retval TRUE A valid statement was found.
683 @retval FALSE A valid statement was not found.
687 IN UINTN ParameterNumber
,
688 OUT UINTN
*EndParameter
,
689 OUT END_TAG_TYPE
*EndTag
695 ; ParameterNumber
< gEfiShellParametersProtocol
->Argc
699 if (gUnicodeCollation
->StriColl (
701 gEfiShellParametersProtocol
->Argv
[ParameterNumber
],
705 *EndParameter
= ParameterNumber
- 1;
708 } else if (gUnicodeCollation
->StriColl (
710 gEfiShellParametersProtocol
->Argv
[ParameterNumber
],
714 *EndParameter
= ParameterNumber
- 1;
717 } else if (gUnicodeCollation
->StriColl (
719 gEfiShellParametersProtocol
->Argv
[ParameterNumber
],
723 *EndParameter
= ParameterNumber
- 1;
724 *EndTag
= EndTagThen
;
729 if (*EndTag
== EndTagMax
) {
737 Move the script file pointer to a different place in the script file.
738 This one is special since it handles the if/else/endif syntax.
740 @param[in] ScriptFile The script file from GetCurrnetScriptFile().
742 @retval TRUE The move target was found and the move was successful.
743 @retval FALSE Something went wrong.
747 IN SCRIPT_FILE
*ScriptFile
750 SCRIPT_COMMAND_LIST
*CommandNode
;
754 CHAR16
*CommandWalker
;
755 CHAR16
*TempLocation
;
760 if (ScriptFile
== NULL
) {
764 for (CommandNode
= (SCRIPT_COMMAND_LIST
*)GetNextNode (&ScriptFile
->CommandList
, &ScriptFile
->CurrentCommand
->Link
), Found
= FALSE
765 ; !IsNull (&ScriptFile
->CommandList
, &CommandNode
->Link
) && !Found
766 ; CommandNode
= (SCRIPT_COMMAND_LIST
*)GetNextNode (&ScriptFile
->CommandList
, &CommandNode
->Link
)
770 // get just the first part of the command line...
773 CommandName
= StrnCatGrow (&CommandName
, NULL
, CommandNode
->Cl
, 0);
774 if (CommandName
== NULL
) {
778 CommandWalker
= CommandName
;
781 // Skip leading spaces and tabs.
783 while ((CommandWalker
[0] == L
' ') || (CommandWalker
[0] == L
'\t')) {
787 TempLocation
= StrStr (CommandWalker
, L
" ");
789 if (TempLocation
!= NULL
) {
790 *TempLocation
= CHAR_NULL
;
794 // did we find a nested item ?
796 if (gUnicodeCollation
->StriColl (
798 (CHAR16
*)CommandWalker
,
803 } else if ((TargetCount
== 1) && (gUnicodeCollation
->StriColl (
805 (CHAR16
*)CommandWalker
,
810 // else can only decrement the last part... not an nested if
811 // hence the TargetCount compare added
814 } else if (gUnicodeCollation
->StriColl (
816 (CHAR16
*)CommandWalker
,
823 if (TargetCount
== 0) {
824 ScriptFile
->CurrentCommand
= (SCRIPT_COMMAND_LIST
*)GetNextNode (&ScriptFile
->CommandList
, &CommandNode
->Link
);
829 // Free the memory for this loop...
831 SHELL_FREE_NON_NULL (CommandName
);
838 Deal with the result of the if operation.
840 @param[in] Result The result of the if.
842 @retval EFI_SUCCESS The operation was successful.
843 @retval EFI_NOT_FOUND The ending tag could not be found.
846 PerformResultOperation (
847 IN CONST BOOLEAN Result
850 if (Result
|| MoveToTagSpecial (ShellCommandGetCurrentScriptFile ())) {
851 return (EFI_SUCCESS
);
854 return (EFI_NOT_FOUND
);
858 Function for 'if' command.
860 @param[in] ImageHandle Handle to the Image (NULL if Internal).
861 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
866 IN EFI_HANDLE ImageHandle
,
867 IN EFI_SYSTEM_TABLE
*SystemTable
871 SHELL_STATUS ShellStatus
;
872 BOOLEAN CaseInsensitive
;
874 UINTN CurrentParameter
;
876 BOOLEAN CurrentValue
;
878 END_TAG_TYPE PreviousEnding
;
879 SCRIPT_FILE
*CurrentScriptFile
;
881 Status
= CommandInit ();
882 ASSERT_EFI_ERROR (Status
);
884 if (!gEfiShellProtocol
->BatchIsActive ()) {
885 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"if");
886 return (SHELL_UNSUPPORTED
);
889 if (gEfiShellParametersProtocol
->Argc
< 3) {
890 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel1HiiHandle
, L
"if");
891 return (SHELL_INVALID_PARAMETER
);
895 // Make sure that an End exists.
897 CurrentScriptFile
= ShellCommandGetCurrentScriptFile ();
898 if (!MoveToTag (GetNextNode
, L
"endif", L
"if", NULL
, CurrentScriptFile
, TRUE
, TRUE
, FALSE
)) {
903 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
904 gShellLevel1HiiHandle
,
907 CurrentScriptFile
!= NULL
908 && CurrentScriptFile
->CurrentCommand
!= NULL
909 ? CurrentScriptFile
->CurrentCommand
->Line
: 0
911 return (SHELL_DEVICE_ERROR
);
915 // initialize the shell lib (we must be in non-auto-init...)
917 Status
= ShellInitialize ();
918 ASSERT_EFI_ERROR (Status
);
920 CurrentParameter
= 1;
923 if ((gUnicodeCollation
->StriColl (
925 gEfiShellParametersProtocol
->Argv
[1],
928 (gUnicodeCollation
->StriColl (
930 gEfiShellParametersProtocol
->Argv
[2],
933 ((gEfiShellParametersProtocol
->Argc
> 3) && (gUnicodeCollation
->StriColl (
935 gEfiShellParametersProtocol
->Argv
[3],
939 CaseInsensitive
= TRUE
;
942 CaseInsensitive
= FALSE
;
945 if ((gUnicodeCollation
->StriColl (
947 gEfiShellParametersProtocol
->Argv
[1],
950 (gUnicodeCollation
->StriColl (
952 gEfiShellParametersProtocol
->Argv
[2],
955 ((gEfiShellParametersProtocol
->Argc
> 3) && (gUnicodeCollation
->StriColl (
957 gEfiShellParametersProtocol
->Argv
[3],
967 for ( ShellStatus
= SHELL_SUCCESS
, CurrentValue
= FALSE
, Ending
= EndTagMax
968 ; CurrentParameter
< gEfiShellParametersProtocol
->Argc
&& ShellStatus
== SHELL_SUCCESS
969 ; CurrentParameter
++)
971 if (gUnicodeCollation
->StriColl (
973 gEfiShellParametersProtocol
->Argv
[CurrentParameter
],
978 // we are at the then
980 if (CurrentParameter
+1 != gEfiShellParametersProtocol
->Argc
) {
981 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_TEXT_AFTER_THEN
), gShellLevel1HiiHandle
, L
"if");
982 ShellStatus
= SHELL_INVALID_PARAMETER
;
984 Status
= PerformResultOperation (CurrentValue
);
985 if (EFI_ERROR (Status
)) {
986 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_AFTER_BAD
), gShellLevel1HiiHandle
, L
"if", gEfiShellParametersProtocol
->Argv
[CurrentParameter
]);
987 ShellStatus
= SHELL_INVALID_PARAMETER
;
991 PreviousEnding
= Ending
;
993 // build up the next statement for analysis
995 if (!BuildNextStatement (CurrentParameter
, &EndParameter
, &Ending
)) {
996 CurrentScriptFile
= ShellCommandGetCurrentScriptFile ();
1001 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1002 gShellLevel1HiiHandle
,
1005 CurrentScriptFile
!= NULL
1006 && CurrentScriptFile
->CurrentCommand
!= NULL
1007 ? CurrentScriptFile
->CurrentCommand
->Line
: 0
1009 ShellStatus
= SHELL_INVALID_PARAMETER
;
1012 // Analyze the statement
1014 Status
= ProcessStatement (&CurrentValue
, CurrentParameter
, EndParameter
, PreviousEnding
, CaseInsensitive
, ForceString
);
1015 if (EFI_ERROR (Status
)) {
1016 // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_STARTING), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[CurrentParameter]);
1017 ShellStatus
= SHELL_INVALID_PARAMETER
;
1020 // Optomize to get out of the loop early...
1022 if (((Ending
== EndTagOr
) && CurrentValue
) || ((Ending
== EndTagAnd
) && !CurrentValue
)) {
1023 Status
= PerformResultOperation (CurrentValue
);
1024 if (EFI_ERROR (Status
)) {
1025 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_AFTER_BAD
), gShellLevel1HiiHandle
, L
"if", gEfiShellParametersProtocol
->Argv
[CurrentParameter
]);
1026 ShellStatus
= SHELL_INVALID_PARAMETER
;
1034 if (ShellStatus
== SHELL_SUCCESS
) {
1035 CurrentParameter
= EndParameter
;
1037 // Skip over the or or and parameter.
1039 if ((Ending
== EndTagOr
) || (Ending
== EndTagAnd
)) {
1046 return (ShellStatus
);
1050 Function for 'else' command.
1052 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1053 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1057 ShellCommandRunElse (
1058 IN EFI_HANDLE ImageHandle
,
1059 IN EFI_SYSTEM_TABLE
*SystemTable
1063 SCRIPT_FILE
*CurrentScriptFile
;
1065 Status
= CommandInit ();
1066 ASSERT_EFI_ERROR (Status
);
1068 if (gEfiShellParametersProtocol
->Argc
> 1) {
1069 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel1HiiHandle
, L
"if");
1070 return (SHELL_INVALID_PARAMETER
);
1073 if (!gEfiShellProtocol
->BatchIsActive ()) {
1074 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"Else");
1075 return (SHELL_UNSUPPORTED
);
1078 CurrentScriptFile
= ShellCommandGetCurrentScriptFile ();
1080 if (!MoveToTag (GetPreviousNode
, L
"if", L
"endif", NULL
, CurrentScriptFile
, FALSE
, TRUE
, FALSE
)) {
1085 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1086 gShellLevel1HiiHandle
,
1089 CurrentScriptFile
!= NULL
1090 && CurrentScriptFile
->CurrentCommand
!= NULL
1091 ? CurrentScriptFile
->CurrentCommand
->Line
: 0
1093 return (SHELL_DEVICE_ERROR
);
1096 if (!MoveToTag (GetPreviousNode
, L
"if", L
"else", NULL
, CurrentScriptFile
, FALSE
, TRUE
, FALSE
)) {
1101 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1102 gShellLevel1HiiHandle
,
1105 CurrentScriptFile
!= NULL
1106 && CurrentScriptFile
->CurrentCommand
!= NULL
1107 ? CurrentScriptFile
->CurrentCommand
->Line
: 0
1109 return (SHELL_DEVICE_ERROR
);
1112 if (!MoveToTag (GetNextNode
, L
"endif", L
"if", NULL
, CurrentScriptFile
, FALSE
, FALSE
, FALSE
)) {
1117 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1118 gShellLevel1HiiHandle
,
1121 CurrentScriptFile
!= NULL
1122 && CurrentScriptFile
->CurrentCommand
!= NULL
1123 ? CurrentScriptFile
->CurrentCommand
->Line
: 0
1125 return (SHELL_DEVICE_ERROR
);
1128 return (SHELL_SUCCESS
);
1132 Function for 'endif' command.
1134 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1135 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1139 ShellCommandRunEndIf (
1140 IN EFI_HANDLE ImageHandle
,
1141 IN EFI_SYSTEM_TABLE
*SystemTable
1145 SCRIPT_FILE
*CurrentScriptFile
;
1147 Status
= CommandInit ();
1148 ASSERT_EFI_ERROR (Status
);
1150 if (gEfiShellParametersProtocol
->Argc
> 1) {
1151 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel1HiiHandle
, L
"if");
1152 return (SHELL_INVALID_PARAMETER
);
1155 if (!gEfiShellProtocol
->BatchIsActive ()) {
1156 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"Endif");
1157 return (SHELL_UNSUPPORTED
);
1160 CurrentScriptFile
= ShellCommandGetCurrentScriptFile ();
1161 if (!MoveToTag (GetPreviousNode
, L
"if", L
"endif", NULL
, CurrentScriptFile
, FALSE
, TRUE
, FALSE
)) {
1166 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1167 gShellLevel1HiiHandle
,
1170 CurrentScriptFile
!= NULL
1171 && CurrentScriptFile
->CurrentCommand
!= NULL
1172 ? CurrentScriptFile
->CurrentCommand
->Line
: 0
1174 return (SHELL_DEVICE_ERROR
);
1177 return (SHELL_SUCCESS
);