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