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>
17 #include <Library/PathLib.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
) {
170 case OperatorUnsignedLessThan
:
171 case OperatorLessThan
:
172 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
176 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) < 0) || (StringCompare(&Compare1
, &Compare2
) < 0)) {
183 if (Compare1
[0] == L
'-') {
184 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
186 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
188 if (Compare2
[0] == L
'-') {
189 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
191 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
193 if (BinOp
== OperatorLessThan
) {
198 if ((UINTN
)Cmp1
< (UINTN
)Cmp2
) {
207 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
211 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) == 0) || (StringCompare(&Compare1
, &Compare2
) == 0)) {
218 if (Compare1
[0] == L
'-') {
219 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
221 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
223 if (Compare2
[0] == L
'-') {
224 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
226 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
);
262 case OperatorUnsignedGreaterOrEqual
:
263 case OperatorGreatorOrEqual
:
264 if (ForceStringCompare
|| !ShellIsHexOrDecimalNumber(Compare1
, FALSE
, FALSE
) || !ShellIsHexOrDecimalNumber(Compare2
, FALSE
, FALSE
)) {
268 if ((CaseInsensitive
&& StringNoCaseCompare(&Compare1
, &Compare2
) >= 0) || (StringCompare(&Compare1
, &Compare2
) >= 0)) {
275 if (Compare1
[0] == L
'-') {
276 Cmp1
= 0 - (INTN
)ShellStrToUintn(Compare1
+1);
278 Cmp1
= (INTN
)ShellStrToUintn(Compare1
);
280 if (Compare2
[0] == L
'-') {
281 Cmp2
= 0 - (INTN
)ShellStrToUintn(Compare2
+1);
283 Cmp2
= (INTN
)ShellStrToUintn(Compare2
);
285 if (BinOp
== OperatorGreatorOrEqual
) {
290 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
) {
339 Process an if statement and determine if its is valid or not.
341 @param[in,out] PassingState Opon entry, the current state. Upon exit,
343 @param[in] StartParameterNumber The number of the first parameter of
345 @param[in] EndParameterNumber The number of the final parameter of
347 @param[in] OperatorToUse The type of termination operator.
348 @param[in] CaseInsensitive TRUE for case insensitive, FALSE otherwise.
349 @param[in] ForceStringCompare TRUE for all string based, FALSE otherwise.
351 @retval EFI_INVALID_PARAMETER A parameter was invalid.
352 @retval EFI_SUCCESS The operation was successful.
357 IN OUT BOOLEAN
*PassingState
,
358 IN UINTN StartParameterNumber
,
359 IN UINTN EndParameterNumber
,
360 IN CONST END_TAG_TYPE OperatorToUse
,
361 IN CONST BOOLEAN CaseInsensitive
,
362 IN CONST BOOLEAN ForceStringCompare
366 BOOLEAN OperationResult
;
368 CHAR16
*StatementWalker
;
369 BIN_OPERATOR_TYPE BinOp
;
372 CHAR16 HexString
[20];
375 ASSERT((END_TAG_TYPE
)OperatorToUse
!= EndTagThen
);
377 Status
= EFI_SUCCESS
;
379 OperationResult
= FALSE
;
380 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
];
381 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"not")) {
383 StatementWalker
= gEfiShellParametersProtocol
->Argv
[++StartParameterNumber
];
389 // now check for 'boolfunc' operators
391 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"isint")) {
392 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
393 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
394 OperationResult
= ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
);
396 Status
= EFI_INVALID_PARAMETER
;
397 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"isint");
399 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"exists") || IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"exist")) {
400 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
401 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
403 // is what remains a file in CWD???
405 OperationResult
= (BOOLEAN
)(ShellFileExists(StatementWalker
)==EFI_SUCCESS
);
406 } else if (StatementWalker
[0] == CHAR_NULL
&& StartParameterNumber
+1 == EndParameterNumber
) {
407 OperationResult
= (BOOLEAN
)(ShellFileExists(gEfiShellParametersProtocol
->Argv
[++StartParameterNumber
])==EFI_SUCCESS
);
409 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"exist(s)");
410 Status
= EFI_INVALID_PARAMETER
;
412 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"available")) {
413 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
414 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
416 // is what remains a file in the CWD or path???
418 OperationResult
= (BOOLEAN
)(ShellIsFileInPath(StatementWalker
)==EFI_SUCCESS
);
420 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"available");
421 Status
= EFI_INVALID_PARAMETER
;
423 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"profile")) {
424 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && StatementWalker
[StrLen(StatementWalker
)-1] == L
')') {
428 StatementWalker
[StrLen(StatementWalker
)-1] = CHAR_NULL
;
429 OperationResult
= IsValidProfile(StatementWalker
);
431 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"profile");
432 Status
= EFI_INVALID_PARAMETER
;
434 } else if (StartParameterNumber
+1 >= EndParameterNumber
) {
435 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[StartParameterNumber
]);
436 Status
= EFI_INVALID_PARAMETER
;
439 // must be 'item binop item' style
446 // get the first item
448 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
];
449 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"efierror")) {
450 TempSpot
= StrStr(StatementWalker
, L
")");
451 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
452 *TempSpot
= CHAR_NULL
;
453 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
454 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
);
455 ASSERT(Compare1
== NULL
);
456 Compare1
= StrnCatGrow(&Compare1
, NULL
, HexString
, 0);
457 StatementWalker
+= StrLen(StatementWalker
) + 1;
459 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
460 Status
= EFI_INVALID_PARAMETER
;
463 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
464 Status
= EFI_INVALID_PARAMETER
;
466 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"pierror")) {
467 TempSpot
= StrStr(StatementWalker
, L
")");
468 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
469 *TempSpot
= CHAR_NULL
;
470 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
471 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>2));
472 ASSERT(Compare1
== NULL
);
473 Compare1
= StrnCatGrow(&Compare1
, NULL
, HexString
, 0);
474 StatementWalker
+= StrLen(StatementWalker
) + 1;
476 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
477 Status
= EFI_INVALID_PARAMETER
;
480 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
481 Status
= EFI_INVALID_PARAMETER
;
483 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"oemerror")) {
484 TempSpot
= StrStr(StatementWalker
, L
")");
485 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
486 TempSpot
= CHAR_NULL
;
487 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
488 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>1));
489 ASSERT(Compare1
== NULL
);
490 Compare1
= StrnCatGrow(&Compare1
, NULL
, HexString
, 0);
491 StatementWalker
+= StrLen(StatementWalker
) + 1;
493 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
494 Status
= EFI_INVALID_PARAMETER
;
497 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
498 Status
= EFI_INVALID_PARAMETER
;
501 ASSERT(Compare1
== NULL
);
502 if (EndParameterNumber
- StartParameterNumber
> 2) {
503 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_STARTING
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+2]);
504 Status
= EFI_INVALID_PARAMETER
;
507 // must be a raw string
509 Compare1
= StrnCatGrow(&Compare1
, NULL
, StatementWalker
, 0);
516 ASSERT(StartParameterNumber
+1<EndParameterNumber
);
517 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+1];
518 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"gt")) {
519 BinOp
= OperatorGreaterThan
;
520 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"lt")) {
521 BinOp
= OperatorLessThan
;
522 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"eq")) {
523 BinOp
= OperatorEqual
;
524 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ne")) {
525 BinOp
= OperatorNotEqual
;
526 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ge")) {
527 BinOp
= OperatorGreatorOrEqual
;
528 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"le")) {
529 BinOp
= OperatorLessOrEqual
;
530 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"==")) {
531 BinOp
= OperatorEqual
;
532 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ugt")) {
533 BinOp
= OperatorUnisgnedGreaterThan
;
534 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ult")) {
535 BinOp
= OperatorUnsignedLessThan
;
536 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"uge")) {
537 BinOp
= OperatorUnsignedGreaterOrEqual
;
538 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"ule")) {
539 BinOp
= OperatorUnsignedLessOrEqual
;
541 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_INVALID_BINOP
), gShellLevel1HiiHandle
, StatementWalker
);
542 Status
= EFI_INVALID_PARAMETER
;
546 // get the second item
548 ASSERT(StartParameterNumber
+2<=EndParameterNumber
);
549 StatementWalker
= gEfiShellParametersProtocol
->Argv
[StartParameterNumber
+2];
550 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"efierror")) {
551 TempSpot
= StrStr(StatementWalker
, L
")");
552 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
553 TempSpot
= CHAR_NULL
;
554 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
555 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
);
556 ASSERT(Compare2
== NULL
);
557 Compare2
= StrnCatGrow(&Compare2
, NULL
, HexString
, 0);
558 StatementWalker
+= StrLen(StatementWalker
) + 1;
560 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
561 Status
= EFI_INVALID_PARAMETER
;
564 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"efierror");
565 Status
= EFI_INVALID_PARAMETER
;
568 // can this be collapsed into the above?
570 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"pierror")) {
571 TempSpot
= StrStr(StatementWalker
, L
")");
572 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
573 TempSpot
= CHAR_NULL
;
574 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
575 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>2));
576 ASSERT(Compare2
== NULL
);
577 Compare2
= StrnCatGrow(&Compare2
, NULL
, HexString
, 0);
578 StatementWalker
+= StrLen(StatementWalker
) + 1;
580 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
581 Status
= EFI_INVALID_PARAMETER
;
584 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"pierror");
585 Status
= EFI_INVALID_PARAMETER
;
587 } else if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"oemerror")) {
588 TempSpot
= StrStr(StatementWalker
, L
")");
589 if (IsNextFragment((CONST CHAR16
**)(&StatementWalker
), L
"(") && TempSpot
!= NULL
) {
590 TempSpot
= CHAR_NULL
;
591 if (ShellIsHexOrDecimalNumber(StatementWalker
, FALSE
, FALSE
)) {
592 UnicodeSPrint(HexString
, sizeof(HexString
), L
"0x%x", ShellStrToUintn(StatementWalker
)|MAX_BIT
|(MAX_BIT
>>1));
593 ASSERT(Compare2
== NULL
);
594 Compare2
= StrnCatGrow(&Compare2
, NULL
, HexString
, 0);
595 StatementWalker
+= StrLen(StatementWalker
) + 1;
597 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
598 Status
= EFI_INVALID_PARAMETER
;
601 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_IN
), gShellLevel1HiiHandle
, L
"oemerror");
602 Status
= EFI_INVALID_PARAMETER
;
606 // must be a raw string
608 ASSERT(Compare2
== NULL
);
609 Compare2
= StrnCatGrow(&Compare2
, NULL
, StatementWalker
, 0);
612 if (Compare1
!= NULL
&& Compare2
!= NULL
&& BinOp
!= OperatorMax
) {
613 OperationResult
= TestOperation(Compare1
, Compare2
, BinOp
, CaseInsensitive
, ForceStringCompare
);
616 SHELL_FREE_NON_NULL(Compare1
);
617 SHELL_FREE_NON_NULL(Compare2
);
621 // done processing do result...
624 if (!EFI_ERROR(Status
)) {
626 OperationResult
= (BOOLEAN
)(!OperationResult
);
628 switch(OperatorToUse
) {
630 *PassingState
= (BOOLEAN
)(*PassingState
|| OperationResult
);
633 *PassingState
= (BOOLEAN
)(*PassingState
&& OperationResult
);
636 *PassingState
= (BOOLEAN
)(OperationResult
);
646 Break up the next part of the if statement (until the next 'and', 'or', or 'then').
648 @param[in] ParameterNumber The current parameter number.
649 @param[out] EndParameter Upon successful return, will point to the
650 parameter to start the next iteration with.
651 @param[out] EndTag Upon successful return, will point to the
652 type that was found at the end of this statement.
654 @retval TRUE A valid statement was found.
655 @retval FALSE A valid statement was not found.
660 IN UINTN ParameterNumber
,
661 OUT UINTN
*EndParameter
,
662 OUT END_TAG_TYPE
*EndTag
670 for(Buffer
= NULL
, BufferSize
= 0
671 ; ParameterNumber
< gEfiShellParametersProtocol
->Argc
674 if (gUnicodeCollation
->StriColl(
676 gEfiShellParametersProtocol
->Argv
[ParameterNumber
],
678 *EndParameter
= ParameterNumber
- 1;
681 } else if (gUnicodeCollation
->StriColl(
683 gEfiShellParametersProtocol
->Argv
[ParameterNumber
],
685 *EndParameter
= ParameterNumber
- 1;
688 } else if (gUnicodeCollation
->StriColl(
690 gEfiShellParametersProtocol
->Argv
[ParameterNumber
],
692 *EndParameter
= ParameterNumber
- 1;
693 *EndTag
= EndTagThen
;
697 if (*EndTag
== EndTagMax
) {
704 Move the script file pointer to a different place in the script file.
705 This one is special since it handles the if/else/endif syntax.
707 @param[in] ScriptFile The script file from GetCurrnetScriptFile().
709 @retval TRUE The move target was found and the move was successful.
710 @retval FALSE Something went wrong.
715 IN SCRIPT_FILE
*ScriptFile
718 SCRIPT_COMMAND_LIST
*CommandNode
;
722 CHAR16
*CommandWalker
;
723 CHAR16
*TempLocation
;
728 if (ScriptFile
== NULL
) {
732 for (CommandNode
= (SCRIPT_COMMAND_LIST
*)GetNextNode(&ScriptFile
->CommandList
, &ScriptFile
->CurrentCommand
->Link
), Found
= FALSE
733 ; !IsNull(&ScriptFile
->CommandList
, &CommandNode
->Link
) && !Found
734 ; CommandNode
= (SCRIPT_COMMAND_LIST
*)GetNextNode(&ScriptFile
->CommandList
, &CommandNode
->Link
)
738 // get just the first part of the command line...
741 CommandName
= StrnCatGrow(&CommandName
, NULL
, CommandNode
->Cl
, 0);
742 CommandWalker
= CommandName
;
743 while (CommandWalker
[0] == L
' ') {
746 TempLocation
= StrStr(CommandWalker
, L
" ");
748 if (TempLocation
!= NULL
) {
749 *TempLocation
= CHAR_NULL
;
753 // did we find a nested item ?
755 if (gUnicodeCollation
->StriColl(
757 (CHAR16
*)CommandWalker
,
760 } else if (TargetCount
== 1 && gUnicodeCollation
->StriColl(
762 (CHAR16
*)CommandWalker
,
763 (CHAR16
*)L
"else") == 0) {
765 // else can only decrement the last part... not an nested if
766 // hence the TargetCount compare added
769 } else if (gUnicodeCollation
->StriColl(
771 (CHAR16
*)CommandWalker
,
772 (CHAR16
*)L
"endif") == 0) {
775 if (TargetCount
== 0) {
776 ScriptFile
->CurrentCommand
= (SCRIPT_COMMAND_LIST
*)GetNextNode(&ScriptFile
->CommandList
, &CommandNode
->Link
);
781 // Free the memory for this loop...
783 SHELL_FREE_NON_NULL(CommandName
);
789 Deal with the result of the if operation.
791 @param[in] Result The result of the if.
793 @retval EFI_SUCCESS The operation was successful.
794 @retval EFI_NOT_FOUND The ending tag could not be found.
798 PerformResultOperation (
799 IN CONST BOOLEAN Result
802 if (Result
|| MoveToTagSpecial(ShellCommandGetCurrentScriptFile())) {
803 return (EFI_SUCCESS
);
805 return (EFI_NOT_FOUND
);
809 Function for 'if' command.
811 @param[in] ImageHandle Handle to the Image (NULL if Internal).
812 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
817 IN EFI_HANDLE ImageHandle
,
818 IN EFI_SYSTEM_TABLE
*SystemTable
822 SHELL_STATUS ShellStatus
;
823 BOOLEAN CaseInsensitive
;
825 UINTN CurrentParameter
;
827 BOOLEAN CurrentValue
;
829 END_TAG_TYPE PreviousEnding
;
830 SCRIPT_FILE
*CurrentScriptFile
;
832 Status
= CommandInit();
833 ASSERT_EFI_ERROR(Status
);
835 if (!gEfiShellProtocol
->BatchIsActive()) {
836 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"If");
837 return (SHELL_UNSUPPORTED
);
840 if (gEfiShellParametersProtocol
->Argc
< 3) {
841 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel1HiiHandle
);
842 return (SHELL_INVALID_PARAMETER
);
846 // Make sure that an End exists.
848 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
849 if (!MoveToTag(GetNextNode
, L
"endif", L
"if", NULL
, CurrentScriptFile
, TRUE
, TRUE
, FALSE
)) {
854 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
855 gShellLevel1HiiHandle
,
858 CurrentScriptFile
!=NULL
859 && CurrentScriptFile
->CurrentCommand
!=NULL
860 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
861 return (SHELL_DEVICE_ERROR
);
865 // initialize the shell lib (we must be in non-auto-init...)
867 Status
= ShellInitialize();
868 ASSERT_EFI_ERROR(Status
);
870 CurrentParameter
= 1;
873 if (gUnicodeCollation
->StriColl(
875 gEfiShellParametersProtocol
->Argv
[1],
877 gUnicodeCollation
->StriColl(
879 gEfiShellParametersProtocol
->Argv
[2],
881 (gEfiShellParametersProtocol
->Argc
> 3 && gUnicodeCollation
->StriColl(
883 gEfiShellParametersProtocol
->Argv
[3],
885 CaseInsensitive
= TRUE
;
888 CaseInsensitive
= FALSE
;
890 if (gUnicodeCollation
->StriColl(
892 gEfiShellParametersProtocol
->Argv
[1],
894 gUnicodeCollation
->StriColl(
896 gEfiShellParametersProtocol
->Argv
[2],
898 (gEfiShellParametersProtocol
->Argc
> 3 && gUnicodeCollation
->StriColl(
900 gEfiShellParametersProtocol
->Argv
[3],
908 for ( ShellStatus
= SHELL_SUCCESS
, CurrentValue
= FALSE
, Ending
= EndTagMax
909 ; CurrentParameter
< gEfiShellParametersProtocol
->Argc
&& ShellStatus
== SHELL_SUCCESS
910 ; CurrentParameter
++) {
911 if (gUnicodeCollation
->StriColl(
913 gEfiShellParametersProtocol
->Argv
[CurrentParameter
],
916 // we are at the then
918 if (CurrentParameter
+1 != gEfiShellParametersProtocol
->Argc
) {
919 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_TEXT_AFTER_THEN
), gShellLevel1HiiHandle
);
920 ShellStatus
= SHELL_INVALID_PARAMETER
;
922 Status
= PerformResultOperation(CurrentValue
);
923 if (EFI_ERROR(Status
)) {
924 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_AFTER_BAD
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[CurrentParameter
]);
925 ShellStatus
= SHELL_INVALID_PARAMETER
;
929 PreviousEnding
= Ending
;
931 // build up the next statement for analysis
933 if (!BuildNextStatement(CurrentParameter
, &EndParameter
, &Ending
)) {
934 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
939 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
940 gShellLevel1HiiHandle
,
943 CurrentScriptFile
!=NULL
944 && CurrentScriptFile
->CurrentCommand
!=NULL
945 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
946 ShellStatus
= SHELL_INVALID_PARAMETER
;
949 // Analyze the statement
951 Status
= ProcessStatement(&CurrentValue
, CurrentParameter
, EndParameter
, PreviousEnding
, CaseInsensitive
, ForceString
);
952 if (EFI_ERROR(Status
)) {
953 // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_STARTING), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[CurrentParameter]);
954 ShellStatus
= SHELL_INVALID_PARAMETER
;
957 // Optomize to get out of the loop early...
959 if ((Ending
== EndTagOr
&& CurrentValue
) || (Ending
== EndTagAnd
&& !CurrentValue
)) {
960 Status
= PerformResultOperation(CurrentValue
);
961 if (EFI_ERROR(Status
)) {
962 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SYNTAX_AFTER_BAD
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[CurrentParameter
]);
963 ShellStatus
= SHELL_INVALID_PARAMETER
;
969 if (ShellStatus
== SHELL_SUCCESS
){
970 CurrentParameter
= EndParameter
;
972 // Skip over the or or and parameter.
974 if (Ending
== EndTagOr
|| Ending
== EndTagAnd
) {
980 return (ShellStatus
);
984 Function for 'else' command.
986 @param[in] ImageHandle Handle to the Image (NULL if Internal).
987 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
991 ShellCommandRunElse (
992 IN EFI_HANDLE ImageHandle
,
993 IN EFI_SYSTEM_TABLE
*SystemTable
996 SCRIPT_FILE
*CurrentScriptFile
;
997 ASSERT_EFI_ERROR(CommandInit());
999 if (gEfiShellParametersProtocol
->Argc
> 1) {
1000 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel1HiiHandle
);
1001 return (SHELL_INVALID_PARAMETER
);
1004 if (!gEfiShellProtocol
->BatchIsActive()) {
1005 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"Else");
1006 return (SHELL_UNSUPPORTED
);
1009 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
1011 if (!MoveToTag(GetPreviousNode
, L
"if", L
"endif", NULL
, CurrentScriptFile
, FALSE
, TRUE
, FALSE
)) {
1016 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1017 gShellLevel1HiiHandle
,
1020 CurrentScriptFile
!=NULL
1021 && CurrentScriptFile
->CurrentCommand
!=NULL
1022 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1023 return (SHELL_DEVICE_ERROR
);
1025 if (!MoveToTag(GetPreviousNode
, L
"if", L
"else", NULL
, CurrentScriptFile
, FALSE
, TRUE
, FALSE
)) {
1030 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1031 gShellLevel1HiiHandle
,
1034 CurrentScriptFile
!=NULL
1035 && CurrentScriptFile
->CurrentCommand
!=NULL
1036 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1037 return (SHELL_DEVICE_ERROR
);
1040 if (!MoveToTag(GetNextNode
, L
"endif", L
"if", NULL
, CurrentScriptFile
, FALSE
, FALSE
, FALSE
)) {
1045 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1046 gShellLevel1HiiHandle
,
1049 CurrentScriptFile
!=NULL
1050 && CurrentScriptFile
->CurrentCommand
!=NULL
1051 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1052 return (SHELL_DEVICE_ERROR
);
1055 return (SHELL_SUCCESS
);
1059 Function for 'endif' command.
1061 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1062 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1066 ShellCommandRunEndIf (
1067 IN EFI_HANDLE ImageHandle
,
1068 IN EFI_SYSTEM_TABLE
*SystemTable
1071 SCRIPT_FILE
*CurrentScriptFile
;
1072 ASSERT_EFI_ERROR(CommandInit());
1074 if (gEfiShellParametersProtocol
->Argc
> 1) {
1075 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel1HiiHandle
);
1076 return (SHELL_INVALID_PARAMETER
);
1079 if (!gEfiShellProtocol
->BatchIsActive()) {
1080 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"Endif");
1081 return (SHELL_UNSUPPORTED
);
1084 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
1085 if (!MoveToTag(GetPreviousNode
, L
"if", L
"endif", NULL
, CurrentScriptFile
, FALSE
, TRUE
, FALSE
)) {
1090 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
1091 gShellLevel1HiiHandle
,
1094 CurrentScriptFile
!=NULL
1095 && CurrentScriptFile
->CurrentCommand
!=NULL
1096 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
1097 return (SHELL_DEVICE_ERROR
);
1100 return (SHELL_SUCCESS
);