]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Sample/Tools/Source/GenDepex/GenDepex.c
Add in the 1st version of ECP.
[mirror_edk2.git] / EdkCompatibilityPkg / Sample / Tools / 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 BOOLEAN
84 ParseDepex (
85 IN INT8 *Pbegin,
86 IN UINT32 length
87 );
88
89 VOID
90 PrintGenDepexUtilityInfo (
91 VOID
92 )
93 /*++
94
95 Routine Description:
96
97 Displays the standard utility information to SDTOUT.
98
99 Arguments:
100
101 None
102
103 Returns:
104
105 None
106
107 --*/
108 {
109 printf (
110 "%s, Tiano Dependency Expression Generation Utility. Version %d.%d.\n",
111 UTILITY_NAME,
112 UTILITY_MAJOR_VERSION,
113 UTILITY_MINOR_VERSION
114 );
115 printf ("Copyright (C) 1996-2002 Intel Corporation. All rights reserved.\n\n");
116 }
117
118 VOID
119 PrintGenDepexUsageInfo (
120 VOID
121 )
122 /*++
123
124 Routine Description:
125
126 Displays the utility usage syntax to STDOUT.
127
128 Arguments:
129
130 None
131
132 Returns:
133
134 None
135
136 --*/
137 {
138 printf (
139 "Usage: %s -I <INFILE> -O <OUTFILE> [-P <Optional Boundary for padding up>] \n",
140 UTILITY_NAME
141 );
142 printf (" Where:\n");
143 printf (" <INFILE> is the input pre-processed dependency text files name.\n");
144 printf (" <OUTFILE> 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 UINT8 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 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 += strlen (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 += strlen (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 += strlen (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 += strlen (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 += strlen (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 += strlen (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 += strlen (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 ArgCountParsed = sscanf (
695 Ptrx,
696 "%x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x",
697 &Guid.Data1,
698 &Guid.Data2,
699 &Guid.Data3,
700 &Guid.Data4[0],
701 &Guid.Data4[1],
702 &Guid.Data4[2],
703 &Guid.Data4[3],
704 &Guid.Data4[4],
705 &Guid.Data4[5],
706 &Guid.Data4[6],
707 &Guid.Data4[7]
708 );
709
710 if (ArgCountParsed != 11) {
711 printf ("We have found an illegal GUID\n");
712 printf ("Fix your depex\n");
713 exit (-1);
714 }
715
716 while (*Ptrx != '}') {
717 Ptrx++;
718 }
719 //
720 // Absorb the closing }
721 //
722 Ptrx++;
723
724 //
725 // Don't provide a PUSH Opcode for the Before and After case
726 //
727 if ((!Before_Flag) && (!After_Flag)) {
728 fputc (EFI_DEP_PUSH, OutFile);
729 OutFileSize++;
730 }
731
732 fwrite (&Guid, sizeof (EFI_GUID), 1, OutFile);
733
734 OutFileSize += sizeof (EFI_GUID);
735 Dep_Flag = TRUE;
736
737 } else if (strncmp (Ptrx, DEPENDENCY_END, strlen (DEPENDENCY_END)) == 0) {
738 NotDone = FALSE;
739 } else {
740 //
741 // Not a valid construct. Null terminate somewhere out there and
742 // print an error message.
743 //
744 *(Ptrx + 20) = 0;
745 printf (TOOL_NAME " ERROR: Unrecognized input at: \"%s\"...\n", Ptrx);
746 return EFI_INVALID_PARAMETER;
747 }
748 }
749 //
750 // DRAIN();
751 //
752 while (StackPtr != EvaluationStack) {
753 fputc (PopOpCode ((VOID **) &StackPtr), OutFile);
754 OutFileSize++;
755 }
756
757 if (OutFileSize == 0) {
758 printf ("Grammer contains no operators or constants\n");
759 return EFI_INVALID_PARAMETER;
760 }
761
762 fputc (EFI_DEP_END, OutFile);
763
764 OutFileSize++;
765
766 //
767 // Checks for invalid padding values
768 //
769 if (Padding < 0) {
770
771 printf ("The inputted padding value was %d\n", Padding);
772 printf ("The optional padding value can not be less than ZERO\n");
773 return EFI_INVALID_PARAMETER;
774
775 } else if (Padding > 0) {
776
777 while ((OutFileSize % Padding) != 0) {
778
779 fputc (' ', OutFile);
780 OutFileSize++;
781 }
782 }
783
784 Results = (UINTN) fclose (InFile);
785 if (Results != 0) {
786 printf ("FCLOSE failed\n");
787 }
788
789 Results = (UINTN) fclose (OutFile);
790 if (Results != 0) {
791 printf ("FCLOSE failed\n");
792 }
793
794 free (Buffer);
795 free (EvaluationStack);
796
797 return EFI_SUCCESS;
798 } // End GenerateDependencyExpression function
799
800 EFI_STATUS
801 main (
802 IN UINTN argc,
803 IN CHAR8 *argv[]
804 )
805 /*++
806
807 Routine Description:
808
809 Parse user entries. Print some rudimentary help
810
811 Arguments:
812
813 argc The count of input arguments
814 argv The input arguments string array
815
816 Returns:
817
818 EFI_SUCCESS The function completed successfully.
819 EFI_INVALID_PARAMETER One of the input parameters was invalid or one of the parameters in the text file was invalid.
820 EFI_OUT_OF_RESOURCES Unable to allocate memory.
821 EFI_ABORTED Unable to open/create a file or a misc error.
822
823 --*/
824 // TODO: ] - add argument and description to function comment
825 {
826 FILE *OutFile;
827 FILE *InFile;
828 UINT8 Padding;
829 UINTN Index;
830 BOOLEAN Input_Flag;
831 BOOLEAN Output_Flag;
832 BOOLEAN Pad_Flag;
833
834 InFile = NULL;
835 OutFile = NULL;
836 Padding = 0;
837 Input_Flag = FALSE;
838 Output_Flag = FALSE;
839 Pad_Flag = FALSE;
840
841 //
842 // Output the calling arguments
843 //
844 printf ("\n\n");
845 for (Index = 0; Index < argc; Index++) {
846 printf ("%s ", argv[Index]);
847 }
848
849 printf ("\n\n");
850
851 if (argc < 5) {
852 printf ("Not enough arguments\n");
853 PrintGenDepexUsageInfo ();
854 return EFI_INVALID_PARAMETER;
855 }
856
857 for (Index = 1; Index < argc - 1; Index++) {
858
859 if ((strcmp (argv[Index], "-I") == 0) || (strcmp (argv[Index], "-i") == 0)) {
860
861 if (!Input_Flag) {
862
863 InFile = fopen (argv[Index + 1], "rb");
864 Input_Flag = TRUE;
865
866 } else {
867 printf ("GenDepex only allows one INPUT (-I) argument\n");
868 return EFI_INVALID_PARAMETER;
869 }
870
871 } else if ((strcmp (argv[Index], "-O") == 0) || (strcmp (argv[Index], "-o") == 0)) {
872
873 if (!Output_Flag) {
874
875 OutFile = fopen (argv[Index + 1], "wb");
876 Output_Flag = TRUE;
877
878 } else {
879 printf ("GenDepex only allows one OUTPUT (-O) argument\n");
880 return EFI_INVALID_PARAMETER;
881 }
882
883 } else if ((strcmp (argv[Index], "-P") == 0) || (strcmp (argv[Index], "-p") == 0)) {
884
885 if (!Pad_Flag) {
886
887 Padding = (UINT8) atoi (argv[Index + 1]);
888 Pad_Flag = TRUE;
889
890 } else {
891 printf ("GenDepex only allows one PADDING (-P) argument\n");
892 return EFI_INVALID_PARAMETER;
893 }
894 }
895 }
896
897 PrintGenDepexUtilityInfo ();
898
899 if (InFile == NULL) {
900 printf ("Can not open <INFILE> for reading.\n");
901 PrintGenDepexUsageInfo ();
902 return EFI_ABORTED;
903 }
904
905 if (OutFile == NULL) {
906 printf ("Can not open <OUTFILE> for writting.\n");
907 PrintGenDepexUsageInfo ();
908 return EFI_ABORTED;
909 }
910
911 return GenerateDependencyExpression (InFile, OutFile, Padding);
912 }