udk2010.up2.shell initial release.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10874 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
jcarsey
2010-09-14 05:18:09 +00:00
parent 52fb4d3d13
commit a405b86d27
102 changed files with 30419 additions and 1040 deletions

View File

@ -0,0 +1,81 @@
/** @file
Main file for exit shell level 1 function.
Copyright (c) 2009 - 2010, 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 SHELL_PARAM_ITEM ParamList[] = {
{L"/b", TypeFlag},
{NULL, TypeMax}
};
/**
Function for 'exit' 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
ShellCommandRunExit (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
LIST_ENTRY *Package;
CHAR16 *ProblemParam;
SHELL_STATUS ShellStatus;
ShellStatus = SHELL_SUCCESS;
//
// initialize the shell lib (we must be in non-auto-init...)
//
Status = ShellInitialize();
ASSERT_EFI_ERROR(Status);
Status = CommandInit();
ASSERT_EFI_ERROR(Status);
//
// parse the command line
//
Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
if (EFI_ERROR(Status)) {
if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel1HiiHandle, ProblemParam);
FreePool(ProblemParam);
ShellStatus = SHELL_INVALID_PARAMETER;
} else {
ASSERT(FALSE);
}
} else {
//
// If we are in a batch file and /b then pass TRUE otherwise false...
//
ShellCommandRegisterExit((BOOLEAN)(gEfiShellProtocol->BatchIsActive() && ShellCommandLineGetFlag(Package, L"/b")));
//
// return the specified error code
//
if (ShellCommandLineGetRawValue(Package, 1) != NULL) {
ShellStatus = (SHELL_STATUS)(ShellStrToUintn(ShellCommandLineGetRawValue(Package, 1)));
}
ShellCommandLineFreeVarList (Package);
}
return (ShellStatus);
}

View File

@ -0,0 +1,581 @@
/** @file
Main file for endfor and for shell level 1 functions.
Copyright (c) 2009 - 2010, 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"
#include <Library/PrintLib.h>
BOOLEAN
EFIAPI
ShellIsValidForNumber (
IN CONST CHAR16 *Number
)
{
if (Number == NULL || *Number == CHAR_NULL) {
return (FALSE);
}
if (*Number == L'-') {
Number++;
}
if (StrLen(Number) == 0) {
return (FALSE);
}
if (StrLen(Number) >= 7) {
if (StrStr(Number, L" ") != NULL && (StrStr(Number, L" ") - Number) >= 7) {
return (FALSE);
}
}
if (!ShellIsDecimalDigitCharacter(*Number)) {
return (FALSE);
}
return (TRUE);
}
/**
Function for 'endfor' 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
ShellCommandRunEndFor (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
BOOLEAN Found;
Status = CommandInit();
ASSERT_EFI_ERROR(Status);
if (!gEfiShellProtocol->BatchIsActive()) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"EndFor");
return (SHELL_UNSUPPORTED);
}
if (gEfiShellParametersProtocol->Argc > 1) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel1HiiHandle);
return (SHELL_INVALID_PARAMETER);
}
Found = MoveToTag(GetPreviousNode, L"for", L"endfor", NULL, ShellCommandGetCurrentScriptFile(), FALSE, FALSE, FALSE);
if (!Found) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"For", L"EndFor", ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
return (SHELL_NOT_FOUND);
}
return (SHELL_SUCCESS);
}
typedef struct {
UINT32 Signature;
INTN Current;
INTN End;
INTN Step;
CHAR16 *ReplacementName;
CHAR16 *CurrentValue;
BOOLEAN RemoveSubstAlias;
CHAR16 Set[1];
} SHELL_FOR_INFO;
#define SIZE_OF_SHELL_FOR_INFO OFFSET_OF (SHELL_FOR_INFO, Set)
#define SHELL_FOR_INFO_SIGNATURE SIGNATURE_32 ('S', 'F', 'I', 's')
/**
Update the value of a given alias on the list. If the alias is not there then add it.
@param[in] Alias The alias to test for.
@param[in] CommandString The updated command string.
@param[in,out] List The list to search.
**/
VOID
EFIAPI
InternalUpdateAliasOnList(
IN CONST CHAR16 *Alias,
IN CONST CHAR16 *CommandString,
IN OUT LIST_ENTRY *List
)
{
ALIAS_LIST *Node;
BOOLEAN Found;
//
// assert for NULL parameter
//
ASSERT(Alias != NULL);
//
// check for the Alias
//
for ( Node = (ALIAS_LIST *)GetFirstNode(List), Found = FALSE
; !IsNull(List, &Node->Link)
; Node = (ALIAS_LIST *)GetNextNode(List, &Node->Link)
){
ASSERT(Node->CommandString != NULL);
ASSERT(Node->Alias != NULL);
if (StrCmp(Node->Alias, Alias)==0) {
FreePool(Node->CommandString);
Node->CommandString = NULL;
Node->CommandString = StrnCatGrow(&Node->CommandString, NULL, CommandString, 0);
Found = TRUE;
break;
}
}
if (!Found) {
Node = AllocateZeroPool(sizeof(ALIAS_LIST));
ASSERT(Node->Alias == NULL);
Node->Alias = StrnCatGrow(&Node->Alias, NULL, Alias, 0);
ASSERT(Node->CommandString == NULL);
Node->CommandString = StrnCatGrow(&Node->CommandString, NULL, CommandString, 0);
InsertTailList(List, &Node->Link);
}
}
/**
Find out if an alias is on the given list.
@param[in] Alias The alias to test for.
@param[in] List The list to search.
@retval TRUE The alias is on the list.
@retval FALSE The alias is not on the list.
**/
BOOLEAN
EFIAPI
InternalIsAliasOnList(
IN CONST CHAR16 *Alias,
IN CONST LIST_ENTRY *List
)
{
ALIAS_LIST *Node;
//
// assert for NULL parameter
//
ASSERT(Alias != NULL);
//
// check for the Alias
//
for ( Node = (ALIAS_LIST *)GetFirstNode(List)
; !IsNull(List, &Node->Link)
; Node = (ALIAS_LIST *)GetNextNode(List, &Node->Link)
){
ASSERT(Node->CommandString != NULL);
ASSERT(Node->Alias != NULL);
if (StrCmp(Node->Alias, Alias)==0) {
return (TRUE);
}
}
return (FALSE);
}
/**
Remove an alias from the given list.
@param[in] Alias The alias to remove.
@param[in,out] List The list to search.
**/
BOOLEAN
EFIAPI
InternalRemoveAliasFromList(
IN CONST CHAR16 *Alias,
IN OUT LIST_ENTRY *List
)
{
ALIAS_LIST *Node;
//
// assert for NULL parameter
//
ASSERT(Alias != NULL);
//
// check for the Alias
//
for ( Node = (ALIAS_LIST *)GetFirstNode(List)
; !IsNull(List, &Node->Link)
; Node = (ALIAS_LIST *)GetNextNode(List, &Node->Link)
){
ASSERT(Node->CommandString != NULL);
ASSERT(Node->Alias != NULL);
if (StrCmp(Node->Alias, Alias)==0) {
RemoveEntryList(&Node->Link);
FreePool(Node->Alias);
FreePool(Node->CommandString);
FreePool(Node);
return (TRUE);
}
}
return (FALSE);
}
/**
Function for 'for' 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
ShellCommandRunFor (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
SHELL_STATUS ShellStatus;
SCRIPT_FILE *CurrentScriptFile;
CHAR16 *ArgSet;
CHAR16 *ArgSetWalker;
UINTN ArgSize;
UINTN LoopVar;
SHELL_FOR_INFO *Info;
CHAR16 *TempString;
CHAR16 *TempSpot;
BOOLEAN FirstPass;
EFI_SHELL_FILE_INFO *Node;
EFI_SHELL_FILE_INFO *FileList;
UINTN NewSize;
ArgSet = NULL;
ArgSize = 0;
ShellStatus = SHELL_SUCCESS;
ArgSetWalker = NULL;
TempString = NULL;
FirstPass = FALSE;
//
// initialize the shell lib (we must be in non-auto-init...)
//
Status = ShellInitialize();
ASSERT_EFI_ERROR(Status);
Status = CommandInit();
ASSERT_EFI_ERROR(Status);
if (!gEfiShellProtocol->BatchIsActive()) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"For");
return (SHELL_UNSUPPORTED);
}
if (gEfiShellParametersProtocol->Argc < 4) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel1HiiHandle);
return (SHELL_INVALID_PARAMETER);
}
CurrentScriptFile = ShellCommandGetCurrentScriptFile();
ASSERT(CurrentScriptFile != NULL);
if (CurrentScriptFile->CurrentCommand->Data == NULL) {
FirstPass = TRUE;
//
// Make sure that an End exists.
//
if (!MoveToTag(GetNextNode, L"endfor", L"for", NULL, CurrentScriptFile, TRUE, TRUE, FALSE)) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"EndFor", L"For", ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
return (SHELL_DEVICE_ERROR);
}
//
// Process the line.
//
if (gEfiShellParametersProtocol->Argv[1][0] != L'%' || gEfiShellParametersProtocol->Argv[1][2] != CHAR_NULL
||!((gEfiShellParametersProtocol->Argv[1][1] >= L'a' && gEfiShellParametersProtocol->Argv[1][1] <= L'z')
||(gEfiShellParametersProtocol->Argv[1][1] >= L'A' && gEfiShellParametersProtocol->Argv[1][1] <= L'Z'))
) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_VAR), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[2]);
return (SHELL_INVALID_PARAMETER);
}
if (gUnicodeCollation->StriColl(
gUnicodeCollation,
L"in",
gEfiShellParametersProtocol->Argv[2]) == 0) {
for (LoopVar = 0x3 ; LoopVar < gEfiShellParametersProtocol->Argc ; LoopVar++) {
ASSERT((ArgSet == NULL && ArgSize == 0) || (ArgSet != NULL));
if (ArgSet == NULL) {
// ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0);
} else {
ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" \"", 0);
}
if (StrStr(gEfiShellParametersProtocol->Argv[LoopVar], L"*") != NULL
||StrStr(gEfiShellParametersProtocol->Argv[LoopVar], L"?") != NULL
||StrStr(gEfiShellParametersProtocol->Argv[LoopVar], L"[") != NULL
||StrStr(gEfiShellParametersProtocol->Argv[LoopVar], L"]") != NULL) {
FileList = NULL;
Status = ShellOpenFileMetaArg ((CHAR16*)gEfiShellParametersProtocol->Argv[LoopVar], EFI_FILE_MODE_READ, &FileList);
if (EFI_ERROR(Status) || FileList == NULL || IsListEmpty(&FileList->Link)) {
ArgSet = StrnCatGrow(&ArgSet, &ArgSize, gEfiShellParametersProtocol->Argv[LoopVar], 0);
} else {
for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&FileList->Link)
; !IsNull(&FileList->Link, &Node->Link)
; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&FileList->Link, &Node->Link)
){
ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" \"", 0);
ArgSet = StrnCatGrow(&ArgSet, &ArgSize, Node->FullName, 0);
ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0);
}
ShellCloseFileMetaArg(&FileList);
}
} else {
ArgSet = StrnCatGrow(&ArgSet, &ArgSize, gEfiShellParametersProtocol->Argv[LoopVar], 0);
}
ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0);
}
//
// set up for an 'in' for loop
//
NewSize = StrSize(ArgSet);
NewSize += sizeof(SHELL_FOR_INFO)+StrSize(gEfiShellParametersProtocol->Argv[1]);
Info = AllocateZeroPool(NewSize);
ASSERT(Info != NULL);
Info->Signature = SHELL_FOR_INFO_SIGNATURE;
CopyMem(Info->Set, ArgSet, StrSize(ArgSet));
NewSize = StrSize(gEfiShellParametersProtocol->Argv[1]);
CopyMem(Info->Set+(StrSize(ArgSet)/sizeof(Info->Set[0])), gEfiShellParametersProtocol->Argv[1], NewSize);
Info->ReplacementName = Info->Set+StrSize(ArgSet)/sizeof(Info->Set[0]);
Info->CurrentValue = (CHAR16*)Info->Set;
Info->Step = 0;
Info->Current = 0;
Info->End = 0;
if (InternalIsAliasOnList(Info->ReplacementName, &CurrentScriptFile->SubstList)) {
Info->RemoveSubstAlias = FALSE;
} else {
Info->RemoveSubstAlias = TRUE;
}
CurrentScriptFile->CurrentCommand->Data = Info;
} else if (gUnicodeCollation->StriColl(
gUnicodeCollation,
L"run",
gEfiShellParametersProtocol->Argv[2]) == 0) {
for (LoopVar = 0x3 ; LoopVar < gEfiShellParametersProtocol->Argc ; LoopVar++) {
ASSERT((ArgSet == NULL && ArgSize == 0) || (ArgSet != NULL));
if (ArgSet == NULL) {
// ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0);
} else {
ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" ", 0);
}
ArgSet = StrnCatGrow(&ArgSet, &ArgSize, gEfiShellParametersProtocol->Argv[LoopVar], 0);
// ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" ", 0);
}
//
// set up for a 'run' for loop
//
Info = AllocateZeroPool(sizeof(SHELL_FOR_INFO)+StrSize(gEfiShellParametersProtocol->Argv[1]));
ASSERT(Info != NULL);
CopyMem(Info->Set, gEfiShellParametersProtocol->Argv[1], StrSize(gEfiShellParametersProtocol->Argv[1]));
Info->ReplacementName = Info->Set;
Info->CurrentValue = NULL;
ArgSetWalker = ArgSet;
if (ArgSetWalker[0] != L'(') {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, ArgSet, ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
ShellStatus = SHELL_INVALID_PARAMETER;
} else {
ArgSetWalker++;
while (ArgSetWalker != NULL && ArgSetWalker[0] == L' ') {
ArgSetWalker++;
}
if (!ShellIsValidForNumber(ArgSetWalker)) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, ArgSet, ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
ShellStatus = SHELL_INVALID_PARAMETER;
} else {
if (ArgSetWalker[0] == L'-') {
Info->Current = 0 - (INTN)ShellStrToUintn(ArgSetWalker+1);
} else {
Info->Current = (INTN)ShellStrToUintn(ArgSetWalker);
}
ArgSetWalker = StrStr(ArgSetWalker, L" ");
while (ArgSetWalker != NULL && ArgSetWalker[0] == L' ') {
ArgSetWalker++;
}
if (ArgSetWalker == NULL || *ArgSetWalker == CHAR_NULL || !ShellIsValidForNumber(ArgSetWalker)){
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, ArgSet, ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
ShellStatus = SHELL_INVALID_PARAMETER;
} else {
if (ArgSetWalker[0] == L'-') {
Info->End = 0 - (INTN)ShellStrToUintn(ArgSetWalker+1);
} else {
Info->End = (INTN)ShellStrToUintn(ArgSetWalker);
}
if (Info->Current < Info->End) {
Info->Step = 1;
} else {
Info->Step = -1;
}
ArgSetWalker = StrStr(ArgSetWalker, L" ");
while (ArgSetWalker != NULL && ArgSetWalker[0] == L' ') {
ArgSetWalker++;
}
if (ArgSetWalker != NULL && *ArgSetWalker != CHAR_NULL) {
TempSpot = StrStr(ArgSetWalker, L")");
if (TempSpot == NULL) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, ArgSet, ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
ShellStatus = SHELL_INVALID_PARAMETER;
} else {
*TempSpot = CHAR_NULL;
if (ArgSetWalker == NULL || *ArgSetWalker == CHAR_NULL || !ShellIsValidForNumber(ArgSetWalker)){
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, ArgSet, ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
ShellStatus = SHELL_INVALID_PARAMETER;
} else {
if (*ArgSetWalker == L')') {
ASSERT(Info->Step == 1 || Info->Step == -1);
} else {
if (ArgSetWalker[0] == L'-') {
Info->Step = 0 - (INTN)ShellStrToUintn(ArgSetWalker+1);
} else {
Info->Step = (INTN)ShellStrToUintn(ArgSetWalker);
}
}
}
}
}
}
}
}
if (ShellStatus == SHELL_SUCCESS) {
if (InternalIsAliasOnList(Info->ReplacementName, &CurrentScriptFile->SubstList)) {
Info->RemoveSubstAlias = FALSE;
} else {
Info->RemoveSubstAlias = TRUE;
}
}
CurrentScriptFile->CurrentCommand->Data = Info;
} else {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, ArgSet, ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
ShellStatus = SHELL_INVALID_PARAMETER;
}
} else {
//
// These need to be NULL since they are used to determine if this is the first pass later on...
//
ASSERT(ArgSetWalker == NULL);
ASSERT(ArgSet == NULL);
}
Info = (SHELL_FOR_INFO*)CurrentScriptFile->CurrentCommand->Data;
if (CurrentScriptFile->CurrentCommand->Reset) {
Info->CurrentValue = (CHAR16*)Info->Set;
FirstPass = TRUE;
CurrentScriptFile->CurrentCommand->Reset = FALSE;
}
if (ShellStatus == SHELL_SUCCESS) {
ASSERT(Info != NULL);
if (Info->Step != 0) {
//
// only advance if not the first pass
//
if (!FirstPass) {
//
// sequence version of for loop...
//
Info->Current += Info->Step;
}
TempString = AllocateZeroPool(50*sizeof(CHAR16));
UnicodeSPrint(TempString, 50*sizeof(CHAR16), L"%d", Info->Current);
InternalUpdateAliasOnList(Info->ReplacementName, TempString, &CurrentScriptFile->SubstList);
FreePool(TempString);
if ((Info->Step > 0 && Info->Current > Info->End) || (Info->Step < 0 && Info->Current < Info->End)) {
CurrentScriptFile->CurrentCommand->Data = NULL;
//
// find the matching endfor (we're done with the loop)
//
if (!MoveToTag(GetNextNode, L"endfor", L"for", NULL, CurrentScriptFile, TRUE, FALSE, FALSE)) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"EndFor", L"For", ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
ShellStatus = SHELL_DEVICE_ERROR;
}
if (Info->RemoveSubstAlias) {
//
// remove item from list
//
InternalRemoveAliasFromList(Info->ReplacementName, &CurrentScriptFile->SubstList);
}
FreePool(Info);
}
} else {
//
// Must be in 'in' version of for loop...
//
ASSERT(Info->Set != NULL);
if (Info->CurrentValue != NULL && *Info->CurrentValue != CHAR_NULL) {
if (Info->CurrentValue[0] == L'\"') {
Info->CurrentValue++;
}
while (Info->CurrentValue[0] == L' ') {
Info->CurrentValue++;
}
if (Info->CurrentValue[0] == L'\"') {
Info->CurrentValue++;
}
//
// do the next one of the set
//
ASSERT(TempString == NULL);
TempString = StrnCatGrow(&TempString, NULL, Info->CurrentValue, 0);
TempSpot = StrStr(TempString, L"\" \"");
if (TempSpot != NULL) {
*TempSpot = CHAR_NULL;
}
while (TempString[StrLen(TempString)-1] == L'\"') {
TempString[StrLen(TempString)-1] = CHAR_NULL;
}
InternalUpdateAliasOnList(Info->ReplacementName, TempString, &CurrentScriptFile->SubstList);
Info->CurrentValue += StrLen(TempString);
if (Info->CurrentValue[0] == L'\"') {
Info->CurrentValue++;
}
while (Info->CurrentValue[0] == L' ') {
Info->CurrentValue++;
}
if (Info->CurrentValue[0] == L'\"') {
Info->CurrentValue++;
}
FreePool(TempString);
} else {
CurrentScriptFile->CurrentCommand->Data = NULL;
//
// find the matching endfor (we're done with the loop)
//
if (!MoveToTag(GetNextNode, L"endfor", L"for", NULL, CurrentScriptFile, TRUE, FALSE, FALSE)) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"EndFor", L"For", ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
ShellStatus = SHELL_DEVICE_ERROR;
}
if (Info->RemoveSubstAlias) {
//
// remove item from list
//
InternalRemoveAliasFromList(Info->ReplacementName, &CurrentScriptFile->SubstList);
}
FreePool(Info);
}
}
}
if (ArgSet != NULL) {
FreePool(ArgSet);
}
return (ShellStatus);
}

View File

@ -0,0 +1,92 @@
/** @file
Main file for goto shell level 1 function.
Copyright (c) 2009 - 2010, 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"
/**
Function for 'goto' 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
ShellCommandRunGoto (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
LIST_ENTRY *Package;
CHAR16 *ProblemParam;
SHELL_STATUS ShellStatus;
CHAR16 *CompareString;
UINTN Size;
ShellStatus = SHELL_SUCCESS;
CompareString = NULL;
//
// initialize the shell lib (we must be in non-auto-init...)
//
Status = ShellInitialize();
ASSERT_EFI_ERROR(Status);
Status = CommandInit();
ASSERT_EFI_ERROR(Status);
if (!gEfiShellProtocol->BatchIsActive()) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"Goto");
return (SHELL_UNSUPPORTED);
}
//
// parse the command line
//
Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE);
if (EFI_ERROR(Status)) {
if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel1HiiHandle, ProblemParam);
FreePool(ProblemParam);
ShellStatus = SHELL_INVALID_PARAMETER;
} else {
ASSERT(FALSE);
}
} else {
if (ShellCommandLineGetRawValue(Package, 2) != NULL) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel1HiiHandle);
ShellStatus = SHELL_INVALID_PARAMETER;
} else if (ShellCommandLineGetRawValue(Package, 1) == NULL) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel1HiiHandle);
ShellStatus = SHELL_INVALID_PARAMETER;
} else {
Size = 0;
ASSERT((CompareString == NULL && Size == 0) || (CompareString != NULL));
CompareString = StrnCatGrow(&CompareString, &Size, L":", 0);
CompareString = StrnCatGrow(&CompareString, &Size, ShellCommandLineGetRawValue(Package, 1), 0);
//
// Check forwards and then backwards for a label...
//
if (!MoveToTag(GetNextNode, L"endfor", L"for", CompareString, ShellCommandGetCurrentScriptFile(), FALSE, FALSE, TRUE)) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, CompareString, L"Goto", ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
ShellStatus = SHELL_NOT_FOUND;
}
FreePool(CompareString);
}
ShellCommandLineFreeVarList (Package);
}
return (ShellStatus);
}

View File

@ -0,0 +1,962 @@
/** @file
Main file for If and else shell level 1 function.
Copyright (c) 2009 - 2010, 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"
#include <Library/PrintLib.h>
typedef enum {
END_TAG_OR,
END_TAG_AND,
END_TAG_THEN,
END_TAG_MAX
} END_TAG_TYPE;
typedef enum {
OPERATOR_GT,
OPERATOR_LT,
OPERATOR_EQ,
OPERATOR_NE,
OPERATOR_GE,
OPERATOR_LE,
OPERATOR_UGT,
OPERATOR_ULT,
OPERATOR_UGE,
OPERATOR_ULE,
OPERATOR_MAX
} BIN_OPERATOR_TYPE;
BOOLEAN
EFIAPI
IsNextFragment (
IN CONST CHAR16 **Statement,
IN CONST CHAR16 *Fragment
)
{
CHAR16 *Tester;
Tester = NULL;
Tester = StrnCatGrow(&Tester, NULL, *Statement, StrLen(Fragment));
ASSERT(Tester != NULL);
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++;
}
FreePool(Tester);
return (TRUE);
}
FreePool(Tester);
return (FALSE);
}
BOOLEAN
EFIAPI
IsValidProfile (
IN CONST CHAR16 *String
)
{
CONST CHAR16 *ProfilesString;
CONST CHAR16 *TempLocation;
ProfilesString = ShellGetEnvironmentVariable(L"profiles");
TempLocation = StrStr(ProfilesString, String);
if ((TempLocation != NULL) && (*(TempLocation-1) == L';') && (*(TempLocation+StrLen(String)) == L';')) {
return (TRUE);
}
return (FALSE);
}
BOOLEAN
EFIAPI
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 OPERATOR_UGT:
case OPERATOR_GT:
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)StrDecimalToUintn(Compare1+1);
} else {
Cmp1 = (INTN)StrDecimalToUintn(Compare1);
}
if (Compare2[0] == L'-') {
Cmp2 = 0 - (INTN)StrDecimalToUintn(Compare2+1);
} else {
Cmp2 = (INTN)StrDecimalToUintn(Compare2);
}
if (BinOp == OPERATOR_GT) {
if (Cmp1 > Cmp2) {
return (TRUE);
}
} else {
if ((UINTN)Cmp1 > (UINTN)Cmp2) {
return (TRUE);
}
}
}
return (FALSE);
break;
case OPERATOR_ULT:
case OPERATOR_LT:
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)StrDecimalToUintn(Compare1+1);
} else {
Cmp1 = (INTN)StrDecimalToUintn(Compare1);
}
if (Compare2[0] == L'-') {
Cmp2 = 0 - (INTN)StrDecimalToUintn(Compare2+1);
} else {
Cmp2 = (INTN)StrDecimalToUintn(Compare2);
}
if (BinOp == OPERATOR_LT) {
if (Cmp1 < Cmp2) {
return (TRUE);
}
} else {
if ((UINTN)Cmp1 < (UINTN)Cmp2) {
return (TRUE);
}
}
}
return (FALSE);
break;
case OPERATOR_EQ:
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);
break;
case OPERATOR_NE:
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)StrDecimalToUintn(Compare1+1);
} else {
Cmp1 = (INTN)StrDecimalToUintn(Compare1);
}
if (Compare2[0] == L'-') {
Cmp2 = 0 - (INTN)StrDecimalToUintn(Compare2+1);
} else {
Cmp2 = (INTN)StrDecimalToUintn(Compare2);
}
if (Cmp1 != Cmp2) {
return (TRUE);
}
}
return (FALSE);
break;
case OPERATOR_UGE:
case OPERATOR_GE:
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)StrDecimalToUintn(Compare1+1);
} else {
Cmp1 = (INTN)StrDecimalToUintn(Compare1);
}
if (Compare2[0] == L'-') {
Cmp2 = 0 - (INTN)StrDecimalToUintn(Compare2+1);
} else {
Cmp2 = (INTN)StrDecimalToUintn(Compare2);
}
if (BinOp == OPERATOR_GE) {
if (Cmp1 >= Cmp2) {
return (TRUE);
}
} else {
if ((UINTN)Cmp1 >= (UINTN)Cmp2) {
return (TRUE);
}
}
}
return (FALSE);
break;
case OPERATOR_LE:
case OPERATOR_ULE:
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)StrDecimalToUintn(Compare1+1);
} else {
Cmp1 = (INTN)StrDecimalToUintn(Compare1);
}
if (Compare2[0] == L'-') {
Cmp2 = 0 - (INTN)StrDecimalToUintn(Compare2+1);
} else {
Cmp2 = (INTN)StrDecimalToUintn(Compare2);
}
if (BinOp == OPERATOR_LE) {
if (Cmp1 <= Cmp2) {
return (TRUE);
}
} else {
if ((UINTN)Cmp1 <= (UINTN)Cmp2) {
return (TRUE);
}
}
}
return (FALSE);
break;
}
ASSERT(FALSE);
return (FALSE);
}
EFI_STATUS
EFIAPI
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;
ASSERT((END_TAG_TYPE)OperatorToUse != END_TAG_THEN);
Status = EFI_SUCCESS;
BinOp = OPERATOR_MAX;
OperationResult = FALSE;
StatementWalker = gEfiShellParametersProtocol->Argv[StartParameterNumber];
if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"not")) {
NotPresent = TRUE;
StatementWalker = gEfiShellParametersProtocol->Argv[++StartParameterNumber];
} else {
NotPresent = FALSE;
}
//
// now check for 'boolfunc' operators
//
if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"isint")) {
if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && 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 (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"exists") || IsNextFragment((CONST CHAR16**)(&StatementWalker), L"exist")) {
if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && 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 (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"available")) {
if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && 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 (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"profile")) {
if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && 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 = OPERATOR_MAX;
//
// get the first item
//
StatementWalker = gEfiShellParametersProtocol->Argv[StartParameterNumber];
if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"efierror")) {
TempSpot = StrStr(StatementWalker, L")");
if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && 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 (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"pierror")) {
TempSpot = StrStr(StatementWalker, L")");
if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && 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 (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"oemerror")) {
TempSpot = StrStr(StatementWalker, L")");
if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && 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 (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"gt")) {
BinOp = OPERATOR_GT;
} else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"lt")) {
BinOp = OPERATOR_LT;
} else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"eq")) {
BinOp = OPERATOR_EQ;
} else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"ne")) {
BinOp = OPERATOR_NE;
} else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"ge")) {
BinOp = OPERATOR_GE;
} else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"le")) {
BinOp = OPERATOR_LE;
} else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"==")) {
BinOp = OPERATOR_EQ;
} else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"ugt")) {
BinOp = OPERATOR_UGT;
} else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"ult")) {
BinOp = OPERATOR_ULT;
} else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"uge")) {
BinOp = OPERATOR_UGE;
} else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"ule")) {
BinOp = OPERATOR_ULE;
} 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 (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"efierror")) {
TempSpot = StrStr(StatementWalker, L")");
if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && 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 (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"pierror")) {
TempSpot = StrStr(StatementWalker, L")");
if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && 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 (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"oemerror")) {
TempSpot = StrStr(StatementWalker, L")");
if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && 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 != OPERATOR_MAX) {
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 END_TAG_OR:
*PassingState = (BOOLEAN)(*PassingState || OperationResult);
break;
case END_TAG_AND:
*PassingState = (BOOLEAN)(*PassingState && OperationResult);
break;
case END_TAG_MAX:
*PassingState = (BOOLEAN)(OperationResult);
break;
default:
ASSERT(FALSE);
}
}
return (Status);
}
BOOLEAN
EFIAPI
BuildNextStatement (
IN UINTN ParameterNumber,
OUT UINTN *EndParameter,
OUT END_TAG_TYPE *EndTag
)
{
CHAR16 *Buffer;
UINTN BufferSize;
*EndTag = END_TAG_MAX;
for(Buffer = NULL, BufferSize = 0
; ParameterNumber < gEfiShellParametersProtocol->Argc
; ParameterNumber++
) {
if (gUnicodeCollation->StriColl(
gUnicodeCollation,
gEfiShellParametersProtocol->Argv[ParameterNumber],
L"or") == 0) {
*EndParameter = ParameterNumber - 1;
*EndTag = END_TAG_OR;
break;
} else if (gUnicodeCollation->StriColl(
gUnicodeCollation,
gEfiShellParametersProtocol->Argv[ParameterNumber],
L"and") == 0) {
*EndParameter = ParameterNumber - 1;
*EndTag = END_TAG_AND;
break;
} else if (gUnicodeCollation->StriColl(
gUnicodeCollation,
gEfiShellParametersProtocol->Argv[ParameterNumber],
L"then") == 0) {
*EndParameter = ParameterNumber - 1;
*EndTag = END_TAG_THEN;
break;
}
}
if (*EndTag == END_TAG_MAX) {
return (FALSE);
}
return (TRUE);
}
BOOLEAN
EFIAPI
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);
CommandWalker = CommandName;
while (CommandWalker[0] == L' ') {
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);
}
EFI_STATUS
EFIAPI
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;
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);
return (SHELL_INVALID_PARAMETER);
}
//
// Make sure that an End exists.
//
if (!MoveToTag(GetNextNode, L"endif", L"if", NULL, ShellCommandGetCurrentScriptFile(), TRUE, TRUE, FALSE)) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"EnfIf", L"If", ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
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 = END_TAG_MAX
; 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);
ShellStatus = SHELL_INVALID_PARAMETER;
} else {
Status = PerformResultOperation(CurrentValue);
if (EFI_ERROR(Status)) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_AFTER_BAD), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[CurrentParameter]);
ShellStatus = SHELL_INVALID_PARAMETER;
}
}
} else {
PreviousEnding = Ending;
//
// build up the next statement for analysis
//
if (!BuildNextStatement(CurrentParameter, &EndParameter, &Ending)) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"Then", L"If", ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
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 == END_TAG_OR && CurrentValue) || (Ending == END_TAG_AND && !CurrentValue)) {
Status = PerformResultOperation(CurrentValue);
if (EFI_ERROR(Status)) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_AFTER_BAD), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[CurrentParameter]);
ShellStatus = SHELL_INVALID_PARAMETER;
}
break;
}
}
}
if (ShellStatus == SHELL_SUCCESS){
CurrentParameter = EndParameter;
//
// Skip over the or or and parameter.
//
if (Ending == END_TAG_OR || Ending == END_TAG_AND) {
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
)
{
ASSERT_EFI_ERROR(CommandInit());
if (gEfiShellParametersProtocol->Argc > 1) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel1HiiHandle);
return (SHELL_INVALID_PARAMETER);
}
if (!gEfiShellProtocol->BatchIsActive()) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"Else");
return (SHELL_UNSUPPORTED);
}
if (!MoveToTag(GetPreviousNode, L"if", L"endif", NULL, ShellCommandGetCurrentScriptFile(), FALSE, TRUE, FALSE)) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"If", L"Else", ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
return (SHELL_DEVICE_ERROR);
}
if (!MoveToTag(GetPreviousNode, L"if", L"else", NULL, ShellCommandGetCurrentScriptFile(), FALSE, TRUE, FALSE)) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"If", L"Else", ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
return (SHELL_DEVICE_ERROR);
}
if (!MoveToTag(GetNextNode, L"endif", L"if", NULL, ShellCommandGetCurrentScriptFile(), FALSE, FALSE, FALSE)) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"EndIf", "Else", ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
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
)
{
ASSERT_EFI_ERROR(CommandInit());
if (gEfiShellParametersProtocol->Argc > 1) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel1HiiHandle);
return (SHELL_INVALID_PARAMETER);
}
if (!gEfiShellProtocol->BatchIsActive()) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"Endif");
return (SHELL_UNSUPPORTED);
}
if (!MoveToTag(GetPreviousNode, L"if", L"endif", NULL, ShellCommandGetCurrentScriptFile(), FALSE, TRUE, FALSE)) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"If", L"EndIf", ShellCommandGetCurrentScriptFile()->CurrentCommand->Line);
return (SHELL_DEVICE_ERROR);
}
return (SHELL_SUCCESS);
}

View File

@ -0,0 +1,40 @@
/** @file
Main file for else and endif shell level 1 functions. Does nothing really...
Copyright (c) 2009-2010, 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"
SHELL_STATUS
EFIAPI
ShellCommandRunNoOpScriptCommand (
VOID *RESERVED
)
{
EFI_STATUS Status;
//
// ASSERT that we can init...
//
Status = CommandInit();
ASSERT_EFI_ERROR(Status);
//
// We best be in a script...
//
ASSERT(gEfiShellProtocol->BatchIsActive());
//
// Do nothing...
//
return (SHELL_SUCCESS);
}

View File

@ -0,0 +1,63 @@
/** @file
Main file for Shift shell level 1 function.
Copyright (c) 2009 - 2010, 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"
/**
Function for 'shift' 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
ShellCommandRunShift (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
SCRIPT_FILE *CurrentScriptFile;
UINTN LoopVar;
Status = CommandInit();
ASSERT_EFI_ERROR(Status);
if (!gEfiShellProtocol->BatchIsActive()) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"Shift");
return (SHELL_UNSUPPORTED);
}
CurrentScriptFile = ShellCommandGetCurrentScriptFile();
ASSERT(CurrentScriptFile != NULL);
if (CurrentScriptFile->Argc < 2) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel1HiiHandle);
return (SHELL_UNSUPPORTED);
}
for (LoopVar = 0 ; LoopVar < CurrentScriptFile->Argc ; LoopVar++) {
if (LoopVar == 0) {
SHELL_FREE_NON_NULL(CurrentScriptFile->Argv[LoopVar]);
}
if (LoopVar < CurrentScriptFile->Argc -1) {
CurrentScriptFile->Argv[LoopVar] = CurrentScriptFile->Argv[LoopVar+1];
} else {
CurrentScriptFile->Argv[LoopVar] = NULL;
}
}
CurrentScriptFile->Argc--;
return (SHELL_SUCCESS);
}

View File

@ -0,0 +1,251 @@
/** @file
Main file for NULL named library for level 1 shell command functions.
Copyright (c) 2009 - 2010, 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;
CONST EFI_GUID gShellLevel1HiiGuid = \
{ \
0xdec5daa4, 0x6781, 0x4820, { 0x9c, 0x63, 0xa7, 0xb0, 0xe4, 0xf1, 0xdb, 0x31 }
};
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_UNSUPPORTED);
}
gShellLevel1HiiHandle = HiiAddPackages (&gShellLevel1HiiGuid, gImageHandle, UefiShellLevel1CommandsLibStrings, NULL);
if (gShellLevel1HiiHandle == NULL) {
return (EFI_DEVICE_ERROR);
}
//
// install our shell command handlers that are always installed
//
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.
**/
EFI_STATUS
EFIAPI
ShellLevel1CommandsLibDestructor (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
if (gShellLevel1HiiHandle != NULL) {
HiiRemovePackages(gShellLevel1HiiHandle);
}
return (EFI_SUCCESS);
}
BOOLEAN
EFIAPI
TestNodeForMove (
IN CONST LIST_MANIP_FUNC Function,
IN CONST CHAR16 *DecrementerTag,
IN CONST CHAR16 *IncrementerTag,
IN CONST CHAR16 *Label OPTIONAL,
IN SCRIPT_FILE *ScriptFile,
IN CONST BOOLEAN MovePast,
IN CONST BOOLEAN FindOnly,
IN CONST SCRIPT_COMMAND_LIST *CommandNode,
IN 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);
CommandNameWalker = CommandName;
while(CommandNameWalker[0] == L' ') {
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);
}
BOOLEAN
EFIAPI
MoveToTag (
IN CONST LIST_MANIP_FUNC Function,
IN CONST CHAR16 *DecrementerTag,
IN CONST CHAR16 *IncrementerTag,
IN CONST CHAR16 *Label OPTIONAL,
IN 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);
}

