]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Sample/Tools/Source/GenDepex/GenDepex.c
Sync all bug fixes between EDK1.04 and EDK1.06 into EdkCompatibilityPkg.
[mirror_edk2.git] / EdkCompatibilityPkg / Sample / Tools / Source / GenDepex / GenDepex.c
1 /*++
2
3 Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 GenDepex.c
15
16 Abstract:
17
18 Generate Dependency Expression ("GenDepex")
19
20 Infix to Postfix Algorithm
21
22 This code has been scrubbed to be free of having any EFI core tree dependencies.
23 It should build in any environment that supports a standard C-library w/ string
24 operations and File I/O services.
25
26 As an example of usage, consider the following:
27
28 The input user file could be something like "Sample.DXS" whose contents are
29
30 #include "Tiano.h"
31
32 DEPENDENCY_START
33 NOT (DISK_IO_PROTOCOL AND SIMPLE_FILE_SYSTEM_PROTOCOL)
34 OR EFI_PXE_BASE_CODE_PROTOCOL
35 DEPENDENCY_END
36
37 This file is then washed through the C-preprocessor, viz.,
38
39 cl /EP Sample.DXS > Sample.TMP1
40
41 This yields the following file "Sample.TMP1" whose contents are
42
43 DEPENDENCY_START
44 NOT ({ 0xce345171, 0xba0b, 0x11d2, 0x8e, 0x4f, 0x0, 0xa0, 0xc9, 0x69, 0x72,
45 0x3b } AND { 0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69,
46 0x72, 0x3b }) OR { 0x03c4e603, 0xac28, 0x11d3, 0x9a, 0x2d, 0x00, 0x90, 0x27,
47 0x3f, 0xc1, 0x4d }
48 DEPENDENCY_END
49
50 This file, in turn, will be fed into the utility, viz.,
51
52 GenDepex Sample.TMP1 Sample.TMP2
53
54 With a file that is 55 bytes long:
55
56 55 bytes for the grammar binary
57 PUSH opcode - 1 byte
58 GUID Instance - 16 bytes
59 PUSH opcode - 1 byte
60 GUID Instance - 16 bytes
61 AND opcode - 1 byte
62 NOT opcode - 1 byte
63 PUSH opcode - 1 byte
64 GUID Instance - 16 bytes
65 OR opcode - 1 byte
66 END opcode - 1 byte
67
68 The file "Sample.TMP2" could be fed via a Section-builder utility
69 (GenSection) that would be used for the creation of a dependency
70 section file (.DPX) which in turn would be used by a generate FFS
71 utility (GenFfsFile) to produce a DXE driver/core (.DXE) or
72 a DXE application (.APP) file.
73
74 Complies with Tiano C Coding Standards Document, version 0.31, 12 Dec 2000.
75
76 --*/
77
78 #include "GenDepex.h"
79
80 //
81 // Utility Name
82 //
83 #define UTILITY_NAME "GenDepex"
84
85 //
86 // Utility version information
87 //
88 #define UTILITY_VERSION "v1.0"
89
90 extern
91 BOOLEAN
92 ParseDepex (
93 IN INT8 *Pbegin,
94 IN UINT32 length
95 );
96
97 VOID
98 PrintGenDepexUtilityInfo (
99 VOID
100 )
101 /*++
102
103 Routine Description:
104
105 Displays the standard utility information to SDTOUT.
106
107 Arguments:
108
109 None
110
111 Returns:
112
113 None
114
115 --*/
116 {
117 int Index;
118 const char *Str[] = {
119 UTILITY_NAME" "UTILITY_VERSION" - Intel Generate Dependency Expression Utility",
120 " Copyright (C), 1996 - 2008 Intel Corporation",
121
122 #if ( defined(UTILITY_BUILD) && defined(UTILITY_VENDOR) )
123 " Built from "UTILITY_BUILD", project of "UTILITY_VENDOR,
124 #endif
125 NULL
126 };
127 for (Index = 0; Str[Index] != NULL; Index++) {
128 fprintf (stdout, "%s\n", Str[Index]);
129 }
130 }
131
132 VOID
133 PrintGenDepexUsageInfo (
134 VOID
135 )
136 /*++
137
138 Routine Description:
139
140 Displays the utility usage syntax to STDOUT.
141
142 Arguments:
143
144 None
145
146 Returns:
147
148 None
149
150 --*/
151 {
152 int Index;
153 const char *Str[] = {
154 "",
155 "Usage:",
156 " "UTILITY_NAME" [OPTION]...",
157 "Options:",
158 " -I INFILE The input pre-processed dependency text files name",
159 " -O OUTFILE The output binary dependency files name",
160 " -P BOUNDARY The padding integer value to align the output file size",
161 NULL
162 };
163
164 PrintGenDepexUtilityInfo ();
165 for (Index = 0; Str[Index] != NULL; Index++) {
166 fprintf (stdout, "%s\n", Str[Index]);
167 }
168 }
169
170 DEPENDENCY_OPCODE
171 PopOpCode (
172 IN OUT VOID **Stack
173 )
174 /*++
175
176 Routine Description:
177
178 Pop an element from the Opcode stack.
179
180 Arguments:
181
182 Stack Current top of the OpCode stack location
183
184 Returns:
185
186 DEPENDENCY_OPCODE OpCode at the top of the OpCode stack.
187 Stack New top of the OpCode stack location
188
189
190 --*/
191 {
192 DEPENDENCY_OPCODE *OpCodePtr;
193
194 OpCodePtr = *Stack;
195 OpCodePtr--;
196 *Stack = OpCodePtr;
197 return *OpCodePtr;
198 }
199
200 VOID
201 PushOpCode (
202 IN OUT VOID **Stack,
203 IN DEPENDENCY_OPCODE OpCode
204 )
205 /*++
206
207 Routine Description:
208
209 Push an element onto the Opcode Stack
210
211 Arguments:
212
213 Stack Current top of the OpCode stack location
214 OpCode OpCode to push onto the stack
215
216 Returns:
217
218 Stack New top of the OpCode stack location
219
220 --*/
221 {
222 DEPENDENCY_OPCODE *OpCodePtr;
223
224 OpCodePtr = *Stack;
225 *OpCodePtr = OpCode;
226 OpCodePtr++;
227 *Stack = OpCodePtr;
228 }
229
230 EFI_STATUS
231 GenerateDependencyExpression (
232 IN FILE *InFile,
233 IN OUT FILE *OutFile,
234 IN UINT8 Padding OPTIONAL
235 )
236 /*++
237
238 Routine Description:
239
240 This takes the pre-compiled dependency text file and
241 converts it into a binary dependency file.
242
243 The BNF for the dependency expression is as follows
244 (from the DXE 1.0 Draft specification).
245
246 The inputted BNF grammar is thus:
247 <depex> ::= sor <dep> |
248 before GUID <dep> |
249 after GUID <dep> |
250 <bool>
251
252 <dep> ::= <bool> |
253
254 <bool> ::= <bool> and <term> |
255 <bool> or <term> |
256 <term>
257
258 <term> ::= not <factor> |
259 <factor>
260
261 <factor> ::= ( <bool> ) |
262 <term> <term> |
263 GUID |
264 <boolval>
265
266 <boolval> ::= true |
267 false
268
269 The outputed binary grammer is thus:
270 <depex> ::= sor <dep> |
271 before <depinst> <dep> |
272 after <depinst> <dep> |
273 <bool>
274
275 <dep> ::= <bool> |
276
277 <bool> ::= <bool> and <term> |
278 <bool> or <term> | <term>
279
280 <term> ::= not <factor> |
281 <factor>
282
283 <factor> ::= ( <bool> ) |
284 <term> <term> |
285 <boolval> |
286 <depinst> |
287 <termval>
288
289 <boolval> ::= true |
290 false
291
292 <depinst> ::= push GUID
293
294 <termval> ::= end
295
296 BugBug: A correct grammer is parsed correctly. A file that violates the
297 grammer may parse when it should generate an error. There is some
298 error checking and it covers most of the case when it's an include
299 of definition issue. An ill formed expresion may not be detected.
300
301 Arguments:
302
303 InFile - Input pre-compiled text file of the dependency expression.
304 This needs to be in ASCII.
305 The file pointer can not be NULL.
306
307 OutFile - Binary dependency file.
308 The file pointer can not be NULL.
309
310 Padding - OPTIONAL integer value to pad the output file to.
311
312
313 Returns:
314
315 EFI_SUCCESS The function completed successfully.
316 EFI_INVALID_PARAMETER One of the parameters in the text file was invalid.
317 EFI_OUT_OF_RESOURCES Unable to allocate memory.
318 EFI_ABORTED An misc error occurred.
319
320 --*/
321 {
322 INT8 *Ptrx;
323 INT8 *Pend;
324 INT8 *EvaluationStack;
325 INT8 *StackPtr;
326 INT8 *Buffer;
327 INT8 Line[LINESIZE];
328 UINTN Index;
329 UINTN OutFileSize;
330 UINTN FileSize;
331 UINTN Results;
332 BOOLEAN NotDone;
333 BOOLEAN Before_Flag;
334 BOOLEAN After_Flag;
335 BOOLEAN Dep_Flag;
336 BOOLEAN SOR_Flag;
337 EFI_GUID Guid;
338 UINTN ArgCountParsed;
339 DEPENDENCY_OPCODE Opcode;
340
341 Before_Flag = FALSE;
342 After_Flag = FALSE;
343 Dep_Flag = FALSE;
344 SOR_Flag = FALSE;
345
346 memset (Line, 0, LINESIZE);
347
348 OutFileSize = 0;
349
350 EvaluationStack = (INT8 *) malloc (EVAL_STACK_SIZE);
351
352 if (EvaluationStack != NULL) {
353 StackPtr = EvaluationStack;
354 } else {
355 printf ("Unable to allocate memory to EvaluationStack - Out of resources\n");
356 return EFI_OUT_OF_RESOURCES;
357 }
358
359 Results = (UINTN) fseek (InFile, 0, SEEK_END);
360
361 if (Results != 0) {
362 printf ("FSEEK failed - Aborted\n");
363 return EFI_ABORTED;
364 }
365
366 FileSize = ftell (InFile);
367
368 if (FileSize == -1L) {
369 printf ("FTELL failed - Aborted\n");
370 return EFI_ABORTED;
371 }
372
373 Buffer = (INT8 *) malloc (FileSize + BUFFER_SIZE);
374
375 if (Buffer == NULL) {
376 printf ("Unable to allocate memory to Buffer - Out of resources\n");
377 free (EvaluationStack);
378
379 Results = (UINTN) fclose (InFile);
380 if (Results != 0) {
381 printf ("FCLOSE failed\n");
382 }
383
384 Results = (UINTN) fclose (OutFile);
385 if (Results != 0) {
386 printf ("FCLOSE failed\n");
387 }
388
389 return EFI_OUT_OF_RESOURCES;
390 }
391
392 Results = (UINTN) fseek (InFile, 0, SEEK_SET);
393
394 if (Results != 0) {
395 printf ("FSEEK failed - Aborted\n");
396 return EFI_ABORTED;
397 }
398
399 fread (Buffer, FileSize, 1, InFile);
400
401 Ptrx = Buffer;
402 Pend = Ptrx + FileSize - strlen (DEPENDENCY_END);
403 Index = FileSize;
404
405 NotDone = TRUE;
406 while ((Index--) && NotDone) {
407
408 if (strncmp (Pend, DEPENDENCY_END, strlen (DEPENDENCY_END)) == 0) {
409 NotDone = FALSE;
410 } else {
411 Pend--;
412 }
413 }
414
415 if (NotDone) {
416 printf ("Couldn't find end string %s\n", DEPENDENCY_END);
417
418 Results = (UINTN) fclose (InFile);
419 if (Results != 0) {
420 printf ("FCLOSE failed\n");
421 }
422
423 Results = (UINTN) fclose (OutFile);
424 if (Results != 0) {
425 printf ("FCLOSE failed\n");
426 }
427
428 free (Buffer);
429 free (EvaluationStack);
430
431 return EFI_INVALID_PARAMETER;
432 }
433
434 Index = FileSize;
435
436 NotDone = TRUE;
437 while ((Index--) && NotDone) {
438
439 if (strncmp (Ptrx, DEPENDENCY_START, strlen (DEPENDENCY_START)) == 0) {
440 Ptrx += strlen (DEPENDENCY_START);
441 NotDone = FALSE;
442 //
443 // BUGBUG -- should Index be decremented by sizeof(DEPENDENCY_START)?
444 //
445 } else {
446 Ptrx++;
447 }
448 }
449
450 if (NotDone) {
451 printf ("Couldn't find start string %s\n", DEPENDENCY_START);
452
453 Results = (UINTN) fclose (InFile);
454 if (Results != 0) {
455 printf ("FCLOSE failed\n");
456 }
457
458 Results = (UINTN) fclose (OutFile);
459 if (Results != 0) {
460 printf ("FCLOSE failed\n");
461 }
462
463 free (Buffer);
464 free (EvaluationStack);
465
466 return EFI_INVALID_PARAMETER;
467 }
468 //
469 // validate the syntax of expression
470 //
471 if (!ParseDepex (Ptrx, Pend - Ptrx - 1)) {
472 printf ("The syntax of expression is wrong\n");
473
474 Results = (UINTN) fclose (InFile);
475 if (Results != 0) {
476 printf ("FCLOSE failed\n");
477 }
478
479 Results = (UINTN) fclose (OutFile);
480 if (Results != 0) {
481 printf ("FCLOSE failed\n");
482 }
483
484 free (Buffer);
485 free (EvaluationStack);
486
487 return EFI_INVALID_PARAMETER;
488 }
489
490 NotDone = TRUE;
491
492 while ((Index--) && NotDone) {
493
494 if (*Ptrx == ' ') {
495 Ptrx++;
496 } else if (*Ptrx == '\n' || *Ptrx == '\r') {
497 Ptrx++;
498 } else if (strncmp (Ptrx, OPERATOR_SOR, strlen (OPERATOR_SOR)) == 0) {
499 //
500 // Checks for some invalid dependencies
501 //
502 if (Before_Flag) {
503
504 printf ("A BEFORE operator was detected.\n");
505 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
506 return EFI_INVALID_PARAMETER;
507
508 } else if (After_Flag) {
509
510 printf ("An AFTER operator was detected.\n");
511 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
512 return EFI_INVALID_PARAMETER;
513
514 } else if (SOR_Flag) {
515
516 printf ("Another SOR operator was detected.\n");
517 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
518 return EFI_INVALID_PARAMETER;
519
520 } else if (Dep_Flag) {
521
522 printf ("The Schedule On Request - SOR operator must be the first operator following DEPENDENCY_START\n");
523 return EFI_INVALID_PARAMETER;
524
525 } else {
526 //
527 // BUGBUG - This was not in the spec but is in the CORE code
528 // An OPERATOR_SOR has to be first - following the DEPENDENCY_START
529 //
530 fputc (EFI_DEP_SOR, OutFile);
531 OutFileSize++;
532 Ptrx += strlen (OPERATOR_SOR);
533 SOR_Flag = TRUE;
534
535 }
536 } else if (strncmp (Ptrx, OPERATOR_BEFORE, strlen (OPERATOR_BEFORE)) == 0) {
537 //
538 // Checks for some invalid dependencies
539 //
540 if (Before_Flag) {
541
542 printf ("Another BEFORE operator was detected.\n");
543 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
544 return EFI_INVALID_PARAMETER;
545
546 } else if (After_Flag) {
547
548 printf ("An AFTER operator was detected.\n");
549 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
550 return EFI_INVALID_PARAMETER;
551
552 } else if (SOR_Flag) {
553
554 printf ("A SOR operator was detected.\n");
555 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
556 return EFI_INVALID_PARAMETER;
557
558 } else if (Dep_Flag) {
559
560 printf ("The BEFORE operator must be the first operator following DEPENDENCY_START\n");
561 return EFI_INVALID_PARAMETER;
562
563 } else {
564 fputc (EFI_DEP_BEFORE, OutFile);
565 OutFileSize++;
566 Ptrx += strlen (OPERATOR_BEFORE);
567 Before_Flag = TRUE;
568 }
569 } else if (strncmp (Ptrx, OPERATOR_AFTER, strlen (OPERATOR_AFTER)) == 0) {
570 //
571 // Checks for some invalid dependencies
572 //
573 if (Before_Flag) {
574
575 printf ("A BEFORE operator was detected.\n");
576 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
577 return EFI_INVALID_PARAMETER;
578
579 } else if (After_Flag) {
580
581 printf ("Another AFTER operator was detected.\n");
582 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
583 return EFI_INVALID_PARAMETER;
584
585 } else if (SOR_Flag) {
586
587 printf ("A SOR operator was detected.\n");
588 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
589 return EFI_INVALID_PARAMETER;
590
591 } else if (Dep_Flag) {
592
593 printf ("The AFTER operator must be the first operator following DEPENDENCY_START\n");
594 return EFI_INVALID_PARAMETER;
595
596 } else {
597 fputc (EFI_DEP_AFTER, OutFile);
598 OutFileSize++;
599 Ptrx += strlen (OPERATOR_AFTER);
600 Dep_Flag = TRUE;
601 After_Flag = TRUE;
602 }
603 } else if (strncmp (Ptrx, OPERATOR_AND, strlen (OPERATOR_AND)) == 0) {
604 while (StackPtr != EvaluationStack) {
605 Opcode = PopOpCode ((VOID **) &StackPtr);
606 if (Opcode != DXE_DEP_LEFT_PARENTHESIS) {
607 fputc (Opcode, OutFile);
608 OutFileSize++;
609 } else {
610 PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS);
611 break;
612 }
613 }
614
615 PushOpCode ((VOID **) &StackPtr, EFI_DEP_AND);
616 Ptrx += strlen (OPERATOR_AND);
617 Dep_Flag = TRUE;
618
619 } else if (strncmp (Ptrx, OPERATOR_OR, strlen (OPERATOR_OR)) == 0) {
620 while (StackPtr != EvaluationStack) {
621 Opcode = PopOpCode ((VOID **) &StackPtr);
622 if (Opcode != DXE_DEP_LEFT_PARENTHESIS) {
623 fputc (Opcode, OutFile);
624 OutFileSize++;
625 } else {
626 PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS);
627 break;
628 }
629 }
630
631 PushOpCode ((VOID **) &StackPtr, EFI_DEP_OR);
632 Ptrx += strlen (OPERATOR_OR);
633 Dep_Flag = TRUE;
634
635 } else if (strncmp (Ptrx, OPERATOR_NOT, strlen (OPERATOR_NOT)) == 0) {
636 while (StackPtr != EvaluationStack) {
637 Opcode = PopOpCode ((VOID **) &StackPtr);
638 if (Opcode != DXE_DEP_LEFT_PARENTHESIS) {
639 fputc (Opcode, OutFile);
640 OutFileSize++;
641 } else {
642 PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS);
643 break;
644 }
645 }
646
647 PushOpCode ((VOID **) &StackPtr, EFI_DEP_NOT);
648 Ptrx += strlen (OPERATOR_NOT);
649 Dep_Flag = TRUE;
650
651 } else if (*Ptrx == '\t') {
652
653 printf ("File contains tabs. This violates the coding standard\n");
654 return EFI_INVALID_PARAMETER;
655
656 } else if (*Ptrx == '\n') {
657 //
658 // Skip the newline character in the file
659 //
660 Ptrx++;
661
662 } else if (strncmp (Ptrx, OPERATOR_LEFT_PARENTHESIS, strlen (OPERATOR_LEFT_PARENTHESIS)) == 0) {
663 PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS);
664
665 Ptrx += strlen (OPERATOR_LEFT_PARENTHESIS);
666 Dep_Flag = TRUE;
667
668 } else if (strncmp (Ptrx, OPERATOR_RIGHT_PARENTHESIS, strlen (OPERATOR_RIGHT_PARENTHESIS)) == 0) {
669 while (StackPtr != EvaluationStack) {
670 Opcode = PopOpCode ((VOID **) &StackPtr);
671 if (Opcode != DXE_DEP_LEFT_PARENTHESIS) {
672 fputc (Opcode, OutFile);
673 OutFileSize++;
674 } else {
675 break;
676 }
677 }
678
679 Ptrx += strlen (OPERATOR_RIGHT_PARENTHESIS);
680 Dep_Flag = TRUE;
681
682 } else if (strncmp (Ptrx, OPERATOR_TRUE, strlen (OPERATOR_TRUE)) == 0) {
683
684 fputc (EFI_DEP_TRUE, OutFile);
685
686 OutFileSize++;
687
688 //
689 // OutFileSize += sizeof (EFI_DEP_TRUE);
690 //
691 Dep_Flag = TRUE;
692
693 Ptrx += strlen (OPERATOR_TRUE);
694
695 } else if (strncmp (Ptrx, OPERATOR_FALSE, strlen (OPERATOR_FALSE)) == 0) {
696
697 fputc (EFI_DEP_FALSE, OutFile);
698
699 OutFileSize++;
700
701 //
702 // OutFileSize += sizeof (EFI_DEP_FALSE);
703 //
704 Dep_Flag = TRUE;
705
706 Ptrx += strlen (OPERATOR_FALSE);
707
708 } else if (*Ptrx == '{') {
709 Ptrx++;
710
711 if (*Ptrx == ' ') {
712 Ptrx++;
713 }
714
715 ArgCountParsed = sscanf (
716 Ptrx,
717 "%x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x",
718 &Guid.Data1,
719 &Guid.Data2,
720 &Guid.Data3,
721 &Guid.Data4[0],
722 &Guid.Data4[1],
723 &Guid.Data4[2],
724 &Guid.Data4[3],
725 &Guid.Data4[4],
726 &Guid.Data4[5],
727 &Guid.Data4[6],
728 &Guid.Data4[7]
729 );
730
731 if (ArgCountParsed != 11) {
732 printf ("We have found an illegal GUID\n");
733 printf ("Fix your depex\n");
734 exit (-1);
735 }
736
737 while (*Ptrx != '}') {
738 Ptrx++;
739 }
740 //
741 // Absorb the closing }
742 //
743 Ptrx++;
744
745 //
746 // Don't provide a PUSH Opcode for the Before and After case
747 //
748 if ((!Before_Flag) && (!After_Flag)) {
749 fputc (EFI_DEP_PUSH, OutFile);
750 OutFileSize++;
751 }
752
753 fwrite (&Guid, sizeof (EFI_GUID), 1, OutFile);
754
755 OutFileSize += sizeof (EFI_GUID);
756 Dep_Flag = TRUE;
757
758 } else if (strncmp (Ptrx, DEPENDENCY_END, strlen (DEPENDENCY_END)) == 0) {
759 NotDone = FALSE;
760 } else {
761 //
762 // Not a valid construct. Null terminate somewhere out there and
763 // print an error message.
764 //
765 *(Ptrx + 20) = 0;
766 printf (UTILITY_NAME" ERROR: Unrecognized input at: \"%s\"...\n", Ptrx);
767 return EFI_INVALID_PARAMETER;
768 }
769 }
770 //
771 // DRAIN();
772 //
773 while (StackPtr != EvaluationStack) {
774 fputc (PopOpCode ((VOID **) &StackPtr), OutFile);
775 OutFileSize++;
776 }
777
778 if (OutFileSize == 0) {
779 printf ("Grammer contains no operators or constants\n");
780 return EFI_INVALID_PARAMETER;
781 }
782
783 fputc (EFI_DEP_END, OutFile);
784
785 OutFileSize++;
786
787 //
788 // Checks for invalid padding values
789 //
790 if (Padding < 0) {
791
792 printf ("The inputted padding value was %d\n", Padding);
793 printf ("The optional padding value can not be less than ZERO\n");
794 return EFI_INVALID_PARAMETER;
795
796 } else if (Padding > 0) {
797
798 while ((OutFileSize % Padding) != 0) {
799
800 fputc (' ', OutFile);
801 OutFileSize++;
802 }
803 }
804
805 Results = (UINTN) fclose (InFile);
806 if (Results != 0) {
807 printf ("FCLOSE failed\n");
808 }
809
810 Results = (UINTN) fclose (OutFile);
811 if (Results != 0) {
812 printf ("FCLOSE failed\n");
813 }
814
815 free (Buffer);
816 free (EvaluationStack);
817
818 return EFI_SUCCESS;
819 } // End GenerateDependencyExpression function
820
821 EFI_STATUS
822 main (
823 IN UINTN argc,
824 IN CHAR8 *argv[]
825 )
826 /*++
827
828 Routine Description:
829
830 Parse user entries. Print some rudimentary help
831
832 Arguments:
833
834 argc The count of input arguments
835 argv The input arguments string array
836
837 Returns:
838
839 EFI_SUCCESS The function completed successfully.
840 EFI_INVALID_PARAMETER One of the input parameters was invalid or one of the parameters in the text file was invalid.
841 EFI_OUT_OF_RESOURCES Unable to allocate memory.
842 EFI_ABORTED Unable to open/create a file or a misc error.
843
844 --*/
845 // TODO: ] - add argument and description to function comment
846 {
847 FILE *OutFile;
848 FILE *InFile;
849 UINT8 Padding;
850 UINTN Index;
851 BOOLEAN Input_Flag;
852 BOOLEAN Output_Flag;
853 BOOLEAN Pad_Flag;
854
855 InFile = NULL;
856 OutFile = NULL;
857 Padding = 0;
858 Input_Flag = FALSE;
859 Output_Flag = FALSE;
860 Pad_Flag = FALSE;
861
862 //
863 // Output the calling arguments
864 //
865 //printf ("\n\n");
866 //for (Index = 0; Index < argc; Index++) {
867 // printf ("%s ", argv[Index]);
868 //}
869 //
870 //printf ("\n\n");
871
872 if (argc < 5) {
873 printf ("Not enough arguments\n");
874 PrintGenDepexUsageInfo ();
875 return EFI_INVALID_PARAMETER;
876 }
877
878 for (Index = 1; Index < argc - 1; Index++) {
879
880 if ((strcmp (argv[Index], "-I") == 0) || (strcmp (argv[Index], "-i") == 0)) {
881
882 if (!Input_Flag) {
883
884 InFile = fopen (argv[Index + 1], "rb");
885 Input_Flag = TRUE;
886
887 } else {
888 printf ("GenDepex only allows one INPUT (-I) argument\n");
889 return EFI_INVALID_PARAMETER;
890 }
891
892 } else if ((strcmp (argv[Index], "-O") == 0) || (strcmp (argv[Index], "-o") == 0)) {
893
894 if (!Output_Flag) {
895
896 OutFile = fopen (argv[Index + 1], "wb");
897 Output_Flag = TRUE;
898
899 } else {
900 printf ("GenDepex only allows one OUTPUT (-O) argument\n");
901 return EFI_INVALID_PARAMETER;
902 }
903
904 } else if ((strcmp (argv[Index], "-P") == 0) || (strcmp (argv[Index], "-p") == 0)) {
905
906 if (!Pad_Flag) {
907
908 Padding = (UINT8) atoi (argv[Index + 1]);
909 Pad_Flag = TRUE;
910
911 } else {
912 printf ("GenDepex only allows one PADDING (-P) argument\n");
913 return EFI_INVALID_PARAMETER;
914 }
915 }
916 }
917
918 PrintGenDepexUtilityInfo ();
919
920 if (InFile == NULL) {
921 printf ("Can not open <INFILE> for reading.\n");
922 PrintGenDepexUsageInfo ();
923 return EFI_ABORTED;
924 }
925
926 if (OutFile == NULL) {
927 printf ("Can not open <OUTFILE> for writting.\n");
928 PrintGenDepexUsageInfo ();
929 return EFI_ABORTED;
930 }
931
932 return GenerateDependencyExpression (InFile, OutFile, Padding);
933 }