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 - 2014, 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>
31 OperatorGreatorOrEqual
,
33 OperatorUnisgnedGreaterThan
,
34 OperatorUnsignedLessThan
,
35 OperatorUnsignedGreaterOrEqual
,
36 OperatorUnsignedLessOrEqual
,
41 Extract the next fragment, if there is one.
43 @param[in, out] Statement The current remaining statement.
44 @param[in] Fragment The current fragment.
46 @retval FALSE There is not another fragment.
47 @retval TRUE There is another fragment.
52 IN OUT CONST CHAR16
**Statement
,
53 IN CONST CHAR16
*Fragment
60 Tester
= StrnCatGrow(&Tester
, NULL
, *Statement
, StrLen(Fragment
));
61 ASSERT(Tester
!= NULL
);
62 Tester
[StrLen(Fragment
)] = CHAR_NULL
;
63 if (gUnicodeCollation
->StriColl(
68 // increment the string pointer to the end of what we found and then chop off spaces...
70 *Statement
+=StrLen(Fragment
);
71 while (*Statement
[0] == L
' ') {
82 Determine if String represents a valid profile.
84 @param[in] String The pointer to the string to test.
86 @retval TRUE String is a valid profile.
87 @retval FALSE String is not a valid profile.
92 IN CONST CHAR16
*String
95 CONST CHAR16
*ProfilesString
;
96 CONST CHAR16
*TempLocation
;
98 ProfilesString
= ShellGetEnvironmentVariable(L
"profiles");
99 ASSERT(ProfilesString
!= NULL
);
100 TempLocation
= StrStr(ProfilesString
, String
);
101 if ((TempLocation
!= NULL
) && (*(TempLocation
-1) == L
';') && (*(TempLocation
+StrLen(String
)) == L
';')) {
108 Do a comparison between 2 things.
110 @param[in] Compare1 The first item to compare.
111 @param[in] Compare2 The second item to compare.
112 @param[in] BinOp The type of comparison to perform.
113 @param[in] CaseInsensitive TRUE to do non-case comparison, FALSE otherwise.
114 @param[in] ForceStringCompare TRUE to force string comparison, FALSE otherwise.
116 @return The result of the comparison.
121 IN CONST CHAR16
*Compare1
,
122 IN CONST CHAR16
*Compare2
,
123 IN CONST BIN_OPERATOR_TYPE BinOp
,
124 IN CONST BOOLEAN CaseInsensitive
,
125 IN CONST BOOLEAN ForceStringCompare
132 // "Compare1 BinOp Compare2"
135 case OperatorUnisgnedGreaterThan
:
136 case OperatorGreaterThan
:
137 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
141 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) > 0) || (StringCompare(&Compare1
, &Compare2
) > 0)) {
148 if (Compare1
[0] == L
'-') {
149 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
151 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
153 if (Compare2
[0] == L
'-') {
154 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
156 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
158 if (BinOp
== OperatorGreaterThan
) {
163 if ((UINTN
)Cmp1
> (UINTN
)Cmp2
) {
169 case OperatorUnsignedLessThan
:
170 case OperatorLessThan
:
171 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
175 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) < 0) || (StringCompare(&Compare1
, &Compare2
) < 0)) {
182 if (Compare1
[0] == L
'-') {
183 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
185 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
187 if (Compare2
[0] == L
'-') {
188 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
190 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
192 if (BinOp
== OperatorLessThan
) {
197 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
);
231 case OperatorNotEqual
:
232 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
236 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) != 0) || (StringCompare(&Compare1
, &Compare2
) != 0)) {
243 if (Compare1
[0] == L
'-') {
244 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
246 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
248 if (Compare2
[0] == L
'-') {
249 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
251 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
258 case OperatorUnsignedGreaterOrEqual
:
259 case OperatorGreatorOrEqual
:
260 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
264 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) >= 0) || (StringCompare(&Compare1
, &Compare2
) >= 0)) {
271 if (Compare1
[0] == L
'-') {
272 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
274 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
276 if (Compare2
[0] == L
'-') {
277 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
279 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
281 if (BinOp
== OperatorGreatorOrEqual
) {
286 if ((UINTN
)Cmp1
>= (UINTN
)Cmp2
) {
292 case OperatorLessOrEqual
:
293 case OperatorUnsignedLessOrEqual
:
294 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
298 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) <= 0) || (StringCompare(&Compare1
, &Compare2
) <= 0)) {
305 if (Compare1
[0] == L
'-') {
306 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
308 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
310 if (Compare2
[0] == L
'-') {
311 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
313 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
315 if (BinOp
== OperatorLessOrEqual
) {
320 if ((UINTN
)Cmp1
<= (UINTN
)Cmp2
) {
333 Process an if statement and determine if its is valid or not.
335 @param[in, out] PassingState Opon entry, the current state. Upon exit,
337 @param[in] StartParameterNumber The number of the first parameter of
339 @param[in] EndParameterNumber The number of the final parameter of
341 @param[in] OperatorToUse The type of termination operator.
342 @param[in] CaseInsensitive TRUE for case insensitive, FALSE otherwise.
343 @param[in] ForceStringCompare TRUE for all string based, FALSE otherwise.
345 @retval EFI_INVALID_PARAMETER A parameter was invalid.
346 @retval EFI_SUCCESS The operation was successful.
351 IN OUT BOOLEAN
*PassingState
,
352 IN UINTN StartParameterNumber
,
353 IN UINTN EndParameterNumber
,
354 IN CONST END_TAG_TYPE OperatorToUse
,
355 IN CONST BOOLEAN CaseInsensitive
,
356 IN CONST BOOLEAN ForceStringCompare
360 BOOLEAN OperationResult
;
362 CHAR16
*StatementWalker
;
363 BIN_OPERATOR_TYPE BinOp
;
366 CHAR16 HexString
[20];
369 ASSERT((END_TAG_TYPE
)OperatorToUse
!= EndTagThen
);
371 Status
= EFI_SUCCESS
;
373 OperationResult
= FALSE
;
374 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
];
375 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"not")) {
377 StatementWalker
= gEfiShellParametersProtocol
->Argv
[++StartParameterNumber
];
383 // now check for 'boolfunc' operators
385 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"isint")) {
386 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
387 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
388 OperationResult
= ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
);
390 Status
= EFI_INVALID_PARAMETER
;
391 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"isint");
393 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"exists") || IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"exist")) {
394 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
395 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
397 // is what remains a file in CWD???
399 OperationResult
= (BOOLEAN
)(ShellFileExists(StatementWalker
)==EFI_SUCCESS
);
400 } else if (StatementWalker
[0] == CHAR_NULL
&& StartParameterNumber
+1 == EndParameterNumber
) {
401 OperationResult
= (BOOLEAN
)(ShellFileExists(gEfiShellParametersProtocol
->Argv
[++StartParameterNumber
])==EFI_SUCCESS
);
403 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"exist(s)");
404 Status
= EFI_INVALID_PARAMETER
;
406 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"available")) {
407 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
408 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
410 // is what remains a file in the CWD or path???
412 OperationResult
= (BOOLEAN
)(ShellIsFileInPath(StatementWalker
)==EFI_SUCCESS
);
414 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"available");
415 Status
= EFI_INVALID_PARAMETER
;
417 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"profile")) {
418 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
422 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
423 OperationResult
= IsValidProfile(StatementWalker
);
425 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"profile");
426 Status
= EFI_INVALID_PARAMETER
;
428 } else if (StartParameterNumber
+1 >= EndParameterNumber
) {
429 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[StartParameterNumber
]);
430 Status
= EFI_INVALID_PARAMETER
;
433 // must be 'item binop item' style
440 // get the first item
442 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
];
443 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"efierror")) {
444 TempSpot
= StrStr(StatementWalker
, L
")");
445 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
446 *TempSpot
= CHAR_NULL
;
447 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
448 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
);
449 ASSERT(Compare1
== NULL
);
450 Compare1
= StrnCatGrow(&Compare1
, NULL
, HexString
, 0);
451 StatementWalker
+= StrLen(StatementWalker
) + 1;
453 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
454 Status
= EFI_INVALID_PARAMETER
;
457 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
458 Status
= EFI_INVALID_PARAMETER
;
460 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"pierror")) {
461 TempSpot
= StrStr(StatementWalker
, L
")");
462 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
463 *TempSpot
= CHAR_NULL
;
464 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
465 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>2));
466 ASSERT(Compare1
== NULL
);
467 Compare1
= StrnCatGrow(&Compare1
, NULL
, HexString
, 0);
468 StatementWalker
+= StrLen(StatementWalker
) + 1;
470 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
471 Status
= EFI_INVALID_PARAMETER
;
474 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
475 Status
= EFI_INVALID_PARAMETER
;
477 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"oemerror")) {
478 TempSpot
= StrStr(StatementWalker
, L
")");
479 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
480 TempSpot
= CHAR_NULL
;
481 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
482 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>1));
483 ASSERT(Compare1
== NULL
);
484 Compare1
= StrnCatGrow(&Compare1
, NULL
, HexString
, 0);
485 StatementWalker
+= StrLen(StatementWalker
) + 1;
487 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
488 Status
= EFI_INVALID_PARAMETER
;
491 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
492 Status
= EFI_INVALID_PARAMETER
;
495 ASSERT(Compare1
== NULL
);
496 if (EndParameterNumber
- StartParameterNumber
> 2) {
497 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_STARTING
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+2]);
498 Status
= EFI_INVALID_PARAMETER
;
501 // must be a raw string
503 Compare1
= StrnCatGrow(&Compare1
, NULL
, StatementWalker
, 0);
510 ASSERT(StartParameterNumber
+1<EndParameterNumber
);
511 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+1];
512 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"gt")) {
513 BinOp
= OperatorGreaterThan
;
514 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"lt")) {
515 BinOp
= OperatorLessThan
;
516 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"eq")) {
517 BinOp
= OperatorEqual
;
518 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ne")) {
519 BinOp
= OperatorNotEqual
;
520 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ge")) {
521 BinOp
= OperatorGreatorOrEqual
;
522 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"le")) {
523 BinOp
= OperatorLessOrEqual
;
524 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"==")) {
525 BinOp
= OperatorEqual
;
526 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ugt")) {
527 BinOp
= OperatorUnisgnedGreaterThan
;
528 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ult")) {
529 BinOp
= OperatorUnsignedLessThan
;
530 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"uge")) {
531 BinOp
= OperatorUnsignedGreaterOrEqual
;
532 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ule")) {
533 BinOp
= OperatorUnsignedLessOrEqual
;
535 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_INVALID_BINOP
), gShellLevel1HiiHandle
, StatementWalker
);
536 Status
= EFI_INVALID_PARAMETER
;
540 // get the second item
542 ASSERT(StartParameterNumber
+2<=EndParameterNumber
);
543 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+2];
544 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"efierror")) {
545 TempSpot
= StrStr(StatementWalker
, L
")");
546 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
547 TempSpot
= CHAR_NULL
;
548 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
549 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
);
550 ASSERT(Compare2
== NULL
);
551 Compare2
= StrnCatGrow(&Compare2
, NULL
, HexString
, 0);
552 StatementWalker
+= StrLen(StatementWalker
) + 1;
554 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
555 Status
= EFI_INVALID_PARAMETER
;
558 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
559 Status
= EFI_INVALID_PARAMETER
;
562 // can this be collapsed into the above?
564 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"pierror")) {
565 TempSpot
= StrStr(StatementWalker
, L
")");
566 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
567 TempSpot
= CHAR_NULL
;
568 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
569 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>2));
570 ASSERT(Compare2
== NULL
);
571 Compare2
= StrnCatGrow(&Compare2
, NULL
, HexString
, 0);
572 StatementWalker
+= StrLen(StatementWalker
) + 1;
574 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
575 Status
= EFI_INVALID_PARAMETER
;
578 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
579 Status
= EFI_INVALID_PARAMETER
;
581 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"oemerror")) {
582 TempSpot
= StrStr(StatementWalker
, L
")");
583 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
584 TempSpot
= CHAR_NULL
;
585 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
586 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>1));
587 ASSERT(Compare2
== NULL
);
588 Compare2
= StrnCatGrow(&Compare2
, NULL
, HexString
, 0);
589 StatementWalker
+= StrLen(StatementWalker
) + 1;
591 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
592 Status
= EFI_INVALID_PARAMETER
;
595 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
596 Status
= EFI_INVALID_PARAMETER
;
600 // must be a raw string
602 ASSERT(Compare2
== NULL
);
603 Compare2
= StrnCatGrow(&Compare2
, NULL
, StatementWalker
, 0);
606 if (Compare1
!= NULL
&& Compare2
!= NULL
&& BinOp
!= OperatorMax
) {
607 OperationResult
= TestOperation(Compare1
, Compare2
, BinOp
, CaseInsensitive
, ForceStringCompare
);
610 SHELL_FREE_NON_NULL(Compare1
);
611 SHELL_FREE_NON_NULL(Compare2
);
615 // done processing do result...
618 if (!EFI_ERROR(Status
)) {
620 OperationResult
= (BOOLEAN
)(!OperationResult
);
622 switch(OperatorToUse
) {
624 *PassingState
= (BOOLEAN
)(*PassingState
|| OperationResult
);
627 *PassingState
= (BOOLEAN
)(*PassingState
&& OperationResult
);
630 *PassingState
= (BOOLEAN
)(OperationResult
);
640 Break up the next part of the if statement (until the next 'and', 'or', or 'then').
642 @param[in] ParameterNumber The current parameter number.
643 @param[out] EndParameter Upon successful return, will point to the
644 parameter to start the next iteration with.
645 @param[out] EndTag Upon successful return, will point to the
646 type that was found at the end of this statement.
648 @retval TRUE A valid statement was found.
649 @retval FALSE A valid statement was not found.
654 IN UINTN ParameterNumber
,
655 OUT UINTN
*EndParameter
,
656 OUT END_TAG_TYPE
*EndTag
662 ; ParameterNumber
< gEfiShellParametersProtocol
->Argc
665 if (gUnicodeCollation
->StriColl(
667 gEfiShellParametersProtocol
->Argv
[ParameterNumber
],
669 *EndParameter
= ParameterNumber
- 1;
672 } else if (gUnicodeCollation
->StriColl(
674 gEfiShellParametersProtocol
->Argv
[ParameterNumber
],
676 *EndParameter
= ParameterNumber
- 1;
679 } else if (gUnicodeCollation
->StriColl(
681 gEfiShellParametersProtocol
->Argv
[ParameterNumber
],
683 *EndParameter
= ParameterNumber
- 1;
684 *EndTag
= EndTagThen
;
688 if (*EndTag
== EndTagMax
) {
695 Move the script file pointer to a different place in the script file.
696 This one is special since it handles the if/else/endif syntax.
698 @param[in] ScriptFile The script file from GetCurrnetScriptFile().
700 @retval TRUE The move target was found and the move was successful.
701 @retval FALSE Something went wrong.
706 IN SCRIPT_FILE
*ScriptFile
709 SCRIPT_COMMAND_LIST
*CommandNode
;
713 CHAR16
*CommandWalker
;
714 CHAR16
*TempLocation
;
719 if (ScriptFile
== NULL
) {
723 for (CommandNode
= (SCRIPT_COMMAND_LIST
*)GetNextNode(&ScriptFile
->CommandList
, &ScriptFile
->CurrentCommand
->Link
), Found
= FALSE
724 ; !IsNull(&ScriptFile
->CommandList
, &CommandNode
->Link
) && !Found
725 ; CommandNode
= (SCRIPT_COMMAND_LIST
*)GetNextNode(&ScriptFile
->CommandList
, &CommandNode
->Link
)
729 // get just the first part of the command line...
732 CommandName
= StrnCatGrow(&CommandName
, NULL
, CommandNode
->Cl
, 0);
733 if (CommandName
== NULL
) {
736 CommandWalker
= CommandName
;
739 // Skip leading spaces and tabs.
741 while ((CommandWalker
[0] == L
' ') || (CommandWalker
[0] == L
'\t')) {
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
;
828 SCRIPT_FILE
*CurrentScriptFile
;
830 Status
= CommandInit();
831 ASSERT_EFI_ERROR(Status
);
833 if (!gEfiShellProtocol
->BatchIsActive()) {
834 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"if");
835 return (SHELL_UNSUPPORTED
);
838 if (gEfiShellParametersProtocol
->Argc
< 3) {
839 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel1HiiHandle
, L
"if");
840 return (SHELL_INVALID_PARAMETER
);
844 // Make sure that an End exists.
846 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
847 if (!MoveToTag(GetNextNode
, L
"endif", L
"if", NULL
, CurrentScriptFile
, TRUE
, TRUE
, FALSE
)) {
852 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
853 gShellLevel1HiiHandle
,
856 CurrentScriptFile
!=NULL
857 && CurrentScriptFile
->CurrentCommand
!=NULL
858 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
859 return (SHELL_DEVICE_ERROR
);
863 // initialize the shell lib (we must be in non-auto-init...)
865 Status
= ShellInitialize();
866 ASSERT_EFI_ERROR(Status
);
868 CurrentParameter
= 1;
871 if (gUnicodeCollation
->StriColl(
873 gEfiShellParametersProtocol
->Argv
[1],
875 gUnicodeCollation
->StriColl(
877 gEfiShellParametersProtocol
->Argv
[2],
879 (gEfiShellParametersProtocol
->Argc
> 3 && gUnicodeCollation
->StriColl(
881 gEfiShellParametersProtocol
->Argv
[3],
883 CaseInsensitive
= TRUE
;
886 CaseInsensitive
= FALSE
;
888 if (gUnicodeCollation
->StriColl(
890 gEfiShellParametersProtocol
->Argv
[1],
892 gUnicodeCollation
->StriColl(
894 gEfiShellParametersProtocol
->Argv
[2],
896 (gEfiShellParametersProtocol
->Argc
> 3 && gUnicodeCollation
->StriColl(
898 gEfiShellParametersProtocol
->Argv
[3],
906 for ( ShellStatus
= SHELL_SUCCESS
, CurrentValue
= FALSE
, Ending
= EndTagMax
907 ; CurrentParameter
< gEfiShellParametersProtocol
->Argc
&& ShellStatus
== SHELL_SUCCESS
908 ; CurrentParameter
++) {
909 if (gUnicodeCollation
->StriColl(
911 gEfiShellParametersProtocol
->Argv
[CurrentParameter
],
914 // we are at the then
916 if (CurrentParameter
+1 != gEfiShellParametersProtocol
->Argc
) {
917 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_TEXT_AFTER_THEN
), gShellLevel1HiiHandle
, L
"if");
918 ShellStatus
= SHELL_INVALID_PARAMETER
;
920 Status
= PerformResultOperation(CurrentValue
);
921 if (EFI_ERROR(Status
)) {
922 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_AFTER_BAD
), gShellLevel1HiiHandle
, L
"if", gEfiShellParametersProtocol
->Argv
[CurrentParameter
]);
923 ShellStatus
= SHELL_INVALID_PARAMETER
;
927 PreviousEnding
= Ending
;
929 // build up the next statement for analysis
931 if (!BuildNextStatement(CurrentParameter
, &EndParameter
, &Ending
)) {
932 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
937 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
938 gShellLevel1HiiHandle
,
941 CurrentScriptFile
!=NULL
942 && CurrentScriptFile
->CurrentCommand
!=NULL
943 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
944 ShellStatus
= SHELL_INVALID_PARAMETER
;
947 // Analyze the statement
949 Status
= ProcessStatement(&CurrentValue
, CurrentParameter
, EndParameter
, PreviousEnding
, CaseInsensitive
, ForceString
);
950 if (EFI_ERROR(Status
)) {
951 // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_STARTING), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[CurrentParameter]);
952 ShellStatus
= SHELL_INVALID_PARAMETER
;
955 // Optomize to get out of the loop early...
957 if ((Ending
== EndTagOr
&& CurrentValue
) || (Ending
== EndTagAnd
&& !CurrentValue
)) {
958 Status
= PerformResultOperation(CurrentValue
);
959 if (EFI_ERROR(Status
)) {
960 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_AFTER_BAD
), gShellLevel1HiiHandle
, L
"if", gEfiShellParametersProtocol
->Argv
[CurrentParameter
]);
961 ShellStatus
= SHELL_INVALID_PARAMETER
;
967 if (ShellStatus
== SHELL_SUCCESS
){
968 CurrentParameter
= EndParameter
;
970 // Skip over the or or and parameter.
972 if (Ending
== EndTagOr
|| Ending
== EndTagAnd
) {
978 return (ShellStatus
);
982 Function for 'else' command.
984 @param[in] ImageHandle Handle to the Image (NULL if Internal).
985 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
989 ShellCommandRunElse (
990 IN EFI_HANDLE ImageHandle
,
991 IN EFI_SYSTEM_TABLE
*SystemTable
994 SCRIPT_FILE
*CurrentScriptFile
;
995 ASSERT_EFI_ERROR(CommandInit());
997 if (gEfiShellParametersProtocol
->Argc
> 1) {
998 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel1HiiHandle
, L
"if");
999 return (SHELL_INVALID_PARAMETER
);
1002 if (!gEfiShellProtocol
->BatchIsActive()) {
1003 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"Else");
1004 return (SHELL_UNSUPPORTED
);
1007 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
1009 if (!MoveToTag(GetPreviousNode
, L
"if", L
"endif", NULL
, CurrentScriptFile
, FALSE
, TRUE
, FALSE
)) {
1014 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1015 gShellLevel1HiiHandle
,
1018 CurrentScriptFile
!=NULL
1019 && CurrentScriptFile
->CurrentCommand
!=NULL
1020 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1021 return (SHELL_DEVICE_ERROR
);
1023 if (!MoveToTag(GetPreviousNode
, L
"if", L
"else", NULL
, CurrentScriptFile
, FALSE
, TRUE
, FALSE
)) {
1028 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1029 gShellLevel1HiiHandle
,
1032 CurrentScriptFile
!=NULL
1033 && CurrentScriptFile
->CurrentCommand
!=NULL
1034 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1035 return (SHELL_DEVICE_ERROR
);
1038 if (!MoveToTag(GetNextNode
, L
"endif", L
"if", NULL
, CurrentScriptFile
, FALSE
, FALSE
, FALSE
)) {
1043 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1044 gShellLevel1HiiHandle
,
1047 CurrentScriptFile
!=NULL
1048 && CurrentScriptFile
->CurrentCommand
!=NULL
1049 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1050 return (SHELL_DEVICE_ERROR
);
1053 return (SHELL_SUCCESS
);
1057 Function for 'endif' command.
1059 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1060 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1064 ShellCommandRunEndIf (
1065 IN EFI_HANDLE ImageHandle
,
1066 IN EFI_SYSTEM_TABLE
*SystemTable
1069 SCRIPT_FILE
*CurrentScriptFile
;
1070 ASSERT_EFI_ERROR(CommandInit());
1072 if (gEfiShellParametersProtocol
->Argc
> 1) {
1073 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel1HiiHandle
, L
"if");
1074 return (SHELL_INVALID_PARAMETER
);
1077 if (!gEfiShellProtocol
->BatchIsActive()) {
1078 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"Endif");
1079 return (SHELL_UNSUPPORTED
);
1082 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
1083 if (!MoveToTag(GetPreviousNode
, L
"if", L
"endif", NULL
, CurrentScriptFile
, FALSE
, TRUE
, FALSE
)) {
1088 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1089 gShellLevel1HiiHandle
,
1092 CurrentScriptFile
!=NULL
1093 && CurrentScriptFile
->CurrentCommand
!=NULL
1094 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1095 return (SHELL_DEVICE_ERROR
);
1098 return (SHELL_SUCCESS
);