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