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