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