REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the ShellPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Ray Ni <ray.ni@intel.com>
		
			
				
	
	
		
			803 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			803 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Main file for endfor and for shell level 1 functions.
 | 
						|
 | 
						|
  (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
 | 
						|
  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
 | 
						|
  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "UefiShellLevel1CommandsLib.h"
 | 
						|
#include <Library/PrintLib.h>
 | 
						|
 | 
						|
/**
 | 
						|
  Determine if a valid string is a valid number for the 'for' command.
 | 
						|
 | 
						|
  @param[in] Number The pointer to the string representation of the number to test.
 | 
						|
 | 
						|
  @retval TRUE    The number is valid.
 | 
						|
  @retval FALSE   The number is not valid.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
ShellIsValidForNumber (
 | 
						|
  IN CONST CHAR16  *Number
 | 
						|
  )
 | 
						|
{
 | 
						|
  if ((Number == NULL) || (*Number == CHAR_NULL)) {
 | 
						|
    return (FALSE);
 | 
						|
  }
 | 
						|
 | 
						|
  if (*Number == L'-') {
 | 
						|
    Number++;
 | 
						|
  }
 | 
						|
 | 
						|
  if (StrLen (Number) == 0) {
 | 
						|
    return (FALSE);
 | 
						|
  }
 | 
						|
 | 
						|
  if (StrLen (Number) >= 7) {
 | 
						|
    if ((StrStr (Number, L" ") == NULL) || (((StrStr (Number, L" ") != NULL) && ((StrStr (Number, L" ") - Number) >= 7)))) {
 | 
						|
      return (FALSE);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (!ShellIsDecimalDigitCharacter (*Number)) {
 | 
						|
    return (FALSE);
 | 
						|
  }
 | 
						|
 | 
						|
  return (TRUE);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Function for 'endfor' command.
 | 
						|
 | 
						|
  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
 | 
						|
  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
 | 
						|
**/
 | 
						|
SHELL_STATUS
 | 
						|
EFIAPI
 | 
						|
ShellCommandRunEndFor (
 | 
						|
  IN EFI_HANDLE        ImageHandle,
 | 
						|
  IN EFI_SYSTEM_TABLE  *SystemTable
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS   Status;
 | 
						|
  BOOLEAN      Found;
 | 
						|
  SCRIPT_FILE  *CurrentScriptFile;
 | 
						|
 | 
						|
  Status = CommandInit ();
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  if (!gEfiShellProtocol->BatchIsActive ()) {
 | 
						|
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"endfor");
 | 
						|
    return (SHELL_UNSUPPORTED);
 | 
						|
  }
 | 
						|
 | 
						|
  if (gEfiShellParametersProtocol->Argc > 1) {
 | 
						|
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel1HiiHandle, L"endfor");
 | 
						|
    return (SHELL_INVALID_PARAMETER);
 | 
						|
  }
 | 
						|
 | 
						|
  Found = MoveToTag (GetPreviousNode, L"for", L"endfor", NULL, ShellCommandGetCurrentScriptFile (), FALSE, FALSE, FALSE);
 | 
						|
 | 
						|
  if (!Found) {
 | 
						|
    CurrentScriptFile = ShellCommandGetCurrentScriptFile ();
 | 
						|
    ShellPrintHiiEx (
 | 
						|
      -1,
 | 
						|
      -1,
 | 
						|
      NULL,
 | 
						|
      STRING_TOKEN (STR_SYNTAX_NO_MATCHING),
 | 
						|
      gShellLevel1HiiHandle,
 | 
						|
      L"For",
 | 
						|
      L"EndFor",
 | 
						|
      CurrentScriptFile != NULL
 | 
						|
                    && CurrentScriptFile->CurrentCommand != NULL
 | 
						|
          ? CurrentScriptFile->CurrentCommand->Line : 0
 | 
						|
      );
 | 
						|
    return (SHELL_NOT_FOUND);
 | 
						|
  }
 | 
						|
 | 
						|
  return (SHELL_SUCCESS);
 | 
						|
}
 | 
						|
 | 
						|
typedef struct {
 | 
						|
  UINT32     Signature;
 | 
						|
  INTN       Current;
 | 
						|
  INTN       End;
 | 
						|
  INTN       Step;
 | 
						|
  CHAR16     *ReplacementName;
 | 
						|
  CHAR16     *CurrentValue;
 | 
						|
  BOOLEAN    RemoveSubstAlias;
 | 
						|
  CHAR16     Set[1];
 | 
						|
} SHELL_FOR_INFO;
 | 
						|
#define SIZE_OF_SHELL_FOR_INFO    OFFSET_OF (SHELL_FOR_INFO, Set)
 | 
						|
#define SHELL_FOR_INFO_SIGNATURE  SIGNATURE_32 ('S', 'F', 'I', 's')
 | 
						|
 | 
						|
