From af1a266670d040d2f4083ff309d732d648afba2a Mon Sep 17 00:00:00 2001 From: Angelos Mouzakitis Date: Tue, 10 Oct 2023 14:33:42 +0000 Subject: Add submodule dependency files Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec --- .../Library/UefiShellLevel2CommandsLib/Parse.c | 311 +++++++++++++++++++++ 1 file changed, 311 insertions(+) create mode 100644 roms/edk2/ShellPkg/Library/UefiShellLevel2CommandsLib/Parse.c (limited to 'roms/edk2/ShellPkg/Library/UefiShellLevel2CommandsLib/Parse.c') diff --git a/roms/edk2/ShellPkg/Library/UefiShellLevel2CommandsLib/Parse.c b/roms/edk2/ShellPkg/Library/UefiShellLevel2CommandsLib/Parse.c new file mode 100644 index 000000000..47cb33252 --- /dev/null +++ b/roms/edk2/ShellPkg/Library/UefiShellLevel2CommandsLib/Parse.c @@ -0,0 +1,311 @@ +/** @file + Main file for Parse shell level 2 function. + + (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#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; + } +} + +/** + Handle stings for SFO Output with escape character ^ in a string + 1. Quotation marks in the string must be escaped by using a ^ character (i.e. ^"). + 2. The ^ character may be inserted using ^^. + + @param[in] String The Unicode NULL-terminated string. + + @retval NewString The new string handled for SFO. +**/ +EFI_STRING +HandleStringWithEscapeCharForParse ( + IN CHAR16 *String + ) +{ + EFI_STRING NewStr; + EFI_STRING StrWalker; + EFI_STRING ReturnStr; + + if (String == NULL) { + return NULL; + } + + // + // start to parse the input string. + // + NewStr = AllocateZeroPool (StrSize (String)); + if (NewStr == NULL) { + return NULL; + } + ReturnStr = NewStr; + StrWalker = String; + while (*StrWalker != CHAR_NULL) { + if (*StrWalker == L'^' && (*(StrWalker + 1) == L'^' || *(StrWalker + 1) == L'"')) { + *NewStr = *(StrWalker + 1); + StrWalker++; + } else { + *NewStr = *StrWalker; + } + StrWalker++; + NewStr++; + } + + return ReturnStr; +} + + +/** + Do the actual parsing of the file. the file should be SFO output from a + shell command or a similar format. + + @param[in] FileName The filename to open. + @param[in] TableName The name of the table to find. + @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. +**/ +SHELL_STATUS +PerformParsing( + IN CONST CHAR16 *FileName, + IN CONST CHAR16 *TableName, + IN CONST UINTN ColumnIndex, + IN CONST UINTN TableNameInstance, + IN CONST UINTN ShellCommandInstance, + IN BOOLEAN StreamingUnicode + ) +{ + SHELL_FILE_HANDLE FileHandle; + EFI_STATUS Status; + BOOLEAN Ascii; + UINTN LoopVariable; + UINTN ColumnLoop; + CHAR16 *TempLine; + CHAR16 *ColumnPointer; + SHELL_STATUS ShellStatus; + CHAR16 *TempSpot; + CHAR16 *SfoString; + + ASSERT(FileName != NULL); + ASSERT(TableName != NULL); + + ShellStatus = SHELL_SUCCESS; + + Status = ShellOpenFileByName(FileName, &FileHandle, EFI_FILE_MODE_READ, 0); + if (EFI_ERROR(Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel2HiiHandle, L"parse", FileName); + ShellStatus = SHELL_NOT_FOUND; + } else if (!EFI_ERROR (FileHandleIsDirectory (FileHandle))) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_FILE), gShellLevel2HiiHandle, L"parse", FileName); + ShellStatus = SHELL_NOT_FOUND; + } else { + for (LoopVariable = 0 ; LoopVariable < ShellCommandInstance && !ShellFileHandleEof(FileHandle);) { + TempLine = ShellFileHandleReturnLine (FileHandle, &Ascii); + + if ((TempLine == NULL) || (*TempLine == CHAR_NULL && StreamingUnicode)) { + break; + } + + // + // Search for "ShellCommand," in the file to start the SFO table + // for a given ShellCommand. The UEFI Shell spec does not specify + // a space after the comma. + // + if (StrStr (TempLine, L"ShellCommand,") == TempLine) { + LoopVariable++; + } + SHELL_FREE_NON_NULL(TempLine); + } + if (LoopVariable == ShellCommandInstance) { + LoopVariable = 0; + while(1) { + TempLine = ShellFileHandleReturnLine (FileHandle, &Ascii); + if (TempLine == NULL + || *TempLine == CHAR_NULL + || StrStr (TempLine, L"ShellCommand,") == TempLine) { + SHELL_FREE_NON_NULL(TempLine); + break; + } + if (StrStr (TempLine, TableName) == TempLine) { + LoopVariable++; + if (LoopVariable == TableNameInstance + || (TableNameInstance == (UINTN)-1)) { + for (ColumnLoop = 1, ColumnPointer = TempLine; ColumnLoop < ColumnIndex && ColumnPointer != NULL && *ColumnPointer != CHAR_NULL; ColumnLoop++) { + ColumnPointer = StrStr (ColumnPointer, L",\""); + if (ColumnPointer != NULL && *ColumnPointer != CHAR_NULL){ + ColumnPointer++; + } + } + if (ColumnLoop == ColumnIndex) { + if (ColumnPointer == NULL) { + 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",\""); + if (TempSpot != NULL) { + *TempSpot = CHAR_NULL; + } + while (ColumnPointer != NULL && *ColumnPointer != CHAR_NULL && ColumnPointer[0] == L' '){ + ColumnPointer++; + } + if (ColumnPointer != NULL && *ColumnPointer != CHAR_NULL && ColumnPointer[0] == L'\"'){ + ColumnPointer++; + } + if (ColumnPointer != NULL && *ColumnPointer != CHAR_NULL && ColumnPointer[StrLen (ColumnPointer) - 1] == L'\"'){ + ColumnPointer[StrLen (ColumnPointer) - 1] = CHAR_NULL; + } + SfoString = HandleStringWithEscapeCharForParse (ColumnPointer); + if (SfoString != NULL) { + ShellPrintEx (-1, -1, L"%s\r\n", SfoString); + SHELL_FREE_NON_NULL (SfoString); + } + } + } + } + } + SHELL_FREE_NON_NULL(TempLine); + } + } + } + return (ShellStatus); +} + +STATIC CONST SHELL_PARAM_ITEM ParamList[] = { + {L"-i", TypeValue}, + {L"-s", TypeValue}, + {NULL, TypeMax} + }; + +/** + Function for 'parse' 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 +ShellCommandRunParse ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + CONST CHAR16 *FileName; + CONST CHAR16 *TableName; + CONST CHAR16 *ColumnString; + SHELL_STATUS ShellStatus; + UINTN ShellCommandInstance; + UINTN TableNameInstance; + BOOLEAN StreamingUnicode; + + ShellStatus = SHELL_SUCCESS; + ProblemParam = NULL; + StreamingUnicode = FALSE; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize(); + ASSERT_EFI_ERROR(Status); + + // + // parse the command line + // + 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); + FreePool(ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT(FALSE); + } + } else { + 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 ((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 { + 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 { + TableNameInstance = ShellStrToUintn(ShellCommandLineGetValue(Package, L"-i")); + } + if (ShellCommandLineGetValue(Package, L"-s") == NULL) { + ShellCommandInstance = 1; + } else { + ShellCommandInstance = ShellStrToUintn(ShellCommandLineGetValue(Package, L"-s")); + } + + ShellStatus = PerformParsing(FileName, TableName, ShellStrToUintn(ColumnString), TableNameInstance, ShellCommandInstance, StreamingUnicode); + } + } + + // + // free the command line package + // + ShellCommandLineFreeVarList (Package); + + return (ShellStatus); +} + -- cgit