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