| /** @file | |
| Main file for NULL named library for level 1 shell command functions. | |
| (C) Copyright 2013 Hewlett-Packard Development Company, L.P.<BR> | |
| Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR> | |
| This program and the accompanying materials | |
| are licensed and made available under the terms and conditions of the BSD License | |
| which accompanies this distribution. The full text of the license may be found at | |
| http://opensource.org/licenses/bsd-license.php | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
| **/ | |
| #include "UefiShellLevel1CommandsLib.h" | |
| STATIC CONST CHAR16 mFileName[] = L"ShellCommands"; | |
| EFI_HANDLE gShellLevel1HiiHandle = NULL; | |
| /** | |
| Return the help text filename. Only used if no HII information found. | |
| @retval the filename. | |
| **/ | |
| CONST CHAR16* | |
| EFIAPI | |
| ShellCommandGetManFileNameLevel1 ( | |
| VOID | |
| ) | |
| { | |
| return (mFileName); | |
| } | |
| /** | |
| Constructor for the Shell Level 1 Commands library. | |
| Install the handlers for level 1 UEFI Shell 2.0 commands. | |
| @param ImageHandle the image handle of the process | |
| @param SystemTable the EFI System Table pointer | |
| @retval EFI_SUCCESS the shell command handlers were installed sucessfully | |
| @retval EFI_UNSUPPORTED the shell level required was not found. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| ShellLevel1CommandsLibConstructor ( | |
| IN EFI_HANDLE ImageHandle, | |
| IN EFI_SYSTEM_TABLE *SystemTable | |
| ) | |
| { | |
| // | |
| // if shell level is less than 2 do nothing | |
| // | |
| if (PcdGet8(PcdShellSupportLevel) < 1) { | |
| return (EFI_SUCCESS); | |
| } | |
| gShellLevel1HiiHandle = HiiAddPackages (&gShellLevel1HiiGuid, gImageHandle, UefiShellLevel1CommandsLibStrings, NULL); | |
| if (gShellLevel1HiiHandle == NULL) { | |
| return (EFI_DEVICE_ERROR); | |
| } | |
| // | |
| // install our shell command handlers that are always installed | |
| // | |
| ShellCommandRegisterCommandName(L"stall", ShellCommandRunStall , ShellCommandGetManFileNameLevel1, 1, L"", FALSE, gShellLevel1HiiHandle, (EFI_STRING_ID)(PcdGet8(PcdShellSupportLevel) < 3 ? 0 : STRING_TOKEN(STR_GET_HELP_STALL) )); | |
| ShellCommandRegisterCommandName(L"for", ShellCommandRunFor , ShellCommandGetManFileNameLevel1, 1, L"", FALSE, gShellLevel1HiiHandle, (EFI_STRING_ID)(PcdGet8(PcdShellSupportLevel) < 3 ? 0 : STRING_TOKEN(STR_GET_HELP_FOR) )); | |
| ShellCommandRegisterCommandName(L"goto", ShellCommandRunGoto , ShellCommandGetManFileNameLevel1, 1, L"", FALSE, gShellLevel1HiiHandle, (EFI_STRING_ID)(PcdGet8(PcdShellSupportLevel) < 3 ? 0 : STRING_TOKEN(STR_GET_HELP_GOTO) )); | |
| ShellCommandRegisterCommandName(L"if", ShellCommandRunIf , ShellCommandGetManFileNameLevel1, 1, L"", FALSE, gShellLevel1HiiHandle, (EFI_STRING_ID)(PcdGet8(PcdShellSupportLevel) < 3 ? 0 : STRING_TOKEN(STR_GET_HELP_IF) )); | |
| ShellCommandRegisterCommandName(L"shift", ShellCommandRunShift , ShellCommandGetManFileNameLevel1, 1, L"", FALSE, gShellLevel1HiiHandle, (EFI_STRING_ID)(PcdGet8(PcdShellSupportLevel) < 3 ? 0 : STRING_TOKEN(STR_GET_HELP_SHIFT) )); | |
| ShellCommandRegisterCommandName(L"exit", ShellCommandRunExit , ShellCommandGetManFileNameLevel1, 1, L"", TRUE , gShellLevel1HiiHandle, (EFI_STRING_ID)(PcdGet8(PcdShellSupportLevel) < 3 ? 0 : STRING_TOKEN(STR_GET_HELP_EXIT) )); | |
| ShellCommandRegisterCommandName(L"else", ShellCommandRunElse , ShellCommandGetManFileNameLevel1, 1, L"", FALSE, gShellLevel1HiiHandle, (EFI_STRING_ID)(PcdGet8(PcdShellSupportLevel) < 3 ? 0 : STRING_TOKEN(STR_GET_HELP_ELSE) )); | |
| ShellCommandRegisterCommandName(L"endif", ShellCommandRunEndIf , ShellCommandGetManFileNameLevel1, 1, L"", FALSE, gShellLevel1HiiHandle, (EFI_STRING_ID)(PcdGet8(PcdShellSupportLevel) < 3 ? 0 : STRING_TOKEN(STR_GET_HELP_ENDIF) )); | |
| ShellCommandRegisterCommandName(L"endfor", ShellCommandRunEndFor , ShellCommandGetManFileNameLevel1, 1, L"", FALSE, gShellLevel1HiiHandle, (EFI_STRING_ID)(PcdGet8(PcdShellSupportLevel) < 3 ? 0 : STRING_TOKEN(STR_GET_HELP_ENDFOR))); | |
| return (EFI_SUCCESS); | |
| } | |
| /** | |
| Destructor for the library. free any resources. | |
| @param ImageHandle The image handle of the process. | |
| @param SystemTable The EFI System Table pointer. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| ShellLevel1CommandsLibDestructor ( | |
| IN EFI_HANDLE ImageHandle, | |
| IN EFI_SYSTEM_TABLE *SystemTable | |
| ) | |
| { | |
| if (gShellLevel1HiiHandle != NULL) { | |
| HiiRemovePackages(gShellLevel1HiiHandle); | |
| } | |
| return (EFI_SUCCESS); | |
| } | |
| /** | |
| Test a node to see if meets the criterion. | |
| It functions so that count starts at 1 and it increases or decreases when it | |
| hits the specified tags. when it hits zero the location has been found. | |
| DecrementerTag and IncrementerTag are used to get around for/endfor and | |
| similar paired types where the entire middle should be ignored. | |
| If label is used it will be used instead of the count. | |
| @param[in] Function The function to use to enumerate through the | |
| list. Normally GetNextNode or GetPreviousNode. | |
| @param[in] DecrementerTag The tag to decrement the count at. | |
| @param[in] IncrementerTag The tag to increment the count at. | |
| @param[in] Label A label to look for. | |
| @param[in, out] ScriptFile The pointer to the current script file structure. | |
| @param[in] MovePast TRUE makes function return 1 past the found | |
| location. | |
| @param[in] FindOnly TRUE to not change the ScriptFile. | |
| @param[in] CommandNode The pointer to the Node to test. | |
| @param[in, out] TargetCount The pointer to the current count. | |
| **/ | |
| BOOLEAN | |
| EFIAPI | |
| TestNodeForMove ( | |
| IN CONST LIST_MANIP_FUNC Function, | |
| IN CONST CHAR16 *DecrementerTag, | |
| IN CONST CHAR16 *IncrementerTag, | |
| IN CONST CHAR16 *Label OPTIONAL, | |
| IN OUT SCRIPT_FILE *ScriptFile, | |
| IN CONST BOOLEAN MovePast, | |
| IN CONST BOOLEAN FindOnly, | |
| IN CONST SCRIPT_COMMAND_LIST *CommandNode, | |
| IN OUT UINTN *TargetCount | |
| ) | |
| { | |
| BOOLEAN Found; | |
| CHAR16 *CommandName; | |
| CHAR16 *CommandNameWalker; | |
| CHAR16 *TempLocation; | |
| Found = FALSE; | |
| // | |
| // get just the first part of the command line... | |
| // | |
| CommandName = NULL; | |
| CommandName = StrnCatGrow(&CommandName, NULL, CommandNode->Cl, 0); | |
| if (CommandName == NULL) { | |
| return (FALSE); | |
| } | |
| CommandNameWalker = CommandName; | |
| // | |
| // Skip leading spaces and tabs. | |
| // | |
| while ((CommandNameWalker[0] == L' ') || (CommandNameWalker[0] == L'\t')) { | |
| CommandNameWalker++; | |
| } | |
| TempLocation = StrStr(CommandNameWalker, L" "); | |
| if (TempLocation != NULL) { | |
| *TempLocation = CHAR_NULL; | |
| } | |
| // | |
| // did we find a nested item ? | |
| // | |
| if (gUnicodeCollation->StriColl( | |
| gUnicodeCollation, | |
| (CHAR16*)CommandNameWalker, | |
| (CHAR16*)IncrementerTag) == 0) { | |
| (*TargetCount)++; | |
| } else if (gUnicodeCollation->StriColl( | |
| gUnicodeCollation, | |
| (CHAR16*)CommandNameWalker, | |
| (CHAR16*)DecrementerTag) == 0) { | |
| if (*TargetCount > 0) { | |
| (*TargetCount)--; | |
| } | |
| } | |
| // | |
| // did we find the matching one... | |
| // | |
| if (Label == NULL) { | |
| if (*TargetCount == 0) { | |
| Found = TRUE; | |
| if (!FindOnly) { | |
| if (MovePast) { | |
| ScriptFile->CurrentCommand = (SCRIPT_COMMAND_LIST *)(*Function)(&ScriptFile->CommandList, &CommandNode->Link); | |
| } else { | |
| ScriptFile->CurrentCommand = (SCRIPT_COMMAND_LIST *)CommandNode; | |
| } | |
| } | |
| } | |
| } else { | |
| if (gUnicodeCollation->StriColl( | |
| gUnicodeCollation, | |
| (CHAR16*)CommandNameWalker, | |
| (CHAR16*)Label) == 0 | |
| && (*TargetCount) == 0) { | |
| Found = TRUE; | |
| if (!FindOnly) { | |
| // | |
| // we found the target label without loops | |
| // | |
| if (MovePast) { | |
| ScriptFile->CurrentCommand = (SCRIPT_COMMAND_LIST *)(*Function)(&ScriptFile->CommandList, &CommandNode->Link); | |
| } else { | |
| ScriptFile->CurrentCommand = (SCRIPT_COMMAND_LIST *)CommandNode; | |
| } | |
| } | |
| } | |
| } | |
| // | |
| // Free the memory for this loop... | |
| // | |
| FreePool(CommandName); | |
| return (Found); | |
| } | |
| /** | |
| Move the script pointer from 1 tag (line) to another. | |
| It functions so that count starts at 1 and it increases or decreases when it | |
| hits the specified tags. when it hits zero the location has been found. | |
| DecrementerTag and IncrementerTag are used to get around for/endfor and | |
| similar paired types where the entire middle should be ignored. | |
| If label is used it will be used instead of the count. | |
| @param[in] Function The function to use to enumerate through the | |
| list. Normally GetNextNode or GetPreviousNode. | |
| @param[in] DecrementerTag The tag to decrement the count at. | |
| @param[in] IncrementerTag The tag to increment the count at. | |
| @param[in] Label A label to look for. | |
| @param[in, out] ScriptFile The pointer to the current script file structure. | |
| @param[in] MovePast TRUE makes function return 1 past the found | |
| location. | |
| @param[in] FindOnly TRUE to not change the ScriptFile. | |
| @param[in] WrapAroundScript TRUE to wrap end-to-begining or vise versa in | |
| searching. | |
| **/ | |
| BOOLEAN | |
| EFIAPI | |
| MoveToTag ( | |
| IN CONST LIST_MANIP_FUNC Function, | |
| IN CONST CHAR16 *DecrementerTag, | |
| IN CONST CHAR16 *IncrementerTag, | |
| IN CONST CHAR16 *Label OPTIONAL, | |
| IN OUT SCRIPT_FILE *ScriptFile, | |
| IN CONST BOOLEAN MovePast, | |
| IN CONST BOOLEAN FindOnly, | |
| IN CONST BOOLEAN WrapAroundScript | |
| ) | |
| { | |
| SCRIPT_COMMAND_LIST *CommandNode; | |
| BOOLEAN Found; | |
| UINTN TargetCount; | |
| if (Label == NULL) { | |
| TargetCount = 1; | |
| } else { | |
| TargetCount = 0; | |
| } | |
| if (ScriptFile == NULL) { | |
| return FALSE; | |
| } | |
| for (CommandNode = (SCRIPT_COMMAND_LIST *)(*Function)(&ScriptFile->CommandList, &ScriptFile->CurrentCommand->Link), Found = FALSE | |
| ; !IsNull(&ScriptFile->CommandList, &CommandNode->Link)&& !Found | |
| ; CommandNode = (SCRIPT_COMMAND_LIST *)(*Function)(&ScriptFile->CommandList, &CommandNode->Link) | |
| ){ | |
| Found = TestNodeForMove( | |
| Function, | |
| DecrementerTag, | |
| IncrementerTag, | |
| Label, | |
| ScriptFile, | |
| MovePast, | |
| FindOnly, | |
| CommandNode, | |
| &TargetCount); | |
| } | |
| if (WrapAroundScript && !Found) { | |
| for (CommandNode = (SCRIPT_COMMAND_LIST *)GetFirstNode(&ScriptFile->CommandList), Found = FALSE | |
| ; CommandNode != ScriptFile->CurrentCommand && !Found | |
| ; CommandNode = (SCRIPT_COMMAND_LIST *)(*Function)(&ScriptFile->CommandList, &CommandNode->Link) | |
| ){ | |
| Found = TestNodeForMove( | |
| Function, | |
| DecrementerTag, | |
| IncrementerTag, | |
| Label, | |
| ScriptFile, | |
| MovePast, | |
| FindOnly, | |
| CommandNode, | |
| &TargetCount); | |
| } | |
| } | |
| return (Found); | |
| } | |