2 Main file for Help shell level 3 function.
4 Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved. <BR>
5 Copyright (c) 2014, ARM Limited. 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 "UefiShellLevel3CommandsLib.h"
18 #include <Library/ShellLib.h>
19 #include <Library/HandleParsingLib.h>
21 #include <Protocol/EfiShellDynamicCommand.h>
24 Attempt to print help from a dynamically added command.
26 @param[in] CommandToGetHelpOn The unicode name of the command that help is
28 @param[in] SectionToGetHelpOn Pointer to the section specifier(s).
29 @param[in] PrintCommandText Print the command followed by the help content
32 @retval EFI_SUCCESS The help was displayed
33 @retval EFI_NOT_FOUND The command name could not be found
34 @retval EFI_DEVICE_ERROR The help data format was incorrect.
38 PrintDynamicCommandHelp(
39 IN CHAR16
*CommandToGetHelpOn
,
40 IN CHAR16
*SectionToGetHelpOn
,
41 IN BOOLEAN PrintCommandText
46 EFI_HANDLE
*CommandHandleList
;
47 EFI_HANDLE
*NextCommand
;
48 EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL
*DynamicCommand
;
50 Status
= EFI_NOT_FOUND
;
52 CommandHandleList
= NULL
;
54 CommandHandleList
= GetHandleListByProtocol(&gEfiShellDynamicCommandProtocolGuid
);
56 if (CommandHandleList
== NULL
) {
58 // not found or out of resources
63 for (NextCommand
= CommandHandleList
; *NextCommand
!= NULL
; NextCommand
++) {
64 Status
= gBS
->HandleProtocol(
66 &gEfiShellDynamicCommandProtocolGuid
,
67 (VOID
**)&DynamicCommand
70 if (EFI_ERROR(Status
)) {
75 // Check execution break flag when printing multiple command help information.
77 if (ShellGetExecutionBreakFlag ()) {
81 if ((gUnicodeCollation
->MetaiMatch (gUnicodeCollation
, (CHAR16
*)DynamicCommand
->CommandName
, CommandToGetHelpOn
)) ||
82 (gEfiShellProtocol
->GetAlias (CommandToGetHelpOn
, NULL
) != NULL
&& (gUnicodeCollation
->MetaiMatch (gUnicodeCollation
, (CHAR16
*)DynamicCommand
->CommandName
, (CHAR16
*)(gEfiShellProtocol
->GetAlias(CommandToGetHelpOn
, NULL
)))))) {
83 // Print as Shell Help if in ManPage format.
84 Status
= ShellPrintHelp (DynamicCommand
->CommandName
, SectionToGetHelpOn
,
86 if (Status
== EFI_DEVICE_ERROR
) {
87 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_HELP_INV
),
88 gShellLevel3HiiHandle
, DynamicCommand
->CommandName
);
89 } else if (EFI_ERROR(Status
)) {
90 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_HELP_NF
),
91 gShellLevel3HiiHandle
, DynamicCommand
->CommandName
);
98 return (Found
? EFI_SUCCESS
: Status
);
102 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
103 {L
"-usage", TypeFlag
},
104 {L
"-section", TypeMaxValue
},
105 {L
"-verbose", TypeFlag
},
111 Function for 'help' command.
113 @param[in] ImageHandle Handle to the Image (NULL if Internal).
114 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
118 ShellCommandRunHelp (
119 IN EFI_HANDLE ImageHandle
,
120 IN EFI_SYSTEM_TABLE
*SystemTable
125 CHAR16
*ProblemParam
;
126 SHELL_STATUS ShellStatus
;
127 CONST COMMAND_LIST
*CommandList
;
128 CONST COMMAND_LIST
*Node
;
129 CHAR16
*CommandToGetHelpOn
;
130 CHAR16
*SectionToGetHelpOn
;
133 BOOLEAN PrintCommandText
;
135 PrintCommandText
= TRUE
;
137 ShellStatus
= SHELL_SUCCESS
;
138 CommandToGetHelpOn
= NULL
;
139 SectionToGetHelpOn
= NULL
;
143 // initialize the shell lib (we must be in non-auto-init...)
145 Status
= ShellInitialize();
146 ASSERT_EFI_ERROR(Status
);
148 Status
= CommandInit();
149 ASSERT_EFI_ERROR(Status
);
152 // parse the command line
154 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
155 if (EFI_ERROR(Status
)) {
156 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
157 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellLevel3HiiHandle
, ProblemParam
);
158 FreePool(ProblemParam
);
159 ShellStatus
= SHELL_INVALID_PARAMETER
;
165 // Check for conflicting parameters.
167 if (ShellCommandLineGetFlag(Package
, L
"-usage")
168 &&ShellCommandLineGetFlag(Package
, L
"-section")
169 &&(ShellCommandLineGetFlag(Package
, L
"-verbose") || ShellCommandLineGetFlag(Package
, L
"-v"))
171 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_CON
), gShellLevel3HiiHandle
);
172 ShellStatus
= SHELL_INVALID_PARAMETER
;
173 } else if (ShellCommandLineGetRawValue(Package
, 2) != NULL
) {
174 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel3HiiHandle
);
175 ShellStatus
= SHELL_INVALID_PARAMETER
;
178 // Get the command name we are getting help on
180 ASSERT(CommandToGetHelpOn
== NULL
);
181 StrnCatGrow(&CommandToGetHelpOn
, NULL
, ShellCommandLineGetRawValue(Package
, 1), 0);
182 if (CommandToGetHelpOn
== NULL
&& ShellCommandLineGetFlag(Package
, L
"-?")) {
184 // If we dont have a command and we got a simple -?
185 // we are looking for help on help command.
187 StrnCatGrow(&CommandToGetHelpOn
, NULL
, L
"help", 0);
190 if (CommandToGetHelpOn
== NULL
) {
191 StrnCatGrow(&CommandToGetHelpOn
, NULL
, L
"*", 0);
192 ASSERT(SectionToGetHelpOn
== NULL
);
193 StrnCatGrow(&SectionToGetHelpOn
, NULL
, L
"NAME", 0);
195 PrintCommandText
= FALSE
;
196 ASSERT(SectionToGetHelpOn
== NULL
);
198 // Get the section name for the given command name
200 if (ShellCommandLineGetFlag(Package
, L
"-section")) {
201 StrnCatGrow(&SectionToGetHelpOn
, NULL
, ShellCommandLineGetValue(Package
, L
"-section"), 0);
202 } else if (ShellCommandLineGetFlag(Package
, L
"-usage")) {
203 StrnCatGrow(&SectionToGetHelpOn
, NULL
, L
"NAME,SYNOPSIS", 0);
204 } else if (ShellCommandLineGetFlag(Package
, L
"-verbose") || ShellCommandLineGetFlag(Package
, L
"-v")) {
207 // The output of help <command> will display NAME, SYNOPSIS, OPTIONS, DESCRIPTION, and EXAMPLES sections.
209 StrnCatGrow (&SectionToGetHelpOn
, NULL
, L
"NAME,SYNOPSIS,OPTIONS,DESCRIPTION,EXAMPLES", 0);
213 if (gUnicodeCollation
->StriColl(gUnicodeCollation
, CommandToGetHelpOn
, L
"special") == 0) {
215 // we need info on the special characters
217 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_HELP_SC_HEADER
), gShellLevel3HiiHandle
);
218 HiiString
= HiiGetString(gShellLevel3HiiHandle
, STRING_TOKEN(STR_HELP_SC_DATA
), NULL
);
219 ShellPrintEx(-1, -1, L
"%s", HiiString
);
223 CommandList
= ShellCommandGetCommandList(TRUE
);
224 ASSERT(CommandList
!= NULL
);
225 for ( Node
= (COMMAND_LIST
*)GetFirstNode(&CommandList
->Link
)
226 ; CommandList
!= NULL
&& !IsListEmpty(&CommandList
->Link
) && !IsNull(&CommandList
->Link
, &Node
->Link
)
227 ; Node
= (COMMAND_LIST
*)GetNextNode(&CommandList
->Link
, &Node
->Link
)
230 // Checking execution break flag when print multiple command help information.
232 if (ShellGetExecutionBreakFlag ()) {
235 if ((gUnicodeCollation
->MetaiMatch(gUnicodeCollation
, Node
->CommandString
, CommandToGetHelpOn
)) ||
236 (gEfiShellProtocol
->GetAlias(CommandToGetHelpOn
, NULL
) != NULL
&& (gUnicodeCollation
->MetaiMatch(gUnicodeCollation
, Node
->CommandString
, (CHAR16
*)(gEfiShellProtocol
->GetAlias(CommandToGetHelpOn
, NULL
)))))) {
238 // We have a command to look for help on.
240 Status
= ShellPrintHelp(Node
->CommandString
, SectionToGetHelpOn
, PrintCommandText
);
241 if (Status
== EFI_DEVICE_ERROR
) {
242 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_HELP_INV
), gShellLevel3HiiHandle
, Node
->CommandString
);
243 } else if (EFI_ERROR(Status
)) {
244 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_HELP_NF
), gShellLevel3HiiHandle
, Node
->CommandString
);
252 // now try to match against the dynamic command list and print help
254 Status
= PrintDynamicCommandHelp (CommandToGetHelpOn
, SectionToGetHelpOn
,
256 if (!EFI_ERROR(Status
)) {
261 // Search the .man file for Shell applications (Shell external commands).
264 Status
= ShellPrintHelp(CommandToGetHelpOn
, SectionToGetHelpOn
, FALSE
);
265 if (Status
== EFI_DEVICE_ERROR
) {
266 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_HELP_INV
), gShellLevel3HiiHandle
, CommandToGetHelpOn
);
267 } else if (EFI_ERROR(Status
)) {
268 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_HELP_NF
), gShellLevel3HiiHandle
, CommandToGetHelpOn
);
276 ShellStatus
= SHELL_NOT_FOUND
;
280 // free the command line package
282 ShellCommandLineFreeVarList (Package
);
286 if (CommandToGetHelpOn
!= NULL
&& StrCmp(CommandToGetHelpOn
, L
"*") == 0){
288 // If '*' then the command entered was 'Help' without qualifiers, This footer
289 // provides additional info on help switches
291 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_HELP_FOOTER
), gShellLevel3HiiHandle
);
293 if (CommandToGetHelpOn
!= NULL
) {
294 FreePool(CommandToGetHelpOn
);
296 if (SectionToGetHelpOn
!= NULL
) {
297 FreePool(SectionToGetHelpOn
);
300 return (ShellStatus
);