diff options
author | Tapan Shah <tapandshah@hp.com> | 2015-06-03 20:33:41 +0000 |
---|---|---|
committer | jcarsey <jcarsey@Edk2> | 2015-06-03 20:33:41 +0000 |
commit | 421fbf99f82f6925c395cbd25821ccec09582b6b (patch) | |
tree | 977e19eb8652bbfad801bc8ebe53cb89b98ccedd /ShellPkg | |
parent | c1993157bd81e5ab440cf24ef77b0b3fb325e89f (diff) | |
download | edk2-platforms-421fbf99f82f6925c395cbd25821ccec09582b6b.tar.xz |
ShellPkg: Add pipe support for parse command
parse reads data from StdIn when pipe is used and does not require –sfo output stored in a file. (e.g.: fs0:\> ls *.nsh –sfo | parse FileInfo 2)
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Tapan Shah <tapandshah@hp.com>
Reviewed-by: Jaben Carsey <jaben.carsey@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17555 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'ShellPkg')
-rw-r--r-- | ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.c | 3 | ||||
-rw-r--r-- | ShellPkg/Library/UefiShellLevel2CommandsLib/Parse.c | 226 |
2 files changed, 211 insertions, 18 deletions
diff --git a/ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.c b/ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.c index f224925760..b6d5d991a6 100644 --- a/ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.c +++ b/ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.c @@ -1,7 +1,7 @@ /** @file
Provides interface to shell internal functions for shell commands.
- (C) Copyright 2013-2014 Hewlett-Packard Development Company, L.P.<BR>
+ (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>
Copyright (c) 2009 - 2014, 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
@@ -1622,7 +1622,6 @@ ShellFileHandleEof( gEfiShellProtocol->GetFilePosition(Handle, &Pos);
Info = gEfiShellProtocol->GetFileInfo (Handle);
- ASSERT(Info != NULL);
gEfiShellProtocol->SetFilePosition(Handle, Pos);
if (Info == NULL) {
diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Parse.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Parse.c index 69a104389f..545b7af342 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Parse.c +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Parse.c @@ -16,6 +16,179 @@ #include "UefiShellLevel2CommandsLib.h"
/**
+ Check if data is coming from StdIn output.
+
+ @param[in] None
+
+ @retval TRUE StdIn stream data available to parse
+ @retval FALSE StdIn stream data is not available to parse.
+**/
+BOOLEAN
+IsStdInDataAvailable (
+ VOID
+ )
+{
+ SHELL_FILE_HANDLE FileHandle;
+ EFI_STATUS Status;
+ CHAR16 CharBuffer;
+ UINTN CharSize;
+ UINT64 OriginalFilePosition;
+
+ Status = EFI_SUCCESS;
+ FileHandle = NULL;
+ OriginalFilePosition = 0;
+
+ if (ShellOpenFileByName (L">i", &FileHandle, EFI_FILE_MODE_READ, 0) == EFI_SUCCESS) {
+ CharSize = sizeof(CHAR16);
+ gEfiShellProtocol->GetFilePosition (FileHandle, &OriginalFilePosition);
+ Status = gEfiShellProtocol->ReadFile (FileHandle, &CharSize, &CharBuffer);
+ if (EFI_ERROR (Status) || (CharSize != sizeof(CHAR16))) {
+ return FALSE;
+ }
+ gEfiShellProtocol->SetFilePosition(FileHandle, OriginalFilePosition);
+ }
+
+ if (FileHandle == NULL) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+}
+
+/**
+ Function to read a single line (up to but not including the \n) using StdIn data from a SHELL_FILE_HANDLE.
+
+ If the position upon start is 0, then the Ascii Boolean will be set. This should be
+ maintained and not changed for all operations with the same file.
+
+ @param[in] Handle SHELL_FILE_HANDLE to read from.
+ @param[in, out] Buffer The pointer to buffer to read into.
+ @param[in, out] Size The pointer to number of bytes in Buffer.
+ @param[in] Truncate If the buffer is large enough, this has no effect.
+ If the buffer is is too small and Truncate is TRUE,
+ the line will be truncated.
+ If the buffer is is too small and Truncate is FALSE,
+ then no read will occur.
+
+ @retval EFI_SUCCESS The operation was successful. The line is stored in
+ Buffer.
+ @retval EFI_INVALID_PARAMETER Handle was NULL.
+ @retval EFI_INVALID_PARAMETER Size was NULL.
+ @retval EFI_BUFFER_TOO_SMALL Size was not large enough to store the line.
+ Size was updated to the minimum space required.
+**/
+EFI_STATUS
+EFIAPI
+ShellFileHandleReadStdInLine(
+ IN SHELL_FILE_HANDLE Handle,
+ IN OUT CHAR16 *Buffer,
+ IN OUT UINTN *Size,
+ IN BOOLEAN Truncate
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 CharBuffer;
+ UINTN CharSize;
+ UINTN CountSoFar;
+ UINT64 OriginalFilePosition;
+
+
+ if (Handle == NULL
+ ||Size == NULL
+ ){
+ return (EFI_INVALID_PARAMETER);
+ }
+ if (Buffer == NULL) {
+ ASSERT(*Size == 0);
+ } else {
+ *Buffer = CHAR_NULL;
+ }
+ gEfiShellProtocol->GetFilePosition (Handle, &OriginalFilePosition);
+
+ for (CountSoFar = 0;;CountSoFar++){
+ CharBuffer = 0;
+ CharSize = sizeof(CHAR16);
+ Status = gEfiShellProtocol->ReadFile (Handle, &CharSize, &CharBuffer);
+ if ( EFI_ERROR(Status)
+ || CharSize == 0
+ || (CharBuffer == L'\n')
+ ){
+ break;
+ }
+ //
+ // if we have space save it...
+ //
+ if ((CountSoFar+1)*sizeof(CHAR16) < *Size){
+ ASSERT(Buffer != NULL);
+ ((CHAR16*)Buffer)[CountSoFar] = CharBuffer;
+ ((CHAR16*)Buffer)[CountSoFar+1] = CHAR_NULL;
+ }
+ }
+
+ //
+ // if we ran out of space tell when...
+ //
+ if ((CountSoFar+1)*sizeof(CHAR16) > *Size){
+ *Size = (CountSoFar+1)*sizeof(CHAR16);
+ if (!Truncate) {
+ gEfiShellProtocol->SetFilePosition(Handle, OriginalFilePosition);
+ } else {
+ DEBUG((DEBUG_WARN, "The line was truncated in ShellFileHandleReadLine"));
+ }
+ return (EFI_BUFFER_TOO_SMALL);
+ }
+ while(Buffer[StrLen(Buffer)-1] == L'\r') {
+ Buffer[StrLen(Buffer)-1] = CHAR_NULL;
+ }
+
+ return (Status);
+}
+
+
+/**
+ Function to read a single line using StdIn from a SHELL_FILE_HANDLE. The \n is not included in the returned
+ buffer. The returned buffer must be callee freed.
+
+ If the position upon start is 0, then the Ascii Boolean will be set. This should be
+ maintained and not changed for all operations with the same file.
+
+ @param[in] Handle SHELL_FILE_HANDLE to read from.
+
+ @return The line of text from the file.
+ @retval NULL There was not enough memory available.
+
+ @sa ShellFileHandleReadLine
+**/
+CHAR16*
+EFIAPI
+ParseReturnStdInLine (
+ IN SHELL_FILE_HANDLE Handle
+ )
+{
+ CHAR16 *RetVal;
+ UINTN Size;
+ EFI_STATUS Status;
+
+ Size = 0;
+ RetVal = NULL;
+
+ Status = ShellFileHandleReadStdInLine (Handle, RetVal, &Size, FALSE);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ RetVal = AllocateZeroPool(Size);
+ if (RetVal == NULL) {
+ return (NULL);
+ }
+ Status = ShellFileHandleReadStdInLine (Handle, RetVal, &Size, FALSE);
+
+ }
+ if (EFI_ERROR(Status) && (RetVal != NULL)) {
+ FreePool(RetVal);
+ RetVal = NULL;
+ }
+ return (RetVal);
+}
+
+/**
Do the actual parsing of the file. the file should be SFO output from a
shell command or a similar format.
@@ -24,6 +197,7 @@ @param[in] ColumnIndex The column number to get.
@param[in] TableNameInstance Which instance of the table to get (row).
@param[in] ShellCommandInstance Which instance of the command to get.
+ @param[in] StreamingUnicode Indicates Input file is StdIn Unicode streaming data or not
@retval SHELL_NOT_FOUND The requested instance was not found.
@retval SHELL_SUCCESS The operation was successful.
@@ -35,7 +209,8 @@ PerformParsing( IN CONST CHAR16 *TableName,
IN CONST UINTN ColumnIndex,
IN CONST UINTN TableNameInstance,
- IN CONST UINTN ShellCommandInstance
+ IN CONST UINTN ShellCommandInstance,
+ IN BOOLEAN StreamingUnicode
)
{
SHELL_FILE_HANDLE FileHandle;
@@ -62,9 +237,14 @@ PerformParsing( ShellStatus = SHELL_NOT_FOUND;
} else {
for (LoopVariable = 0 ; LoopVariable < ShellCommandInstance && !ShellFileHandleEof(FileHandle);) {
- TempLine = ShellFileHandleReturnLine(FileHandle, &Ascii);
- if (TempLine == NULL) {
- break;
+ if (StreamingUnicode) {
+ TempLine = ParseReturnStdInLine (FileHandle);
+ } else {
+ TempLine = ShellFileHandleReturnLine (FileHandle, &Ascii);
+ }
+
+ if ((TempLine == NULL) || (*TempLine == CHAR_NULL && StreamingUnicode == TRUE)) {
+ break;
}
//
@@ -80,7 +260,11 @@ PerformParsing( if (LoopVariable == ShellCommandInstance) {
LoopVariable = 0;
while(1) {
- TempLine = ShellFileHandleReturnLine(FileHandle, &Ascii);
+ if (StreamingUnicode) {
+ TempLine = ParseReturnStdInLine (FileHandle);
+ } else {
+ TempLine = ShellFileHandleReturnLine (FileHandle, &Ascii);
+ }
if (TempLine == NULL
|| *TempLine == CHAR_NULL
|| StrStr (TempLine, L"ShellCommand,") == TempLine) {
@@ -99,7 +283,7 @@ PerformParsing( }
if (ColumnLoop == ColumnIndex) {
if (ColumnPointer == NULL) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellLevel2HiiHandle, L"parse", L"Column Index");
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellLevel2HiiHandle, L"parse", L"Column Index");
ShellStatus = SHELL_INVALID_PARAMETER;
} else {
TempSpot = StrStr (ColumnPointer, L",\"");
@@ -156,9 +340,11 @@ ShellCommandRunParse ( SHELL_STATUS ShellStatus;
UINTN ShellCommandInstance;
UINTN TableNameInstance;
+ BOOLEAN StreamingUnicode;
- ShellStatus = SHELL_SUCCESS;
- ProblemParam = NULL;
+ ShellStatus = SHELL_SUCCESS;
+ ProblemParam = NULL;
+ StreamingUnicode = FALSE;
//
// initialize the shell lib (we must be in non-auto-init...)
@@ -169,7 +355,7 @@ ShellCommandRunParse ( //
// parse the command line
//
- Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
+ Status = ShellCommandLineParseEx (ParamList, &Package, &ProblemParam, TRUE, FALSE);
if (EFI_ERROR(Status)) {
if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"parse", ProblemParam);
@@ -179,17 +365,25 @@ ShellCommandRunParse ( ASSERT(FALSE);
}
} else {
- if (ShellCommandLineGetCount(Package) < 4) {
+ StreamingUnicode = IsStdInDataAvailable ();
+ if ((!StreamingUnicode && (ShellCommandLineGetCount(Package) < 4)) ||
+ (ShellCommandLineGetCount(Package) < 3)) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"parse");
ShellStatus = SHELL_INVALID_PARAMETER;
- } else if (ShellCommandLineGetCount(Package) > 4) {
+ } else if ((StreamingUnicode && (ShellCommandLineGetCount(Package) > 3)) ||
+ (ShellCommandLineGetCount(Package) > 4)) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"parse");
ShellStatus = SHELL_INVALID_PARAMETER;
} else {
- FileName = ShellCommandLineGetRawValue(Package, 1);
- TableName = ShellCommandLineGetRawValue(Package, 2);
- ColumnString = ShellCommandLineGetRawValue(Package, 3);
-
+ if (StreamingUnicode) {
+ FileName = L">i";
+ TableName = ShellCommandLineGetRawValue(Package, 1);
+ ColumnString = ShellCommandLineGetRawValue(Package, 2);
+ } else {
+ FileName = ShellCommandLineGetRawValue(Package, 1);
+ TableName = ShellCommandLineGetRawValue(Package, 2);
+ ColumnString = ShellCommandLineGetRawValue(Package, 3);
+ }
if (ShellCommandLineGetValue(Package, L"-i") == NULL) {
TableNameInstance = (UINTN)-1;
} else {
@@ -201,7 +395,7 @@ ShellCommandRunParse ( ShellCommandInstance = ShellStrToUintn(ShellCommandLineGetValue(Package, L"-s"));
}
- ShellStatus = PerformParsing(FileName, TableName, ShellStrToUintn(ColumnString), TableNameInstance, ShellCommandInstance);
+ ShellStatus = PerformParsing(FileName, TableName, ShellStrToUintn(ColumnString), TableNameInstance, ShellCommandInstance, StreamingUnicode);
}
}
|