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