summaryrefslogtreecommitdiff
path: root/Core/ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.c
diff options
context:
space:
mode:
Diffstat (limited to 'Core/ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.c')
-rw-r--r--Core/ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.c310
1 files changed, 310 insertions, 0 deletions
diff --git a/Core/ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.c b/Core/ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.c
new file mode 100644
index 0000000000..80d0dfe652
--- /dev/null
+++ b/Core/ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.c
@@ -0,0 +1,310 @@
+/** @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);
+}
+