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