2 Main file for Help shell level 3 function.
4 Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved. <BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "UefiShellLevel3CommandsLib.h"
17 #include <Library/ShellLib.h>
18 #include <Library/HandleParsingLib.h>
20 #include <Protocol/EfiShellDynamicCommand.h>
23 Attempt to print help from a dynamically added command.
25 @param[in] CommandToGetHelpOn The unicode name of the command that help is requested on.
27 @retval EFI_SUCCESS The help was displayed
28 @retval FI_NOT_FOUND The command name could not be found
33 PrintDynamicCommandHelp(
34 IN CHAR16
*CommandToGetHelpOn
38 BOOLEAN Found
= FALSE
;
39 EFI_HANDLE
*CommandHandleList
= NULL
;
40 EFI_HANDLE
*NextCommand
;
41 EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL
*DynamicCommand
;
42 CHAR16
*OutText
= NULL
;
44 CommandHandleList
= GetHandleListByProtocol(&gEfiShellDynamicCommandProtocolGuid
);
46 if (CommandHandleList
== NULL
) {
48 // not found or out of resources
53 for (NextCommand
= CommandHandleList
; *NextCommand
!= NULL
; NextCommand
++) {
54 Status
= gBS
->HandleProtocol(
56 &gEfiShellDynamicCommandProtocolGuid
,
57 (VOID
**)&DynamicCommand
60 if (EFI_ERROR(Status
)) {
64 if ((gUnicodeCollation
->MetaiMatch(gUnicodeCollation
, (CHAR16
*)DynamicCommand
->CommandName
, CommandToGetHelpOn
)) ||
65 (gEfiShellProtocol
->GetAlias(CommandToGetHelpOn
, NULL
) != NULL
&& (gUnicodeCollation
->MetaiMatch(gUnicodeCollation
, (CHAR16
*)DynamicCommand
->CommandName
, (CHAR16
*)(gEfiShellProtocol
->GetAlias(CommandToGetHelpOn
, NULL
)))))) {
67 // TODO: how to get proper language?
69 OutText
= DynamicCommand
->GetHelp(DynamicCommand
, "en");
71 if (OutText
== NULL
) {
76 // Trim extra characters from the end the the string before printing
78 while (StrLen(OutText
) > 0
79 && (OutText
[StrLen(OutText
) - 1] == L
'\r' || OutText
[StrLen(OutText
) - 1] == L
'\n' || OutText
[StrLen(OutText
) - 1] == L
' ')) {
80 OutText
[StrLen(OutText
) - 1] = CHAR_NULL
;
84 // Make sure we have something to print still.
86 if (StrLen(OutText
) == 0) {
95 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN(STR_HELP_COMMAND
), gShellLevel3HiiHandle
, DynamicCommand
->CommandName
, OutText
);
104 FreePool(CommandHandleList
);
106 return Found
? EFI_SUCCESS
: EFI_NOT_FOUND
;
109 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
110 {L
"-usage", TypeFlag
},
111 {L
"-section", TypeMaxValue
},
112 {L
"-verbose", TypeFlag
},
118 Function for 'help' command.
120 @param[in] ImageHandle Handle to the Image (NULL if Internal).
121 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
125 ShellCommandRunHelp (
126 IN EFI_HANDLE ImageHandle
,
127 IN EFI_SYSTEM_TABLE
*SystemTable
132 CHAR16
*ProblemParam
;
133 SHELL_STATUS ShellStatus
;
134 CONST COMMAND_LIST
*CommandList
;
135 CONST COMMAND_LIST
*Node
;
136 CHAR16
*CommandToGetHelpOn
;
137 CHAR16
*SectionToGetHelpOn
;
140 BOOLEAN PrintCommandText
;
142 PrintCommandText
= TRUE
;
144 ShellStatus
= SHELL_SUCCESS
;
145 CommandToGetHelpOn
= NULL
;
146 SectionToGetHelpOn
= NULL
;
150 // initialize the shell lib (we must be in non-auto-init...)
152 Status
= ShellInitialize();
153 ASSERT_EFI_ERROR(Status
);
155 Status
= CommandInit();
156 ASSERT_EFI_ERROR(Status
);
159 // parse the command line
161 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
162 if (EFI_ERROR(Status
)) {
163 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
164 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellLevel3HiiHandle
, ProblemParam
);
165 FreePool(ProblemParam
);
166 ShellStatus
= SHELL_INVALID_PARAMETER
;
172 // Check for conflicting parameters.
174 if (ShellCommandLineGetFlag(Package
, L
"-usage")
175 &&ShellCommandLineGetFlag(Package
, L
"-section")
176 &&(ShellCommandLineGetFlag(Package
, L
"-verbose") || ShellCommandLineGetFlag(Package
, L
"-v"))
178 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_CON
), gShellLevel3HiiHandle
);
179 ShellStatus
= SHELL_INVALID_PARAMETER
;
180 } else if (ShellCommandLineGetRawValue(Package
, 2) != NULL
) {
181 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel3HiiHandle
);
182 ShellStatus
= SHELL_INVALID_PARAMETER
;
185 // Get the command name we are getting help on
187 ASSERT(CommandToGetHelpOn
== NULL
);
188 StrnCatGrow(&CommandToGetHelpOn
, NULL
, ShellCommandLineGetRawValue(Package
, 1), 0);
189 if (CommandToGetHelpOn
== NULL
&& ShellCommandLineGetFlag(Package
, L
"-?")) {
191 // If we dont have a command and we got a simple -?
192 // we are looking for help on help command.
194 StrnCatGrow(&CommandToGetHelpOn
, NULL
, L
"help", 0);
197 if (CommandToGetHelpOn
== NULL
) {
198 StrnCatGrow(&CommandToGetHelpOn
, NULL
, L
"*", 0);
199 ASSERT(SectionToGetHelpOn
== NULL
);
200 StrnCatGrow(&SectionToGetHelpOn
, NULL
, L
"NAME", 0);
202 PrintCommandText
= FALSE
;
203 ASSERT(SectionToGetHelpOn
== NULL
);
205 // Get the section name for the given command name
207 if (ShellCommandLineGetFlag(Package
, L
"-section")) {
208 StrnCatGrow(&SectionToGetHelpOn
, NULL
, ShellCommandLineGetValue(Package
, L
"-section"), 0);
209 } else if (ShellCommandLineGetFlag(Package
, L
"-usage")) {
210 StrnCatGrow(&SectionToGetHelpOn
, NULL
, L
"NAME,SYNOPSIS", 0);
211 } else if (ShellCommandLineGetFlag(Package
, L
"-verbose") || ShellCommandLineGetFlag(Package
, L
"-v")) {
214 // The output of help <command> will display NAME, SYNOPSIS, OPTIONS, DESCRIPTION, and EXAMPLES sections.
216 StrnCatGrow (&SectionToGetHelpOn
, NULL
, L
"NAME,SYNOPSIS,OPTIONS,DESCRIPTION,EXAMPLES", 0);
220 if (gUnicodeCollation
->StriColl(gUnicodeCollation
, CommandToGetHelpOn
, L
"special") == 0) {
222 // we need info on the special characters
224 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_HELP_SC_HEADER
), gShellLevel3HiiHandle
);
225 HiiString
= HiiGetString(gShellLevel3HiiHandle
, STRING_TOKEN(STR_HELP_SC_DATA
), NULL
);
226 ShellPrintEx(-1, -1, L
"%s", HiiString
);
230 CommandList
= ShellCommandGetCommandList(TRUE
);
231 ASSERT(CommandList
!= NULL
);
232 for ( Node
= (COMMAND_LIST
*)GetFirstNode(&CommandList
->Link
)
233 ; CommandList
!= NULL
&& !IsListEmpty(&CommandList
->Link
) && !IsNull(&CommandList
->Link
, &Node
->Link
)
234 ; Node
= (COMMAND_LIST
*)GetNextNode(&CommandList
->Link
, &Node
->Link
)
237 // Checking execution break flag when print multiple command help information.
239 if (ShellGetExecutionBreakFlag ()) {
242 if ((gUnicodeCollation
->MetaiMatch(gUnicodeCollation
, Node
->CommandString
, CommandToGetHelpOn
)) ||
243 (gEfiShellProtocol
->GetAlias(CommandToGetHelpOn
, NULL
) != NULL
&& (gUnicodeCollation
->MetaiMatch(gUnicodeCollation
, Node
->CommandString
, (CHAR16
*)(gEfiShellProtocol
->GetAlias(CommandToGetHelpOn
, NULL
)))))) {
245 // We have a command to look for help on.
247 Status
= ShellPrintHelp(Node
->CommandString
, SectionToGetHelpOn
, PrintCommandText
);
248 if (Status
== EFI_DEVICE_ERROR
) {
249 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_HELP_INV
), gShellLevel3HiiHandle
, Node
->CommandString
);
250 } else if (EFI_ERROR(Status
)) {
251 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_HELP_NF
), gShellLevel3HiiHandle
, Node
->CommandString
);
258 // Search the .man file for Shell applications (Shell external commands).
261 Status
= ShellPrintHelp(CommandToGetHelpOn
, SectionToGetHelpOn
, FALSE
);
262 if (Status
== EFI_DEVICE_ERROR
) {
263 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_HELP_INV
), gShellLevel3HiiHandle
, CommandToGetHelpOn
);
264 } else if (EFI_ERROR(Status
)) {
265 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_HELP_NF
), gShellLevel3HiiHandle
, CommandToGetHelpOn
);
272 // now try to match against the dynamic command list and print help
274 Status
= PrintDynamicCommandHelp(CommandToGetHelpOn
);
275 if (Status
== EFI_SUCCESS
) {
282 ShellStatus
= SHELL_NOT_FOUND
;
286 // free the command line package
288 ShellCommandLineFreeVarList (Package
);
292 if (CommandToGetHelpOn
!= NULL
&& StrCmp(CommandToGetHelpOn
, L
"*") == 0){
294 // If '*' then the command entered was 'Help' without qualifiers, This footer
295 // provides additional info on help switches
297 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_HELP_FOOTER
), gShellLevel3HiiHandle
);
299 if (CommandToGetHelpOn
!= NULL
) {
300 FreePool(CommandToGetHelpOn
);
302 if (SectionToGetHelpOn
!= NULL
) {
303 FreePool(SectionToGetHelpOn
);
306 return (ShellStatus
);