]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellLevel2CommandsLib/Parse.c
ShellPkg: Apply uncrustify changes
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel2CommandsLib / Parse.c
CommitLineData
a405b86d 1/** @file\r
2 Main file for Parse shell level 2 function.\r
3\r
c011b6c9 4 (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>\r
ba0014b9 5 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
56ba3746 6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
a405b86d 7\r
8**/\r
9\r
10#include "UefiShellLevel2CommandsLib.h"\r
11\r
421fbf99
TS
12/**\r
13 Check if data is coming from StdIn output.\r
14\r
15 @param[in] None\r
ba0014b9
LG
16\r
17 @retval TRUE StdIn stream data available to parse\r
18 @retval FALSE StdIn stream data is not available to parse.\r
421fbf99
TS
19**/\r
20BOOLEAN\r
21IsStdInDataAvailable (\r
22 VOID\r
23 )\r
24{\r
47d20b54
MK
25 SHELL_FILE_HANDLE FileHandle;\r
26 EFI_STATUS Status;\r
27 CHAR16 CharBuffer;\r
28 UINTN CharSize;\r
29 UINT64 OriginalFilePosition;\r
421fbf99 30\r
ba0014b9 31 Status = EFI_SUCCESS;\r
421fbf99
TS
32 FileHandle = NULL;\r
33 OriginalFilePosition = 0;\r
34\r
35 if (ShellOpenFileByName (L">i", &FileHandle, EFI_FILE_MODE_READ, 0) == EFI_SUCCESS) {\r
47d20b54 36 CharSize = sizeof (CHAR16);\r
421fbf99
TS
37 gEfiShellProtocol->GetFilePosition (FileHandle, &OriginalFilePosition);\r
38 Status = gEfiShellProtocol->ReadFile (FileHandle, &CharSize, &CharBuffer);\r
47d20b54 39 if (EFI_ERROR (Status) || (CharSize != sizeof (CHAR16))) {\r
421fbf99
TS
40 return FALSE;\r
41 }\r
47d20b54
MK
42\r
43 gEfiShellProtocol->SetFilePosition (FileHandle, OriginalFilePosition);\r
421fbf99
TS
44 }\r
45\r
46 if (FileHandle == NULL) {\r
47 return FALSE;\r
48 } else {\r
49 return TRUE;\r
50 }\r
51}\r
52\r
307f2ce4
TS
53/**\r
54 Handle stings for SFO Output with escape character ^ in a string\r
ba0014b9 55 1. Quotation marks in the string must be escaped by using a ^ character (i.e. ^").\r
307f2ce4
TS
56 2. The ^ character may be inserted using ^^.\r
57\r
58 @param[in] String The Unicode NULL-terminated string.\r
ba0014b9 59\r
307f2ce4
TS
60 @retval NewString The new string handled for SFO.\r
61**/\r
62EFI_STRING\r
63HandleStringWithEscapeCharForParse (\r
64 IN CHAR16 *String\r
65 )\r
66{\r
67 EFI_STRING NewStr;\r
68 EFI_STRING StrWalker;\r
69 EFI_STRING ReturnStr;\r
70\r
71 if (String == NULL) {\r
72 return NULL;\r
73 }\r
ba0014b9 74\r
307f2ce4
TS
75 //\r
76 // start to parse the input string.\r
77 //\r
78 NewStr = AllocateZeroPool (StrSize (String));\r
79 if (NewStr == NULL) {\r
80 return NULL;\r
81 }\r
47d20b54 82\r
307f2ce4
TS
83 ReturnStr = NewStr;\r
84 StrWalker = String;\r
85 while (*StrWalker != CHAR_NULL) {\r
47d20b54 86 if ((*StrWalker == L'^') && ((*(StrWalker + 1) == L'^') || (*(StrWalker + 1) == L'"'))) {\r
307f2ce4
TS
87 *NewStr = *(StrWalker + 1);\r
88 StrWalker++;\r
89 } else {\r
90 *NewStr = *StrWalker;\r
91 }\r
47d20b54 92\r
307f2ce4
TS
93 StrWalker++;\r
94 NewStr++;\r
95 }\r
ba0014b9 96\r
307f2ce4
TS
97 return ReturnStr;\r
98}\r
99\r
b54fd049 100/**\r
ba0014b9 101 Do the actual parsing of the file. the file should be SFO output from a\r
b54fd049 102 shell command or a similar format.\r
103\r
104 @param[in] FileName The filename to open.\r
105 @param[in] TableName The name of the table to find.\r
106 @param[in] ColumnIndex The column number to get.\r
107 @param[in] TableNameInstance Which instance of the table to get (row).\r
108 @param[in] ShellCommandInstance Which instance of the command to get.\r
421fbf99 109 @param[in] StreamingUnicode Indicates Input file is StdIn Unicode streaming data or not\r
b54fd049 110\r
111 @retval SHELL_NOT_FOUND The requested instance was not found.\r
112 @retval SHELL_SUCCESS The operation was successful.\r
113**/\r
a405b86d 114SHELL_STATUS\r
47d20b54
MK
115PerformParsing (\r
116 IN CONST CHAR16 *FileName,\r
117 IN CONST CHAR16 *TableName,\r
118 IN CONST UINTN ColumnIndex,\r
119 IN CONST UINTN TableNameInstance,\r
120 IN CONST UINTN ShellCommandInstance,\r
121 IN BOOLEAN StreamingUnicode\r
a405b86d 122 )\r
123{\r
47d20b54
MK
124 SHELL_FILE_HANDLE FileHandle;\r
125 EFI_STATUS Status;\r
126 BOOLEAN Ascii;\r
127 UINTN LoopVariable;\r
128 UINTN ColumnLoop;\r
129 CHAR16 *TempLine;\r
130 CHAR16 *ColumnPointer;\r
131 SHELL_STATUS ShellStatus;\r
132 CHAR16 *TempSpot;\r
133 CHAR16 *SfoString;\r
134\r
135 ASSERT (FileName != NULL);\r
136 ASSERT (TableName != NULL);\r
137\r
138 ShellStatus = SHELL_SUCCESS;\r
139\r
140 Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ, 0);\r
141 if (EFI_ERROR (Status)) {\r
142 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel2HiiHandle, L"parse", FileName);\r
a405b86d 143 ShellStatus = SHELL_NOT_FOUND;\r
78d42190 144 } else if (!EFI_ERROR (FileHandleIsDirectory (FileHandle))) {\r
ba0014b9 145 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_FILE), gShellLevel2HiiHandle, L"parse", FileName);\r
78d42190 146 ShellStatus = SHELL_NOT_FOUND;\r
a405b86d 147 } else {\r
47d20b54
MK
148 for (LoopVariable = 0; LoopVariable < ShellCommandInstance && !ShellFileHandleEof (FileHandle);) {\r
149 TempLine = ShellFileHandleReturnLine (FileHandle, &Ascii);\r
421fbf99 150\r
47d20b54
MK
151 if ((TempLine == NULL) || ((*TempLine == CHAR_NULL) && StreamingUnicode)) {\r
152 break;\r
a405b86d 153 }\r
78d42190
CP
154\r
155 //\r
156 // Search for "ShellCommand," in the file to start the SFO table\r
157 // for a given ShellCommand. The UEFI Shell spec does not specify\r
158 // a space after the comma.\r
159 //\r
160 if (StrStr (TempLine, L"ShellCommand,") == TempLine) {\r
a405b86d 161 LoopVariable++;\r
162 }\r
47d20b54
MK
163\r
164 SHELL_FREE_NON_NULL (TempLine);\r
a405b86d 165 }\r
47d20b54 166\r
a405b86d 167 if (LoopVariable == ShellCommandInstance) {\r
168 LoopVariable = 0;\r
47d20b54 169 while (1) {\r
ba0014b9 170 TempLine = ShellFileHandleReturnLine (FileHandle, &Ascii);\r
47d20b54
MK
171 if ( (TempLine == NULL)\r
172 || (*TempLine == CHAR_NULL)\r
173 || (StrStr (TempLine, L"ShellCommand,") == TempLine))\r
174 {\r
175 SHELL_FREE_NON_NULL (TempLine);\r
a405b86d 176 break;\r
177 }\r
47d20b54 178\r
78d42190 179 if (StrStr (TempLine, TableName) == TempLine) {\r
a405b86d 180 LoopVariable++;\r
47d20b54
MK
181 if ( (LoopVariable == TableNameInstance)\r
182 || (TableNameInstance == (UINTN)-1))\r
183 {\r
78d42190 184 for (ColumnLoop = 1, ColumnPointer = TempLine; ColumnLoop < ColumnIndex && ColumnPointer != NULL && *ColumnPointer != CHAR_NULL; ColumnLoop++) {\r
76c94bb2 185 ColumnPointer = StrStr (ColumnPointer, L",\"");\r
47d20b54 186 if ((ColumnPointer != NULL) && (*ColumnPointer != CHAR_NULL)) {\r
8fcf74a8 187 ColumnPointer++;\r
188 }\r
78d42190 189 }\r
47d20b54 190\r
78d42190
CP
191 if (ColumnLoop == ColumnIndex) {\r
192 if (ColumnPointer == NULL) {\r
47d20b54 193 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellLevel2HiiHandle, L"parse", L"Column Index");\r
78d42190
CP
194 ShellStatus = SHELL_INVALID_PARAMETER;\r
195 } else {\r
76c94bb2 196 TempSpot = StrStr (ColumnPointer, L",\"");\r
78d42190
CP
197 if (TempSpot != NULL) {\r
198 *TempSpot = CHAR_NULL;\r
199 }\r
47d20b54
MK
200\r
201 while (ColumnPointer != NULL && *ColumnPointer != CHAR_NULL && ColumnPointer[0] == L' ') {\r
78d42190
CP
202 ColumnPointer++;\r
203 }\r
47d20b54
MK
204\r
205 if ((ColumnPointer != NULL) && (*ColumnPointer != CHAR_NULL) && (ColumnPointer[0] == L'\"')) {\r
78d42190
CP
206 ColumnPointer++;\r
207 }\r
47d20b54
MK
208\r
209 if ((ColumnPointer != NULL) && (*ColumnPointer != CHAR_NULL) && (ColumnPointer[StrLen (ColumnPointer) - 1] == L'\"')) {\r
78d42190
CP
210 ColumnPointer[StrLen (ColumnPointer) - 1] = CHAR_NULL;\r
211 }\r
47d20b54 212\r
307f2ce4
TS
213 SfoString = HandleStringWithEscapeCharForParse (ColumnPointer);\r
214 if (SfoString != NULL) {\r
215 ShellPrintEx (-1, -1, L"%s\r\n", SfoString);\r
216 SHELL_FREE_NON_NULL (SfoString);\r
217 }\r
78d42190 218 }\r
8fcf74a8 219 }\r
a405b86d 220 }\r
221 }\r
47d20b54
MK
222\r
223 SHELL_FREE_NON_NULL (TempLine);\r
a405b86d 224 }\r
225 }\r
226 }\r
47d20b54 227\r
a405b86d 228 return (ShellStatus);\r
229}\r
230\r
47d20b54
MK
231STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
232 { L"-i", TypeValue },\r
233 { L"-s", TypeValue },\r
234 { NULL, TypeMax }\r
235};\r
a405b86d 236\r
237/**\r
238 Function for 'parse' command.\r
239\r
240 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
241 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
242**/\r
243SHELL_STATUS\r
244EFIAPI\r
245ShellCommandRunParse (\r
246 IN EFI_HANDLE ImageHandle,\r
247 IN EFI_SYSTEM_TABLE *SystemTable\r
248 )\r
249{\r
47d20b54
MK
250 EFI_STATUS Status;\r
251 LIST_ENTRY *Package;\r
252 CHAR16 *ProblemParam;\r
253 CONST CHAR16 *FileName;\r
254 CONST CHAR16 *TableName;\r
255 CONST CHAR16 *ColumnString;\r
256 SHELL_STATUS ShellStatus;\r
257 UINTN ShellCommandInstance;\r
258 UINTN TableNameInstance;\r
259 BOOLEAN StreamingUnicode;\r
a405b86d 260\r
421fbf99
TS
261 ShellStatus = SHELL_SUCCESS;\r
262 ProblemParam = NULL;\r
263 StreamingUnicode = FALSE;\r
a405b86d 264\r
265 //\r
266 // initialize the shell lib (we must be in non-auto-init...)\r
267 //\r
47d20b54
MK
268 Status = ShellInitialize ();\r
269 ASSERT_EFI_ERROR (Status);\r
a405b86d 270\r
271 //\r
272 // parse the command line\r
273 //\r
421fbf99 274 Status = ShellCommandLineParseEx (ParamList, &Package, &ProblemParam, TRUE, FALSE);\r
47d20b54
MK
275 if (EFI_ERROR (Status)) {\r
276 if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {\r
277 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"parse", ProblemParam);\r
278 FreePool (ProblemParam);\r
a405b86d 279 ShellStatus = SHELL_INVALID_PARAMETER;\r
280 } else {\r
47d20b54 281 ASSERT (FALSE);\r
a405b86d 282 }\r
283 } else {\r
421fbf99 284 StreamingUnicode = IsStdInDataAvailable ();\r
47d20b54
MK
285 if ((!StreamingUnicode && (ShellCommandLineGetCount (Package) < 4)) ||\r
286 (ShellCommandLineGetCount (Package) < 3))\r
287 {\r
288 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"parse");\r
a405b86d 289 ShellStatus = SHELL_INVALID_PARAMETER;\r
47d20b54
MK
290 } else if ((StreamingUnicode && (ShellCommandLineGetCount (Package) > 3)) ||\r
291 (ShellCommandLineGetCount (Package) > 4))\r
292 {\r
293 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"parse");\r
a405b86d 294 ShellStatus = SHELL_INVALID_PARAMETER;\r
295 } else {\r
421fbf99 296 if (StreamingUnicode) {\r
47d20b54
MK
297 FileName = L">i";\r
298 TableName = ShellCommandLineGetRawValue (Package, 1);\r
299 ColumnString = ShellCommandLineGetRawValue (Package, 2);\r
421fbf99 300 } else {\r
47d20b54
MK
301 FileName = ShellCommandLineGetRawValue (Package, 1);\r
302 TableName = ShellCommandLineGetRawValue (Package, 2);\r
303 ColumnString = ShellCommandLineGetRawValue (Package, 3);\r
421fbf99 304 }\r
47d20b54
MK
305\r
306 if (ShellCommandLineGetValue (Package, L"-i") == NULL) {\r
a405b86d 307 TableNameInstance = (UINTN)-1;\r
308 } else {\r
47d20b54 309 TableNameInstance = ShellStrToUintn (ShellCommandLineGetValue (Package, L"-i"));\r
a405b86d 310 }\r
47d20b54
MK
311\r
312 if (ShellCommandLineGetValue (Package, L"-s") == NULL) {\r
a405b86d 313 ShellCommandInstance = 1;\r
314 } else {\r
47d20b54 315 ShellCommandInstance = ShellStrToUintn (ShellCommandLineGetValue (Package, L"-s"));\r
a405b86d 316 }\r
317\r
47d20b54 318 ShellStatus = PerformParsing (FileName, TableName, ShellStrToUintn (ColumnString), TableNameInstance, ShellCommandInstance, StreamingUnicode);\r
a405b86d 319 }\r
320 }\r
321\r
322 //\r
323 // free the command line package\r
324 //\r
325 ShellCommandLineFreeVarList (Package);\r
326\r
327 return (ShellStatus);\r
328}\r