]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/CodeTools/TianoTools/GenDepex/GenDepex.c
Restructuring for better separation of Tool packages.
[mirror_edk2.git] / Tools / CodeTools / 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 memset (Buffer, 0, FileSize + BUFFER_SIZE);
378 fread (Buffer, FileSize, 1, InFile);
379
380 Ptrx = Buffer;
381 Pend = Ptrx + FileSize - strlen (DEPENDENCY_END);
382 Index = FileSize;
383
384 NotDone = TRUE;
385 while ((Index--) && NotDone) {
386
387 if (strncmp (Pend, DEPENDENCY_END, strlen (DEPENDENCY_END)) == 0) {
388 NotDone = FALSE;
389 } else {
390 Pend--;
391 }
392 }
393
394 if (NotDone) {
395 printf ("Couldn't find end string %s\n", DEPENDENCY_END);
396
397 Results = (UINTN) fclose (InFile);
398 if (Results != 0) {
399 printf ("FCLOSE failed\n");
400 }
401
402 Results = (UINTN) fclose (OutFile);
403 if (Results != 0) {
404 printf ("FCLOSE failed\n");
405 }
406
407 free (Buffer);
408 free (EvaluationStack);
409
410 return EFI_INVALID_PARAMETER;
411 }
412
413 Index = FileSize;
414
415 NotDone = TRUE;
416 while ((Index--) && NotDone) {
417
418 if (strncmp (Ptrx, DEPENDENCY_START, strlen (DEPENDENCY_START)) == 0) {
419 Ptrx += sizeof (DEPENDENCY_START);
420 NotDone = FALSE;
421 //
422 // BUGBUG -- should Index be decremented by sizeof(DEPENDENCY_START)?
423 //
424 } else {
425 Ptrx++;
426 }
427 }
428
429 if (NotDone) {
430 printf ("Couldn't find start string %s\n", DEPENDENCY_START);
431
432 Results = (UINTN) fclose (InFile);
433 if (Results != 0) {
434 printf ("FCLOSE failed\n");
435 }
436
437 Results = (UINTN) fclose (OutFile);
438 if (Results != 0) {
439 printf ("FCLOSE failed\n");
440 }
441
442 free (Buffer);
443 free (EvaluationStack);
444
445 return EFI_INVALID_PARAMETER;
446 }
447 //
448 // validate the syntax of expression
449 //
450 if (!ParseDepex (Ptrx, Pend - Ptrx - 1)) {
451 printf ("The syntax of expression is wrong\n");
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 NotDone = TRUE;
470
471 while ((Index--) && NotDone) {
472
473 if (*Ptrx == ' ') {
474 Ptrx++;
475 } else if (*Ptrx == '\n' || *Ptrx == '\r') {
476 Ptrx++;
477 } else if (strncmp (Ptrx, OPERATOR_SOR, strlen (OPERATOR_SOR)) == 0) {
478 //
479 // Checks for some invalid dependencies
480 //
481 if (Before_Flag) {
482
483 printf ("A BEFORE operator was detected.\n");
484 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
485 return EFI_INVALID_PARAMETER;
486
487 } else if (After_Flag) {
488
489 printf ("An AFTER operator was detected.\n");
490 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
491 return EFI_INVALID_PARAMETER;
492
493 } else if (SOR_Flag) {
494
495 printf ("Another SOR operator was detected.\n");
496 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
497 return EFI_INVALID_PARAMETER;
498
499 } else if (Dep_Flag) {
500
501 printf ("The Schedule On Request - SOR operator must be the first operator following DEPENDENCY_START\n");
502 return EFI_INVALID_PARAMETER;
503
504 } else {
505 //
506 // BUGBUG - This was not in the spec but is in the CORE code
507 // An OPERATOR_SOR has to be first - following the DEPENDENCY_START
508 //
509 fputc (EFI_DEP_SOR, OutFile);
510 OutFileSize++;
511 Ptrx += sizeof (OPERATOR_SOR);
512 SOR_Flag = TRUE;
513
514 }
515 } else if (strncmp (Ptrx, OPERATOR_BEFORE, strlen (OPERATOR_BEFORE)) == 0) {
516 //
517 // Checks for some invalid dependencies
518 //
519 if (Before_Flag) {
520
521 printf ("Another BEFORE operator was detected.\n");
522 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
523 return EFI_INVALID_PARAMETER;
524
525 } else if (After_Flag) {
526
527 printf ("An AFTER operator was detected.\n");
528 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
529 return EFI_INVALID_PARAMETER;
530
531 } else if (SOR_Flag) {
532
533 printf ("A SOR operator was detected.\n");
534 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
535 return EFI_INVALID_PARAMETER;
536
537 } else if (Dep_Flag) {
538
539 printf ("The BEFORE operator must be the first operator following DEPENDENCY_START\n");
540 return EFI_INVALID_PARAMETER;
541
542 } else {
543 fputc (EFI_DEP_BEFORE, OutFile);
544 OutFileSize++;
545 Ptrx += sizeof (OPERATOR_BEFORE);
546 Before_Flag = TRUE;
547 }
548 } else if (strncmp (Ptrx, OPERATOR_AFTER, strlen (OPERATOR_AFTER)) == 0) {
549 //
550 // Checks for some invalid dependencies
551 //
552 if (Before_Flag) {
553
554 printf ("A BEFORE 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 (After_Flag) {
559
560 printf ("Another AFTER operator was detected.\n");
561 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
562 return EFI_INVALID_PARAMETER;
563
564 } else if (SOR_Flag) {
565
566 printf ("A SOR operator was detected.\n");
567 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
568 return EFI_INVALID_PARAMETER;
569
570 } else if (Dep_Flag) {
571
572 printf ("The AFTER operator must be the first operator following DEPENDENCY_START\n");
573 return EFI_INVALID_PARAMETER;
574
575 } else {
576 fputc (EFI_DEP_AFTER, OutFile);
577 OutFileSize++;
578 Ptrx += sizeof (OPERATOR_AFTER);
579 Dep_Flag = TRUE;
580 After_Flag = TRUE;
581 }
582 } else if (strncmp (Ptrx, OPERATOR_AND, strlen (OPERATOR_AND)) == 0) {
583 while (StackPtr != EvaluationStack) {
584 Opcode = PopOpCode ((VOID **) &StackPtr);
585 if (Opcode != DXE_DEP_LEFT_PARENTHESIS) {
586 fputc (Opcode, OutFile);
587 OutFileSize++;
588 } else {
589 PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS);
590 break;
591 }
592 }
593
594 PushOpCode ((VOID **) &StackPtr, EFI_DEP_AND);
595 Ptrx += sizeof (OPERATOR_AND);
596 Dep_Flag = TRUE;
597
598 } else if (strncmp (Ptrx, OPERATOR_OR, strlen (OPERATOR_OR)) == 0) {
599 while (StackPtr != EvaluationStack) {
600 Opcode = PopOpCode ((VOID **) &StackPtr);
601 if (Opcode != DXE_DEP_LEFT_PARENTHESIS) {
602 fputc (Opcode, OutFile);
603 OutFileSize++;
604 } else {
605 PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS);
606 break;
607 }
608 }
609
610 PushOpCode ((VOID **) &StackPtr, EFI_DEP_OR);
611 Ptrx += sizeof (OPERATOR_OR);
612 Dep_Flag = TRUE;
613
614 } else if (strncmp (Ptrx, OPERATOR_NOT, strlen (OPERATOR_NOT)) == 0) {
615 while (StackPtr != EvaluationStack) {
616 Opcode = PopOpCode ((VOID **) &StackPtr);
617 if (Opcode != DXE_DEP_LEFT_PARENTHESIS) {
618 fputc (Opcode, OutFile);
619 OutFileSize++;
620 } else {
621 PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS);
622 break;
623 }
624 }
625
626 PushOpCode ((VOID **) &StackPtr, EFI_DEP_NOT);
627 Ptrx += sizeof (OPERATOR_NOT);
628 Dep_Flag = TRUE;
629
630 } else if (*Ptrx == '\t') {
631
632 printf ("File contains tabs. This violates the coding standard\n");
633 return EFI_INVALID_PARAMETER;
634
635 } else if (*Ptrx == '\n') {
636 //
637 // Skip the newline character in the file
638 //
639 Ptrx++;
640
641 } else if (strncmp (Ptrx, OPERATOR_LEFT_PARENTHESIS, strlen (OPERATOR_LEFT_PARENTHESIS)) == 0) {
642 PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS);
643
644 Ptrx += strlen (OPERATOR_LEFT_PARENTHESIS);
645 Dep_Flag = TRUE;
646
647 } else if (strncmp (Ptrx, OPERATOR_RIGHT_PARENTHESIS, strlen (OPERATOR_RIGHT_PARENTHESIS)) == 0) {
648 while (StackPtr != EvaluationStack) {
649 Opcode = PopOpCode ((VOID **) &StackPtr);
650 if (Opcode != DXE_DEP_LEFT_PARENTHESIS) {
651 fputc (Opcode, OutFile);
652 OutFileSize++;
653 } else {
654 break;
655 }
656 }
657
658 Ptrx += strlen (OPERATOR_RIGHT_PARENTHESIS);
659 Dep_Flag = TRUE;
660
661 } else if (strncmp (Ptrx, OPERATOR_TRUE, strlen (OPERATOR_TRUE)) == 0) {
662
663 fputc (EFI_DEP_TRUE, OutFile);
664
665 OutFileSize++;
666
667 //
668 // OutFileSize += sizeof (EFI_DEP_TRUE);
669 //
670 Dep_Flag = TRUE;
671
672 Ptrx += strlen (OPERATOR_TRUE);
673
674 } else if (strncmp (Ptrx, OPERATOR_FALSE, strlen (OPERATOR_FALSE)) == 0) {
675
676 fputc (EFI_DEP_FALSE, OutFile);
677
678 OutFileSize++;
679
680 //
681 // OutFileSize += sizeof (EFI_DEP_FALSE);
682 //
683 Dep_Flag = TRUE;
684
685 Ptrx += strlen (OPERATOR_FALSE);
686
687 } else if (*Ptrx == '{') {
688 Ptrx++;
689
690 if (*Ptrx == ' ') {
691 Ptrx++;
692 }
693
694 {
695 int byte_index;
696 // This is an array of UINT32s. sscanf will trash memory
697 // if you try to read into a UINT8 with a %x formatter.
698 UINT32 Guid_Data4[8];
699
700 ArgCountParsed = sscanf (
701 Ptrx,
702 "%x, %x, %x, { %x, %x, %x, %x, %x, %x, %x, %x }",
703 &Guid.Data1,
704 &Guid.Data2,
705 &Guid.Data3,
706 &Guid_Data4[0],
707 &Guid_Data4[1],
708 &Guid_Data4[2],
709 &Guid_Data4[3],
710 &Guid_Data4[4],
711 &Guid_Data4[5],
712 &Guid_Data4[6],
713 &Guid_Data4[7]
714 );
715
716 // Now we can copy the 32 bit ints into the GUID.
717 for (byte_index=0; byte_index<8; byte_index++) {
718 Guid.Data4[byte_index] = (UINT8) Guid_Data4[byte_index];
719 }
720 }
721
722 if (ArgCountParsed != 11) {
723 printf ("We have found an illegal GUID\n");
724 printf ("Fix your depex\n");
725 exit (-1);
726 }
727
728 while (*Ptrx != '}') {
729 Ptrx++;
730 }
731
732 Ptrx++;
733 while (*Ptrx != '}') {
734 Ptrx++;
735 }
736 //
737 // Absorb the closing }
738 //
739 Ptrx++;
740
741 //
742 // Don't provide a PUSH Opcode for the Before and After case
743 //
744 if ((!Before_Flag) && (!After_Flag)) {
745 fputc (EFI_DEP_PUSH, OutFile);
746 OutFileSize++;
747 }
748
749 fwrite (&Guid, sizeof (EFI_GUID), 1, OutFile);
750
751 OutFileSize += sizeof (EFI_GUID);
752 Dep_Flag = TRUE;
753
754 } else if (strncmp (Ptrx, DEPENDENCY_END, strlen (DEPENDENCY_END)) == 0) {
755 NotDone = FALSE;
756 } else {
757 //
758 // Not a valid construct. Null terminate somewhere out there and
759 // print an error message.
760 //
761 *(Ptrx + 20) = 0;
762 printf (TOOL_NAME " ERROR: Unrecognized input at: \"%s\"...\n", Ptrx);
763 return EFI_INVALID_PARAMETER;
764 }
765 }
766 //
767 // DRAIN();
768 //
769 while (StackPtr != EvaluationStack) {
770 fputc (PopOpCode ((VOID **) &StackPtr), OutFile);
771 OutFileSize++;
772 }
773
774 if (OutFileSize == 0) {
775 printf ("Grammer contains no operators or constants\n");
776 return EFI_INVALID_PARAMETER;
777 }
778
779 fputc (EFI_DEP_END, OutFile);
780
781 OutFileSize++;
782
783 //
784 // Checks for invalid padding values
785 //
786 if (Padding < 0) {
787
788 printf ("The inputted padding value was %d\n", Padding);
789 printf ("The optional padding value can not be less than ZERO\n");
790 return EFI_INVALID_PARAMETER;
791
792 } else if (Padding > 0) {
793
794 while ((OutFileSize % Padding) != 0) {
795
796 fputc (' ', OutFile);
797 OutFileSize++;
798 }
799 }
800
801 Results = (UINTN) fclose (InFile);
802 if (Results != 0) {
803 printf ("FCLOSE failed\n");
804 }
805
806 Results = (UINTN) fclose (OutFile);
807 if (Results != 0) {
808 printf ("FCLOSE failed\n");
809 }
810
811 free (Buffer);
812 free (EvaluationStack);
813
814 return EFI_SUCCESS;
815 } // End GenerateDependencyExpression function
816
817 int
818 main (
819 IN UINTN argc,
820 IN CHAR8 *argv[]
821 )
822 /*++
823
824 Routine Description:
825
826 Parse user entries. Print some rudimentary help
827
828 Arguments:
829
830 argc The count of input arguments
831 argv The input arguments string array
832
833 Returns:
834
835 EFI_SUCCESS The function completed successfully.
836 EFI_INVALID_PARAMETER One of the input parameters was invalid or one of the parameters in the text file was invalid.
837 EFI_OUT_OF_RESOURCES Unable to allocate memory.
838 EFI_ABORTED Unable to open/create a file or a misc error.
839
840 --*/
841 // TODO: ] - add argument and description to function comment
842 {
843 FILE *OutFile;
844 FILE *InFile;
845 UINT8 Padding;
846 UINTN Index;
847 BOOLEAN Input_Flag;
848 BOOLEAN Output_Flag;
849 BOOLEAN Pad_Flag;
850
851 InFile = NULL;
852 OutFile = NULL;
853 Padding = 0;
854 Input_Flag = FALSE;
855 Output_Flag = FALSE;
856 Pad_Flag = FALSE;
857
858 if (argc < 5) {
859 printf ("Not enough arguments\n");
860 PrintGenDepexUsageInfo ();
861 return EFI_INVALID_PARAMETER;
862 }
863
864 for (Index = 1; Index < argc - 1; Index++) {
865
866 if ((strcmp (argv[Index], "-I") == 0) || (strcmp (argv[Index], "-i") == 0)) {
867
868 if (!Input_Flag) {
869
870 InFile = fopen (argv[Index + 1], "rb");
871 Input_Flag = TRUE;
872
873 } else {
874 printf ("GenDepex only allows one INPUT (-I) argument\n");
875 return EFI_INVALID_PARAMETER;
876 }
877
878 } else if ((strcmp (argv[Index], "-O") == 0) || (strcmp (argv[Index], "-o") == 0)) {
879
880 if (!Output_Flag) {
881
882 OutFile = fopen (argv[Index + 1], "wb");
883 Output_Flag = TRUE;
884
885 } else {
886 printf ("GenDepex only allows one OUTPUT (-O) argument\n");
887 return EFI_INVALID_PARAMETER;
888 }
889
890 } else if ((strcmp (argv[Index], "-P") == 0) || (strcmp (argv[Index], "-p") == 0)) {
891
892 if (!Pad_Flag) {
893
894 Padding = (UINT8) atoi (argv[Index + 1]);
895 Pad_Flag = TRUE;
896
897 } else {
898 printf ("GenDepex only allows one PADDING (-P) argument\n");
899 return EFI_INVALID_PARAMETER;
900 }
901 }
902 }
903
904 PrintGenDepexUtilityInfo ();
905
906 if (InFile == NULL) {
907 printf ("Can not open <INFILE> for reading.\n");
908 PrintGenDepexUsageInfo ();
909 return EFI_ABORTED;
910 }
911
912 if (OutFile == NULL) {
913 printf ("Can not open <OUTFILE> for writting.\n");
914 PrintGenDepexUsageInfo ();
915 return EFI_ABORTED;
916 }
917
918 return GenerateDependencyExpression (InFile, OutFile, Padding);
919 }