]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellLevel1CommandsLib/For.c
ShellPkg: Apply uncrustify changes
[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
c011b6c9 4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>\r
7162fdb0 5 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
56ba3746 6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
a405b86d 7\r
8**/\r
9\r
10#include "UefiShellLevel1CommandsLib.h"\r
11#include <Library/PrintLib.h>\r
12\r
77dcec12 13/**\r
14 Determine if a valid string is a valid number for the 'for' command.\r
15\r
16 @param[in] Number The pointer to the string representation of the number to test.\r
17\r
18 @retval TRUE The number is valid.\r
19 @retval FALSE The number is not valid.\r
20**/\r
a405b86d 21BOOLEAN\r
a405b86d 22ShellIsValidForNumber (\r
47d20b54 23 IN CONST CHAR16 *Number\r
a405b86d 24 )\r
25{\r
47d20b54 26 if ((Number == NULL) || (*Number == CHAR_NULL)) {\r
a405b86d 27 return (FALSE);\r
28 }\r
29\r
30 if (*Number == L'-') {\r
31 Number++;\r
32 }\r
33\r
47d20b54 34 if (StrLen (Number) == 0) {\r
a405b86d 35 return (FALSE);\r
36 }\r
37\r
47d20b54
MK
38 if (StrLen (Number) >= 7) {\r
39 if ((StrStr (Number, L" ") == NULL) || (((StrStr (Number, L" ") != NULL) && ((StrStr (Number, L" ") - Number) >= 7)))) {\r
a405b86d 40 return (FALSE);\r
41 }\r
42 }\r
43\r
47d20b54 44 if (!ShellIsDecimalDigitCharacter (*Number)) {\r
a405b86d 45 return (FALSE);\r
46 }\r
47\r
48 return (TRUE);\r
49}\r
50\r
51/**\r
52 Function for 'endfor' command.\r
53\r
54 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
55 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
56**/\r
57SHELL_STATUS\r
58EFIAPI\r
59ShellCommandRunEndFor (\r
60 IN EFI_HANDLE ImageHandle,\r
61 IN EFI_SYSTEM_TABLE *SystemTable\r
62 )\r
63{\r
47d20b54
MK
64 EFI_STATUS Status;\r
65 BOOLEAN Found;\r
66 SCRIPT_FILE *CurrentScriptFile;\r
a405b86d 67\r
47d20b54
MK
68 Status = CommandInit ();\r
69 ASSERT_EFI_ERROR (Status);\r
a405b86d 70\r
47d20b54
MK
71 if (!gEfiShellProtocol->BatchIsActive ()) {\r
72 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"endfor");\r
a405b86d 73 return (SHELL_UNSUPPORTED);\r
74 }\r
75\r
76 if (gEfiShellParametersProtocol->Argc > 1) {\r
47d20b54 77 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel1HiiHandle, L"endfor");\r
a405b86d 78 return (SHELL_INVALID_PARAMETER);\r
79 }\r
80\r
47d20b54 81 Found = MoveToTag (GetPreviousNode, L"for", L"endfor", NULL, ShellCommandGetCurrentScriptFile (), FALSE, FALSE, FALSE);\r
a405b86d 82\r
83 if (!Found) {\r
47d20b54
MK
84 CurrentScriptFile = ShellCommandGetCurrentScriptFile ();\r
85 ShellPrintHiiEx (\r
ba0014b9
LG
86 -1,\r
87 -1,\r
88 NULL,\r
89 STRING_TOKEN (STR_SYNTAX_NO_MATCHING),\r
90 gShellLevel1HiiHandle,\r
91 L"For",\r
92 L"EndFor",\r
47d20b54
MK
93 CurrentScriptFile != NULL\r
94 && CurrentScriptFile->CurrentCommand != NULL\r
95 ? CurrentScriptFile->CurrentCommand->Line : 0\r
96 );\r
a405b86d 97 return (SHELL_NOT_FOUND);\r
98 }\r
47d20b54 99\r
a405b86d 100 return (SHELL_SUCCESS);\r
101}\r
102\r
103typedef struct {\r
47d20b54
MK
104 UINT32 Signature;\r
105 INTN Current;\r
106 INTN End;\r
107 INTN Step;\r
108 CHAR16 *ReplacementName;\r
109 CHAR16 *CurrentValue;\r
110 BOOLEAN RemoveSubstAlias;\r
111 CHAR16 Set[1];\r
112} SHELL_FOR_INFO;\r
113#define SIZE_OF_SHELL_FOR_INFO OFFSET_OF (SHELL_FOR_INFO, Set)\r
114#define SHELL_FOR_INFO_SIGNATURE SIGNATURE_32 ('S', 'F', 'I', 's')\r
a405b86d 115\r
116/**\r
117 Update the value of a given alias on the list. If the alias is not there then add it.\r
118\r
4ff7e37b
ED
119 @param[in] Alias The alias to test for.\r
120 @param[in] CommandString The updated command string.\r
121 @param[in, out] List The list to search.\r
9ea69f8a 122\r
123 @retval EFI_SUCCESS The operation was completed successfully.\r
124 @retval EFI_OUT_OF_RESOURCES There was not enough free memory.\r
a405b86d 125**/\r
9ea69f8a 126EFI_STATUS\r
47d20b54
MK
127InternalUpdateAliasOnList (\r
128 IN CONST CHAR16 *Alias,\r
129 IN CONST CHAR16 *CommandString,\r
130 IN OUT LIST_ENTRY *List\r
a405b86d 131 )\r
132{\r
47d20b54
MK
133 ALIAS_LIST *Node;\r
134 BOOLEAN Found;\r
a405b86d 135\r
136 //\r
137 // assert for NULL parameter\r
138 //\r
47d20b54 139 ASSERT (Alias != NULL);\r
a405b86d 140\r
141 //\r
142 // check for the Alias\r
143 //\r
47d20b54
MK
144 for ( Node = (ALIAS_LIST *)GetFirstNode (List), Found = FALSE\r
145 ; !IsNull (List, &Node->Link)\r
146 ; Node = (ALIAS_LIST *)GetNextNode (List, &Node->Link)\r
147 )\r
148 {\r
149 ASSERT (Node->CommandString != NULL);\r
150 ASSERT (Node->Alias != NULL);\r
151 if (StrCmp (Node->Alias, Alias) == 0) {\r
152 FreePool (Node->CommandString);\r
a405b86d 153 Node->CommandString = NULL;\r
47d20b54
MK
154 Node->CommandString = StrnCatGrow (&Node->CommandString, NULL, CommandString, 0);\r
155 Found = TRUE;\r
a405b86d 156 break;\r
157 }\r
158 }\r
47d20b54 159\r
a405b86d 160 if (!Found) {\r
47d20b54 161 Node = AllocateZeroPool (sizeof (ALIAS_LIST));\r
9ea69f8a 162 if (Node == NULL) {\r
163 return (EFI_OUT_OF_RESOURCES);\r
164 }\r
47d20b54
MK
165\r
166 ASSERT (Node->Alias == NULL);\r
167 Node->Alias = StrnCatGrow (&Node->Alias, NULL, Alias, 0);\r
168 ASSERT (Node->CommandString == NULL);\r
169 Node->CommandString = StrnCatGrow (&Node->CommandString, NULL, CommandString, 0);\r
170 InsertTailList (List, &Node->Link);\r
a405b86d 171 }\r
47d20b54 172\r
9ea69f8a 173 return (EFI_SUCCESS);\r
a405b86d 174}\r
175\r
176/**\r
177 Find out if an alias is on the given list.\r
178\r
179 @param[in] Alias The alias to test for.\r
180 @param[in] List The list to search.\r
181\r
182 @retval TRUE The alias is on the list.\r
183 @retval FALSE The alias is not on the list.\r
184**/\r
185BOOLEAN\r
47d20b54
MK
186InternalIsAliasOnList (\r
187 IN CONST CHAR16 *Alias,\r
188 IN CONST LIST_ENTRY *List\r
a405b86d 189 )\r
190{\r
47d20b54 191 ALIAS_LIST *Node;\r
a405b86d 192\r
193 //\r
194 // assert for NULL parameter\r
195 //\r
47d20b54 196 ASSERT (Alias != NULL);\r
a405b86d 197\r
198 //\r
199 // check for the Alias\r
200 //\r
47d20b54
MK
201 for ( Node = (ALIAS_LIST *)GetFirstNode (List)\r
202 ; !IsNull (List, &Node->Link)\r
203 ; Node = (ALIAS_LIST *)GetNextNode (List, &Node->Link)\r
204 )\r
205 {\r
206 ASSERT (Node->CommandString != NULL);\r
207 ASSERT (Node->Alias != NULL);\r
208 if (StrCmp (Node->Alias, Alias) == 0) {\r
a405b86d 209 return (TRUE);\r
210 }\r
211 }\r
47d20b54 212\r
a405b86d 213 return (FALSE);\r
214}\r
215\r
216/**\r
217 Remove an alias from the given list.\r
218\r
4ff7e37b
ED
219 @param[in] Alias The alias to remove.\r
220 @param[in, out] List The list to search.\r
a405b86d 221**/\r
222BOOLEAN\r
47d20b54
MK
223InternalRemoveAliasFromList (\r
224 IN CONST CHAR16 *Alias,\r
225 IN OUT LIST_ENTRY *List\r
a405b86d 226 )\r
227{\r
47d20b54 228 ALIAS_LIST *Node;\r
a405b86d 229\r
230 //\r
231 // assert for NULL parameter\r
232 //\r
47d20b54 233 ASSERT (Alias != NULL);\r
a405b86d 234\r
235 //\r
236 // check for the Alias\r
237 //\r
47d20b54
MK
238 for ( Node = (ALIAS_LIST *)GetFirstNode (List)\r
239 ; !IsNull (List, &Node->Link)\r
240 ; Node = (ALIAS_LIST *)GetNextNode (List, &Node->Link)\r
241 )\r
242 {\r
243 ASSERT (Node->CommandString != NULL);\r
244 ASSERT (Node->Alias != NULL);\r
245 if (StrCmp (Node->Alias, Alias) == 0) {\r
246 RemoveEntryList (&Node->Link);\r
247 FreePool (Node->Alias);\r
248 FreePool (Node->CommandString);\r
249 FreePool (Node);\r
a405b86d 250 return (TRUE);\r
251 }\r
252 }\r
47d20b54 253\r
a405b86d 254 return (FALSE);\r
255}\r
256\r
e82edcf9
JC
257/**\r
258 Function to determine whether a string is decimal or hex representation of a number\r
259 and return the number converted from the string.\r
260\r
261 @param[in] String String representation of a number\r
262\r
263 @return the number\r
264 @retval (UINTN)(-1) An error ocurred.\r
265**/\r
266UINTN\r
47d20b54
MK
267ReturnUintn (\r
268 IN CONST CHAR16 *String\r
e82edcf9
JC
269 )\r
270{\r
47d20b54 271 UINT64 RetVal;\r
e82edcf9 272\r
47d20b54 273 if (!EFI_ERROR (ShellConvertStringToUint64 (String, &RetVal, FALSE, TRUE))) {\r
e82edcf9
JC
274 return ((UINTN)RetVal);\r
275 }\r
47d20b54 276\r
e82edcf9
JC
277 return ((UINTN)(-1));\r
278}\r
279\r
a405b86d 280/**\r
281 Function for 'for' command.\r
282\r
283 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
284 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
285**/\r
286SHELL_STATUS\r
287EFIAPI\r
288ShellCommandRunFor (\r
289 IN EFI_HANDLE ImageHandle,\r
290 IN EFI_SYSTEM_TABLE *SystemTable\r
291 )\r
292{\r
47d20b54
MK
293 EFI_STATUS Status;\r
294 SHELL_STATUS ShellStatus;\r
295 SCRIPT_FILE *CurrentScriptFile;\r
296 CHAR16 *ArgSet;\r
297 CHAR16 *ArgSetWalker;\r
298 CHAR16 *Parameter;\r
299 UINTN ArgSize;\r
300 UINTN LoopVar;\r
301 SHELL_FOR_INFO *Info;\r
302 CHAR16 *TempString;\r
303 CHAR16 *TempSpot;\r
304 BOOLEAN FirstPass;\r
305 EFI_SHELL_FILE_INFO *Node;\r
306 EFI_SHELL_FILE_INFO *FileList;\r
307 UINTN NewSize;\r
308\r
309 ArgSet = NULL;\r
310 ArgSize = 0;\r
311 ShellStatus = SHELL_SUCCESS;\r
312 ArgSetWalker = NULL;\r
313 TempString = NULL;\r
314 Parameter = NULL;\r
315 FirstPass = FALSE;\r
a405b86d 316\r
317 //\r
318 // initialize the shell lib (we must be in non-auto-init...)\r
319 //\r
47d20b54
MK
320 Status = ShellInitialize ();\r
321 ASSERT_EFI_ERROR (Status);\r
a405b86d 322\r
47d20b54
MK
323 Status = CommandInit ();\r
324 ASSERT_EFI_ERROR (Status);\r
a405b86d 325\r
47d20b54
MK
326 if (!gEfiShellProtocol->BatchIsActive ()) {\r
327 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"for");\r
a405b86d 328 return (SHELL_UNSUPPORTED);\r
329 }\r
330\r
331 if (gEfiShellParametersProtocol->Argc < 4) {\r
47d20b54 332 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel1HiiHandle, L"for");\r
a405b86d 333 return (SHELL_INVALID_PARAMETER);\r
334 }\r
335\r
47d20b54
MK
336 CurrentScriptFile = ShellCommandGetCurrentScriptFile ();\r
337 ASSERT (CurrentScriptFile != NULL);\r
a405b86d 338\r
81cd2f53 339 if ((CurrentScriptFile->CurrentCommand != NULL) && (CurrentScriptFile->CurrentCommand->Data == NULL)) {\r
a405b86d 340 FirstPass = TRUE;\r
341\r
342 //\r
343 // Make sure that an End exists.\r
344 //\r
47d20b54
MK
345 if (!MoveToTag (GetNextNode, L"endfor", L"for", NULL, CurrentScriptFile, TRUE, TRUE, FALSE)) {\r
346 ShellPrintHiiEx (\r
ba0014b9
LG
347 -1,\r
348 -1,\r
349 NULL,\r
350 STRING_TOKEN (STR_SYNTAX_NO_MATCHING),\r
351 gShellLevel1HiiHandle,\r
352 L"EndFor",\r
353 L"For",\r
47d20b54
MK
354 CurrentScriptFile->CurrentCommand->Line\r
355 );\r
a405b86d 356 return (SHELL_DEVICE_ERROR);\r
357 }\r
358\r
359 //\r
360 // Process the line.\r
361 //\r
47d20b54
MK
362 if ( (gEfiShellParametersProtocol->Argv[1][0] != L'%') || (gEfiShellParametersProtocol->Argv[1][2] != CHAR_NULL)\r
363 || !( ((gEfiShellParametersProtocol->Argv[1][1] >= L'a') && (gEfiShellParametersProtocol->Argv[1][1] <= L'z'))\r
364 || ((gEfiShellParametersProtocol->Argv[1][1] >= L'A') && (gEfiShellParametersProtocol->Argv[1][1] <= L'Z')))\r
365 )\r
366 {\r
367 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_VAR), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[1]);\r
a405b86d 368 return (SHELL_INVALID_PARAMETER);\r
369 }\r
370\r
47d20b54
MK
371 if (gUnicodeCollation->StriColl (\r
372 gUnicodeCollation,\r
373 L"in",\r
374 gEfiShellParametersProtocol->Argv[2]\r
375 ) == 0)\r
376 {\r
377 for (LoopVar = 0x3; LoopVar < gEfiShellParametersProtocol->Argc; LoopVar++) {\r
378 ASSERT ((ArgSet == NULL && ArgSize == 0) || (ArgSet != NULL));\r
379 if ( (StrStr (gEfiShellParametersProtocol->Argv[LoopVar], L"*") != NULL)\r
380 || (StrStr (gEfiShellParametersProtocol->Argv[LoopVar], L"?") != NULL)\r
381 || (StrStr (gEfiShellParametersProtocol->Argv[LoopVar], L"[") != NULL)\r
382 || (StrStr (gEfiShellParametersProtocol->Argv[LoopVar], L"]") != NULL))\r
383 {\r
a405b86d 384 FileList = NULL;\r
47d20b54
MK
385 Status = ShellOpenFileMetaArg ((CHAR16 *)gEfiShellParametersProtocol->Argv[LoopVar], EFI_FILE_MODE_READ, &FileList);\r
386 if (EFI_ERROR (Status) || (FileList == NULL) || IsListEmpty (&FileList->Link)) {\r
387 ArgSet = StrnCatGrow (&ArgSet, &ArgSize, L" \"", 0);\r
388 ArgSet = StrnCatGrow (&ArgSet, &ArgSize, gEfiShellParametersProtocol->Argv[LoopVar], 0);\r
389 ArgSet = StrnCatGrow (&ArgSet, &ArgSize, L"\"", 0);\r
a405b86d 390 } else {\r
47d20b54
MK
391 for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link)\r
392 ; !IsNull (&FileList->Link, &Node->Link)\r
393 ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&FileList->Link, &Node->Link)\r
394 )\r
395 {\r
396 ArgSet = StrnCatGrow (&ArgSet, &ArgSize, L" \"", 0);\r
397 ArgSet = StrnCatGrow (&ArgSet, &ArgSize, Node->FullName, 0);\r
398 ArgSet = StrnCatGrow (&ArgSet, &ArgSize, L"\"", 0);\r
a405b86d 399 }\r
47d20b54
MK
400\r
401 ShellCloseFileMetaArg (&FileList);\r
a405b86d 402 }\r
403 } else {\r
3a3395f0 404 Parameter = gEfiShellParametersProtocol->Argv[LoopVar];\r
47d20b54
MK
405 if ((Parameter[0] == L'\"') && (Parameter[StrLen (Parameter)-1] == L'\"')) {\r
406 ArgSet = StrnCatGrow (&ArgSet, &ArgSize, L" ", 0);\r
407 ArgSet = StrnCatGrow (&ArgSet, &ArgSize, Parameter, 0);\r
3a3395f0 408 } else {\r
47d20b54
MK
409 ArgSet = StrnCatGrow (&ArgSet, &ArgSize, L" \"", 0);\r
410 ArgSet = StrnCatGrow (&ArgSet, &ArgSize, Parameter, 0);\r
411 ArgSet = StrnCatGrow (&ArgSet, &ArgSize, L"\"", 0);\r
3a3395f0 412 }\r
a405b86d 413 }\r
a405b86d 414 }\r
47d20b54 415\r
532691c8 416 if (ArgSet == NULL) {\r
417 ShellStatus = SHELL_OUT_OF_RESOURCES;\r
a405b86d 418 } else {\r
532691c8 419 //\r
420 // set up for an 'in' for loop\r
421 //\r
47d20b54
MK
422 NewSize = StrSize (ArgSet);\r
423 NewSize += sizeof (SHELL_FOR_INFO)+StrSize (gEfiShellParametersProtocol->Argv[1]);\r
424 Info = AllocateZeroPool (NewSize);\r
59b7dbac
RN
425 if (Info == NULL) {\r
426 FreePool (ArgSet);\r
427 return SHELL_OUT_OF_RESOURCES;\r
428 }\r
47d20b54 429\r
532691c8 430 Info->Signature = SHELL_FOR_INFO_SIGNATURE;\r
47d20b54
MK
431 CopyMem (Info->Set, ArgSet, StrSize (ArgSet));\r
432 NewSize = StrSize (gEfiShellParametersProtocol->Argv[1]);\r
433 CopyMem (Info->Set+(StrSize (ArgSet)/sizeof (Info->Set[0])), gEfiShellParametersProtocol->Argv[1], NewSize);\r
434 Info->ReplacementName = Info->Set+StrSize (ArgSet)/sizeof (Info->Set[0]);\r
435 Info->CurrentValue = (CHAR16 *)Info->Set;\r
436 Info->Step = 0;\r
437 Info->Current = 0;\r
438 Info->End = 0;\r
439\r
440 if (InternalIsAliasOnList (Info->ReplacementName, &CurrentScriptFile->SubstList)) {\r
441 Info->RemoveSubstAlias = FALSE;\r
532691c8 442 } else {\r
47d20b54 443 Info->RemoveSubstAlias = TRUE;\r
532691c8 444 }\r
47d20b54 445\r
532691c8 446 CurrentScriptFile->CurrentCommand->Data = Info;\r
a405b86d 447 }\r
47d20b54
MK
448 } else if (gUnicodeCollation->StriColl (\r
449 gUnicodeCollation,\r
450 L"run",\r
451 gEfiShellParametersProtocol->Argv[2]\r
452 ) == 0)\r
453 {\r
454 for (LoopVar = 0x3; LoopVar < gEfiShellParametersProtocol->Argc; LoopVar++) {\r
455 ASSERT ((ArgSet == NULL && ArgSize == 0) || (ArgSet != NULL));\r
456 if ((StrStr (gEfiShellParametersProtocol->Argv[LoopVar], L")") != NULL) &&\r
457 ((LoopVar + 1) < gEfiShellParametersProtocol->Argc)\r
458 )\r
459 {\r
8337590c
QS
460 return (SHELL_INVALID_PARAMETER);\r
461 }\r
47d20b54 462\r
a405b86d 463 if (ArgSet == NULL) {\r
47d20b54 464 // ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0);\r
a405b86d 465 } else {\r
47d20b54 466 ArgSet = StrnCatGrow (&ArgSet, &ArgSize, L" ", 0);\r
a405b86d 467 }\r
47d20b54
MK
468\r
469 ArgSet = StrnCatGrow (&ArgSet, &ArgSize, gEfiShellParametersProtocol->Argv[LoopVar], 0);\r
470 // ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" ", 0);\r
a405b86d 471 }\r
47d20b54 472\r
532691c8 473 if (ArgSet == NULL) {\r
474 ShellStatus = SHELL_OUT_OF_RESOURCES;\r
a405b86d 475 } else {\r
532691c8 476 //\r
477 // set up for a 'run' for loop\r
478 //\r
47d20b54 479 Info = AllocateZeroPool (sizeof (SHELL_FOR_INFO)+StrSize (gEfiShellParametersProtocol->Argv[1]));\r
59b7dbac
RN
480 if (Info == NULL) {\r
481 FreePool (ArgSet);\r
482 return SHELL_OUT_OF_RESOURCES;\r
483 }\r
47d20b54 484\r
b471606b 485 Info->Signature = SHELL_FOR_INFO_SIGNATURE;\r
47d20b54 486 CopyMem (Info->Set, gEfiShellParametersProtocol->Argv[1], StrSize (gEfiShellParametersProtocol->Argv[1]));\r
532691c8 487 Info->ReplacementName = Info->Set;\r
488 Info->CurrentValue = NULL;\r
47d20b54 489 ArgSetWalker = ArgSet;\r
532691c8 490 if (ArgSetWalker[0] != L'(') {\r
47d20b54 491 ShellPrintHiiEx (\r
ba0014b9
LG
492 -1,\r
493 -1,\r
494 NULL,\r
495 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT),\r
496 gShellLevel1HiiHandle,\r
497 ArgSet,\r
47d20b54
MK
498 CurrentScriptFile->CurrentCommand->Line\r
499 );\r
a405b86d 500 ShellStatus = SHELL_INVALID_PARAMETER;\r
501 } else {\r
47d20b54 502 TempSpot = StrStr (ArgSetWalker, L")");\r
532691c8 503 if (TempSpot != NULL) {\r
504 TempString = TempSpot+1;\r
505 if (*(TempString) != CHAR_NULL) {\r
47d20b54 506 while (TempString != NULL && *TempString == L' ') {\r
532691c8 507 TempString++;\r
508 }\r
47d20b54
MK
509\r
510 if (StrLen (TempString) > 0) {\r
532691c8 511 TempSpot = NULL;\r
512 }\r
513 }\r
a405b86d 514 }\r
47d20b54 515\r
532691c8 516 if (TempSpot == NULL) {\r
47d20b54 517 ShellPrintHiiEx (\r
ba0014b9
LG
518 -1,\r
519 -1,\r
520 NULL,\r
521 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT),\r
522 gShellLevel1HiiHandle,\r
47d20b54
MK
523 CurrentScriptFile->CurrentCommand->Line\r
524 );\r
a405b86d 525 ShellStatus = SHELL_INVALID_PARAMETER;\r
526 } else {\r
532691c8 527 *TempSpot = CHAR_NULL;\r
528 ArgSetWalker++;\r
a405b86d 529 while (ArgSetWalker != NULL && ArgSetWalker[0] == L' ') {\r
530 ArgSetWalker++;\r
531 }\r
47d20b54
MK
532\r
533 if (!ShellIsValidForNumber (ArgSetWalker)) {\r
534 ShellPrintHiiEx (\r
ba0014b9
LG
535 -1,\r
536 -1,\r
537 NULL,\r
538 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT),\r
539 gShellLevel1HiiHandle,\r
540 ArgSet,\r
47d20b54
MK
541 CurrentScriptFile->CurrentCommand->Line\r
542 );\r
77dcec12 543 ShellStatus = SHELL_INVALID_PARAMETER;\r
544 } else {\r
545 if (ArgSetWalker[0] == L'-') {\r
47d20b54 546 Info->Current = 0 - (INTN)ReturnUintn (ArgSetWalker+1);\r
77dcec12 547 } else {\r
47d20b54 548 Info->Current = (INTN)ReturnUintn (ArgSetWalker);\r
77dcec12 549 }\r
47d20b54
MK
550\r
551 ArgSetWalker = StrStr (ArgSetWalker, L" ");\r
77dcec12 552 while (ArgSetWalker != NULL && ArgSetWalker[0] == L' ') {\r
553 ArgSetWalker++;\r
554 }\r
47d20b54
MK
555\r
556 if ((ArgSetWalker == NULL) || (*ArgSetWalker == CHAR_NULL) || !ShellIsValidForNumber (ArgSetWalker)) {\r
557 ShellPrintHiiEx (\r
ba0014b9
LG
558 -1,\r
559 -1,\r
560 NULL,\r
561 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT),\r
562 gShellLevel1HiiHandle,\r
563 ArgSet,\r
47d20b54
MK
564 CurrentScriptFile->CurrentCommand->Line\r
565 );\r
532691c8 566 ShellStatus = SHELL_INVALID_PARAMETER;\r
567 } else {\r
568 if (ArgSetWalker[0] == L'-') {\r
47d20b54 569 Info->End = 0 - (INTN)ReturnUintn (ArgSetWalker+1);\r
a405b86d 570 } else {\r
47d20b54 571 Info->End = (INTN)ReturnUintn (ArgSetWalker);\r
532691c8 572 }\r
47d20b54 573\r
532691c8 574 if (Info->Current < Info->End) {\r
47d20b54 575 Info->Step = 1;\r
532691c8 576 } else {\r
47d20b54 577 Info->Step = -1;\r
532691c8 578 }\r
579\r
47d20b54 580 ArgSetWalker = StrStr (ArgSetWalker, L" ");\r
532691c8 581 while (ArgSetWalker != NULL && ArgSetWalker[0] == L' ') {\r
582 ArgSetWalker++;\r
583 }\r
47d20b54
MK
584\r
585 if ((ArgSetWalker != NULL) && (*ArgSetWalker != CHAR_NULL)) {\r
586 if ((ArgSetWalker == NULL) || (*ArgSetWalker == CHAR_NULL) || !ShellIsValidForNumber (ArgSetWalker)) {\r
587 ShellPrintHiiEx (\r
ba0014b9
LG
588 -1,\r
589 -1,\r
590 NULL,\r
591 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT),\r
592 gShellLevel1HiiHandle,\r
593 ArgSet,\r
47d20b54
MK
594 CurrentScriptFile->CurrentCommand->Line\r
595 );\r
532691c8 596 ShellStatus = SHELL_INVALID_PARAMETER;\r
a405b86d 597 } else {\r
532691c8 598 if (*ArgSetWalker == L')') {\r
47d20b54 599 ASSERT (Info->Step == 1 || Info->Step == -1);\r
a405b86d 600 } else {\r
532691c8 601 if (ArgSetWalker[0] == L'-') {\r
47d20b54 602 Info->Step = 0 - (INTN)ReturnUintn (ArgSetWalker+1);\r
532691c8 603 } else {\r
47d20b54 604 Info->Step = (INTN)ReturnUintn (ArgSetWalker);\r
532691c8 605 }\r
606\r
47d20b54
MK
607 if (StrStr (ArgSetWalker, L" ") != NULL) {\r
608 ShellPrintHiiEx (\r
ba0014b9
LG
609 -1,\r
610 -1,\r
611 NULL,\r
612 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT),\r
613 gShellLevel1HiiHandle,\r
614 ArgSet,\r
47d20b54
MK
615 CurrentScriptFile->CurrentCommand->Line\r
616 );\r
532691c8 617 ShellStatus = SHELL_INVALID_PARAMETER;\r
618 }\r
77dcec12 619 }\r
a405b86d 620 }\r
621 }\r
622 }\r
623 }\r
624 }\r
625 }\r
47d20b54 626\r
532691c8 627 if (ShellStatus == SHELL_SUCCESS) {\r
47d20b54
MK
628 if (InternalIsAliasOnList (Info->ReplacementName, &CurrentScriptFile->SubstList)) {\r
629 Info->RemoveSubstAlias = FALSE;\r
532691c8 630 } else {\r
47d20b54 631 Info->RemoveSubstAlias = TRUE;\r
532691c8 632 }\r
633 }\r
47d20b54 634\r
532691c8 635 if (CurrentScriptFile->CurrentCommand != NULL) {\r
636 CurrentScriptFile->CurrentCommand->Data = Info;\r
a405b86d 637 }\r
cbdd109b 638 }\r
a405b86d 639 } else {\r
47d20b54 640 ShellPrintHiiEx (\r
ba0014b9
LG
641 -1,\r
642 -1,\r
643 NULL,\r
644 STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT),\r
645 gShellLevel1HiiHandle,\r
646 ArgSet,\r
47d20b54
MK
647 CurrentScriptFile != NULL\r
648 && CurrentScriptFile->CurrentCommand != NULL\r
649 ? CurrentScriptFile->CurrentCommand->Line : 0\r
650 );\r
a405b86d 651 ShellStatus = SHELL_INVALID_PARAMETER;\r
652 }\r
653 } else {\r
654 //\r
655 // These need to be NULL since they are used to determine if this is the first pass later on...\r
656 //\r
47d20b54
MK
657 ASSERT (ArgSetWalker == NULL);\r
658 ASSERT (ArgSet == NULL);\r
a405b86d 659 }\r
660\r
47d20b54
MK
661 if ((CurrentScriptFile != NULL) && (CurrentScriptFile->CurrentCommand != NULL)) {\r
662 Info = (SHELL_FOR_INFO *)CurrentScriptFile->CurrentCommand->Data;\r
d8f8021c 663 if (CurrentScriptFile->CurrentCommand->Reset) {\r
7162fdb0 664 if (Info != NULL) {\r
47d20b54 665 Info->CurrentValue = (CHAR16 *)Info->Set;\r
7162fdb0 666 }\r
47d20b54
MK
667\r
668 FirstPass = TRUE;\r
d8f8021c 669 CurrentScriptFile->CurrentCommand->Reset = FALSE;\r
670 }\r
671 } else {\r
672 ShellStatus = SHELL_UNSUPPORTED;\r
47d20b54 673 Info = NULL;\r
a405b86d 674 }\r
47d20b54 675\r
a405b86d 676 if (ShellStatus == SHELL_SUCCESS) {\r
47d20b54 677 ASSERT (Info != NULL);\r
a405b86d 678 if (Info->Step != 0) {\r
679 //\r
680 // only advance if not the first pass\r
681 //\r
682 if (!FirstPass) {\r
683 //\r
684 // sequence version of for loop...\r
685 //\r
686 Info->Current += Info->Step;\r
687 }\r
688\r
47d20b54
MK
689 TempString = AllocateZeroPool (50*sizeof (CHAR16));\r
690 UnicodeSPrint (TempString, 50*sizeof (CHAR16), L"%d", Info->Current);\r
691 InternalUpdateAliasOnList (Info->ReplacementName, TempString, &CurrentScriptFile->SubstList);\r
692 FreePool (TempString);\r
a405b86d 693\r
47d20b54 694 if (((Info->Step > 0) && (Info->Current > Info->End)) || ((Info->Step < 0) && (Info->Current < Info->End))) {\r
a405b86d 695 CurrentScriptFile->CurrentCommand->Data = NULL;\r
696 //\r
697 // find the matching endfor (we're done with the loop)\r
698 //\r
47d20b54
MK
699 if (!MoveToTag (GetNextNode, L"endfor", L"for", NULL, CurrentScriptFile, TRUE, FALSE, FALSE)) {\r
700 ShellPrintHiiEx (\r
ba0014b9
LG
701 -1,\r
702 -1,\r
703 NULL,\r
704 STRING_TOKEN (STR_SYNTAX_NO_MATCHING),\r
705 gShellLevel1HiiHandle,\r
706 L"EndFor",\r
707 L"For",\r
47d20b54
MK
708 CurrentScriptFile != NULL\r
709 && CurrentScriptFile->CurrentCommand != NULL\r
710 ? CurrentScriptFile->CurrentCommand->Line : 0\r
711 );\r
a405b86d 712 ShellStatus = SHELL_DEVICE_ERROR;\r
713 }\r
47d20b54 714\r
a405b86d 715 if (Info->RemoveSubstAlias) {\r
716 //\r
717 // remove item from list\r
718 //\r
47d20b54 719 InternalRemoveAliasFromList (Info->ReplacementName, &CurrentScriptFile->SubstList);\r
a405b86d 720 }\r
47d20b54
MK
721\r
722 FreePool (Info);\r
a405b86d 723 }\r
724 } else {\r
725 //\r
726 // Must be in 'in' version of for loop...\r
727 //\r
47d20b54
MK
728 ASSERT (Info->Set != NULL);\r
729 if ((Info->CurrentValue != NULL) && (*Info->CurrentValue != CHAR_NULL)) {\r
b471606b 730 if (Info->CurrentValue[0] == L' ') {\r
a405b86d 731 Info->CurrentValue++;\r
732 }\r
47d20b54 733\r
a405b86d 734 if (Info->CurrentValue[0] == L'\"') {\r
735 Info->CurrentValue++;\r
736 }\r
47d20b54 737\r
a405b86d 738 //\r
739 // do the next one of the set\r
740 //\r
47d20b54
MK
741 ASSERT (TempString == NULL);\r
742 TempString = StrnCatGrow (&TempString, NULL, Info->CurrentValue, 0);\r
532691c8 743 if (TempString == NULL) {\r
744 ShellStatus = SHELL_OUT_OF_RESOURCES;\r
745 } else {\r
47d20b54 746 TempSpot = StrStr (TempString, L"\" \"");\r
532691c8 747 if (TempSpot != NULL) {\r
748 *TempSpot = CHAR_NULL;\r
749 }\r
47d20b54
MK
750\r
751 while (TempString[StrLen (TempString)-1] == L'\"') {\r
752 TempString[StrLen (TempString)-1] = CHAR_NULL;\r
532691c8 753 }\r
47d20b54
MK
754\r
755 InternalUpdateAliasOnList (Info->ReplacementName, TempString, &CurrentScriptFile->SubstList);\r
756 Info->CurrentValue += StrLen (TempString);\r
a405b86d 757\r
532691c8 758 if (Info->CurrentValue[0] == L'\"') {\r
759 Info->CurrentValue++;\r
760 }\r
47d20b54
MK
761\r
762 FreePool (TempString);\r
a405b86d 763 }\r
a405b86d 764 } else {\r
765 CurrentScriptFile->CurrentCommand->Data = NULL;\r
766 //\r
767 // find the matching endfor (we're done with the loop)\r
768 //\r
47d20b54
MK
769 if (!MoveToTag (GetNextNode, L"endfor", L"for", NULL, CurrentScriptFile, TRUE, FALSE, FALSE)) {\r
770 ShellPrintHiiEx (\r
ba0014b9
LG
771 -1,\r
772 -1,\r
773 NULL,\r
774 STRING_TOKEN (STR_SYNTAX_NO_MATCHING),\r
775 gShellLevel1HiiHandle,\r
776 L"EndFor",\r
777 L"For",\r
47d20b54
MK
778 CurrentScriptFile != NULL\r
779 && CurrentScriptFile->CurrentCommand != NULL\r
780 ? CurrentScriptFile->CurrentCommand->Line : 0\r
781 );\r
a405b86d 782 ShellStatus = SHELL_DEVICE_ERROR;\r
783 }\r
47d20b54 784\r
a405b86d 785 if (Info->RemoveSubstAlias) {\r
786 //\r
787 // remove item from list\r
788 //\r
47d20b54 789 InternalRemoveAliasFromList (Info->ReplacementName, &CurrentScriptFile->SubstList);\r
a405b86d 790 }\r
47d20b54
MK
791\r
792 FreePool (Info);\r
a405b86d 793 }\r
794 }\r
795 }\r
47d20b54 796\r
a405b86d 797 if (ArgSet != NULL) {\r
47d20b54 798 FreePool (ArgSet);\r
a405b86d 799 }\r
47d20b54 800\r
a405b86d 801 return (ShellStatus);\r
802}\r