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);
 | |
| }
 |