]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel1CommandsLib / UefiShellLevel1CommandsLib.c
1 /** @file
2 Main file for NULL named library for level 1 shell command functions.
3
4 (C) Copyright 2013 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include "UefiShellLevel1CommandsLib.h"
11
12 STATIC CONST CHAR16 mFileName[] = L"ShellCommands";
13 EFI_HII_HANDLE gShellLevel1HiiHandle = NULL;
14
15 /**
16 Return the help text filename. Only used if no HII information found.
17
18 @retval the filename.
19 **/
20 CONST CHAR16 *
21 EFIAPI
22 ShellCommandGetManFileNameLevel1 (
23 VOID
24 )
25 {
26 return (mFileName);
27 }
28
29 /**
30 Constructor for the Shell Level 1 Commands library.
31
32 Install the handlers for level 1 UEFI Shell 2.0 commands.
33
34 @param ImageHandle the image handle of the process
35 @param SystemTable the EFI System Table pointer
36
37 @retval EFI_SUCCESS the shell command handlers were installed sucessfully
38 @retval EFI_UNSUPPORTED the shell level required was not found.
39 **/
40 EFI_STATUS
41 EFIAPI
42 ShellLevel1CommandsLibConstructor (
43 IN EFI_HANDLE ImageHandle,
44 IN EFI_SYSTEM_TABLE *SystemTable
45 )
46 {
47 //
48 // if shell level is less than 2 do nothing
49 //
50 if (PcdGet8 (PcdShellSupportLevel) < 1) {
51 return (EFI_SUCCESS);
52 }
53
54 gShellLevel1HiiHandle = HiiAddPackages (&gShellLevel1HiiGuid, gImageHandle, UefiShellLevel1CommandsLibStrings, NULL);
55 if (gShellLevel1HiiHandle == NULL) {
56 return (EFI_DEVICE_ERROR);
57 }
58
59 //
60 // install our shell command handlers that are always installed
61 //
62 ShellCommandRegisterCommandName (L"stall", ShellCommandRunStall, ShellCommandGetManFileNameLevel1, 1, L"", FALSE, gShellLevel1HiiHandle, (EFI_STRING_ID)(PcdGet8 (PcdShellSupportLevel) < 3 ? 0 : STRING_TOKEN (STR_GET_HELP_STALL)));
63 ShellCommandRegisterCommandName (L"for", ShellCommandRunFor, ShellCommandGetManFileNameLevel1, 1, L"", FALSE, gShellLevel1HiiHandle, (EFI_STRING_ID)(PcdGet8 (PcdShellSupportLevel) < 3 ? 0 : STRING_TOKEN (STR_GET_HELP_FOR)));
64 ShellCommandRegisterCommandName (L"goto", ShellCommandRunGoto, ShellCommandGetManFileNameLevel1, 1, L"", FALSE, gShellLevel1HiiHandle, (EFI_STRING_ID)(PcdGet8 (PcdShellSupportLevel) < 3 ? 0 : STRING_TOKEN (STR_GET_HELP_GOTO)));
65 ShellCommandRegisterCommandName (L"if", ShellCommandRunIf, ShellCommandGetManFileNameLevel1, 1, L"", FALSE, gShellLevel1HiiHandle, (EFI_STRING_ID)(PcdGet8 (PcdShellSupportLevel) < 3 ? 0 : STRING_TOKEN (STR_GET_HELP_IF)));
66 ShellCommandRegisterCommandName (L"shift", ShellCommandRunShift, ShellCommandGetManFileNameLevel1, 1, L"", FALSE, gShellLevel1HiiHandle, (EFI_STRING_ID)(PcdGet8 (PcdShellSupportLevel) < 3 ? 0 : STRING_TOKEN (STR_GET_HELP_SHIFT)));
67 ShellCommandRegisterCommandName (L"exit", ShellCommandRunExit, ShellCommandGetManFileNameLevel1, 1, L"", TRUE, gShellLevel1HiiHandle, (EFI_STRING_ID)(PcdGet8 (PcdShellSupportLevel) < 3 ? 0 : STRING_TOKEN (STR_GET_HELP_EXIT)));
68 ShellCommandRegisterCommandName (L"else", ShellCommandRunElse, ShellCommandGetManFileNameLevel1, 1, L"", FALSE, gShellLevel1HiiHandle, (EFI_STRING_ID)(PcdGet8 (PcdShellSupportLevel) < 3 ? 0 : STRING_TOKEN (STR_GET_HELP_ELSE)));
69 ShellCommandRegisterCommandName (L"endif", ShellCommandRunEndIf, ShellCommandGetManFileNameLevel1, 1, L"", FALSE, gShellLevel1HiiHandle, (EFI_STRING_ID)(PcdGet8 (PcdShellSupportLevel) < 3 ? 0 : STRING_TOKEN (STR_GET_HELP_ENDIF)));
70 ShellCommandRegisterCommandName (L"endfor", ShellCommandRunEndFor, ShellCommandGetManFileNameLevel1, 1, L"", FALSE, gShellLevel1HiiHandle, (EFI_STRING_ID)(PcdGet8 (PcdShellSupportLevel) < 3 ? 0 : STRING_TOKEN (STR_GET_HELP_ENDFOR)));
71
72 return (EFI_SUCCESS);
73 }
74
75 /**
76 Destructor for the library. free any resources.
77
78 @param ImageHandle The image handle of the process.
79 @param SystemTable The EFI System Table pointer.
80 **/
81 EFI_STATUS
82 EFIAPI
83 ShellLevel1CommandsLibDestructor (
84 IN EFI_HANDLE ImageHandle,
85 IN EFI_SYSTEM_TABLE *SystemTable
86 )
87 {
88 if (gShellLevel1HiiHandle != NULL) {
89 HiiRemovePackages (gShellLevel1HiiHandle);
90 }
91
92 return (EFI_SUCCESS);
93 }
94
95 /**
96 Test a node to see if meets the criterion.
97
98 It functions so that count starts at 1 and it increases or decreases when it
99 hits the specified tags. when it hits zero the location has been found.
100
101 DecrementerTag and IncrementerTag are used to get around for/endfor and
102 similar paired types where the entire middle should be ignored.
103
104 If label is used it will be used instead of the count.
105
106 @param[in] Function The function to use to enumerate through the
107 list. Normally GetNextNode or GetPreviousNode.
108 @param[in] DecrementerTag The tag to decrement the count at.
109 @param[in] IncrementerTag The tag to increment the count at.
110 @param[in] Label A label to look for.
111 @param[in, out] ScriptFile The pointer to the current script file structure.
112 @param[in] MovePast TRUE makes function return 1 past the found
113 location.
114 @param[in] FindOnly TRUE to not change the ScriptFile.
115 @param[in] CommandNode The pointer to the Node to test.
116 @param[in, out] TargetCount The pointer to the current count.
117 **/
118 BOOLEAN
119 TestNodeForMove (
120 IN CONST LIST_MANIP_FUNC Function,
121 IN CONST CHAR16 *DecrementerTag,
122 IN CONST CHAR16 *IncrementerTag,
123 IN CONST CHAR16 *Label OPTIONAL,
124 IN OUT SCRIPT_FILE *ScriptFile,
125 IN CONST BOOLEAN MovePast,
126 IN CONST BOOLEAN FindOnly,
127 IN CONST SCRIPT_COMMAND_LIST *CommandNode,
128 IN OUT UINTN *TargetCount
129 )
130 {
131 BOOLEAN Found;
132 CHAR16 *CommandName;
133 CHAR16 *CommandNameWalker;
134 CHAR16 *TempLocation;
135
136 Found = FALSE;
137
138 //
139 // get just the first part of the command line...
140 //
141 CommandName = NULL;
142 CommandName = StrnCatGrow (&CommandName, NULL, CommandNode->Cl, 0);
143 if (CommandName == NULL) {
144 return (FALSE);
145 }
146
147 CommandNameWalker = CommandName;
148
149 //
150 // Skip leading spaces and tabs.
151 //
152 while ((CommandNameWalker[0] == L' ') || (CommandNameWalker[0] == L'\t')) {
153 CommandNameWalker++;
154 }
155
156 TempLocation = StrStr (CommandNameWalker, L" ");
157
158 if (TempLocation != NULL) {
159 *TempLocation = CHAR_NULL;
160 }
161
162 //
163 // did we find a nested item ?
164 //
165 if (gUnicodeCollation->StriColl (
166 gUnicodeCollation,
167 (CHAR16 *)CommandNameWalker,
168 (CHAR16 *)IncrementerTag
169 ) == 0)
170 {
171 (*TargetCount)++;
172 } else if (gUnicodeCollation->StriColl (
173 gUnicodeCollation,
174 (CHAR16 *)CommandNameWalker,
175 (CHAR16 *)DecrementerTag
176 ) == 0)
177 {
178 if (*TargetCount > 0) {
179 (*TargetCount)--;
180 }
181 }
182
183 //
184 // did we find the matching one...
185 //
186 if (Label == NULL) {
187 if (*TargetCount == 0) {
188 Found = TRUE;
189 if (!FindOnly) {
190 if (MovePast) {
191 ScriptFile->CurrentCommand = (SCRIPT_COMMAND_LIST *)(*Function)(&ScriptFile->CommandList, &CommandNode->Link);
192 } else {
193 ScriptFile->CurrentCommand = (SCRIPT_COMMAND_LIST *)CommandNode;
194 }
195 }
196 }
197 } else {
198 if ( (gUnicodeCollation->StriColl (
199 gUnicodeCollation,
200 (CHAR16 *)CommandNameWalker,
201 (CHAR16 *)Label
202 ) == 0)
203 && ((*TargetCount) == 0))
204 {
205 Found = TRUE;
206 if (!FindOnly) {
207 //
208 // we found the target label without loops
209 //
210 if (MovePast) {
211 ScriptFile->CurrentCommand = (SCRIPT_COMMAND_LIST *)(*Function)(&ScriptFile->CommandList, &CommandNode->Link);
212 } else {
213 ScriptFile->CurrentCommand = (SCRIPT_COMMAND_LIST *)CommandNode;
214 }
215 }
216 }
217 }
218
219 //
220 // Free the memory for this loop...
221 //
222 FreePool (CommandName);
223 return (Found);
224 }
225
226 /**
227 Move the script pointer from 1 tag (line) to another.
228
229 It functions so that count starts at 1 and it increases or decreases when it
230 hits the specified tags. when it hits zero the location has been found.
231
232 DecrementerTag and IncrementerTag are used to get around for/endfor and
233 similar paired types where the entire middle should be ignored.
234
235 If label is used it will be used instead of the count.
236
237 @param[in] Function The function to use to enumerate through the
238 list. Normally GetNextNode or GetPreviousNode.
239 @param[in] DecrementerTag The tag to decrement the count at.
240 @param[in] IncrementerTag The tag to increment the count at.
241 @param[in] Label A label to look for.
242 @param[in, out] ScriptFile The pointer to the current script file structure.
243 @param[in] MovePast TRUE makes function return 1 past the found
244 location.
245 @param[in] FindOnly TRUE to not change the ScriptFile.
246 @param[in] WrapAroundScript TRUE to wrap end-to-begining or vise versa in
247 searching.
248 **/
249 BOOLEAN
250 MoveToTag (
251 IN CONST LIST_MANIP_FUNC Function,
252 IN CONST CHAR16 *DecrementerTag,
253 IN CONST CHAR16 *IncrementerTag,
254 IN CONST CHAR16 *Label OPTIONAL,
255 IN OUT SCRIPT_FILE *ScriptFile,
256 IN CONST BOOLEAN MovePast,
257 IN CONST BOOLEAN FindOnly,
258 IN CONST BOOLEAN WrapAroundScript
259 )
260 {
261 SCRIPT_COMMAND_LIST *CommandNode;
262 BOOLEAN Found;
263 UINTN TargetCount;
264
265 if (Label == NULL) {
266 TargetCount = 1;
267 } else {
268 TargetCount = 0;
269 }
270
271 if (ScriptFile == NULL) {
272 return FALSE;
273 }
274
275 for (CommandNode = (SCRIPT_COMMAND_LIST *)(*Function)(&ScriptFile->CommandList, &ScriptFile->CurrentCommand->Link), Found = FALSE
276 ; !IsNull (&ScriptFile->CommandList, &CommandNode->Link) && !Found
277 ; CommandNode = (SCRIPT_COMMAND_LIST *)(*Function)(&ScriptFile->CommandList, &CommandNode->Link)
278 )
279 {
280 Found = TestNodeForMove (
281 Function,
282 DecrementerTag,
283 IncrementerTag,
284 Label,
285 ScriptFile,
286 MovePast,
287 FindOnly,
288 CommandNode,
289 &TargetCount
290 );
291 }
292
293 if (WrapAroundScript && !Found) {
294 for (CommandNode = (SCRIPT_COMMAND_LIST *)GetFirstNode (&ScriptFile->CommandList), Found = FALSE
295 ; CommandNode != ScriptFile->CurrentCommand && !Found
296 ; CommandNode = (SCRIPT_COMMAND_LIST *)(*Function)(&ScriptFile->CommandList, &CommandNode->Link)
297 )
298 {
299 Found = TestNodeForMove (
300 Function,
301 DecrementerTag,
302 IncrementerTag,
303 Label,
304 ScriptFile,
305 MovePast,
306 FindOnly,
307 CommandNode,
308 &TargetCount
309 );
310 }
311 }
312
313 return (Found);
314 }