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 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "UefiShellLevel1CommandsLib.h"
11 #include <Library/PrintLib.h>
14 Determine if a valid string is a valid number for the 'for' command.
16 @param[in] Number The pointer to the string representation of the number to test.
18 @retval TRUE The number is valid.
19 @retval FALSE The number is not valid.
22 ShellIsValidForNumber (
23 IN CONST CHAR16
*Number
26 if ((Number
== NULL
) || (*Number
== CHAR_NULL
)) {
30 if (*Number
== L
'-') {
34 if (StrLen (Number
) == 0) {
38 if (StrLen (Number
) >= 7) {
39 if ((StrStr (Number
, L
" ") == NULL
) || (((StrStr (Number
, L
" ") != NULL
) && ((StrStr (Number
, L
" ") - Number
) >= 7)))) {
44 if (!ShellIsDecimalDigitCharacter (*Number
)) {
52 Function for 'endfor' command.
54 @param[in] ImageHandle Handle to the Image (NULL if Internal).
55 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
59 ShellCommandRunEndFor (
60 IN EFI_HANDLE ImageHandle
,
61 IN EFI_SYSTEM_TABLE
*SystemTable
66 SCRIPT_FILE
*CurrentScriptFile
;
68 Status
= CommandInit ();
69 ASSERT_EFI_ERROR (Status
);
71 if (!gEfiShellProtocol
->BatchIsActive ()) {
72 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"endfor");
73 return (SHELL_UNSUPPORTED
);
76 if (gEfiShellParametersProtocol
->Argc
> 1) {
77 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel1HiiHandle
, L
"endfor");
78 return (SHELL_INVALID_PARAMETER
);
81 Found
= MoveToTag (GetPreviousNode
, L
"for", L
"endfor", NULL
, ShellCommandGetCurrentScriptFile (), FALSE
, FALSE
, FALSE
);
84 CurrentScriptFile
= ShellCommandGetCurrentScriptFile ();
89 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
90 gShellLevel1HiiHandle
,
93 CurrentScriptFile
!= NULL
94 && CurrentScriptFile
->CurrentCommand
!= NULL
95 ? CurrentScriptFile
->CurrentCommand
->Line
: 0
97 return (SHELL_NOT_FOUND
);
100 return (SHELL_SUCCESS
);
108 CHAR16
*ReplacementName
;
109 CHAR16
*CurrentValue
;
110 BOOLEAN RemoveSubstAlias
;
113 #define SIZE_OF_SHELL_FOR_INFO OFFSET_OF (SHELL_FOR_INFO, Set)
114 #define SHELL_FOR_INFO_SIGNATURE SIGNATURE_32 ('S', 'F', 'I', 's')
117 Update the value of a given alias on the list. If the alias is not there then add it.
119 @param[in] Alias The alias to test for.
120 @param[in] CommandString The updated command string.
121 @param[in, out] List The list to search.
123 @retval EFI_SUCCESS The operation was completed successfully.
124 @retval EFI_OUT_OF_RESOURCES There was not enough free memory.
127 InternalUpdateAliasOnList (
128 IN CONST CHAR16
*Alias
,
129 IN CONST CHAR16
*CommandString
,
130 IN OUT LIST_ENTRY
*List
137 // assert for NULL parameter
139 ASSERT (Alias
!= NULL
);
142 // check for the Alias
144 for ( Node
= (ALIAS_LIST
*)GetFirstNode (List
), Found
= FALSE
145 ; !IsNull (List
, &Node
->Link
)
146 ; Node
= (ALIAS_LIST
*)GetNextNode (List
, &Node
->Link
)
149 ASSERT (Node
->CommandString
!= NULL
);
150 ASSERT (Node
->Alias
!= NULL
);
151 if (StrCmp (Node
->Alias
, Alias
) == 0) {
152 FreePool (Node
->CommandString
);
153 Node
->CommandString
= NULL
;
154 Node
->CommandString
= StrnCatGrow (&Node
->CommandString
, NULL
, CommandString
, 0);
161 Node
= AllocateZeroPool (sizeof (ALIAS_LIST
));
163 return (EFI_OUT_OF_RESOURCES
);
166 ASSERT (Node
->Alias
== NULL
);
167 Node
->Alias
= StrnCatGrow (&Node
->Alias
, NULL
, Alias
, 0);
168 ASSERT (Node
->CommandString
== NULL
);
169 Node
->CommandString
= StrnCatGrow (&Node
->CommandString
, NULL
, CommandString
, 0);
170 InsertTailList (List
, &Node
->Link
);
173 return (EFI_SUCCESS
);
177 Find out if an alias is on the given list.
179 @param[in] Alias The alias to test for.
180 @param[in] List The list to search.
182 @retval TRUE The alias is on the list.
183 @retval FALSE The alias is not on the list.
186 InternalIsAliasOnList (
187 IN CONST CHAR16
*Alias
,
188 IN CONST LIST_ENTRY
*List
194 // assert for NULL parameter
196 ASSERT (Alias
!= NULL
);
199 // check for the Alias
201 for ( Node
= (ALIAS_LIST
*)GetFirstNode (List
)
202 ; !IsNull (List
, &Node
->Link
)
203 ; Node
= (ALIAS_LIST
*)GetNextNode (List
, &Node
->Link
)
206 ASSERT (Node
->CommandString
!= NULL
);
207 ASSERT (Node
->Alias
!= NULL
);
208 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.
223 InternalRemoveAliasFromList (
224 IN CONST CHAR16
*Alias
,
225 IN OUT LIST_ENTRY
*List
231 // assert for NULL parameter
233 ASSERT (Alias
!= NULL
);
236 // check for the Alias
238 for ( Node
= (ALIAS_LIST
*)GetFirstNode (List
)
239 ; !IsNull (List
, &Node
->Link
)
240 ; 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
);
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.
268 IN CONST CHAR16
*String
273 if (!EFI_ERROR (ShellConvertStringToUint64 (String
, &RetVal
, FALSE
, TRUE
))) {
274 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
356 return (SHELL_DEVICE_ERROR
);
362 if ( (gEfiShellParametersProtocol
->Argv
[1][0] != L
'%') || (gEfiShellParametersProtocol
->Argv
[1][2] != CHAR_NULL
)
363 || !( ((gEfiShellParametersProtocol
->Argv
[1][1] >= L
'a') && (gEfiShellParametersProtocol
->Argv
[1][1] <= L
'z'))
364 || ((gEfiShellParametersProtocol
->Argv
[1][1] >= L
'A') && (gEfiShellParametersProtocol
->Argv
[1][1] <= L
'Z')))
367 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_INV_VAR
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[1]);
368 return (SHELL_INVALID_PARAMETER
);
371 if (gUnicodeCollation
->StriColl (
374 gEfiShellParametersProtocol
->Argv
[2]
377 for (LoopVar
= 0x3; LoopVar
< gEfiShellParametersProtocol
->Argc
; LoopVar
++) {
378 ASSERT ((ArgSet
== NULL
&& ArgSize
== 0) || (ArgSet
!= NULL
));
379 if ( (StrStr (gEfiShellParametersProtocol
->Argv
[LoopVar
], L
"*") != NULL
)
380 || (StrStr (gEfiShellParametersProtocol
->Argv
[LoopVar
], L
"?") != NULL
)
381 || (StrStr (gEfiShellParametersProtocol
->Argv
[LoopVar
], L
"[") != NULL
)
382 || (StrStr (gEfiShellParametersProtocol
->Argv
[LoopVar
], L
"]") != NULL
))
385 Status
= ShellOpenFileMetaArg ((CHAR16
*)gEfiShellParametersProtocol
->Argv
[LoopVar
], EFI_FILE_MODE_READ
, &FileList
);
386 if (EFI_ERROR (Status
) || (FileList
== NULL
) || IsListEmpty (&FileList
->Link
)) {
387 ArgSet
= StrnCatGrow (&ArgSet
, &ArgSize
, L
" \"", 0);
388 ArgSet
= StrnCatGrow (&ArgSet
, &ArgSize
, gEfiShellParametersProtocol
->Argv
[LoopVar
], 0);
389 ArgSet
= StrnCatGrow (&ArgSet
, &ArgSize
, L
"\"", 0);
391 for (Node
= (EFI_SHELL_FILE_INFO
*)GetFirstNode (&FileList
->Link
)
392 ; !IsNull (&FileList
->Link
, &Node
->Link
)
393 ; Node
= (EFI_SHELL_FILE_INFO
*)GetNextNode (&FileList
->Link
, &Node
->Link
)
396 ArgSet
= StrnCatGrow (&ArgSet
, &ArgSize
, L
" \"", 0);
397 ArgSet
= StrnCatGrow (&ArgSet
, &ArgSize
, Node
->FullName
, 0);
398 ArgSet
= StrnCatGrow (&ArgSet
, &ArgSize
, L
"\"", 0);
401 ShellCloseFileMetaArg (&FileList
);
404 Parameter
= gEfiShellParametersProtocol
->Argv
[LoopVar
];
405 if ((Parameter
[0] == L
'\"') && (Parameter
[StrLen (Parameter
)-1] == L
'\"')) {
406 ArgSet
= StrnCatGrow (&ArgSet
, &ArgSize
, L
" ", 0);
407 ArgSet
= StrnCatGrow (&ArgSet
, &ArgSize
, Parameter
, 0);
409 ArgSet
= StrnCatGrow (&ArgSet
, &ArgSize
, L
" \"", 0);
410 ArgSet
= StrnCatGrow (&ArgSet
, &ArgSize
, Parameter
, 0);
411 ArgSet
= StrnCatGrow (&ArgSet
, &ArgSize
, L
"\"", 0);
416 if (ArgSet
== NULL
) {
417 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
420 // set up for an 'in' for loop
422 NewSize
= StrSize (ArgSet
);
423 NewSize
+= sizeof (SHELL_FOR_INFO
)+StrSize (gEfiShellParametersProtocol
->Argv
[1]);
424 Info
= AllocateZeroPool (NewSize
);
427 return SHELL_OUT_OF_RESOURCES
;
430 Info
->Signature
= SHELL_FOR_INFO_SIGNATURE
;
431 CopyMem (Info
->Set
, ArgSet
, StrSize (ArgSet
));
432 NewSize
= StrSize (gEfiShellParametersProtocol
->Argv
[1]);
433 CopyMem (Info
->Set
+(StrSize (ArgSet
)/sizeof (Info
->Set
[0])), gEfiShellParametersProtocol
->Argv
[1], NewSize
);
434 Info
->ReplacementName
= Info
->Set
+StrSize (ArgSet
)/sizeof (Info
->Set
[0]);
435 Info
->CurrentValue
= (CHAR16
*)Info
->Set
;
440 if (InternalIsAliasOnList (Info
->ReplacementName
, &CurrentScriptFile
->SubstList
)) {
441 Info
->RemoveSubstAlias
= FALSE
;
443 Info
->RemoveSubstAlias
= TRUE
;
446 CurrentScriptFile
->CurrentCommand
->Data
= Info
;
448 } else if (gUnicodeCollation
->StriColl (
451 gEfiShellParametersProtocol
->Argv
[2]
454 for (LoopVar
= 0x3; LoopVar
< gEfiShellParametersProtocol
->Argc
; LoopVar
++) {
455 ASSERT ((ArgSet
== NULL
&& ArgSize
== 0) || (ArgSet
!= NULL
));
456 if ((StrStr (gEfiShellParametersProtocol
->Argv
[LoopVar
], L
")") != NULL
) &&
457 ((LoopVar
+ 1) < gEfiShellParametersProtocol
->Argc
)
460 return (SHELL_INVALID_PARAMETER
);
463 if (ArgSet
== NULL
) {
464 // ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0);
466 ArgSet
= StrnCatGrow (&ArgSet
, &ArgSize
, L
" ", 0);
469 ArgSet
= StrnCatGrow (&ArgSet
, &ArgSize
, gEfiShellParametersProtocol
->Argv
[LoopVar
], 0);
470 // ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" ", 0);
473 if (ArgSet
== NULL
) {
474 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
477 // set up for a 'run' for loop
479 Info
= AllocateZeroPool (sizeof (SHELL_FOR_INFO
)+StrSize (gEfiShellParametersProtocol
->Argv
[1]));
482 return SHELL_OUT_OF_RESOURCES
;
485 Info
->Signature
= SHELL_FOR_INFO_SIGNATURE
;
486 CopyMem (Info
->Set
, gEfiShellParametersProtocol
->Argv
[1], StrSize (gEfiShellParametersProtocol
->Argv
[1]));
487 Info
->ReplacementName
= Info
->Set
;
488 Info
->CurrentValue
= NULL
;
489 ArgSetWalker
= ArgSet
;
490 if (ArgSetWalker
[0] != L
'(') {
495 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
496 gShellLevel1HiiHandle
,
498 CurrentScriptFile
->CurrentCommand
->Line
500 ShellStatus
= SHELL_INVALID_PARAMETER
;
502 TempSpot
= StrStr (ArgSetWalker
, L
")");
503 if (TempSpot
!= NULL
) {
504 TempString
= TempSpot
+1;
505 if (*(TempString
) != CHAR_NULL
) {
506 while (TempString
!= NULL
&& *TempString
== L
' ') {
510 if (StrLen (TempString
) > 0) {
516 if (TempSpot
== NULL
) {
521 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
522 gShellLevel1HiiHandle
,
523 CurrentScriptFile
->CurrentCommand
->Line
525 ShellStatus
= SHELL_INVALID_PARAMETER
;
527 *TempSpot
= CHAR_NULL
;
529 while (ArgSetWalker
!= NULL
&& ArgSetWalker
[0] == L
' ') {
533 if (!ShellIsValidForNumber (ArgSetWalker
)) {
538 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
539 gShellLevel1HiiHandle
,
541 CurrentScriptFile
->CurrentCommand
->Line
543 ShellStatus
= SHELL_INVALID_PARAMETER
;
545 if (ArgSetWalker
[0] == L
'-') {
546 Info
->Current
= 0 - (INTN
)ReturnUintn (ArgSetWalker
+1);
548 Info
->Current
= (INTN
)ReturnUintn (ArgSetWalker
);
551 ArgSetWalker
= StrStr (ArgSetWalker
, L
" ");
552 while (ArgSetWalker
!= NULL
&& ArgSetWalker
[0] == L
' ') {
556 if ((ArgSetWalker
== NULL
) || (*ArgSetWalker
== CHAR_NULL
) || !ShellIsValidForNumber (ArgSetWalker
)) {
561 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
562 gShellLevel1HiiHandle
,
564 CurrentScriptFile
->CurrentCommand
->Line
566 ShellStatus
= SHELL_INVALID_PARAMETER
;
568 if (ArgSetWalker
[0] == L
'-') {
569 Info
->End
= 0 - (INTN
)ReturnUintn (ArgSetWalker
+1);
571 Info
->End
= (INTN
)ReturnUintn (ArgSetWalker
);
574 if (Info
->Current
< Info
->End
) {
580 ArgSetWalker
= StrStr (ArgSetWalker
, L
" ");
581 while (ArgSetWalker
!= NULL
&& ArgSetWalker
[0] == L
' ') {
585 if ((ArgSetWalker
!= NULL
) && (*ArgSetWalker
!= CHAR_NULL
)) {
586 if ((ArgSetWalker
== NULL
) || (*ArgSetWalker
== CHAR_NULL
) || !ShellIsValidForNumber (ArgSetWalker
)) {
591 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
592 gShellLevel1HiiHandle
,
594 CurrentScriptFile
->CurrentCommand
->Line
596 ShellStatus
= SHELL_INVALID_PARAMETER
;
598 if (*ArgSetWalker
== L
')') {
599 ASSERT (Info
->Step
== 1 || Info
->Step
== -1);
601 if (ArgSetWalker
[0] == L
'-') {
602 Info
->Step
= 0 - (INTN
)ReturnUintn (ArgSetWalker
+1);
604 Info
->Step
= (INTN
)ReturnUintn (ArgSetWalker
);
607 if (StrStr (ArgSetWalker
, L
" ") != NULL
) {
612 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
613 gShellLevel1HiiHandle
,
615 CurrentScriptFile
->CurrentCommand
->Line
617 ShellStatus
= SHELL_INVALID_PARAMETER
;
627 if (ShellStatus
== SHELL_SUCCESS
) {
628 if (InternalIsAliasOnList (Info
->ReplacementName
, &CurrentScriptFile
->SubstList
)) {
629 Info
->RemoveSubstAlias
= FALSE
;
631 Info
->RemoveSubstAlias
= TRUE
;
635 if (CurrentScriptFile
->CurrentCommand
!= NULL
) {
636 CurrentScriptFile
->CurrentCommand
->Data
= Info
;
644 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
645 gShellLevel1HiiHandle
,
647 CurrentScriptFile
!= NULL
648 && CurrentScriptFile
->CurrentCommand
!= NULL
649 ? CurrentScriptFile
->CurrentCommand
->Line
: 0
651 ShellStatus
= SHELL_INVALID_PARAMETER
;
655 // These need to be NULL since they are used to determine if this is the first pass later on...
657 ASSERT (ArgSetWalker
== NULL
);
658 ASSERT (ArgSet
== NULL
);
661 if ((CurrentScriptFile
!= NULL
) && (CurrentScriptFile
->CurrentCommand
!= NULL
)) {
662 Info
= (SHELL_FOR_INFO
*)CurrentScriptFile
->CurrentCommand
->Data
;
663 if (CurrentScriptFile
->CurrentCommand
->Reset
) {
665 Info
->CurrentValue
= (CHAR16
*)Info
->Set
;
669 CurrentScriptFile
->CurrentCommand
->Reset
= FALSE
;
672 ShellStatus
= SHELL_UNSUPPORTED
;
676 if (ShellStatus
== SHELL_SUCCESS
) {
677 ASSERT (Info
!= NULL
);
678 if (Info
->Step
!= 0) {
680 // only advance if not the first pass
684 // sequence version of for loop...
686 Info
->Current
+= Info
->Step
;
689 TempString
= AllocateZeroPool (50*sizeof (CHAR16
));
690 UnicodeSPrint (TempString
, 50*sizeof (CHAR16
), L
"%d", Info
->Current
);
691 InternalUpdateAliasOnList (Info
->ReplacementName
, TempString
, &CurrentScriptFile
->SubstList
);
692 FreePool (TempString
);
694 if (((Info
->Step
> 0) && (Info
->Current
> Info
->End
)) || ((Info
->Step
< 0) && (Info
->Current
< Info
->End
))) {
695 CurrentScriptFile
->CurrentCommand
->Data
= NULL
;
697 // find the matching endfor (we're done with the loop)
699 if (!MoveToTag (GetNextNode
, L
"endfor", L
"for", NULL
, CurrentScriptFile
, TRUE
, FALSE
, FALSE
)) {
704 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
705 gShellLevel1HiiHandle
,
708 CurrentScriptFile
!= NULL
709 && CurrentScriptFile
->CurrentCommand
!= NULL
710 ? CurrentScriptFile
->CurrentCommand
->Line
: 0
712 ShellStatus
= SHELL_DEVICE_ERROR
;
715 if (Info
->RemoveSubstAlias
) {
717 // remove item from list
719 InternalRemoveAliasFromList (Info
->ReplacementName
, &CurrentScriptFile
->SubstList
);
726 // Must be in 'in' version of for loop...
728 ASSERT (Info
->Set
!= NULL
);
729 if ((Info
->CurrentValue
!= NULL
) && (*Info
->CurrentValue
!= CHAR_NULL
)) {
730 if (Info
->CurrentValue
[0] == L
' ') {
731 Info
->CurrentValue
++;
734 if (Info
->CurrentValue
[0] == L
'\"') {
735 Info
->CurrentValue
++;
739 // do the next one of the set
741 ASSERT (TempString
== NULL
);
742 TempString
= StrnCatGrow (&TempString
, NULL
, Info
->CurrentValue
, 0);
743 if (TempString
== NULL
) {
744 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
746 TempSpot
= StrStr (TempString
, L
"\" \"");
747 if (TempSpot
!= NULL
) {
748 *TempSpot
= CHAR_NULL
;
751 while (TempString
[StrLen (TempString
)-1] == L
'\"') {
752 TempString
[StrLen (TempString
)-1] = CHAR_NULL
;
755 InternalUpdateAliasOnList (Info
->ReplacementName
, TempString
, &CurrentScriptFile
->SubstList
);
756 Info
->CurrentValue
+= StrLen (TempString
);
758 if (Info
->CurrentValue
[0] == L
'\"') {
759 Info
->CurrentValue
++;
762 FreePool (TempString
);
765 CurrentScriptFile
->CurrentCommand
->Data
= NULL
;
767 // find the matching endfor (we're done with the loop)
769 if (!MoveToTag (GetNextNode
, L
"endfor", L
"for", NULL
, CurrentScriptFile
, TRUE
, FALSE
, FALSE
)) {
774 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
775 gShellLevel1HiiHandle
,
778 CurrentScriptFile
!= NULL
779 && CurrentScriptFile
->CurrentCommand
!= NULL
780 ? CurrentScriptFile
->CurrentCommand
->Line
: 0
782 ShellStatus
= SHELL_DEVICE_ERROR
;
785 if (Info
->RemoveSubstAlias
) {
787 // remove item from list
789 InternalRemoveAliasFromList (Info
->ReplacementName
, &CurrentScriptFile
->SubstList
);
797 if (ArgSet
!= NULL
) {
801 return (ShellStatus
);