2 Main file for If and else shell level 1 function.
4 Copyright (c) 2013, Hewlett-Packard Development Company, L.P.
5 Copyright (c) 2009 - 2011, 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
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.
16 #include "UefiShellLevel1CommandsLib.h"
17 #include <Library/PrintLib.h>
18 #include <Library/PathLib.h>
32 OperatorGreatorOrEqual
,
34 OperatorUnisgnedGreaterThan
,
35 OperatorUnsignedLessThan
,
36 OperatorUnsignedGreaterOrEqual
,
37 OperatorUnsignedLessOrEqual
,
42 Extract the next fragment, if there is one.
44 @param[in, out] Statement The current remaining statement.
45 @param[in] Fragment The current fragment.
47 @retval FALSE There is not another fragment.
48 @retval TRUE There is another fragment.
53 IN OUT CONST CHAR16
**Statement
,
54 IN CONST CHAR16
*Fragment
61 Tester
= StrnCatGrow(&Tester
, NULL
, *Statement
, StrLen(Fragment
));
62 ASSERT(Tester
!= NULL
);
63 Tester
[StrLen(Fragment
)] = CHAR_NULL
;
64 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
' ') {
83 Determine if String represents a valid profile.
85 @param[in] String The pointer to the string to test.
87 @retval TRUE String is a valid profile.
88 @retval FALSE String is not a valid profile.
93 IN CONST CHAR16
*String
96 CONST CHAR16
*ProfilesString
;
97 CONST CHAR16
*TempLocation
;
99 ProfilesString
= ShellGetEnvironmentVariable(L
"profiles");
100 ASSERT(ProfilesString
!= NULL
);
101 TempLocation
= StrStr(ProfilesString
, String
);
102 if ((TempLocation
!= NULL
) && (*(TempLocation
-1) == L
';') && (*(TempLocation
+StrLen(String
)) == L
';')) {
109 Do a comparison between 2 things.
111 @param[in] Compare1 The first item to compare.
112 @param[in] Compare2 The second item to compare.
113 @param[in] BinOp The type of comparison to perform.
114 @param[in] CaseInsensitive TRUE to do non-case comparison, FALSE otherwise.
115 @param[in] ForceStringCompare TRUE to force string comparison, FALSE otherwise.
117 @return The result of the comparison.
122 IN CONST CHAR16
*Compare1
,
123 IN CONST CHAR16
*Compare2
,
124 IN CONST BIN_OPERATOR_TYPE BinOp
,
125 IN CONST BOOLEAN CaseInsensitive
,
126 IN CONST BOOLEAN ForceStringCompare
133 // "Compare1 BinOp Compare2"
136 case OperatorUnisgnedGreaterThan
:
137 case OperatorGreaterThan
:
138 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
142 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) > 0) || (StringCompare(&Compare1
, &Compare2
) > 0)) {
149 if (Compare1
[0] == L
'-') {
150 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
152 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
154 if (Compare2
[0] == L
'-') {
155 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
157 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
159 if (BinOp
== OperatorGreaterThan
) {
164 if ((UINTN
)Cmp1
> (UINTN
)Cmp2
) {
170 case OperatorUnsignedLessThan
:
171 case OperatorLessThan
:
172 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
176 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) < 0) || (StringCompare(&Compare1
, &Compare2
) < 0)) {
183 if (Compare1
[0] == L
'-') {
184 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
186 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
188 if (Compare2
[0] == L
'-') {
189 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
191 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
193 if (BinOp
== OperatorLessThan
) {
198 if ((UINTN
)Cmp1
< (UINTN
)Cmp2
) {
206 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
210 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) == 0) || (StringCompare(&Compare1
, &Compare2
) == 0)) {
217 if (Compare1
[0] == L
'-') {
218 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
220 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
222 if (Compare2
[0] == L
'-') {
223 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
225 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
232 case OperatorNotEqual
:
233 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
237 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) != 0) || (StringCompare(&Compare1
, &Compare2
) != 0)) {
244 if (Compare1
[0] == L
'-') {
245 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
247 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
249 if (Compare2
[0] == L
'-') {
250 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
252 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
259 case OperatorUnsignedGreaterOrEqual
:
260 case OperatorGreatorOrEqual
:
261 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
265 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) >= 0) || (StringCompare(&Compare1
, &Compare2
) >= 0)) {
272 if (Compare1
[0] == L
'-') {
273 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
275 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
277 if (Compare2
[0] == L
'-') {
278 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
280 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
282 if (BinOp
== OperatorGreatorOrEqual
) {
287 if ((UINTN
)Cmp1
>= (UINTN
)Cmp2
) {
293 case OperatorLessOrEqual
:
294 case OperatorUnsignedLessOrEqual
:
295 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
299 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) <= 0) || (StringCompare(&Compare1
, &Compare2
) <= 0)) {
306 if (Compare1
[0] == L
'-') {
307 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
309 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
311 if (Compare2
[0] == L
'-') {
312 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
314 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
316 if (BinOp
== OperatorLessOrEqual
) {
321 if ((UINTN
)Cmp1
<= (UINTN
)Cmp2
) {
334 Process an if statement and determine if its is valid or not.
336 @param[in, out] PassingState Opon entry, the current state. Upon exit,
338 @param[in] StartParameterNumber The number of the first parameter of
340 @param[in] EndParameterNumber The number of the final parameter of
342 @param[in] OperatorToUse The type of termination operator.
343 @param[in] CaseInsensitive TRUE for case insensitive, FALSE otherwise.
344 @param[in] ForceStringCompare TRUE for all string based, FALSE otherwise.
346 @retval EFI_INVALID_PARAMETER A parameter was invalid.
347 @retval EFI_SUCCESS The operation was successful.
352 IN OUT BOOLEAN
*PassingState
,
353 IN UINTN StartParameterNumber
,
354 IN UINTN EndParameterNumber
,
355 IN CONST END_TAG_TYPE OperatorToUse
,
356 IN CONST BOOLEAN CaseInsensitive
,
357 IN CONST BOOLEAN ForceStringCompare
361 BOOLEAN OperationResult
;
363 CHAR16
*StatementWalker
;
364 BIN_OPERATOR_TYPE BinOp
;
367 CHAR16 HexString
[20];
370 ASSERT((END_TAG_TYPE
)OperatorToUse
!= EndTagThen
);
372 Status
= EFI_SUCCESS
;
374 OperationResult
= FALSE
;
375 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
];
376 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"not")) {
378 StatementWalker
= gEfiShellParametersProtocol
->Argv
[++StartParameterNumber
];
384 // now check for 'boolfunc' operators
386 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"isint")) {
387 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
388 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
389 OperationResult
= ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
);
391 Status
= EFI_INVALID_PARAMETER
;
392 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"isint");
394 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"exists") || IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"exist")) {
395 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && 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 (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"available")) {
408 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
409 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
411 // is what remains a file in the CWD or path???
413 OperationResult
= (BOOLEAN
)(ShellIsFileInPath(StatementWalker
)==EFI_SUCCESS
);
415 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"available");
416 Status
= EFI_INVALID_PARAMETER
;
418 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"profile")) {
419 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
423 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
424 OperationResult
= IsValidProfile(StatementWalker
);
426 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"profile");
427 Status
= EFI_INVALID_PARAMETER
;
429 } else if (StartParameterNumber
+1 >= EndParameterNumber
) {
430 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[StartParameterNumber
]);
431 Status
= EFI_INVALID_PARAMETER
;
434 // must be 'item binop item' style
441 // get the first item
443 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
];
444 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"efierror")) {
445 TempSpot
= StrStr(StatementWalker
, L
")");
446 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
447 *TempSpot
= CHAR_NULL
;
448 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
449 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
);
450 ASSERT(Compare1
== NULL
);
451 Compare1
= StrnCatGrow(&Compare1
, NULL
, HexString
, 0);
452 StatementWalker
+= StrLen(StatementWalker
) + 1;
454 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
455 Status
= EFI_INVALID_PARAMETER
;
458 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
459 Status
= EFI_INVALID_PARAMETER
;
461 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"pierror")) {
462 TempSpot
= StrStr(StatementWalker
, L
")");
463 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
464 *TempSpot
= CHAR_NULL
;
465 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
466 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>2));
467 ASSERT(Compare1
== NULL
);
468 Compare1
= StrnCatGrow(&Compare1
, NULL
, HexString
, 0);
469 StatementWalker
+= StrLen(StatementWalker
) + 1;
471 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
472 Status
= EFI_INVALID_PARAMETER
;
475 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
476 Status
= EFI_INVALID_PARAMETER
;
478 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"oemerror")) {
479 TempSpot
= StrStr(StatementWalker
, L
")");
480 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
481 TempSpot
= CHAR_NULL
;
482 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
483 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>1));
484 ASSERT(Compare1
== NULL
);
485 Compare1
= StrnCatGrow(&Compare1
, NULL
, HexString
, 0);
486 StatementWalker
+= StrLen(StatementWalker
) + 1;
488 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
489 Status
= EFI_INVALID_PARAMETER
;
492 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
493 Status
= EFI_INVALID_PARAMETER
;
496 ASSERT(Compare1
== NULL
);
497 if (EndParameterNumber
- StartParameterNumber
> 2) {
498 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_STARTING
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+2]);
499 Status
= EFI_INVALID_PARAMETER
;
502 // must be a raw string
504 Compare1
= StrnCatGrow(&Compare1
, NULL
, StatementWalker
, 0);
511 ASSERT(StartParameterNumber
+1<EndParameterNumber
);
512 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+1];
513 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"gt")) {
514 BinOp
= OperatorGreaterThan
;
515 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"lt")) {
516 BinOp
= OperatorLessThan
;
517 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"eq")) {
518 BinOp
= OperatorEqual
;
519 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ne")) {
520 BinOp
= OperatorNotEqual
;
521 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ge")) {
522 BinOp
= OperatorGreatorOrEqual
;
523 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"le")) {
524 BinOp
= OperatorLessOrEqual
;
525 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"==")) {
526 BinOp
= OperatorEqual
;
527 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ugt")) {
528 BinOp
= OperatorUnisgnedGreaterThan
;
529 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ult")) {
530 BinOp
= OperatorUnsignedLessThan
;
531 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"uge")) {
532 BinOp
= OperatorUnsignedGreaterOrEqual
;
533 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ule")) {
534 BinOp
= OperatorUnsignedLessOrEqual
;
536 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_INVALID_BINOP
), gShellLevel1HiiHandle
, StatementWalker
);
537 Status
= EFI_INVALID_PARAMETER
;
541 // get the second item
543 ASSERT(StartParameterNumber
+2<=EndParameterNumber
);
544 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+2];
545 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"efierror")) {
546 TempSpot
= StrStr(StatementWalker
, L
")");
547 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
548 TempSpot
= CHAR_NULL
;
549 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
550 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
);
551 ASSERT(Compare2
== NULL
);
552 Compare2
= StrnCatGrow(&Compare2
, NULL
, HexString
, 0);
553 StatementWalker
+= StrLen(StatementWalker
) + 1;
555 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
556 Status
= EFI_INVALID_PARAMETER
;
559 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
560 Status
= EFI_INVALID_PARAMETER
;
563 // can this be collapsed into the above?
565 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"pierror")) {
566 TempSpot
= StrStr(StatementWalker
, L
")");
567 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
568 TempSpot
= CHAR_NULL
;
569 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
570 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>2));
571 ASSERT(Compare2
== NULL
);
572 Compare2
= StrnCatGrow(&Compare2
, NULL
, HexString
, 0);
573 StatementWalker
+= StrLen(StatementWalker
) + 1;
575 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
576 Status
= EFI_INVALID_PARAMETER
;
579 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
580 Status
= EFI_INVALID_PARAMETER
;
582 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"oemerror")) {
583 TempSpot
= StrStr(StatementWalker
, L
")");
584 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
585 TempSpot
= CHAR_NULL
;
586 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
587 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>1));
588 ASSERT(Compare2
== NULL
);
589 Compare2
= StrnCatGrow(&Compare2
, NULL
, HexString
, 0);
590 StatementWalker
+= StrLen(StatementWalker
) + 1;
592 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
593 Status
= EFI_INVALID_PARAMETER
;
596 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
597 Status
= EFI_INVALID_PARAMETER
;
601 // must be a raw string
603 ASSERT(Compare2
== NULL
);
604 Compare2
= StrnCatGrow(&Compare2
, NULL
, StatementWalker
, 0);
607 if (Compare1
!= NULL
&& Compare2
!= NULL
&& BinOp
!= OperatorMax
) {
608 OperationResult
= TestOperation(Compare1
, Compare2
, BinOp
, CaseInsensitive
, ForceStringCompare
);
611 SHELL_FREE_NON_NULL(Compare1
);
612 SHELL_FREE_NON_NULL(Compare2
);
616 // done processing do result...
619 if (!EFI_ERROR(Status
)) {
621 OperationResult
= (BOOLEAN
)(!OperationResult
);
623 switch(OperatorToUse
) {
625 *PassingState
= (BOOLEAN
)(*PassingState
|| OperationResult
);
628 *PassingState
= (BOOLEAN
)(*PassingState
&& OperationResult
);
631 *PassingState
= (BOOLEAN
)(OperationResult
);
641 Break up the next part of the if statement (until the next 'and', 'or', or 'then').
643 @param[in] ParameterNumber The current parameter number.
644 @param[out] EndParameter Upon successful return, will point to the
645 parameter to start the next iteration with.
646 @param[out] EndTag Upon successful return, will point to the
647 type that was found at the end of this statement.
649 @retval TRUE A valid statement was found.
650 @retval FALSE A valid statement was not found.
655 IN UINTN ParameterNumber
,
656 OUT UINTN
*EndParameter
,
657 OUT END_TAG_TYPE
*EndTag
663 ; ParameterNumber
< gEfiShellParametersProtocol
->Argc
666 if (gUnicodeCollation
->StriColl(
668 gEfiShellParametersProtocol
->Argv
[ParameterNumber
],
670 *EndParameter
= ParameterNumber
- 1;
673 } else if (gUnicodeCollation
->StriColl(
675 gEfiShellParametersProtocol
->Argv
[ParameterNumber
],
677 *EndParameter
= ParameterNumber
- 1;
680 } else if (gUnicodeCollation
->StriColl(
682 gEfiShellParametersProtocol
->Argv
[ParameterNumber
],
684 *EndParameter
= ParameterNumber
- 1;
685 *EndTag
= EndTagThen
;
689 if (*EndTag
== EndTagMax
) {
696 Move the script file pointer to a different place in the script file.
697 This one is special since it handles the if/else/endif syntax.
699 @param[in] ScriptFile The script file from GetCurrnetScriptFile().
701 @retval TRUE The move target was found and the move was successful.
702 @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.
797 PerformResultOperation (
798 IN CONST BOOLEAN Result
801 if (Result
|| MoveToTagSpecial(ShellCommandGetCurrentScriptFile())) {
802 return (EFI_SUCCESS
);
804 return (EFI_NOT_FOUND
);
808 Function for 'if' command.
810 @param[in] ImageHandle Handle to the Image (NULL if Internal).
811 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
816 IN EFI_HANDLE ImageHandle
,
817 IN EFI_SYSTEM_TABLE
*SystemTable
821 SHELL_STATUS ShellStatus
;
822 BOOLEAN CaseInsensitive
;
824 UINTN CurrentParameter
;
826 BOOLEAN CurrentValue
;
828 END_TAG_TYPE PreviousEnding
;
829 SCRIPT_FILE
*CurrentScriptFile
;
831 Status
= CommandInit();
832 ASSERT_EFI_ERROR(Status
);
834 if (!gEfiShellProtocol
->BatchIsActive()) {
835 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"If");
836 return (SHELL_UNSUPPORTED
);
839 if (gEfiShellParametersProtocol
->Argc
< 3) {
840 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel1HiiHandle
);
841 return (SHELL_INVALID_PARAMETER
);
845 // Make sure that an End exists.
847 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
848 if (!MoveToTag(GetNextNode
, L
"endif", L
"if", NULL
, CurrentScriptFile
, TRUE
, TRUE
, FALSE
)) {
853 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
854 gShellLevel1HiiHandle
,
857 CurrentScriptFile
!=NULL
858 && CurrentScriptFile
->CurrentCommand
!=NULL
859 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
860 return (SHELL_DEVICE_ERROR
);
864 // initialize the shell lib (we must be in non-auto-init...)
866 Status
= ShellInitialize();
867 ASSERT_EFI_ERROR(Status
);
869 CurrentParameter
= 1;
872 if (gUnicodeCollation
->StriColl(
874 gEfiShellParametersProtocol
->Argv
[1],
876 gUnicodeCollation
->StriColl(
878 gEfiShellParametersProtocol
->Argv
[2],
880 (gEfiShellParametersProtocol
->Argc
> 3 && gUnicodeCollation
->StriColl(
882 gEfiShellParametersProtocol
->Argv
[3],
884 CaseInsensitive
= TRUE
;
887 CaseInsensitive
= FALSE
;
889 if (gUnicodeCollation
->StriColl(
891 gEfiShellParametersProtocol
->Argv
[1],
893 gUnicodeCollation
->StriColl(
895 gEfiShellParametersProtocol
->Argv
[2],
897 (gEfiShellParametersProtocol
->Argc
> 3 && gUnicodeCollation
->StriColl(
899 gEfiShellParametersProtocol
->Argv
[3],
907 for ( ShellStatus
= SHELL_SUCCESS
, CurrentValue
= FALSE
, Ending
= EndTagMax
908 ; CurrentParameter
< gEfiShellParametersProtocol
->Argc
&& ShellStatus
== SHELL_SUCCESS
909 ; CurrentParameter
++) {
910 if (gUnicodeCollation
->StriColl(
912 gEfiShellParametersProtocol
->Argv
[CurrentParameter
],
915 // we are at the then
917 if (CurrentParameter
+1 != gEfiShellParametersProtocol
->Argc
) {
918 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_TEXT_AFTER_THEN
), gShellLevel1HiiHandle
);
919 ShellStatus
= SHELL_INVALID_PARAMETER
;
921 Status
= PerformResultOperation(CurrentValue
);
922 if (EFI_ERROR(Status
)) {
923 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_AFTER_BAD
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[CurrentParameter
]);
924 ShellStatus
= SHELL_INVALID_PARAMETER
;
928 PreviousEnding
= Ending
;
930 // build up the next statement for analysis
932 if (!BuildNextStatement(CurrentParameter
, &EndParameter
, &Ending
)) {
933 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
938 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
939 gShellLevel1HiiHandle
,
942 CurrentScriptFile
!=NULL
943 && CurrentScriptFile
->CurrentCommand
!=NULL
944 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
945 ShellStatus
= SHELL_INVALID_PARAMETER
;
948 // Analyze the statement
950 Status
= ProcessStatement(&CurrentValue
, CurrentParameter
, EndParameter
, PreviousEnding
, CaseInsensitive
, ForceString
);
951 if (EFI_ERROR(Status
)) {
952 // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_STARTING), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[CurrentParameter]);
953 ShellStatus
= SHELL_INVALID_PARAMETER
;
956 // Optomize to get out of the loop early...
958 if ((Ending
== EndTagOr
&& CurrentValue
) || (Ending
== EndTagAnd
&& !CurrentValue
)) {
959 Status
= PerformResultOperation(CurrentValue
);
960 if (EFI_ERROR(Status
)) {
961 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_AFTER_BAD
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[CurrentParameter
]);
962 ShellStatus
= SHELL_INVALID_PARAMETER
;
968 if (ShellStatus
== SHELL_SUCCESS
){
969 CurrentParameter
= EndParameter
;
971 // Skip over the or or and parameter.
973 if (Ending
== EndTagOr
|| Ending
== EndTagAnd
) {
979 return (ShellStatus
);
983 Function for 'else' command.
985 @param[in] ImageHandle Handle to the Image (NULL if Internal).
986 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
990 ShellCommandRunElse (
991 IN EFI_HANDLE ImageHandle
,
992 IN EFI_SYSTEM_TABLE
*SystemTable
995 SCRIPT_FILE
*CurrentScriptFile
;
996 ASSERT_EFI_ERROR(CommandInit());
998 if (gEfiShellParametersProtocol
->Argc
> 1) {
999 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel1HiiHandle
);
1000 return (SHELL_INVALID_PARAMETER
);
1003 if (!gEfiShellProtocol
->BatchIsActive()) {
1004 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"Else");
1005 return (SHELL_UNSUPPORTED
);
1008 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
1010 if (!MoveToTag(GetPreviousNode
, L
"if", L
"endif", NULL
, CurrentScriptFile
, FALSE
, TRUE
, FALSE
)) {
1015 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1016 gShellLevel1HiiHandle
,
1019 CurrentScriptFile
!=NULL
1020 && CurrentScriptFile
->CurrentCommand
!=NULL
1021 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1022 return (SHELL_DEVICE_ERROR
);
1024 if (!MoveToTag(GetPreviousNode
, L
"if", L
"else", NULL
, CurrentScriptFile
, FALSE
, TRUE
, FALSE
)) {
1029 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1030 gShellLevel1HiiHandle
,
1033 CurrentScriptFile
!=NULL
1034 && CurrentScriptFile
->CurrentCommand
!=NULL
1035 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1036 return (SHELL_DEVICE_ERROR
);
1039 if (!MoveToTag(GetNextNode
, L
"endif", L
"if", NULL
, CurrentScriptFile
, FALSE
, FALSE
, FALSE
)) {
1044 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1045 gShellLevel1HiiHandle
,
1048 CurrentScriptFile
!=NULL
1049 && CurrentScriptFile
->CurrentCommand
!=NULL
1050 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1051 return (SHELL_DEVICE_ERROR
);
1054 return (SHELL_SUCCESS
);
1058 Function for 'endif' command.
1060 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1061 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1065 ShellCommandRunEndIf (
1066 IN EFI_HANDLE ImageHandle
,
1067 IN EFI_SYSTEM_TABLE
*SystemTable
1070 SCRIPT_FILE
*CurrentScriptFile
;
1071 ASSERT_EFI_ERROR(CommandInit());
1073 if (gEfiShellParametersProtocol
->Argc
> 1) {
1074 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel1HiiHandle
);
1075 return (SHELL_INVALID_PARAMETER
);
1078 if (!gEfiShellProtocol
->BatchIsActive()) {
1079 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"Endif");
1080 return (SHELL_UNSUPPORTED
);
1083 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
1084 if (!MoveToTag(GetPreviousNode
, L
"if", L
"endif", NULL
, CurrentScriptFile
, FALSE
, TRUE
, FALSE
)) {
1089 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1090 gShellLevel1HiiHandle
,
1093 CurrentScriptFile
!=NULL
1094 && CurrentScriptFile
->CurrentCommand
!=NULL
1095 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1096 return (SHELL_DEVICE_ERROR
);
1099 return (SHELL_SUCCESS
);