View File

@ -0,0 +1,182 @@
/** @file
Main file for NULL named library for level 1 shell command functions.
Copyright (c) 2009 - 2010, 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 <Uefi.h>
#include <ShellBase.h>
#include <Protocol/EfiShell.h>
#include <Protocol/EfiShellParameters.h>
#include <Protocol/DevicePath.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/UnicodeCollation.h>
#include <Protocol/DevicePathToText.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <Library/ShellCommandLib.h>
#include <Library/ShellLib.h>
#include <Library/SortLib.h>
#include <Library/UefiLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/HiiLib.h>
#include <Library/FileHandleLib.h>
extern EFI_HANDLE gShellLevel1HiiHandle;
extern CONST EFI_GUID gShellLevel1HiiGuid;
/**
Function for 'exit' 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
ShellCommandRunExit (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
/**
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
);
/**
Function for 'for' 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
ShellCommandRunFor (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
/**
Function for 'endfor' 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
ShellCommandRunEndFor (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
/**
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
);
/**
Function for 'goto' 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
ShellCommandRunGoto (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
/**
Function for 'shift' 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
ShellCommandRunShift (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
/**
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
);
///
/// Function prototype for BOTH GetNextNode and GetPreviousNode...
/// This is used to control the MoveToTag function direction...
///
typedef
LIST_ENTRY *
(EFIAPI *LIST_MANIP_FUNC)(
IN CONST LIST_ENTRY *List,
IN CONST LIST_ENTRY *Node
);
/**
Function to move to a spacified tag in a script file structure.
@param[in] Function The pointer to the function to move with.
@param[in] DecrementerTag The pointer to a string to decrement upon finding.
@param[in] IncrementerTag The pointer to a string to increment upon finding.
@param[in] Label A Label to look for.
@param[in] ScriptFile The script file structure to look in.
@param[in] MovePast TRUE to go to the element just after the found one. FALSE otherwise.
@param[in] FindOnly FALSE to change the execution point in the script file structure. TRUE otherwise.
@param[in] WrapAroundScript TRUE to go to begining when end is hit, or vise versa. FALSE otherwise.
**/
BOOLEAN
EFIAPI
MoveToTag (
IN CONST LIST_MANIP_FUNC Function,
IN CONST CHAR16 *DecrementerTag,
IN CONST CHAR16 *IncrementerTag,
IN CONST CHAR16 *Label OPTIONAL,
IN SCRIPT_FILE *ScriptFile,
IN CONST BOOLEAN MovePast,
IN CONST BOOLEAN FindOnly,
IN CONST BOOLEAN WrapAroundScript
);

