]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellLevel1CommandsLib/For.c
udk2010.up2.shell initial release.
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel1CommandsLib / For.c
1 /** @file
2 Main file for endfor and for shell level 1 functions.
3
4 Copyright (c) 2009 - 2010, 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
9
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.
12
13 **/
14
15 #include "UefiShellLevel1CommandsLib.h"
16 #include <Library/PrintLib.h>
17
18 BOOLEAN
19 EFIAPI
20 ShellIsValidForNumber (
21 IN CONST CHAR16 *Number
22 )
23 {
24 if (Number == NULL || *Number == CHAR_NULL) {
25 return (FALSE);
26 }
27
28 if (*Number == L'-') {
29 Number++;
30 }
31
32 if (StrLen(Number) == 0) {
33 return (FALSE);
34 }
35
36 if (StrLen(Number) >= 7) {
37 if (StrStr(Number, L" ") != NULL && (StrStr(Number, L" ") - Number) >= 7) {
38 return (FALSE);
39 }
40 }
41
42 if (!ShellIsDecimalDigitCharacter(*Number)) {
43 return (FALSE);
44 }
45
46 return (TRUE);
47 }
48
49 /**
50 Function for 'endfor' command.
51
52 @param[in] ImageHandle Handle to the Image (NULL if Internal).
53 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
54 **/
55 SHELL_STATUS
56 EFIAPI
57 ShellCommandRunEndFor (
58 IN EFI_HANDLE ImageHandle,
59 IN EFI_SYSTEM_TABLE *SystemTable
60 )
61 {
62 EFI_STATUS Status;
63 BOOLEAN Found;
64
65 Status = CommandInit();
66 ASSERT_EFI_ERROR(Status);
67
68 if (!gEfiShellProtocol->BatchIsActive()) {
69 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"EndFor");
70 return (SHELL_UNSUPPORTED);
71 }
72
73 if (gEfiShellParametersProtocol->Argc > 1) {
74 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel1HiiHandle);
75 return (SHELL_INVALID_PARAMETER);
76 }
77
78 Found = MoveToTag(GetPreviousNode, L"for", L"endfor", NULL, ShellCommandGetCurrentScriptFile(), FALSE, FALSE, FALSE);
79
80 if (!Found) {
81 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"For", L"EndFor", ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
82 return (SHELL_NOT_FOUND);
83 }
84 return (SHELL_SUCCESS);
85 }
86
87 typedef struct {
88 UINT32 Signature;
89 INTN Current;
90 INTN End;
91 INTN Step;
92 CHAR16 *ReplacementName;
93 CHAR16 *CurrentValue;
94 BOOLEAN RemoveSubstAlias;
95 CHAR16 Set[1];
96 } SHELL_FOR_INFO;
97 #define SIZE_OF_SHELL_FOR_INFO OFFSET_OF (SHELL_FOR_INFO, Set)
98 #define SHELL_FOR_INFO_SIGNATURE SIGNATURE_32 ('S', 'F', 'I', 's')
99
100 /**
101 Update the value of a given alias on the list. If the alias is not there then add it.
102
103 @param[in] Alias The alias to test for.
104 @param[in] CommandString The updated command string.
105 @param[in,out] List The list to search.
106 **/
107 VOID
108 EFIAPI
109 InternalUpdateAliasOnList(
110 IN CONST CHAR16 *Alias,
111 IN CONST CHAR16 *CommandString,
112 IN OUT LIST_ENTRY *List
113 )
114 {
115 ALIAS_LIST *Node;
116 BOOLEAN Found;
117
118 //
119 // assert for NULL parameter
120 //
121 ASSERT(Alias != NULL);
122
123 //
124 // check for the Alias
125 //
126 for ( Node = (ALIAS_LIST *)GetFirstNode(List), Found = FALSE
127 ; !IsNull(List, &Node->Link)
128 ; Node = (ALIAS_LIST *)GetNextNode(List, &Node->Link)
129 ){
130 ASSERT(Node->CommandString != NULL);
131 ASSERT(Node->Alias != NULL);
132 if (StrCmp(Node->Alias, Alias)==0) {
133 FreePool(Node->CommandString);
134 Node->CommandString = NULL;
135 Node->CommandString = StrnCatGrow(&Node->CommandString, NULL, CommandString, 0);
136 Found = TRUE;
137 break;
138 }
139 }
140 if (!Found) {
141 Node = AllocateZeroPool(sizeof(ALIAS_LIST));
142 ASSERT(Node->Alias == NULL);
143 Node->Alias = StrnCatGrow(&Node->Alias, NULL, Alias, 0);
144 ASSERT(Node->CommandString == NULL);
145 Node->CommandString = StrnCatGrow(&Node->CommandString, NULL, CommandString, 0);
146 InsertTailList(List, &Node->Link);
147 }
148 }
149
150 /**
151 Find out if an alias is on the given list.
152
153 @param[in] Alias The alias to test for.
154 @param[in] List The list to search.
155
156 @retval TRUE The alias is on the list.
157 @retval FALSE The alias is not on the list.
158 **/
159 BOOLEAN
160 EFIAPI
161 InternalIsAliasOnList(
162 IN CONST CHAR16 *Alias,
163 IN CONST LIST_ENTRY *List
164 )
165 {
166 ALIAS_LIST *Node;
167
168 //
169 // assert for NULL parameter
170 //
171 ASSERT(Alias != NULL);
172
173 //
174 // check for the Alias
175 //
176 for ( Node = (ALIAS_LIST *)GetFirstNode(List)
177 ; !IsNull(List, &Node->Link)
178 ; Node = (ALIAS_LIST *)GetNextNode(List, &Node->Link)
179 ){
180 ASSERT(Node->CommandString != NULL);
181 ASSERT(Node->Alias != NULL);
182 if (StrCmp(Node->Alias, Alias)==0) {
183 return (TRUE);
184 }
185 }
186 return (FALSE);
187 }
188
189 /**
190 Remove an alias from the given list.
191
192 @param[in] Alias The alias to remove.
193 @param[in,out] List The list to search.
194 **/
195 BOOLEAN
196 EFIAPI
197 InternalRemoveAliasFromList(
198 IN CONST CHAR16 *Alias,
199 IN OUT LIST_ENTRY *List
200 )
201 {
202 ALIAS_LIST *Node;
203
204 //
205 // assert for NULL parameter
206 //
207 ASSERT(Alias != NULL);
208
209 //
210 // check for the Alias
211 //
212 for ( Node = (ALIAS_LIST *)GetFirstNode(List)
213 ; !IsNull(List, &Node->Link)
214 ; Node = (ALIAS_LIST *)GetNextNode(List, &Node->Link)
215 ){
216 ASSERT(Node->CommandString != NULL);
217 ASSERT(Node->Alias != NULL);
218 if (StrCmp(Node->Alias, Alias)==0) {
219 RemoveEntryList(&Node->Link);
220 FreePool(Node->Alias);
221 FreePool(Node->CommandString);
222 FreePool(Node);
223 return (TRUE);
224 }
225 }
226 return (FALSE);
227 }
228
229 /**
230 Function for 'for' command.
231
232 @param[in] ImageHandle Handle to the Image (NULL if Internal).
233 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
234 **/
235 SHELL_STATUS
236 EFIAPI
237 ShellCommandRunFor (
238 IN EFI_HANDLE ImageHandle,
239 IN EFI_SYSTEM_TABLE *SystemTable
240 )
241 {
242 EFI_STATUS Status;
243 SHELL_STATUS ShellStatus;
244 SCRIPT_FILE *CurrentScriptFile;
245 CHAR16 *ArgSet;
246 CHAR16 *ArgSetWalker;
247 UINTN ArgSize;
248 UINTN LoopVar;
249 SHELL_FOR_INFO *Info;
250 CHAR16 *TempString;
251 CHAR16 *TempSpot;
252 BOOLEAN FirstPass;
253 EFI_SHELL_FILE_INFO *Node;
254 EFI_SHELL_FILE_INFO *FileList;
255 UINTN NewSize;
256
257 ArgSet = NULL;
258 ArgSize = 0;
259 ShellStatus = SHELL_SUCCESS;
260 ArgSetWalker = NULL;
261 TempString = NULL;
262 FirstPass = FALSE;
263
264 //
265 // initialize the shell lib (we must be in non-auto-init...)
266 //
267 Status = ShellInitialize();
268 ASSERT_EFI_ERROR(Status);
269
270 Status = CommandInit();
271 ASSERT_EFI_ERROR(Status);
272
273 if (!gEfiShellProtocol->BatchIsActive()) {
274 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"For");
275 return (SHELL_UNSUPPORTED);
276 }
277
278 if (gEfiShellParametersProtocol->Argc < 4) {
279 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel1HiiHandle);
280 return (SHELL_INVALID_PARAMETER);
281 }
282
283 CurrentScriptFile = ShellCommandGetCurrentScriptFile();
284 ASSERT(CurrentScriptFile != NULL);
285
286 if (CurrentScriptFile->CurrentCommand->Data == NULL) {
287 FirstPass = TRUE;
288
289 //
290 // Make sure that an End exists.
291 //
292 if (!MoveToTag(GetNextNode, L"endfor", L"for", NULL, CurrentScriptFile, TRUE, TRUE, FALSE)) {
293 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"EndFor", L"For", ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
294 return (SHELL_DEVICE_ERROR);
295 }
296
297 //
298 // Process the line.
299 //
300 if (gEfiShellParametersProtocol->Argv[1][0] != L'%' || gEfiShellParametersProtocol->Argv[1][2] != CHAR_NULL
301 ||!((gEfiShellParametersProtocol->Argv[1][1] >= L'a' && gEfiShellParametersProtocol->Argv[1][1] <= L'z')
302 ||(gEfiShellParametersProtocol->Argv[1][1] >= L'A' && gEfiShellParametersProtocol->Argv[1][1] <= L'Z'))
303 ) {
304 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_VAR), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[2]);
305 return (SHELL_INVALID_PARAMETER);
306 }
307
308 if (gUnicodeCollation->StriColl(
309 gUnicodeCollation,
310 L"in",
311 gEfiShellParametersProtocol->Argv[2]) == 0) {
312 for (LoopVar = 0x3 ; LoopVar < gEfiShellParametersProtocol->Argc ; LoopVar++) {
313 ASSERT((ArgSet == NULL && ArgSize == 0) || (ArgSet != NULL));
314 if (ArgSet == NULL) {
315 // ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0);
316 } else {
317 ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" \"", 0);
318 }
319 if (StrStr(gEfiShellParametersProtocol->Argv[LoopVar], L"*") != NULL
320 ||StrStr(gEfiShellParametersProtocol->Argv[LoopVar], L"?") != NULL
321 ||StrStr(gEfiShellParametersProtocol->Argv[LoopVar], L"[") != NULL
322 ||StrStr(gEfiShellParametersProtocol->Argv[LoopVar], L"]") != NULL) {
323 FileList = NULL;
324 Status = ShellOpenFileMetaArg ((CHAR16*)gEfiShellParametersProtocol->Argv[LoopVar], EFI_FILE_MODE_READ, &FileList);
325 if (EFI_ERROR(Status) || FileList == NULL || IsListEmpty(&FileList->Link)) {
326 ArgSet = StrnCatGrow(&ArgSet, &ArgSize, gEfiShellParametersProtocol->Argv[LoopVar], 0);
327 } else {
328 for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&FileList->Link)
329 ; !IsNull(&FileList->Link, &Node->Link)
330 ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&FileList->Link, &Node->Link)
331 ){
332 ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" \"", 0);
333 ArgSet = StrnCatGrow(&ArgSet, &ArgSize, Node->FullName, 0);
334 ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0);
335 }
336 ShellCloseFileMetaArg(&FileList);
337 }
338 } else {
339 ArgSet = StrnCatGrow(&ArgSet, &ArgSize, gEfiShellParametersProtocol->Argv[LoopVar], 0);
340 }
341 ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0);
342 }
343 //
344 // set up for an 'in' for loop
345 //
346 NewSize = StrSize(ArgSet);
347 NewSize += sizeof(SHELL_FOR_INFO)+StrSize(gEfiShellParametersProtocol->Argv[1]);
348 Info = AllocateZeroPool(NewSize);
349 ASSERT(Info != NULL);
350 Info->Signature = SHELL_FOR_INFO_SIGNATURE;
351 CopyMem(Info->Set, ArgSet, StrSize(ArgSet));
352 NewSize = StrSize(gEfiShellParametersProtocol->Argv[1]);
353 CopyMem(Info->Set+(StrSize(ArgSet)/sizeof(Info->Set[0])), gEfiShellParametersProtocol->Argv[1], NewSize);
354 Info->ReplacementName = Info->Set+StrSize(ArgSet)/sizeof(Info->Set[0]);
355 Info->CurrentValue = (CHAR16*)Info->Set;
356 Info->Step = 0;
357 Info->Current = 0;
358 Info->End = 0;
359
360 if (InternalIsAliasOnList(Info->ReplacementName, &CurrentScriptFile->SubstList)) {
361 Info->RemoveSubstAlias = FALSE;
362 } else {
363 Info->RemoveSubstAlias = TRUE;
364 }
365 CurrentScriptFile->CurrentCommand->Data = Info;
366 } else if (gUnicodeCollation->StriColl(
367 gUnicodeCollation,
368 L"run",
369 gEfiShellParametersProtocol->Argv[2]) == 0) {
370 for (LoopVar = 0x3 ; LoopVar < gEfiShellParametersProtocol->Argc ; LoopVar++) {
371 ASSERT((ArgSet == NULL && ArgSize == 0) || (ArgSet != NULL));
372 if (ArgSet == NULL) {
373 // ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0);
374 } else {
375 ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" ", 0);
376 }
377 ArgSet = StrnCatGrow(&ArgSet, &ArgSize, gEfiShellParametersProtocol->Argv[LoopVar], 0);
378 // ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" ", 0);
379 }
380 //
381 // set up for a 'run' for loop
382 //
383 Info = AllocateZeroPool(sizeof(SHELL_FOR_INFO)+StrSize(gEfiShellParametersProtocol->Argv[1]));
384 ASSERT(Info != NULL);
385 CopyMem(Info->Set, gEfiShellParametersProtocol->Argv[1], StrSize(gEfiShellParametersProtocol->Argv[1]));
386 Info->ReplacementName = Info->Set;
387 Info->CurrentValue = NULL;
388 ArgSetWalker = ArgSet;
389 if (ArgSetWalker[0] != L'(') {
390 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, ArgSet, ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
391 ShellStatus = SHELL_INVALID_PARAMETER;
392 } else {
393 ArgSetWalker++;
394 while (ArgSetWalker != NULL && ArgSetWalker[0] == L' ') {
395 ArgSetWalker++;
396 }
397 if (!ShellIsValidForNumber(ArgSetWalker)) {
398 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, ArgSet, ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
399 ShellStatus = SHELL_INVALID_PARAMETER;
400 } else {
401 if (ArgSetWalker[0] == L'-') {
402 Info->Current = 0 - (INTN)ShellStrToUintn(ArgSetWalker+1);
403 } else {
404 Info->Current = (INTN)ShellStrToUintn(ArgSetWalker);
405 }
406 ArgSetWalker = StrStr(ArgSetWalker, L" ");
407 while (ArgSetWalker != NULL && ArgSetWalker[0] == L' ') {
408 ArgSetWalker++;
409 }
410 if (ArgSetWalker == NULL || *ArgSetWalker == CHAR_NULL || !ShellIsValidForNumber(ArgSetWalker)){
411 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, ArgSet, ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
412 ShellStatus = SHELL_INVALID_PARAMETER;
413 } else {
414 if (ArgSetWalker[0] == L'-') {
415 Info->End = 0 - (INTN)ShellStrToUintn(ArgSetWalker+1);
416 } else {
417 Info->End = (INTN)ShellStrToUintn(ArgSetWalker);
418 }
419 if (Info->Current < Info->End) {
420 Info->Step = 1;
421 } else {
422 Info->Step = -1;
423 }
424
425 ArgSetWalker = StrStr(ArgSetWalker, L" ");
426 while (ArgSetWalker != NULL && ArgSetWalker[0] == L' ') {
427 ArgSetWalker++;
428 }
429 if (ArgSetWalker != NULL && *ArgSetWalker != CHAR_NULL) {
430 TempSpot = StrStr(ArgSetWalker, L")");
431 if (TempSpot == NULL) {
432 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, ArgSet, ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
433 ShellStatus = SHELL_INVALID_PARAMETER;
434 } else {
435 *TempSpot = CHAR_NULL;
436 if (ArgSetWalker == NULL || *ArgSetWalker == CHAR_NULL || !ShellIsValidForNumber(ArgSetWalker)){
437 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, ArgSet, ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
438 ShellStatus = SHELL_INVALID_PARAMETER;
439 } else {
440 if (*ArgSetWalker == L')') {
441 ASSERT(Info->Step == 1 || Info->Step == -1);
442 } else {
443 if (ArgSetWalker[0] == L'-') {
444 Info->Step = 0 - (INTN)ShellStrToUintn(ArgSetWalker+1);
445 } else {
446 Info->Step = (INTN)ShellStrToUintn(ArgSetWalker);
447 }
448 }
449 }
450 }
451 }
452 }
453 }
454 }
455 if (ShellStatus == SHELL_SUCCESS) {
456 if (InternalIsAliasOnList(Info->ReplacementName, &CurrentScriptFile->SubstList)) {
457 Info->RemoveSubstAlias = FALSE;
458 } else {
459 Info->RemoveSubstAlias = TRUE;
460 }
461 }
462 CurrentScriptFile->CurrentCommand->Data = Info;
463 } else {
464 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, ArgSet, ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
465 ShellStatus = SHELL_INVALID_PARAMETER;
466 }
467 } else {
468 //
469 // These need to be NULL since they are used to determine if this is the first pass later on...
470 //
471 ASSERT(ArgSetWalker == NULL);
472 ASSERT(ArgSet == NULL);
473 }
474
475 Info = (SHELL_FOR_INFO*)CurrentScriptFile->CurrentCommand->Data;
476 if (CurrentScriptFile->CurrentCommand->Reset) {
477 Info->CurrentValue = (CHAR16*)Info->Set;
478 FirstPass = TRUE;
479 CurrentScriptFile->CurrentCommand->Reset = FALSE;
480 }
481 if (ShellStatus == SHELL_SUCCESS) {
482 ASSERT(Info != NULL);
483 if (Info->Step != 0) {
484 //
485 // only advance if not the first pass
486 //
487 if (!FirstPass) {
488 //
489 // sequence version of for loop...
490 //
491 Info->Current += Info->Step;
492 }
493
494 TempString = AllocateZeroPool(50*sizeof(CHAR16));
495 UnicodeSPrint(TempString, 50*sizeof(CHAR16), L"%d", Info->Current);
496 InternalUpdateAliasOnList(Info->ReplacementName, TempString, &CurrentScriptFile->SubstList);
497 FreePool(TempString);
498
499 if ((Info->Step > 0 && Info->Current > Info->End) || (Info->Step < 0 && Info->Current < Info->End)) {
500 CurrentScriptFile->CurrentCommand->Data = NULL;
501 //
502 // find the matching endfor (we're done with the loop)
503 //
504 if (!MoveToTag(GetNextNode, L"endfor", L"for", NULL, CurrentScriptFile, TRUE, FALSE, FALSE)) {
505 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"EndFor", L"For", ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
506 ShellStatus = SHELL_DEVICE_ERROR;
507 }
508 if (Info->RemoveSubstAlias) {
509 //
510 // remove item from list
511 //
512 InternalRemoveAliasFromList(Info->ReplacementName, &CurrentScriptFile->SubstList);
513 }
514 FreePool(Info);
515 }
516 } else {
517 //
518 // Must be in 'in' version of for loop...
519 //
520 ASSERT(Info->Set != NULL);
521 if (Info->CurrentValue != NULL && *Info->CurrentValue != CHAR_NULL) {
522 if (Info->CurrentValue[0] == L'\"') {
523 Info->CurrentValue++;
524 }
525 while (Info->CurrentValue[0] == L' ') {
526 Info->CurrentValue++;
527 }
528 if (Info->CurrentValue[0] == L'\"') {
529 Info->CurrentValue++;
530 }
531 //
532 // do the next one of the set
533 //
534 ASSERT(TempString == NULL);
535 TempString = StrnCatGrow(&TempString, NULL, Info->CurrentValue, 0);
536 TempSpot = StrStr(TempString, L"\" \"");
537 if (TempSpot != NULL) {
538 *TempSpot = CHAR_NULL;
539 }
540 while (TempString[StrLen(TempString)-1] == L'\"') {
541 TempString[StrLen(TempString)-1] = CHAR_NULL;
542 }
543 InternalUpdateAliasOnList(Info->ReplacementName, TempString, &CurrentScriptFile->SubstList);
544 Info->CurrentValue += StrLen(TempString);
545
546 if (Info->CurrentValue[0] == L'\"') {
547 Info->CurrentValue++;
548 }
549 while (Info->CurrentValue[0] == L' ') {
550 Info->CurrentValue++;
551 }
552 if (Info->CurrentValue[0] == L'\"') {
553 Info->CurrentValue++;
554 }
555 FreePool(TempString);
556
557 } else {
558 CurrentScriptFile->CurrentCommand->Data = NULL;
559 //
560 // find the matching endfor (we're done with the loop)
561 //
562 if (!MoveToTag(GetNextNode, L"endfor", L"for", NULL, CurrentScriptFile, TRUE, FALSE, FALSE)) {
563 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"EndFor", L"For", ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
564 ShellStatus = SHELL_DEVICE_ERROR;
565 }
566 if (Info->RemoveSubstAlias) {
567 //
568 // remove item from list
569 //
570 InternalRemoveAliasFromList(Info->ReplacementName, &CurrentScriptFile->SubstList);
571 }
572 FreePool(Info);
573 }
574 }
575 }
576 if (ArgSet != NULL) {
577 FreePool(ArgSet);
578 }
579 return (ShellStatus);
580 }
581