/**
 | 
						|
  Update the value of a given alias on the list.  If the alias is not there then add it.
 | 
						|
 | 
						|
  @param[in] Alias               The alias to test for.
 | 
						|
  @param[in] CommandString       The updated command string.
 | 
						|
  @param[in, out] List           The list to search.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The operation was completed successfully.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES  There was not enough free memory.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
InternalUpdateAliasOnList (
 | 
						|
  IN CONST CHAR16    *Alias,
 | 
						|
  IN CONST CHAR16    *CommandString,
 | 
						|
  IN OUT LIST_ENTRY  *List
 | 
						|
  )
 | 
						|
{
 | 
						|
  ALIAS_LIST  *Node;
 | 
						|
  BOOLEAN     Found;
 | 
						|
 | 
						|
  //
 | 
						|
  // assert for NULL parameter
 | 
						|
  //
 | 
						|
  ASSERT (Alias != NULL);
 | 
						|
 | 
						|
  //
 | 
						|
  // check for the Alias
 | 
						|
  //
 | 
						|
  for ( Node = (ALIAS_LIST *)GetFirstNode (List), Found = FALSE
 | 
						|
        ; !IsNull (List, &Node->Link)
 | 
						|
        ; Node = (ALIAS_LIST *)GetNextNode (List, &Node->Link)
 | 
						|
        )
 | 
						|
  {
 | 
						|
    ASSERT (Node->CommandString != NULL);
 | 
						|
    ASSERT (Node->Alias != NULL);
 | 
						|
    if (StrCmp (Node->Alias, Alias) == 0) {
 | 
						|
      FreePool (Node->CommandString);
 | 
						|
      Node->CommandString = NULL;
 | 
						|
      Node->CommandString = StrnCatGrow (&Node->CommandString, NULL, CommandString, 0);
 | 
						|
      Found               = TRUE;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (!Found) {
 | 
						|
    Node = AllocateZeroPool (sizeof (ALIAS_LIST));
 | 
						|
    if (Node == NULL) {
 | 
						|
      return (EFI_OUT_OF_RESOURCES);
 | 
						|
    }
 | 
						|
 | 
						|
    ASSERT (Node->Alias == NULL);
 | 
						|
    Node->Alias = StrnCatGrow (&Node->Alias, NULL, Alias, 0);
 | 
						|
    ASSERT (Node->CommandString == NULL);
 | 
						|
    Node->CommandString = StrnCatGrow (&Node->CommandString, NULL, CommandString, 0);
 | 
						|
    InsertTailList (List, &Node->Link);
 | 
						|
  }
 | 
						|
 | 
						|
  return (EFI_SUCCESS);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Find out if an alias is on the given list.
 | 
						|
 | 
						|
  @param[in] Alias              The alias to test for.
 | 
						|
  @param[in] List               The list to search.
 | 
						|
 | 
						|
  @retval TRUE                  The alias is on the list.
 | 
						|
  @retval FALSE                 The alias is not on the list.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
InternalIsAliasOnList (
 | 
						|
  IN CONST CHAR16      *Alias,
 | 
						|
  IN CONST LIST_ENTRY  *List
 | 
						|
  )
 | 
						|
{
 | 
						|
  ALIAS_LIST  *Node;
 | 
						|
 | 
						|
  //
 | 
						|
  // assert for NULL parameter
 | 
						|
  //
 | 
						|
  ASSERT (Alias != NULL);
 | 
						|
 | 
						|
  //
 | 
						|
  // check for the Alias
 | 
						|
  //
 | 
						|
  for ( Node = (ALIAS_LIST *)GetFirstNode (List)
 | 
						|
        ; !IsNull (List, &Node->Link)
 | 
						|
        ; Node = (ALIAS_LIST *)GetNextNode (List, &Node->Link)
 | 
						|
        )
 | 
						|
  {
 | 
						|
    ASSERT (Node->CommandString != NULL);
 | 
						|
    ASSERT (Node->Alias != NULL);
 | 
						|
    if (StrCmp (Node->Alias, Alias) == 0) {
 | 
						|
      return (TRUE);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return (FALSE);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Remove an alias from the given list.
 | 
						|
 | 
						|
  @param[in] Alias               The alias to remove.
 | 
						|
  @param[in, out] List           The list to search.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
InternalRemoveAliasFromList (
 | 
						|
  IN CONST CHAR16    *Alias,
 | 
						|
  IN OUT LIST_ENTRY  *List
 | 
						|
  )
 | 
						|
{
 | 
						|
  ALIAS_LIST  *Node;
 | 
						|
 | 
						|
  //
 | 
						|
  // assert for NULL parameter
 | 
						|
  //
 | 
						|
  ASSERT (Alias != NULL);
 | 
						|
 | 
						|
  //
 | 
						|
  // check for the Alias
 | 
						|
  //
 | 
						|
  for ( Node = (ALIAS_LIST *)GetFirstNode (List)
 | 
						|
        ; !IsNull (List, &Node->Link)
 | 
						|
        ; Node = (ALIAS_LIST *)GetNextNode (List, &Node->Link)
 | 
						|
        )
 | 
						|
  {
 | 
						|
    ASSERT (Node->CommandString != NULL);
 | 
						|
    ASSERT (Node->Alias != NULL);
 | 
						|
    if (StrCmp (Node->Alias, Alias) == 0) {
 | 
						|
      RemoveEntryList (&Node->Link);
 | 
						|
      FreePool (Node->Alias);
 | 
						|
      FreePool (Node->CommandString);
 | 
						|
      FreePool (Node);
 | 
						|
      return (TRUE);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return (FALSE);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Function to determine whether a string is decimal or hex representation of a number
 | 
						|
  and return the number converted from the string.
 | 
						|
 | 
						|
  @param[in] String   String representation of a number
 | 
						|
 | 
						|
  @return             the number
 | 
						|
  @retval (UINTN)(-1) An error ocurred.
 | 
						|
**/
 | 
						|
