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>
		
			
				
	
	
		
			1179 lines
		
	
	
		
			41 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1179 lines
		
	
	
		
			41 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Main file for If and else shell level 1 function.
 | 
						|
 | 
						|
  (C) Copyright 2013-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>
 | 
						|
 | 
						|
typedef enum {
 | 
						|
  EndTagOr,
 | 
						|
  EndTagAnd,
 | 
						|
  EndTagThen,
 | 
						|
  EndTagMax
 | 
						|
} END_TAG_TYPE;
 | 
						|
 | 
						|
typedef enum {
 | 
						|
  OperatorGreaterThan,
 | 
						|
  OperatorLessThan,
 | 
						|
  OperatorEqual,
 | 
						|
  OperatorNotEqual,
 | 
						|
  OperatorGreatorOrEqual,
 | 
						|
  OperatorLessOrEqual,
 | 
						|
  OperatorUnisgnedGreaterThan,
 | 
						|
  OperatorUnsignedLessThan,
 | 
						|
  OperatorUnsignedGreaterOrEqual,
 | 
						|
  OperatorUnsignedLessOrEqual,
 | 
						|
  OperatorMax
 | 
						|
} BIN_OPERATOR_TYPE;
 | 
						|
 | 
						|
/**
 | 
						|
  Extract the next fragment, if there is one.
 | 
						|
 | 
						|
  @param[in, out] Statement    The current remaining statement.
 | 
						|
  @param[in] Fragment          The current fragment.
 | 
						|
  @param[out] Match            TRUE when there is another Fragment in Statement,
 | 
						|
                               FALSE otherwise.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS          The match operation is performed successfully.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES Out of resources.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
IsNextFragment (
 | 
						|
  IN OUT CONST CHAR16  **Statement,
 | 
						|
  IN CONST CHAR16      *Fragment,
 | 
						|
  OUT BOOLEAN          *Match
 | 
						|
  )
 | 
						|
{
 | 
						|
  CHAR16  *Tester;
 | 
						|
 | 
						|
  Tester = NULL;
 | 
						|
 | 
						|
  Tester = StrnCatGrow (&Tester, NULL, *Statement, StrLen (Fragment));
 | 
						|
  if (Tester == NULL) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  Tester[StrLen (Fragment)] = CHAR_NULL;
 | 
						|
  if (gUnicodeCollation->StriColl (
 | 
						|
                           gUnicodeCollation,
 | 
						|
                           (CHAR16 *)Fragment,
 | 
						|
                           Tester
 | 
						|
                           ) == 0)
 | 
						|
  {
 | 
						|
    //
 | 
						|
    // increment the string pointer to the end of what we found and then chop off spaces...
 | 
						|
    //
 | 
						|
    *Statement += StrLen (Fragment);
 | 
						|
    while (*Statement[0] == L' ') {
 | 
						|
      (*Statement)++;
 | 
						|
    }
 | 
						|
 | 
						|
    *Match = TRUE;
 | 
						|
  } else {
 | 
						|
    *Match = FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  FreePool (Tester);
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Determine if String represents a valid profile.
 | 
						|
 | 
						|
  @param[in] String     The pointer to the string to test.
 | 
						|
 | 
						|
  @retval TRUE    String is a valid profile.
 | 
						|
  @retval FALSE   String is not a valid profile.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
IsValidProfile (
 | 
						|
  IN CONST CHAR16  *String
 | 
						|
  )
 | 
						|
{
 | 
						|
  CONST CHAR16  *ProfilesString;
 | 
						|
  CONST CHAR16  *TempLocation;
 | 
						|
 | 
						|
  ProfilesString = ShellGetEnvironmentVariable (L"profiles");
 | 
						|
  ASSERT (ProfilesString != NULL);
 | 
						|
  TempLocation = StrStr (ProfilesString, String);
 | 
						|
  if ((TempLocation != NULL) && (*(TempLocation-1) == L';') && (*(TempLocation+StrLen (String)) == L';')) {
 | 
						|
    return (TRUE);
 | 
						|
  }
 | 
						|
 | 
						|
  return (FALSE);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Do a comparison between 2 things.
 | 
						|
 | 
						|
  @param[in] Compare1           The first item to compare.
 | 
						|
  @param[in] Compare2           The second item to compare.
 | 
						|
  @param[in] BinOp              The type of comparison to perform.
 | 
						|
  @param[in] CaseInsensitive    TRUE to do non-case comparison, FALSE otherwise.
 | 
						|
  @param[in] ForceStringCompare TRUE to force string comparison, FALSE otherwise.
 | 
						|
 | 
						|
  @return     The result of the comparison.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
TestOperation (
 | 
						|
  IN CONST CHAR16             *Compare1,
 | 
						|
  IN CONST CHAR16             *Compare2,
 | 
						|
  IN CONST BIN_OPERATOR_TYPE  BinOp,
 | 
						|
  IN CONST BOOLEAN            CaseInsensitive,
 | 
						|
  IN CONST BOOLEAN            ForceStringCompare
 | 
						|
  )
 | 
						|
{
 | 
						|
  INTN  Cmp1;
 | 
						|
  INTN  Cmp2;
 | 
						|
 | 
						|
  //
 | 
						|
  // "Compare1 BinOp Compare2"
 | 
						|
  //
 | 
						|
  switch (BinOp) {
 | 
						|
    case OperatorUnisgnedGreaterThan:
 | 
						|
    case OperatorGreaterThan:
 | 
						|
      if (ForceStringCompare || !ShellIsHexOrDecimalNumber (Compare1, FALSE, FALSE) || !ShellIsHexOrDecimalNumber (Compare2, FALSE, FALSE)) {
 | 
						|
        //
 | 
						|
        // string compare
 | 
						|
        //
 | 
						|
        if ((CaseInsensitive && (StringNoCaseCompare (&Compare1, &Compare2) > 0)) || (StringCompare (&Compare1, &Compare2) > 0)) {
 | 
						|
          return (TRUE);
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        //
 | 
						|
        // numeric compare
 | 
						|
        //
 | 
						|
        if (Compare1[0] == L'-') {
 | 
						|
          Cmp1 = 0 - (INTN)ShellStrToUintn (Compare1+1);
 | 
						|
        } else {
 | 
						|
          Cmp1 = (INTN)ShellStrToUintn (Compare1);
 | 
						|
        }
 | 
						|
 | 
						|
        if (Compare2[0] == L'-') {
 | 
						|
          Cmp2 = 0 - (INTN)ShellStrToUintn (Compare2+1);
 | 
						|
        } else {
 | 
						|
          Cmp2 = (INTN)ShellStrToUintn (Compare2);
 | 
						|
        }
 | 
						|
 | 
						|
        if (BinOp == OperatorGreaterThan) {
 | 
						|
          if (Cmp1 > Cmp2) {
 | 
						|
            return (TRUE);
 | 
						|
          }
 | 
						|
        } else {
 | 
						|
          if ((UINTN)Cmp1 > (UINTN)Cmp2) {
 | 
						|
            return (TRUE);
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      return (FALSE);
 | 
						|
    case OperatorUnsignedLessThan:
 | 
						|
    case OperatorLessThan:
 | 
						|
      if (ForceStringCompare || !ShellIsHexOrDecimalNumber (Compare1, FALSE, FALSE) || !ShellIsHexOrDecimalNumber (Compare2, FALSE, FALSE)) {
 | 
						|
        //
 | 
						|
        // string compare
 | 
						|
        //
 | 
						|
        if ((CaseInsensitive && (StringNoCaseCompare (&Compare1, &Compare2) < 0)) || (StringCompare (&Compare1, &Compare2) < 0)) {
 | 
						|
          return (TRUE);
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        //
 | 
						|
        // numeric compare
 | 
						|
        //
 | 
						|
        if (Compare1[0] == L'-') {
 | 
						|
          Cmp1 = 0 - (INTN)ShellStrToUintn (Compare1+1);
 | 
						|
        } else {
 | 
						|
          Cmp1 = (INTN)ShellStrToUintn (Compare1);
 | 
						|
        }
 | 
						|
 | 
						|
        if (Compare2[0] == L'-') {
 | 
						|
          Cmp2 = 0 - (INTN)ShellStrToUintn (Compare2+1);
 | 
						|
        } else {
 | 
						|
          Cmp2 = (INTN)ShellStrToUintn (Compare2);
 | 
						|
        }
 | 
						|
 | 
						|
        if (BinOp == OperatorLessThan) {
 | 
						|
          if (Cmp1 < Cmp2) {
 | 
						|
            return (TRUE);
 | 
						|
          }
 | 
						|
        } else {
 | 
						|
          if ((UINTN)Cmp1 < (UINTN)Cmp2) {
 | 
						|
            return (TRUE);
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      return (FALSE);
 | 
						|
    case OperatorEqual:
 | 
						|
      if (ForceStringCompare || !ShellIsHexOrDecimalNumber (Compare1, FALSE, FALSE) || !ShellIsHexOrDecimalNumber (Compare2, FALSE, FALSE)) {
 | 
						|
        //
 | 
						|
        // string compare
 | 
						|
        //
 | 
						|
        if ((CaseInsensitive && (StringNoCaseCompare (&Compare1, &Compare2) == 0)) || (StringCompare (&Compare1, &Compare2) == 0)) {
 | 
						|
          return (TRUE);
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        //
 | 
						|
        // numeric compare
 | 
						|
        //
 | 
						|
        if (Compare1[0] == L'-') {
 | 
						|
          Cmp1 = 0 - (INTN)ShellStrToUintn (Compare1+1);
 | 
						|
        } else {
 | 
						|
          Cmp1 = (INTN)ShellStrToUintn (Compare1);
 | 
						|
        }
 | 
						|
 | 
						|
        if (Compare2[0] == L'-') {
 | 
						|
          Cmp2 = 0 - (INTN)ShellStrToUintn (Compare2+1);
 | 
						|
        } else {
 | 
						|
          Cmp2 = (INTN)ShellStrToUintn (Compare2);
 | 
						|
        }
 | 
						|
 | 
						|
        if (Cmp1 == Cmp2) {
 | 
						|
          return (TRUE);
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      return (FALSE);
 | 
						|
    case OperatorNotEqual:
 | 
						|
      if (ForceStringCompare || !ShellIsHexOrDecimalNumber (Compare1, FALSE, FALSE) || !ShellIsHexOrDecimalNumber (Compare2, FALSE, FALSE)) {
 | 
						|
        //
 | 
						|
        // string compare
 | 
						|
        //
 | 
						|
        if ((CaseInsensitive && (StringNoCaseCompare (&Compare1, &Compare2) != 0)) || (StringCompare (&Compare1, &Compare2) != 0)) {
 | 
						|
          return (TRUE);
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        //
 | 
						|
        // numeric compare
 | 
						|
        //
 | 
						|
        if (Compare1[0] == L'-') {
 | 
						|
          Cmp1 = 0 - (INTN)ShellStrToUintn (Compare1+1);
 | 
						|
        } else {
 | 
						|
          Cmp1 = (INTN)ShellStrToUintn (Compare1);
 | 
						|
        }
 | 
						|
 | 
						|
        if (Compare2[0] == L'-') {
 | 
						|
          Cmp2 = 0 - (INTN)ShellStrToUintn (Compare2+1);
 | 
						|
        } else {
 | 
						|
          Cmp2 = (INTN)ShellStrToUintn (Compare2);
 | 
						|
        }
 | 
						|
 | 
						|
        if (Cmp1 != Cmp2) {
 | 
						|
          return (TRUE);
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      return (FALSE);
 | 
						|
    case OperatorUnsignedGreaterOrEqual:
 | 
						|
    case OperatorGreatorOrEqual:
 | 
						|
      if (ForceStringCompare || !ShellIsHexOrDecimalNumber (Compare1, FALSE, FALSE) || !ShellIsHexOrDecimalNumber (Compare2, FALSE, FALSE)) {
 | 
						|
        //
 | 
						|
        // string compare
 | 
						|
        //
 | 
						|
        if ((CaseInsensitive && (StringNoCaseCompare (&Compare1, &Compare2) >= 0)) || (StringCompare (&Compare1, &Compare2) >= 0)) {
 | 
						|
          return (TRUE);
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        //
 | 
						|
        // numeric compare
 | 
						|
        //
 | 
						|
        if (Compare1[0] == L'-') {
 | 
						|
          Cmp1 = 0 - (INTN)ShellStrToUintn (Compare1+1);
 | 
						|
        } else {
 | 
						|
          Cmp1 = (INTN)ShellStrToUintn (Compare1);
 | 
						|
        }
 | 
						|
 | 
						|
        if (Compare2[0] == L'-') {
 | 
						|
          Cmp2 = 0 - (INTN)ShellStrToUintn (Compare2+1);
 | 
						|
        } else {
 | 
						|
          Cmp2 = (INTN)ShellStrToUintn (Compare2);
 | 
						|
        }
 | 
						|
 | 
						|
        if (BinOp == OperatorGreatorOrEqual) {
 | 
						|
          if (Cmp1 >= Cmp2) {
 | 
						|
            return (TRUE);
 | 
						|
          }
 | 
						|
        } else {
 | 
						|
          if ((UINTN)Cmp1 >= (UINTN)Cmp2) {
 | 
						|
            return (TRUE);
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      return (FALSE);
 | 
						|
    case OperatorLessOrEqual:
 | 
						|
    case OperatorUnsignedLessOrEqual:
 | 
						|
      if (ForceStringCompare || !ShellIsHexOrDecimalNumber (Compare1, FALSE, FALSE) || !ShellIsHexOrDecimalNumber (Compare2, FALSE, FALSE)) {
 | 
						|
        //
 | 
						|
        // string compare
 | 
						|
        //
 | 
						|
        if ((CaseInsensitive && (StringNoCaseCompare (&Compare1, &Compare2) <= 0)) || (StringCompare (&Compare1, &Compare2) <= 0)) {
 | 
						|
          return (TRUE);
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        //
 | 
						|
        // numeric compare
 | 
						|
        //
 | 
						|
        if (Compare1[0] == L'-') {
 | 
						|
          Cmp1 = 0 - (INTN)ShellStrToUintn (Compare1+1);
 | 
						|
        } else {
 | 
						|
          Cmp1 = (INTN)ShellStrToUintn (Compare1);
 | 
						|
        }
 | 
						|
 | 
						|
        if (Compare2[0] == L'-') {
 | 
						|
          Cmp2 = 0 - (INTN)ShellStrToUintn (Compare2+1);
 | 
						|
        } else {
 | 
						|
          Cmp2 = (INTN)ShellStrToUintn (Compare2);
 | 
						|
        }
 | 
						|
 | 
						|
        if (BinOp == OperatorLessOrEqual) {
 | 
						|
          if (Cmp1 <= Cmp2) {
 | 
						|
            return (TRUE);
 | 
						|
          }
 | 
						|
        } else {
 | 
						|
          if ((UINTN)Cmp1 <= (UINTN)Cmp2) {
 | 
						|
            return (TRUE);
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      return (FALSE);
 | 
						|
    default:
 | 
						|
      ASSERT (FALSE);
 | 
						|
      return (FALSE);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Process an if statement and determine if its is valid or not.
 | 
						|
 | 
						|
  @param[in, out] PassingState     Opon entry, the current state.  Upon exit,
 | 
						|
                                   the new state.
 | 
						|
  @param[in] StartParameterNumber  The number of the first parameter of
 | 
						|
                                   this statement.
 | 
						|
  @param[in] EndParameterNumber    The number of the final parameter of
 | 
						|
                                   this statement.
 | 
						|
  @param[in] OperatorToUse         The type of termination operator.
 | 
						|
  @param[in] CaseInsensitive       TRUE for case insensitive, FALSE otherwise.
 | 
						|
  @param[in] ForceStringCompare    TRUE for all string based, FALSE otherwise.
 | 
						|
 | 
						|
  @retval EFI_INVALID_PARAMETER   A parameter was invalid.
 | 
						|
  @retval EFI_SUCCESS             The operation was successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
ProcessStatement (
 | 
						|
  IN OUT BOOLEAN         *PassingState,
 | 
						|
  IN UINTN               StartParameterNumber,
 | 
						|
  IN UINTN               EndParameterNumber,
 | 
						|
  IN CONST END_TAG_TYPE  OperatorToUse,
 | 
						|
  IN CONST BOOLEAN       CaseInsensitive,
 | 
						|
  IN CONST BOOLEAN       ForceStringCompare
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS         Status;
 | 
						|
  BOOLEAN            OperationResult;
 | 
						|
  BOOLEAN            NotPresent;
 | 
						|
  CHAR16             *StatementWalker;
 | 
						|
  BIN_OPERATOR_TYPE  BinOp;
 | 
						|
  CHAR16             *Compare1;
 | 
						|
  CHAR16             *Compare2;
 | 
						|
  CHAR16             HexString[20];
 | 
						|
  CHAR16             *TempSpot;
 | 
						|
  BOOLEAN            Match;
 | 
						|
 | 
						|
  ASSERT ((END_TAG_TYPE)OperatorToUse != EndTagThen);
 | 
						|
 | 
						|
  Status          = EFI_SUCCESS;
 | 
						|
  BinOp           = OperatorMax;
 | 
						|
  OperationResult = FALSE;
 | 
						|
  Match           = FALSE;
 | 
						|
  StatementWalker = gEfiShellParametersProtocol->Argv[StartParameterNumber];
 | 
						|
  if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"not", &Match)) && Match) {
 | 
						|
    NotPresent      = TRUE;
 | 
						|
    StatementWalker = gEfiShellParametersProtocol->Argv[++StartParameterNumber];
 | 
						|
  } else {
 | 
						|
    NotPresent = FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // now check for 'boolfunc' operators
 | 
						|
  //
 | 
						|
  if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"isint", &Match)) && Match) {
 | 
						|
    if (  !EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"(", &Match)) && Match
 | 
						|
       && (StatementWalker[StrLen (StatementWalker)-1] == L')'))
 | 
						|
    {
 | 
						|
      StatementWalker[StrLen (StatementWalker)-1] = CHAR_NULL;
 | 
						|
      OperationResult                             = ShellIsHexOrDecimalNumber (StatementWalker, FALSE, FALSE);
 | 
						|
    } else {
 | 
						|
      Status = EFI_INVALID_PARAMETER;
 | 
						|
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"isint");
 | 
						|
    }
 | 
						|
  } else if ((!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"exists", &Match)) && Match) ||
 | 
						|
             (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"exist", &Match)) && Match))
 | 
						|
  {
 | 
						|
    if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"(", &Match)) && Match &&
 | 
						|
        (StatementWalker[StrLen (StatementWalker)-1] == L')'))
 | 
						|
    {
 | 
						|
      StatementWalker[StrLen (StatementWalker)-1] = CHAR_NULL;
 | 
						|
      //
 | 
						|
      // is what remains a file in CWD???
 | 
						|
      //
 | 
						|
      OperationResult = (BOOLEAN)(ShellFileExists (StatementWalker) == EFI_SUCCESS);
 | 
						|
    } else if ((StatementWalker[0] == CHAR_NULL) && (StartParameterNumber+1 == EndParameterNumber)) {
 | 
						|
      OperationResult = (BOOLEAN)(ShellFileExists (gEfiShellParametersProtocol->Argv[++StartParameterNumber]) == EFI_SUCCESS);
 | 
						|
    } else {
 | 
						|
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"exist(s)");
 | 
						|
      Status = EFI_INVALID_PARAMETER;
 | 
						|
    }
 | 
						|
  } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"available", &Match)) && Match) {
 | 
						|
    if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"(", &Match)) && Match &&
 | 
						|
        (StatementWalker[StrLen (StatementWalker)-1] == L')'))
 | 
						|
    {
 | 
						|
      StatementWalker[StrLen (StatementWalker)-1] = CHAR_NULL;
 | 
						|
      //
 | 
						|
      // is what remains a file in the CWD or path???
 | 
						|
      //
 | 
						|
      OperationResult = (BOOLEAN)(ShellIsFileInPath (StatementWalker) == EFI_SUCCESS);
 | 
						|
    } else {
 | 
						|
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"available");
 | 
						|
      Status = EFI_INVALID_PARAMETER;
 | 
						|
    }
 | 
						|
  } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"profile", &Match)) && Match) {
 | 
						|
    if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"(", &Match)) && Match &&
 | 
						|
        (StatementWalker[StrLen (StatementWalker)-1] == L')'))
 | 
						|
    {
 | 
						|
      //
 | 
						|
      // Chop off that ')'
 | 
						|
      //
 | 
						|
      StatementWalker[StrLen (StatementWalker)-1] = CHAR_NULL;
 | 
						|
      OperationResult                             = IsValidProfile (StatementWalker);
 | 
						|
    } else {
 | 
						|
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"profile");
 | 
						|
      Status = EFI_INVALID_PARAMETER;
 | 
						|
    }
 | 
						|
  } else if (StartParameterNumber+1 >= EndParameterNumber) {
 | 
						|
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[StartParameterNumber]);
 | 
						|
    Status = EFI_INVALID_PARAMETER;
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // must be 'item binop item' style
 | 
						|
    //
 | 
						|
    Compare1 = NULL;
 | 
						|
    Compare2 = NULL;
 | 
						|
    BinOp    = OperatorMax;
 | 
						|
 | 
						|
    //
 | 
						|
    // get the first item
 | 
						|
    //
 | 
						|
    StatementWalker = gEfiShellParametersProtocol->Argv[StartParameterNumber];
 | 
						|
    if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"efierror", &Match)) && Match) {
 | 
						|
      TempSpot = StrStr (StatementWalker, L")");
 | 
						|
      if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"(", &Match)) && Match && (TempSpot != NULL)) {
 | 
						|
        *TempSpot = CHAR_NULL;
 | 
						|
        if (ShellIsHexOrDecimalNumber (StatementWalker, FALSE, FALSE)) {
 | 
						|
          UnicodeSPrint (HexString, sizeof (HexString), L"0x%x", ShellStrToUintn (StatementWalker)|MAX_BIT);
 | 
						|
          ASSERT (Compare1 == NULL);
 | 
						|
          Compare1         = StrnCatGrow (&Compare1, NULL, HexString, 0);
 | 
						|
          StatementWalker += StrLen (StatementWalker) + 1;
 | 
						|
        } else {
 | 
						|
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"efierror");
 | 
						|
          Status = EFI_INVALID_PARAMETER;
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"efierror");
 | 
						|
        Status = EFI_INVALID_PARAMETER;
 | 
						|
      }
 | 
						|
    } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"pierror", &Match)) && Match) {
 | 
						|
      TempSpot = StrStr (StatementWalker, L")");
 | 
						|
      if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"(", &Match)) && Match && (TempSpot != NULL)) {
 | 
						|
        *TempSpot = CHAR_NULL;
 | 
						|
        if (ShellIsHexOrDecimalNumber (StatementWalker, FALSE, FALSE)) {
 | 
						|
          UnicodeSPrint (HexString, sizeof (HexString), L"0x%x", ShellStrToUintn (StatementWalker)|MAX_BIT|(MAX_BIT>>2));
 | 
						|
          ASSERT (Compare1 == NULL);
 | 
						|
          Compare1         = StrnCatGrow (&Compare1, NULL, HexString, 0);
 | 
						|
          StatementWalker += StrLen (StatementWalker) + 1;
 | 
						|
        } else {
 | 
						|
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"pierror");
 | 
						|
          Status = EFI_INVALID_PARAMETER;
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"pierror");
 | 
						|
        Status = EFI_INVALID_PARAMETER;
 | 
						|
      }
 | 
						|
    } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"oemerror", &Match)) && Match) {
 | 
						|
      TempSpot = StrStr (StatementWalker, L")");
 | 
						|
      if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"(", &Match)) && Match && (TempSpot != NULL)) {
 | 
						|
        TempSpot = CHAR_NULL;
 | 
						|
        if (ShellIsHexOrDecimalNumber (StatementWalker, FALSE, FALSE)) {
 | 
						|
          UnicodeSPrint (HexString, sizeof (HexString), L"0x%x", ShellStrToUintn (StatementWalker)|MAX_BIT|(MAX_BIT>>1));
 | 
						|
          ASSERT (Compare1 == NULL);
 | 
						|
          Compare1         = StrnCatGrow (&Compare1, NULL, HexString, 0);
 | 
						|
          StatementWalker += StrLen (StatementWalker) + 1;
 | 
						|
        } else {
 | 
						|
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"oemerror");
 | 
						|
          Status = EFI_INVALID_PARAMETER;
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"oemerror");
 | 
						|
        Status = EFI_INVALID_PARAMETER;
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      ASSERT (Compare1 == NULL);
 | 
						|
      if (EndParameterNumber - StartParameterNumber > 2) {
 | 
						|
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_STARTING), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[StartParameterNumber+2]);
 | 
						|
        Status = EFI_INVALID_PARAMETER;
 | 
						|
      } else {
 | 
						|
        //
 | 
						|
        // must be a raw string
 | 
						|
        //
 | 
						|
        Compare1 = StrnCatGrow (&Compare1, NULL, StatementWalker, 0);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // get the operator
 | 
						|
    //
 | 
						|
    ASSERT (StartParameterNumber+1 < EndParameterNumber);
 | 
						|
    StatementWalker = gEfiShellParametersProtocol->Argv[StartParameterNumber+1];
 | 
						|
    if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"gt", &Match)) && Match) {
 | 
						|
      BinOp = OperatorGreaterThan;
 | 
						|
    } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"lt", &Match)) && Match) {
 | 
						|
      BinOp = OperatorLessThan;
 | 
						|
    } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"eq", &Match)) && Match) {
 | 
						|
      BinOp = OperatorEqual;
 | 
						|
    } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"ne", &Match)) && Match) {
 | 
						|
      BinOp = OperatorNotEqual;
 | 
						|
    } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"ge", &Match)) && Match) {
 | 
						|
      BinOp = OperatorGreatorOrEqual;
 | 
						|
    } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"le", &Match)) && Match) {
 | 
						|
      BinOp = OperatorLessOrEqual;
 | 
						|
    } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"==", &Match)) && Match) {
 | 
						|
      BinOp = OperatorEqual;
 | 
						|
    } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"ugt", &Match)) && Match) {
 | 
						|
      BinOp = OperatorUnisgnedGreaterThan;
 | 
						|
    } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"ult", &Match)) && Match) {
 | 
						|
      BinOp = OperatorUnsignedLessThan;
 | 
						|
    } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"uge", &Match)) && Match) {
 | 
						|
      BinOp = OperatorUnsignedGreaterOrEqual;
 | 
						|
    } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"ule", &Match)) && Match) {
 | 
						|
      BinOp = OperatorUnsignedLessOrEqual;
 | 
						|
    } else {
 | 
						|
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_INVALID_BINOP), gShellLevel1HiiHandle, StatementWalker);
 | 
						|
      Status = EFI_INVALID_PARAMETER;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // get the second item
 | 
						|
    //
 | 
						|
    ASSERT (StartParameterNumber+2 <= EndParameterNumber);
 | 
						|
    StatementWalker = gEfiShellParametersProtocol->Argv[StartParameterNumber+2];
 | 
						|
    if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"efierror", &Match)) && Match) {
 | 
						|
      TempSpot = StrStr (StatementWalker, L")");
 | 
						|
      if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"(", &Match)) && Match && (TempSpot != NULL)) {
 | 
						|
        TempSpot = CHAR_NULL;
 | 
						|
        if (ShellIsHexOrDecimalNumber (StatementWalker, FALSE, FALSE)) {
 | 
						|
          UnicodeSPrint (HexString, sizeof (HexString), L"0x%x", ShellStrToUintn (StatementWalker)|MAX_BIT);
 | 
						|
          ASSERT (Compare2 == NULL);
 | 
						|
          Compare2         = StrnCatGrow (&Compare2, NULL, HexString, 0);
 | 
						|
          StatementWalker += StrLen (StatementWalker) + 1;
 | 
						|
        } else {
 | 
						|
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"efierror");
 | 
						|
          Status = EFI_INVALID_PARAMETER;
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"efierror");
 | 
						|
        Status = EFI_INVALID_PARAMETER;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      // can this be collapsed into the above?
 | 
						|
      //
 | 
						|
    } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"pierror", &Match)) && Match) {
 | 
						|
      TempSpot = StrStr (StatementWalker, L")");
 | 
						|
      if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"(", &Match)) && Match && (TempSpot != NULL)) {
 | 
						|
        TempSpot = CHAR_NULL;
 | 
						|
        if (ShellIsHexOrDecimalNumber (StatementWalker, FALSE, FALSE)) {
 | 
						|
          UnicodeSPrint (HexString, sizeof (HexString), L"0x%x", ShellStrToUintn (StatementWalker)|MAX_BIT|(MAX_BIT>>2));
 | 
						|
          ASSERT (Compare2 == NULL);
 | 
						|
          Compare2         = StrnCatGrow (&Compare2, NULL, HexString, 0);
 | 
						|
          StatementWalker += StrLen (StatementWalker) + 1;
 | 
						|
        } else {
 | 
						|
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"pierror");
 | 
						|
          Status = EFI_INVALID_PARAMETER;
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"pierror");
 | 
						|
        Status = EFI_INVALID_PARAMETER;
 | 
						|
      }
 | 
						|
    } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"oemerror", &Match)) && Match) {
 | 
						|
      TempSpot = StrStr (StatementWalker, L")");
 | 
						|
      if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"(", &Match)) && Match && (TempSpot != NULL)) {
 | 
						|
        TempSpot = CHAR_NULL;
 | 
						|
        if (ShellIsHexOrDecimalNumber (StatementWalker, FALSE, FALSE)) {
 | 
						|
          UnicodeSPrint (HexString, sizeof (HexString), L"0x%x", ShellStrToUintn (StatementWalker)|MAX_BIT|(MAX_BIT>>1));
 | 
						|
          ASSERT (Compare2 == NULL);
 | 
						|
          Compare2         = StrnCatGrow (&Compare2, NULL, HexString, 0);
 | 
						|
          StatementWalker += StrLen (StatementWalker) + 1;
 | 
						|
        } else {
 | 
						|
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"oemerror");
 | 
						|
          Status = EFI_INVALID_PARAMETER;
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"oemerror");
 | 
						|
        Status = EFI_INVALID_PARAMETER;
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      //
 | 
						|
      // must be a raw string
 | 
						|
      //
 | 
						|
      ASSERT (Compare2 == NULL);
 | 
						|
      Compare2 = StrnCatGrow (&Compare2, NULL, StatementWalker, 0);
 | 
						|
    }
 | 
						|
 | 
						|
    if ((Compare1 != NULL) && (Compare2 != NULL) && (BinOp != OperatorMax)) {
 | 
						|
      OperationResult = TestOperation (Compare1, Compare2, BinOp, CaseInsensitive, ForceStringCompare);
 | 
						|
    }
 | 
						|
 | 
						|
    SHELL_FREE_NON_NULL (Compare1);
 | 
						|
    SHELL_FREE_NON_NULL (Compare2);
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // done processing do result...
 | 
						|
  //
 | 
						|
 | 
						|
  if (!EFI_ERROR (Status)) {
 | 
						|
    if (NotPresent) {
 | 
						|
      OperationResult = (BOOLEAN)(!OperationResult);
 | 
						|
    }
 | 
						|
 | 
						|
    switch (OperatorToUse) {
 | 
						|
      case EndTagOr:
 | 
						|
        *PassingState = (BOOLEAN)(*PassingState || OperationResult);
 | 
						|
        break;
 | 
						|
      case EndTagAnd:
 | 
						|
        *PassingState = (BOOLEAN)(*PassingState && OperationResult);
 | 
						|
        break;
 | 
						|
      case EndTagMax:
 | 
						|
        *PassingState = (BOOLEAN)(OperationResult);
 | 
						|
        break;
 | 
						|
      default:
 | 
						|
        ASSERT (FALSE);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return (Status);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Break up the next part of the if statement (until the next 'and', 'or', or 'then').
 | 
						|
 | 
						|
  @param[in] ParameterNumber      The current parameter number.
 | 
						|
  @param[out] EndParameter        Upon successful return, will point to the
 | 
						|
                                  parameter to start the next iteration with.
 | 
						|
  @param[out] EndTag              Upon successful return, will point to the
 | 
						|
                                  type that was found at the end of this statement.
 | 
						|
 | 
						|
  @retval TRUE    A valid statement was found.
 | 
						|
  @retval FALSE   A valid statement was not found.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
BuildNextStatement (
 | 
						|
  IN UINTN          ParameterNumber,
 | 
						|
  OUT UINTN         *EndParameter,
 | 
						|
  OUT END_TAG_TYPE  *EndTag
 | 
						|
  )
 | 
						|
{
 | 
						|
  *EndTag = EndTagMax;
 | 
						|
 | 
						|
  for (
 | 
						|
       ; ParameterNumber < gEfiShellParametersProtocol->Argc
 | 
						|
       ; ParameterNumber++
 | 
						|
       )
 | 
						|
  {
 | 
						|
    if (gUnicodeCollation->StriColl (
 | 
						|
                             gUnicodeCollation,
 | 
						|
                             gEfiShellParametersProtocol->Argv[ParameterNumber],
 | 
						|
                             L"or"
 | 
						|
                             ) == 0)
 | 
						|
    {
 | 
						|
      *EndParameter = ParameterNumber - 1;
 | 
						|
      *EndTag       = EndTagOr;
 | 
						|
      break;
 | 
						|
    } else if (gUnicodeCollation->StriColl (
 | 
						|
                                    gUnicodeCollation,
 | 
						|
                                    gEfiShellParametersProtocol->Argv[ParameterNumber],
 | 
						|
                                    L"and"
 | 
						|
                                    ) == 0)
 | 
						|
    {
 | 
						|
      *EndParameter = ParameterNumber - 1;
 | 
						|
      *EndTag       = EndTagAnd;
 | 
						|
      break;
 | 
						|
    } else if (gUnicodeCollation->StriColl (
 | 
						|
                                    gUnicodeCollation,
 | 
						|
                                    gEfiShellParametersProtocol->Argv[ParameterNumber],
 | 
						|
                                    L"then"
 | 
						|
                                    ) == 0)
 | 
						|
    {
 | 
						|
      *EndParameter = ParameterNumber - 1;
 | 
						|
      *EndTag       = EndTagThen;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (*EndTag == EndTagMax) {
 | 
						|
    return (FALSE);
 | 
						|
  }
 | 
						|
 | 
						|
  return (TRUE);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Move the script file pointer to a different place in the script file.
 | 
						|
  This one is special since it handles the if/else/endif syntax.
 | 
						|
 | 
						|
  @param[in] ScriptFile     The script file from GetCurrnetScriptFile().
 | 
						|
 | 
						|
  @retval TRUE     The move target was found and the move was successful.
 | 
						|
  @retval FALSE    Something went wrong.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
MoveToTagSpecial (
 | 
						|
  IN SCRIPT_FILE  *ScriptFile
 | 
						|
  )
 | 
						|
{
 | 
						|
  SCRIPT_COMMAND_LIST  *CommandNode;
 | 
						|
  BOOLEAN              Found;
 | 
						|
  UINTN                TargetCount;
 | 
						|
  CHAR16               *CommandName;
 | 
						|
  CHAR16               *CommandWalker;
 | 
						|
  CHAR16               *TempLocation;
 | 
						|
 | 
						|
  TargetCount = 1;
 | 
						|
  Found       = FALSE;
 | 
						|
 | 
						|
  if (ScriptFile == NULL) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  for (CommandNode = (SCRIPT_COMMAND_LIST *)GetNextNode (&ScriptFile->CommandList, &ScriptFile->CurrentCommand->Link), Found = FALSE
 | 
						|
       ; !IsNull (&ScriptFile->CommandList, &CommandNode->Link) && !Found
 | 
						|
       ; CommandNode = (SCRIPT_COMMAND_LIST *)GetNextNode (&ScriptFile->CommandList, &CommandNode->Link)
 | 
						|
       )
 | 
						|
  {
 | 
						|
    //
 | 
						|
    // get just the first part of the command line...
 | 
						|
    //
 | 
						|
    CommandName = NULL;
 | 
						|
    CommandName = StrnCatGrow (&CommandName, NULL, CommandNode->Cl, 0);
 | 
						|
    if (CommandName == NULL) {
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    CommandWalker = CommandName;
 | 
						|
 | 
						|
    //
 | 
						|
    // Skip leading spaces and tabs.
 | 
						|
    //
 | 
						|
    while ((CommandWalker[0] == L' ') || (CommandWalker[0] == L'\t')) {
 | 
						|
      CommandWalker++;
 | 
						|
    }
 | 
						|
 | 
						|
    TempLocation = StrStr (CommandWalker, L" ");
 | 
						|
 | 
						|
    if (TempLocation != NULL) {
 | 
						|
      *TempLocation = CHAR_NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // did we find a nested item ?
 | 
						|
    //
 | 
						|
    if (gUnicodeCollation->StriColl (
 | 
						|
                             gUnicodeCollation,
 | 
						|
                             (CHAR16 *)CommandWalker,
 | 
						|
                             L"If"
 | 
						|
                             ) == 0)
 | 
						|
    {
 | 
						|
      TargetCount++;
 | 
						|
    } else if ((TargetCount == 1) && (gUnicodeCollation->StriColl (
 | 
						|
                                                           gUnicodeCollation,
 | 
						|
                                                           (CHAR16 *)CommandWalker,
 | 
						|
                                                           (CHAR16 *)L"else"
 | 
						|
                                                           ) == 0))
 | 
						|
    {
 | 
						|
      //
 | 
						|
      // else can only decrement the last part... not an nested if
 | 
						|
      // hence the TargetCount compare added
 | 
						|
      //
 | 
						|
      TargetCount--;
 | 
						|
    } else if (gUnicodeCollation->StriColl (
 | 
						|
                                    gUnicodeCollation,
 | 
						|
                                    (CHAR16 *)CommandWalker,
 | 
						|
                                    (CHAR16 *)L"endif"
 | 
						|
                                    ) == 0)
 | 
						|
    {
 | 
						|
      TargetCount--;
 | 
						|
    }
 | 
						|
 | 
						|
    if (TargetCount == 0) {
 | 
						|
      ScriptFile->CurrentCommand = (SCRIPT_COMMAND_LIST *)GetNextNode (&ScriptFile->CommandList, &CommandNode->Link);
 | 
						|
      Found                      = TRUE;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Free the memory for this loop...
 | 
						|
    //
 | 
						|
    SHELL_FREE_NON_NULL (CommandName);
 | 
						|
  }
 | 
						|
 | 
						|
  return (Found);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Deal with the result of the if operation.
 | 
						|
 | 
						|
  @param[in] Result     The result of the if.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       The operation was successful.
 | 
						|
  @retval EFI_NOT_FOUND     The ending tag could not be found.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
PerformResultOperation (
 | 
						|
  IN CONST BOOLEAN  Result
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (Result || MoveToTagSpecial (ShellCommandGetCurrentScriptFile ())) {
 | 
						|
    return (EFI_SUCCESS);
 | 
						|
  }
 | 
						|
 | 
						|
  return (EFI_NOT_FOUND);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Function for 'if' 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
 | 
						|
ShellCommandRunIf (
 | 
						|
  IN EFI_HANDLE        ImageHandle,
 | 
						|
  IN EFI_SYSTEM_TABLE  *SystemTable
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS    Status;
 | 
						|
  SHELL_STATUS  ShellStatus;
 | 
						|
  BOOLEAN       CaseInsensitive;
 | 
						|
  BOOLEAN       ForceString;
 | 
						|
  UINTN         CurrentParameter;
 | 
						|
  UINTN         EndParameter;
 | 
						|
  BOOLEAN       CurrentValue;
 | 
						|
  END_TAG_TYPE  Ending;
 | 
						|
  END_TAG_TYPE  PreviousEnding;
 | 
						|
  SCRIPT_FILE   *CurrentScriptFile;
 | 
						|
 | 
						|
  Status = CommandInit ();
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  if (!gEfiShellProtocol->BatchIsActive ()) {
 | 
						|
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"if");
 | 
						|
    return (SHELL_UNSUPPORTED);
 | 
						|
  }
 | 
						|
 | 
						|
  if (gEfiShellParametersProtocol->Argc < 3) {
 | 
						|
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel1HiiHandle, L"if");
 | 
						|
    return (SHELL_INVALID_PARAMETER);
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Make sure that an End exists.
 | 
						|
  //
 | 
						|
  CurrentScriptFile = ShellCommandGetCurrentScriptFile ();
 | 
						|
  if (!MoveToTag (GetNextNode, L"endif", L"if", NULL, CurrentScriptFile, TRUE, TRUE, FALSE)) {
 | 
						|
    ShellPrintHiiEx (
 | 
						|
      -1,
 | 
						|
      -1,
 | 
						|
      NULL,
 | 
						|
      STRING_TOKEN (STR_SYNTAX_NO_MATCHING),
 | 
						|
      gShellLevel1HiiHandle,
 | 
						|
      L"EndIf",
 | 
						|
      L"If",
 | 
						|
      CurrentScriptFile != NULL
 | 
						|
                    && CurrentScriptFile->CurrentCommand != NULL
 | 
						|
        ? CurrentScriptFile->CurrentCommand->Line : 0
 | 
						|
      );
 | 
						|
    return (SHELL_DEVICE_ERROR);
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // initialize the shell lib (we must be in non-auto-init...)
 | 
						|
  //
 | 
						|
  Status = ShellInitialize ();
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  CurrentParameter = 1;
 | 
						|
  EndParameter     = 0;
 | 
						|
 | 
						|
  if ((gUnicodeCollation->StriColl (
 | 
						|
                            gUnicodeCollation,
 | 
						|
                            gEfiShellParametersProtocol->Argv[1],
 | 
						|
                            L"/i"
 | 
						|
                            ) == 0) ||
 | 
						|
      (gUnicodeCollation->StriColl (
 | 
						|
                            gUnicodeCollation,
 | 
						|
                            gEfiShellParametersProtocol->Argv[2],
 | 
						|
                            L"/i"
 | 
						|
                            ) == 0) ||
 | 
						|
      ((gEfiShellParametersProtocol->Argc > 3) && (gUnicodeCollation->StriColl (
 | 
						|
                                                                        gUnicodeCollation,
 | 
						|
                                                                        gEfiShellParametersProtocol->Argv[3],
 | 
						|
                                                                        L"/i"
 | 
						|
                                                                        ) == 0)))
 | 
						|
  {
 | 
						|
    CaseInsensitive = TRUE;
 | 
						|
    CurrentParameter++;
 | 
						|
  } else {
 | 
						|
    CaseInsensitive = FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((gUnicodeCollation->StriColl (
 | 
						|
                            gUnicodeCollation,
 | 
						|
                            gEfiShellParametersProtocol->Argv[1],
 | 
						|
                            L"/s"
 | 
						|
                            ) == 0) ||
 | 
						|
      (gUnicodeCollation->StriColl (
 | 
						|
                            gUnicodeCollation,
 | 
						|
                            gEfiShellParametersProtocol->Argv[2],
 | 
						|
                            L"/s"
 | 
						|
                            ) == 0) ||
 | 
						|
      ((gEfiShellParametersProtocol->Argc > 3) && (gUnicodeCollation->StriColl (
 | 
						|
                                                                        gUnicodeCollation,
 | 
						|
                                                                        gEfiShellParametersProtocol->Argv[3],
 | 
						|
                                                                        L"/s"
 | 
						|
                                                                        ) == 0)))
 | 
						|
  {
 | 
						|
    ForceString = TRUE;
 | 
						|
    CurrentParameter++;
 | 
						|
  } else {
 | 
						|
    ForceString = FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  for ( ShellStatus = SHELL_SUCCESS, CurrentValue = FALSE, Ending = EndTagMax
 | 
						|
        ; CurrentParameter < gEfiShellParametersProtocol->Argc && ShellStatus == SHELL_SUCCESS
 | 
						|
        ; CurrentParameter++)
 | 
						|
  {
 | 
						|
    if (gUnicodeCollation->StriColl (
 | 
						|
                             gUnicodeCollation,
 | 
						|
                             gEfiShellParametersProtocol->Argv[CurrentParameter],
 | 
						|
                             L"then"
 | 
						|
                             ) == 0)
 | 
						|
    {
 | 
						|
      //
 | 
						|
      // we are at the then
 | 
						|
      //
 | 
						|
      if (CurrentParameter+1 != gEfiShellParametersProtocol->Argc) {
 | 
						|
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_TEXT_AFTER_THEN), gShellLevel1HiiHandle, L"if");
 | 
						|
        ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
      } else {
 | 
						|
        Status = PerformResultOperation (CurrentValue);
 | 
						|
        if (EFI_ERROR (Status)) {
 | 
						|
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_AFTER_BAD), gShellLevel1HiiHandle, L"if", gEfiShellParametersProtocol->Argv[CurrentParameter]);
 | 
						|
          ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      PreviousEnding = Ending;
 | 
						|
      //
 | 
						|
      // build up the next statement for analysis
 | 
						|
      //
 | 
						|
      if (!BuildNextStatement (CurrentParameter, &EndParameter, &Ending)) {
 | 
						|
        CurrentScriptFile = ShellCommandGetCurrentScriptFile ();
 | 
						|
        ShellPrintHiiEx (
 | 
						|
          -1,
 | 
						|
          -1,
 | 
						|
          NULL,
 | 
						|
          STRING_TOKEN (STR_SYNTAX_NO_MATCHING),
 | 
						|
          gShellLevel1HiiHandle,
 | 
						|
          L"Then",
 | 
						|
          L"If",
 | 
						|
          CurrentScriptFile != NULL
 | 
						|
                        && CurrentScriptFile->CurrentCommand != NULL
 | 
						|
            ? CurrentScriptFile->CurrentCommand->Line : 0
 | 
						|
          );
 | 
						|
        ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
      } else {
 | 
						|
        //
 | 
						|
        // Analyze the statement
 | 
						|
        //
 | 
						|
        Status = ProcessStatement (&CurrentValue, CurrentParameter, EndParameter, PreviousEnding, CaseInsensitive, ForceString);
 | 
						|
        if (EFI_ERROR (Status)) {
 | 
						|
          //          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_STARTING), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[CurrentParameter]);
 | 
						|
          ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
        } else {
 | 
						|
          //
 | 
						|
          // Optomize to get out of the loop early...
 | 
						|
          //
 | 
						|
          if (((Ending == EndTagOr) && CurrentValue) || ((Ending == EndTagAnd) && !CurrentValue)) {
 | 
						|
            Status = PerformResultOperation (CurrentValue);
 | 
						|
            if (EFI_ERROR (Status)) {
 | 
						|
              ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_AFTER_BAD), gShellLevel1HiiHandle, L"if", gEfiShellParametersProtocol->Argv[CurrentParameter]);
 | 
						|
              ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
            }
 | 
						|
 | 
						|
            break;
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      if (ShellStatus == SHELL_SUCCESS) {
 | 
						|
        CurrentParameter = EndParameter;
 | 
						|
        //
 | 
						|
        // Skip over the or or and parameter.
 | 
						|
        //
 | 
						|
        if ((Ending == EndTagOr) || (Ending == EndTagAnd)) {
 | 
						|
          CurrentParameter++;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return (ShellStatus);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Function for 'else' 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
 | 
						|
ShellCommandRunElse (
 | 
						|
  IN EFI_HANDLE        ImageHandle,
 | 
						|
  IN EFI_SYSTEM_TABLE  *SystemTable
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS   Status;
 | 
						|
  SCRIPT_FILE  *CurrentScriptFile;
 | 
						|
 | 
						|
  Status = CommandInit ();
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  if (gEfiShellParametersProtocol->Argc > 1) {
 | 
						|
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel1HiiHandle, L"if");
 | 
						|
    return (SHELL_INVALID_PARAMETER);
 | 
						|
  }
 | 
						|
 | 
						|
  if (!gEfiShellProtocol->BatchIsActive ()) {
 | 
						|
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"Else");
 | 
						|
    return (SHELL_UNSUPPORTED);
 | 
						|
  }
 | 
						|
 | 
						|
  CurrentScriptFile = ShellCommandGetCurrentScriptFile ();
 | 
						|
 | 
						|
  if (!MoveToTag (GetPreviousNode, L"if", L"endif", NULL, CurrentScriptFile, FALSE, TRUE, FALSE)) {
 | 
						|
    ShellPrintHiiEx (
 | 
						|
      -1,
 | 
						|
      -1,
 | 
						|
      NULL,
 | 
						|
      STRING_TOKEN (STR_SYNTAX_NO_MATCHING),
 | 
						|
      gShellLevel1HiiHandle,
 | 
						|
      L"If",
 | 
						|
      L"Else",
 | 
						|
      CurrentScriptFile != NULL
 | 
						|
                    && CurrentScriptFile->CurrentCommand != NULL
 | 
						|
        ? CurrentScriptFile->CurrentCommand->Line : 0
 | 
						|
      );
 | 
						|
    return (SHELL_DEVICE_ERROR);
 | 
						|
  }
 | 
						|
 | 
						|
  if (!MoveToTag (GetPreviousNode, L"if", L"else", NULL, CurrentScriptFile, FALSE, TRUE, FALSE)) {
 | 
						|
    ShellPrintHiiEx (
 | 
						|
      -1,
 | 
						|
      -1,
 | 
						|
      NULL,
 | 
						|
      STRING_TOKEN (STR_SYNTAX_NO_MATCHING),
 | 
						|
      gShellLevel1HiiHandle,
 | 
						|
      L"If",
 | 
						|
      L"Else",
 | 
						|
      CurrentScriptFile != NULL
 | 
						|
                    && CurrentScriptFile->CurrentCommand != NULL
 | 
						|
        ? CurrentScriptFile->CurrentCommand->Line : 0
 | 
						|
      );
 | 
						|
    return (SHELL_DEVICE_ERROR);
 | 
						|
  }
 | 
						|
 | 
						|
  if (!MoveToTag (GetNextNode, L"endif", L"if", NULL, CurrentScriptFile, FALSE, FALSE, FALSE)) {
 | 
						|
    ShellPrintHiiEx (
 | 
						|
      -1,
 | 
						|
      -1,
 | 
						|
      NULL,
 | 
						|
      STRING_TOKEN (STR_SYNTAX_NO_MATCHING),
 | 
						|
      gShellLevel1HiiHandle,
 | 
						|
      L"EndIf",
 | 
						|
      "Else",
 | 
						|
      CurrentScriptFile != NULL
 | 
						|
                    && CurrentScriptFile->CurrentCommand != NULL
 | 
						|
        ? CurrentScriptFile->CurrentCommand->Line : 0
 | 
						|
      );
 | 
						|
    return (SHELL_DEVICE_ERROR);
 | 
						|
  }
 | 
						|
 | 
						|
  return (SHELL_SUCCESS);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Function for 'endif' 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
 | 
						|
ShellCommandRunEndIf (
 | 
						|
  IN EFI_HANDLE        ImageHandle,
 | 
						|
  IN EFI_SYSTEM_TABLE  *SystemTable
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS   Status;
 | 
						|
  SCRIPT_FILE  *CurrentScriptFile;
 | 
						|
 | 
						|
  Status = CommandInit ();
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  if (gEfiShellParametersProtocol->Argc > 1) {
 | 
						|
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel1HiiHandle, L"if");
 | 
						|
    return (SHELL_INVALID_PARAMETER);
 | 
						|
  }
 | 
						|
 | 
						|
  if (!gEfiShellProtocol->BatchIsActive ()) {
 | 
						|
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"Endif");
 | 
						|
    return (SHELL_UNSUPPORTED);
 | 
						|
  }
 | 
						|
 | 
						|
  CurrentScriptFile = ShellCommandGetCurrentScriptFile ();
 | 
						|
  if (!MoveToTag (GetPreviousNode, L"if", L"endif", NULL, CurrentScriptFile, FALSE, TRUE, FALSE)) {
 | 
						|
    ShellPrintHiiEx (
 | 
						|
      -1,
 | 
						|
      -1,
 | 
						|
      NULL,
 | 
						|
      STRING_TOKEN (STR_SYNTAX_NO_MATCHING),
 | 
						|
      gShellLevel1HiiHandle,
 | 
						|
      L"If",
 | 
						|
      L"EndIf",
 | 
						|
      CurrentScriptFile != NULL
 | 
						|
                    && CurrentScriptFile->CurrentCommand != NULL
 | 
						|
        ? CurrentScriptFile->CurrentCommand->Line : 0
 | 
						|
      );
 | 
						|
    return (SHELL_DEVICE_ERROR);
 | 
						|
  }
 | 
						|
 | 
						|
  return (SHELL_SUCCESS);
 | 
						|
}
 |