]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrCompiler.cpp
1) Sync EdkCompatibilityPkg with EDK 1.04. The changes includes:
[mirror_edk2.git] / EdkCompatibilityPkg / Sample / Tools / Source / UefiVfrCompile / VfrCompiler.cpp
CommitLineData
95d675b5 1#include "stdio.h"\r
2#include "string.h"\r
3#include "process.h"\r
4#include "VfrCompiler.h"\r
5\r
6\r
7VOID\r
8CVfrCompiler::SET_RUN_STATUS (\r
9 IN COMPILER_RUN_STATUS Status\r
10 )\r
11{\r
12 mRunStatus = Status;\r
13}\r
14\r
15BOOLEAN\r
16CVfrCompiler::IS_RUN_STATUS (\r
17 IN COMPILER_RUN_STATUS Status\r
18 )\r
19{\r
20 return mRunStatus == Status;\r
21}\r
22\r
23VOID\r
24CVfrCompiler::OptionInitialization (\r
25 IN INT32 Argc, \r
26 IN INT8 **Argv\r
27 )\r
28{\r
29 INT32 Index;\r
30\r
31 mOptions.VfrFileName[0] = '\0';\r
32 mOptions.RecordListFile[0] = '\0';\r
33 mOptions.CreateRecordListFile = FALSE;\r
34 mOptions.CreateIfrPkgFile = FALSE;\r
35 mOptions.PkgOutputFileName[0] = '\0';\r
36 mOptions.COutputFileName[0] = '\0';\r
37 mOptions.OutputDirectory[0] = '\0';\r
38 mOptions.PreprocessorOutputFileName[0] = '\0';\r
39 mOptions.VfrBaseFileName[0] = '\0';\r
40 mOptions.IncludePaths = NULL;\r
41 mOptions.CPreprocessorOptions = NULL;\r
42\r
43 for (Index = 1; (Index < Argc) && (Argv[Index][0] == '-'); Index++) {\r
44 if ((_stricmp(Argv[Index], "-?") == 0) || (_stricmp(Argv[Index], "-h") == 0)) {\r
45 Usage ();\r
46 SET_RUN_STATUS (STATUS_DEAD);\r
47 return;\r
48 } else if (_stricmp(Argv[Index], "-l") == 0) {\r
49 mOptions.CreateRecordListFile = TRUE;\r
50 gCIfrRecordInfoDB.TurnOn ();\r
51 } else if (_stricmp(Argv[Index], "-i") == 0) {\r
52 Index++;\r
53 if ((Index >= Argc) || (Argv[Index][0] == '-')) {\r
54 printf ("%s -i - missing path argument\n", PROGRAM_NAME);\r
55 goto Fail;\r
56 }\r
57\r
58 AppendIncludePath(Argv[Index]);\r
59 } else if (_stricmp(Argv[Index], "-od") == 0) {\r
60 Index++;\r
61 if ((Index >= Argc) || (Argv[Index][0] == '-')) {\r
62 printf ("%s -od - missing output directory name\n", PROGRAM_NAME);\r
63 goto Fail;\r
64 }\r
65 strcpy (mOptions.OutputDirectory, Argv[Index]);\r
66 } else if (_stricmp(Argv[Index], "-ibin") == 0) {\r
67 mOptions.CreateIfrPkgFile = TRUE;\r
68 } else if (_stricmp(Argv[Index], "-nostrings") == 0) {\r
69 } else if (_stricmp(Argv[Index], "-ppflag") == 0) {\r
70 Index++;\r
71 if ((Index >= Argc) || (Argv[Index][0] == '-')) {\r
72 printf ("%s -od - missing C-preprocessor argument\n", PROGRAM_NAME);\r
73 goto Fail;\r
74 }\r
75\r
76 AppendCPreprocessorOptions (Argv[Index]);\r
77 } else {\r
78 printf ("%s unrecognized option %s\n", PROGRAM_NAME, Argv[Index]);\r
79 Usage ();\r
80 goto Fail;\r
81 }\r
82 }\r
83\r
84 if (Index != Argc - 1) {\r
85 printf ("%s must specify VFR file name", PROGRAM_NAME);\r
86 Usage ();\r
87 goto Fail;\r
88 } else {\r
89 strcpy (mOptions.VfrFileName, Argv[Index]);\r
90 }\r
91\r
92 if (SetBaseFileName() != 0) {\r
93 goto Fail;\r
94 }\r
95 if (SetPkgOutputFileName () != 0) {\r
96 goto Fail;\r
97 }\r
98 if (SetCOutputFileName() != 0) {\r
99 goto Fail;\r
100 }\r
101 if (SetPreprocessorOutputFileName () != 0) {\r
102 goto Fail;\r
103 }\r
104 if (SetRecordListFileName () != 0) {\r
105 goto Fail;\r
106 }\r
107 return;\r
108\r
109Fail:\r
110 SET_RUN_STATUS (STATUS_FAILED);\r
111\r
112 mOptions.VfrFileName[0] = '\0';\r
113 mOptions.RecordListFile[0] = '\0';\r
114 mOptions.CreateRecordListFile = FALSE;\r
115 mOptions.CreateIfrPkgFile = FALSE;\r
116 mOptions.PkgOutputFileName[0] = '\0';\r
117 mOptions.COutputFileName[0] = '\0';\r
118 mOptions.OutputDirectory[0] = '\0';\r
119 mOptions.PreprocessorOutputFileName[0] = '\0';\r
120 mOptions.VfrBaseFileName[0] = '\0';\r
121 if (mOptions.IncludePaths != NULL) {\r
122 delete mOptions.IncludePaths;\r
123 mOptions.IncludePaths = NULL;\r
124 } \r
125 if (mOptions.CPreprocessorOptions != NULL) {\r
126 delete mOptions.CPreprocessorOptions;\r
127 mOptions.CPreprocessorOptions = NULL;\r
128 }\r
129}\r
130\r
131VOID\r
132CVfrCompiler::AppendIncludePath (\r
133 IN INT8 *PathStr\r
134 )\r
135{\r
136 UINT32 Len = 0;\r
137 INT8 *IncludePaths = NULL;\r
138\r
139 Len = strlen (" -I ") + strlen (PathStr) + 1;\r
140 if (mOptions.IncludePaths != NULL) {\r
141 Len += strlen (mOptions.IncludePaths);\r
142 }\r
143 IncludePaths = new INT8[Len];\r
144 if (IncludePaths == NULL) {\r
145 printf ("%s memory allocation failure\n", PROGRAM_NAME);\r
146 return;\r
147 }\r
148 IncludePaths[0] = '\0';\r
149 if (mOptions.IncludePaths != NULL) {\r
150 strcat (IncludePaths, mOptions.IncludePaths);\r
151 }\r
152 strcat (IncludePaths, " -I ");\r
153 strcat (IncludePaths, PathStr);\r
154 if (mOptions.IncludePaths != NULL) {\r
155 delete mOptions.IncludePaths;\r
156 }\r
157 mOptions.IncludePaths = IncludePaths;\r
158}\r
159\r
160VOID\r
161CVfrCompiler::AppendCPreprocessorOptions (\r
162 IN INT8 *Options\r
163 )\r
164{\r
165 UINT32 Len = 0;\r
166 INT8 *Opt = NULL;\r
167\r
168 Len = strlen (Options) + strlen (" ") + 1;\r
169 if (mOptions.CPreprocessorOptions != NULL) {\r
170 Len += strlen (mOptions.CPreprocessorOptions);\r
171 }\r
172 Opt = new INT8[Len];\r
173 if (Opt == NULL) {\r
174 printf ("%s memory allocation failure\n", PROGRAM_NAME);\r
175 return;\r
176 }\r
177 Opt[0] = 0;\r
178 if (mOptions.CPreprocessorOptions != NULL) {\r
179 strcat (Opt, mOptions.CPreprocessorOptions);\r
180 }\r
181 strcat (Opt, " ");\r
182 strcat (Opt, Options);\r
183 if (mOptions.CPreprocessorOptions != NULL) {\r
184 delete mOptions.CPreprocessorOptions;\r
185 }\r
186 mOptions.CPreprocessorOptions = Opt;\r
187}\r
188\r
189INT8\r
190CVfrCompiler::SetBaseFileName (\r
191 VOID\r
192 )\r
193{\r
194 INT8 *pFileName, *pPath, *pExt;\r
195\r
196 if (mOptions.VfrFileName[0] == '\0') {\r
197 return -1;\r
198 }\r
199\r
200 pFileName = mOptions.VfrFileName;\r
201 while ((pPath = strchr (pFileName, '\\')) != NULL) {\r
202 pFileName = pPath + 1;\r
203 }\r
204\r
205 if (pFileName == NULL) {\r
206 return -1;\r
207 }\r
208\r
209 if ((pExt = strchr (pFileName, '.')) == NULL) {\r
210 return -1;\r
211 }\r
212\r
213 strncpy (mOptions.VfrBaseFileName, pFileName, pExt - pFileName);\r
214 mOptions.VfrBaseFileName[pExt - pFileName] = '\0';\r
215\r
216 return 0;\r
217}\r
218\r
219INT8\r
220CVfrCompiler::SetPkgOutputFileName (\r
221 VOID\r
222 )\r
223{\r
224 if (mOptions.VfrBaseFileName[0] == '\0') {\r
225 return -1;\r
226 }\r
227\r
228 strcpy (mOptions.PkgOutputFileName, mOptions.OutputDirectory);\r
229 strcat (mOptions.PkgOutputFileName, mOptions.VfrBaseFileName);\r
230 strcat (mOptions.PkgOutputFileName, VFR_PACKAGE_FILENAME_EXTENSION);\r
231\r
232 return 0;\r
233}\r
234\r
235INT8\r
236CVfrCompiler::SetCOutputFileName (\r
237 VOID\r
238 )\r
239{\r
240 if (mOptions.VfrBaseFileName[0] == '\0') {\r
241 return -1;\r
242 }\r
243\r
244 strcpy (mOptions.COutputFileName, mOptions.OutputDirectory);\r
245 strcat (mOptions.COutputFileName, mOptions.VfrBaseFileName);\r
246 strcat (mOptions.COutputFileName, ".c");\r
247\r
248 return 0;\r
249}\r
250\r
251INT8\r
252CVfrCompiler::SetPreprocessorOutputFileName (\r
253 VOID\r
254 )\r
255{\r
256 if (mOptions.VfrBaseFileName[0] == '\0') {\r
257 return -1;\r
258 }\r
259\r
260 strcpy (mOptions.PreprocessorOutputFileName, mOptions.OutputDirectory);\r
261 strcat (mOptions.PreprocessorOutputFileName, mOptions.VfrBaseFileName);\r
262 strcat (mOptions.PreprocessorOutputFileName, VFR_PREPROCESS_FILENAME_EXTENSION);\r
263\r
264 return 0;\r
265}\r
266\r
267INT8\r
268CVfrCompiler::SetRecordListFileName (\r
269 VOID\r
270 )\r
271{\r
272 if (mOptions.VfrBaseFileName[0] == '\0') {\r
273 return -1;\r
274 }\r
275\r
276 strcpy (mOptions.RecordListFile, mOptions.OutputDirectory);\r
277 strcat (mOptions.RecordListFile, mOptions.VfrBaseFileName);\r
278 strcat (mOptions.RecordListFile, VFR_RECORDLIST_FILENAME_EXTENSION);\r
279\r
280 return 0;\r
281}\r
282\r
283CVfrCompiler::CVfrCompiler (\r
284 IN INT32 Argc, \r
285 IN INT8 **Argv\r
286 )\r
287{\r
288 mPreProcessCmd = PREPROCESSOR_COMMAND;\r
289 mPreProcessOpt = PREPROCESSOR_OPTIONS;\r
290\r
291 OptionInitialization(Argc, Argv);\r
292\r
293 if ((IS_RUN_STATUS(STATUS_FAILED)) || (IS_RUN_STATUS(STATUS_DEAD))) {\r
294 return;\r
295 }\r
296\r
297 SET_RUN_STATUS(STATUS_INITIALIZED);\r
298}\r
299\r
300CVfrCompiler::~CVfrCompiler (\r
301 VOID\r
302 )\r
303{\r
304 if (mOptions.IncludePaths != NULL) {\r
305 delete mOptions.IncludePaths;\r
306 mOptions.IncludePaths = NULL;\r
307 }\r
308\r
309 if (mOptions.CPreprocessorOptions != NULL) {\r
310 delete mOptions.CPreprocessorOptions;\r
311 mOptions.CPreprocessorOptions = NULL;\r
312 }\r
313\r
314 SET_RUN_STATUS(STATUS_DEAD);\r
315}\r
316\r
317VOID \r
318CVfrCompiler::Usage (\r
319 VOID\r
320 )\r
321{\r
322 UINT32 Index;\r
323 CONST INT8 *Help[] = {\r
324 " ", \r
325 "VfrCompile version " VFR_COMPILER_VERSION,\r
326 " ",\r
327 " Usage: VfrCompile {options} [VfrFile]",\r
328 " ",\r
329 " where options include:",\r
330 " -? or -h prints this help",\r
331 " -l create an output IFR listing file",\r
332 " -i IncPath add IncPath to the search path for VFR included files",\r
333 " -od OutputDir deposit all output files to directory OutputDir (default=cwd)",\r
334 " -ibin create an IFR HII pack file"\r
335 " -ppflag C-preprocessor argument",\r
336 " where parameters include:",\r
337 " VfrFile name of the input VFR script file",\r
338 " ",\r
339 NULL\r
340 };\r
341 for (Index = 0; Help[Index] != NULL; Index++) {\r
342 fprintf (stdout, "%s\n", Help[Index]);\r
343 }\r
344}\r
345\r
346VOID\r
347CVfrCompiler::PreProcess (\r
348 VOID\r
349 )\r
350{\r
351 FILE *pVfrFile = NULL;\r
352 UINT32 CmdLen = 0;\r
353 INT8 *PreProcessCmd = NULL;\r
354\r
355 if (!IS_RUN_STATUS(STATUS_INITIALIZED)) {\r
356 goto Fail;\r
357 }\r
358\r
359 if ((pVfrFile = fopen (mOptions.VfrFileName, "r")) == NULL) {\r
360 printf ("%s could not open input VFR file - %s\n", PROGRAM_NAME, mOptions.VfrFileName);\r
361 goto Fail;\r
362 }\r
363 fclose (pVfrFile);\r
364\r
365 CmdLen = strlen (mPreProcessCmd) + strlen (mPreProcessOpt) + \r
366 strlen (mOptions.VfrFileName) + strlen (mOptions.PreprocessorOutputFileName);\r
367 if (mOptions.CPreprocessorOptions != NULL) {\r
368 CmdLen += strlen (mOptions.CPreprocessorOptions);\r
369 }\r
370 if (mOptions.IncludePaths != NULL) {\r
371 CmdLen += strlen (mOptions.IncludePaths);\r
372 }\r
373\r
374 PreProcessCmd = new INT8[CmdLen + 10];\r
375 if (PreProcessCmd == NULL) {\r
376 printf ("%s could not allocate memory\n", PROGRAM_NAME);\r
377 goto Fail;\r
378 }\r
379 strcpy (PreProcessCmd, mPreProcessCmd), strcat (PreProcessCmd, " ");\r
380 strcat (PreProcessCmd, mPreProcessOpt), strcat (PreProcessCmd, " ");\r
381 if (mOptions.IncludePaths != NULL) {\r
382 strcat (PreProcessCmd, mOptions.IncludePaths), strcat (PreProcessCmd, " ");\r
383 }\r
384 if (mOptions.CPreprocessorOptions != NULL) {\r
385 strcat (PreProcessCmd, mOptions.CPreprocessorOptions), strcat (PreProcessCmd, " ");\r
386 }\r
387 strcat (PreProcessCmd, mOptions.VfrFileName), strcat (PreProcessCmd, " > ");\r
388 strcat (PreProcessCmd, mOptions.PreprocessorOutputFileName);\r
389\r
390 if (system (PreProcessCmd) != 0) {\r
391 printf ("%s failed to spawn C preprocessor on VFR file \n\t - %s\n", PROGRAM_NAME, PreProcessCmd);\r
392 goto Fail;\r
393 }\r
394\r
395 delete PreProcessCmd;\r
396 SET_RUN_STATUS (STATUS_PREPROCESSED);\r
397 return;\r
398\r
399Fail:\r
400 if (!IS_RUN_STATUS(STATUS_DEAD)) {\r
401 SET_RUN_STATUS (STATUS_FAILED);\r
402 }\r
403 delete PreProcessCmd;\r
404}\r
405\r
406extern UINT8 VfrParserStart (IN FILE *);\r
407\r
408VOID\r
409CVfrCompiler::Compile (\r
410 VOID\r
411 )\r
412{\r
413 FILE *VfrFile = NULL;\r
414\r
415 if (!IS_RUN_STATUS(STATUS_PREPROCESSED)) {\r
416 goto Fail;\r
417 }\r
418\r
419 if ((VfrFile = fopen (mOptions.PreprocessorOutputFileName, "r")) == NULL) {\r
420 printf ("%s failed to open input VFR preprocessor output file - %s\n", PROGRAM_NAME, mOptions.PreprocessorOutputFileName);\r
421 goto Fail;\r
422 }\r
423\r
424 if (VfrParserStart (VfrFile) != 0) {\r
425 goto Fail;\r
426 }\r
427\r
428 fclose (VfrFile);\r
429\r
430 if (gCFormPkg.HavePendingUnassigned () == TRUE) {\r
431 gCFormPkg.PendingAssignPrintAll ();\r
432 goto Fail;\r
433 }\r
434\r
435 SET_RUN_STATUS (STATUS_COMPILEED);\r
436 return;\r
437\r
438Fail:\r
439 if (!IS_RUN_STATUS(STATUS_DEAD)) {\r
440 printf ("%s compile error!\n", PROGRAM_NAME);\r
441 SET_RUN_STATUS (STATUS_FAILED);\r
442 }\r
443 if (VfrFile != NULL) {\r
444 fclose (VfrFile);\r
445 }\r
446}\r
447\r
448VOID\r
449CVfrCompiler::GenBinary (\r
450 VOID\r
451 )\r
452{\r
453 FILE *pFile = NULL;\r
454\r
455 if (!IS_RUN_STATUS(STATUS_COMPILEED)) {\r
456 goto Fail;\r
457 }\r
458\r
459 if (mOptions.CreateIfrPkgFile == TRUE) {\r
460 if ((pFile = fopen (mOptions.PkgOutputFileName, "wb")) == NULL) {\r
461 printf ("can not open PkgFileName\n", mOptions.PkgOutputFileName);\r
462 goto Fail;\r
463 }\r
464 if (gCFormPkg.BuildPkg (pFile) != VFR_RETURN_SUCCESS) {\r
465 fclose (pFile);\r
466 goto Fail;\r
467 }\r
468 fclose (pFile);\r
469 }\r
470\r
471 SET_RUN_STATUS (STATUS_GENBINARY);\r
472 return;\r
473\r
474Fail:\r
475 if (!IS_RUN_STATUS(STATUS_DEAD)) {\r
476 SET_RUN_STATUS (STATUS_FAILED);\r
477 }\r
478}\r
479\r
480static const char *gSourceFileHeader[] = {\r
481 "//",\r
482 "// DO NOT EDIT -- auto-generated file",\r
483 "//",\r
484 "// This file is generated by the vfrcompiler utility",\r
485 "//",\r
486 NULL\r
487};\r
488\r
489VOID\r
490CVfrCompiler::GenCFile (\r
491 VOID\r
492 )\r
493{\r
494 FILE *pFile;\r
495 UINT32 Index;\r
496\r
497 if (!IS_RUN_STATUS(STATUS_GENBINARY)) {\r
498 goto Fail;\r
499 }\r
500\r
501 if ((pFile = fopen (mOptions.COutputFileName, "w")) == NULL) {\r
502 printf ("failed to open output C file - %s\n", mOptions.COutputFileName);\r
503 goto Fail;\r
504 }\r
505\r
506 for (Index = 0; gSourceFileHeader[Index] != NULL; Index++) {\r
507 fprintf (pFile, "%s\n", gSourceFileHeader[Index]);\r
508 }\r
509\r
510 gCVfrBufferConfig.OutputCFile (pFile, mOptions.VfrBaseFileName);\r
511\r
512 if (gCFormPkg.GenCFile (mOptions.VfrBaseFileName, pFile) != VFR_RETURN_SUCCESS) {\r
513 fclose (pFile);\r
514 goto Fail;\r
515 }\r
516 fclose (pFile);\r
517\r
518 SET_RUN_STATUS (STATUS_FINISHED);\r
519 return;\r
520\r
521Fail:\r
522 if (!IS_RUN_STATUS(STATUS_DEAD)) {\r
523 SET_RUN_STATUS (STATUS_FAILED);\r
524 }\r
525}\r
526\r
527VOID\r
528CVfrCompiler::GenRecordListFile (\r
529 VOID\r
530 )\r
531{\r
532 FILE *pInFile = NULL;\r
533 FILE *pOutFile = NULL;\r
534 INT8 LineBuf[MAX_LINE_LEN];\r
535 UINT32 LineNo;\r
536\r
537 if (mOptions.CreateRecordListFile == TRUE) {\r
538 if ((mOptions.PreprocessorOutputFileName[0] == '\0') || (mOptions.RecordListFile[0] == '\0')) {\r
539 return;\r
540 }\r
541\r
542 if ((pInFile = fopen (mOptions.PreprocessorOutputFileName, "r")) == NULL) {\r
543 printf ("%s failed to open input VFR preprocessor output file - %s\n", PROGRAM_NAME, mOptions.PreprocessorOutputFileName);\r
544 return;\r
545 }\r
546\r
547 if ((pOutFile = fopen (mOptions.RecordListFile, "w")) == NULL) {\r
548 printf ("%s failed to open record list file for writing - %s\n", PROGRAM_NAME, mOptions.RecordListFile);\r
549 goto Err1;\r
550 }\r
551\r
552 fprintf (pOutFile, "//\n// VFR compiler version " VFR_COMPILER_VERSION "\n//\n");\r
553 LineNo = 0;\r
554 while (!feof (pInFile)) {\r
555 if (fgets (LineBuf, MAX_LINE_LEN, pInFile) != NULL) {\r
556 fprintf (pOutFile, "%s", LineBuf);\r
557 LineNo++;\r
558 gCIfrRecordInfoDB.IfrRecordOutput (pOutFile, LineNo);\r
559 }\r
560 }\r
561\r
562 fclose (pOutFile);\r
563 fclose (pInFile);\r
564 }\r
565\r
566 return;\r
567\r
568Err1:\r
569 fclose (pInFile);\r
570}\r
571\r
572INT32\r
573main (\r
574 IN INT32 Argc, \r
575 IN INT8 **Argv\r
576 )\r
577{\r
578 COMPILER_RUN_STATUS Status;\r
579 CVfrCompiler Compiler(Argc, Argv);\r
580\r
581 Compiler.PreProcess();\r
582 Compiler.Compile();\r
583 Compiler.GenBinary();\r
584 Compiler.GenCFile();\r
585 Compiler.GenRecordListFile ();\r
586\r
587 Status = Compiler.RunStatus ();\r
588 if ((Status == STATUS_DEAD) || (Status == STATUS_FAILED)) {\r
589 return 2;\r
590 }\r
591\r
592 return 0;\r
593}\r
594\r