]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellLevel3CommandsLib/Help.c
ShellPkg: Remove 'STATIC' from function declarations to avoid source level debugging...
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel3CommandsLib / Help.c
1 /** @file
2 Main file for Help shell level 3 function.
3
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
9
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.
12
13 **/
14
15 #include "UefiShellLevel3CommandsLib.h"
16
17 #include <Library/ShellLib.h>
18 #include <Library/HandleParsingLib.h>
19
20 #include <Protocol/EfiShellDynamicCommand.h>
21
22 /**
23 Attempt to print help from a dynamically added command.
24
25 @param[in] CommandToGetHelpOn The unicode name of the command that help is requested on.
26
27 @retval EFI_SUCCESS The help was displayed
28 @retval FI_NOT_FOUND The command name could not be found
29 **/
30 EFI_STATUS
31 EFIAPI
32 PrintDynamicCommandHelp(
33 IN CHAR16 *CommandToGetHelpOn
34 )
35 {
36 EFI_STATUS Status;
37 BOOLEAN Found;
38 EFI_HANDLE *CommandHandleList;
39 EFI_HANDLE *NextCommand;
40 EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *DynamicCommand;
41 CHAR16 *OutText;
42
43 Found = FALSE;
44 CommandHandleList = NULL;
45 OutText = NULL;
46
47 CommandHandleList = GetHandleListByProtocol(&gEfiShellDynamicCommandProtocolGuid);
48
49 if (CommandHandleList == NULL) {
50 //
51 // not found or out of resources
52 //
53 return FALSE;
54 }
55
56 for (NextCommand = CommandHandleList; *NextCommand != NULL; NextCommand++) {
57 Status = gBS->HandleProtocol(
58 *NextCommand,
59 &gEfiShellDynamicCommandProtocolGuid,
60 (VOID **)&DynamicCommand
61 );
62
63 if (EFI_ERROR(Status)) {
64 continue;
65 }
66
67 if ((gUnicodeCollation->MetaiMatch(gUnicodeCollation, (CHAR16 *)DynamicCommand->CommandName, CommandToGetHelpOn)) ||
68 (gEfiShellProtocol->GetAlias(CommandToGetHelpOn, NULL) != NULL && (gUnicodeCollation->MetaiMatch(gUnicodeCollation, (CHAR16 *)DynamicCommand->CommandName, (CHAR16*)(gEfiShellProtocol->GetAlias(CommandToGetHelpOn, NULL)))))) {
69 //
70 // TODO: how to get proper language?
71 //
72 OutText = DynamicCommand->GetHelp(DynamicCommand, "en");
73
74 if (OutText == NULL) {
75 continue;
76 }
77
78 //
79 // Trim extra characters from the end the the string before printing
80 //
81 while (StrLen(OutText) > 0
82 && (OutText[StrLen(OutText) - 1] == L'\r' || OutText[StrLen(OutText) - 1] == L'\n' || OutText[StrLen(OutText) - 1] == L' ')) {
83 OutText[StrLen(OutText) - 1] = CHAR_NULL;
84 }
85
86 //
87 // Make sure we have something to print still.
88 //
89 if (StrLen(OutText) == 0) {
90 FreePool(OutText);
91 OutText = NULL;
92 continue;
93 }
94
95 //
96 // Print and move on.
97 //
98 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_HELP_COMMAND), gShellLevel3HiiHandle, DynamicCommand->CommandName, OutText);
99 FreePool(OutText);
100 OutText = NULL;
101 Found = TRUE;
102 break;
103 }
104
105 }
106
107 FreePool(CommandHandleList);
108
109 return Found ? EFI_SUCCESS : EFI_NOT_FOUND;
110 }
111
112 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
113 {L"-usage", TypeFlag},
114 {L"-section", TypeMaxValue},
115 {L"-verbose", TypeFlag},
116 {L"-v", TypeFlag},
117 {NULL, TypeMax}
118 };
119
120 /**
121 Function for 'help' command.
122
123 @param[in] ImageHandle Handle to the Image (NULL if Internal).
124 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
125 **/
126 SHELL_STATUS
127 EFIAPI
128 ShellCommandRunHelp (
129 IN EFI_HANDLE ImageHandle,
130 IN EFI_SYSTEM_TABLE *SystemTable
131 )
132 {
133 EFI_STATUS Status;
134 LIST_ENTRY *Package;
135 CHAR16 *ProblemParam;
136 SHELL_STATUS ShellStatus;
137 CONST COMMAND_LIST *CommandList;
138 CONST COMMAND_LIST *Node;
139 CHAR16 *CommandToGetHelpOn;
140 CHAR16 *SectionToGetHelpOn;
141 CHAR16 *HiiString;
142 BOOLEAN Found;
143 BOOLEAN PrintCommandText;
144
145 PrintCommandText = TRUE;
146 ProblemParam = NULL;
147 ShellStatus = SHELL_SUCCESS;
148 CommandToGetHelpOn = NULL;
149 SectionToGetHelpOn = NULL;
150 Found = FALSE;
151
152 //
153 // initialize the shell lib (we must be in non-auto-init...)
154 //
155 Status = ShellInitialize();
156 ASSERT_EFI_ERROR(Status);
157
158 Status = CommandInit();
159 ASSERT_EFI_ERROR(Status);
160
161 //
162 // parse the command line
163 //
164 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
165 if (EFI_ERROR(Status)) {
166 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
167 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel3HiiHandle, ProblemParam);
168 FreePool(ProblemParam);
169 ShellStatus = SHELL_INVALID_PARAMETER;
170 } else {
171 ASSERT(FALSE);
172 }
173 } else {
174 //
175 // Check for conflicting parameters.
176 //
177 if (ShellCommandLineGetFlag(Package, L"-usage")
178 &&ShellCommandLineGetFlag(Package, L"-section")
179 &&(ShellCommandLineGetFlag(Package, L"-verbose") || ShellCommandLineGetFlag(Package, L"-v"))
180 ){
181 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CON), gShellLevel3HiiHandle);
182 ShellStatus = SHELL_INVALID_PARAMETER;
183 } else if (ShellCommandLineGetRawValue(Package, 2) != NULL) {
184 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel3HiiHandle);
185 ShellStatus = SHELL_INVALID_PARAMETER;
186 } else {
187 //
188 // Get the command name we are getting help on
189 //
190 ASSERT(CommandToGetHelpOn == NULL);
191 StrnCatGrow(&CommandToGetHelpOn, NULL, ShellCommandLineGetRawValue(Package, 1), 0);
192 if (CommandToGetHelpOn == NULL && ShellCommandLineGetFlag(Package, L"-?")) {
193 //
194 // If we dont have a command and we got a simple -?
195 // we are looking for help on help command.
196 //
197 StrnCatGrow(&CommandToGetHelpOn, NULL, L"help", 0);
198 }
199
200 if (CommandToGetHelpOn == NULL) {
201 StrnCatGrow(&CommandToGetHelpOn, NULL, L"*", 0);
202 ASSERT(SectionToGetHelpOn == NULL);
203 StrnCatGrow(&SectionToGetHelpOn, NULL, L"NAME", 0);
204 } else {
205 PrintCommandText = FALSE;
206 ASSERT(SectionToGetHelpOn == NULL);
207 //
208 // Get the section name for the given command name
209 //
210 if (ShellCommandLineGetFlag(Package, L"-section")) {
211 StrnCatGrow(&SectionToGetHelpOn, NULL, ShellCommandLineGetValue(Package, L"-section"), 0);
212 } else if (ShellCommandLineGetFlag(Package, L"-usage")) {
213 StrnCatGrow(&SectionToGetHelpOn, NULL, L"NAME,SYNOPSIS", 0);
214 } else if (ShellCommandLineGetFlag(Package, L"-verbose") || ShellCommandLineGetFlag(Package, L"-v")) {
215 } else {
216 //
217 // The output of help <command> will display NAME, SYNOPSIS, OPTIONS, DESCRIPTION, and EXAMPLES sections.
218 //
219 StrnCatGrow (&SectionToGetHelpOn, NULL, L"NAME,SYNOPSIS,OPTIONS,DESCRIPTION,EXAMPLES", 0);
220 }
221 }
222
223 if (gUnicodeCollation->StriColl(gUnicodeCollation, CommandToGetHelpOn, L"special") == 0) {
224 //
225 // we need info on the special characters
226 //
227 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HELP_SC_HEADER), gShellLevel3HiiHandle);
228 HiiString = HiiGetString(gShellLevel3HiiHandle, STRING_TOKEN(STR_HELP_SC_DATA), NULL);
229 ShellPrintEx(-1, -1, L"%s", HiiString);
230 FreePool(HiiString);
231 Found = TRUE;
232 } else {
233 CommandList = ShellCommandGetCommandList(TRUE);
234 ASSERT(CommandList != NULL);
235 for ( Node = (COMMAND_LIST*)GetFirstNode(&CommandList->Link)
236 ; CommandList != NULL && !IsListEmpty(&CommandList->Link) && !IsNull(&CommandList->Link, &Node->Link)
237 ; Node = (COMMAND_LIST*)GetNextNode(&CommandList->Link, &Node->Link)
238 ){
239 //
240 // Checking execution break flag when print multiple command help information.
241 //
242 if (ShellGetExecutionBreakFlag ()) {
243 break;
244 }
245 if ((gUnicodeCollation->MetaiMatch(gUnicodeCollation, Node->CommandString, CommandToGetHelpOn)) ||
246 (gEfiShellProtocol->GetAlias(CommandToGetHelpOn, NULL) != NULL && (gUnicodeCollation->MetaiMatch(gUnicodeCollation, Node->CommandString, (CHAR16*)(gEfiShellProtocol->GetAlias(CommandToGetHelpOn, NULL)))))) {
247 //
248 // We have a command to look for help on.
249 //
250 Status = ShellPrintHelp(Node->CommandString, SectionToGetHelpOn, PrintCommandText);
251 if (Status == EFI_DEVICE_ERROR) {
252 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HELP_INV), gShellLevel3HiiHandle, Node->CommandString);
253 } else if (EFI_ERROR(Status)) {
254 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HELP_NF), gShellLevel3HiiHandle, Node->CommandString);
255 } else {
256 Found = TRUE;
257 }
258 }
259 }
260 //
261 // Search the .man file for Shell applications (Shell external commands).
262 //
263 if (!Found) {
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);
269 } else {
270 Found = TRUE;
271 }
272 }
273
274 //
275 // now try to match against the dynamic command list and print help
276 //
277 Status = PrintDynamicCommandHelp(CommandToGetHelpOn);
278 if (Status == EFI_SUCCESS) {
279 Found = TRUE;
280 }
281
282 }
283
284 if (!Found) {
285 ShellStatus = SHELL_NOT_FOUND;
286 }
287
288 //
289 // free the command line package
290 //
291 ShellCommandLineFreeVarList (Package);
292 }
293 }
294
295 if (CommandToGetHelpOn != NULL && StrCmp(CommandToGetHelpOn, L"*") == 0){
296 //
297 // If '*' then the command entered was 'Help' without qualifiers, This footer
298 // provides additional info on help switches
299 //
300 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HELP_FOOTER), gShellLevel3HiiHandle);
301 }
302 if (CommandToGetHelpOn != NULL) {
303 FreePool(CommandToGetHelpOn);
304 }
305 if (SectionToGetHelpOn != NULL) {
306 FreePool(SectionToGetHelpOn);
307 }
308
309 return (ShellStatus);
310 }