View File

@ -0,0 +1,54 @@
## @file
# Provides shell level 1 functions
#
# Copyright (c) 2009-2010, 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.
#
#
##
[Defines]
INF_VERSION = 0x00010006
BASE_NAME = UefiShellLevel1CommandsLib
FILE_GUID = 50cb6037-1102-47af-b2dd-9944b6eb1abe
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
LIBRARY_CLASS = NULL|UEFI_APPLICATION UEFI_DRIVER
CONSTRUCTOR = ShellLevel1CommandsLibConstructor
DESTRUCTOR = ShellLevel1CommandsLibDestructor
[Sources.common]
UefiShellLevel1CommandsLib.c
UefiShellLevel1CommandsLib.h
UefiShellLevel1CommandsLib.uni
Exit.c
Goto.c
If.c
For.c
Shift.c
[Packages]
MdePkg/MdePkg.dec
ShellPkg/ShellPkg.dec
MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
MemoryAllocationLib
BaseLib
BaseMemoryLib
DebugLib
ShellCommandLib
ShellLib
UefiLib
UefiRuntimeServicesTableLib
UefiBootServicesTableLib
SortLib
PrintLib
[Pcd.common]
gEfiShellPkgTokenSpaceGuid.PcdShellSupportLevel # ALWAYS_CONSUMED