2 Main file for endfor and for shell level 1 functions.
4 (C) Copyright 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>
20 Determine if a valid string is a valid number for the 'for' command.
22 @param[in] Number The pointer to the string representation of the number to test.
24 @retval TRUE The number is valid.
25 @retval FALSE The number is not valid.
29 ShellIsValidForNumber (
30 IN CONST CHAR16
*Number
33 if (Number
== NULL
|| *Number
== CHAR_NULL
) {
37 if (*Number
== L
'-') {
41 if (StrLen(Number
) == 0) {
45 if (StrLen(Number
) >= 7) {
46 if ((StrStr(Number
, L
" ") == NULL
) || (((StrStr(Number
, L
" ") != NULL
) && (StrStr(Number
, L
" ") - Number
) >= 7))) {
51 if (!ShellIsDecimalDigitCharacter(*Number
)) {
59 Function for 'endfor' command.
61 @param[in] ImageHandle Handle to the Image (NULL if Internal).
62 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
66 ShellCommandRunEndFor (
67 IN EFI_HANDLE ImageHandle
,
68 IN EFI_SYSTEM_TABLE
*SystemTable
73 SCRIPT_FILE
*CurrentScriptFile
;
75 Status
= CommandInit();
76 ASSERT_EFI_ERROR(Status
);
78 if (!gEfiShellProtocol
->BatchIsActive()) {
79 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"endfor");
80 return (SHELL_UNSUPPORTED
);
83 if (gEfiShellParametersProtocol
->Argc
> 1) {
84 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel1HiiHandle
, L
"endfor");
85 return (SHELL_INVALID_PARAMETER
);
88 Found
= MoveToTag(GetPreviousNode
, L
"for", L
"endfor", NULL
, ShellCommandGetCurrentScriptFile(), FALSE
, FALSE
, FALSE
);
91 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
96 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
97 gShellLevel1HiiHandle
,
100 CurrentScriptFile
!=NULL
101 && CurrentScriptFile
->CurrentCommand
!=NULL
102 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
103 return (SHELL_NOT_FOUND
);
105 return (SHELL_SUCCESS
);
113 CHAR16
*ReplacementName
;
114 CHAR16
*CurrentValue
;
115 BOOLEAN RemoveSubstAlias
;
118 #define SIZE_OF_SHELL_FOR_INFO OFFSET_OF (SHELL_FOR_INFO, Set)
119 #define SHELL_FOR_INFO_SIGNATURE SIGNATURE_32 ('S', 'F', 'I', 's')
122 Update the value of a given alias on the list. If the alias is not there then add it.
124 @param[in] Alias The alias to test for.
125 @param[in] CommandString The updated command string.
126 @param[in, out] List The list to search.
128 @retval EFI_SUCCESS The operation was completed successfully.
129 @retval EFI_OUT_OF_RESOURCES There was not enough free memory.
133 InternalUpdateAliasOnList(
134 IN CONST CHAR16
*Alias
,
135 IN CONST CHAR16
*CommandString
,
136 IN OUT LIST_ENTRY
*List
143 // assert for NULL parameter
145 ASSERT(Alias
!= NULL
);
148 // check for the Alias
150 for ( Node
= (ALIAS_LIST
*)GetFirstNode(List
), Found
= FALSE
151 ; !IsNull(List
, &Node
->Link
)
152 ; Node
= (ALIAS_LIST
*)GetNextNode(List
, &Node
->Link
)
154 ASSERT(Node
->CommandString
!= NULL
);
155 ASSERT(Node
->Alias
!= NULL
);
156 if (StrCmp(Node
->Alias
, Alias
)==0) {
157 FreePool(Node
->CommandString
);
158 Node
->CommandString
= NULL
;
159 Node
->CommandString
= StrnCatGrow(&Node
->CommandString
, NULL
, CommandString
, 0);
165 Node
= AllocateZeroPool(sizeof(ALIAS_LIST
));
167 return (EFI_OUT_OF_RESOURCES
);
169 ASSERT(Node
->Alias
== NULL
);
170 Node
->Alias
= StrnCatGrow(&Node
->Alias
, NULL
, Alias
, 0);
171 ASSERT(Node
->CommandString
== NULL
);
172 Node
->CommandString
= StrnCatGrow(&Node
->CommandString
, NULL
, CommandString
, 0);
173 InsertTailList(List
, &Node
->Link
);
175 return (EFI_SUCCESS
);
179 Find out if an alias is on the given list.
181 @param[in] Alias The alias to test for.
182 @param[in] List The list to search.
184 @retval TRUE The alias is on the list.
185 @retval FALSE The alias is not on the list.
189 InternalIsAliasOnList(
190 IN CONST CHAR16
*Alias
,
191 IN CONST LIST_ENTRY
*List
197 // assert for NULL parameter
199 ASSERT(Alias
!= NULL
);
202 // check for the Alias
204 for ( Node
= (ALIAS_LIST
*)GetFirstNode(List
)
205 ; !IsNull(List
, &Node
->Link
)
206 ; Node
= (ALIAS_LIST
*)GetNextNode(List
, &Node
->Link
)
208 ASSERT(Node
->CommandString
!= NULL
);
209 ASSERT(Node
->Alias
!= NULL
);
210 if (StrCmp(Node
->Alias
, Alias
)==0) {
218 Remove an alias from the given list.
220 @param[in] Alias The alias to remove.
221 @param[in, out] List The list to search.
225 InternalRemoveAliasFromList(
226 IN CONST CHAR16
*Alias
,
227 IN OUT LIST_ENTRY
*List
233 // assert for NULL parameter
235 ASSERT(Alias
!= NULL
);
238 // check for the Alias
240 for ( Node
= (ALIAS_LIST
*)GetFirstNode(List
)
241 ; !IsNull(List
, &Node
->Link
)
242 ; Node
= (ALIAS_LIST
*)GetNextNode(List
, &Node
->Link
)
244 ASSERT(Node
->CommandString
!= NULL
);
245 ASSERT(Node
->Alias
!= NULL
);
246 if (StrCmp(Node
->Alias
, Alias
)==0) {
247 RemoveEntryList(&Node
->Link
);
248 FreePool(Node
->Alias
);
249 FreePool(Node
->CommandString
);
258 Function to determine whether a string is decimal or hex representation of a number
259 and return the number converted from the string.
261 @param[in] String String representation of a number
264 @retval (UINTN)(-1) An error ocurred.
269 IN CONST CHAR16
*String
274 if (!EFI_ERROR(ShellConvertStringToUint64(String
, &RetVal
, FALSE
, TRUE
))) {
275 return ((UINTN
)RetVal
);
277 return ((UINTN
)(-1));
281 Function for 'for' command.
283 @param[in] ImageHandle Handle to the Image (NULL if Internal).
284 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
289 IN EFI_HANDLE ImageHandle
,
290 IN EFI_SYSTEM_TABLE
*SystemTable
294 SHELL_STATUS ShellStatus
;
295 SCRIPT_FILE
*CurrentScriptFile
;
297 CHAR16
*ArgSetWalker
;
301 SHELL_FOR_INFO
*Info
;
305 EFI_SHELL_FILE_INFO
*Node
;
306 EFI_SHELL_FILE_INFO
*FileList
;
311 ShellStatus
= SHELL_SUCCESS
;
318 // initialize the shell lib (we must be in non-auto-init...)
320 Status
= ShellInitialize();
321 ASSERT_EFI_ERROR(Status
);
323 Status
= CommandInit();
324 ASSERT_EFI_ERROR(Status
);
326 if (!gEfiShellProtocol
->BatchIsActive()) {
327 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"for");
328 return (SHELL_UNSUPPORTED
);
331 if (gEfiShellParametersProtocol
->Argc
< 4) {
332 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel1HiiHandle
, L
"for");
333 return (SHELL_INVALID_PARAMETER
);
336 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
337 ASSERT(CurrentScriptFile
!= NULL
);
339 if ((CurrentScriptFile
->CurrentCommand
!= NULL
) && (CurrentScriptFile
->CurrentCommand
->Data
== NULL
)) {
343 // Make sure that an End exists.
345 if (!MoveToTag(GetNextNode
, L
"endfor", L
"for", NULL
, CurrentScriptFile
, TRUE
, TRUE
, FALSE
)) {
350 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
351 gShellLevel1HiiHandle
,
354 CurrentScriptFile
->CurrentCommand
->Line
);
355 return (SHELL_DEVICE_ERROR
);
361 if (gEfiShellParametersProtocol
->Argv
[1][0] != L
'%' || gEfiShellParametersProtocol
->Argv
[1][2] != CHAR_NULL
362 ||!((gEfiShellParametersProtocol
->Argv
[1][1] >= L
'a' && gEfiShellParametersProtocol
->Argv
[1][1] <= L
'z')
363 ||(gEfiShellParametersProtocol
->Argv
[1][1] >= L
'A' && gEfiShellParametersProtocol
->Argv
[1][1] <= L
'Z'))
365 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_INV_VAR
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[1]);
366 return (SHELL_INVALID_PARAMETER
);
369 if (gUnicodeCollation
->StriColl(
372 gEfiShellParametersProtocol
->Argv
[2]) == 0) {
373 for (LoopVar
= 0x3 ; LoopVar
< gEfiShellParametersProtocol
->Argc
; LoopVar
++) {
374 ASSERT((ArgSet
== NULL
&& ArgSize
== 0) || (ArgSet
!= NULL
));
375 if (StrStr(gEfiShellParametersProtocol
->Argv
[LoopVar
], L
"*") != NULL
376 ||StrStr(gEfiShellParametersProtocol
->Argv
[LoopVar
], L
"?") != NULL
377 ||StrStr(gEfiShellParametersProtocol
->Argv
[LoopVar
], L
"[") != NULL
378 ||StrStr(gEfiShellParametersProtocol
->Argv
[LoopVar
], L
"]") != NULL
) {
380 Status
= ShellOpenFileMetaArg ((CHAR16
*)gEfiShellParametersProtocol
->Argv
[LoopVar
], EFI_FILE_MODE_READ
, &FileList
);
381 if (EFI_ERROR(Status
) || FileList
== NULL
|| IsListEmpty(&FileList
->Link
)) {
382 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
" \"", 0);
383 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, gEfiShellParametersProtocol
->Argv
[LoopVar
], 0);
384 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
"\"", 0);
386 for (Node
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&FileList
->Link
)
387 ; !IsNull(&FileList
->Link
, &Node
->Link
)
388 ; Node
= (EFI_SHELL_FILE_INFO
*)GetNextNode(&FileList
->Link
, &Node
->Link
)
390 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
" \"", 0);
391 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, Node
->FullName
, 0);
392 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
"\"", 0);
394 ShellCloseFileMetaArg(&FileList
);
397 Parameter
= gEfiShellParametersProtocol
->Argv
[LoopVar
];
398 if (Parameter
[0] == L
'\"' && Parameter
[StrLen(Parameter
)-1] == L
'\"') {
399 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
" ", 0);
400 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, Parameter
, 0);
402 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
" \"", 0);
403 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, Parameter
, 0);
404 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
"\"", 0);
408 if (ArgSet
== NULL
) {
409 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
412 // set up for an 'in' for loop
414 NewSize
= StrSize(ArgSet
);
415 NewSize
+= sizeof(SHELL_FOR_INFO
)+StrSize(gEfiShellParametersProtocol
->Argv
[1]);
416 Info
= AllocateZeroPool(NewSize
);
417 ASSERT(Info
!= NULL
);
418 Info
->Signature
= SHELL_FOR_INFO_SIGNATURE
;
419 CopyMem(Info
->Set
, ArgSet
, StrSize(ArgSet
));
420 NewSize
= StrSize(gEfiShellParametersProtocol
->Argv
[1]);
421 CopyMem(Info
->Set
+(StrSize(ArgSet
)/sizeof(Info
->Set
[0])), gEfiShellParametersProtocol
->Argv
[1], NewSize
);
422 Info
->ReplacementName
= Info
->Set
+StrSize(ArgSet
)/sizeof(Info
->Set
[0]);
423 Info
->CurrentValue
= (CHAR16
*)Info
->Set
;
428 if (InternalIsAliasOnList(Info
->ReplacementName
, &CurrentScriptFile
->SubstList
)) {
429 Info
->RemoveSubstAlias
= FALSE
;
431 Info
->RemoveSubstAlias
= TRUE
;
433 CurrentScriptFile
->CurrentCommand
->Data
= Info
;
435 } else if (gUnicodeCollation
->StriColl(
438 gEfiShellParametersProtocol
->Argv
[2]) == 0) {
439 for (LoopVar
= 0x3 ; LoopVar
< gEfiShellParametersProtocol
->Argc
; LoopVar
++) {
440 ASSERT((ArgSet
== NULL
&& ArgSize
== 0) || (ArgSet
!= NULL
));
441 if (StrStr (gEfiShellParametersProtocol
->Argv
[LoopVar
], L
")") != NULL
&&
442 (LoopVar
+ 1) < gEfiShellParametersProtocol
->Argc
444 return (SHELL_INVALID_PARAMETER
);
446 if (ArgSet
== NULL
) {
447 // ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0);
449 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
" ", 0);
451 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, gEfiShellParametersProtocol
->Argv
[LoopVar
], 0);
452 // ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" ", 0);
454 if (ArgSet
== NULL
) {
455 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
458 // set up for a 'run' for loop
460 Info
= AllocateZeroPool(sizeof(SHELL_FOR_INFO
)+StrSize(gEfiShellParametersProtocol
->Argv
[1]));
461 ASSERT(Info
!= NULL
);
462 Info
->Signature
= SHELL_FOR_INFO_SIGNATURE
;
463 CopyMem(Info
->Set
, gEfiShellParametersProtocol
->Argv
[1], StrSize(gEfiShellParametersProtocol
->Argv
[1]));
464 Info
->ReplacementName
= Info
->Set
;
465 Info
->CurrentValue
= NULL
;
466 ArgSetWalker
= ArgSet
;
467 if (ArgSetWalker
[0] != L
'(') {
472 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
473 gShellLevel1HiiHandle
,
475 CurrentScriptFile
->CurrentCommand
->Line
);
476 ShellStatus
= SHELL_INVALID_PARAMETER
;
478 TempSpot
= StrStr(ArgSetWalker
, L
")");
479 if (TempSpot
!= NULL
) {
480 TempString
= TempSpot
+1;
481 if (*(TempString
) != CHAR_NULL
) {
482 while(TempString
!= NULL
&& *TempString
== L
' ') {
485 if (StrLen(TempString
) > 0) {
490 if (TempSpot
== NULL
) {
495 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
496 gShellLevel1HiiHandle
,
497 CurrentScriptFile
->CurrentCommand
->Line
);
498 ShellStatus
= SHELL_INVALID_PARAMETER
;
500 *TempSpot
= CHAR_NULL
;
502 while (ArgSetWalker
!= NULL
&& ArgSetWalker
[0] == L
' ') {
505 if (!ShellIsValidForNumber(ArgSetWalker
)) {
510 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
511 gShellLevel1HiiHandle
,
513 CurrentScriptFile
->CurrentCommand
->Line
);
514 ShellStatus
= SHELL_INVALID_PARAMETER
;
516 if (ArgSetWalker
[0] == L
'-') {
517 Info
->Current
= 0 - (INTN
)ReturnUintn(ArgSetWalker
+1);
519 Info
->Current
= (INTN
)ReturnUintn(ArgSetWalker
);
521 ArgSetWalker
= StrStr(ArgSetWalker
, L
" ");
522 while (ArgSetWalker
!= NULL
&& ArgSetWalker
[0] == L
' ') {
525 if (ArgSetWalker
== NULL
|| *ArgSetWalker
== CHAR_NULL
|| !ShellIsValidForNumber(ArgSetWalker
)){
530 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
531 gShellLevel1HiiHandle
,
533 CurrentScriptFile
->CurrentCommand
->Line
);
534 ShellStatus
= SHELL_INVALID_PARAMETER
;
536 if (ArgSetWalker
[0] == L
'-') {
537 Info
->End
= 0 - (INTN
)ReturnUintn(ArgSetWalker
+1);
539 Info
->End
= (INTN
)ReturnUintn(ArgSetWalker
);
541 if (Info
->Current
< Info
->End
) {
547 ArgSetWalker
= StrStr(ArgSetWalker
, L
" ");
548 while (ArgSetWalker
!= NULL
&& ArgSetWalker
[0] == L
' ') {
551 if (ArgSetWalker
!= NULL
&& *ArgSetWalker
!= CHAR_NULL
) {
552 if (ArgSetWalker
== NULL
|| *ArgSetWalker
== CHAR_NULL
|| !ShellIsValidForNumber(ArgSetWalker
)){
557 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
558 gShellLevel1HiiHandle
,
560 CurrentScriptFile
->CurrentCommand
->Line
);
561 ShellStatus
= SHELL_INVALID_PARAMETER
;
563 if (*ArgSetWalker
== L
')') {
564 ASSERT(Info
->Step
== 1 || Info
->Step
== -1);
566 if (ArgSetWalker
[0] == L
'-') {
567 Info
->Step
= 0 - (INTN
)ReturnUintn(ArgSetWalker
+1);
569 Info
->Step
= (INTN
)ReturnUintn(ArgSetWalker
);
572 if (StrStr(ArgSetWalker
, L
" ") != NULL
) {
577 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
578 gShellLevel1HiiHandle
,
580 CurrentScriptFile
->CurrentCommand
->Line
);
581 ShellStatus
= SHELL_INVALID_PARAMETER
;
591 if (ShellStatus
== SHELL_SUCCESS
) {
592 if (InternalIsAliasOnList(Info
->ReplacementName
, &CurrentScriptFile
->SubstList
)) {
593 Info
->RemoveSubstAlias
= FALSE
;
595 Info
->RemoveSubstAlias
= TRUE
;
598 if (CurrentScriptFile
->CurrentCommand
!= NULL
) {
599 CurrentScriptFile
->CurrentCommand
->Data
= Info
;
607 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
608 gShellLevel1HiiHandle
,
610 CurrentScriptFile
!=NULL
611 && CurrentScriptFile
->CurrentCommand
!=NULL
612 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
613 ShellStatus
= SHELL_INVALID_PARAMETER
;
617 // These need to be NULL since they are used to determine if this is the first pass later on...
619 ASSERT(ArgSetWalker
== NULL
);
620 ASSERT(ArgSet
== NULL
);
623 if (CurrentScriptFile
!= NULL
&& CurrentScriptFile
->CurrentCommand
!= NULL
) {
624 Info
= (SHELL_FOR_INFO
*)CurrentScriptFile
->CurrentCommand
->Data
;
625 if (CurrentScriptFile
->CurrentCommand
->Reset
) {
626 Info
->CurrentValue
= (CHAR16
*)Info
->Set
;
628 CurrentScriptFile
->CurrentCommand
->Reset
= FALSE
;
631 ShellStatus
= SHELL_UNSUPPORTED
;
634 if (ShellStatus
== SHELL_SUCCESS
) {
635 ASSERT(Info
!= NULL
);
636 if (Info
->Step
!= 0) {
638 // only advance if not the first pass
642 // sequence version of for loop...
644 Info
->Current
+= Info
->Step
;
647 TempString
= AllocateZeroPool(50*sizeof(CHAR16
));
648 UnicodeSPrint(TempString
, 50*sizeof(CHAR16
), L
"%d", Info
->Current
);
649 InternalUpdateAliasOnList(Info
->ReplacementName
, TempString
, &CurrentScriptFile
->SubstList
);
650 FreePool(TempString
);
652 if ((Info
->Step
> 0 && Info
->Current
> Info
->End
) || (Info
->Step
< 0 && Info
->Current
< Info
->End
)) {
653 CurrentScriptFile
->CurrentCommand
->Data
= NULL
;
655 // find the matching endfor (we're done with the loop)
657 if (!MoveToTag(GetNextNode
, L
"endfor", L
"for", NULL
, CurrentScriptFile
, TRUE
, FALSE
, FALSE
)) {
662 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
663 gShellLevel1HiiHandle
,
666 CurrentScriptFile
!=NULL
667 && CurrentScriptFile
->CurrentCommand
!=NULL
668 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
669 ShellStatus
= SHELL_DEVICE_ERROR
;
671 if (Info
->RemoveSubstAlias
) {
673 // remove item from list
675 InternalRemoveAliasFromList(Info
->ReplacementName
, &CurrentScriptFile
->SubstList
);
681 // Must be in 'in' version of for loop...
683 ASSERT(Info
->Set
!= NULL
);
684 if (Info
->CurrentValue
!= NULL
&& *Info
->CurrentValue
!= CHAR_NULL
) {
685 if (Info
->CurrentValue
[0] == L
' ') {
686 Info
->CurrentValue
++;
688 if (Info
->CurrentValue
[0] == L
'\"') {
689 Info
->CurrentValue
++;
692 // do the next one of the set
694 ASSERT(TempString
== NULL
);
695 TempString
= StrnCatGrow(&TempString
, NULL
, Info
->CurrentValue
, 0);
696 if (TempString
== NULL
) {
697 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
699 TempSpot
= StrStr(TempString
, L
"\" \"");
700 if (TempSpot
!= NULL
) {
701 *TempSpot
= CHAR_NULL
;
703 while (TempString
[StrLen(TempString
)-1] == L
'\"') {
704 TempString
[StrLen(TempString
)-1] = CHAR_NULL
;
706 InternalUpdateAliasOnList(Info
->ReplacementName
, TempString
, &CurrentScriptFile
->SubstList
);
707 Info
->CurrentValue
+= StrLen(TempString
);
709 if (Info
->CurrentValue
[0] == L
'\"') {
710 Info
->CurrentValue
++;
712 FreePool(TempString
);
715 CurrentScriptFile
->CurrentCommand
->Data
= NULL
;
717 // find the matching endfor (we're done with the loop)
719 if (!MoveToTag(GetNextNode
, L
"endfor", L
"for", NULL
, CurrentScriptFile
, TRUE
, FALSE
, FALSE
)) {
724 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
725 gShellLevel1HiiHandle
,
728 CurrentScriptFile
!=NULL
729 && CurrentScriptFile
->CurrentCommand
!=NULL
730 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
731 ShellStatus
= SHELL_DEVICE_ERROR
;
733 if (Info
->RemoveSubstAlias
) {
735 // remove item from list
737 InternalRemoveAliasFromList(Info
->ReplacementName
, &CurrentScriptFile
->SubstList
);
743 if (ArgSet
!= NULL
) {
746 return (ShellStatus
);