mirror of https://github.com/acidanthera/audk.git
updated comments and added string-to-number conversion with return value to indicate success or failure. All parameter checking updated to non-case-sensitive.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11424 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
68fb05272b
commit
252d945725
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Provides interface to shell functionality for shell commands and applications.
|
||||
|
||||
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2006 - 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
|
||||
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "UefiShellLib.h"
|
||||
#include <ShellBase.h>
|
||||
#include <Library/SortLib.h>
|
||||
|
||||
#define FIND_XXXXX_FILE_BUFFER_SIZE (SIZE_OF_EFI_FILE_INFO + MAX_FILE_NAME_LEN)
|
||||
|
||||
|
@ -123,7 +124,7 @@ ShellFindSE2 (
|
|||
// maybe it's not there???
|
||||
//
|
||||
if (Status == EFI_BUFFER_TOO_SMALL) {
|
||||
Buffer = (EFI_HANDLE*)AllocatePool(BufferSize);
|
||||
Buffer = (EFI_HANDLE*)AllocateZeroPool(BufferSize);
|
||||
ASSERT(Buffer != NULL);
|
||||
Status = gBS->LocateHandle (ByProtocol,
|
||||
&gEfiShellEnvironment2Guid,
|
||||
|
@ -159,12 +160,14 @@ ShellFindSE2 (
|
|||
return (Status);
|
||||
}
|
||||
|
||||
/*/
|
||||
/**
|
||||
Function to do most of the work of the constructor. Allows for calling
|
||||
multiple times without complete re-initialization.
|
||||
|
||||
@param[in] ImageHandle A copy of the ImageHandle.
|
||||
@param[in] SystemTable A pointer to the SystemTable for the application.
|
||||
|
||||
@retval EFI_SUCCESS The operationw as successful.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
|
@ -817,7 +820,7 @@ ShellReadFile(
|
|||
EFI_STATUS
|
||||
EFIAPI
|
||||
ShellWriteFile(
|
||||
IN SHELL_FILE_HANDLE FileHandle,
|
||||
IN SHELL_FILE_HANDLE FileHandle,
|
||||
IN OUT UINTN *BufferSize,
|
||||
IN VOID *Buffer
|
||||
)
|
||||
|
@ -1169,7 +1172,6 @@ ShellSetEnvironmentVariable (
|
|||
@retval EFI_OUT_OF_RESOURCES Out of resources.
|
||||
@retval EFI_UNSUPPORTED The operation is not allowed.
|
||||
**/
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ShellExecute (
|
||||
|
@ -1770,10 +1772,11 @@ EFIAPI
|
|||
InternalIsOnCheckList (
|
||||
IN CONST CHAR16 *Name,
|
||||
IN CONST SHELL_PARAM_ITEM *CheckList,
|
||||
OUT SHELL_PARAM_TYPE *Type
|
||||
OUT SHELL_PARAM_TYPE *Type
|
||||
)
|
||||
{
|
||||
SHELL_PARAM_ITEM *TempListItem;
|
||||
CHAR16 *TempString;
|
||||
|
||||
//
|
||||
// ASSERT that all 3 pointer parameters aren't NULL
|
||||
|
@ -1788,6 +1791,7 @@ InternalIsOnCheckList (
|
|||
if ((StrCmp(Name, L"-?") == 0) ||
|
||||
(StrCmp(Name, L"-b") == 0)
|
||||
) {
|
||||
*Type = TypeFlag;
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
@ -1799,10 +1803,22 @@ InternalIsOnCheckList (
|
|||
// If the Type is TypeStart only check the first characters of the passed in param
|
||||
// If it matches set the type and return TRUE
|
||||
//
|
||||
if (TempListItem->Type == TypeStart && StrnCmp(Name, TempListItem->Name, StrLen(TempListItem->Name)) == 0) {
|
||||
*Type = TempListItem->Type;
|
||||
return (TRUE);
|
||||
} else if (StrCmp(Name, TempListItem->Name) == 0) {
|
||||
if (TempListItem->Type == TypeStart) {
|
||||
if (StrnCmp(Name, TempListItem->Name, StrLen(TempListItem->Name)) == 0) {
|
||||
*Type = TempListItem->Type;
|
||||
return (TRUE);
|
||||
}
|
||||
TempString = NULL;
|
||||
TempString = StrnCatGrow(&TempString, NULL, Name, StrLen(TempListItem->Name));
|
||||
if (TempString != NULL) {
|
||||
if (StringNoCaseCompare(&TempString, &TempListItem->Name) == 0) {
|
||||
*Type = TempListItem->Type;
|
||||
FreePool(TempString);
|
||||
return (TRUE);
|
||||
}
|
||||
FreePool(TempString);
|
||||
}
|
||||
} else if (StringNoCaseCompare(&Name, &TempListItem->Name) == 0) {
|
||||
*Type = TempListItem->Type;
|
||||
return (TRUE);
|
||||
}
|
||||
|
@ -1888,11 +1904,12 @@ InternalCommandLineParse (
|
|||
)
|
||||
{
|
||||
UINTN LoopCounter;
|
||||
SHELL_PARAM_TYPE CurrentItemType;
|
||||
SHELL_PARAM_TYPE CurrentItemType;
|
||||
SHELL_PARAM_PACKAGE *CurrentItemPackage;
|
||||
UINTN GetItemValue;
|
||||
UINTN ValueSize;
|
||||
UINTN Count;
|
||||
CONST CHAR16 *TempPointer;
|
||||
|
||||
CurrentItemPackage = NULL;
|
||||
GetItemValue = 0;
|
||||
|
@ -1938,9 +1955,9 @@ InternalCommandLineParse (
|
|||
//
|
||||
// this is a flag
|
||||
//
|
||||
CurrentItemPackage = AllocatePool(sizeof(SHELL_PARAM_PACKAGE));
|
||||
CurrentItemPackage = AllocateZeroPool(sizeof(SHELL_PARAM_PACKAGE));
|
||||
ASSERT(CurrentItemPackage != NULL);
|
||||
CurrentItemPackage->Name = AllocatePool(StrSize(Argv[LoopCounter]));
|
||||
CurrentItemPackage->Name = AllocateZeroPool(StrSize(Argv[LoopCounter]));
|
||||
ASSERT(CurrentItemPackage->Name != NULL);
|
||||
StrCpy(CurrentItemPackage->Name, Argv[LoopCounter]);
|
||||
CurrentItemPackage->Type = CurrentItemType;
|
||||
|
@ -1996,27 +2013,35 @@ InternalCommandLineParse (
|
|||
//
|
||||
// add this one as a non-flag
|
||||
//
|
||||
CurrentItemPackage = AllocatePool(sizeof(SHELL_PARAM_PACKAGE));
|
||||
|
||||
TempPointer = Argv[LoopCounter];
|
||||
if ((*TempPointer == L'^' && *(TempPointer+1) == L'-')
|
||||
|| (*TempPointer == L'^' && *(TempPointer+1) == L'/')
|
||||
|| (*TempPointer == L'^' && *(TempPointer+1) == L'+')
|
||||
){
|
||||
TempPointer++;
|
||||
}
|
||||
CurrentItemPackage = AllocateZeroPool(sizeof(SHELL_PARAM_PACKAGE));
|
||||
ASSERT(CurrentItemPackage != NULL);
|
||||
CurrentItemPackage->Name = NULL;
|
||||
CurrentItemPackage->Type = TypePosition;
|
||||
CurrentItemPackage->Value = AllocatePool(StrSize(Argv[LoopCounter]));
|
||||
CurrentItemPackage->Value = AllocateZeroPool(StrSize(TempPointer));
|
||||
ASSERT(CurrentItemPackage->Value != NULL);
|
||||
StrCpy(CurrentItemPackage->Value, Argv[LoopCounter]);
|
||||
StrCpy(CurrentItemPackage->Value, TempPointer);
|
||||
CurrentItemPackage->OriginalPosition = Count++;
|
||||
InsertHeadList(*CheckPackage, &CurrentItemPackage->Link);
|
||||
} else if (ProblemParam != NULL) {
|
||||
} else {
|
||||
//
|
||||
// this was a non-recognised flag... error!
|
||||
//
|
||||
*ProblemParam = AllocatePool(StrSize(Argv[LoopCounter]));
|
||||
ASSERT(*ProblemParam != NULL);
|
||||
StrCpy(*ProblemParam, Argv[LoopCounter]);
|
||||
if (ProblemParam != NULL) {
|
||||
*ProblemParam = AllocateZeroPool(StrSize(Argv[LoopCounter]));
|
||||
ASSERT(*ProblemParam != NULL);
|
||||
StrCpy(*ProblemParam, Argv[LoopCounter]);
|
||||
}
|
||||
ShellCommandLineFreeVarList(*CheckPackage);
|
||||
*CheckPackage = NULL;
|
||||
return (EFI_VOLUME_CORRUPTED);
|
||||
} else {
|
||||
//ASSERT(FALSE);
|
||||
}
|
||||
}
|
||||
if (GetItemValue != 0) {
|
||||
|
@ -2183,6 +2208,7 @@ ShellCommandLineGetFlag (
|
|||
)
|
||||
{
|
||||
LIST_ENTRY *Node;
|
||||
CHAR16 *TempString;
|
||||
|
||||
//
|
||||
// ASSERT that both CheckPackage and KeyString aren't NULL
|
||||
|
@ -2202,7 +2228,7 @@ ShellCommandLineGetFlag (
|
|||
for ( Node = GetFirstNode(CheckPackage)
|
||||
; !IsNull (CheckPackage, Node)
|
||||
; Node = GetNextNode(CheckPackage, Node)
|
||||
){
|
||||
){
|
||||
//
|
||||
// If the Name matches, return TRUE (and there may be NULL name)
|
||||
//
|
||||
|
@ -2210,11 +2236,20 @@ ShellCommandLineGetFlag (
|
|||
//
|
||||
// If Type is TypeStart then only compare the begining of the strings
|
||||
//
|
||||
if ( ((SHELL_PARAM_PACKAGE*)Node)->Type == TypeStart
|
||||
&& StrnCmp(KeyString, ((SHELL_PARAM_PACKAGE*)Node)->Name, StrLen(KeyString)) == 0
|
||||
){
|
||||
return (TRUE);
|
||||
} else if (StrCmp(KeyString, ((SHELL_PARAM_PACKAGE*)Node)->Name) == 0) {
|
||||
if (((SHELL_PARAM_PACKAGE*)Node)->Type == TypeStart) {
|
||||
if (StrnCmp(KeyString, ((SHELL_PARAM_PACKAGE*)Node)->Name, StrLen(KeyString)) == 0) {
|
||||
return (TRUE);
|
||||
}
|
||||
TempString = NULL;
|
||||
TempString = StrnCatGrow(&TempString, NULL, KeyString, StrLen(((SHELL_PARAM_PACKAGE*)Node)->Name));
|
||||
if (TempString != NULL) {
|
||||
if (StringNoCaseCompare(&KeyString, &((SHELL_PARAM_PACKAGE*)Node)->Name) == 0) {
|
||||
FreePool(TempString);
|
||||
return (TRUE);
|
||||
}
|
||||
FreePool(TempString);
|
||||
}
|
||||
} else if (StringNoCaseCompare(&KeyString, &((SHELL_PARAM_PACKAGE*)Node)->Name) == 0) {
|
||||
return (TRUE);
|
||||
}
|
||||
}
|
||||
|
@ -2242,6 +2277,7 @@ ShellCommandLineGetValue (
|
|||
)
|
||||
{
|
||||
LIST_ENTRY *Node;
|
||||
CHAR16 *TempString;
|
||||
|
||||
//
|
||||
// check for CheckPackage == NULL
|
||||
|
@ -2256,25 +2292,28 @@ ShellCommandLineGetValue (
|
|||
for ( Node = GetFirstNode(CheckPackage)
|
||||
; !IsNull (CheckPackage, Node)
|
||||
; Node = GetNextNode(CheckPackage, Node)
|
||||
){
|
||||
){
|
||||
//
|
||||
// If the Name matches, return the value (name can be NULL)
|
||||
// If the Name matches, return TRUE (and there may be NULL name)
|
||||
//
|
||||
if (((SHELL_PARAM_PACKAGE*)Node)->Name != NULL) {
|
||||
//
|
||||
// If Type is TypeStart then only compare the begining of the strings
|
||||
//
|
||||
if ( ((SHELL_PARAM_PACKAGE*)Node)->Type == TypeStart
|
||||
&& StrnCmp(KeyString, ((SHELL_PARAM_PACKAGE*)Node)->Name, StrLen(KeyString)) == 0
|
||||
){
|
||||
//
|
||||
// return the string part after the flag
|
||||
//
|
||||
return (((SHELL_PARAM_PACKAGE*)Node)->Name + StrLen(KeyString));
|
||||
} else if (StrCmp(KeyString, ((SHELL_PARAM_PACKAGE*)Node)->Name) == 0) {
|
||||
//
|
||||
// return the value
|
||||
//
|
||||
if (((SHELL_PARAM_PACKAGE*)Node)->Type == TypeStart) {
|
||||
if (StrnCmp(KeyString, ((SHELL_PARAM_PACKAGE*)Node)->Name, StrLen(KeyString)) == 0) {
|
||||
return (((SHELL_PARAM_PACKAGE*)Node)->Name + StrLen(KeyString));
|
||||
}
|
||||
TempString = NULL;
|
||||
TempString = StrnCatGrow(&TempString, NULL, KeyString, StrLen(((SHELL_PARAM_PACKAGE*)Node)->Name));
|
||||
if (TempString != NULL) {
|
||||
if (StringNoCaseCompare(&KeyString, &((SHELL_PARAM_PACKAGE*)Node)->Name) == 0) {
|
||||
FreePool(TempString);
|
||||
return (((SHELL_PARAM_PACKAGE*)Node)->Name + StrLen(KeyString));
|
||||
}
|
||||
FreePool(TempString);
|
||||
}
|
||||
} else if (StringNoCaseCompare(&KeyString, &((SHELL_PARAM_PACKAGE*)Node)->Name) == 0) {
|
||||
return (((SHELL_PARAM_PACKAGE*)Node)->Value);
|
||||
}
|
||||
}
|
||||
|
@ -2554,8 +2593,8 @@ InternalPrintTo (
|
|||
|
||||
Note: The background color is controlled by the shell command cls.
|
||||
|
||||
@param[in] Row the row to print at
|
||||
@param[in] Col the column to print at
|
||||
@param[in] Row the row to print at
|
||||
@param[in] Format the format string
|
||||
@param[in] Marker the marker for the variable argument list
|
||||
|
||||
|
@ -2568,7 +2607,7 @@ InternalShellPrintWorker(
|
|||
IN INT32 Col OPTIONAL,
|
||||
IN INT32 Row OPTIONAL,
|
||||
IN CONST CHAR16 *Format,
|
||||
VA_LIST Marker
|
||||
IN VA_LIST Marker
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
@ -2600,7 +2639,6 @@ InternalShellPrintWorker(
|
|||
|
||||
if (Col != -1 && Row != -1) {
|
||||
Status = gST->ConOut->SetCursorPosition(gST->ConOut, Col, Row);
|
||||
ASSERT_EFI_ERROR(Status);
|
||||
}
|
||||
|
||||
FormatWalker = mPostReplaceFormat2;
|
||||
|
@ -2908,13 +2946,15 @@ ShellIsFileInPath(
|
|||
FreePool(NewName);
|
||||
return (Status);
|
||||
}
|
||||
|
||||
/**
|
||||
Function to determine whether a string is decimal or hex representation of a number
|
||||
and return the number converted from the string.
|
||||
|
||||
@param[in] String String representation of a number
|
||||
|
||||
@retval all the number
|
||||
@return the number
|
||||
@retval (UINTN)(-1) An error ocurred.
|
||||
**/
|
||||
UINTN
|
||||
EFIAPI
|
||||
|
@ -2922,17 +2962,19 @@ ShellStrToUintn(
|
|||
IN CONST CHAR16 *String
|
||||
)
|
||||
{
|
||||
CONST CHAR16 *Walker;
|
||||
for (Walker = String; Walker != NULL && *Walker != CHAR_NULL && *Walker == L' '; Walker++);
|
||||
if (Walker == NULL || *Walker == CHAR_NULL) {
|
||||
ASSERT(FALSE);
|
||||
return ((UINTN)(-1));
|
||||
} else {
|
||||
if (StrnCmp(Walker, L"0x", 2) == 0 || StrnCmp(Walker, L"0X", 2) == 0){
|
||||
return (StrHexToUintn(Walker));
|
||||
}
|
||||
return (StrDecimalToUintn(Walker));
|
||||
UINT64 RetVal;
|
||||
BOOLEAN Hex;
|
||||
|
||||
Hex = FALSE;
|
||||
|
||||
if (!InternalShellIsHexOrDecimalNumber(String, Hex, TRUE)) {
|
||||
Hex = TRUE;
|
||||
}
|
||||
|
||||
if (!EFI_ERROR(ShellConvertStringToUint64(String, &RetVal, Hex, TRUE))) {
|
||||
return ((UINTN)RetVal);
|
||||
}
|
||||
return ((UINTN)(-1));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3086,7 +3128,7 @@ ShellPromptForResponse (
|
|||
Buffer = NULL;
|
||||
Size = 0;
|
||||
if (Type != ShellPromptResponseTypeFreeform) {
|
||||
Resp = (SHELL_PROMPT_RESPONSE*)AllocatePool(sizeof(SHELL_PROMPT_RESPONSE));
|
||||
Resp = (SHELL_PROMPT_RESPONSE*)AllocateZeroPool(sizeof(SHELL_PROMPT_RESPONSE));
|
||||
if (Resp == NULL) {
|
||||
return (EFI_OUT_OF_RESOURCES);
|
||||
}
|
||||
|
@ -3315,7 +3357,7 @@ ShellPromptForResponseHii (
|
|||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
ShellIsHexOrDecimalNumber (
|
||||
InternalShellIsHexOrDecimalNumber (
|
||||
IN CONST CHAR16 *String,
|
||||
IN CONST BOOLEAN ForceHex,
|
||||
IN CONST BOOLEAN StopAtSpace
|
||||
|
@ -3372,6 +3414,7 @@ ShellIsHexOrDecimalNumber (
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
@ -3405,3 +3448,350 @@ ShellFileExists(
|
|||
|
||||
return (EFI_SUCCESS);
|
||||
}
|
||||
|
||||
/**
|
||||
Convert a Unicode character to upper case only if
|
||||
it maps to a valid small-case ASCII character.
|
||||
|
||||
This internal function only deal with Unicode character
|
||||
which maps to a valid small-case ASCII character, i.e.
|
||||
L'a' to L'z'. For other Unicode character, the input character
|
||||
is returned directly.
|
||||
|
||||
@param Char The character to convert.
|
||||
|
||||
@retval LowerCharacter If the Char is with range L'a' to L'z'.
|
||||
@retval Unchanged Otherwise.
|
||||
|
||||
**/
|
||||
CHAR16
|
||||
EFIAPI
|
||||
InternalShellCharToUpper (
|
||||
IN CHAR16 Char
|
||||
)
|
||||
{
|
||||
if (Char >= L'a' && Char <= L'z') {
|
||||
return (CHAR16) (Char - (L'a' - L'A'));
|
||||
}
|
||||
|
||||
return Char;
|
||||
}
|
||||
|
||||
/**
|
||||
Convert a Unicode character to numerical value.
|
||||
|
||||
This internal function only deal with Unicode character
|
||||
which maps to a valid hexadecimal ASII character, i.e.
|
||||
L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other
|
||||
Unicode character, the value returned does not make sense.
|
||||
|
||||
@param Char The character to convert.
|
||||
|
||||
@return The numerical value converted.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
EFIAPI
|
||||
InternalShellHexCharToUintn (
|
||||
IN CHAR16 Char
|
||||
)
|
||||
{
|
||||
if (ShellIsDecimalDigitCharacter (Char)) {
|
||||
return Char - L'0';
|
||||
}
|
||||
|
||||
return (UINTN) (10 + InternalShellCharToUpper (Char) - L'A');
|
||||
}
|
||||
|
||||
/**
|
||||
Convert a Null-terminated Unicode hexadecimal string to a value of type UINT64.
|
||||
|
||||
This function returns a value of type UINTN by interpreting the contents
|
||||
of the Unicode string specified by String as a hexadecimal number.
|
||||
The format of the input Unicode string String is:
|
||||
|
||||
[spaces][zeros][x][hexadecimal digits].
|
||||
|
||||
The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
|
||||
The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
|
||||
If "x" appears in the input string, it must be prefixed with at least one 0.
|
||||
The function will ignore the pad space, which includes spaces or tab characters,
|
||||
before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or
|
||||
[hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the
|
||||
first valid hexadecimal digit. Then, the function stops at the first character that is
|
||||
a not a valid hexadecimal character or NULL, whichever one comes first.
|
||||
|
||||
If String has only pad spaces, then zero is returned.
|
||||
If String has no leading pad spaces, leading zeros or valid hexadecimal digits,
|
||||
then zero is returned.
|
||||
|
||||
@param[in] String A pointer to a Null-terminated Unicode string.
|
||||
@param[out] Value Upon a successful return the value of the conversion.
|
||||
@param[in] StopAtSpace FALSE to skip spaces.
|
||||
|
||||
@retval EFI_SUCCESS The conversion was successful.
|
||||
@retval EFI_INVALID_PARAMETER A parameter was NULL or invalid.
|
||||
@retval EFI_DEVICE_ERROR An overflow occured.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
InternalShellStrHexToUint64 (
|
||||
IN CONST CHAR16 *String,
|
||||
OUT UINT64 *Value,
|
||||
IN CONST BOOLEAN StopAtSpace
|
||||
)
|
||||
{
|
||||
UINT64 Result;
|
||||
|
||||
if (String == NULL || StrSize(String) == 0 || Value == NULL) {
|
||||
return (EFI_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
//
|
||||
// Ignore the pad spaces (space or tab)
|
||||
//
|
||||
while ((*String == L' ') || (*String == L'\t')) {
|
||||
String++;
|
||||
}
|
||||
|
||||
//
|
||||
// Ignore leading Zeros after the spaces
|
||||
//
|
||||
while (*String == L'0') {
|
||||
String++;
|
||||
}
|
||||
|
||||
if (InternalShellCharToUpper (*String) == L'X') {
|
||||
if (*(String - 1) != L'0') {
|
||||
return 0;
|
||||
}
|
||||
//
|
||||
// Skip the 'X'
|
||||
//
|
||||
String++;
|
||||
}
|
||||
|
||||
Result = 0;
|
||||
|
||||
//
|
||||
// Skip spaces if requested
|
||||
//
|
||||
while (StopAtSpace && *String == L' ') {
|
||||
String++;
|
||||
}
|
||||
|
||||
while (ShellIsHexaDecimalDigitCharacter (*String)) {
|
||||
//
|
||||
// If the Hex Number represented by String overflows according
|
||||
// to the range defined by UINTN, then ASSERT().
|
||||
//
|
||||
if (!(Result <= (RShiftU64((((UINT64) ~0) - InternalShellHexCharToUintn (*String)), 4)))) {
|
||||
// if (!(Result <= ((((UINT64) ~0) - InternalShellHexCharToUintn (*String)) >> 4))) {
|
||||
return (EFI_DEVICE_ERROR);
|
||||
}
|
||||
|
||||
Result = (LShiftU64(Result, 4));
|
||||
Result += InternalShellHexCharToUintn (*String);
|
||||
String++;
|
||||
|
||||
//
|
||||
// Skip spaces if requested
|
||||
//
|
||||
while (StopAtSpace && *String == L' ') {
|
||||
String++;
|
||||
}
|
||||
}
|
||||
|
||||
*Value = Result;
|
||||
return (EFI_SUCCESS);
|
||||
}
|
||||
|
||||
/**
|
||||
Convert a Null-terminated Unicode decimal string to a value of
|
||||
type UINT64.
|
||||
|
||||
This function returns a value of type UINT64 by interpreting the contents
|
||||
of the Unicode string specified by String as a decimal number. The format
|
||||
of the input Unicode string String is:
|
||||
|
||||
[spaces] [decimal digits].
|
||||
|
||||
The valid decimal digit character is in the range [0-9]. The
|
||||
function will ignore the pad space, which includes spaces or
|
||||
tab characters, before [decimal digits]. The running zero in the
|
||||
beginning of [decimal digits] will be ignored. Then, the function
|
||||
stops at the first character that is a not a valid decimal character
|
||||
or a Null-terminator, whichever one comes first.
|
||||
|
||||
If String has only pad spaces, then 0 is returned.
|
||||
If String has no pad spaces or valid decimal digits,
|
||||
then 0 is returned.
|
||||
|
||||
@param[in] String A pointer to a Null-terminated Unicode string.
|
||||
@param[out] Value Upon a successful return the value of the conversion.
|
||||
@param[in] StopAtSpace FALSE to skip spaces.
|
||||
|
||||
@retval EFI_SUCCESS The conversion was successful.
|
||||
@retval EFI_INVALID_PARAMETER A parameter was NULL or invalid.
|
||||
@retval EFI_DEVICE_ERROR An overflow occured.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
InternalShellStrDecimalToUint64 (
|
||||
IN CONST CHAR16 *String,
|
||||
OUT UINT64 *Value,
|
||||
IN CONST BOOLEAN StopAtSpace
|
||||
)
|
||||
{
|
||||
UINT64 Result;
|
||||
|
||||
if (String == NULL || StrSize (String) == 0 || Value == NULL) {
|
||||
return (EFI_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
//
|
||||
// Ignore the pad spaces (space or tab)
|
||||
//
|
||||
while ((*String == L' ') || (*String == L'\t')) {
|
||||
String++;
|
||||
}
|
||||
|
||||
//
|
||||
// Ignore leading Zeros after the spaces
|
||||
//
|
||||
while (*String == L'0') {
|
||||
String++;
|
||||
}
|
||||
|
||||
Result = 0;
|
||||
|
||||
//
|
||||
// Skip spaces if requested
|
||||
//
|
||||
while (StopAtSpace && *String == L' ') {
|
||||
String++;
|
||||
}
|
||||
while (ShellIsDecimalDigitCharacter (*String)) {
|
||||
//
|
||||
// If the number represented by String overflows according
|
||||
// to the range defined by UINT64, then ASSERT().
|
||||
//
|
||||
|
||||
if (!(Result <= (DivU64x32((((UINT64) ~0) - (*String - L'0')),10)))) {
|
||||
return (EFI_DEVICE_ERROR);
|
||||
}
|
||||
|
||||
Result = MultU64x32(Result, 10) + (*String - L'0');
|
||||
String++;
|
||||
|
||||
//
|
||||
// Stop at spaces if requested
|
||||
//
|
||||
if (StopAtSpace && *String == L' ') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*Value = Result;
|
||||
|
||||
return (EFI_SUCCESS);
|
||||
}
|
||||
|
||||
/**
|
||||
Function to verify and convert a string to its numerical value.
|
||||
|
||||
If Hex it must be preceeded with a 0x, 0X, or has ForceHex set TRUE.
|
||||
|
||||
@param[in] String The string to evaluate.
|
||||
@param[out] Value Upon a successful return the value of the conversion.
|
||||
@param[in] ForceHex TRUE - always assume hex.
|
||||
@param[in] StopAtSpace FALSE to skip spaces.
|
||||
|
||||
@retval EFI_SUCCESS The conversion was successful.
|
||||
@retval EFI_INVALID_PARAMETER String contained an invalid character.
|
||||
@retval EFI_NOT_FOUND String was a number, but Value was NULL.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ShellConvertStringToUint64(
|
||||
IN CONST CHAR16 *String,
|
||||
OUT UINT64 *Value,
|
||||
IN CONST BOOLEAN ForceHex,
|
||||
IN CONST BOOLEAN StopAtSpace
|
||||
)
|
||||
{
|
||||
UINT64 RetVal;
|
||||
CONST CHAR16 *Walker;
|
||||
EFI_STATUS Status;
|
||||
BOOLEAN Hex;
|
||||
|
||||
Hex = ForceHex;
|
||||
|
||||
if (!InternalShellIsHexOrDecimalNumber(String, Hex, StopAtSpace)) {
|
||||
if (!Hex) {
|
||||
Hex = TRUE;
|
||||
if (!InternalShellIsHexOrDecimalNumber(String, Hex, StopAtSpace)) {
|
||||
return (EFI_INVALID_PARAMETER);
|
||||
}
|
||||
} else {
|
||||
return (EFI_INVALID_PARAMETER);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Chop off leading spaces
|
||||
//
|
||||
for (Walker = String; Walker != NULL && *Walker != CHAR_NULL && *Walker == L' '; Walker++);
|
||||
|
||||
//
|
||||
// make sure we have something left that is numeric.
|
||||
//
|
||||
if (Walker == NULL || *Walker == CHAR_NULL || !InternalShellIsHexOrDecimalNumber(Walker, Hex, StopAtSpace)) {
|
||||
return (EFI_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
//
|
||||
// do the conversion.
|
||||
//
|
||||
if (Hex || StrnCmp(Walker, L"0x", 2) == 0 || StrnCmp(Walker, L"0X", 2) == 0){
|
||||
Status = InternalShellStrHexToUint64(Walker, &RetVal, StopAtSpace);
|
||||
} else {
|
||||
Status = InternalShellStrDecimalToUint64(Walker, &RetVal, StopAtSpace);
|
||||
}
|
||||
|
||||
if (Value == NULL && !EFI_ERROR(Status)) {
|
||||
return (EFI_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (Value != NULL) {
|
||||
*Value = RetVal;
|
||||
}
|
||||
|
||||
return (Status);
|
||||
}
|
||||
|
||||
/**
|
||||
Function to determin if an entire string is a valid number.
|
||||
|
||||
If Hex it must be preceeded with a 0x or has ForceHex, set TRUE.
|
||||
|
||||
@param[in] String The string to evaluate.
|
||||
@param[in] ForceHex TRUE - always assume hex.
|
||||
@param[in] StopAtSpace TRUE to halt upon finding a space, FALSE to keep going.
|
||||
|
||||
@retval TRUE It is all numeric (dec/hex) characters.
|
||||
@retval FALSE There is a non-numeric character.
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
ShellIsHexOrDecimalNumber (
|
||||
IN CONST CHAR16 *String,
|
||||
IN CONST BOOLEAN ForceHex,
|
||||
IN CONST BOOLEAN StopAtSpace
|
||||
)
|
||||
{
|
||||
if (ShellConvertStringToUint64(String, NULL, ForceHex, StopAtSpace) == EFI_NOT_FOUND) {
|
||||
return (TRUE);
|
||||
}
|
||||
return (FALSE);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Provides interface to shell functionality for shell commands and applications.
|
||||
|
||||
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2006 - 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
|
||||
|
@ -12,6 +12,9 @@
|
|||
|
||||
**/
|
||||
|
||||
#if !defined (_UEFI_SHELL_LIB_INTERNAL_H_)
|
||||
#define _UEFI_SHELL_LIB_INTERNAL_H_
|
||||
|
||||
#include <Uefi.h>
|
||||
|
||||
#include <Guid/FileInfo.h>
|
||||
|
@ -48,3 +51,26 @@ typedef struct {
|
|||
EFI_SHELL_FLUSH_FILE FlushFile;
|
||||
EFI_SHELL_GET_FILE_SIZE GetFileSize;
|
||||
} FILE_HANDLE_FUNCTION_MAP;
|
||||
|
||||
/**
|
||||
Function to determin if an entire string is a valid number.
|
||||
|
||||
If Hex it must be preceeded with a 0x or has ForceHex, set TRUE.
|
||||
|
||||
@param[in] String The string to evaluate.
|
||||
@param[in] ForceHex TRUE - always assume hex.
|
||||
@param[in] StopAtSpace TRUE to halt upon finding a space, FALSE to keep going.
|
||||
|
||||
@retval TRUE It is all numeric (dec/hex) characters.
|
||||
@retval FALSE There is a non-numeric character.
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
InternalShellIsHexOrDecimalNumber (
|
||||
IN CONST CHAR16 *String,
|
||||
IN CONST BOOLEAN ForceHex,
|
||||
IN CONST BOOLEAN StopAtSpace
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
## @file
|
||||
# Provides interface to shell functionality for shell commands and applications.
|
||||
#
|
||||
# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved. <BR>
|
||||
# Copyright (c) 2006 - 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
|
||||
|
@ -47,6 +47,7 @@
|
|||
PrintLib
|
||||
UefiLib
|
||||
HiiLib
|
||||
SortLib
|
||||
|
||||
[Protocols]
|
||||
gEfiSimpleFileSystemProtocolGuid # ALWAYS_CONSUMED
|
||||
|
|
Loading…
Reference in New Issue