]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/TianoTools/GenDepex/GenDepex.c
Remove warning message in MAC GCC tool build
[mirror_edk2.git] / Tools / Source / TianoTools / GenDepex / GenDepex.c
CommitLineData
878ddf1f 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
9776330c 212 IN INT8 Padding OPTIONAL\r
878ddf1f 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
8d3adb74 693 {\r
694 int byte_index;\r
695 // This is an array of UINT32s. sscanf will trash memory\r
696 // if you try to read into a UINT8 with a %x formatter.\r
697 UINT32 Guid_Data4[8];\r
698\r
699 ArgCountParsed = sscanf (\r
700 Ptrx,\r
701 "%x, %x, %x, { %x, %x, %x, %x, %x, %x, %x, %x }",\r
702 &Guid.Data1,\r
703 &Guid.Data2,\r
704 &Guid.Data3,\r
705 &Guid_Data4[0],\r
706 &Guid_Data4[1],\r
707 &Guid_Data4[2],\r
708 &Guid_Data4[3],\r
709 &Guid_Data4[4],\r
710 &Guid_Data4[5],\r
711 &Guid_Data4[6],\r
712 &Guid_Data4[7]\r
713 );\r
714 \r
715 // Now we can copy the 32 bit ints into the GUID.\r
716 for (byte_index=0; byte_index<8; byte_index++) {\r
717 Guid.Data4[byte_index] = (UINT8) Guid_Data4[byte_index];\r
718 }\r
719 }\r
878ddf1f 720\r
721 if (ArgCountParsed != 11) {\r
722 printf ("We have found an illegal GUID\n");\r
723 printf ("Fix your depex\n");\r
724 exit (-1);\r
725 }\r
726\r
727 while (*Ptrx != '}') {\r
728 Ptrx++;\r
729 }\r
730\r
ce53a8c3 731 Ptrx++;\r
878ddf1f 732 while (*Ptrx != '}') {\r
733 Ptrx++;\r
734 }\r
ce53a8c3 735 //\r
878ddf1f 736 // Absorb the closing }\r
737 //\r
738 Ptrx++;\r
739\r
740 //\r
741 // Don't provide a PUSH Opcode for the Before and After case\r
742 //\r
743 if ((!Before_Flag) && (!After_Flag)) {\r
744 fputc (EFI_DEP_PUSH, OutFile);\r
745 OutFileSize++;\r
746 }\r
747\r
748 fwrite (&Guid, sizeof (EFI_GUID), 1, OutFile);\r
749\r
750 OutFileSize += sizeof (EFI_GUID);\r
751 Dep_Flag = TRUE;\r
752\r
753 } else if (strncmp (Ptrx, DEPENDENCY_END, strlen (DEPENDENCY_END)) == 0) {\r
754 NotDone = FALSE;\r
755 } else {\r
756 //\r
757 // Not a valid construct. Null terminate somewhere out there and\r
758 // print an error message.\r
759 //\r
760 *(Ptrx + 20) = 0;\r
761 printf (TOOL_NAME " ERROR: Unrecognized input at: \"%s\"...\n", Ptrx);\r
762 return EFI_INVALID_PARAMETER;\r
763 }\r
764 }\r
765 //\r
766 // DRAIN();\r
767 //\r
768 while (StackPtr != EvaluationStack) {\r
769 fputc (PopOpCode ((VOID **) &StackPtr), OutFile);\r
770 OutFileSize++;\r
771 }\r
772\r
773 if (OutFileSize == 0) {\r
774 printf ("Grammer contains no operators or constants\n");\r
775 return EFI_INVALID_PARAMETER;\r
776 }\r
777\r
778 fputc (EFI_DEP_END, OutFile);\r
779\r
780 OutFileSize++;\r
781\r
782 //\r
783 // Checks for invalid padding values\r
784 //\r
785 if (Padding < 0) {\r
786\r
787 printf ("The inputted padding value was %d\n", Padding);\r
788 printf ("The optional padding value can not be less than ZERO\n");\r
789 return EFI_INVALID_PARAMETER;\r
790\r
791 } else if (Padding > 0) {\r
792\r
793 while ((OutFileSize % Padding) != 0) {\r
794\r
795 fputc (' ', OutFile);\r
796 OutFileSize++;\r
797 }\r
798 }\r
799\r
800 Results = (UINTN) fclose (InFile);\r
801 if (Results != 0) {\r
802 printf ("FCLOSE failed\n");\r
803 }\r
804\r
805 Results = (UINTN) fclose (OutFile);\r
806 if (Results != 0) {\r
807 printf ("FCLOSE failed\n");\r
808 }\r
809\r
810 free (Buffer);\r
811 free (EvaluationStack);\r
812\r
813 return EFI_SUCCESS;\r
814} // End GenerateDependencyExpression function\r
815\r
816int\r
817main (\r
818 IN UINTN argc,\r
819 IN CHAR8 *argv[]\r
820 )\r
821/*++\r
822\r
823Routine Description:\r
824\r
825 Parse user entries. Print some rudimentary help\r
826\r
827Arguments:\r
828\r
829 argc The count of input arguments\r
830 argv The input arguments string array\r
831\r
832Returns:\r
833\r
834 EFI_SUCCESS The function completed successfully.\r
835 EFI_INVALID_PARAMETER One of the input parameters was invalid or one of the parameters in the text file was invalid.\r
836 EFI_OUT_OF_RESOURCES Unable to allocate memory.\r
837 EFI_ABORTED Unable to open/create a file or a misc error.\r
838\r
839--*/\r
840// TODO: ] - add argument and description to function comment\r
841{\r
842 FILE *OutFile;\r
843 FILE *InFile;\r
844 UINT8 Padding;\r
845 UINTN Index;\r
846 BOOLEAN Input_Flag;\r
847 BOOLEAN Output_Flag;\r
848 BOOLEAN Pad_Flag;\r
849\r
850 InFile = NULL;\r
851 OutFile = NULL;\r
852 Padding = 0;\r
853 Input_Flag = FALSE;\r
854 Output_Flag = FALSE;\r
855 Pad_Flag = FALSE;\r
856\r
878ddf1f 857 if (argc < 5) {\r
858 printf ("Not enough arguments\n");\r
859 PrintGenDepexUsageInfo ();\r
860 return EFI_INVALID_PARAMETER;\r
861 }\r
862\r
863 for (Index = 1; Index < argc - 1; Index++) {\r
864\r
865 if ((strcmp (argv[Index], "-I") == 0) || (strcmp (argv[Index], "-i") == 0)) {\r
866\r
867 if (!Input_Flag) {\r
868\r
869 InFile = fopen (argv[Index + 1], "rb");\r
870 Input_Flag = TRUE;\r
871\r
872 } else {\r
873 printf ("GenDepex only allows one INPUT (-I) argument\n");\r
874 return EFI_INVALID_PARAMETER;\r
875 }\r
876\r
877 } else if ((strcmp (argv[Index], "-O") == 0) || (strcmp (argv[Index], "-o") == 0)) {\r
878\r
879 if (!Output_Flag) {\r
880\r
881 OutFile = fopen (argv[Index + 1], "wb");\r
882 Output_Flag = TRUE;\r
883\r
884 } else {\r
885 printf ("GenDepex only allows one OUTPUT (-O) argument\n");\r
886 return EFI_INVALID_PARAMETER;\r
887 }\r
888\r
889 } else if ((strcmp (argv[Index], "-P") == 0) || (strcmp (argv[Index], "-p") == 0)) {\r
890\r
891 if (!Pad_Flag) {\r
892\r
893 Padding = (UINT8) atoi (argv[Index + 1]);\r
894 Pad_Flag = TRUE;\r
895\r
896 } else {\r
897 printf ("GenDepex only allows one PADDING (-P) argument\n");\r
898 return EFI_INVALID_PARAMETER;\r
899 }\r
900 }\r
901 }\r
902\r
903 PrintGenDepexUtilityInfo ();\r
904\r
905 if (InFile == NULL) {\r
906 printf ("Can not open <INFILE> for reading.\n");\r
907 PrintGenDepexUsageInfo ();\r
908 return EFI_ABORTED;\r
909 }\r
910\r
911 if (OutFile == NULL) {\r
912 printf ("Can not open <OUTFILE> for writting.\n");\r
913 PrintGenDepexUsageInfo ();\r
914 return EFI_ABORTED;\r
915 }\r
916\r
917 return GenerateDependencyExpression (InFile, OutFile, Padding);\r
918}\r