TianoCore EDK2 master
Loading...
Searching...
No Matches
Help.c
Go to the documentation of this file.
1
13
14#include <Library/ShellLib.h>
16
18
35 IN OUT CHAR16 **DestList,
36 IN OUT UINTN *DestSize,
37 IN CONST CHAR16 *Item
38 )
39{
40 CHAR16 *NewList;
41 INTN LexicalMatchValue;
42 CHAR16 *LexicalSpot;
43 UINTN SizeOfAddedNameInBytes;
44
45 //
46 // If there are none, then just return with success
47 //
48 if ((Item == NULL) || (*Item == CHAR_NULL) || (StrLen (Item) == 0)) {
49 return (EFI_SUCCESS);
50 }
51
52 NewList = *DestList;
53
54 SizeOfAddedNameInBytes = StrSize (Item);
55 NewList = ReallocatePool (*DestSize, (*DestSize) + SizeOfAddedNameInBytes, NewList);
56 (*DestSize) = (*DestSize) + SizeOfAddedNameInBytes;
57
58 //
59 // Find the correct spot in the list
60 //
61 for (LexicalSpot = NewList
62 ; LexicalSpot != NULL && LexicalSpot < NewList + (*DestSize)
63 ; LexicalSpot += StrLen (LexicalSpot) + 1
64 )
65 {
66 //
67 // Get Lexical Comparison Value between PrevCommand and Command list entry
68 //
69 LexicalMatchValue = gUnicodeCollation->StriColl (
70 gUnicodeCollation,
71 (CHAR16 *)LexicalSpot,
72 (CHAR16 *)Item
73 );
74 //
75 // The new item goes before this one.
76 //
77 if ((LexicalMatchValue > 0) || (StrLen (LexicalSpot) == 0)) {
78 if (StrLen (LexicalSpot) != 0) {
79 //
80 // Move this and all other items out of the way
81 //
82 CopyMem (
83 LexicalSpot + (SizeOfAddedNameInBytes/sizeof (CHAR16)),
84 LexicalSpot,
85 (*DestSize) - SizeOfAddedNameInBytes - ((LexicalSpot - NewList) * sizeof (CHAR16))
86 );
87 }
88
89 //
90 // Stick this one in place
91 //
92 StrCpyS (LexicalSpot, SizeOfAddedNameInBytes/sizeof (CHAR16), Item);
93 break;
94 }
95 }
96
97 *DestList = NewList;
98 return (EFI_SUCCESS);
99}
100
114 IN OUT CHAR16 **DestList,
115 IN OUT UINTN *DestSize,
116 IN CONST COMMAND_LIST *SourceList
117 )
118{
119 CONST COMMAND_LIST *Node;
120
121 for ( Node = (COMMAND_LIST *)GetFirstNode (&SourceList->Link)
122 ; SourceList != NULL && !IsListEmpty (&SourceList->Link) && !IsNull (&SourceList->Link, &Node->Link)
123 ; Node = (COMMAND_LIST *)GetNextNode (&SourceList->Link, &Node->Link)
124 )
125 {
126 LexicalInsertIntoList (DestList, DestSize, Node->CommandString);
127 }
128
129 return (EFI_SUCCESS);
130}
131
143STATIC
146 IN OUT CHAR16 **DestList,
147 IN OUT UINTN *DestSize
148 )
149{
150 EFI_HANDLE *CommandHandleList;
151 CONST EFI_HANDLE *NextCommand;
153 EFI_STATUS Status;
154
155 CommandHandleList = GetHandleListByProtocol (&gEfiShellDynamicCommandProtocolGuid);
156
157 //
158 // If there are none, then just return with success
159 //
160 if (CommandHandleList == NULL) {
161 return (EFI_SUCCESS);
162 }
163
164 Status = EFI_SUCCESS;
165
166 //
167 // Append those to the list.
168 //
169 for (NextCommand = CommandHandleList; *NextCommand != NULL && !EFI_ERROR (Status); NextCommand++) {
170 Status = gBS->HandleProtocol (
171 *NextCommand,
172 &gEfiShellDynamicCommandProtocolGuid,
173 (VOID **)&DynamicCommand
174 );
175
176 if (EFI_ERROR (Status)) {
177 continue;
178 }
179
180 Status = LexicalInsertIntoList (DestList, DestSize, DynamicCommand->CommandName);
181 }
182
183 SHELL_FREE_NON_NULL (CommandHandleList);
184 return (Status);
185}
186
202 IN CONST CHAR16 *CommandToGetHelpOn,
203 IN CONST CHAR16 *SectionToGetHelpOn,
204 IN BOOLEAN PrintCommandText
205 )
206{
207 EFI_STATUS Status;
208 BOOLEAN Found;
209 EFI_HANDLE *CommandHandleList;
210 EFI_HANDLE *NextCommand;
212
213 Status = EFI_NOT_FOUND;
214 Found = FALSE;
215 CommandHandleList = NULL;
216
217 CommandHandleList = GetHandleListByProtocol (&gEfiShellDynamicCommandProtocolGuid);
218
219 if (CommandHandleList == NULL) {
220 //
221 // not found or out of resources
222 //
223 return Status;
224 }
225
226 for (NextCommand = CommandHandleList; *NextCommand != NULL; NextCommand++) {
227 Status = gBS->HandleProtocol (
228 *NextCommand,
229 &gEfiShellDynamicCommandProtocolGuid,
230 (VOID **)&DynamicCommand
231 );
232
233 if (EFI_ERROR (Status)) {
234 continue;
235 }
236
237 //
238 // Check execution break flag when printing multiple command help information.
239 //
241 break;
242 }
243
244 if ((gUnicodeCollation->MetaiMatch (gUnicodeCollation, (CHAR16 *)DynamicCommand->CommandName, (CHAR16 *)CommandToGetHelpOn)) ||
245 ((gEfiShellProtocol->GetAlias (CommandToGetHelpOn, NULL) != NULL) && (gUnicodeCollation->MetaiMatch (gUnicodeCollation, (CHAR16 *)DynamicCommand->CommandName, (CHAR16 *)(gEfiShellProtocol->GetAlias (CommandToGetHelpOn, NULL))))))
246 {
247 // Print as Shell Help if in ManPage format.
248 Status = ShellPrintHelp (
249 DynamicCommand->CommandName,
250 SectionToGetHelpOn,
251 PrintCommandText
252 );
253 if (Status == EFI_DEVICE_ERROR) {
255 -1,
256 -1,
257 NULL,
258 STRING_TOKEN (STR_HELP_INV),
259 gShellLevel3HiiHandle,
260 DynamicCommand->CommandName
261 );
262 } else if (EFI_ERROR (Status)) {
264 -1,
265 -1,
266 NULL,
267 STRING_TOKEN (STR_HELP_NF),
268 gShellLevel3HiiHandle,
269 DynamicCommand->CommandName
270 );
271 } else {
272 Found = TRUE;
273 }
274 }
275 }
276
277 SHELL_FREE_NON_NULL (CommandHandleList);
278
279 return (Found ? EFI_SUCCESS : Status);
280}
281
282STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
283 { L"-usage", TypeFlag },
284 { L"-section", TypeMaxValue },
285 { L"-verbose", TypeFlag },
286 { L"-v", TypeFlag },
287 { NULL, TypeMax }
288};
289
297EFIAPI
299 IN EFI_HANDLE ImageHandle,
300 IN EFI_SYSTEM_TABLE *SystemTable
301 )
302{
303 EFI_STATUS Status;
304 LIST_ENTRY *Package;
305 CHAR16 *ProblemParam;
306 SHELL_STATUS ShellStatus;
307 CHAR16 *SortedCommandList;
308 CONST CHAR16 *CurrentCommand;
309 CHAR16 *CommandToGetHelpOn;
310 CHAR16 *SectionToGetHelpOn;
311 BOOLEAN Found;
312 BOOLEAN PrintCommandText;
313 UINTN SortedCommandListSize;
314
315 PrintCommandText = TRUE;
316 ProblemParam = NULL;
317 ShellStatus = SHELL_SUCCESS;
318 CommandToGetHelpOn = NULL;
319 SectionToGetHelpOn = NULL;
320 SortedCommandList = NULL;
321 Found = FALSE;
322
323 //
324 // initialize the shell lib (we must be in non-auto-init...)
325 //
326 Status = ShellInitialize ();
327 ASSERT_EFI_ERROR (Status);
328
329 Status = CommandInit ();
330 ASSERT_EFI_ERROR (Status);
331
332 //
333 // parse the command line
334 //
335 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
336 if (EFI_ERROR (Status)) {
337 if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
338 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel3HiiHandle, L"help", ProblemParam);
339 FreePool (ProblemParam);
340 ShellStatus = SHELL_INVALID_PARAMETER;
341 } else {
342 ASSERT (FALSE);
343 }
344 } else {
345 //
346 // Check for conflicting parameters.
347 //
348 if ( ShellCommandLineGetFlag (Package, L"-usage")
349 && ShellCommandLineGetFlag (Package, L"-section")
350 && (ShellCommandLineGetFlag (Package, L"-verbose") || ShellCommandLineGetFlag (Package, L"-v"))
351 )
352 {
353 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CON), gShellLevel3HiiHandle, L"help");
354 ShellStatus = SHELL_INVALID_PARAMETER;
355 } else if (ShellCommandLineGetRawValue (Package, 2) != NULL) {
356 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel3HiiHandle, L"help");
357 ShellStatus = SHELL_INVALID_PARAMETER;
358 } else {
359 //
360 // Get the command name we are getting help on
361 //
362 ASSERT (CommandToGetHelpOn == NULL);
363 StrnCatGrow (&CommandToGetHelpOn, NULL, ShellCommandLineGetRawValue (Package, 1), 0);
364 if ((CommandToGetHelpOn == NULL) && ShellCommandLineGetFlag (Package, L"-?")) {
365 //
366 // If we dont have a command and we got a simple -?
367 // we are looking for help on help command.
368 //
369 StrnCatGrow (&CommandToGetHelpOn, NULL, L"help", 0);
370 }
371
372 if (CommandToGetHelpOn == NULL) {
373 StrnCatGrow (&CommandToGetHelpOn, NULL, L"*", 0);
374 ASSERT (SectionToGetHelpOn == NULL);
375 StrnCatGrow (&SectionToGetHelpOn, NULL, L"NAME", 0);
376 } else {
377 PrintCommandText = FALSE;
378 ASSERT (SectionToGetHelpOn == NULL);
379 //
380 // Get the section name for the given command name
381 //
382 if (ShellCommandLineGetFlag (Package, L"-section")) {
383 StrnCatGrow (&SectionToGetHelpOn, NULL, ShellCommandLineGetValue (Package, L"-section"), 0);
384 } else if (ShellCommandLineGetFlag (Package, L"-usage")) {
385 StrnCatGrow (&SectionToGetHelpOn, NULL, L"NAME,SYNOPSIS", 0);
386 } else if (ShellCommandLineGetFlag (Package, L"-verbose") || ShellCommandLineGetFlag (Package, L"-v")) {
387 } else {
388 //
389 // The output of help <command> will display NAME, SYNOPSIS, OPTIONS, DESCRIPTION, and EXAMPLES sections.
390 //
391 StrnCatGrow (&SectionToGetHelpOn, NULL, L"NAME,SYNOPSIS,OPTIONS,DESCRIPTION,EXAMPLES", 0);
392 }
393 }
394
395 if (gUnicodeCollation->StriColl (gUnicodeCollation, CommandToGetHelpOn, L"special") == 0) {
396 //
397 // we need info on the special characters
398 //
399 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HELP_SC_HEADER), gShellLevel3HiiHandle);
400 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HELP_SC_DATA), gShellLevel3HiiHandle);
401 Found = TRUE;
402 } else {
403 SortedCommandList = NULL;
404 SortedCommandListSize = 0;
405 CopyListOfCommandNames (&SortedCommandList, &SortedCommandListSize, ShellCommandGetCommandList (TRUE));
406 CopyListOfCommandNamesWithDynamic (&SortedCommandList, &SortedCommandListSize);
407
408 for (CurrentCommand = SortedCommandList
409 ; CurrentCommand != NULL && CurrentCommand < SortedCommandList + SortedCommandListSize/sizeof (CHAR16) && *CurrentCommand != CHAR_NULL
410 ; CurrentCommand += StrLen (CurrentCommand) + 1
411 )
412 {
413 //
414 // Checking execution break flag when print multiple command help information.
415 //
417 break;
418 }
419
420 if ((gUnicodeCollation->MetaiMatch (gUnicodeCollation, (CHAR16 *)CurrentCommand, CommandToGetHelpOn)) ||
421 ((gEfiShellProtocol->GetAlias (CommandToGetHelpOn, NULL) != NULL) && (gUnicodeCollation->MetaiMatch (gUnicodeCollation, (CHAR16 *)CurrentCommand, (CHAR16 *)(gEfiShellProtocol->GetAlias (CommandToGetHelpOn, NULL))))))
422 {
423 //
424 // We have a command to look for help on.
425 //
426 Status = ShellPrintHelp (CurrentCommand, SectionToGetHelpOn, PrintCommandText);
427 if (EFI_ERROR (Status)) {
428 //
429 // now try to match against the dynamic command list and print help
430 //
431 Status = PrintDynamicCommandHelp (CurrentCommand, SectionToGetHelpOn, PrintCommandText);
432 }
433
434 if (Status == EFI_DEVICE_ERROR) {
435 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HELP_INV), gShellLevel3HiiHandle, CurrentCommand);
436 } else if (EFI_ERROR (Status)) {
437 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HELP_NF), gShellLevel3HiiHandle, CurrentCommand);
438 } else {
439 Found = TRUE;
440 }
441 }
442 }
443
444 //
445 // Search the .man file for Shell applications (Shell external commands).
446 //
447 if (!Found) {
448 Status = ShellPrintHelp (CommandToGetHelpOn, SectionToGetHelpOn, FALSE);
449 if (Status == EFI_DEVICE_ERROR) {
450 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HELP_INV), gShellLevel3HiiHandle, CommandToGetHelpOn);
451 } else if (EFI_ERROR (Status)) {
452 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HELP_NF), gShellLevel3HiiHandle, CommandToGetHelpOn);
453 } else {
454 Found = TRUE;
455 }
456 }
457 }
458
459 if (!Found) {
460 ShellStatus = SHELL_NOT_FOUND;
461 }
462
463 //
464 // free the command line package
465 //
467 }
468 }
469
470 if ((CommandToGetHelpOn != NULL) && (StrCmp (CommandToGetHelpOn, L"*") == 0)) {
471 //
472 // If '*' then the command entered was 'Help' without qualifiers, This footer
473 // provides additional info on help switches
474 //
475 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HELP_FOOTER), gShellLevel3HiiHandle);
476 }
477
478 if (CommandToGetHelpOn != NULL) {
479 FreePool (CommandToGetHelpOn);
480 }
481
482 if (SectionToGetHelpOn != NULL) {
483 FreePool (SectionToGetHelpOn);
484 }
485
486 SHELL_FREE_NON_NULL (SortedCommandList);
487
488 return (ShellStatus);
489}
UINT64 UINTN
INT64 INTN
BOOLEAN EFIAPI IsNull(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:443
UINTN EFIAPI StrSize(IN CONST CHAR16 *String)
Definition: String.c:72
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
RETURN_STATUS EFIAPI StrCpyS(OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source)
Definition: SafeString.c:226
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:333
INTN EFIAPI StrCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString)
Definition: String.c:109
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
Definition: LinkedList.c:298
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
Definition: String.c:30
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ReallocatePool(IN UINTN OldSize, IN UINTN NewSize, IN VOID *OldBuffer OPTIONAL)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_HANDLE *EFIAPI GetHandleListByProtocol(IN CONST EFI_GUID *ProtocolGuid OPTIONAL)
SHELL_STATUS EFIAPI ShellCommandRunHelp(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: Help.c:298
EFI_STATUS CopyListOfCommandNames(IN OUT CHAR16 **DestList, IN OUT UINTN *DestSize, IN CONST COMMAND_LIST *SourceList)
Definition: Help.c:113
STATIC EFI_STATUS CopyListOfCommandNamesWithDynamic(IN OUT CHAR16 **DestList, IN OUT UINTN *DestSize)
Definition: Help.c:145
EFI_STATUS LexicalInsertIntoList(IN OUT CHAR16 **DestList, IN OUT UINTN *DestSize, IN CONST CHAR16 *Item)
Definition: Help.c:34
EFI_STATUS PrintDynamicCommandHelp(IN CONST CHAR16 *CommandToGetHelpOn, IN CONST CHAR16 *SectionToGetHelpOn, IN BOOLEAN PrintCommandText)
Definition: Help.c:201
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
SHELL_STATUS
Definition: Shell.h:21
@ SHELL_SUCCESS
Definition: Shell.h:25
@ SHELL_NOT_FOUND
Definition: Shell.h:101
@ SHELL_INVALID_PARAMETER
Definition: Shell.h:35
EFI_STATUS EFIAPI CommandInit(VOID)
CONST COMMAND_LIST *EFIAPI ShellCommandGetCommandList(IN CONST BOOLEAN Sort)
EFI_STATUS EFIAPI ShellPrintHelp(IN CONST CHAR16 *CommandToGetHelpOn, IN CONST CHAR16 *SectionToGetHelpOn, IN BOOLEAN PrintCommandText)
CONST CHAR16 *EFIAPI ShellCommandLineGetValue(IN CONST LIST_ENTRY *CheckPackage, IN CHAR16 *KeyString)
BOOLEAN EFIAPI ShellGetExecutionBreakFlag(VOID)
#define ShellCommandLineParse(CheckList, CheckPackage, ProblemParam, AutoPageBreak)
Make it easy to upgrade from older versions of the shell library.
Definition: ShellLib.h:755
EFI_STATUS EFIAPI ShellPrintHiiEx(IN INT32 Col OPTIONAL, IN INT32 Row OPTIONAL, IN CONST CHAR8 *Language OPTIONAL, IN CONST EFI_STRING_ID HiiFormatStringId, IN CONST EFI_HII_HANDLE HiiFormatHandle,...)
BOOLEAN EFIAPI ShellCommandLineGetFlag(IN CONST LIST_ENTRY *CONST CheckPackage, IN CONST CHAR16 *CONST KeyString)
@ TypeMaxValue
A flag followed by all the command line data before the next flag.
Definition: ShellLib.h:704
@ TypeFlag
A flag that is present or not present only (IE "-a").
Definition: ShellLib.h:699
CHAR16 *EFIAPI StrnCatGrow(IN OUT CHAR16 **Destination, IN OUT UINTN *CurrentSize, IN CONST CHAR16 *Source, IN UINTN Count)
VOID EFIAPI ShellCommandLineFreeVarList(IN LIST_ENTRY *CheckPackage)
EFI_STATUS EFIAPI ShellInitialize(VOID)
Definition: UefiShellLib.c:532
CONST CHAR16 *EFIAPI ShellCommandLineGetRawValue(IN CONST LIST_ENTRY *CONST CheckPackage, IN UINTN Position)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
#define STRING_TOKEN(t)
EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL protocol structure.