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