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