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 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "UefiShellLevel2CommandsLib.h"
13 Check if data is coming from StdIn output.
17 @retval TRUE StdIn stream data available to parse
18 @retval FALSE StdIn stream data is not available to parse.
21 IsStdInDataAvailable (
25 SHELL_FILE_HANDLE FileHandle
;
29 UINT64 OriginalFilePosition
;
33 OriginalFilePosition
= 0;
35 if (ShellOpenFileByName (L
">i", &FileHandle
, EFI_FILE_MODE_READ
, 0) == EFI_SUCCESS
) {
36 CharSize
= sizeof (CHAR16
);
37 gEfiShellProtocol
->GetFilePosition (FileHandle
, &OriginalFilePosition
);
38 Status
= gEfiShellProtocol
->ReadFile (FileHandle
, &CharSize
, &CharBuffer
);
39 if (EFI_ERROR (Status
) || (CharSize
!= sizeof (CHAR16
))) {
43 gEfiShellProtocol
->SetFilePosition (FileHandle
, OriginalFilePosition
);
46 if (FileHandle
== NULL
) {
54 Handle stings for SFO Output with escape character ^ in a string
55 1. Quotation marks in the string must be escaped by using a ^ character (i.e. ^").
56 2. The ^ character may be inserted using ^^.
58 @param[in] String The Unicode NULL-terminated string.
60 @retval NewString The new string handled for SFO.
63 HandleStringWithEscapeCharForParse (
76 // start to parse the input string.
78 NewStr
= AllocateZeroPool (StrSize (String
));
85 while (*StrWalker
!= CHAR_NULL
) {
86 if ((*StrWalker
== L
'^') && ((*(StrWalker
+ 1) == L
'^') || (*(StrWalker
+ 1) == L
'"'))) {
87 *NewStr
= *(StrWalker
+ 1);
101 Do the actual parsing of the file. the file should be SFO output from a
102 shell command or a similar format.
104 @param[in] FileName The filename to open.
105 @param[in] TableName The name of the table to find.
106 @param[in] ColumnIndex The column number to get.
107 @param[in] TableNameInstance Which instance of the table to get (row).
108 @param[in] ShellCommandInstance Which instance of the command to get.
109 @param[in] StreamingUnicode Indicates Input file is StdIn Unicode streaming data or not
111 @retval SHELL_NOT_FOUND The requested instance was not found.
112 @retval SHELL_SUCCESS The operation was successful.
116 IN CONST CHAR16
*FileName
,
117 IN CONST CHAR16
*TableName
,
118 IN CONST UINTN ColumnIndex
,
119 IN CONST UINTN TableNameInstance
,
120 IN CONST UINTN ShellCommandInstance
,
121 IN BOOLEAN StreamingUnicode
124 SHELL_FILE_HANDLE FileHandle
;
130 CHAR16
*ColumnPointer
;
131 SHELL_STATUS ShellStatus
;
135 ASSERT (FileName
!= NULL
);
136 ASSERT (TableName
!= NULL
);
138 ShellStatus
= SHELL_SUCCESS
;
140 Status
= ShellOpenFileByName (FileName
, &FileHandle
, EFI_FILE_MODE_READ
, 0);
141 if (EFI_ERROR (Status
)) {
142 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellLevel2HiiHandle
, L
"parse", FileName
);
143 ShellStatus
= SHELL_NOT_FOUND
;
144 } else if (!EFI_ERROR (FileHandleIsDirectory (FileHandle
))) {
145 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_NOT_FILE
), gShellLevel2HiiHandle
, L
"parse", FileName
);
146 ShellStatus
= SHELL_NOT_FOUND
;
148 for (LoopVariable
= 0; LoopVariable
< ShellCommandInstance
&& !ShellFileHandleEof (FileHandle
);) {
149 TempLine
= ShellFileHandleReturnLine (FileHandle
, &Ascii
);
151 if ((TempLine
== NULL
) || ((*TempLine
== CHAR_NULL
) && StreamingUnicode
)) {
156 // Search for "ShellCommand," in the file to start the SFO table
157 // for a given ShellCommand. The UEFI Shell spec does not specify
158 // a space after the comma.
160 if (StrStr (TempLine
, L
"ShellCommand,") == TempLine
) {
164 SHELL_FREE_NON_NULL (TempLine
);
167 if (LoopVariable
== ShellCommandInstance
) {
170 TempLine
= ShellFileHandleReturnLine (FileHandle
, &Ascii
);
171 if ( (TempLine
== NULL
)
172 || (*TempLine
== CHAR_NULL
)
173 || (StrStr (TempLine
, L
"ShellCommand,") == TempLine
))
175 SHELL_FREE_NON_NULL (TempLine
);
179 if (StrStr (TempLine
, TableName
) == TempLine
) {
181 if ( (LoopVariable
== TableNameInstance
)
182 || (TableNameInstance
== (UINTN
)-1))
184 for (ColumnLoop
= 1, ColumnPointer
= TempLine
; ColumnLoop
< ColumnIndex
&& ColumnPointer
!= NULL
&& *ColumnPointer
!= CHAR_NULL
; ColumnLoop
++) {
185 ColumnPointer
= StrStr (ColumnPointer
, L
",\"");
186 if ((ColumnPointer
!= NULL
) && (*ColumnPointer
!= CHAR_NULL
)) {
191 if (ColumnLoop
== ColumnIndex
) {
192 if (ColumnPointer
== NULL
) {
193 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_VALUE
), gShellLevel2HiiHandle
, L
"parse", L
"Column Index");
194 ShellStatus
= SHELL_INVALID_PARAMETER
;
196 TempSpot
= StrStr (ColumnPointer
, L
",\"");
197 if (TempSpot
!= NULL
) {
198 *TempSpot
= CHAR_NULL
;
201 while (ColumnPointer
!= NULL
&& *ColumnPointer
!= CHAR_NULL
&& ColumnPointer
[0] == L
' ') {
205 if ((ColumnPointer
!= NULL
) && (*ColumnPointer
!= CHAR_NULL
) && (ColumnPointer
[0] == L
'\"')) {
209 if ((ColumnPointer
!= NULL
) && (*ColumnPointer
!= CHAR_NULL
) && (ColumnPointer
[StrLen (ColumnPointer
) - 1] == L
'\"')) {
210 ColumnPointer
[StrLen (ColumnPointer
) - 1] = CHAR_NULL
;
213 SfoString
= HandleStringWithEscapeCharForParse (ColumnPointer
);
214 if (SfoString
!= NULL
) {
215 ShellPrintEx (-1, -1, L
"%s\r\n", SfoString
);
216 SHELL_FREE_NON_NULL (SfoString
);
223 SHELL_FREE_NON_NULL (TempLine
);
228 return (ShellStatus
);
231 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
232 { L
"-i", TypeValue
},
233 { L
"-s", TypeValue
},
238 Function for 'parse' command.
240 @param[in] ImageHandle Handle to the Image (NULL if Internal).
241 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
245 ShellCommandRunParse (
246 IN EFI_HANDLE ImageHandle
,
247 IN EFI_SYSTEM_TABLE
*SystemTable
252 CHAR16
*ProblemParam
;
253 CONST CHAR16
*FileName
;
254 CONST CHAR16
*TableName
;
255 CONST CHAR16
*ColumnString
;
256 SHELL_STATUS ShellStatus
;
257 UINTN ShellCommandInstance
;
258 UINTN TableNameInstance
;
259 BOOLEAN StreamingUnicode
;
261 ShellStatus
= SHELL_SUCCESS
;
263 StreamingUnicode
= FALSE
;
266 // initialize the shell lib (we must be in non-auto-init...)
268 Status
= ShellInitialize ();
269 ASSERT_EFI_ERROR (Status
);
272 // parse the command line
274 Status
= ShellCommandLineParseEx (ParamList
, &Package
, &ProblemParam
, TRUE
, FALSE
);
275 if (EFI_ERROR (Status
)) {
276 if ((Status
== EFI_VOLUME_CORRUPTED
) && (ProblemParam
!= NULL
)) {
277 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellLevel2HiiHandle
, L
"parse", ProblemParam
);
278 FreePool (ProblemParam
);
279 ShellStatus
= SHELL_INVALID_PARAMETER
;
284 StreamingUnicode
= IsStdInDataAvailable ();
285 if ((!StreamingUnicode
&& (ShellCommandLineGetCount (Package
) < 4)) ||
286 (ShellCommandLineGetCount (Package
) < 3))
288 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel2HiiHandle
, L
"parse");
289 ShellStatus
= SHELL_INVALID_PARAMETER
;
290 } else if ((StreamingUnicode
&& (ShellCommandLineGetCount (Package
) > 3)) ||
291 (ShellCommandLineGetCount (Package
) > 4))
293 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel2HiiHandle
, L
"parse");
294 ShellStatus
= SHELL_INVALID_PARAMETER
;
296 if (StreamingUnicode
) {
298 TableName
= ShellCommandLineGetRawValue (Package
, 1);
299 ColumnString
= ShellCommandLineGetRawValue (Package
, 2);
301 FileName
= ShellCommandLineGetRawValue (Package
, 1);
302 TableName
= ShellCommandLineGetRawValue (Package
, 2);
303 ColumnString
= ShellCommandLineGetRawValue (Package
, 3);
306 if (ShellCommandLineGetValue (Package
, L
"-i") == NULL
) {
307 TableNameInstance
= (UINTN
)-1;
309 TableNameInstance
= ShellStrToUintn (ShellCommandLineGetValue (Package
, L
"-i"));
312 if (ShellCommandLineGetValue (Package
, L
"-s") == NULL
) {
313 ShellCommandInstance
= 1;
315 ShellCommandInstance
= ShellStrToUintn (ShellCommandLineGetValue (Package
, L
"-s"));
318 ShellStatus
= PerformParsing (FileName
, TableName
, ShellStrToUintn (ColumnString
), TableNameInstance
, ShellCommandInstance
, StreamingUnicode
);
323 // free the command line package
325 ShellCommandLineFreeVarList (Package
);
327 return (ShellStatus
);