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 - 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>
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.
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
, L
"endfor");
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.
131 InternalUpdateAliasOnList(
132 IN CONST CHAR16
*Alias
,
133 IN CONST CHAR16
*CommandString
,
134 IN OUT LIST_ENTRY
*List
141 // assert for NULL parameter
143 ASSERT(Alias
!= NULL
);
146 // check for the Alias
148 for ( Node
= (ALIAS_LIST
*)GetFirstNode(List
), Found
= FALSE
149 ; !IsNull(List
, &Node
->Link
)
150 ; Node
= (ALIAS_LIST
*)GetNextNode(List
, &Node
->Link
)
152 ASSERT(Node
->CommandString
!= NULL
);
153 ASSERT(Node
->Alias
!= NULL
);
154 if (StrCmp(Node
->Alias
, Alias
)==0) {
155 FreePool(Node
->CommandString
);
156 Node
->CommandString
= NULL
;
157 Node
->CommandString
= StrnCatGrow(&Node
->CommandString
, NULL
, CommandString
, 0);
163 Node
= AllocateZeroPool(sizeof(ALIAS_LIST
));
165 return (EFI_OUT_OF_RESOURCES
);
167 ASSERT(Node
->Alias
== NULL
);
168 Node
->Alias
= StrnCatGrow(&Node
->Alias
, NULL
, Alias
, 0);
169 ASSERT(Node
->CommandString
== NULL
);
170 Node
->CommandString
= StrnCatGrow(&Node
->CommandString
, NULL
, CommandString
, 0);
171 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
)
205 ASSERT(Node
->CommandString
!= NULL
);
206 ASSERT(Node
->Alias
!= NULL
);
207 if (StrCmp(Node
->Alias
, Alias
)==0) {
215 Remove an alias from the given list.
217 @param[in] Alias The alias to remove.
218 @param[in, out] List The list to search.
221 InternalRemoveAliasFromList(
222 IN CONST CHAR16
*Alias
,
223 IN OUT LIST_ENTRY
*List
229 // assert for NULL parameter
231 ASSERT(Alias
!= NULL
);
234 // check for the Alias
236 for ( Node
= (ALIAS_LIST
*)GetFirstNode(List
)
237 ; !IsNull(List
, &Node
->Link
)
238 ; Node
= (ALIAS_LIST
*)GetNextNode(List
, &Node
->Link
)
240 ASSERT(Node
->CommandString
!= NULL
);
241 ASSERT(Node
->Alias
!= NULL
);
242 if (StrCmp(Node
->Alias
, Alias
)==0) {
243 RemoveEntryList(&Node
->Link
);
244 FreePool(Node
->Alias
);
245 FreePool(Node
->CommandString
);
254 Function to determine whether a string is decimal or hex representation of a number
255 and return the number converted from the string.
257 @param[in] String String representation of a number
260 @retval (UINTN)(-1) An error ocurred.
264 IN CONST CHAR16
*String
269 if (!EFI_ERROR(ShellConvertStringToUint64(String
, &RetVal
, FALSE
, TRUE
))) {
270 return ((UINTN
)RetVal
);
272 return ((UINTN
)(-1));
276 Function for 'for' command.
278 @param[in] ImageHandle Handle to the Image (NULL if Internal).
279 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
284 IN EFI_HANDLE ImageHandle
,
285 IN EFI_SYSTEM_TABLE
*SystemTable
289 SHELL_STATUS ShellStatus
;
290 SCRIPT_FILE
*CurrentScriptFile
;
292 CHAR16
*ArgSetWalker
;
296 SHELL_FOR_INFO
*Info
;
300 EFI_SHELL_FILE_INFO
*Node
;
301 EFI_SHELL_FILE_INFO
*FileList
;
306 ShellStatus
= SHELL_SUCCESS
;
313 // initialize the shell lib (we must be in non-auto-init...)
315 Status
= ShellInitialize();
316 ASSERT_EFI_ERROR(Status
);
318 Status
= CommandInit();
319 ASSERT_EFI_ERROR(Status
);
321 if (!gEfiShellProtocol
->BatchIsActive()) {
322 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_NO_SCRIPT
), gShellLevel1HiiHandle
, L
"for");
323 return (SHELL_UNSUPPORTED
);
326 if (gEfiShellParametersProtocol
->Argc
< 4) {
327 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel1HiiHandle
, L
"for");
328 return (SHELL_INVALID_PARAMETER
);
331 CurrentScriptFile
= ShellCommandGetCurrentScriptFile();
332 ASSERT(CurrentScriptFile
!= NULL
);
334 if ((CurrentScriptFile
->CurrentCommand
!= NULL
) && (CurrentScriptFile
->CurrentCommand
->Data
== NULL
)) {
338 // Make sure that an End exists.
340 if (!MoveToTag(GetNextNode
, L
"endfor", L
"for", NULL
, CurrentScriptFile
, TRUE
, TRUE
, FALSE
)) {
345 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
346 gShellLevel1HiiHandle
,
349 CurrentScriptFile
->CurrentCommand
->Line
);
350 return (SHELL_DEVICE_ERROR
);
356 if (gEfiShellParametersProtocol
->Argv
[1][0] != L
'%' || gEfiShellParametersProtocol
->Argv
[1][2] != CHAR_NULL
357 ||!((gEfiShellParametersProtocol
->Argv
[1][1] >= L
'a' && gEfiShellParametersProtocol
->Argv
[1][1] <= L
'z')
358 ||(gEfiShellParametersProtocol
->Argv
[1][1] >= L
'A' && gEfiShellParametersProtocol
->Argv
[1][1] <= L
'Z'))
360 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_INV_VAR
), gShellLevel1HiiHandle
, gEfiShellParametersProtocol
->Argv
[1]);
361 return (SHELL_INVALID_PARAMETER
);
364 if (gUnicodeCollation
->StriColl(
367 gEfiShellParametersProtocol
->Argv
[2]) == 0) {
368 for (LoopVar
= 0x3 ; LoopVar
< gEfiShellParametersProtocol
->Argc
; LoopVar
++) {
369 ASSERT((ArgSet
== NULL
&& ArgSize
== 0) || (ArgSet
!= NULL
));
370 if (StrStr(gEfiShellParametersProtocol
->Argv
[LoopVar
], L
"*") != NULL
371 ||StrStr(gEfiShellParametersProtocol
->Argv
[LoopVar
], L
"?") != NULL
372 ||StrStr(gEfiShellParametersProtocol
->Argv
[LoopVar
], L
"[") != NULL
373 ||StrStr(gEfiShellParametersProtocol
->Argv
[LoopVar
], L
"]") != NULL
) {
375 Status
= ShellOpenFileMetaArg ((CHAR16
*)gEfiShellParametersProtocol
->Argv
[LoopVar
], EFI_FILE_MODE_READ
, &FileList
);
376 if (EFI_ERROR(Status
) || FileList
== NULL
|| IsListEmpty(&FileList
->Link
)) {
377 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
" \"", 0);
378 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, gEfiShellParametersProtocol
->Argv
[LoopVar
], 0);
379 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
"\"", 0);
381 for (Node
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&FileList
->Link
)
382 ; !IsNull(&FileList
->Link
, &Node
->Link
)
383 ; Node
= (EFI_SHELL_FILE_INFO
*)GetNextNode(&FileList
->Link
, &Node
->Link
)
385 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
" \"", 0);
386 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, Node
->FullName
, 0);
387 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
"\"", 0);
389 ShellCloseFileMetaArg(&FileList
);
392 Parameter
= gEfiShellParametersProtocol
->Argv
[LoopVar
];
393 if (Parameter
[0] == L
'\"' && Parameter
[StrLen(Parameter
)-1] == L
'\"') {
394 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
" ", 0);
395 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, Parameter
, 0);
397 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
" \"", 0);
398 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, Parameter
, 0);
399 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
"\"", 0);
403 if (ArgSet
== NULL
) {
404 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
407 // set up for an 'in' for loop
409 NewSize
= StrSize(ArgSet
);
410 NewSize
+= sizeof(SHELL_FOR_INFO
)+StrSize(gEfiShellParametersProtocol
->Argv
[1]);
411 Info
= AllocateZeroPool(NewSize
);
414 return SHELL_OUT_OF_RESOURCES
;
416 Info
->Signature
= SHELL_FOR_INFO_SIGNATURE
;
417 CopyMem(Info
->Set
, ArgSet
, StrSize(ArgSet
));
418 NewSize
= StrSize(gEfiShellParametersProtocol
->Argv
[1]);
419 CopyMem(Info
->Set
+(StrSize(ArgSet
)/sizeof(Info
->Set
[0])), gEfiShellParametersProtocol
->Argv
[1], NewSize
);
420 Info
->ReplacementName
= Info
->Set
+StrSize(ArgSet
)/sizeof(Info
->Set
[0]);
421 Info
->CurrentValue
= (CHAR16
*)Info
->Set
;
426 if (InternalIsAliasOnList(Info
->ReplacementName
, &CurrentScriptFile
->SubstList
)) {
427 Info
->RemoveSubstAlias
= FALSE
;
429 Info
->RemoveSubstAlias
= TRUE
;
431 CurrentScriptFile
->CurrentCommand
->Data
= Info
;
433 } else if (gUnicodeCollation
->StriColl(
436 gEfiShellParametersProtocol
->Argv
[2]) == 0) {
437 for (LoopVar
= 0x3 ; LoopVar
< gEfiShellParametersProtocol
->Argc
; LoopVar
++) {
438 ASSERT((ArgSet
== NULL
&& ArgSize
== 0) || (ArgSet
!= NULL
));
439 if (StrStr (gEfiShellParametersProtocol
->Argv
[LoopVar
], L
")") != NULL
&&
440 (LoopVar
+ 1) < gEfiShellParametersProtocol
->Argc
442 return (SHELL_INVALID_PARAMETER
);
444 if (ArgSet
== NULL
) {
445 // ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0);
447 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, L
" ", 0);
449 ArgSet
= StrnCatGrow(&ArgSet
, &ArgSize
, gEfiShellParametersProtocol
->Argv
[LoopVar
], 0);
450 // ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" ", 0);
452 if (ArgSet
== NULL
) {
453 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
456 // set up for a 'run' for loop
458 Info
= AllocateZeroPool(sizeof(SHELL_FOR_INFO
)+StrSize(gEfiShellParametersProtocol
->Argv
[1]));
461 return SHELL_OUT_OF_RESOURCES
;
463 Info
->Signature
= SHELL_FOR_INFO_SIGNATURE
;
464 CopyMem(Info
->Set
, gEfiShellParametersProtocol
->Argv
[1], StrSize(gEfiShellParametersProtocol
->Argv
[1]));
465 Info
->ReplacementName
= Info
->Set
;
466 Info
->CurrentValue
= NULL
;
467 ArgSetWalker
= ArgSet
;
468 if (ArgSetWalker
[0] != L
'(') {
473 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
474 gShellLevel1HiiHandle
,
476 CurrentScriptFile
->CurrentCommand
->Line
);
477 ShellStatus
= SHELL_INVALID_PARAMETER
;
479 TempSpot
= StrStr(ArgSetWalker
, L
")");
480 if (TempSpot
!= NULL
) {
481 TempString
= TempSpot
+1;
482 if (*(TempString
) != CHAR_NULL
) {
483 while(TempString
!= NULL
&& *TempString
== L
' ') {
486 if (StrLen(TempString
) > 0) {
491 if (TempSpot
== NULL
) {
496 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
497 gShellLevel1HiiHandle
,
498 CurrentScriptFile
->CurrentCommand
->Line
);
499 ShellStatus
= SHELL_INVALID_PARAMETER
;
501 *TempSpot
= CHAR_NULL
;
503 while (ArgSetWalker
!= NULL
&& ArgSetWalker
[0] == L
' ') {
506 if (!ShellIsValidForNumber(ArgSetWalker
)) {
511 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
512 gShellLevel1HiiHandle
,
514 CurrentScriptFile
->CurrentCommand
->Line
);
515 ShellStatus
= SHELL_INVALID_PARAMETER
;
517 if (ArgSetWalker
[0] == L
'-') {
518 Info
->Current
= 0 - (INTN
)ReturnUintn(ArgSetWalker
+1);
520 Info
->Current
= (INTN
)ReturnUintn(ArgSetWalker
);
522 ArgSetWalker
= StrStr(ArgSetWalker
, L
" ");
523 while (ArgSetWalker
!= NULL
&& ArgSetWalker
[0] == L
' ') {
526 if (ArgSetWalker
== NULL
|| *ArgSetWalker
== CHAR_NULL
|| !ShellIsValidForNumber(ArgSetWalker
)){
531 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
532 gShellLevel1HiiHandle
,
534 CurrentScriptFile
->CurrentCommand
->Line
);
535 ShellStatus
= SHELL_INVALID_PARAMETER
;
537 if (ArgSetWalker
[0] == L
'-') {
538 Info
->End
= 0 - (INTN
)ReturnUintn(ArgSetWalker
+1);
540 Info
->End
= (INTN
)ReturnUintn(ArgSetWalker
);
542 if (Info
->Current
< Info
->End
) {
548 ArgSetWalker
= StrStr(ArgSetWalker
, L
" ");
549 while (ArgSetWalker
!= NULL
&& ArgSetWalker
[0] == L
' ') {
552 if (ArgSetWalker
!= NULL
&& *ArgSetWalker
!= CHAR_NULL
) {
553 if (ArgSetWalker
== NULL
|| *ArgSetWalker
== CHAR_NULL
|| !ShellIsValidForNumber(ArgSetWalker
)){
558 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
559 gShellLevel1HiiHandle
,
561 CurrentScriptFile
->CurrentCommand
->Line
);
562 ShellStatus
= SHELL_INVALID_PARAMETER
;
564 if (*ArgSetWalker
== L
')') {
565 ASSERT(Info
->Step
== 1 || Info
->Step
== -1);
567 if (ArgSetWalker
[0] == L
'-') {
568 Info
->Step
= 0 - (INTN
)ReturnUintn(ArgSetWalker
+1);
570 Info
->Step
= (INTN
)ReturnUintn(ArgSetWalker
);
573 if (StrStr(ArgSetWalker
, L
" ") != NULL
) {
578 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
579 gShellLevel1HiiHandle
,
581 CurrentScriptFile
->CurrentCommand
->Line
);
582 ShellStatus
= SHELL_INVALID_PARAMETER
;
592 if (ShellStatus
== SHELL_SUCCESS
) {
593 if (InternalIsAliasOnList(Info
->ReplacementName
, &CurrentScriptFile
->SubstList
)) {
594 Info
->RemoveSubstAlias
= FALSE
;
596 Info
->RemoveSubstAlias
= TRUE
;
599 if (CurrentScriptFile
->CurrentCommand
!= NULL
) {
600 CurrentScriptFile
->CurrentCommand
->Data
= Info
;
608 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT
),
609 gShellLevel1HiiHandle
,
611 CurrentScriptFile
!=NULL
612 && CurrentScriptFile
->CurrentCommand
!=NULL
613 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
614 ShellStatus
= SHELL_INVALID_PARAMETER
;
618 // These need to be NULL since they are used to determine if this is the first pass later on...
620 ASSERT(ArgSetWalker
== NULL
);
621 ASSERT(ArgSet
== NULL
);
624 if (CurrentScriptFile
!= NULL
&& CurrentScriptFile
->CurrentCommand
!= NULL
) {
625 Info
= (SHELL_FOR_INFO
*)CurrentScriptFile
->CurrentCommand
->Data
;
626 if (CurrentScriptFile
->CurrentCommand
->Reset
) {
627 Info
->CurrentValue
= (CHAR16
*)Info
->Set
;
629 CurrentScriptFile
->CurrentCommand
->Reset
= FALSE
;
632 ShellStatus
= SHELL_UNSUPPORTED
;
635 if (ShellStatus
== SHELL_SUCCESS
) {
636 ASSERT(Info
!= NULL
);
637 if (Info
->Step
!= 0) {
639 // only advance if not the first pass
643 // sequence version of for loop...
645 Info
->Current
+= Info
->Step
;
648 TempString
= AllocateZeroPool(50*sizeof(CHAR16
));
649 UnicodeSPrint(TempString
, 50*sizeof(CHAR16
), L
"%d", Info
->Current
);
650 InternalUpdateAliasOnList(Info
->ReplacementName
, TempString
, &CurrentScriptFile
->SubstList
);
651 FreePool(TempString
);
653 if ((Info
->Step
> 0 && Info
->Current
> Info
->End
) || (Info
->Step
< 0 && Info
->Current
< Info
->End
)) {
654 CurrentScriptFile
->CurrentCommand
->Data
= NULL
;
656 // find the matching endfor (we're done with the loop)
658 if (!MoveToTag(GetNextNode
, L
"endfor", L
"for", NULL
, CurrentScriptFile
, TRUE
, FALSE
, FALSE
)) {
663 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
664 gShellLevel1HiiHandle
,
667 CurrentScriptFile
!=NULL
668 && CurrentScriptFile
->CurrentCommand
!=NULL
669 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
670 ShellStatus
= SHELL_DEVICE_ERROR
;
672 if (Info
->RemoveSubstAlias
) {
674 // remove item from list
676 InternalRemoveAliasFromList(Info
->ReplacementName
, &CurrentScriptFile
->SubstList
);
682 // Must be in 'in' version of for loop...
684 ASSERT(Info
->Set
!= NULL
);
685 if (Info
->CurrentValue
!= NULL
&& *Info
->CurrentValue
!= CHAR_NULL
) {
686 if (Info
->CurrentValue
[0] == L
' ') {
687 Info
->CurrentValue
++;
689 if (Info
->CurrentValue
[0] == L
'\"') {
690 Info
->CurrentValue
++;
693 // do the next one of the set
695 ASSERT(TempString
== NULL
);
696 TempString
= StrnCatGrow(&TempString
, NULL
, Info
->CurrentValue
, 0);
697 if (TempString
== NULL
) {
698 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
700 TempSpot
= StrStr(TempString
, L
"\" \"");
701 if (TempSpot
!= NULL
) {
702 *TempSpot
= CHAR_NULL
;
704 while (TempString
[StrLen(TempString
)-1] == L
'\"') {
705 TempString
[StrLen(TempString
)-1] = CHAR_NULL
;
707 InternalUpdateAliasOnList(Info
->ReplacementName
, TempString
, &CurrentScriptFile
->SubstList
);
708 Info
->CurrentValue
+= StrLen(TempString
);
710 if (Info
->CurrentValue
[0] == L
'\"') {
711 Info
->CurrentValue
++;
713 FreePool(TempString
);
716 CurrentScriptFile
->CurrentCommand
->Data
= NULL
;
718 // find the matching endfor (we're done with the loop)
720 if (!MoveToTag(GetNextNode
, L
"endfor", L
"for", NULL
, CurrentScriptFile
, TRUE
, FALSE
, FALSE
)) {
725 STRING_TOKEN (STR_SYNTAX_NO_MATCHING
),
726 gShellLevel1HiiHandle
,
729 CurrentScriptFile
!=NULL
730 && CurrentScriptFile
->CurrentCommand
!=NULL
731 ? CurrentScriptFile
->CurrentCommand
->Line
:0);
732 ShellStatus
= SHELL_DEVICE_ERROR
;
734 if (Info
->RemoveSubstAlias
) {
736 // remove item from list
738 InternalRemoveAliasFromList(Info
->ReplacementName
, &CurrentScriptFile
->SubstList
);
744 if (ArgSet
!= NULL
) {
747 return (ShellStatus
);