/** @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");
  if (ProfilesString == NULL) {
    ASSERT (ProfilesString != NULL);
    return (FALSE);
  }

  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;
      ShellPrintHiiDefaultEx (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 {
      ShellPrintHiiDefaultEx (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 {
      ShellPrintHiiDefaultEx (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 {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"profile");
      Status = EFI_INVALID_PARAMETER;
    }
  } else if (StartParameterNumber+1 >= EndParameterNumber) {
    ShellPrintHiiDefaultEx (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 {
          ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"efierror");
          Status = EFI_INVALID_PARAMETER;
        }
      } else {
        ShellPrintHiiDefaultEx (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 {
          ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"pierror");
          Status = EFI_INVALID_PARAMETER;
        }
      } else {
        ShellPrintHiiDefaultEx (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 {
          ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"oemerror");
          Status = EFI_INVALID_PARAMETER;
        }
      } else {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"oemerror");
        Status = EFI_INVALID_PARAMETER;
      }
    } else {
      ASSERT (Compare1 == NULL);
      if (EndParameterNumber - StartParameterNumber > 2) {
        ShellPrintHiiDefaultEx (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 {
      ShellPrintHiiDefaultEx (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 {
          ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"efierror");
          Status = EFI_INVALID_PARAMETER;
        }
      } else {
        ShellPrintHiiDefaultEx (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 {
          ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"pierror");
          Status = EFI_INVALID_PARAMETER;
        }
      } else {
        ShellPrintHiiDefaultEx (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 {
          ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"oemerror");
          Status = EFI_INVALID_PARAMETER;
        }
      } else {
        ShellPrintHiiDefaultEx (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 ()) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"if");
    return (SHELL_UNSUPPORTED);
  }

  if (gEfiShellParametersProtocol->Argc < 3) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel1HiiHandle, L"if");
    return (SHELL_INVALID_PARAMETER);
  }

  //
  // Make sure that an End exists.
  //
  CurrentScriptFile = ShellCommandGetCurrentScriptFile ();
  if (CurrentScriptFile == NULL) {
    return (SHELL_INVALID_PARAMETER);
  }

  if (!MoveToTag (GetNextNode, L"endif", L"if", NULL, CurrentScriptFile, TRUE, TRUE, FALSE)) {
    ShellPrintHiiDefaultEx (
      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) {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_TEXT_AFTER_THEN), gShellLevel1HiiHandle, L"if");
        ShellStatus = SHELL_INVALID_PARAMETER;
      } else {
        Status = PerformResultOperation (CurrentValue);
        if (EFI_ERROR (Status)) {
          ShellPrintHiiDefaultEx (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 ();
        ShellPrintHiiDefaultEx (
          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)) {
          //          ShellPrintHiiDefaultEx (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)) {
              ShellPrintHiiDefaultEx (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) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel1HiiHandle, L"if");
    return (SHELL_INVALID_PARAMETER);
  }

  if (!gEfiShellProtocol->BatchIsActive ()) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"Else");
    return (SHELL_UNSUPPORTED);
  }

  CurrentScriptFile = ShellCommandGetCurrentScriptFile ();
  if (CurrentScriptFile == NULL) {
    return (SHELL_INVALID_PARAMETER);
  }

  if (!MoveToTag (GetPreviousNode, L"if", L"endif", NULL, CurrentScriptFile, FALSE, TRUE, FALSE)) {
    ShellPrintHiiDefaultEx (
      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)) {
    ShellPrintHiiDefaultEx (
      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)) {
    ShellPrintHiiDefaultEx (
      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) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel1HiiHandle, L"if");
    return (SHELL_INVALID_PARAMETER);
  }

  if (!gEfiShellProtocol->BatchIsActive ()) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"Endif");
    return (SHELL_UNSUPPORTED);
  }

  CurrentScriptFile = ShellCommandGetCurrentScriptFile ();
  if (CurrentScriptFile == NULL) {
    return (SHELL_INVALID_PARAMETER);
  }

  if (!MoveToTag (GetPreviousNode, L"if", L"endif", NULL, CurrentScriptFile, FALSE, TRUE, FALSE)) {
    ShellPrintHiiDefaultEx (
      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);
}