UINTN
 | 
						|
ReturnUintn (
 | 
						|
  IN CONST CHAR16  *String
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT64  RetVal;
 | 
						|
 | 
						|
  if (!EFI_ERROR (ShellConvertStringToUint64 (String, &RetVal, FALSE, TRUE))) {
 | 
						|
    return ((UINTN)RetVal);
 | 
						|
  }
 | 
						|
 | 
						|
  return ((UINTN)(-1));
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Function for 'for' command.
 | 
						|
 | 
						|
  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
 | 
						|
  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
 | 
						|
**/
 | 
						|
SHELL_STATUS
 | 
						|
EFIAPI
 | 
						|
ShellCommandRunFor (
 | 
						|
  IN EFI_HANDLE        ImageHandle,
 | 
						|
  IN EFI_SYSTEM_TABLE  *SystemTable
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS           Status;
 | 
						|
  SHELL_STATUS         ShellStatus;
 | 
						|
  SCRIPT_FILE          *CurrentScriptFile;
 | 
						|
  CHAR16               *ArgSet;
 | 
						|
  CHAR16               *ArgSetWalker;
 | 
						|
  CHAR16               *Parameter;
 | 
						|
  UINTN                ArgSize;
 | 
						|
  UINTN                LoopVar;
 | 
						|
  SHELL_FOR_INFO       *Info;
 | 
						|
  CHAR16               *TempString;
 | 
						|
  CHAR16               *TempSpot;
 | 
						|
  BOOLEAN              FirstPass;
 | 
						|
  EFI_SHELL_FILE_INFO  *Node;
 | 
						|
  EFI_SHELL_FILE_INFO  *FileList;
 | 
						|
  UINTN                NewSize;
 | 
						|
 | 
						|
  ArgSet       = NULL;
 | 
						|
  ArgSize      = 0;
 | 
						|
  ShellStatus  = SHELL_SUCCESS;
 | 
						|
  ArgSetWalker = NULL;
 | 
						|
  TempString   = NULL;
 | 
						|
  Parameter    = NULL;
 | 
						|
  FirstPass    = FALSE;
 | 
						|
 | 
						|
  //
 | 
						|
  // initialize the shell lib (we must be in non-auto-init...)
 | 
						|
  //
 | 
						|
  Status = ShellInitialize ();
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  Status = CommandInit ();
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  if (!gEfiShellProtocol->BatchIsActive ()) {
 | 
						|
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"for");
 | 
						|
    return (SHELL_UNSUPPORTED);
 | 
						|
  }
 | 
						|
 | 
						|
  if (gEfiShellParametersProtocol->Argc < 4) {
 | 
						|
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel1HiiHandle, L"for");
 | 
						|
    return (SHELL_INVALID_PARAMETER);
 | 
						|
  }
 | 
						|
 | 
						|
  CurrentScriptFile = ShellCommandGetCurrentScriptFile ();
 | 
						|
  ASSERT (CurrentScriptFile != NULL);
 | 
						|
 | 
						|
  if ((CurrentScriptFile->CurrentCommand != NULL) && (CurrentScriptFile->CurrentCommand->Data == NULL)) {
 | 
						|
    FirstPass = TRUE;
 | 
						|
 | 
						|
    //
 | 
						|
    // Make sure that an End exists.
 | 
						|
    //
 | 
						|
    if (!MoveToTag (GetNextNode, L"endfor", L"for", NULL, CurrentScriptFile, TRUE, TRUE, FALSE)) {
 | 
						|
      ShellPrintHiiEx (
 | 
						|
        -1,
 | 
						|
        -1,
 | 
						|
        NULL,
 | 
						|
        STRING_TOKEN (STR_SYNTAX_NO_MATCHING),
 | 
						|
        gShellLevel1HiiHandle,
 | 
						|
        L"EndFor",
 | 
						|
        L"For",
 | 
						|
        CurrentScriptFile->CurrentCommand->Line
 | 
						|
        );
 | 
						|
      return (SHELL_DEVICE_ERROR);
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Process the line.
 | 
						|
    //
 | 
						|
    if (  (gEfiShellParametersProtocol->Argv[1][0] != L'%') || (gEfiShellParametersProtocol->Argv[1][2] != CHAR_NULL)
 | 
						|
       || !(  ((gEfiShellParametersProtocol->Argv[1][1] >= L'a') && (gEfiShellParametersProtocol->Argv[1][1] <= L'z'))
 | 
						|
           || ((gEfiShellParametersProtocol->Argv[1][1] >= L'A') && (gEfiShellParametersProtocol->Argv[1][1] <= L'Z')))
 | 
						|
          )
 | 
						|
    {
 | 
						|
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_VAR), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[1]);
 | 
						|
      return (SHELL_INVALID_PARAMETER);
 | 
						|
    }
 | 
						|
 | 
						|
    if (gUnicodeCollation->StriColl (
 | 
						|
                             gUnicodeCollation,
 | 
						|
                             L"in",
 | 
						|
                             gEfiShellParametersProtocol->Argv[2]
 | 
						|
                             ) == 0)
 | 
						|
    {
 | 
						|
      for (LoopVar = 0x3; LoopVar < gEfiShellParametersProtocol->Argc; LoopVar++) {
 | 
						|
        ASSERT ((ArgSet == NULL && ArgSize == 0) || (ArgSet != NULL));
 | 
						|
        if (  (StrStr (gEfiShellParametersProtocol->Argv[LoopVar], L"*") != NULL)
 | 
						|
           || (StrStr (gEfiShellParametersProtocol->Argv[LoopVar], L"?") != NULL)
 | 
						|
           || (StrStr (gEfiShellParametersProtocol->Argv[LoopVar], L"[") != NULL)
 | 
						|
           || (StrStr (gEfiShellParametersProtocol->Argv[LoopVar], L"]") != NULL))
 | 
						|
        {
 | 
						|
          FileList = NULL;
 | 
						|
          Status   = ShellOpenFileMetaArg ((CHAR16 *)gEfiShellParametersProtocol->Argv[LoopVar], EFI_FILE_MODE_READ, &FileList);
 | 
						|
          if (EFI_ERROR (Status) || (FileList == NULL) || IsListEmpty (&FileList->Link)) {
 | 
						|
            ArgSet = StrnCatGrow (&ArgSet, &ArgSize, L" \"", 0);
 | 
						|
            ArgSet = StrnCatGrow (&ArgSet, &ArgSize, gEfiShellParametersProtocol->Argv[LoopVar], 0);
 | 
						|
            ArgSet = StrnCatGrow (&ArgSet, &ArgSize, L"\"", 0);
 | 
						|
          } else {
 | 
						|
            for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link)
 | 
						|
                 ; !IsNull (&FileList->Link, &Node->Link)
 | 
						|
                 ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&FileList->Link, &Node->Link)
 | 
						|
                 )
 | 
						|
            {
 | 
						|
              ArgSet = StrnCatGrow (&ArgSet, &ArgSize, L" \"", 0);
 | 
						|
              ArgSet = StrnCatGrow (&ArgSet, &ArgSize, Node->FullName, 0);
 | 
						|
              ArgSet = StrnCatGrow (&ArgSet, &ArgSize, L"\"", 0);
 | 
						|
            }
 | 
						|
 | 
						|
            ShellCloseFileMetaArg (&FileList);
 | 
						|
          }
 | 
						|
        } else {
 | 
						|
          Parameter = gEfiShellParametersProtocol->Argv[LoopVar];
 | 
						|
          if ((Parameter[0] == L'\"') && (Parameter[StrLen (Parameter)-1] == L'\"')) {
 | 
						|
            ArgSet = StrnCatGrow (&ArgSet, &ArgSize, L" ", 0);
 | 
						|
            ArgSet = StrnCatGrow (&ArgSet, &ArgSize, Parameter, 0);
 | 
						|
          } else {
 | 
						|
            ArgSet = StrnCatGrow (&ArgSet, &ArgSize, L" \"", 0);
 | 
						|
            ArgSet = StrnCatGrow (&ArgSet, &ArgSize, Parameter, 0);
 | 
						|
            ArgSet = StrnCatGrow (&ArgSet, &ArgSize, L"\"", 0);
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      if (ArgSet == NULL) {
 | 
						|
        ShellStatus = SHELL_OUT_OF_RESOURCES;
 | 
						|
      } else {
 | 
						|
        //
 | 
						|
        // set up for an 'in' for loop
 | 
						|
        //
 | 
						|
        NewSize  = StrSize (ArgSet);
 | 
						|
        NewSize += sizeof (SHELL_FOR_INFO)+StrSize (gEfiShellParametersProtocol->Argv[1]);
 | 
						|
        Info     = AllocateZeroPool (NewSize);
 | 
						|
        if (Info == NULL) {
 | 
						|
          FreePool (ArgSet);
 | 
						|
          return SHELL_OUT_OF_RESOURCES;
 | 
						|
        }
 | 
						|
 | 
						|
        Info->Signature = SHELL_FOR_INFO_SIGNATURE;
 | 
						|
        CopyMem (Info->Set, ArgSet, StrSize (ArgSet));
 | 
						|
        NewSize = StrSize (gEfiShellParametersProtocol->Argv[1]);
 | 
						|
        CopyMem (Info->Set+(StrSize (ArgSet)/sizeof (Info->Set[0])), gEfiShellParametersProtocol->Argv[1], NewSize);
 | 
						|
        Info->ReplacementName = Info->Set+StrSize (ArgSet)/sizeof (Info->Set[0]);
 | 
						|
        Info->CurrentValue    = (CHAR16 *)Info->Set;
 | 
						|
        Info->Step            = 0;
 | 
						|
        Info->Current         = 0;
 | 
						|
        Info->End             = 0;
 | 
						|
 | 
						|
        if (InternalIsAliasOnList (Info->ReplacementName, &CurrentScriptFile->SubstList)) {
 | 
						|
          Info->RemoveSubstAlias = FALSE;
 | 
						|
        } else {
 | 
						|
          Info->RemoveSubstAlias = TRUE;
 | 
						|
        }
 | 
						|
 | 
						|
        CurrentScriptFile->CurrentCommand->Data = Info;
 | 
						|
      }
 | 
						|
    } else if (gUnicodeCollation->StriColl (
 | 
						|
                                    gUnicodeCollation,
 | 
						|
                                    L"run",
 | 
						|
                                    gEfiShellParametersProtocol->Argv[2]
 | 
						|
                                    ) == 0)
 | 
						|
    {
 | 
						|
      for (LoopVar = 0x3; LoopVar < gEfiShellParametersProtocol->Argc; LoopVar++) {
 | 
						|
        ASSERT ((ArgSet == NULL && ArgSize == 0) || (ArgSet != NULL));
 | 
						|
        if ((StrStr (gEfiShellParametersProtocol->Argv[LoopVar], L")") != NULL) &&
 | 
						|
            ((LoopVar + 1) < gEfiShellParametersProtocol->Argc)
 | 
						|
            )
 | 
						|
        {
 | 
						|
          return (SHELL_INVALID_PARAMETER);
 | 
						|
        }
 | 
						|
 | 
						|
        if (ArgSet == NULL) {
 | 
						|
          //        ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0);
 | 
						|
        } else {
 | 
						|
          ArgSet = StrnCatGrow (&ArgSet, &ArgSize, L" ", 0);
 | 
						|
        }
 | 
						|
 | 
						|
        ArgSet = StrnCatGrow (&ArgSet, &ArgSize, gEfiShellParametersProtocol->Argv[LoopVar], 0);
 | 
						|
        //        ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" ", 0);
 | 
						|
      }
 | 
						|
 | 
						|
      if (ArgSet == NULL) {
 | 
						|
        ShellStatus = SHELL_OUT_OF_RESOURCES;
 | 
						|
      } else {
 | 
						|
        //
 | 
						|
        // set up for a 'run' for loop
 | 
						|
        //
 | 
						|
        Info = AllocateZeroPool (sizeof (SHELL_FOR_INFO)+StrSize (gEfiShellParametersProtocol->Argv[1]));
 | 
						|
        if (Info == NULL) {
 | 
						|
          FreePool (ArgSet);
 | 
						|
          return SHELL_OUT_OF_RESOURCES;
 | 
						|
        }
 | 
						|
 | 
						|
        Info->Signature = SHELL_FOR_INFO_SIGNATURE;
 | 
						|
        CopyMem (Info->Set, gEfiShellParametersProtocol->Argv[1], StrSize (gEfiShellParametersProtocol->Argv[1]));
 | 
						|
        Info->ReplacementName = Info->Set;
 | 
						|
        Info->CurrentValue    = NULL;
 | 
						|
        ArgSetWalker          = ArgSet;
 | 
						|
        if (ArgSetWalker[0] != L'(') {
 | 
						|
          ShellPrintHiiEx (
 | 
						|
            -1,
 | 
						|
            -1,
 | 
						|
            NULL,
 | 
						|
            STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT),
 | 
						|
            gShellLevel1HiiHandle,
 | 
						|
            ArgSet,
 | 
						|
            CurrentScriptFile->CurrentCommand->Line
 | 
						|
            );
 | 
						|
          ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
        } else {
 | 
						|
          TempSpot = StrStr (ArgSetWalker, L")");
 | 
						|
          if (TempSpot != NULL) {
 | 
						|
            TempString = TempSpot+1;
 | 
						|
            if (*(TempString) != CHAR_NULL) {
 | 
						|
              while (TempString != NULL && *TempString == L' ') {
 | 
						|
                TempString++;
 | 
						|
              }
 | 
						|
 | 
						|
              if (StrLen (TempString) > 0) {
 | 
						|
                TempSpot = NULL;
 | 
						|
              }
 | 
						|
            }
 | 
						|
          }
 | 
						|
 | 
						|
          if (TempSpot == NULL) {
 | 
						|
            ShellPrintHiiEx (
 | 
						|
              -1,
 | 
						|
              -1,
 | 
						|
              NULL,
 | 
						|
              STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT),
 | 
						|
              gShellLevel1HiiHandle,
 | 
						|
              CurrentScriptFile->CurrentCommand->Line
 | 
						|
              );
 | 
						|
            ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
          } else {
 | 
						|
            *TempSpot = CHAR_NULL;
 | 
						|
            ArgSetWalker++;
 | 
						|
            while (ArgSetWalker != NULL && ArgSetWalker[0] == L' ') {
 | 
						|
              ArgSetWalker++;
 | 
						|
            }
 | 
						|
 | 
						|
            if (!ShellIsValidForNumber (ArgSetWalker)) {
 | 
						|
              ShellPrintHiiEx (
 | 
						|
                -1,
 | 
						|
                -1,
 | 
						|
                NULL,
 | 
						|
                STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT),
 | 
						|
                gShellLevel1HiiHandle,
 | 
						|
                ArgSet,
 | 
						|
                CurrentScriptFile->CurrentCommand->Line
 | 
						|
                );
 | 
						|
              ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
            } else {
 | 
						|
              if (ArgSetWalker[0] == L'-') {
 | 
						|
                Info->Current = 0 - (INTN)ReturnUintn (ArgSetWalker+1);
 | 
						|
              } else {
 | 
						|
                Info->Current = (INTN)ReturnUintn (ArgSetWalker);
 | 
						|
              }
 | 
						|
 | 
						|
              ArgSetWalker = StrStr (ArgSetWalker, L" ");
 | 
						|
              while (ArgSetWalker != NULL && ArgSetWalker[0] == L' ') {
 | 
						|
                ArgSetWalker++;
 | 
						|
              }
 | 
						|
 | 
						|
              if ((ArgSetWalker == NULL) || (*ArgSetWalker == CHAR_NULL) || !ShellIsValidForNumber (ArgSetWalker)) {
 | 
						|
                ShellPrintHiiEx (
 | 
						|
                  -1,
 | 
						|
                  -1,
 | 
						|
                  NULL,
 | 
						|
                  STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT),
 | 
						|
                  gShellLevel1HiiHandle,
 | 
						|
                  ArgSet,
 | 
						|
                  CurrentScriptFile->CurrentCommand->Line
 | 
						|
                  );
 | 
						|
                ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
              } else {
 | 
						|
                if (ArgSetWalker[0] == L'-') {
 | 
						|
                  Info->End = 0 - (INTN)ReturnUintn (ArgSetWalker+1);
 | 
						|
                } else {
 | 
						|
                  Info->End = (INTN)ReturnUintn (ArgSetWalker);
 | 
						|
                }
 | 
						|
 | 
						|
                if (Info->Current < Info->End) {
 | 
						|
                  Info->Step = 1;
 | 
						|
                } else {
 | 
						|
                  Info->Step = -1;
 | 
						|
                }
 | 
						|
 | 
						|
                ArgSetWalker = StrStr (ArgSetWalker, L" ");
 | 
						|
                while (ArgSetWalker != NULL && ArgSetWalker[0] == L' ') {
 | 
						|
                  ArgSetWalker++;
 | 
						|
                }
 | 
						|
 | 
						|
                if ((ArgSetWalker != NULL) && (*ArgSetWalker != CHAR_NULL)) {
 | 
						|
                  if ((ArgSetWalker == NULL) || (*ArgSetWalker == CHAR_NULL) || !ShellIsValidForNumber (ArgSetWalker)) {
 | 
						|
                    ShellPrintHiiEx (
 | 
						|
                      -1,
 | 
						|
                      -1,
 | 
						|
                      NULL,
 | 
						|
                      STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT),
 | 
						|
                      gShellLevel1HiiHandle,
 | 
						|
                      ArgSet,
 | 
						|
                      CurrentScriptFile->CurrentCommand->Line
 | 
						|
                      );
 | 
						|
                    ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
                  } else {
 | 
						|
                    if (*ArgSetWalker == L')') {
 | 
						|
                      ASSERT (Info->Step == 1 || Info->Step == -1);
 | 
						|
                    } else {
 | 
						|
                      if (ArgSetWalker[0] == L'-') {
 | 
						|
                        Info->Step = 0 - (INTN)ReturnUintn (ArgSetWalker+1);
 | 
						|
                      } else {
 | 
						|
                        Info->Step = (INTN)ReturnUintn (ArgSetWalker);
 | 
						|
                      }
 | 
						|
 | 
						|
                      if (StrStr (ArgSetWalker, L" ") != NULL) {
 | 
						|
                        ShellPrintHiiEx (
 | 
						|
                          -1,
 | 
						|
                          -1,
 | 
						|
                          NULL,
 | 
						|
                          STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT),
 | 
						|
                          gShellLevel1HiiHandle,
 | 
						|
                          ArgSet,
 | 
						|
                          CurrentScriptFile->CurrentCommand->Line
 | 
						|
                          );
 | 
						|
                        ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
                      }
 | 
						|
                    }
 | 
						|
                  }
 | 
						|
                }
 | 
						|
              }
 | 
						|
            }
 | 
						|
          }
 | 
						|
        }
 | 
						|
 | 
						|
        if (ShellStatus == SHELL_SUCCESS) {
 | 
						|
          if (InternalIsAliasOnList (Info->ReplacementName, &CurrentScriptFile->SubstList)) {
 | 
						|
            Info->RemoveSubstAlias = FALSE;
 | 
						|
          } else {
 | 
						|
            Info->RemoveSubstAlias = TRUE;
 | 
						|
          }
 | 
						|
        }
 | 
						|
 | 
						|
        if (CurrentScriptFile->CurrentCommand != NULL) {
 | 
						|
          CurrentScriptFile->CurrentCommand->Data = Info;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      ShellPrintHiiEx (
 | 
						|
        -1,
 | 
						|
        -1,
 | 
						|
        NULL,
 | 
						|
        STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT),
 | 
						|
        gShellLevel1HiiHandle,
 | 
						|
        ArgSet,
 | 
						|
        CurrentScriptFile != NULL
 | 
						|
                      && CurrentScriptFile->CurrentCommand != NULL
 | 
						|
          ? CurrentScriptFile->CurrentCommand->Line : 0
 | 
						|
        );
 | 
						|
      ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // These need to be NULL since they are used to determine if this is the first pass later on...
 | 
						|
    //
 | 
						|
    ASSERT (ArgSetWalker == NULL);
 | 
						|
    ASSERT (ArgSet       == NULL);
 | 
						|
  }
 | 
						|
 | 
						|
  if ((CurrentScriptFile != NULL) && (CurrentScriptFile->CurrentCommand != NULL)) {
 | 
						|
    Info = (SHELL_FOR_INFO *)CurrentScriptFile->CurrentCommand->Data;
 | 
						|
    if (CurrentScriptFile->CurrentCommand->Reset) {
 | 
						|
      if (Info != NULL) {
 | 
						|
        Info->CurrentValue = (CHAR16 *)Info->Set;
 | 
						|
      }
 | 
						|
 | 
						|
      FirstPass                                = TRUE;
 | 
						|
      CurrentScriptFile->CurrentCommand->Reset = FALSE;
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    ShellStatus = SHELL_UNSUPPORTED;
 | 
						|
    Info        = NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  if (ShellStatus == SHELL_SUCCESS) {
 | 
						|
    ASSERT (Info != NULL);
 | 
						|
    if (Info->Step != 0) {
 | 
						|
      //
 | 
						|
      // only advance if not the first pass
 | 
						|
      //
 | 
						|
      if (!FirstPass) {
 | 
						|
        //
 | 
						|
        // sequence version of for loop...
 | 
						|
        //
 | 
						|
        Info->Current += Info->Step;
 | 
						|
      }
 | 
						|
 | 
						|
      TempString = AllocateZeroPool (50*sizeof (CHAR16));
 | 
						|
      UnicodeSPrint (TempString, 50*sizeof (CHAR16), L"%d", Info->Current);
 | 
						|
      InternalUpdateAliasOnList (Info->ReplacementName, TempString, &CurrentScriptFile->SubstList);
 | 
						|
      FreePool (TempString);
 | 
						|
 | 
						|
      if (((Info->Step > 0) && (Info->Current > Info->End)) || ((Info->Step < 0) && (Info->Current < Info->End))) {
 | 
						|
        CurrentScriptFile->CurrentCommand->Data = NULL;
 | 
						|
        //
 | 
						|
        // find the matching endfor (we're done with the loop)
 | 
						|
        //
 | 
						|
        if (!MoveToTag (GetNextNode, L"endfor", L"for", NULL, CurrentScriptFile, TRUE, FALSE, FALSE)) {
 | 
						|
          ShellPrintHiiEx (
 | 
						|
            -1,
 | 
						|
            -1,
 | 
						|
            NULL,
 | 
						|
            STRING_TOKEN (STR_SYNTAX_NO_MATCHING),
 | 
						|
            gShellLevel1HiiHandle,
 | 
						|
            L"EndFor",
 | 
						|
            L"For",
 | 
						|
            CurrentScriptFile != NULL
 | 
						|
                          && CurrentScriptFile->CurrentCommand != NULL
 | 
						|
              ? CurrentScriptFile->CurrentCommand->Line : 0
 | 
						|
            );
 | 
						|
          ShellStatus = SHELL_DEVICE_ERROR;
 | 
						|
        }
 | 
						|
 | 
						|
        if (Info->RemoveSubstAlias) {
 | 
						|
          //
 | 
						|
          // remove item from list
 | 
						|
          //
 | 
						|
          InternalRemoveAliasFromList (Info->ReplacementName, &CurrentScriptFile->SubstList);
 | 
						|
        }
 | 
						|
 | 
						|
        FreePool (Info);
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      //
 | 
						|
      // Must be in 'in' version of for loop...
 | 
						|
      //
 | 
						|
      ASSERT (Info->Set != NULL);
 | 
						|
      if ((Info->CurrentValue != NULL) && (*Info->CurrentValue != CHAR_NULL)) {
 | 
						|
        if (Info->CurrentValue[0] == L' ') {
 | 
						|
          Info->CurrentValue++;
 | 
						|
        }
 | 
						|
 | 
						|
        if (Info->CurrentValue[0] == L'\"') {
 | 
						|
          Info->CurrentValue++;
 | 
						|
        }
 | 
						|
 | 
						|
        //
 | 
						|
        // do the next one of the set
 | 
						|
        //
 | 
						|
        ASSERT (TempString == NULL);
 | 
						|
        TempString = StrnCatGrow (&TempString, NULL, Info->CurrentValue, 0);
 | 
						|
        if (TempString == NULL) {
 | 
						|
          ShellStatus = SHELL_OUT_OF_RESOURCES;
 | 
						|
        } else {
 | 
						|
          TempSpot = StrStr (TempString, L"\" \"");
 | 
						|
          if (TempSpot != NULL) {
 | 
						|
            *TempSpot = CHAR_NULL;
 | 
						|
          }
 | 
						|
 | 
						|
          while (TempString[StrLen (TempString)-1] == L'\"') {
 | 
						|
            TempString[StrLen (TempString)-1] = CHAR_NULL;
 | 
						|
          }
 | 
						|
 | 
						|
          InternalUpdateAliasOnList (Info->ReplacementName, TempString, &CurrentScriptFile->SubstList);
 | 
						|
          Info->CurrentValue += StrLen (TempString);
 | 
						|
 | 
						|
          if (Info->CurrentValue[0] == L'\"') {
 | 
						|
            Info->CurrentValue++;
 | 
						|
          }
 | 
						|
 | 
						|
          FreePool (TempString);
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        CurrentScriptFile->CurrentCommand->Data = NULL;
 | 
						|
        //
 | 
						|
        // find the matching endfor (we're done with the loop)
 | 
						|
        //
 | 
						|
        if (!MoveToTag (GetNextNode, L"endfor", L"for", NULL, CurrentScriptFile, TRUE, FALSE, FALSE)) {
 | 
						|
          ShellPrintHiiEx (
 | 
						|
            -1,
 | 
						|
            -1,
 | 
						|
            NULL,
 | 
						|
            STRING_TOKEN (STR_SYNTAX_NO_MATCHING),
 | 
						|
            gShellLevel1HiiHandle,
 | 
						|
            L"EndFor",
 | 
						|
            L"For",
 | 
						|
            CurrentScriptFile != NULL
 | 
						|
                          && CurrentScriptFile->CurrentCommand != NULL
 | 
						|
              ? CurrentScriptFile->CurrentCommand->Line : 0
 | 
						|
            );
 | 
						|
          ShellStatus = SHELL_DEVICE_ERROR;
 | 
						|
        }
 | 
						|
 | 
						|
        if (Info->RemoveSubstAlias) {
 | 
						|
          //
 | 
						|
          // remove item from list
 | 
						|
          //
 | 
						|
          InternalRemoveAliasFromList (Info->ReplacementName, &CurrentScriptFile->SubstList);
 | 
						|
        }
 | 
						|
 | 
						|
        FreePool (Info);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (ArgSet != NULL) {
 | 
						|
    FreePool (ArgSet);
 | 
						|
  }
 | 
						|
 | 
						|
  return (ShellStatus);
 | 
						|
}
 |