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");
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.
119 IN CONST CHAR16
*Compare1
,
120 IN CONST CHAR16
*Compare2
,
121 IN CONST BIN_OPERATOR_TYPE BinOp
,
122 IN CONST BOOLEAN CaseInsensitive
,
123 IN CONST BOOLEAN ForceStringCompare
130 // "Compare1 BinOp Compare2"
133 case OperatorUnisgnedGreaterThan
:
134 case OperatorGreaterThan
:
135 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
139 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) > 0) || (StringCompare(&Compare1
, &Compare2
) > 0)) {
146 if (Compare1
[0] == L
'-') {
147 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
149 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
151 if (Compare2
[0] == L
'-') {
152 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
154 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
156 if (BinOp
== OperatorGreaterThan
) {
161 if ((UINTN
)Cmp1
> (UINTN
)Cmp2
) {
168 case OperatorUnsignedLessThan
:
169 case OperatorLessThan
:
170 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
174 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) < 0) || (StringCompare(&Compare1
, &Compare2
) < 0)) {
181 if (Compare1
[0] == L
'-') {
182 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
184 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
186 if (Compare2
[0] == L
'-') {
187 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
189 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
191 if (BinOp
== OperatorLessThan
) {
196 if ((UINTN
)Cmp1
< (UINTN
)Cmp2
) {
205 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
209 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) == 0) || (StringCompare(&Compare1
, &Compare2
) == 0)) {
216 if (Compare1
[0] == L
'-') {
217 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
219 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
221 if (Compare2
[0] == L
'-') {
222 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
224 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
);
260 case OperatorUnsignedGreaterOrEqual
:
261 case OperatorGreatorOrEqual
:
262 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
266 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) >= 0) || (StringCompare(&Compare1
, &Compare2
) >= 0)) {
273 if (Compare1
[0] == L
'-') {
274 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
276 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
278 if (Compare2
[0] == L
'-') {
279 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
281 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
283 if (BinOp
== OperatorGreatorOrEqual
) {
288 if ((UINTN
)Cmp1
>= (UINTN
)Cmp2
) {
295 case OperatorLessOrEqual
:
296 case OperatorUnsignedLessOrEqual
:
297 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
301 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) <= 0) || (StringCompare(&Compare1
, &Compare2
) <= 0)) {
308 if (Compare1
[0] == L
'-') {
309 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
311 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
313 if (Compare2
[0] == L
'-') {
314 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
316 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
318 if (BinOp
== OperatorLessOrEqual
) {
323 if ((UINTN
)Cmp1
<= (UINTN
)Cmp2
) {
337 Process an if statement and determine if its is valid or not.
339 @param[in,out] PassingState Opon entry, the current state. Upon exit,
341 @param[in] StartParameterNumber The number of the first parameter of
343 @param[in] EndParameterNumber The number of the final parameter of
345 @param[in] OperatorToUse The type of termination operator.
346 @param[in] CaseInsensitive TRUE for case insensitive, FALSE otherwise.
347 @param[in] ForceStringCompare TRUE for all string based, FALSE otherwise.
349 @retval EFI_INVALID_PARAMETER A parameter was invalid.
350 @retval EFI_SUCCESS The operation was successful.
355 IN OUT BOOLEAN
*PassingState
,
356 IN UINTN StartParameterNumber
,
357 IN UINTN EndParameterNumber
,
358 IN CONST END_TAG_TYPE OperatorToUse
,
359 IN CONST BOOLEAN CaseInsensitive
,
360 IN CONST BOOLEAN ForceStringCompare
364 BOOLEAN OperationResult
;
366 CHAR16
*StatementWalker
;
367 BIN_OPERATOR_TYPE BinOp
;
370 CHAR16 HexString
[20];
373 ASSERT((END_TAG_TYPE
)OperatorToUse
!= EndTagThen
);
375 Status
= EFI_SUCCESS
;
377 OperationResult
= FALSE
;
378 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
];
379 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"not")) {
381 StatementWalker
= gEfiShellParametersProtocol
->Argv
[++StartParameterNumber
];
387 // now check for 'boolfunc' operators
389 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"isint")) {
390 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
391 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
392 OperationResult
= ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
);
394 Status
= EFI_INVALID_PARAMETER
;
395 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"isint");
397 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"exists") || IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"exist")) {
398 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
399 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
401 // is what remains a file in CWD???
403 OperationResult
= (BOOLEAN
)(ShellFileExists(StatementWalker
)==EFI_SUCCESS
);
404 } else if (StatementWalker
[0] == CHAR_NULL
&& StartParameterNumber
+1 == EndParameterNumber
) {
405 OperationResult
= (BOOLEAN
)(ShellFileExists(gEfiShellParametersProtocol
->Argv
[++StartParameterNumber
])==EFI_SUCCESS
);
407 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"exist(s)");
408 Status
= EFI_INVALID_PARAMETER
;
410 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"available")) {
411 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
412 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
414 // is what remains a file in the CWD or path???
416 OperationResult
= (BOOLEAN
)(ShellIsFileInPath(StatementWalker
)==EFI_SUCCESS
);
418 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"available");
419 Status
= EFI_INVALID_PARAMETER
;
421 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"profile")) {
422 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
426 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
427 OperationResult
= IsValidProfile(StatementWalker
);
429 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"profile");
430 Status
= EFI_INVALID_PARAMETER
;
432 } else if (StartParameterNumber
+1 >= EndParameterNumber
) {
433 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[StartParameterNumber
]);
434 Status
= EFI_INVALID_PARAMETER
;
437 // must be 'item binop item' style
444 // get the first item
446 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
];
447 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"efierror")) {
448 TempSpot
= StrStr(StatementWalker
, L
")");
449 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
450 *TempSpot
= CHAR_NULL
;
451 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
452 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
);
453 ASSERT(Compare1
== NULL
);
454 Compare1
= StrnCatGrow(&Compare1
, NULL
, HexString
, 0);
455 StatementWalker
+= StrLen(StatementWalker
) + 1;
457 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
458 Status
= EFI_INVALID_PARAMETER
;
461 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
462 Status
= EFI_INVALID_PARAMETER
;
464 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"pierror")) {
465 TempSpot
= StrStr(StatementWalker
, L
")");
466 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
467 *TempSpot
= CHAR_NULL
;
468 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
469 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>2));
470 ASSERT(Compare1
== NULL
);
471 Compare1
= StrnCatGrow(&Compare1
, NULL
, HexString
, 0);
472 StatementWalker
+= StrLen(StatementWalker
) + 1;
474 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
475 Status
= EFI_INVALID_PARAMETER
;
478 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
479 Status
= EFI_INVALID_PARAMETER
;
481 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"oemerror")) {
482 TempSpot
= StrStr(StatementWalker
, L
")");
483 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
484 TempSpot
= CHAR_NULL
;
485 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
486 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>1));
487 ASSERT(Compare1
== NULL
);
488 Compare1
= StrnCatGrow(&Compare1
, NULL
, HexString
, 0);
489 StatementWalker
+= StrLen(StatementWalker
) + 1;
491 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
492 Status
= EFI_INVALID_PARAMETER
;
495 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
496 Status
= EFI_INVALID_PARAMETER
;
499 ASSERT(Compare1
== NULL
);
500 if (EndParameterNumber
- StartParameterNumber
> 2) {
501 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_STARTING
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+2]);
502 Status
= EFI_INVALID_PARAMETER
;
505 // must be a raw string
507 Compare1
= StrnCatGrow(&Compare1
, NULL
, StatementWalker
, 0);
514 ASSERT(StartParameterNumber
+1<EndParameterNumber
);
515 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+1];
516 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"gt")) {
517 BinOp
= OperatorGreaterThan
;
518 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"lt")) {
519 BinOp
= OperatorLessThan
;
520 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"eq")) {
521 BinOp
= OperatorEqual
;
522 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ne")) {
523 BinOp
= OperatorNotEqual
;
524 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ge")) {
525 BinOp
= OperatorGreatorOrEqual
;
526 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"le")) {
527 BinOp
= OperatorLessOrEqual
;
528 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"==")) {
529 BinOp
= OperatorEqual
;
530 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ugt")) {
531 BinOp
= OperatorUnisgnedGreaterThan
;
532 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ult")) {
533 BinOp
= OperatorUnsignedLessThan
;
534 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"uge")) {
535 BinOp
= OperatorUnsignedGreaterOrEqual
;
536 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ule")) {
537 BinOp
= OperatorUnsignedLessOrEqual
;
539 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_INVALID_BINOP
), gShellLevel1HiiHandle
, StatementWalker
);
540 Status
= EFI_INVALID_PARAMETER
;
544 // get the second item
546 ASSERT(StartParameterNumber
+2<=EndParameterNumber
);
547 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+2];
548 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"efierror")) {
549 TempSpot
= StrStr(StatementWalker
, L
")");
550 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
551 TempSpot
= CHAR_NULL
;
552 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
553 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
);
554 ASSERT(Compare2
== NULL
);
555 Compare2
= StrnCatGrow(&Compare2
, NULL
, HexString
, 0);
556 StatementWalker
+= StrLen(StatementWalker
) + 1;
558 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
559 Status
= EFI_INVALID_PARAMETER
;
562 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
563 Status
= EFI_INVALID_PARAMETER
;
566 // can this be collapsed into the above?
568 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"pierror")) {
569 TempSpot
= StrStr(StatementWalker
, L
")");
570 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
571 TempSpot
= CHAR_NULL
;
572 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
573 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>2));
574 ASSERT(Compare2
== NULL
);
575 Compare2
= StrnCatGrow(&Compare2
, NULL
, HexString
, 0);
576 StatementWalker
+= StrLen(StatementWalker
) + 1;
578 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
579 Status
= EFI_INVALID_PARAMETER
;
582 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
583 Status
= EFI_INVALID_PARAMETER
;
585 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"oemerror")) {
586 TempSpot
= StrStr(StatementWalker
, L
")");
587 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
588 TempSpot
= CHAR_NULL
;
589 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
590 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>1));
591 ASSERT(Compare2
== NULL
);
592 Compare2
= StrnCatGrow(&Compare2
, NULL
, HexString
, 0);
593 StatementWalker
+= StrLen(StatementWalker
) + 1;
595 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
596 Status
= EFI_INVALID_PARAMETER
;
599 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
600 Status
= EFI_INVALID_PARAMETER
;
604 // must be a raw string
606 ASSERT(Compare2
== NULL
);
607 Compare2
= StrnCatGrow(&Compare2
, NULL
, StatementWalker
, 0);
610 if (Compare1
!= NULL
&& Compare2
!= NULL
&& BinOp
!= OperatorMax
) {
611 OperationResult
= TestOperation(Compare1
, Compare2
, BinOp
, CaseInsensitive
, ForceStringCompare
);
614 SHELL_FREE_NON_NULL(Compare1
);
615 SHELL_FREE_NON_NULL(Compare2
);
619 // done processing do result...
622 if (!EFI_ERROR(Status
)) {
624 OperationResult
= (BOOLEAN
)(!OperationResult
);
626 switch(OperatorToUse
) {
628 *PassingState
= (BOOLEAN
)(*PassingState
|| OperationResult
);
631 *PassingState
= (BOOLEAN
)(*PassingState
&& OperationResult
);
634 *PassingState
= (BOOLEAN
)(OperationResult
);
644 Break up the next part of the if statement (until the next 'and', 'or', or 'then').
646 @param[in] ParameterNumber The current parameter number.
647 @param[out] EndParameter Upon successful return, will point to the
648 parameter to start the next iteration with.
649 @param[out] EndTag Upon successful return, will point to the
650 type that was found at the end of this statement.
652 @retval TRUE A valid statement was found.
653 @retval FALSE A valid statement was not found.
658 IN UINTN ParameterNumber
,
659 OUT UINTN
*EndParameter
,
660 OUT END_TAG_TYPE
*EndTag
668 for(Buffer
= NULL
, BufferSize
= 0
669 ; ParameterNumber
< gEfiShellParametersProtocol
->Argc
672 if (gUnicodeCollation
->StriColl(
674 gEfiShellParametersProtocol
->Argv
[ParameterNumber
],
676 *EndParameter
= ParameterNumber
- 1;
679 } else if (gUnicodeCollation
->StriColl(
681 gEfiShellParametersProtocol
->Argv
[ParameterNumber
],
683 *EndParameter
= ParameterNumber
- 1;
686 } else if (gUnicodeCollation
->StriColl(
688 gEfiShellParametersProtocol
->Argv
[ParameterNumber
],
690 *EndParameter
= ParameterNumber
- 1;
691 *EndTag
= EndTagThen
;
695 if (*EndTag
== EndTagMax
) {
702 Move the script file pointer to a different place in the script file.
703 This one is special since it handles the if/else/endif syntax.
705 @param[in] ScriptFile The script file from GetCurrnetScriptFile().
707 @retval TRUE The move target was found and the move was successful.
708 @retval FALSE Something went wrong.
713 IN SCRIPT_FILE
*ScriptFile
716 SCRIPT_COMMAND_LIST
*CommandNode
;
720 CHAR16
*CommandWalker
;
721 CHAR16
*TempLocation
;
726 if (ScriptFile
== NULL
) {
730 for (CommandNode
= (SCRIPT_COMMAND_LIST
*)GetNextNode(&ScriptFile
->CommandList
, &ScriptFile
->CurrentCommand
->Link
), Found
= FALSE
731 ; !IsNull(&ScriptFile
->CommandList
, &CommandNode
->Link
) && !Found
732 ; CommandNode
= (SCRIPT_COMMAND_LIST
*)GetNextNode(&ScriptFile
->CommandList
, &CommandNode
->Link
)
736 // get just the first part of the command line...
739 CommandName
= StrnCatGrow(&CommandName
, NULL
, CommandNode
->Cl
, 0);
740 CommandWalker
= CommandName
;
741 while (CommandWalker
[0] == L
' ') {
744 TempLocation
= StrStr(CommandWalker
, L
" ");
746 if (TempLocation
!= NULL
) {
747 *TempLocation
= CHAR_NULL
;
751 // did we find a nested item ?
753 if (gUnicodeCollation
->StriColl(
755 (CHAR16
*)CommandWalker
,
758 } else if (TargetCount
== 1 && gUnicodeCollation
->StriColl(
760 (CHAR16
*)CommandWalker
,
761 (CHAR16
*)L
"else") == 0) {
763 // else can only decrement the last part... not an nested if
764 // hence the TargetCount compare added
767 } else if (gUnicodeCollation
->StriColl(
769 (CHAR16
*)CommandWalker
,
770 (CHAR16
*)L
"endif") == 0) {
773 if (TargetCount
== 0) {
774 ScriptFile
->CurrentCommand
= (SCRIPT_COMMAND_LIST
*)GetNextNode(&ScriptFile
->CommandList
, &CommandNode
->Link
);
779 // Free the memory for this loop...
781 SHELL_FREE_NON_NULL(CommandName
);
787 Deal with the result of the if operation.
789 @param[in] Result The result of the if.
791 @retval EFI_SUCCESS The operation was successful.
792 @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
;
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
);
840 return (SHELL_INVALID_PARAMETER
);
844 // Make sure that an End exists.
846 if (!MoveToTag(GetNextNode
, L
"endif", L
"if", NULL
, ShellCommandGetCurrentScriptFile(), TRUE
, TRUE
, FALSE
)) {
847 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_NO_MATCHING
), gShellLevel1HiiHandle
, L
"EnfIf", L
"If", ShellCommandGetCurrentScriptFile()->CurrentCommand
->Line
);
848 return (SHELL_DEVICE_ERROR
);
852 // initialize the shell lib (we must be in non-auto-init...)
854 Status
= ShellInitialize();
855 ASSERT_EFI_ERROR(Status
);
857 CurrentParameter
= 1;
860 if (gUnicodeCollation
->StriColl(
862 gEfiShellParametersProtocol
->Argv
[1],
864 gUnicodeCollation
->StriColl(
866 gEfiShellParametersProtocol
->Argv
[2],
868 (gEfiShellParametersProtocol
->Argc
> 3 && gUnicodeCollation
->StriColl(
870 gEfiShellParametersProtocol
->Argv
[3],
872 CaseInsensitive
= TRUE
;
875 CaseInsensitive
= FALSE
;
877 if (gUnicodeCollation
->StriColl(
879 gEfiShellParametersProtocol
->Argv
[1],
881 gUnicodeCollation
->StriColl(
883 gEfiShellParametersProtocol
->Argv
[2],
885 (gEfiShellParametersProtocol
->Argc
> 3 && gUnicodeCollation
->StriColl(
887 gEfiShellParametersProtocol
->Argv
[3],
895 for ( ShellStatus
= SHELL_SUCCESS
, CurrentValue
= FALSE
, Ending
= EndTagMax
896 ; CurrentParameter
< gEfiShellParametersProtocol
->Argc
&& ShellStatus
== SHELL_SUCCESS
897 ; CurrentParameter
++) {
898 if (gUnicodeCollation
->StriColl(
900 gEfiShellParametersProtocol
->Argv
[CurrentParameter
],
903 // we are at the then
905 if (CurrentParameter
+1 != gEfiShellParametersProtocol
->Argc
) {
906 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_TEXT_AFTER_THEN
), gShellLevel1HiiHandle
);
907 ShellStatus
= SHELL_INVALID_PARAMETER
;
909 Status
= PerformResultOperation(CurrentValue
);
910 if (EFI_ERROR(Status
)) {
911 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_AFTER_BAD
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[CurrentParameter
]);
912 ShellStatus
= SHELL_INVALID_PARAMETER
;
916 PreviousEnding
= Ending
;
918 // build up the next statement for analysis
920 if (!BuildNextStatement(CurrentParameter
, &EndParameter
, &Ending
)) {
921 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_NO_MATCHING
), gShellLevel1HiiHandle
, L
"Then", L
"If", ShellCommandGetCurrentScriptFile()->CurrentCommand
->Line
);
922 ShellStatus
= SHELL_INVALID_PARAMETER
;
925 // Analyze the statement
927 Status
= ProcessStatement(&CurrentValue
, CurrentParameter
, EndParameter
, PreviousEnding
, CaseInsensitive
, ForceString
);
928 if (EFI_ERROR(Status
)) {
929 // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_STARTING), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[CurrentParameter]);
930 ShellStatus
= SHELL_INVALID_PARAMETER
;
933 // Optomize to get out of the loop early...
935 if ((Ending
== EndTagOr
&& CurrentValue
) || (Ending
== EndTagAnd
&& !CurrentValue
)) {
936 Status
= PerformResultOperation(CurrentValue
);
937 if (EFI_ERROR(Status
)) {
938 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_AFTER_BAD
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[CurrentParameter
]);
939 ShellStatus
= SHELL_INVALID_PARAMETER
;
945 if (ShellStatus
== SHELL_SUCCESS
){
946 CurrentParameter
= EndParameter
;
948 // Skip over the or or and parameter.
950 if (Ending
== EndTagOr
|| Ending
== EndTagAnd
) {
956 return (ShellStatus
);
960 Function for 'else' command.
962 @param[in] ImageHandle Handle to the Image (NULL if Internal).
963 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
967 ShellCommandRunElse (
968 IN EFI_HANDLE ImageHandle
,
969 IN EFI_SYSTEM_TABLE
*SystemTable
972 ASSERT_EFI_ERROR(CommandInit());
974 if (gEfiShellParametersProtocol
->Argc
> 1) {
975 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel1HiiHandle
);
976 return (SHELL_INVALID_PARAMETER
);
979 if (!gEfiShellProtocol
->BatchIsActive()) {
980 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"Else");
981 return (SHELL_UNSUPPORTED
);
985 if (!MoveToTag(GetPreviousNode
, L
"if", L
"endif", NULL
, ShellCommandGetCurrentScriptFile(), FALSE
, TRUE
, FALSE
)) {
986 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_NO_MATCHING
), gShellLevel1HiiHandle
, L
"If", L
"Else", ShellCommandGetCurrentScriptFile()->CurrentCommand
->Line
);
987 return (SHELL_DEVICE_ERROR
);
989 if (!MoveToTag(GetPreviousNode
, L
"if", L
"else", NULL
, ShellCommandGetCurrentScriptFile(), FALSE
, TRUE
, FALSE
)) {
990 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_NO_MATCHING
), gShellLevel1HiiHandle
, L
"If", L
"Else", ShellCommandGetCurrentScriptFile()->CurrentCommand
->Line
);
991 return (SHELL_DEVICE_ERROR
);
994 if (!MoveToTag(GetNextNode
, L
"endif", L
"if", NULL
, ShellCommandGetCurrentScriptFile(), FALSE
, FALSE
, FALSE
)) {
995 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_NO_MATCHING
), gShellLevel1HiiHandle
, L
"EndIf", "Else", ShellCommandGetCurrentScriptFile()->CurrentCommand
->Line
);
996 return (SHELL_DEVICE_ERROR
);
999 return (SHELL_SUCCESS
);
1003 Function for 'endif' command.
1005 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1006 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1010 ShellCommandRunEndIf (
1011 IN EFI_HANDLE ImageHandle
,
1012 IN EFI_SYSTEM_TABLE
*SystemTable
1015 ASSERT_EFI_ERROR(CommandInit());
1017 if (gEfiShellParametersProtocol
->Argc
> 1) {
1018 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel1HiiHandle
);
1019 return (SHELL_INVALID_PARAMETER
);
1022 if (!gEfiShellProtocol
->BatchIsActive()) {
1023 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"Endif");
1024 return (SHELL_UNSUPPORTED
);
1027 if (!MoveToTag(GetPreviousNode
, L
"if", L
"endif", NULL
, ShellCommandGetCurrentScriptFile(), FALSE
, TRUE
, FALSE
)) {
1028 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_NO_MATCHING
), gShellLevel1HiiHandle
, L
"If", L
"EndIf", ShellCommandGetCurrentScriptFile()->CurrentCommand
->Line
);
1029 return (SHELL_DEVICE_ERROR
);
1032 return (SHELL_SUCCESS
);