2 Main file for endfor and for shell level 1 functions.
4 Copyright (c) 2009 - 2012, 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>
19 Determine if a valid string is a valid number for the 'for' command.
21 @param[in] Number The pointer to the string representation of the number to test.
23 @retval TRUE The number is valid.
24 @retval FALSE The number is not valid.
28 ShellIsValidForNumber (
29 IN CONST CHAR16
*Number
32 if (Number
== NULL
|| *Number
== CHAR_NULL
) {
36 if (*Number
== L
'-') {
40 if (StrLen(Number
) == 0) {
44 if (StrLen(Number
) >= 7) {
45 if ((StrStr(Number
, L
" ") == NULL
) || (((StrStr(Number
, L
" ") != NULL
) && (StrStr(Number
, L
" ") - Number
) >= 7))) {
50 if (!ShellIsDecimalDigitCharacter(*Number
)) {
58 Function for 'endfor' command.
60 @param[in] ImageHandle Handle to the Image (NULL if Internal).
61 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
65 ShellCommandRunEndFor (
66 IN EFI_HANDLE ImageHandle
,
67 IN EFI_SYSTEM_TABLE
*SystemTable
72 SCRIPT_FILE
*CurrentScriptFile
;
74 Status
= CommandInit();
75 ASSERT_EFI_ERROR(Status
);
77 if (!gEfiShellProtocol
->BatchIsActive()) {
78 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"EndFor");
79 return (SHELL_UNSUPPORTED
);
82 if (gEfiShellParametersProtocol
->Argc
> 1) {
83 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel1HiiHandle
);
84 return (SHELL_INVALID_PARAMETER
);
87 Found
= MoveToTag(GetPreviousNode
, L
"for", L
"endfor", NULL
, ShellCommandGetCurrentScriptFile(), FALSE
, FALSE
, FALSE
);
90 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
95 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
96 gShellLevel1HiiHandle
,
99 CurrentScriptFile
!=NULL
100 && CurrentScriptFile
->CurrentCommand
!=NULL
101 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
102 return (SHELL_NOT_FOUND
);
104 return (SHELL_SUCCESS
);
112 CHAR16
*ReplacementName
;
113 CHAR16
*CurrentValue
;
114 BOOLEAN RemoveSubstAlias
;
117 #define SIZE_OF_SHELL_FOR_INFO OFFSET_OF (SHELL_FOR_INFO, Set)
118 #define SHELL_FOR_INFO_SIGNATURE SIGNATURE_32 ('S', 'F', 'I', 's')
121 Update the value of a given alias on the list. If the alias is not there then add it.
123 @param[in] Alias The alias to test for.
124 @param[in] CommandString The updated command string.
125 @param[in, out] List The list to search.
127 @retval EFI_SUCCESS The operation was completed successfully.
128 @retval EFI_OUT_OF_RESOURCES There was not enough free memory.
132 InternalUpdateAliasOnList(
133 IN CONST CHAR16
*Alias
,
134 IN CONST CHAR16
*CommandString
,
135 IN OUT LIST_ENTRY
*List
142 // assert for NULL parameter
144 ASSERT(Alias
!= NULL
);
147 // check for the Alias
149 for ( Node
= (ALIAS_LIST
*)GetFirstNode(List
), Found
= FALSE
150 ; !IsNull(List
, &Node
->Link
)
151 ; Node
= (ALIAS_LIST
*)GetNextNode(List
, &Node
->Link
)
153 ASSERT(Node
->CommandString
!= NULL
);
154 ASSERT(Node
->Alias
!= NULL
);
155 if (StrCmp(Node
->Alias
, Alias
)==0) {
156 FreePool(Node
->CommandString
);
157 Node
->CommandString
= NULL
;
158 Node
->CommandString
= StrnCatGrow(&Node
->CommandString
, NULL
, CommandString
, 0);
164 Node
= AllocateZeroPool(sizeof(ALIAS_LIST
));
166 return (EFI_OUT_OF_RESOURCES
);
168 ASSERT(Node
->Alias
== NULL
);
169 Node
->Alias
= StrnCatGrow(&Node
->Alias
, NULL
, Alias
, 0);
170 ASSERT(Node
->CommandString
== NULL
);
171 Node
->CommandString
= StrnCatGrow(&Node
->CommandString
, NULL
, CommandString
, 0);
172 InsertTailList(List
, &Node
->Link
);
174 return (EFI_SUCCESS
);
178 Find out if an alias is on the given list.
180 @param[in] Alias The alias to test for.
181 @param[in] List The list to search.
183 @retval TRUE The alias is on the list.
184 @retval FALSE The alias is not on the list.
188 InternalIsAliasOnList(
189 IN CONST CHAR16
*Alias
,
190 IN CONST LIST_ENTRY
*List
196 // assert for NULL parameter
198 ASSERT(Alias
!= NULL
);
201 // check for the Alias
203 for ( Node
= (ALIAS_LIST
*)GetFirstNode(List
)
204 ; !IsNull(List
, &Node
->Link
)
205 ; Node
= (ALIAS_LIST
*)GetNextNode(List
, &Node
->Link
)
207 ASSERT(Node
->CommandString
!= NULL
);
208 ASSERT(Node
->Alias
!= NULL
);
209 if (StrCmp(Node
->Alias
, Alias
)==0) {
217 Remove an alias from the given list.
219 @param[in] Alias The alias to remove.
220 @param[in, out] List The list to search.
224 InternalRemoveAliasFromList(
225 IN CONST CHAR16
*Alias
,
226 IN OUT LIST_ENTRY
*List
232 // assert for NULL parameter
234 ASSERT(Alias
!= NULL
);
237 // check for the Alias
239 for ( Node
= (ALIAS_LIST
*)GetFirstNode(List
)
240 ; !IsNull(List
, &Node
->Link
)
241 ; Node
= (ALIAS_LIST
*)GetNextNode(List
, &Node
->Link
)
243 ASSERT(Node
->CommandString
!= NULL
);
244 ASSERT(Node
->Alias
!= NULL
);
245 if (StrCmp(Node
->Alias
, Alias
)==0) {
246 RemoveEntryList(&Node
->Link
);
247 FreePool(Node
->Alias
);
248 FreePool(Node
->CommandString
);
257 Function to determine whether a string is decimal or hex representation of a number
258 and return the number converted from the string.
260 @param[in] String String representation of a number
263 @retval (UINTN)(-1) An error ocurred.
268 IN CONST CHAR16
*String
273 if (!EFI_ERROR(ShellConvertStringToUint64(String
, &RetVal
, FALSE
, TRUE
))) {
274 return ((UINTN
)RetVal
);
276 return ((UINTN
)(-1));
280 Function for 'for' command.
282 @param[in] ImageHandle Handle to the Image (NULL if Internal).
283 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
288 IN EFI_HANDLE ImageHandle
,
289 IN EFI_SYSTEM_TABLE
*SystemTable
293 SHELL_STATUS ShellStatus
;
294 SCRIPT_FILE
*CurrentScriptFile
;
296 CHAR16
*ArgSetWalker
;
299 SHELL_FOR_INFO
*Info
;
303 EFI_SHELL_FILE_INFO
*Node
;
304 EFI_SHELL_FILE_INFO
*FileList
;
309 ShellStatus
= SHELL_SUCCESS
;
315 // initialize the shell lib (we must be in non-auto-init...)
317 Status
= ShellInitialize();
318 ASSERT_EFI_ERROR(Status
);
320 Status
= CommandInit();
321 ASSERT_EFI_ERROR(Status
);
323 if (!gEfiShellProtocol
->BatchIsActive()) {
324 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"For");
325 return (SHELL_UNSUPPORTED
);
328 if (gEfiShellParametersProtocol
->Argc
< 4) {
329 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel1HiiHandle
);
330 return (SHELL_INVALID_PARAMETER
);
333 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
334 ASSERT(CurrentScriptFile
!= NULL
);
336 if (CurrentScriptFile
->CurrentCommand
->Data
== NULL
) {
340 // Make sure that an End exists.
342 if (!MoveToTag(GetNextNode
, L
"endfor", L
"for", NULL
, CurrentScriptFile
, TRUE
, TRUE
, FALSE
)) {
347 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
348 gShellLevel1HiiHandle
,
351 CurrentScriptFile
->CurrentCommand
!=NULL
352 ?CurrentScriptFile
->CurrentCommand
->Line
:0);
353 return (SHELL_DEVICE_ERROR
);
359 if (gEfiShellParametersProtocol
->Argv
[1][0] != L
'%' || gEfiShellParametersProtocol
->Argv
[1][2] != CHAR_NULL
360 ||!((gEfiShellParametersProtocol
->Argv
[1][1] >= L
'a' && gEfiShellParametersProtocol
->Argv
[1][1] <= L
'z')
361 ||(gEfiShellParametersProtocol
->Argv
[1][1] >= L
'A' && gEfiShellParametersProtocol
->Argv
[1][1] <= L
'Z'))
363 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_INV_VAR
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[1]);
364 return (SHELL_INVALID_PARAMETER
);
367 if (gUnicodeCollation
->StriColl(
370 gEfiShellParametersProtocol
->Argv
[2]) == 0) {
371 for (LoopVar
= 0x3 ; LoopVar
< gEfiShellParametersProtocol
->Argc
; LoopVar
++) {
372 ASSERT((ArgSet
== NULL
&& ArgSize
== 0) || (ArgSet
!= NULL
));
373 if (StrStr(gEfiShellParametersProtocol
->Argv
[LoopVar
], L
"*") != NULL
374 ||StrStr(gEfiShellParametersProtocol
->Argv
[LoopVar
], L
"?") != NULL
375 ||StrStr(gEfiShellParametersProtocol
->Argv
[LoopVar
], L
"[") != NULL
376 ||StrStr(gEfiShellParametersProtocol
->Argv
[LoopVar
], L
"]") != NULL
) {
378 Status
= ShellOpenFileMetaArg ((CHAR16
*)gEfiShellParametersProtocol
->Argv
[LoopVar
], EFI_FILE_MODE_READ
, &FileList
);
379 if (EFI_ERROR(Status
) || FileList
== NULL
|| IsListEmpty(&FileList
->Link
)) {
380 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
" \"", 0);
381 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, gEfiShellParametersProtocol
->Argv
[LoopVar
], 0);
382 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
"\"", 0);
384 for (Node
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&FileList
->Link
)
385 ; !IsNull(&FileList
->Link
, &Node
->Link
)
386 ; Node
= (EFI_SHELL_FILE_INFO
*)GetNextNode(&FileList
->Link
, &Node
->Link
)
388 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
" \"", 0);
389 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, Node
->FullName
, 0);
390 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
"\"", 0);
392 ShellCloseFileMetaArg(&FileList
);
395 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
" \"", 0);
396 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, gEfiShellParametersProtocol
->Argv
[LoopVar
], 0);
397 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
"\"", 0);
400 if (ArgSet
== NULL
) {
401 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
404 // set up for an 'in' for loop
406 NewSize
= StrSize(ArgSet
);
407 NewSize
+= sizeof(SHELL_FOR_INFO
)+StrSize(gEfiShellParametersProtocol
->Argv
[1]);
408 Info
= AllocateZeroPool(NewSize
);
409 ASSERT(Info
!= NULL
);
410 Info
->Signature
= SHELL_FOR_INFO_SIGNATURE
;
411 CopyMem(Info
->Set
, ArgSet
, StrSize(ArgSet
));
412 NewSize
= StrSize(gEfiShellParametersProtocol
->Argv
[1]);
413 CopyMem(Info
->Set
+(StrSize(ArgSet
)/sizeof(Info
->Set
[0])), gEfiShellParametersProtocol
->Argv
[1], NewSize
);
414 Info
->ReplacementName
= Info
->Set
+StrSize(ArgSet
)/sizeof(Info
->Set
[0]);
415 Info
->CurrentValue
= (CHAR16
*)Info
->Set
;
420 if (InternalIsAliasOnList(Info
->ReplacementName
, &CurrentScriptFile
->SubstList
)) {
421 Info
->RemoveSubstAlias
= FALSE
;
423 Info
->RemoveSubstAlias
= TRUE
;
425 CurrentScriptFile
->CurrentCommand
->Data
= Info
;
427 } else if (gUnicodeCollation
->StriColl(
430 gEfiShellParametersProtocol
->Argv
[2]) == 0) {
431 for (LoopVar
= 0x3 ; LoopVar
< gEfiShellParametersProtocol
->Argc
; LoopVar
++) {
432 ASSERT((ArgSet
== NULL
&& ArgSize
== 0) || (ArgSet
!= NULL
));
433 if (ArgSet
== NULL
) {
434 // ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0);
436 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
" ", 0);
438 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, gEfiShellParametersProtocol
->Argv
[LoopVar
], 0);
439 // ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" ", 0);
441 if (ArgSet
== NULL
) {
442 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
445 // set up for a 'run' for loop
447 Info
= AllocateZeroPool(sizeof(SHELL_FOR_INFO
)+StrSize(gEfiShellParametersProtocol
->Argv
[1]));
448 ASSERT(Info
!= NULL
);
449 Info
->Signature
= SHELL_FOR_INFO_SIGNATURE
;
450 CopyMem(Info
->Set
, gEfiShellParametersProtocol
->Argv
[1], StrSize(gEfiShellParametersProtocol
->Argv
[1]));
451 Info
->ReplacementName
= Info
->Set
;
452 Info
->CurrentValue
= NULL
;
453 ArgSetWalker
= ArgSet
;
454 if (ArgSetWalker
[0] != L
'(') {
459 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
460 gShellLevel1HiiHandle
,
462 CurrentScriptFile
!=NULL
463 && CurrentScriptFile
->CurrentCommand
!=NULL
464 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
465 ShellStatus
= SHELL_INVALID_PARAMETER
;
467 TempSpot
= StrStr(ArgSetWalker
, L
")");
468 if (TempSpot
!= NULL
) {
469 TempString
= TempSpot
+1;
470 if (*(TempString
) != CHAR_NULL
) {
471 while(TempString
!= NULL
&& *TempString
== L
' ') {
474 if (StrLen(TempString
) > 0) {
479 if (TempSpot
== NULL
) {
484 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
485 gShellLevel1HiiHandle
,
486 CurrentScriptFile
!=NULL
487 && CurrentScriptFile
->CurrentCommand
!=NULL
488 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
489 ShellStatus
= SHELL_INVALID_PARAMETER
;
491 *TempSpot
= CHAR_NULL
;
493 while (ArgSetWalker
!= NULL
&& ArgSetWalker
[0] == L
' ') {
496 if (!ShellIsValidForNumber(ArgSetWalker
)) {
501 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
502 gShellLevel1HiiHandle
,
504 CurrentScriptFile
!=NULL
505 && CurrentScriptFile
->CurrentCommand
!=NULL
506 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
507 ShellStatus
= SHELL_INVALID_PARAMETER
;
509 if (ArgSetWalker
[0] == L
'-') {
510 Info
->Current
= 0 - (INTN
)ReturnUintn(ArgSetWalker
+1);
512 Info
->Current
= (INTN
)ReturnUintn(ArgSetWalker
);
514 ArgSetWalker
= StrStr(ArgSetWalker
, L
" ");
515 while (ArgSetWalker
!= NULL
&& ArgSetWalker
[0] == L
' ') {
518 if (ArgSetWalker
== NULL
|| *ArgSetWalker
== CHAR_NULL
|| !ShellIsValidForNumber(ArgSetWalker
)){
523 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
524 gShellLevel1HiiHandle
,
526 CurrentScriptFile
!=NULL
527 && CurrentScriptFile
->CurrentCommand
!=NULL
528 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
529 ShellStatus
= SHELL_INVALID_PARAMETER
;
531 if (ArgSetWalker
[0] == L
'-') {
532 Info
->End
= 0 - (INTN
)ReturnUintn(ArgSetWalker
+1);
534 Info
->End
= (INTN
)ReturnUintn(ArgSetWalker
);
536 if (Info
->Current
< Info
->End
) {
542 ArgSetWalker
= StrStr(ArgSetWalker
, L
" ");
543 while (ArgSetWalker
!= NULL
&& ArgSetWalker
[0] == L
' ') {
546 if (ArgSetWalker
!= NULL
&& *ArgSetWalker
!= CHAR_NULL
) {
547 if (ArgSetWalker
== NULL
|| *ArgSetWalker
== CHAR_NULL
|| !ShellIsValidForNumber(ArgSetWalker
)){
552 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
553 gShellLevel1HiiHandle
,
555 CurrentScriptFile
!=NULL
556 && CurrentScriptFile
->CurrentCommand
!=NULL
557 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
558 ShellStatus
= SHELL_INVALID_PARAMETER
;
560 if (*ArgSetWalker
== L
')') {
561 ASSERT(Info
->Step
== 1 || Info
->Step
== -1);
563 if (ArgSetWalker
[0] == L
'-') {
564 Info
->Step
= 0 - (INTN
)ReturnUintn(ArgSetWalker
+1);
566 Info
->Step
= (INTN
)ReturnUintn(ArgSetWalker
);
569 if (StrStr(ArgSetWalker
, L
" ") != NULL
) {
574 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
575 gShellLevel1HiiHandle
,
577 CurrentScriptFile
!=NULL
578 && CurrentScriptFile
->CurrentCommand
!=NULL
579 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
580 ShellStatus
= SHELL_INVALID_PARAMETER
;
590 if (ShellStatus
== SHELL_SUCCESS
) {
591 if (InternalIsAliasOnList(Info
->ReplacementName
, &CurrentScriptFile
->SubstList
)) {
592 Info
->RemoveSubstAlias
= FALSE
;
594 Info
->RemoveSubstAlias
= TRUE
;
597 if (CurrentScriptFile
->CurrentCommand
!= NULL
) {
598 CurrentScriptFile
->CurrentCommand
->Data
= Info
;
606 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
607 gShellLevel1HiiHandle
,
609 CurrentScriptFile
!=NULL
610 && CurrentScriptFile
->CurrentCommand
!=NULL
611 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
612 ShellStatus
= SHELL_INVALID_PARAMETER
;
616 // These need to be NULL since they are used to determine if this is the first pass later on...
618 ASSERT(ArgSetWalker
== NULL
);
619 ASSERT(ArgSet
== NULL
);
622 if (CurrentScriptFile
!= NULL
&& CurrentScriptFile
->CurrentCommand
!= NULL
) {
623 Info
= (SHELL_FOR_INFO
*)CurrentScriptFile
->CurrentCommand
->Data
;
624 if (CurrentScriptFile
->CurrentCommand
->Reset
) {
625 Info
->CurrentValue
= (CHAR16
*)Info
->Set
;
627 CurrentScriptFile
->CurrentCommand
->Reset
= FALSE
;
630 ShellStatus
= SHELL_UNSUPPORTED
;
633 if (ShellStatus
== SHELL_SUCCESS
) {
634 ASSERT(Info
!= NULL
);
635 if (Info
->Step
!= 0) {
637 // only advance if not the first pass
641 // sequence version of for loop...
643 Info
->Current
+= Info
->Step
;
646 TempString
= AllocateZeroPool(50*sizeof(CHAR16
));
647 UnicodeSPrint(TempString
, 50*sizeof(CHAR16
), L
"%d", Info
->Current
);
648 InternalUpdateAliasOnList(Info
->ReplacementName
, TempString
, &CurrentScriptFile
->SubstList
);
649 FreePool(TempString
);
651 if ((Info
->Step
> 0 && Info
->Current
> Info
->End
) || (Info
->Step
< 0 && Info
->Current
< Info
->End
)) {
652 CurrentScriptFile
->CurrentCommand
->Data
= NULL
;
654 // find the matching endfor (we're done with the loop)
656 if (!MoveToTag(GetNextNode
, L
"endfor", L
"for", NULL
, CurrentScriptFile
, TRUE
, FALSE
, FALSE
)) {
661 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
662 gShellLevel1HiiHandle
,
665 CurrentScriptFile
!=NULL
666 && CurrentScriptFile
->CurrentCommand
!=NULL
667 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
668 ShellStatus
= SHELL_DEVICE_ERROR
;
670 if (Info
->RemoveSubstAlias
) {
672 // remove item from list
674 InternalRemoveAliasFromList(Info
->ReplacementName
, &CurrentScriptFile
->SubstList
);
680 // Must be in 'in' version of for loop...
682 ASSERT(Info
->Set
!= NULL
);
683 if (Info
->CurrentValue
!= NULL
&& *Info
->CurrentValue
!= CHAR_NULL
) {
684 if (Info
->CurrentValue
[0] == L
' ') {
685 Info
->CurrentValue
++;
687 if (Info
->CurrentValue
[0] == L
'\"') {
688 Info
->CurrentValue
++;
691 // do the next one of the set
693 ASSERT(TempString
== NULL
);
694 TempString
= StrnCatGrow(&TempString
, NULL
, Info
->CurrentValue
, 0);
695 if (TempString
== NULL
) {
696 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
698 TempSpot
= StrStr(TempString
, L
"\" \"");
699 if (TempSpot
!= NULL
) {
700 *TempSpot
= CHAR_NULL
;
702 while (TempString
[StrLen(TempString
)-1] == L
'\"') {
703 TempString
[StrLen(TempString
)-1] = CHAR_NULL
;
705 InternalUpdateAliasOnList(Info
->ReplacementName
, TempString
, &CurrentScriptFile
->SubstList
);
706 Info
->CurrentValue
+= StrLen(TempString
);
708 if (Info
->CurrentValue
[0] == L
'\"') {
709 Info
->CurrentValue
++;
711 while (Info
->CurrentValue
[0] == L
' ') {
712 Info
->CurrentValue
++;
714 if (Info
->CurrentValue
[0] == L
'\"') {
715 Info
->CurrentValue
++;
717 FreePool(TempString
);
720 CurrentScriptFile
->CurrentCommand
->Data
= NULL
;
722 // find the matching endfor (we're done with the loop)
724 if (!MoveToTag(GetNextNode
, L
"endfor", L
"for", NULL
, CurrentScriptFile
, TRUE
, FALSE
, FALSE
)) {
729 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
730 gShellLevel1HiiHandle
,
733 CurrentScriptFile
!=NULL
734 && CurrentScriptFile
->CurrentCommand
!=NULL
735 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
736 ShellStatus
= SHELL_DEVICE_ERROR
;
738 if (Info
->RemoveSubstAlias
) {
740 // remove item from list
742 InternalRemoveAliasFromList(Info
->ReplacementName
, &CurrentScriptFile
->SubstList
);
748 if (ArgSet
!= NULL
) {
751 return (ShellStatus
);