2 Main file for Parse shell level 2 function.
4 (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "UefiShellLevel2CommandsLib.h"
19 Check if data is coming from StdIn output.
23 @retval TRUE StdIn stream data available to parse
24 @retval FALSE StdIn stream data is not available to parse.
27 IsStdInDataAvailable (
31 SHELL_FILE_HANDLE FileHandle
;
35 UINT64 OriginalFilePosition
;
39 OriginalFilePosition
= 0;
41 if (ShellOpenFileByName (L
">i", &FileHandle
, EFI_FILE_MODE_READ
, 0) == EFI_SUCCESS
) {
42 CharSize
= sizeof(CHAR16
);
43 gEfiShellProtocol
->GetFilePosition (FileHandle
, &OriginalFilePosition
);
44 Status
= gEfiShellProtocol
->ReadFile (FileHandle
, &CharSize
, &CharBuffer
);
45 if (EFI_ERROR (Status
) || (CharSize
!= sizeof(CHAR16
))) {
48 gEfiShellProtocol
->SetFilePosition(FileHandle
, OriginalFilePosition
);
51 if (FileHandle
== NULL
) {
59 Handle stings for SFO Output with escape character ^ in a string
60 1. Quotation marks in the string must be escaped by using a ^ character (i.e. ^").
61 2. The ^ character may be inserted using ^^.
63 @param[in] String The Unicode NULL-terminated string.
65 @retval NewString The new string handled for SFO.
68 HandleStringWithEscapeCharForParse (
81 // start to parse the input string.
83 NewStr
= AllocateZeroPool (StrSize (String
));
89 while (*StrWalker
!= CHAR_NULL
) {
90 if (*StrWalker
== L
'^' && (*(StrWalker
+ 1) == L
'^' || *(StrWalker
+ 1) == L
'"')) {
91 *NewStr
= *(StrWalker
+ 1);
105 Do the actual parsing of the file. the file should be SFO output from a
106 shell command or a similar format.
108 @param[in] FileName The filename to open.
109 @param[in] TableName The name of the table to find.
110 @param[in] ColumnIndex The column number to get.
111 @param[in] TableNameInstance Which instance of the table to get (row).
112 @param[in] ShellCommandInstance Which instance of the command to get.
113 @param[in] StreamingUnicode Indicates Input file is StdIn Unicode streaming data or not
115 @retval SHELL_NOT_FOUND The requested instance was not found.
116 @retval SHELL_SUCCESS The operation was successful.
120 IN CONST CHAR16
*FileName
,
121 IN CONST CHAR16
*TableName
,
122 IN CONST UINTN ColumnIndex
,
123 IN CONST UINTN TableNameInstance
,
124 IN CONST UINTN ShellCommandInstance
,
125 IN BOOLEAN StreamingUnicode
128 SHELL_FILE_HANDLE FileHandle
;
134 CHAR16
*ColumnPointer
;
135 SHELL_STATUS ShellStatus
;
139 ASSERT(FileName
!= NULL
);
140 ASSERT(TableName
!= NULL
);
142 ShellStatus
= SHELL_SUCCESS
;
144 Status
= ShellOpenFileByName(FileName
, &FileHandle
, EFI_FILE_MODE_READ
, 0);
145 if (EFI_ERROR(Status
)) {
146 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellLevel2HiiHandle
, L
"parse", FileName
);
147 ShellStatus
= SHELL_NOT_FOUND
;
148 } else if (!EFI_ERROR (FileHandleIsDirectory (FileHandle
))) {
149 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_NOT_FILE
), gShellLevel2HiiHandle
, L
"parse", FileName
);
150 ShellStatus
= SHELL_NOT_FOUND
;
152 for (LoopVariable
= 0 ; LoopVariable
< ShellCommandInstance
&& !ShellFileHandleEof(FileHandle
);) {
153 TempLine
= ShellFileHandleReturnLine (FileHandle
, &Ascii
);
155 if ((TempLine
== NULL
) || (*TempLine
== CHAR_NULL
&& StreamingUnicode
)) {
160 // Search for "ShellCommand," in the file to start the SFO table
161 // for a given ShellCommand. The UEFI Shell spec does not specify
162 // a space after the comma.
164 if (StrStr (TempLine
, L
"ShellCommand,") == TempLine
) {
167 SHELL_FREE_NON_NULL(TempLine
);
169 if (LoopVariable
== ShellCommandInstance
) {
172 TempLine
= ShellFileHandleReturnLine (FileHandle
, &Ascii
);
174 || *TempLine
== CHAR_NULL
175 || StrStr (TempLine
, L
"ShellCommand,") == TempLine
) {
176 SHELL_FREE_NON_NULL(TempLine
);
179 if (StrStr (TempLine
, TableName
) == TempLine
) {
181 if (LoopVariable
== TableNameInstance
182 || (TableNameInstance
== (UINTN
)-1)) {
183 for (ColumnLoop
= 1, ColumnPointer
= TempLine
; ColumnLoop
< ColumnIndex
&& ColumnPointer
!= NULL
&& *ColumnPointer
!= CHAR_NULL
; ColumnLoop
++) {
184 ColumnPointer
= StrStr (ColumnPointer
, L
",\"");
185 if (ColumnPointer
!= NULL
&& *ColumnPointer
!= CHAR_NULL
){
189 if (ColumnLoop
== ColumnIndex
) {
190 if (ColumnPointer
== NULL
) {
191 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_VALUE
), gShellLevel2HiiHandle
, L
"parse", L
"Column Index");
192 ShellStatus
= SHELL_INVALID_PARAMETER
;
194 TempSpot
= StrStr (ColumnPointer
, L
",\"");
195 if (TempSpot
!= NULL
) {
196 *TempSpot
= CHAR_NULL
;
198 while (ColumnPointer
!= NULL
&& *ColumnPointer
!= CHAR_NULL
&& ColumnPointer
[0] == L
' '){
201 if (ColumnPointer
!= NULL
&& *ColumnPointer
!= CHAR_NULL
&& ColumnPointer
[0] == L
'\"'){
204 if (ColumnPointer
!= NULL
&& *ColumnPointer
!= CHAR_NULL
&& ColumnPointer
[StrLen (ColumnPointer
) - 1] == L
'\"'){
205 ColumnPointer
[StrLen (ColumnPointer
) - 1] = CHAR_NULL
;
207 SfoString
= HandleStringWithEscapeCharForParse (ColumnPointer
);
208 if (SfoString
!= NULL
) {
209 ShellPrintEx (-1, -1, L
"%s\r\n", SfoString
);
210 SHELL_FREE_NON_NULL (SfoString
);
216 SHELL_FREE_NON_NULL(TempLine
);
220 return (ShellStatus
);
223 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
230 Function for 'parse' command.
232 @param[in] ImageHandle Handle to the Image (NULL if Internal).
233 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
237 ShellCommandRunParse (
238 IN EFI_HANDLE ImageHandle
,
239 IN EFI_SYSTEM_TABLE
*SystemTable
244 CHAR16
*ProblemParam
;
245 CONST CHAR16
*FileName
;
246 CONST CHAR16
*TableName
;
247 CONST CHAR16
*ColumnString
;
248 SHELL_STATUS ShellStatus
;
249 UINTN ShellCommandInstance
;
250 UINTN TableNameInstance
;
251 BOOLEAN StreamingUnicode
;
253 ShellStatus
= SHELL_SUCCESS
;
255 StreamingUnicode
= FALSE
;
258 // initialize the shell lib (we must be in non-auto-init...)
260 Status
= ShellInitialize();
261 ASSERT_EFI_ERROR(Status
);
264 // parse the command line
266 Status
= ShellCommandLineParseEx (ParamList
, &Package
, &ProblemParam
, TRUE
, FALSE
);
267 if (EFI_ERROR(Status
)) {
268 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
269 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellLevel2HiiHandle
, L
"parse", ProblemParam
);
270 FreePool(ProblemParam
);
271 ShellStatus
= SHELL_INVALID_PARAMETER
;
276 StreamingUnicode
= IsStdInDataAvailable ();
277 if ((!StreamingUnicode
&& (ShellCommandLineGetCount(Package
) < 4)) ||
278 (ShellCommandLineGetCount(Package
) < 3)) {
279 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel2HiiHandle
, L
"parse");
280 ShellStatus
= SHELL_INVALID_PARAMETER
;
281 } else if ((StreamingUnicode
&& (ShellCommandLineGetCount(Package
) > 3)) ||
282 (ShellCommandLineGetCount(Package
) > 4)) {
283 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel2HiiHandle
, L
"parse");
284 ShellStatus
= SHELL_INVALID_PARAMETER
;
286 if (StreamingUnicode
) {
288 TableName
= ShellCommandLineGetRawValue(Package
, 1);
289 ColumnString
= ShellCommandLineGetRawValue(Package
, 2);
291 FileName
= ShellCommandLineGetRawValue(Package
, 1);
292 TableName
= ShellCommandLineGetRawValue(Package
, 2);
293 ColumnString
= ShellCommandLineGetRawValue(Package
, 3);
295 if (ShellCommandLineGetValue(Package
, L
"-i") == NULL
) {
296 TableNameInstance
= (UINTN
)-1;
298 TableNameInstance
= ShellStrToUintn(ShellCommandLineGetValue(Package
, L
"-i"));
300 if (ShellCommandLineGetValue(Package
, L
"-s") == NULL
) {
301 ShellCommandInstance
= 1;
303 ShellCommandInstance
= ShellStrToUintn(ShellCommandLineGetValue(Package
, L
"-s"));
306 ShellStatus
= PerformParsing(FileName
, TableName
, ShellStrToUintn(ColumnString
), TableNameInstance
, ShellCommandInstance
, StreamingUnicode
);
311 // free the command line package
313 ShellCommandLineFreeVarList (Package
);
315 return (ShellStatus
);