2 Main file for If and else shell level 1 function.
4 Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "UefiShellLevel1CommandsLib.h"
16 #include <Library/PrintLib.h>
30 OperatorGreatorOrEqual
,
32 OperatorUnisgnedGreaterThan
,
33 OperatorUnsignedLessThan
,
34 OperatorUnsignedGreaterOrEqual
,
35 OperatorUnsignedLessOrEqual
,
40 Extract the next fragment, if there is one.
42 @param[in,out] Statement The current remaining statement.
43 @param[in] Fragment The current fragment.
45 @retval FALSE There is not another fragment.
46 @retval TRUE There is another fragment.
51 IN OUT CONST CHAR16
**Statement
,
52 IN CONST CHAR16
*Fragment
59 Tester
= StrnCatGrow(&Tester
, NULL
, *Statement
, StrLen(Fragment
));
60 ASSERT(Tester
!= NULL
);
61 Tester
[StrLen(Fragment
)] = CHAR_NULL
;
62 if (gUnicodeCollation
->StriColl(
67 // increment the string pointer to the end of what we found and then chop off spaces...
69 *Statement
+=StrLen(Fragment
);
70 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.
91 IN CONST CHAR16
*String
94 CONST CHAR16
*ProfilesString
;
95 CONST CHAR16
*TempLocation
;
97 ProfilesString
= ShellGetEnvironmentVariable(L
"profiles");
99 // According to the Shell spec this is a required environment variable.
101 ASSERT(ProfileString
!= NULL
);
102 TempLocation
= StrStr(ProfilesString
, String
);
103 if ((TempLocation
!= NULL
) && (*(TempLocation
-1) == L
';') && (*(TempLocation
+StrLen(String
)) == L
';')) {
110 Do a comparison between 2 things.
112 @param[in] Compare1 The first item to compare.
113 @param[in] Compare2 The second item to compare.
114 @param[in] BinOp The type of comparison to perform.
115 @param[in] CaseInsensitive TRUE to do non-case comparison, FALSE otherwise.
116 @param[in] ForceStringCompare TRUE to force string comparison, FALSE otherwise.
118 @return The result of the comparison.
123 IN CONST CHAR16
*Compare1
,
124 IN CONST CHAR16
*Compare2
,
125 IN CONST BIN_OPERATOR_TYPE BinOp
,
126 IN CONST BOOLEAN CaseInsensitive
,
127 IN CONST BOOLEAN ForceStringCompare
134 // "Compare1 BinOp Compare2"
137 case OperatorUnisgnedGreaterThan
:
138 case OperatorGreaterThan
:
139 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
143 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) > 0) || (StringCompare(&Compare1
, &Compare2
) > 0)) {
150 if (Compare1
[0] == L
'-') {
151 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
153 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
155 if (Compare2
[0] == L
'-') {
156 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
158 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
160 if (BinOp
== OperatorGreaterThan
) {
165 if ((UINTN
)Cmp1
> (UINTN
)Cmp2
) {
172 case OperatorUnsignedLessThan
:
173 case OperatorLessThan
:
174 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
178 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) < 0) || (StringCompare(&Compare1
, &Compare2
) < 0)) {
185 if (Compare1
[0] == L
'-') {
186 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
188 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
190 if (Compare2
[0] == L
'-') {
191 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
193 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
195 if (BinOp
== OperatorLessThan
) {
200 if ((UINTN
)Cmp1
< (UINTN
)Cmp2
) {
209 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
213 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) == 0) || (StringCompare(&Compare1
, &Compare2
) == 0)) {
220 if (Compare1
[0] == L
'-') {
221 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
223 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
225 if (Compare2
[0] == L
'-') {
226 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
228 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
236 case OperatorNotEqual
:
237 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
241 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) != 0) || (StringCompare(&Compare1
, &Compare2
) != 0)) {
248 if (Compare1
[0] == L
'-') {
249 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
251 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
253 if (Compare2
[0] == L
'-') {
254 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
256 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
264 case OperatorUnsignedGreaterOrEqual
:
265 case OperatorGreatorOrEqual
:
266 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
270 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) >= 0) || (StringCompare(&Compare1
, &Compare2
) >= 0)) {
277 if (Compare1
[0] == L
'-') {
278 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
280 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
282 if (Compare2
[0] == L
'-') {
283 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
285 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
287 if (BinOp
== OperatorGreatorOrEqual
) {
292 if ((UINTN
)Cmp1
>= (UINTN
)Cmp2
) {
299 case OperatorLessOrEqual
:
300 case OperatorUnsignedLessOrEqual
:
301 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
305 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) <= 0) || (StringCompare(&Compare1
, &Compare2
) <= 0)) {
312 if (Compare1
[0] == L
'-') {
313 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
315 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
317 if (Compare2
[0] == L
'-') {
318 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
320 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
322 if (BinOp
== OperatorLessOrEqual
) {
327 if ((UINTN
)Cmp1
<= (UINTN
)Cmp2
) {
341 Process an if statement and determine if its is valid or not.
343 @param[in,out] PassingState Opon entry, the current state. Upon exit,
345 @param[in] StartParameterNumber The number of the first parameter of
347 @param[in] EndParameterNumber The number of the final parameter of
349 @param[in] OperatorToUse The type of termination operator.
350 @param[in] CaseInsensitive TRUE for case insensitive, FALSE otherwise.
351 @param[in] ForceStringCompare TRUE for all string based, FALSE otherwise.
353 @retval EFI_INVALID_PARAMETER A parameter was invalid.
354 @retval EFI_SUCCESS The operation was successful.
359 IN OUT BOOLEAN
*PassingState
,
360 IN UINTN StartParameterNumber
,
361 IN UINTN EndParameterNumber
,
362 IN CONST END_TAG_TYPE OperatorToUse
,
363 IN CONST BOOLEAN CaseInsensitive
,
364 IN CONST BOOLEAN ForceStringCompare
368 BOOLEAN OperationResult
;
370 CHAR16
*StatementWalker
;
371 BIN_OPERATOR_TYPE BinOp
;
374 CHAR16 HexString
[20];
377 ASSERT((END_TAG_TYPE
)OperatorToUse
!= EndTagThen
);
379 Status
= EFI_SUCCESS
;
381 OperationResult
= FALSE
;
382 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
];
383 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"not")) {
385 StatementWalker
= gEfiShellParametersProtocol
->Argv
[++StartParameterNumber
];
391 // now check for 'boolfunc' operators
393 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"isint")) {
394 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
395 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
396 OperationResult
= ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
);
398 Status
= EFI_INVALID_PARAMETER
;
399 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"isint");
401 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"exists") || IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"exist")) {
402 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
403 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
405 // is what remains a file in CWD???
407 OperationResult
= (BOOLEAN
)(ShellFileExists(StatementWalker
)==EFI_SUCCESS
);
408 } else if (StatementWalker
[0] == CHAR_NULL
&& StartParameterNumber
+1 == EndParameterNumber
) {
409 OperationResult
= (BOOLEAN
)(ShellFileExists(gEfiShellParametersProtocol
->Argv
[++StartParameterNumber
])==EFI_SUCCESS
);
411 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"exist(s)");
412 Status
= EFI_INVALID_PARAMETER
;
414 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"available")) {
415 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
416 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
418 // is what remains a file in the CWD or path???
420 OperationResult
= (BOOLEAN
)(ShellIsFileInPath(StatementWalker
)==EFI_SUCCESS
);
422 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"available");
423 Status
= EFI_INVALID_PARAMETER
;
425 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"profile")) {
426 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
430 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
431 OperationResult
= IsValidProfile(StatementWalker
);
433 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"profile");
434 Status
= EFI_INVALID_PARAMETER
;
436 } else if (StartParameterNumber
+1 >= EndParameterNumber
) {
437 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[StartParameterNumber
]);
438 Status
= EFI_INVALID_PARAMETER
;
441 // must be 'item binop item' style
448 // get the first item
450 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
];
451 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"efierror")) {
452 TempSpot
= StrStr(StatementWalker
, L
")");
453 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
454 *TempSpot
= CHAR_NULL
;
455 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
456 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
);
457 ASSERT(Compare1
== NULL
);
458 Compare1
= StrnCatGrow(&Compare1
, NULL
, HexString
, 0);
459 StatementWalker
+= StrLen(StatementWalker
) + 1;
461 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
462 Status
= EFI_INVALID_PARAMETER
;
465 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
466 Status
= EFI_INVALID_PARAMETER
;
468 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"pierror")) {
469 TempSpot
= StrStr(StatementWalker
, L
")");
470 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
471 *TempSpot
= CHAR_NULL
;
472 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
473 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>2));
474 ASSERT(Compare1
== NULL
);
475 Compare1
= StrnCatGrow(&Compare1
, NULL
, HexString
, 0);
476 StatementWalker
+= StrLen(StatementWalker
) + 1;
478 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
479 Status
= EFI_INVALID_PARAMETER
;
482 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
483 Status
= EFI_INVALID_PARAMETER
;
485 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"oemerror")) {
486 TempSpot
= StrStr(StatementWalker
, L
")");
487 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
488 TempSpot
= CHAR_NULL
;
489 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
490 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>1));
491 ASSERT(Compare1
== NULL
);
492 Compare1
= StrnCatGrow(&Compare1
, NULL
, HexString
, 0);
493 StatementWalker
+= StrLen(StatementWalker
) + 1;
495 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
496 Status
= EFI_INVALID_PARAMETER
;
499 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
500 Status
= EFI_INVALID_PARAMETER
;
503 ASSERT(Compare1
== NULL
);
504 if (EndParameterNumber
- StartParameterNumber
> 2) {
505 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_STARTING
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+2]);
506 Status
= EFI_INVALID_PARAMETER
;
509 // must be a raw string
511 Compare1
= StrnCatGrow(&Compare1
, NULL
, StatementWalker
, 0);
518 ASSERT(StartParameterNumber
+1<EndParameterNumber
);
519 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+1];
520 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"gt")) {
521 BinOp
= OperatorGreaterThan
;
522 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"lt")) {
523 BinOp
= OperatorLessThan
;
524 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"eq")) {
525 BinOp
= OperatorEqual
;
526 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ne")) {
527 BinOp
= OperatorNotEqual
;
528 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ge")) {
529 BinOp
= OperatorGreatorOrEqual
;
530 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"le")) {
531 BinOp
= OperatorLessOrEqual
;
532 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"==")) {
533 BinOp
= OperatorEqual
;
534 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ugt")) {
535 BinOp
= OperatorUnisgnedGreaterThan
;
536 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ult")) {
537 BinOp
= OperatorUnsignedLessThan
;
538 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"uge")) {
539 BinOp
= OperatorUnsignedGreaterOrEqual
;
540 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ule")) {
541 BinOp
= OperatorUnsignedLessOrEqual
;
543 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_INVALID_BINOP
), gShellLevel1HiiHandle
, StatementWalker
);
544 Status
= EFI_INVALID_PARAMETER
;
548 // get the second item
550 ASSERT(StartParameterNumber
+2<=EndParameterNumber
);
551 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+2];
552 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"efierror")) {
553 TempSpot
= StrStr(StatementWalker
, L
")");
554 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
555 TempSpot
= CHAR_NULL
;
556 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
557 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
);
558 ASSERT(Compare2
== NULL
);
559 Compare2
= StrnCatGrow(&Compare2
, NULL
, HexString
, 0);
560 StatementWalker
+= StrLen(StatementWalker
) + 1;
562 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
563 Status
= EFI_INVALID_PARAMETER
;
566 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
567 Status
= EFI_INVALID_PARAMETER
;
570 // can this be collapsed into the above?
572 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"pierror")) {
573 TempSpot
= StrStr(StatementWalker
, L
")");
574 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
575 TempSpot
= CHAR_NULL
;
576 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
577 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>2));
578 ASSERT(Compare2
== NULL
);
579 Compare2
= StrnCatGrow(&Compare2
, NULL
, HexString
, 0);
580 StatementWalker
+= StrLen(StatementWalker
) + 1;
582 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
583 Status
= EFI_INVALID_PARAMETER
;
586 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
587 Status
= EFI_INVALID_PARAMETER
;
589 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"oemerror")) {
590 TempSpot
= StrStr(StatementWalker
, L
")");
591 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
592 TempSpot
= CHAR_NULL
;
593 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
594 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>1));
595 ASSERT(Compare2
== NULL
);
596 Compare2
= StrnCatGrow(&Compare2
, NULL
, HexString
, 0);
597 StatementWalker
+= StrLen(StatementWalker
) + 1;
599 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
600 Status
= EFI_INVALID_PARAMETER
;
603 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
604 Status
= EFI_INVALID_PARAMETER
;
608 // must be a raw string
610 ASSERT(Compare2
== NULL
);
611 Compare2
= StrnCatGrow(&Compare2
, NULL
, StatementWalker
, 0);
614 if (Compare1
!= NULL
&& Compare2
!= NULL
&& BinOp
!= OperatorMax
) {
615 OperationResult
= TestOperation(Compare1
, Compare2
, BinOp
, CaseInsensitive
, ForceStringCompare
);
618 SHELL_FREE_NON_NULL(Compare1
);
619 SHELL_FREE_NON_NULL(Compare2
);
623 // done processing do result...
626 if (!EFI_ERROR(Status
)) {
628 OperationResult
= (BOOLEAN
)(!OperationResult
);
630 switch(OperatorToUse
) {
632 *PassingState
= (BOOLEAN
)(*PassingState
|| OperationResult
);
635 *PassingState
= (BOOLEAN
)(*PassingState
&& OperationResult
);
638 *PassingState
= (BOOLEAN
)(OperationResult
);
648 Break up the next part of the if statement (until the next 'and', 'or', or 'then').
650 @param[in] ParameterNumber The current parameter number.
651 @param[out] EndParameter Upon successful return, will point to the
652 parameter to start the next iteration with.
653 @param[out] EndTag Upon successful return, will point to the
654 type that was found at the end of this statement.
656 @retval TRUE A valid statement was found.
657 @retval FALSE A valid statement was not found.
662 IN UINTN ParameterNumber
,
663 OUT UINTN
*EndParameter
,
664 OUT END_TAG_TYPE
*EndTag
672 for(Buffer
= NULL
, BufferSize
= 0
673 ; ParameterNumber
< gEfiShellParametersProtocol
->Argc
676 if (gUnicodeCollation
->StriColl(
678 gEfiShellParametersProtocol
->Argv
[ParameterNumber
],
680 *EndParameter
= ParameterNumber
- 1;
683 } else if (gUnicodeCollation
->StriColl(
685 gEfiShellParametersProtocol
->Argv
[ParameterNumber
],
687 *EndParameter
= ParameterNumber
- 1;
690 } else if (gUnicodeCollation
->StriColl(
692 gEfiShellParametersProtocol
->Argv
[ParameterNumber
],
694 *EndParameter
= ParameterNumber
- 1;
695 *EndTag
= EndTagThen
;
699 if (*EndTag
== EndTagMax
) {
706 Move the script file pointer to a different place in the script file.
707 This one is special since it handles the if/else/endif syntax.
709 @param[in] ScriptFile The script file from GetCurrnetScriptFile().
711 @retval TRUE The move target was found and the move was successful.
712 @retval FALSE Something went wrong.
717 IN SCRIPT_FILE
*ScriptFile
720 SCRIPT_COMMAND_LIST
*CommandNode
;
724 CHAR16
*CommandWalker
;
725 CHAR16
*TempLocation
;
730 if (ScriptFile
== NULL
) {
734 for (CommandNode
= (SCRIPT_COMMAND_LIST
*)GetNextNode(&ScriptFile
->CommandList
, &ScriptFile
->CurrentCommand
->Link
), Found
= FALSE
735 ; !IsNull(&ScriptFile
->CommandList
, &CommandNode
->Link
) && !Found
736 ; CommandNode
= (SCRIPT_COMMAND_LIST
*)GetNextNode(&ScriptFile
->CommandList
, &CommandNode
->Link
)
740 // get just the first part of the command line...
743 CommandName
= StrnCatGrow(&CommandName
, NULL
, CommandNode
->Cl
, 0);
744 CommandWalker
= CommandName
;
745 while (CommandWalker
[0] == L
' ') {
748 TempLocation
= StrStr(CommandWalker
, L
" ");
750 if (TempLocation
!= NULL
) {
751 *TempLocation
= CHAR_NULL
;
755 // did we find a nested item ?
757 if (gUnicodeCollation
->StriColl(
759 (CHAR16
*)CommandWalker
,
762 } else if (TargetCount
== 1 && gUnicodeCollation
->StriColl(
764 (CHAR16
*)CommandWalker
,
765 (CHAR16
*)L
"else") == 0) {
767 // else can only decrement the last part... not an nested if
768 // hence the TargetCount compare added
771 } else if (gUnicodeCollation
->StriColl(
773 (CHAR16
*)CommandWalker
,
774 (CHAR16
*)L
"endif") == 0) {
777 if (TargetCount
== 0) {
778 ScriptFile
->CurrentCommand
= (SCRIPT_COMMAND_LIST
*)GetNextNode(&ScriptFile
->CommandList
, &CommandNode
->Link
);
783 // Free the memory for this loop...
785 SHELL_FREE_NON_NULL(CommandName
);
791 Deal with the result of the if operation.
793 @param[in] Result The result of the if.
795 @retval EFI_SUCCESS The operation was successful.
796 @retval EFI_NOT_FOUND The ending tag could not be found.
800 PerformResultOperation (
801 IN CONST BOOLEAN Result
804 if (Result
|| MoveToTagSpecial(ShellCommandGetCurrentScriptFile())) {
805 return (EFI_SUCCESS
);
807 return (EFI_NOT_FOUND
);
811 Function for 'if' command.
813 @param[in] ImageHandle Handle to the Image (NULL if Internal).
814 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
819 IN EFI_HANDLE ImageHandle
,
820 IN EFI_SYSTEM_TABLE
*SystemTable
824 SHELL_STATUS ShellStatus
;
825 BOOLEAN CaseInsensitive
;
827 UINTN CurrentParameter
;
829 BOOLEAN CurrentValue
;
831 END_TAG_TYPE PreviousEnding
;
832 SCRIPT_FILE
*CurrentScriptFile
;
834 Status
= CommandInit();
835 ASSERT_EFI_ERROR(Status
);
837 if (!gEfiShellProtocol
->BatchIsActive()) {
838 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"If");
839 return (SHELL_UNSUPPORTED
);
842 if (gEfiShellParametersProtocol
->Argc
< 3) {
843 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel1HiiHandle
);
844 return (SHELL_INVALID_PARAMETER
);
848 // Make sure that an End exists.
850 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
851 if (!MoveToTag(GetNextNode
, L
"endif", L
"if", NULL
, CurrentScriptFile
, TRUE
, TRUE
, FALSE
)) {
856 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
857 gShellLevel1HiiHandle
,
860 CurrentScriptFile
!=NULL
861 && CurrentScriptFile
->CurrentCommand
!=NULL
862 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
863 return (SHELL_DEVICE_ERROR
);
867 // initialize the shell lib (we must be in non-auto-init...)
869 Status
= ShellInitialize();
870 ASSERT_EFI_ERROR(Status
);
872 CurrentParameter
= 1;
875 if (gUnicodeCollation
->StriColl(
877 gEfiShellParametersProtocol
->Argv
[1],
879 gUnicodeCollation
->StriColl(
881 gEfiShellParametersProtocol
->Argv
[2],
883 (gEfiShellParametersProtocol
->Argc
> 3 && gUnicodeCollation
->StriColl(
885 gEfiShellParametersProtocol
->Argv
[3],
887 CaseInsensitive
= TRUE
;
890 CaseInsensitive
= FALSE
;
892 if (gUnicodeCollation
->StriColl(
894 gEfiShellParametersProtocol
->Argv
[1],
896 gUnicodeCollation
->StriColl(
898 gEfiShellParametersProtocol
->Argv
[2],
900 (gEfiShellParametersProtocol
->Argc
> 3 && gUnicodeCollation
->StriColl(
902 gEfiShellParametersProtocol
->Argv
[3],
910 for ( ShellStatus
= SHELL_SUCCESS
, CurrentValue
= FALSE
, Ending
= EndTagMax
911 ; CurrentParameter
< gEfiShellParametersProtocol
->Argc
&& ShellStatus
== SHELL_SUCCESS
912 ; CurrentParameter
++) {
913 if (gUnicodeCollation
->StriColl(
915 gEfiShellParametersProtocol
->Argv
[CurrentParameter
],
918 // we are at the then
920 if (CurrentParameter
+1 != gEfiShellParametersProtocol
->Argc
) {
921 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_TEXT_AFTER_THEN
), gShellLevel1HiiHandle
);
922 ShellStatus
= SHELL_INVALID_PARAMETER
;
924 Status
= PerformResultOperation(CurrentValue
);
925 if (EFI_ERROR(Status
)) {
926 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_AFTER_BAD
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[CurrentParameter
]);
927 ShellStatus
= SHELL_INVALID_PARAMETER
;
931 PreviousEnding
= Ending
;
933 // build up the next statement for analysis
935 if (!BuildNextStatement(CurrentParameter
, &EndParameter
, &Ending
)) {
936 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
941 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
942 gShellLevel1HiiHandle
,
945 CurrentScriptFile
!=NULL
946 && CurrentScriptFile
->CurrentCommand
!=NULL
947 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
948 ShellStatus
= SHELL_INVALID_PARAMETER
;
951 // Analyze the statement
953 Status
= ProcessStatement(&CurrentValue
, CurrentParameter
, EndParameter
, PreviousEnding
, CaseInsensitive
, ForceString
);
954 if (EFI_ERROR(Status
)) {
955 // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_STARTING), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[CurrentParameter]);
956 ShellStatus
= SHELL_INVALID_PARAMETER
;
959 // Optomize to get out of the loop early...
961 if ((Ending
== EndTagOr
&& CurrentValue
) || (Ending
== EndTagAnd
&& !CurrentValue
)) {
962 Status
= PerformResultOperation(CurrentValue
);
963 if (EFI_ERROR(Status
)) {
964 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_AFTER_BAD
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[CurrentParameter
]);
965 ShellStatus
= SHELL_INVALID_PARAMETER
;
971 if (ShellStatus
== SHELL_SUCCESS
){
972 CurrentParameter
= EndParameter
;
974 // Skip over the or or and parameter.
976 if (Ending
== EndTagOr
|| Ending
== EndTagAnd
) {
982 return (ShellStatus
);
986 Function for 'else' command.
988 @param[in] ImageHandle Handle to the Image (NULL if Internal).
989 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
993 ShellCommandRunElse (
994 IN EFI_HANDLE ImageHandle
,
995 IN EFI_SYSTEM_TABLE
*SystemTable
998 SCRIPT_FILE
*CurrentScriptFile
;
999 ASSERT_EFI_ERROR(CommandInit());
1001 if (gEfiShellParametersProtocol
->Argc
> 1) {
1002 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel1HiiHandle
);
1003 return (SHELL_INVALID_PARAMETER
);
1006 if (!gEfiShellProtocol
->BatchIsActive()) {
1007 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"Else");
1008 return (SHELL_UNSUPPORTED
);
1011 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
1013 if (!MoveToTag(GetPreviousNode
, L
"if", L
"endif", NULL
, CurrentScriptFile
, FALSE
, TRUE
, FALSE
)) {
1018 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1019 gShellLevel1HiiHandle
,
1022 CurrentScriptFile
!=NULL
1023 && CurrentScriptFile
->CurrentCommand
!=NULL
1024 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1025 return (SHELL_DEVICE_ERROR
);
1027 if (!MoveToTag(GetPreviousNode
, L
"if", L
"else", NULL
, CurrentScriptFile
, FALSE
, TRUE
, FALSE
)) {
1032 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1033 gShellLevel1HiiHandle
,
1036 CurrentScriptFile
!=NULL
1037 && CurrentScriptFile
->CurrentCommand
!=NULL
1038 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1039 return (SHELL_DEVICE_ERROR
);
1042 if (!MoveToTag(GetNextNode
, L
"endif", L
"if", NULL
, CurrentScriptFile
, FALSE
, FALSE
, FALSE
)) {
1047 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1048 gShellLevel1HiiHandle
,
1051 CurrentScriptFile
!=NULL
1052 && CurrentScriptFile
->CurrentCommand
!=NULL
1053 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1054 return (SHELL_DEVICE_ERROR
);
1057 return (SHELL_SUCCESS
);
1061 Function for 'endif' command.
1063 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1064 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1068 ShellCommandRunEndIf (
1069 IN EFI_HANDLE ImageHandle
,
1070 IN EFI_SYSTEM_TABLE
*SystemTable
1073 SCRIPT_FILE
*CurrentScriptFile
;
1074 ASSERT_EFI_ERROR(CommandInit());
1076 if (gEfiShellParametersProtocol
->Argc
> 1) {
1077 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel1HiiHandle
);
1078 return (SHELL_INVALID_PARAMETER
);
1081 if (!gEfiShellProtocol
->BatchIsActive()) {
1082 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"Endif");
1083 return (SHELL_UNSUPPORTED
);
1086 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
1087 if (!MoveToTag(GetPreviousNode
, L
"if", L
"endif", NULL
, CurrentScriptFile
, FALSE
, TRUE
, FALSE
)) {
1092 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1093 gShellLevel1HiiHandle
,
1096 CurrentScriptFile
!=NULL
1097 && CurrentScriptFile
->CurrentCommand
!=NULL
1098 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1099 return (SHELL_DEVICE_ERROR
);
1102 return (SHELL_SUCCESS
);