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 - 2016, 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.
45 @param[out] Match TRUE when there is another Fragment in Statement,
48 @retval EFI_SUCCESS The match operation is performed successfully.
49 @retval EFI_OUT_OF_RESOURCES Out of resources.
53 IN OUT CONST CHAR16
**Statement
,
54 IN CONST CHAR16
*Fragment
,
62 Tester
= StrnCatGrow(&Tester
, NULL
, *Statement
, StrLen(Fragment
));
64 return EFI_OUT_OF_RESOURCES
;
66 Tester
[StrLen(Fragment
)] = CHAR_NULL
;
67 if (gUnicodeCollation
->StriColl(
72 // increment the string pointer to the end of what we found and then chop off spaces...
74 *Statement
+=StrLen(Fragment
);
75 while (*Statement
[0] == L
' ') {
87 Determine if String represents a valid profile.
89 @param[in] String The pointer to the string to test.
91 @retval TRUE String is a valid profile.
92 @retval FALSE String is not a valid profile.
97 IN CONST CHAR16
*String
100 CONST CHAR16
*ProfilesString
;
101 CONST CHAR16
*TempLocation
;
103 ProfilesString
= ShellGetEnvironmentVariable(L
"profiles");
104 ASSERT(ProfilesString
!= NULL
);
105 TempLocation
= StrStr(ProfilesString
, String
);
106 if ((TempLocation
!= NULL
) && (*(TempLocation
-1) == L
';') && (*(TempLocation
+StrLen(String
)) == L
';')) {
113 Do a comparison between 2 things.
115 @param[in] Compare1 The first item to compare.
116 @param[in] Compare2 The second item to compare.
117 @param[in] BinOp The type of comparison to perform.
118 @param[in] CaseInsensitive TRUE to do non-case comparison, FALSE otherwise.
119 @param[in] ForceStringCompare TRUE to force string comparison, FALSE otherwise.
121 @return The result of the comparison.
126 IN CONST CHAR16
*Compare1
,
127 IN CONST CHAR16
*Compare2
,
128 IN CONST BIN_OPERATOR_TYPE BinOp
,
129 IN CONST BOOLEAN CaseInsensitive
,
130 IN CONST BOOLEAN ForceStringCompare
137 // "Compare1 BinOp Compare2"
140 case OperatorUnisgnedGreaterThan
:
141 case OperatorGreaterThan
:
142 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
146 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) > 0) || (StringCompare(&Compare1
, &Compare2
) > 0)) {
153 if (Compare1
[0] == L
'-') {
154 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
156 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
158 if (Compare2
[0] == L
'-') {
159 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
161 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
163 if (BinOp
== OperatorGreaterThan
) {
168 if ((UINTN
)Cmp1
> (UINTN
)Cmp2
) {
174 case OperatorUnsignedLessThan
:
175 case OperatorLessThan
:
176 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
180 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) < 0) || (StringCompare(&Compare1
, &Compare2
) < 0)) {
187 if (Compare1
[0] == L
'-') {
188 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
190 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
192 if (Compare2
[0] == L
'-') {
193 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
195 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
197 if (BinOp
== OperatorLessThan
) {
202 if ((UINTN
)Cmp1
< (UINTN
)Cmp2
) {
210 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
214 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) == 0) || (StringCompare(&Compare1
, &Compare2
) == 0)) {
221 if (Compare1
[0] == L
'-') {
222 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
224 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
226 if (Compare2
[0] == L
'-') {
227 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
229 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
);
263 case OperatorUnsignedGreaterOrEqual
:
264 case OperatorGreatorOrEqual
:
265 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
269 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) >= 0) || (StringCompare(&Compare1
, &Compare2
) >= 0)) {
276 if (Compare1
[0] == L
'-') {
277 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
279 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
281 if (Compare2
[0] == L
'-') {
282 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
284 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
286 if (BinOp
== OperatorGreatorOrEqual
) {
291 if ((UINTN
)Cmp1
>= (UINTN
)Cmp2
) {
297 case OperatorLessOrEqual
:
298 case OperatorUnsignedLessOrEqual
:
299 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
303 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) <= 0) || (StringCompare(&Compare1
, &Compare2
) <= 0)) {
310 if (Compare1
[0] == L
'-') {
311 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
313 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
315 if (Compare2
[0] == L
'-') {
316 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
318 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
320 if (BinOp
== OperatorLessOrEqual
) {
325 if ((UINTN
)Cmp1
<= (UINTN
)Cmp2
) {
338 Process an if statement and determine if its is valid or not.
340 @param[in, out] PassingState Opon entry, the current state. Upon exit,
342 @param[in] StartParameterNumber The number of the first parameter of
344 @param[in] EndParameterNumber The number of the final parameter of
346 @param[in] OperatorToUse The type of termination operator.
347 @param[in] CaseInsensitive TRUE for case insensitive, FALSE otherwise.
348 @param[in] ForceStringCompare TRUE for all string based, FALSE otherwise.
350 @retval EFI_INVALID_PARAMETER A parameter was invalid.
351 @retval EFI_SUCCESS The operation was successful.
356 IN OUT BOOLEAN
*PassingState
,
357 IN UINTN StartParameterNumber
,
358 IN UINTN EndParameterNumber
,
359 IN CONST END_TAG_TYPE OperatorToUse
,
360 IN CONST BOOLEAN CaseInsensitive
,
361 IN CONST BOOLEAN ForceStringCompare
365 BOOLEAN OperationResult
;
367 CHAR16
*StatementWalker
;
368 BIN_OPERATOR_TYPE BinOp
;
371 CHAR16 HexString
[20];
375 ASSERT((END_TAG_TYPE
)OperatorToUse
!= EndTagThen
);
377 Status
= EFI_SUCCESS
;
379 OperationResult
= FALSE
;
380 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
];
381 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"not", &Match
)) && Match
) {
383 StatementWalker
= gEfiShellParametersProtocol
->Argv
[++StartParameterNumber
];
389 // now check for 'boolfunc' operators
391 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"isint", &Match
)) && Match
) {
392 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
393 && StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
394 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
395 OperationResult
= ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
);
397 Status
= EFI_INVALID_PARAMETER
;
398 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"isint");
400 } else if ((!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"exists", &Match
)) && Match
) ||
401 (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"exist", &Match
)) && Match
)) {
402 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&&
403 StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
404 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
406 // is what remains a file in CWD???
408 OperationResult
= (BOOLEAN
)(ShellFileExists(StatementWalker
)==EFI_SUCCESS
);
409 } else if (StatementWalker
[0] == CHAR_NULL
&& StartParameterNumber
+1 == EndParameterNumber
) {
410 OperationResult
= (BOOLEAN
)(ShellFileExists(gEfiShellParametersProtocol
->Argv
[++StartParameterNumber
])==EFI_SUCCESS
);
412 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"exist(s)");
413 Status
= EFI_INVALID_PARAMETER
;
415 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"available", &Match
)) && Match
) {
416 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&&
417 StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
418 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
420 // is what remains a file in the CWD or path???
422 OperationResult
= (BOOLEAN
)(ShellIsFileInPath(StatementWalker
)==EFI_SUCCESS
);
424 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"available");
425 Status
= EFI_INVALID_PARAMETER
;
427 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"profile", &Match
)) && Match
) {
428 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&&
429 StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
433 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
434 OperationResult
= IsValidProfile(StatementWalker
);
436 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"profile");
437 Status
= EFI_INVALID_PARAMETER
;
439 } else if (StartParameterNumber
+1 >= EndParameterNumber
) {
440 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[StartParameterNumber
]);
441 Status
= EFI_INVALID_PARAMETER
;
444 // must be 'item binop item' style
451 // get the first item
453 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
];
454 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"efierror", &Match
)) && Match
) {
455 TempSpot
= StrStr(StatementWalker
, L
")");
456 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&& TempSpot
!= NULL
) {
457 *TempSpot
= CHAR_NULL
;
458 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
459 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
);
460 ASSERT(Compare1
== NULL
);
461 Compare1
= StrnCatGrow(&Compare1
, NULL
, HexString
, 0);
462 StatementWalker
+= StrLen(StatementWalker
) + 1;
464 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
465 Status
= EFI_INVALID_PARAMETER
;
468 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
469 Status
= EFI_INVALID_PARAMETER
;
471 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"pierror", &Match
)) && Match
) {
472 TempSpot
= StrStr(StatementWalker
, L
")");
473 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&& TempSpot
!= NULL
) {
474 *TempSpot
= CHAR_NULL
;
475 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
476 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>2));
477 ASSERT(Compare1
== NULL
);
478 Compare1
= StrnCatGrow(&Compare1
, NULL
, HexString
, 0);
479 StatementWalker
+= StrLen(StatementWalker
) + 1;
481 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
482 Status
= EFI_INVALID_PARAMETER
;
485 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
486 Status
= EFI_INVALID_PARAMETER
;
488 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"oemerror", &Match
)) && Match
) {
489 TempSpot
= StrStr(StatementWalker
, L
")");
490 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&& TempSpot
!= NULL
) {
491 TempSpot
= CHAR_NULL
;
492 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
493 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>1));
494 ASSERT(Compare1
== NULL
);
495 Compare1
= StrnCatGrow(&Compare1
, NULL
, HexString
, 0);
496 StatementWalker
+= StrLen(StatementWalker
) + 1;
498 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
499 Status
= EFI_INVALID_PARAMETER
;
502 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
503 Status
= EFI_INVALID_PARAMETER
;
506 ASSERT(Compare1
== NULL
);
507 if (EndParameterNumber
- StartParameterNumber
> 2) {
508 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_STARTING
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+2]);
509 Status
= EFI_INVALID_PARAMETER
;
512 // must be a raw string
514 Compare1
= StrnCatGrow(&Compare1
, NULL
, StatementWalker
, 0);
521 ASSERT(StartParameterNumber
+1<EndParameterNumber
);
522 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+1];
523 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"gt", &Match
)) && Match
) {
524 BinOp
= OperatorGreaterThan
;
525 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"lt", &Match
)) && Match
) {
526 BinOp
= OperatorLessThan
;
527 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"eq", &Match
)) && Match
) {
528 BinOp
= OperatorEqual
;
529 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ne", &Match
)) && Match
) {
530 BinOp
= OperatorNotEqual
;
531 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ge", &Match
)) && Match
) {
532 BinOp
= OperatorGreatorOrEqual
;
533 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"le", &Match
)) && Match
) {
534 BinOp
= OperatorLessOrEqual
;
535 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"==", &Match
)) && Match
) {
536 BinOp
= OperatorEqual
;
537 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ugt", &Match
)) && Match
) {
538 BinOp
= OperatorUnisgnedGreaterThan
;
539 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ult", &Match
)) && Match
) {
540 BinOp
= OperatorUnsignedLessThan
;
541 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"uge", &Match
)) && Match
) {
542 BinOp
= OperatorUnsignedGreaterOrEqual
;
543 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ule", &Match
)) && Match
) {
544 BinOp
= OperatorUnsignedLessOrEqual
;
546 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_INVALID_BINOP
), gShellLevel1HiiHandle
, StatementWalker
);
547 Status
= EFI_INVALID_PARAMETER
;
551 // get the second item
553 ASSERT(StartParameterNumber
+2<=EndParameterNumber
);
554 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+2];
555 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"efierror", &Match
)) && Match
) {
556 TempSpot
= StrStr(StatementWalker
, L
")");
557 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&& TempSpot
!= NULL
) {
558 TempSpot
= CHAR_NULL
;
559 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
560 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
);
561 ASSERT(Compare2
== NULL
);
562 Compare2
= StrnCatGrow(&Compare2
, NULL
, HexString
, 0);
563 StatementWalker
+= StrLen(StatementWalker
) + 1;
565 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
566 Status
= EFI_INVALID_PARAMETER
;
569 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
570 Status
= EFI_INVALID_PARAMETER
;
573 // can this be collapsed into the above?
575 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"pierror", &Match
)) && Match
) {
576 TempSpot
= StrStr(StatementWalker
, L
")");
577 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&& TempSpot
!= NULL
) {
578 TempSpot
= CHAR_NULL
;
579 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
580 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>2));
581 ASSERT(Compare2
== NULL
);
582 Compare2
= StrnCatGrow(&Compare2
, NULL
, HexString
, 0);
583 StatementWalker
+= StrLen(StatementWalker
) + 1;
585 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
586 Status
= EFI_INVALID_PARAMETER
;
589 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
590 Status
= EFI_INVALID_PARAMETER
;
592 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"oemerror", &Match
)) && Match
) {
593 TempSpot
= StrStr(StatementWalker
, L
")");
594 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&& TempSpot
!= NULL
) {
595 TempSpot
= CHAR_NULL
;
596 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
597 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>1));
598 ASSERT(Compare2
== NULL
);
599 Compare2
= StrnCatGrow(&Compare2
, NULL
, HexString
, 0);
600 StatementWalker
+= StrLen(StatementWalker
) + 1;
602 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
603 Status
= EFI_INVALID_PARAMETER
;
606 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
607 Status
= EFI_INVALID_PARAMETER
;
611 // must be a raw string
613 ASSERT(Compare2
== NULL
);
614 Compare2
= StrnCatGrow(&Compare2
, NULL
, StatementWalker
, 0);
617 if (Compare1
!= NULL
&& Compare2
!= NULL
&& BinOp
!= OperatorMax
) {
618 OperationResult
= TestOperation(Compare1
, Compare2
, BinOp
, CaseInsensitive
, ForceStringCompare
);
621 SHELL_FREE_NON_NULL(Compare1
);
622 SHELL_FREE_NON_NULL(Compare2
);
626 // done processing do result...
629 if (!EFI_ERROR(Status
)) {
631 OperationResult
= (BOOLEAN
)(!OperationResult
);
633 switch(OperatorToUse
) {
635 *PassingState
= (BOOLEAN
)(*PassingState
|| OperationResult
);
638 *PassingState
= (BOOLEAN
)(*PassingState
&& OperationResult
);
641 *PassingState
= (BOOLEAN
)(OperationResult
);
651 Break up the next part of the if statement (until the next 'and', 'or', or 'then').
653 @param[in] ParameterNumber The current parameter number.
654 @param[out] EndParameter Upon successful return, will point to the
655 parameter to start the next iteration with.
656 @param[out] EndTag Upon successful return, will point to the
657 type that was found at the end of this statement.
659 @retval TRUE A valid statement was found.
660 @retval FALSE A valid statement was not found.
665 IN UINTN ParameterNumber
,
666 OUT UINTN
*EndParameter
,
667 OUT END_TAG_TYPE
*EndTag
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 if (CommandName
== NULL
) {
747 CommandWalker
= CommandName
;
750 // Skip leading spaces and tabs.
752 while ((CommandWalker
[0] == L
' ') || (CommandWalker
[0] == L
'\t')) {
755 TempLocation
= StrStr(CommandWalker
, L
" ");
757 if (TempLocation
!= NULL
) {
758 *TempLocation
= CHAR_NULL
;
762 // did we find a nested item ?
764 if (gUnicodeCollation
->StriColl(
766 (CHAR16
*)CommandWalker
,
769 } else if (TargetCount
== 1 && gUnicodeCollation
->StriColl(
771 (CHAR16
*)CommandWalker
,
772 (CHAR16
*)L
"else") == 0) {
774 // else can only decrement the last part... not an nested if
775 // hence the TargetCount compare added
778 } else if (gUnicodeCollation
->StriColl(
780 (CHAR16
*)CommandWalker
,
781 (CHAR16
*)L
"endif") == 0) {
784 if (TargetCount
== 0) {
785 ScriptFile
->CurrentCommand
= (SCRIPT_COMMAND_LIST
*)GetNextNode(&ScriptFile
->CommandList
, &CommandNode
->Link
);
790 // Free the memory for this loop...
792 SHELL_FREE_NON_NULL(CommandName
);
798 Deal with the result of the if operation.
800 @param[in] Result The result of the if.
802 @retval EFI_SUCCESS The operation was successful.
803 @retval EFI_NOT_FOUND The ending tag could not be found.
807 PerformResultOperation (
808 IN CONST BOOLEAN Result
811 if (Result
|| MoveToTagSpecial(ShellCommandGetCurrentScriptFile())) {
812 return (EFI_SUCCESS
);
814 return (EFI_NOT_FOUND
);
818 Function for 'if' command.
820 @param[in] ImageHandle Handle to the Image (NULL if Internal).
821 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
826 IN EFI_HANDLE ImageHandle
,
827 IN EFI_SYSTEM_TABLE
*SystemTable
831 SHELL_STATUS ShellStatus
;
832 BOOLEAN CaseInsensitive
;
834 UINTN CurrentParameter
;
836 BOOLEAN CurrentValue
;
838 END_TAG_TYPE PreviousEnding
;
839 SCRIPT_FILE
*CurrentScriptFile
;
841 Status
= CommandInit();
842 ASSERT_EFI_ERROR(Status
);
844 if (!gEfiShellProtocol
->BatchIsActive()) {
845 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"if");
846 return (SHELL_UNSUPPORTED
);
849 if (gEfiShellParametersProtocol
->Argc
< 3) {
850 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel1HiiHandle
, L
"if");
851 return (SHELL_INVALID_PARAMETER
);
855 // Make sure that an End exists.
857 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
858 if (!MoveToTag(GetNextNode
, L
"endif", L
"if", NULL
, CurrentScriptFile
, TRUE
, TRUE
, FALSE
)) {
863 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
864 gShellLevel1HiiHandle
,
867 CurrentScriptFile
!=NULL
868 && CurrentScriptFile
->CurrentCommand
!=NULL
869 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
870 return (SHELL_DEVICE_ERROR
);
874 // initialize the shell lib (we must be in non-auto-init...)
876 Status
= ShellInitialize();
877 ASSERT_EFI_ERROR(Status
);
879 CurrentParameter
= 1;
882 if (gUnicodeCollation
->StriColl(
884 gEfiShellParametersProtocol
->Argv
[1],
886 gUnicodeCollation
->StriColl(
888 gEfiShellParametersProtocol
->Argv
[2],
890 (gEfiShellParametersProtocol
->Argc
> 3 && gUnicodeCollation
->StriColl(
892 gEfiShellParametersProtocol
->Argv
[3],
894 CaseInsensitive
= TRUE
;
897 CaseInsensitive
= FALSE
;
899 if (gUnicodeCollation
->StriColl(
901 gEfiShellParametersProtocol
->Argv
[1],
903 gUnicodeCollation
->StriColl(
905 gEfiShellParametersProtocol
->Argv
[2],
907 (gEfiShellParametersProtocol
->Argc
> 3 && gUnicodeCollation
->StriColl(
909 gEfiShellParametersProtocol
->Argv
[3],
917 for ( ShellStatus
= SHELL_SUCCESS
, CurrentValue
= FALSE
, Ending
= EndTagMax
918 ; CurrentParameter
< gEfiShellParametersProtocol
->Argc
&& ShellStatus
== SHELL_SUCCESS
919 ; CurrentParameter
++) {
920 if (gUnicodeCollation
->StriColl(
922 gEfiShellParametersProtocol
->Argv
[CurrentParameter
],
925 // we are at the then
927 if (CurrentParameter
+1 != gEfiShellParametersProtocol
->Argc
) {
928 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_TEXT_AFTER_THEN
), gShellLevel1HiiHandle
, L
"if");
929 ShellStatus
= SHELL_INVALID_PARAMETER
;
931 Status
= PerformResultOperation(CurrentValue
);
932 if (EFI_ERROR(Status
)) {
933 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_AFTER_BAD
), gShellLevel1HiiHandle
, L
"if", gEfiShellParametersProtocol
->Argv
[CurrentParameter
]);
934 ShellStatus
= SHELL_INVALID_PARAMETER
;
938 PreviousEnding
= Ending
;
940 // build up the next statement for analysis
942 if (!BuildNextStatement(CurrentParameter
, &EndParameter
, &Ending
)) {
943 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
948 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
949 gShellLevel1HiiHandle
,
952 CurrentScriptFile
!=NULL
953 && CurrentScriptFile
->CurrentCommand
!=NULL
954 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
955 ShellStatus
= SHELL_INVALID_PARAMETER
;
958 // Analyze the statement
960 Status
= ProcessStatement(&CurrentValue
, CurrentParameter
, EndParameter
, PreviousEnding
, CaseInsensitive
, ForceString
);
961 if (EFI_ERROR(Status
)) {
962 // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_STARTING), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[CurrentParameter]);
963 ShellStatus
= SHELL_INVALID_PARAMETER
;
966 // Optomize to get out of the loop early...
968 if ((Ending
== EndTagOr
&& CurrentValue
) || (Ending
== EndTagAnd
&& !CurrentValue
)) {
969 Status
= PerformResultOperation(CurrentValue
);
970 if (EFI_ERROR(Status
)) {
971 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_AFTER_BAD
), gShellLevel1HiiHandle
, L
"if", gEfiShellParametersProtocol
->Argv
[CurrentParameter
]);
972 ShellStatus
= SHELL_INVALID_PARAMETER
;
978 if (ShellStatus
== SHELL_SUCCESS
){
979 CurrentParameter
= EndParameter
;
981 // Skip over the or or and parameter.
983 if (Ending
== EndTagOr
|| Ending
== EndTagAnd
) {
989 return (ShellStatus
);
993 Function for 'else' command.
995 @param[in] ImageHandle Handle to the Image (NULL if Internal).
996 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1000 ShellCommandRunElse (
1001 IN EFI_HANDLE ImageHandle
,
1002 IN EFI_SYSTEM_TABLE
*SystemTable
1006 SCRIPT_FILE
*CurrentScriptFile
;
1008 Status
= CommandInit ();
1009 ASSERT_EFI_ERROR (Status
);
1011 if (gEfiShellParametersProtocol
->Argc
> 1) {
1012 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel1HiiHandle
, L
"if");
1013 return (SHELL_INVALID_PARAMETER
);
1016 if (!gEfiShellProtocol
->BatchIsActive()) {
1017 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"Else");
1018 return (SHELL_UNSUPPORTED
);
1021 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
1023 if (!MoveToTag(GetPreviousNode
, L
"if", L
"endif", 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
);
1037 if (!MoveToTag(GetPreviousNode
, L
"if", L
"else", NULL
, CurrentScriptFile
, FALSE
, TRUE
, FALSE
)) {
1042 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1043 gShellLevel1HiiHandle
,
1046 CurrentScriptFile
!=NULL
1047 && CurrentScriptFile
->CurrentCommand
!=NULL
1048 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1049 return (SHELL_DEVICE_ERROR
);
1052 if (!MoveToTag(GetNextNode
, L
"endif", L
"if", NULL
, CurrentScriptFile
, FALSE
, FALSE
, FALSE
)) {
1057 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1058 gShellLevel1HiiHandle
,
1061 CurrentScriptFile
!=NULL
1062 && CurrentScriptFile
->CurrentCommand
!=NULL
1063 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1064 return (SHELL_DEVICE_ERROR
);
1067 return (SHELL_SUCCESS
);
1071 Function for 'endif' command.
1073 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1074 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1078 ShellCommandRunEndIf (
1079 IN EFI_HANDLE ImageHandle
,
1080 IN EFI_SYSTEM_TABLE
*SystemTable
1084 SCRIPT_FILE
*CurrentScriptFile
;
1086 Status
= CommandInit ();
1087 ASSERT_EFI_ERROR (Status
);
1089 if (gEfiShellParametersProtocol
->Argc
> 1) {
1090 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel1HiiHandle
, L
"if");
1091 return (SHELL_INVALID_PARAMETER
);
1094 if (!gEfiShellProtocol
->BatchIsActive()) {
1095 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"Endif");
1096 return (SHELL_UNSUPPORTED
);
1099 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
1100 if (!MoveToTag(GetPreviousNode
, L
"if", L
"endif", NULL
, CurrentScriptFile
, FALSE
, TRUE
, FALSE
)) {
1105 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1106 gShellLevel1HiiHandle
,
1109 CurrentScriptFile
!=NULL
1110 && CurrentScriptFile
->CurrentCommand
!=NULL
1111 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1112 return (SHELL_DEVICE_ERROR
);
1115 return (SHELL_SUCCESS
);