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