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