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.
96 IN CONST CHAR16
*String
99 CONST CHAR16
*ProfilesString
;
100 CONST CHAR16
*TempLocation
;
102 ProfilesString
= ShellGetEnvironmentVariable(L
"profiles");
103 ASSERT(ProfilesString
!= NULL
);
104 TempLocation
= StrStr(ProfilesString
, String
);
105 if ((TempLocation
!= NULL
) && (*(TempLocation
-1) == L
';') && (*(TempLocation
+StrLen(String
)) == L
';')) {
112 Do a comparison between 2 things.
114 @param[in] Compare1 The first item to compare.
115 @param[in] Compare2 The second item to compare.
116 @param[in] BinOp The type of comparison to perform.
117 @param[in] CaseInsensitive TRUE to do non-case comparison, FALSE otherwise.
118 @param[in] ForceStringCompare TRUE to force string comparison, FALSE otherwise.
120 @return The result of the comparison.
124 IN CONST CHAR16
*Compare1
,
125 IN CONST CHAR16
*Compare2
,
126 IN CONST BIN_OPERATOR_TYPE BinOp
,
127 IN CONST BOOLEAN CaseInsensitive
,
128 IN CONST BOOLEAN ForceStringCompare
135 // "Compare1 BinOp Compare2"
138 case OperatorUnisgnedGreaterThan
:
139 case OperatorGreaterThan
:
140 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
144 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) > 0) || (StringCompare(&Compare1
, &Compare2
) > 0)) {
151 if (Compare1
[0] == L
'-') {
152 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
154 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
156 if (Compare2
[0] == L
'-') {
157 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
159 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
161 if (BinOp
== OperatorGreaterThan
) {
166 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
) {
208 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
212 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) == 0) || (StringCompare(&Compare1
, &Compare2
) == 0)) {
219 if (Compare1
[0] == L
'-') {
220 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
222 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
224 if (Compare2
[0] == L
'-') {
225 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
227 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
234 case OperatorNotEqual
:
235 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
239 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) != 0) || (StringCompare(&Compare1
, &Compare2
) != 0)) {
246 if (Compare1
[0] == L
'-') {
247 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
249 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
251 if (Compare2
[0] == L
'-') {
252 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
254 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
261 case OperatorUnsignedGreaterOrEqual
:
262 case OperatorGreatorOrEqual
:
263 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
267 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) >= 0) || (StringCompare(&Compare1
, &Compare2
) >= 0)) {
274 if (Compare1
[0] == L
'-') {
275 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
277 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
279 if (Compare2
[0] == L
'-') {
280 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
282 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
284 if (BinOp
== OperatorGreatorOrEqual
) {
289 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
) {
336 Process an if statement and determine if its is valid or not.
338 @param[in, out] PassingState Opon entry, the current state. Upon exit,
340 @param[in] StartParameterNumber The number of the first parameter of
342 @param[in] EndParameterNumber The number of the final parameter of
344 @param[in] OperatorToUse The type of termination operator.
345 @param[in] CaseInsensitive TRUE for case insensitive, FALSE otherwise.
346 @param[in] ForceStringCompare TRUE for all string based, FALSE otherwise.
348 @retval EFI_INVALID_PARAMETER A parameter was invalid.
349 @retval EFI_SUCCESS The operation was successful.
353 IN OUT BOOLEAN
*PassingState
,
354 IN UINTN StartParameterNumber
,
355 IN UINTN EndParameterNumber
,
356 IN CONST END_TAG_TYPE OperatorToUse
,
357 IN CONST BOOLEAN CaseInsensitive
,
358 IN CONST BOOLEAN ForceStringCompare
362 BOOLEAN OperationResult
;
364 CHAR16
*StatementWalker
;
365 BIN_OPERATOR_TYPE BinOp
;
368 CHAR16 HexString
[20];
372 ASSERT((END_TAG_TYPE
)OperatorToUse
!= EndTagThen
);
374 Status
= EFI_SUCCESS
;
376 OperationResult
= FALSE
;
378 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
];
379 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"not", &Match
)) && Match
) {
381 StatementWalker
= gEfiShellParametersProtocol
->Argv
[++StartParameterNumber
];
387 // now check for 'boolfunc' operators
389 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"isint", &Match
)) && Match
) {
390 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
391 && StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
392 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
393 OperationResult
= ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
);
395 Status
= EFI_INVALID_PARAMETER
;
396 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"isint");
398 } else if ((!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"exists", &Match
)) && Match
) ||
399 (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"exist", &Match
)) && Match
)) {
400 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&&
401 StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
402 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
404 // is what remains a file in CWD???
406 OperationResult
= (BOOLEAN
)(ShellFileExists(StatementWalker
)==EFI_SUCCESS
);
407 } else if (StatementWalker
[0] == CHAR_NULL
&& StartParameterNumber
+1 == EndParameterNumber
) {
408 OperationResult
= (BOOLEAN
)(ShellFileExists(gEfiShellParametersProtocol
->Argv
[++StartParameterNumber
])==EFI_SUCCESS
);
410 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"exist(s)");
411 Status
= EFI_INVALID_PARAMETER
;
413 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"available", &Match
)) && Match
) {
414 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&&
415 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 (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"profile", &Match
)) && Match
) {
426 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&&
427 StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
431 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
432 OperationResult
= IsValidProfile(StatementWalker
);
434 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"profile");
435 Status
= EFI_INVALID_PARAMETER
;
437 } else if (StartParameterNumber
+1 >= EndParameterNumber
) {
438 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[StartParameterNumber
]);
439 Status
= EFI_INVALID_PARAMETER
;
442 // must be 'item binop item' style
449 // get the first item
451 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
];
452 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"efierror", &Match
)) && Match
) {
453 TempSpot
= StrStr(StatementWalker
, L
")");
454 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&& TempSpot
!= NULL
) {
455 *TempSpot
= CHAR_NULL
;
456 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
457 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
);
458 ASSERT(Compare1
== NULL
);
459 Compare1
= StrnCatGrow(&Compare1
, NULL
, HexString
, 0);
460 StatementWalker
+= StrLen(StatementWalker
) + 1;
462 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
463 Status
= EFI_INVALID_PARAMETER
;
466 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
467 Status
= EFI_INVALID_PARAMETER
;
469 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"pierror", &Match
)) && Match
) {
470 TempSpot
= StrStr(StatementWalker
, L
")");
471 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&& TempSpot
!= NULL
) {
472 *TempSpot
= CHAR_NULL
;
473 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
474 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>2));
475 ASSERT(Compare1
== NULL
);
476 Compare1
= StrnCatGrow(&Compare1
, NULL
, HexString
, 0);
477 StatementWalker
+= StrLen(StatementWalker
) + 1;
479 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
480 Status
= EFI_INVALID_PARAMETER
;
483 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
484 Status
= EFI_INVALID_PARAMETER
;
486 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"oemerror", &Match
)) && Match
) {
487 TempSpot
= StrStr(StatementWalker
, L
")");
488 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&& TempSpot
!= NULL
) {
489 TempSpot
= CHAR_NULL
;
490 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
491 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>1));
492 ASSERT(Compare1
== NULL
);
493 Compare1
= StrnCatGrow(&Compare1
, NULL
, HexString
, 0);
494 StatementWalker
+= StrLen(StatementWalker
) + 1;
496 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
497 Status
= EFI_INVALID_PARAMETER
;
500 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
501 Status
= EFI_INVALID_PARAMETER
;
504 ASSERT(Compare1
== NULL
);
505 if (EndParameterNumber
- StartParameterNumber
> 2) {
506 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_STARTING
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+2]);
507 Status
= EFI_INVALID_PARAMETER
;
510 // must be a raw string
512 Compare1
= StrnCatGrow(&Compare1
, NULL
, StatementWalker
, 0);
519 ASSERT(StartParameterNumber
+1<EndParameterNumber
);
520 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+1];
521 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"gt", &Match
)) && Match
) {
522 BinOp
= OperatorGreaterThan
;
523 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"lt", &Match
)) && Match
) {
524 BinOp
= OperatorLessThan
;
525 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"eq", &Match
)) && Match
) {
526 BinOp
= OperatorEqual
;
527 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ne", &Match
)) && Match
) {
528 BinOp
= OperatorNotEqual
;
529 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ge", &Match
)) && Match
) {
530 BinOp
= OperatorGreatorOrEqual
;
531 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"le", &Match
)) && Match
) {
532 BinOp
= OperatorLessOrEqual
;
533 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"==", &Match
)) && Match
) {
534 BinOp
= OperatorEqual
;
535 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ugt", &Match
)) && Match
) {
536 BinOp
= OperatorUnisgnedGreaterThan
;
537 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ult", &Match
)) && Match
) {
538 BinOp
= OperatorUnsignedLessThan
;
539 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"uge", &Match
)) && Match
) {
540 BinOp
= OperatorUnsignedGreaterOrEqual
;
541 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ule", &Match
)) && Match
) {
542 BinOp
= OperatorUnsignedLessOrEqual
;
544 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_INVALID_BINOP
), gShellLevel1HiiHandle
, StatementWalker
);
545 Status
= EFI_INVALID_PARAMETER
;
549 // get the second item
551 ASSERT(StartParameterNumber
+2<=EndParameterNumber
);
552 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+2];
553 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"efierror", &Match
)) && Match
) {
554 TempSpot
= StrStr(StatementWalker
, L
")");
555 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&& TempSpot
!= NULL
) {
556 TempSpot
= CHAR_NULL
;
557 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
558 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
);
559 ASSERT(Compare2
== NULL
);
560 Compare2
= StrnCatGrow(&Compare2
, NULL
, HexString
, 0);
561 StatementWalker
+= StrLen(StatementWalker
) + 1;
563 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
564 Status
= EFI_INVALID_PARAMETER
;
567 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
568 Status
= EFI_INVALID_PARAMETER
;
571 // can this be collapsed into the above?
573 } else if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"pierror", &Match
)) && Match
) {
574 TempSpot
= StrStr(StatementWalker
, L
")");
575 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&& TempSpot
!= NULL
) {
576 TempSpot
= CHAR_NULL
;
577 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
578 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>2));
579 ASSERT(Compare2
== NULL
);
580 Compare2
= StrnCatGrow(&Compare2
, NULL
, HexString
, 0);
581 StatementWalker
+= StrLen(StatementWalker
) + 1;
583 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
584 Status
= EFI_INVALID_PARAMETER
;
587 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
588 Status
= EFI_INVALID_PARAMETER
;
590 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16
**)(&StatementWalker
), L
"oemerror", &Match
)) && Match
) {
591 TempSpot
= StrStr(StatementWalker
, L
")");
592 if (!EFI_ERROR (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(", &Match
)) && Match
&& TempSpot
!= NULL
) {
593 TempSpot
= CHAR_NULL
;
594 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
595 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>1));
596 ASSERT(Compare2
== NULL
);
597 Compare2
= StrnCatGrow(&Compare2
, NULL
, HexString
, 0);
598 StatementWalker
+= StrLen(StatementWalker
) + 1;
600 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
601 Status
= EFI_INVALID_PARAMETER
;
604 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
605 Status
= EFI_INVALID_PARAMETER
;
609 // must be a raw string
611 ASSERT(Compare2
== NULL
);
612 Compare2
= StrnCatGrow(&Compare2
, NULL
, StatementWalker
, 0);
615 if (Compare1
!= NULL
&& Compare2
!= NULL
&& BinOp
!= OperatorMax
) {
616 OperationResult
= TestOperation(Compare1
, Compare2
, BinOp
, CaseInsensitive
, ForceStringCompare
);
619 SHELL_FREE_NON_NULL(Compare1
);
620 SHELL_FREE_NON_NULL(Compare2
);
624 // done processing do result...
627 if (!EFI_ERROR(Status
)) {
629 OperationResult
= (BOOLEAN
)(!OperationResult
);
631 switch(OperatorToUse
) {
633 *PassingState
= (BOOLEAN
)(*PassingState
|| OperationResult
);
636 *PassingState
= (BOOLEAN
)(*PassingState
&& OperationResult
);
639 *PassingState
= (BOOLEAN
)(OperationResult
);
649 Break up the next part of the if statement (until the next 'and', 'or', or 'then').
651 @param[in] ParameterNumber The current parameter number.
652 @param[out] EndParameter Upon successful return, will point to the
653 parameter to start the next iteration with.
654 @param[out] EndTag Upon successful return, will point to the
655 type that was found at the end of this statement.
657 @retval TRUE A valid statement was found.
658 @retval FALSE A valid statement was not found.
662 IN UINTN ParameterNumber
,
663 OUT UINTN
*EndParameter
,
664 OUT END_TAG_TYPE
*EndTag
670 ; ParameterNumber
< gEfiShellParametersProtocol
->Argc
673 if (gUnicodeCollation
->StriColl(
675 gEfiShellParametersProtocol
->Argv
[ParameterNumber
],
677 *EndParameter
= ParameterNumber
- 1;
680 } else if (gUnicodeCollation
->StriColl(
682 gEfiShellParametersProtocol
->Argv
[ParameterNumber
],
684 *EndParameter
= ParameterNumber
- 1;
687 } else if (gUnicodeCollation
->StriColl(
689 gEfiShellParametersProtocol
->Argv
[ParameterNumber
],
691 *EndParameter
= ParameterNumber
- 1;
692 *EndTag
= EndTagThen
;
696 if (*EndTag
== EndTagMax
) {
703 Move the script file pointer to a different place in the script file.
704 This one is special since it handles the if/else/endif syntax.
706 @param[in] ScriptFile The script file from GetCurrnetScriptFile().
708 @retval TRUE The move target was found and the move was successful.
709 @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 if (CommandName
== NULL
) {
743 CommandWalker
= CommandName
;
746 // Skip leading spaces and tabs.
748 while ((CommandWalker
[0] == L
' ') || (CommandWalker
[0] == L
'\t')) {
751 TempLocation
= StrStr(CommandWalker
, L
" ");
753 if (TempLocation
!= NULL
) {
754 *TempLocation
= CHAR_NULL
;
758 // did we find a nested item ?
760 if (gUnicodeCollation
->StriColl(
762 (CHAR16
*)CommandWalker
,
765 } else if (TargetCount
== 1 && gUnicodeCollation
->StriColl(
767 (CHAR16
*)CommandWalker
,
768 (CHAR16
*)L
"else") == 0) {
770 // else can only decrement the last part... not an nested if
771 // hence the TargetCount compare added
774 } else if (gUnicodeCollation
->StriColl(
776 (CHAR16
*)CommandWalker
,
777 (CHAR16
*)L
"endif") == 0) {
780 if (TargetCount
== 0) {
781 ScriptFile
->CurrentCommand
= (SCRIPT_COMMAND_LIST
*)GetNextNode(&ScriptFile
->CommandList
, &CommandNode
->Link
);
786 // Free the memory for this loop...
788 SHELL_FREE_NON_NULL(CommandName
);
794 Deal with the result of the if operation.
796 @param[in] Result The result of the if.
798 @retval EFI_SUCCESS The operation was successful.
799 @retval EFI_NOT_FOUND The ending tag could not be found.
802 PerformResultOperation (
803 IN CONST BOOLEAN Result
806 if (Result
|| MoveToTagSpecial(ShellCommandGetCurrentScriptFile())) {
807 return (EFI_SUCCESS
);
809 return (EFI_NOT_FOUND
);
813 Function for 'if' command.
815 @param[in] ImageHandle Handle to the Image (NULL if Internal).
816 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
821 IN EFI_HANDLE ImageHandle
,
822 IN EFI_SYSTEM_TABLE
*SystemTable
826 SHELL_STATUS ShellStatus
;
827 BOOLEAN CaseInsensitive
;
829 UINTN CurrentParameter
;
831 BOOLEAN CurrentValue
;
833 END_TAG_TYPE PreviousEnding
;
834 SCRIPT_FILE
*CurrentScriptFile
;
836 Status
= CommandInit();
837 ASSERT_EFI_ERROR(Status
);
839 if (!gEfiShellProtocol
->BatchIsActive()) {
840 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"if");
841 return (SHELL_UNSUPPORTED
);
844 if (gEfiShellParametersProtocol
->Argc
< 3) {
845 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel1HiiHandle
, L
"if");
846 return (SHELL_INVALID_PARAMETER
);
850 // Make sure that an End exists.
852 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
853 if (!MoveToTag(GetNextNode
, L
"endif", L
"if", NULL
, CurrentScriptFile
, TRUE
, TRUE
, FALSE
)) {
858 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
859 gShellLevel1HiiHandle
,
862 CurrentScriptFile
!=NULL
863 && CurrentScriptFile
->CurrentCommand
!=NULL
864 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
865 return (SHELL_DEVICE_ERROR
);
869 // initialize the shell lib (we must be in non-auto-init...)
871 Status
= ShellInitialize();
872 ASSERT_EFI_ERROR(Status
);
874 CurrentParameter
= 1;
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],
889 CaseInsensitive
= TRUE
;
892 CaseInsensitive
= FALSE
;
894 if (gUnicodeCollation
->StriColl(
896 gEfiShellParametersProtocol
->Argv
[1],
898 gUnicodeCollation
->StriColl(
900 gEfiShellParametersProtocol
->Argv
[2],
902 (gEfiShellParametersProtocol
->Argc
> 3 && gUnicodeCollation
->StriColl(
904 gEfiShellParametersProtocol
->Argv
[3],
912 for ( ShellStatus
= SHELL_SUCCESS
, CurrentValue
= FALSE
, Ending
= EndTagMax
913 ; CurrentParameter
< gEfiShellParametersProtocol
->Argc
&& ShellStatus
== SHELL_SUCCESS
914 ; CurrentParameter
++) {
915 if (gUnicodeCollation
->StriColl(
917 gEfiShellParametersProtocol
->Argv
[CurrentParameter
],
920 // we are at the then
922 if (CurrentParameter
+1 != gEfiShellParametersProtocol
->Argc
) {
923 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_TEXT_AFTER_THEN
), gShellLevel1HiiHandle
, L
"if");
924 ShellStatus
= SHELL_INVALID_PARAMETER
;
926 Status
= PerformResultOperation(CurrentValue
);
927 if (EFI_ERROR(Status
)) {
928 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_AFTER_BAD
), gShellLevel1HiiHandle
, L
"if", gEfiShellParametersProtocol
->Argv
[CurrentParameter
]);
929 ShellStatus
= SHELL_INVALID_PARAMETER
;
933 PreviousEnding
= Ending
;
935 // build up the next statement for analysis
937 if (!BuildNextStatement(CurrentParameter
, &EndParameter
, &Ending
)) {
938 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
943 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
944 gShellLevel1HiiHandle
,
947 CurrentScriptFile
!=NULL
948 && CurrentScriptFile
->CurrentCommand
!=NULL
949 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
950 ShellStatus
= SHELL_INVALID_PARAMETER
;
953 // Analyze the statement
955 Status
= ProcessStatement(&CurrentValue
, CurrentParameter
, EndParameter
, PreviousEnding
, CaseInsensitive
, ForceString
);
956 if (EFI_ERROR(Status
)) {
957 // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_STARTING), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[CurrentParameter]);
958 ShellStatus
= SHELL_INVALID_PARAMETER
;
961 // Optomize to get out of the loop early...
963 if ((Ending
== EndTagOr
&& CurrentValue
) || (Ending
== EndTagAnd
&& !CurrentValue
)) {
964 Status
= PerformResultOperation(CurrentValue
);
965 if (EFI_ERROR(Status
)) {
966 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_AFTER_BAD
), gShellLevel1HiiHandle
, L
"if", gEfiShellParametersProtocol
->Argv
[CurrentParameter
]);
967 ShellStatus
= SHELL_INVALID_PARAMETER
;
973 if (ShellStatus
== SHELL_SUCCESS
){
974 CurrentParameter
= EndParameter
;
976 // Skip over the or or and parameter.
978 if (Ending
== EndTagOr
|| Ending
== EndTagAnd
) {
984 return (ShellStatus
);
988 Function for 'else' command.
990 @param[in] ImageHandle Handle to the Image (NULL if Internal).
991 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
995 ShellCommandRunElse (
996 IN EFI_HANDLE ImageHandle
,
997 IN EFI_SYSTEM_TABLE
*SystemTable
1001 SCRIPT_FILE
*CurrentScriptFile
;
1003 Status
= CommandInit ();
1004 ASSERT_EFI_ERROR (Status
);
1006 if (gEfiShellParametersProtocol
->Argc
> 1) {
1007 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel1HiiHandle
, L
"if");
1008 return (SHELL_INVALID_PARAMETER
);
1011 if (!gEfiShellProtocol
->BatchIsActive()) {
1012 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"Else");
1013 return (SHELL_UNSUPPORTED
);
1016 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
1018 if (!MoveToTag(GetPreviousNode
, L
"if", L
"endif", NULL
, CurrentScriptFile
, FALSE
, TRUE
, FALSE
)) {
1023 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1024 gShellLevel1HiiHandle
,
1027 CurrentScriptFile
!=NULL
1028 && CurrentScriptFile
->CurrentCommand
!=NULL
1029 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1030 return (SHELL_DEVICE_ERROR
);
1032 if (!MoveToTag(GetPreviousNode
, L
"if", L
"else", NULL
, CurrentScriptFile
, FALSE
, TRUE
, FALSE
)) {
1037 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1038 gShellLevel1HiiHandle
,
1041 CurrentScriptFile
!=NULL
1042 && CurrentScriptFile
->CurrentCommand
!=NULL
1043 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1044 return (SHELL_DEVICE_ERROR
);
1047 if (!MoveToTag(GetNextNode
, L
"endif", L
"if", NULL
, CurrentScriptFile
, FALSE
, FALSE
, FALSE
)) {
1052 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1053 gShellLevel1HiiHandle
,
1056 CurrentScriptFile
!=NULL
1057 && CurrentScriptFile
->CurrentCommand
!=NULL
1058 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1059 return (SHELL_DEVICE_ERROR
);
1062 return (SHELL_SUCCESS
);
1066 Function for 'endif' command.
1068 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1069 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1073 ShellCommandRunEndIf (
1074 IN EFI_HANDLE ImageHandle
,
1075 IN EFI_SYSTEM_TABLE
*SystemTable
1079 SCRIPT_FILE
*CurrentScriptFile
;
1081 Status
= CommandInit ();
1082 ASSERT_EFI_ERROR (Status
);
1084 if (gEfiShellParametersProtocol
->Argc
> 1) {
1085 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel1HiiHandle
, L
"if");
1086 return (SHELL_INVALID_PARAMETER
);
1089 if (!gEfiShellProtocol
->BatchIsActive()) {
1090 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"Endif");
1091 return (SHELL_UNSUPPORTED
);
1094 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
1095 if (!MoveToTag(GetPreviousNode
, L
"if", L
"endif", NULL
, CurrentScriptFile
, FALSE
, TRUE
, FALSE
)) {
1100 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1101 gShellLevel1HiiHandle
,
1104 CurrentScriptFile
!=NULL
1105 && CurrentScriptFile
->CurrentCommand
!=NULL
1106 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1107 return (SHELL_DEVICE_ERROR
);
1110 return (SHELL_SUCCESS
);