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