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