VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/ShellPkg/Library/UefiShellLevel1CommandsLib/If.c

Last change on this file was 108794, checked in by vboxsync, 4 weeks ago

Devices/EFI/FirmwareNew: Merge edk2-stable202502 from the vendor branch and make it build for the important platforms, bugref:4643

  • Property svn:eol-style set to native
File size: 39.8 KB
Line 
1/** @file
2 Main file for If and else shell level 1 function.
3
4 (C) Copyright 2013-2015 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#include <Library/PrintLib.h>
12
13typedef enum {
14 EndTagOr,
15 EndTagAnd,
16 EndTagThen,
17 EndTagMax
18} END_TAG_TYPE;
19
20typedef enum {
21 OperatorGreaterThan,
22 OperatorLessThan,
23 OperatorEqual,
24 OperatorNotEqual,
25 OperatorGreatorOrEqual,
26 OperatorLessOrEqual,
27 OperatorUnisgnedGreaterThan,
28 OperatorUnsignedLessThan,
29 OperatorUnsignedGreaterOrEqual,
30 OperatorUnsignedLessOrEqual,
31 OperatorMax
32} BIN_OPERATOR_TYPE;
33
34/**
35 Extract the next fragment, if there is one.
36
37 @param[in, out] Statement The current remaining statement.
38 @param[in] Fragment The current fragment.
39 @param[out] Match TRUE when there is another Fragment in Statement,
40 FALSE otherwise.
41
42 @retval EFI_SUCCESS The match operation is performed successfully.
43 @retval EFI_OUT_OF_RESOURCES Out of resources.
44**/
45EFI_STATUS
46IsNextFragment (
47 IN OUT CONST CHAR16 **Statement,
48 IN CONST CHAR16 *Fragment,
49 OUT BOOLEAN *Match
50 )
51{
52 CHAR16 *Tester;
53
54 Tester = NULL;
55
56 Tester = StrnCatGrow (&Tester, NULL, *Statement, StrLen (Fragment));
57 if (Tester == NULL) {
58 return EFI_OUT_OF_RESOURCES;
59 }
60
61 Tester[StrLen (Fragment)] = CHAR_NULL;
62 if (gUnicodeCollation->StriColl (
63 gUnicodeCollation,
64 (CHAR16 *)Fragment,
65 Tester
66 ) == 0)
67 {
68 //
69 // increment the string pointer to the end of what we found and then chop off spaces...
70 //
71 *Statement += StrLen (Fragment);
72 while (*Statement[0] == L' ') {
73 (*Statement)++;
74 }
75
76 *Match = TRUE;
77 } else {
78 *Match = FALSE;
79 }
80
81 FreePool (Tester);
82 return EFI_SUCCESS;
83}
84
85/**
86 Determine if String represents a valid profile.
87
88 @param[in] String The pointer to the string to test.
89
90 @retval TRUE String is a valid profile.
91 @retval FALSE String is not a valid profile.
92**/
93BOOLEAN
94IsValidProfile (
95 IN CONST CHAR16 *String
96 )
97{
98 CONST CHAR16 *ProfilesString;
99 CONST CHAR16 *TempLocation;
100
101 ProfilesString = ShellGetEnvironmentVariable (L"profiles");
102 if (ProfilesString == NULL) {
103 ASSERT (ProfilesString != NULL);
104 return (FALSE);
105 }
106
107 TempLocation = StrStr (ProfilesString, String);
108 if ((TempLocation != NULL) && (*(TempLocation-1) == L';') && (*(TempLocation+StrLen (String)) == L';')) {
109 return (TRUE);
110 }
111
112 return (FALSE);
113}
114
115/**
116 Do a comparison between 2 things.
117
118 @param[in] Compare1 The first item to compare.
119 @param[in] Compare2 The second item to compare.
120 @param[in] BinOp The type of comparison to perform.
121 @param[in] CaseInsensitive TRUE to do non-case comparison, FALSE otherwise.
122 @param[in] ForceStringCompare TRUE to force string comparison, FALSE otherwise.
123
124 @return The result of the comparison.
125**/
126BOOLEAN
127TestOperation (
128 IN CONST CHAR16 *Compare1,
129 IN CONST CHAR16 *Compare2,
130 IN CONST BIN_OPERATOR_TYPE BinOp,
131 IN CONST BOOLEAN CaseInsensitive,
132 IN CONST BOOLEAN ForceStringCompare
133 )
134{
135 INTN Cmp1;
136 INTN Cmp2;
137
138 //
139 // "Compare1 BinOp Compare2"
140 //
141 switch (BinOp) {
142 case OperatorUnisgnedGreaterThan:
143 case OperatorGreaterThan:
144 if (ForceStringCompare || !ShellIsHexOrDecimalNumber (Compare1, FALSE, FALSE) || !ShellIsHexOrDecimalNumber (Compare2, FALSE, FALSE)) {
145 //
146 // string compare
147 //
148 if ((CaseInsensitive && (StringNoCaseCompare (&Compare1, &Compare2) > 0)) || (StringCompare (&Compare1, &Compare2) > 0)) {
149 return (TRUE);
150 }
151 } else {
152 //
153 // numeric compare
154 //
155 if (Compare1[0] == L'-') {
156 Cmp1 = 0 - (INTN)ShellStrToUintn (Compare1+1);
157 } else {
158 Cmp1 = (INTN)ShellStrToUintn (Compare1);
159 }
160
161 if (Compare2[0] == L'-') {
162 Cmp2 = 0 - (INTN)ShellStrToUintn (Compare2+1);
163 } else {
164 Cmp2 = (INTN)ShellStrToUintn (Compare2);
165 }
166
167 if (BinOp == OperatorGreaterThan) {
168 if (Cmp1 > Cmp2) {
169 return (TRUE);
170 }
171 } else {
172 if ((UINTN)Cmp1 > (UINTN)Cmp2) {
173 return (TRUE);
174 }
175 }
176 }
177
178 return (FALSE);
179 case OperatorUnsignedLessThan:
180 case OperatorLessThan:
181 if (ForceStringCompare || !ShellIsHexOrDecimalNumber (Compare1, FALSE, FALSE) || !ShellIsHexOrDecimalNumber (Compare2, FALSE, FALSE)) {
182 //
183 // string compare
184 //
185 if ((CaseInsensitive && (StringNoCaseCompare (&Compare1, &Compare2) < 0)) || (StringCompare (&Compare1, &Compare2) < 0)) {
186 return (TRUE);
187 }
188 } else {
189 //
190 // numeric compare
191 //
192 if (Compare1[0] == L'-') {
193 Cmp1 = 0 - (INTN)ShellStrToUintn (Compare1+1);
194 } else {
195 Cmp1 = (INTN)ShellStrToUintn (Compare1);
196 }
197
198 if (Compare2[0] == L'-') {
199 Cmp2 = 0 - (INTN)ShellStrToUintn (Compare2+1);
200 } else {
201 Cmp2 = (INTN)ShellStrToUintn (Compare2);
202 }
203
204 if (BinOp == OperatorLessThan) {
205 if (Cmp1 < Cmp2) {
206 return (TRUE);
207 }
208 } else {
209 if ((UINTN)Cmp1 < (UINTN)Cmp2) {
210 return (TRUE);
211 }
212 }
213 }
214
215 return (FALSE);
216 case OperatorEqual:
217 if (ForceStringCompare || !ShellIsHexOrDecimalNumber (Compare1, FALSE, FALSE) || !ShellIsHexOrDecimalNumber (Compare2, FALSE, FALSE)) {
218 //
219 // string compare
220 //
221 if ((CaseInsensitive && (StringNoCaseCompare (&Compare1, &Compare2) == 0)) || (StringCompare (&Compare1, &Compare2) == 0)) {
222 return (TRUE);
223 }
224 } else {
225 //
226 // numeric compare
227 //
228 if (Compare1[0] == L'-') {
229 Cmp1 = 0 - (INTN)ShellStrToUintn (Compare1+1);
230 } else {
231 Cmp1 = (INTN)ShellStrToUintn (Compare1);
232 }
233
234 if (Compare2[0] == L'-') {
235 Cmp2 = 0 - (INTN)ShellStrToUintn (Compare2+1);
236 } else {
237 Cmp2 = (INTN)ShellStrToUintn (Compare2);
238 }
239
240 if (Cmp1 == Cmp2) {
241 return (TRUE);
242 }
243 }
244
245 return (FALSE);
246 case OperatorNotEqual:
247 if (ForceStringCompare || !ShellIsHexOrDecimalNumber (Compare1, FALSE, FALSE) || !ShellIsHexOrDecimalNumber (Compare2, FALSE, FALSE)) {
248 //
249 // string compare
250 //
251 if ((CaseInsensitive && (StringNoCaseCompare (&Compare1, &Compare2) != 0)) || (StringCompare (&Compare1, &Compare2) != 0)) {
252 return (TRUE);
253 }
254 } else {
255 //
256 // numeric compare
257 //
258 if (Compare1[0] == L'-') {
259 Cmp1 = 0 - (INTN)ShellStrToUintn (Compare1+1);
260 } else {
261 Cmp1 = (INTN)ShellStrToUintn (Compare1);
262 }
263
264 if (Compare2[0] == L'-') {
265 Cmp2 = 0 - (INTN)ShellStrToUintn (Compare2+1);
266 } else {
267 Cmp2 = (INTN)ShellStrToUintn (Compare2);
268 }
269
270 if (Cmp1 != Cmp2) {
271 return (TRUE);
272 }
273 }
274
275 return (FALSE);
276 case OperatorUnsignedGreaterOrEqual:
277 case OperatorGreatorOrEqual:
278 if (ForceStringCompare || !ShellIsHexOrDecimalNumber (Compare1, FALSE, FALSE) || !ShellIsHexOrDecimalNumber (Compare2, FALSE, FALSE)) {
279 //
280 // string compare
281 //
282 if ((CaseInsensitive && (StringNoCaseCompare (&Compare1, &Compare2) >= 0)) || (StringCompare (&Compare1, &Compare2) >= 0)) {
283 return (TRUE);
284 }
285 } else {
286 //
287 // numeric compare
288 //
289 if (Compare1[0] == L'-') {
290 Cmp1 = 0 - (INTN)ShellStrToUintn (Compare1+1);
291 } else {
292 Cmp1 = (INTN)ShellStrToUintn (Compare1);
293 }
294
295 if (Compare2[0] == L'-') {
296 Cmp2 = 0 - (INTN)ShellStrToUintn (Compare2+1);
297 } else {
298 Cmp2 = (INTN)ShellStrToUintn (Compare2);
299 }
300
301 if (BinOp == OperatorGreatorOrEqual) {
302 if (Cmp1 >= Cmp2) {
303 return (TRUE);
304 }
305 } else {
306 if ((UINTN)Cmp1 >= (UINTN)Cmp2) {
307 return (TRUE);
308 }
309 }
310 }
311
312 return (FALSE);
313 case OperatorLessOrEqual:
314 case OperatorUnsignedLessOrEqual:
315 if (ForceStringCompare || !ShellIsHexOrDecimalNumber (Compare1, FALSE, FALSE) || !ShellIsHexOrDecimalNumber (Compare2, FALSE, FALSE)) {
316 //
317 // string compare
318 //
319 if ((CaseInsensitive && (StringNoCaseCompare (&Compare1, &Compare2) <= 0)) || (StringCompare (&Compare1, &Compare2) <= 0)) {
320 return (TRUE);
321 }
322 } else {
323 //
324 // numeric compare
325 //
326 if (Compare1[0] == L'-') {
327 Cmp1 = 0 - (INTN)ShellStrToUintn (Compare1+1);
328 } else {
329 Cmp1 = (INTN)ShellStrToUintn (Compare1);
330 }
331
332 if (Compare2[0] == L'-') {
333 Cmp2 = 0 - (INTN)ShellStrToUintn (Compare2+1);
334 } else {
335 Cmp2 = (INTN)ShellStrToUintn (Compare2);
336 }
337
338 if (BinOp == OperatorLessOrEqual) {
339 if (Cmp1 <= Cmp2) {
340 return (TRUE);
341 }
342 } else {
343 if ((UINTN)Cmp1 <= (UINTN)Cmp2) {
344 return (TRUE);
345 }
346 }
347 }
348
349 return (FALSE);
350 default:
351 ASSERT (FALSE);
352 return (FALSE);
353 }
354}
355
356/**
357 Process an if statement and determine if its is valid or not.
358
359 @param[in, out] PassingState Opon entry, the current state. Upon exit,
360 the new state.
361 @param[in] StartParameterNumber The number of the first parameter of
362 this statement.
363 @param[in] EndParameterNumber The number of the final parameter of
364 this statement.
365 @param[in] OperatorToUse The type of termination operator.
366 @param[in] CaseInsensitive TRUE for case insensitive, FALSE otherwise.
367 @param[in] ForceStringCompare TRUE for all string based, FALSE otherwise.
368
369 @retval EFI_INVALID_PARAMETER A parameter was invalid.
370 @retval EFI_SUCCESS The operation was successful.
371**/
372EFI_STATUS
373ProcessStatement (
374 IN OUT BOOLEAN *PassingState,
375 IN UINTN StartParameterNumber,
376 IN UINTN EndParameterNumber,
377 IN CONST END_TAG_TYPE OperatorToUse,
378 IN CONST BOOLEAN CaseInsensitive,
379 IN CONST BOOLEAN ForceStringCompare
380 )
381{
382 EFI_STATUS Status;
383 BOOLEAN OperationResult;
384 BOOLEAN NotPresent;
385 CHAR16 *StatementWalker;
386 BIN_OPERATOR_TYPE BinOp;
387 CHAR16 *Compare1;
388 CHAR16 *Compare2;
389 CHAR16 HexString[20];
390 CHAR16 *TempSpot;
391 BOOLEAN Match;
392
393 ASSERT ((END_TAG_TYPE)OperatorToUse != EndTagThen);
394
395 Status = EFI_SUCCESS;
396 BinOp = OperatorMax;
397 OperationResult = FALSE;
398 Match = FALSE;
399 StatementWalker = gEfiShellParametersProtocol->Argv[StartParameterNumber];
400 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"not", &Match)) && Match) {
401 NotPresent = TRUE;
402 StatementWalker = gEfiShellParametersProtocol->Argv[++StartParameterNumber];
403 } else {
404 NotPresent = FALSE;
405 }
406
407 //
408 // now check for 'boolfunc' operators
409 //
410 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"isint", &Match)) && Match) {
411 if ( !EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"(", &Match)) && Match
412 && (StatementWalker[StrLen (StatementWalker)-1] == L')'))
413 {
414 StatementWalker[StrLen (StatementWalker)-1] = CHAR_NULL;
415 OperationResult = ShellIsHexOrDecimalNumber (StatementWalker, FALSE, FALSE);
416 } else {
417 Status = EFI_INVALID_PARAMETER;
418 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"isint");
419 }
420 } else if ((!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"exists", &Match)) && Match) ||
421 (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"exist", &Match)) && Match))
422 {
423 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"(", &Match)) && Match &&
424 (StatementWalker[StrLen (StatementWalker)-1] == L')'))
425 {
426 StatementWalker[StrLen (StatementWalker)-1] = CHAR_NULL;
427 //
428 // is what remains a file in CWD???
429 //
430 OperationResult = (BOOLEAN)(ShellFileExists (StatementWalker) == EFI_SUCCESS);
431 } else if ((StatementWalker[0] == CHAR_NULL) && (StartParameterNumber+1 == EndParameterNumber)) {
432 OperationResult = (BOOLEAN)(ShellFileExists (gEfiShellParametersProtocol->Argv[++StartParameterNumber]) == EFI_SUCCESS);
433 } else {
434 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"exist(s)");
435 Status = EFI_INVALID_PARAMETER;
436 }
437 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"available", &Match)) && Match) {
438 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"(", &Match)) && Match &&
439 (StatementWalker[StrLen (StatementWalker)-1] == L')'))
440 {
441 StatementWalker[StrLen (StatementWalker)-1] = CHAR_NULL;
442 //
443 // is what remains a file in the CWD or path???
444 //
445 OperationResult = (BOOLEAN)(ShellIsFileInPath (StatementWalker) == EFI_SUCCESS);
446 } else {
447 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"available");
448 Status = EFI_INVALID_PARAMETER;
449 }
450 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"profile", &Match)) && Match) {
451 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"(", &Match)) && Match &&
452 (StatementWalker[StrLen (StatementWalker)-1] == L')'))
453 {
454 //
455 // Chop off that ')'
456 //
457 StatementWalker[StrLen (StatementWalker)-1] = CHAR_NULL;
458 OperationResult = IsValidProfile (StatementWalker);
459 } else {
460 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"profile");
461 Status = EFI_INVALID_PARAMETER;
462 }
463 } else if (StartParameterNumber+1 >= EndParameterNumber) {
464 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[StartParameterNumber]);
465 Status = EFI_INVALID_PARAMETER;
466 } else {
467 //
468 // must be 'item binop item' style
469 //
470 Compare1 = NULL;
471 Compare2 = NULL;
472 BinOp = OperatorMax;
473
474 //
475 // get the first item
476 //
477 StatementWalker = gEfiShellParametersProtocol->Argv[StartParameterNumber];
478 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"efierror", &Match)) && Match) {
479 TempSpot = StrStr (StatementWalker, L")");
480 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"(", &Match)) && Match && (TempSpot != NULL)) {
481 *TempSpot = CHAR_NULL;
482 if (ShellIsHexOrDecimalNumber (StatementWalker, FALSE, FALSE)) {
483 UnicodeSPrint (HexString, sizeof (HexString), L"0x%x", ShellStrToUintn (StatementWalker)|MAX_BIT);
484 ASSERT (Compare1 == NULL);
485 Compare1 = StrnCatGrow (&Compare1, NULL, HexString, 0);
486 StatementWalker += StrLen (StatementWalker) + 1;
487 } else {
488 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"efierror");
489 Status = EFI_INVALID_PARAMETER;
490 }
491 } else {
492 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"efierror");
493 Status = EFI_INVALID_PARAMETER;
494 }
495 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"pierror", &Match)) && Match) {
496 TempSpot = StrStr (StatementWalker, L")");
497 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"(", &Match)) && Match && (TempSpot != NULL)) {
498 *TempSpot = CHAR_NULL;
499 if (ShellIsHexOrDecimalNumber (StatementWalker, FALSE, FALSE)) {
500 UnicodeSPrint (HexString, sizeof (HexString), L"0x%x", ShellStrToUintn (StatementWalker)|MAX_BIT|(MAX_BIT>>2));
501 ASSERT (Compare1 == NULL);
502 Compare1 = StrnCatGrow (&Compare1, NULL, HexString, 0);
503 StatementWalker += StrLen (StatementWalker) + 1;
504 } else {
505 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"pierror");
506 Status = EFI_INVALID_PARAMETER;
507 }
508 } else {
509 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"pierror");
510 Status = EFI_INVALID_PARAMETER;
511 }
512 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"oemerror", &Match)) && Match) {
513 TempSpot = StrStr (StatementWalker, L")");
514 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"(", &Match)) && Match && (TempSpot != NULL)) {
515 TempSpot = CHAR_NULL;
516 if (ShellIsHexOrDecimalNumber (StatementWalker, FALSE, FALSE)) {
517 UnicodeSPrint (HexString, sizeof (HexString), L"0x%x", ShellStrToUintn (StatementWalker)|MAX_BIT|(MAX_BIT>>1));
518 ASSERT (Compare1 == NULL);
519 Compare1 = StrnCatGrow (&Compare1, NULL, HexString, 0);
520 StatementWalker += StrLen (StatementWalker) + 1;
521 } else {
522 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"oemerror");
523 Status = EFI_INVALID_PARAMETER;
524 }
525 } else {
526 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"oemerror");
527 Status = EFI_INVALID_PARAMETER;
528 }
529 } else {
530 ASSERT (Compare1 == NULL);
531 if (EndParameterNumber - StartParameterNumber > 2) {
532 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_STARTING), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[StartParameterNumber+2]);
533 Status = EFI_INVALID_PARAMETER;
534 } else {
535 //
536 // must be a raw string
537 //
538 Compare1 = StrnCatGrow (&Compare1, NULL, StatementWalker, 0);
539 }
540 }
541
542 //
543 // get the operator
544 //
545 ASSERT (StartParameterNumber+1 < EndParameterNumber);
546 StatementWalker = gEfiShellParametersProtocol->Argv[StartParameterNumber+1];
547 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"gt", &Match)) && Match) {
548 BinOp = OperatorGreaterThan;
549 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"lt", &Match)) && Match) {
550 BinOp = OperatorLessThan;
551 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"eq", &Match)) && Match) {
552 BinOp = OperatorEqual;
553 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"ne", &Match)) && Match) {
554 BinOp = OperatorNotEqual;
555 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"ge", &Match)) && Match) {
556 BinOp = OperatorGreatorOrEqual;
557 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"le", &Match)) && Match) {
558 BinOp = OperatorLessOrEqual;
559 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"==", &Match)) && Match) {
560 BinOp = OperatorEqual;
561 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"ugt", &Match)) && Match) {
562 BinOp = OperatorUnisgnedGreaterThan;
563 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"ult", &Match)) && Match) {
564 BinOp = OperatorUnsignedLessThan;
565 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"uge", &Match)) && Match) {
566 BinOp = OperatorUnsignedGreaterOrEqual;
567 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"ule", &Match)) && Match) {
568 BinOp = OperatorUnsignedLessOrEqual;
569 } else {
570 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_INVALID_BINOP), gShellLevel1HiiHandle, StatementWalker);
571 Status = EFI_INVALID_PARAMETER;
572 }
573
574 //
575 // get the second item
576 //
577 ASSERT (StartParameterNumber+2 <= EndParameterNumber);
578 StatementWalker = gEfiShellParametersProtocol->Argv[StartParameterNumber+2];
579 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"efierror", &Match)) && Match) {
580 TempSpot = StrStr (StatementWalker, L")");
581 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"(", &Match)) && Match && (TempSpot != NULL)) {
582 TempSpot = CHAR_NULL;
583 if (ShellIsHexOrDecimalNumber (StatementWalker, FALSE, FALSE)) {
584 UnicodeSPrint (HexString, sizeof (HexString), L"0x%x", ShellStrToUintn (StatementWalker)|MAX_BIT);
585 ASSERT (Compare2 == NULL);
586 Compare2 = StrnCatGrow (&Compare2, NULL, HexString, 0);
587 StatementWalker += StrLen (StatementWalker) + 1;
588 } else {
589 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"efierror");
590 Status = EFI_INVALID_PARAMETER;
591 }
592 } else {
593 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"efierror");
594 Status = EFI_INVALID_PARAMETER;
595 }
596
597 //
598 // can this be collapsed into the above?
599 //
600 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"pierror", &Match)) && Match) {
601 TempSpot = StrStr (StatementWalker, L")");
602 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"(", &Match)) && Match && (TempSpot != NULL)) {
603 TempSpot = CHAR_NULL;
604 if (ShellIsHexOrDecimalNumber (StatementWalker, FALSE, FALSE)) {
605 UnicodeSPrint (HexString, sizeof (HexString), L"0x%x", ShellStrToUintn (StatementWalker)|MAX_BIT|(MAX_BIT>>2));
606 ASSERT (Compare2 == NULL);
607 Compare2 = StrnCatGrow (&Compare2, NULL, HexString, 0);
608 StatementWalker += StrLen (StatementWalker) + 1;
609 } else {
610 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"pierror");
611 Status = EFI_INVALID_PARAMETER;
612 }
613 } else {
614 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"pierror");
615 Status = EFI_INVALID_PARAMETER;
616 }
617 } else if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"oemerror", &Match)) && Match) {
618 TempSpot = StrStr (StatementWalker, L")");
619 if (!EFI_ERROR (IsNextFragment ((CONST CHAR16 **)(&StatementWalker), L"(", &Match)) && Match && (TempSpot != NULL)) {
620 TempSpot = CHAR_NULL;
621 if (ShellIsHexOrDecimalNumber (StatementWalker, FALSE, FALSE)) {
622 UnicodeSPrint (HexString, sizeof (HexString), L"0x%x", ShellStrToUintn (StatementWalker)|MAX_BIT|(MAX_BIT>>1));
623 ASSERT (Compare2 == NULL);
624 Compare2 = StrnCatGrow (&Compare2, NULL, HexString, 0);
625 StatementWalker += StrLen (StatementWalker) + 1;
626 } else {
627 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"oemerror");
628 Status = EFI_INVALID_PARAMETER;
629 }
630 } else {
631 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"oemerror");
632 Status = EFI_INVALID_PARAMETER;
633 }
634 } else {
635 //
636 // must be a raw string
637 //
638 ASSERT (Compare2 == NULL);
639 Compare2 = StrnCatGrow (&Compare2, NULL, StatementWalker, 0);
640 }
641
642 if ((Compare1 != NULL) && (Compare2 != NULL) && (BinOp != OperatorMax)) {
643 OperationResult = TestOperation (Compare1, Compare2, BinOp, CaseInsensitive, ForceStringCompare);
644 }
645
646 SHELL_FREE_NON_NULL (Compare1);
647 SHELL_FREE_NON_NULL (Compare2);
648 }
649
650 //
651 // done processing do result...
652 //
653
654 if (!EFI_ERROR (Status)) {
655 if (NotPresent) {
656 OperationResult = (BOOLEAN)(!OperationResult);
657 }
658
659 switch (OperatorToUse) {
660 case EndTagOr:
661 *PassingState = (BOOLEAN)(*PassingState || OperationResult);
662 break;
663 case EndTagAnd:
664 *PassingState = (BOOLEAN)(*PassingState && OperationResult);
665 break;
666 case EndTagMax:
667 *PassingState = (BOOLEAN)(OperationResult);
668 break;
669 default:
670 ASSERT (FALSE);
671 }
672 }
673
674 return (Status);
675}
676
677/**
678 Break up the next part of the if statement (until the next 'and', 'or', or 'then').
679
680 @param[in] ParameterNumber The current parameter number.
681 @param[out] EndParameter Upon successful return, will point to the
682 parameter to start the next iteration with.
683 @param[out] EndTag Upon successful return, will point to the
684 type that was found at the end of this statement.
685
686 @retval TRUE A valid statement was found.
687 @retval FALSE A valid statement was not found.
688**/
689BOOLEAN
690BuildNextStatement (
691 IN UINTN ParameterNumber,
692 OUT UINTN *EndParameter,
693 OUT END_TAG_TYPE *EndTag
694 )
695{
696 *EndTag = EndTagMax;
697
698 for (
699 ; ParameterNumber < gEfiShellParametersProtocol->Argc
700 ; ParameterNumber++
701 )
702 {
703 if (gUnicodeCollation->StriColl (
704 gUnicodeCollation,
705 gEfiShellParametersProtocol->Argv[ParameterNumber],
706 L"or"
707 ) == 0)
708 {
709 *EndParameter = ParameterNumber - 1;
710 *EndTag = EndTagOr;
711 break;
712 } else if (gUnicodeCollation->StriColl (
713 gUnicodeCollation,
714 gEfiShellParametersProtocol->Argv[ParameterNumber],
715 L"and"
716 ) == 0)
717 {
718 *EndParameter = ParameterNumber - 1;
719 *EndTag = EndTagAnd;
720 break;
721 } else if (gUnicodeCollation->StriColl (
722 gUnicodeCollation,
723 gEfiShellParametersProtocol->Argv[ParameterNumber],
724 L"then"
725 ) == 0)
726 {
727 *EndParameter = ParameterNumber - 1;
728 *EndTag = EndTagThen;
729 break;
730 }
731 }
732
733 if (*EndTag == EndTagMax) {
734 return (FALSE);
735 }
736
737 return (TRUE);
738}
739
740/**
741 Move the script file pointer to a different place in the script file.
742 This one is special since it handles the if/else/endif syntax.
743
744 @param[in] ScriptFile The script file from GetCurrnetScriptFile().
745
746 @retval TRUE The move target was found and the move was successful.
747 @retval FALSE Something went wrong.
748**/
749BOOLEAN
750MoveToTagSpecial (
751 IN SCRIPT_FILE *ScriptFile
752 )
753{
754 SCRIPT_COMMAND_LIST *CommandNode;
755 BOOLEAN Found;
756 UINTN TargetCount;
757 CHAR16 *CommandName;
758 CHAR16 *CommandWalker;
759 CHAR16 *TempLocation;
760
761 TargetCount = 1;
762 Found = FALSE;
763
764 if (ScriptFile == NULL) {
765 return FALSE;
766 }
767
768 for (CommandNode = (SCRIPT_COMMAND_LIST *)GetNextNode (&ScriptFile->CommandList, &ScriptFile->CurrentCommand->Link), Found = FALSE
769 ; !IsNull (&ScriptFile->CommandList, &CommandNode->Link) && !Found
770 ; CommandNode = (SCRIPT_COMMAND_LIST *)GetNextNode (&ScriptFile->CommandList, &CommandNode->Link)
771 )
772 {
773 //
774 // get just the first part of the command line...
775 //
776 CommandName = NULL;
777 CommandName = StrnCatGrow (&CommandName, NULL, CommandNode->Cl, 0);
778 if (CommandName == NULL) {
779 continue;
780 }
781
782 CommandWalker = CommandName;
783
784 //
785 // Skip leading spaces and tabs.
786 //
787 while ((CommandWalker[0] == L' ') || (CommandWalker[0] == L'\t')) {
788 CommandWalker++;
789 }
790
791 TempLocation = StrStr (CommandWalker, L" ");
792
793 if (TempLocation != NULL) {
794 *TempLocation = CHAR_NULL;
795 }
796
797 //
798 // did we find a nested item ?
799 //
800 if (gUnicodeCollation->StriColl (
801 gUnicodeCollation,
802 (CHAR16 *)CommandWalker,
803 L"If"
804 ) == 0)
805 {
806 TargetCount++;
807 } else if ((TargetCount == 1) && (gUnicodeCollation->StriColl (
808 gUnicodeCollation,
809 (CHAR16 *)CommandWalker,
810 (CHAR16 *)L"else"
811 ) == 0))
812 {
813 //
814 // else can only decrement the last part... not an nested if
815 // hence the TargetCount compare added
816 //
817 TargetCount--;
818 } else if (gUnicodeCollation->StriColl (
819 gUnicodeCollation,
820 (CHAR16 *)CommandWalker,
821 (CHAR16 *)L"endif"
822 ) == 0)
823 {
824 TargetCount--;
825 }
826
827 if (TargetCount == 0) {
828 ScriptFile->CurrentCommand = (SCRIPT_COMMAND_LIST *)GetNextNode (&ScriptFile->CommandList, &CommandNode->Link);
829 Found = TRUE;
830 }
831
832 //
833 // Free the memory for this loop...
834 //
835 SHELL_FREE_NON_NULL (CommandName);
836 }
837
838 return (Found);
839}
840
841/**
842 Deal with the result of the if operation.
843
844 @param[in] Result The result of the if.
845
846 @retval EFI_SUCCESS The operation was successful.
847 @retval EFI_NOT_FOUND The ending tag could not be found.
848**/
849EFI_STATUS
850PerformResultOperation (
851 IN CONST BOOLEAN Result
852 )
853{
854 if (Result || MoveToTagSpecial (ShellCommandGetCurrentScriptFile ())) {
855 return (EFI_SUCCESS);
856 }
857
858 return (EFI_NOT_FOUND);
859}
860
861/**
862 Function for 'if' command.
863
864 @param[in] ImageHandle Handle to the Image (NULL if Internal).
865 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
866**/
867SHELL_STATUS
868EFIAPI
869ShellCommandRunIf (
870 IN EFI_HANDLE ImageHandle,
871 IN EFI_SYSTEM_TABLE *SystemTable
872 )
873{
874 EFI_STATUS Status;
875 SHELL_STATUS ShellStatus;
876 BOOLEAN CaseInsensitive;
877 BOOLEAN ForceString;
878 UINTN CurrentParameter;
879 UINTN EndParameter;
880 BOOLEAN CurrentValue;
881 END_TAG_TYPE Ending;
882 END_TAG_TYPE PreviousEnding;
883 SCRIPT_FILE *CurrentScriptFile;
884
885 Status = CommandInit ();
886 ASSERT_EFI_ERROR (Status);
887
888 if (!gEfiShellProtocol->BatchIsActive ()) {
889 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"if");
890 return (SHELL_UNSUPPORTED);
891 }
892
893 if (gEfiShellParametersProtocol->Argc < 3) {
894 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel1HiiHandle, L"if");
895 return (SHELL_INVALID_PARAMETER);
896 }
897
898 //
899 // Make sure that an End exists.
900 //
901 CurrentScriptFile = ShellCommandGetCurrentScriptFile ();
902 if (CurrentScriptFile == NULL) {
903 return (SHELL_INVALID_PARAMETER);
904 }
905
906 if (!MoveToTag (GetNextNode, L"endif", L"if", NULL, CurrentScriptFile, TRUE, TRUE, FALSE)) {
907 ShellPrintHiiEx (
908 -1,
909 -1,
910 NULL,
911 STRING_TOKEN (STR_SYNTAX_NO_MATCHING),
912 gShellLevel1HiiHandle,
913 L"EndIf",
914 L"If",
915 CurrentScriptFile != NULL
916 && CurrentScriptFile->CurrentCommand != NULL
917 ? CurrentScriptFile->CurrentCommand->Line : 0
918 );
919 return (SHELL_DEVICE_ERROR);
920 }
921
922 //
923 // initialize the shell lib (we must be in non-auto-init...)
924 //
925 Status = ShellInitialize ();
926 ASSERT_EFI_ERROR (Status);
927
928 CurrentParameter = 1;
929 EndParameter = 0;
930
931 if ((gUnicodeCollation->StriColl (
932 gUnicodeCollation,
933 gEfiShellParametersProtocol->Argv[1],
934 L"/i"
935 ) == 0) ||
936 (gUnicodeCollation->StriColl (
937 gUnicodeCollation,
938 gEfiShellParametersProtocol->Argv[2],
939 L"/i"
940 ) == 0) ||
941 ((gEfiShellParametersProtocol->Argc > 3) && (gUnicodeCollation->StriColl (
942 gUnicodeCollation,
943 gEfiShellParametersProtocol->Argv[3],
944 L"/i"
945 ) == 0)))
946 {
947 CaseInsensitive = TRUE;
948 CurrentParameter++;
949 } else {
950 CaseInsensitive = FALSE;
951 }
952
953 if ((gUnicodeCollation->StriColl (
954 gUnicodeCollation,
955 gEfiShellParametersProtocol->Argv[1],
956 L"/s"
957 ) == 0) ||
958 (gUnicodeCollation->StriColl (
959 gUnicodeCollation,
960 gEfiShellParametersProtocol->Argv[2],
961 L"/s"
962 ) == 0) ||
963 ((gEfiShellParametersProtocol->Argc > 3) && (gUnicodeCollation->StriColl (
964 gUnicodeCollation,
965 gEfiShellParametersProtocol->Argv[3],
966 L"/s"
967 ) == 0)))
968 {
969 ForceString = TRUE;
970 CurrentParameter++;
971 } else {
972 ForceString = FALSE;
973 }
974
975 for ( ShellStatus = SHELL_SUCCESS, CurrentValue = FALSE, Ending = EndTagMax
976 ; CurrentParameter < gEfiShellParametersProtocol->Argc && ShellStatus == SHELL_SUCCESS
977 ; CurrentParameter++)
978 {
979 if (gUnicodeCollation->StriColl (
980 gUnicodeCollation,
981 gEfiShellParametersProtocol->Argv[CurrentParameter],
982 L"then"
983 ) == 0)
984 {
985 //
986 // we are at the then
987 //
988 if (CurrentParameter+1 != gEfiShellParametersProtocol->Argc) {
989 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_TEXT_AFTER_THEN), gShellLevel1HiiHandle, L"if");
990 ShellStatus = SHELL_INVALID_PARAMETER;
991 } else {
992 Status = PerformResultOperation (CurrentValue);
993 if (EFI_ERROR (Status)) {
994 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_AFTER_BAD), gShellLevel1HiiHandle, L"if", gEfiShellParametersProtocol->Argv[CurrentParameter]);
995 ShellStatus = SHELL_INVALID_PARAMETER;
996 }
997 }
998 } else {
999 PreviousEnding = Ending;
1000 //
1001 // build up the next statement for analysis
1002 //
1003 if (!BuildNextStatement (CurrentParameter, &EndParameter, &Ending)) {
1004 CurrentScriptFile = ShellCommandGetCurrentScriptFile ();
1005 ShellPrintHiiEx (
1006 -1,
1007 -1,
1008 NULL,
1009 STRING_TOKEN (STR_SYNTAX_NO_MATCHING),
1010 gShellLevel1HiiHandle,
1011 L"Then",
1012 L"If",
1013 CurrentScriptFile != NULL
1014 && CurrentScriptFile->CurrentCommand != NULL
1015 ? CurrentScriptFile->CurrentCommand->Line : 0
1016 );
1017 ShellStatus = SHELL_INVALID_PARAMETER;
1018 } else {
1019 //
1020 // Analyze the statement
1021 //
1022 Status = ProcessStatement (&CurrentValue, CurrentParameter, EndParameter, PreviousEnding, CaseInsensitive, ForceString);
1023 if (EFI_ERROR (Status)) {
1024 // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_STARTING), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[CurrentParameter]);
1025 ShellStatus = SHELL_INVALID_PARAMETER;
1026 } else {
1027 //
1028 // Optomize to get out of the loop early...
1029 //
1030 if (((Ending == EndTagOr) && CurrentValue) || ((Ending == EndTagAnd) && !CurrentValue)) {
1031 Status = PerformResultOperation (CurrentValue);
1032 if (EFI_ERROR (Status)) {
1033 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_AFTER_BAD), gShellLevel1HiiHandle, L"if", gEfiShellParametersProtocol->Argv[CurrentParameter]);
1034 ShellStatus = SHELL_INVALID_PARAMETER;
1035 }
1036
1037 break;
1038 }
1039 }
1040 }
1041
1042 if (ShellStatus == SHELL_SUCCESS) {
1043 CurrentParameter = EndParameter;
1044 //
1045 // Skip over the or or and parameter.
1046 //
1047 if ((Ending == EndTagOr) || (Ending == EndTagAnd)) {
1048 CurrentParameter++;
1049 }
1050 }
1051 }
1052 }
1053
1054 return (ShellStatus);
1055}
1056
1057/**
1058 Function for 'else' command.
1059
1060 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1061 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1062**/
1063SHELL_STATUS
1064EFIAPI
1065ShellCommandRunElse (
1066 IN EFI_HANDLE ImageHandle,
1067 IN EFI_SYSTEM_TABLE *SystemTable
1068 )
1069{
1070 EFI_STATUS Status;
1071 SCRIPT_FILE *CurrentScriptFile;
1072
1073 Status = CommandInit ();
1074 ASSERT_EFI_ERROR (Status);
1075
1076 if (gEfiShellParametersProtocol->Argc > 1) {
1077 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel1HiiHandle, L"if");
1078 return (SHELL_INVALID_PARAMETER);
1079 }
1080
1081 if (!gEfiShellProtocol->BatchIsActive ()) {
1082 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"Else");
1083 return (SHELL_UNSUPPORTED);
1084 }
1085
1086 CurrentScriptFile = ShellCommandGetCurrentScriptFile ();
1087 if (CurrentScriptFile == NULL) {
1088 return (SHELL_INVALID_PARAMETER);
1089 }
1090
1091 if (!MoveToTag (GetPreviousNode, L"if", L"endif", NULL, CurrentScriptFile, FALSE, TRUE, FALSE)) {
1092 ShellPrintHiiEx (
1093 -1,
1094 -1,
1095 NULL,
1096 STRING_TOKEN (STR_SYNTAX_NO_MATCHING),
1097 gShellLevel1HiiHandle,
1098 L"If",
1099 L"Else",
1100 CurrentScriptFile != NULL
1101 && CurrentScriptFile->CurrentCommand != NULL
1102 ? CurrentScriptFile->CurrentCommand->Line : 0
1103 );
1104 return (SHELL_DEVICE_ERROR);
1105 }
1106
1107 if (!MoveToTag (GetPreviousNode, L"if", L"else", NULL, CurrentScriptFile, FALSE, TRUE, FALSE)) {
1108 ShellPrintHiiEx (
1109 -1,
1110 -1,
1111 NULL,
1112 STRING_TOKEN (STR_SYNTAX_NO_MATCHING),
1113 gShellLevel1HiiHandle,
1114 L"If",
1115 L"Else",
1116 CurrentScriptFile != NULL
1117 && CurrentScriptFile->CurrentCommand != NULL
1118 ? CurrentScriptFile->CurrentCommand->Line : 0
1119 );
1120 return (SHELL_DEVICE_ERROR);
1121 }
1122
1123 if (!MoveToTag (GetNextNode, L"endif", L"if", NULL, CurrentScriptFile, FALSE, FALSE, FALSE)) {
1124 ShellPrintHiiEx (
1125 -1,
1126 -1,
1127 NULL,
1128 STRING_TOKEN (STR_SYNTAX_NO_MATCHING),
1129 gShellLevel1HiiHandle,
1130 L"EndIf",
1131 "Else",
1132 CurrentScriptFile != NULL
1133 && CurrentScriptFile->CurrentCommand != NULL
1134 ? CurrentScriptFile->CurrentCommand->Line : 0
1135 );
1136 return (SHELL_DEVICE_ERROR);
1137 }
1138
1139 return (SHELL_SUCCESS);
1140}
1141
1142/**
1143 Function for 'endif' command.
1144
1145 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1146 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1147**/
1148SHELL_STATUS
1149EFIAPI
1150ShellCommandRunEndIf (
1151 IN EFI_HANDLE ImageHandle,
1152 IN EFI_SYSTEM_TABLE *SystemTable
1153 )
1154{
1155 EFI_STATUS Status;
1156 SCRIPT_FILE *CurrentScriptFile;
1157
1158 Status = CommandInit ();
1159 ASSERT_EFI_ERROR (Status);
1160
1161 if (gEfiShellParametersProtocol->Argc > 1) {
1162 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel1HiiHandle, L"if");
1163 return (SHELL_INVALID_PARAMETER);
1164 }
1165
1166 if (!gEfiShellProtocol->BatchIsActive ()) {
1167 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"Endif");
1168 return (SHELL_UNSUPPORTED);
1169 }
1170
1171 CurrentScriptFile = ShellCommandGetCurrentScriptFile ();
1172 if (CurrentScriptFile == NULL) {
1173 return (SHELL_INVALID_PARAMETER);
1174 }
1175
1176 if (!MoveToTag (GetPreviousNode, L"if", L"endif", NULL, CurrentScriptFile, FALSE, TRUE, FALSE)) {
1177 ShellPrintHiiEx (
1178 -1,
1179 -1,
1180 NULL,
1181 STRING_TOKEN (STR_SYNTAX_NO_MATCHING),
1182 gShellLevel1HiiHandle,
1183 L"If",
1184 L"EndIf",
1185 CurrentScriptFile != NULL
1186 && CurrentScriptFile->CurrentCommand != NULL
1187 ? CurrentScriptFile->CurrentCommand->Line : 0
1188 );
1189 return (SHELL_DEVICE_ERROR);
1190 }
1191
1192 return (SHELL_SUCCESS);
1193}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette