]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/VfrCompile/VfrCompiler.cpp
BaseTools: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / BaseTools / Source / C / VfrCompile / VfrCompiler.cpp
1 /** @file
2
3 VfrCompiler main class and main function.
4
5 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include "stdio.h"
11 #include "stdlib.h"
12 #include "string.h"
13 #include "VfrCompiler.h"
14 #include "CommonLib.h"
15 #include "EfiUtilityMsgs.h"
16
17 PACKAGE_DATA gCBuffer;
18 PACKAGE_DATA gRBuffer;
19 CVfrStringDB gCVfrStringDB;
20
21 VOID
22 CVfrCompiler::DebugError (
23 IN CHAR8 *FileName,
24 IN UINT32 LineNumber,
25 IN UINT32 MessageCode,
26 IN CONST CHAR8 *Text,
27 IN CONST CHAR8 *MsgFmt,
28 ...
29 )
30 {
31 va_list List;
32 va_start (List, MsgFmt);
33 PrintMessage ((CHAR8 *) "ERROR", FileName, LineNumber, MessageCode, (CHAR8 *) Text, (CHAR8 *) MsgFmt, List);
34 va_end (List);
35 }
36
37 VOID
38 CVfrCompiler::SET_RUN_STATUS (
39 IN COMPILER_RUN_STATUS Status
40 )
41 {
42 mRunStatus = Status;
43 }
44
45 BOOLEAN
46 CVfrCompiler::IS_RUN_STATUS (
47 IN COMPILER_RUN_STATUS Status
48 )
49 {
50 return mRunStatus == Status;
51 }
52
53 VOID
54 CVfrCompiler::OptionInitialization (
55 IN INT32 Argc,
56 IN CHAR8 **Argv
57 )
58 {
59 INT32 Index;
60 EFI_STATUS Status;
61
62 Status = EFI_SUCCESS;
63 SetUtilityName ((CHAR8*) PROGRAM_NAME);
64
65 mOptions.VfrFileName = NULL;
66 mOptions.RecordListFile = NULL;
67 mOptions.CreateRecordListFile = FALSE;
68 mOptions.CreateIfrPkgFile = FALSE;
69 mOptions.PkgOutputFileName = NULL;
70 mOptions.COutputFileName = NULL;
71 mOptions.OutputDirectory = NULL;
72 mOptions.PreprocessorOutputFileName = NULL;
73 mOptions.VfrBaseFileName = NULL;
74 mOptions.IncludePaths = NULL;
75 mOptions.SkipCPreprocessor = TRUE;
76 mOptions.CPreprocessorOptions = NULL;
77 mOptions.CompatibleMode = FALSE;
78 mOptions.HasOverrideClassGuid = FALSE;
79 mOptions.WarningAsError = FALSE;
80 mOptions.AutoDefault = FALSE;
81 mOptions.CheckDefault = FALSE;
82 memset (&mOptions.OverrideClassGuid, 0, sizeof (EFI_GUID));
83
84 if (Argc == 1) {
85 Usage ();
86 SET_RUN_STATUS (STATUS_DEAD);
87 return;
88 }
89
90 for (Index = 1; (Index < Argc) && (Argv[Index][0] == '-'); Index++) {
91 if ((stricmp(Argv[Index], "-h") == 0) || (stricmp(Argv[Index], "--help") == 0)) {
92 Usage ();
93 SET_RUN_STATUS (STATUS_DEAD);
94 return;
95 } else if (stricmp(Argv[Index], "--version") == 0) {
96 Version ();
97 SET_RUN_STATUS (STATUS_DEAD);
98 return;
99 } else if (stricmp(Argv[Index], "-l") == 0) {
100 mOptions.CreateRecordListFile = TRUE;
101 gCIfrRecordInfoDB.TurnOn ();
102 } else if (stricmp(Argv[Index], "-i") == 0) {
103 Index++;
104 if ((Index >= Argc) || (Argv[Index][0] == '-')) {
105 DebugError (NULL, 0, 1001, "Missing option", "-i missing path argument");
106 goto Fail;
107 }
108
109 AppendIncludePath(Argv[Index]);
110 } else if (stricmp(Argv[Index], "-o") == 0 || stricmp(Argv[Index], "--output-directory") == 0 || stricmp(Argv[Index], "-od") == 0) {
111 Index++;
112 if ((Index >= Argc) || (Argv[Index][0] == '-')) {
113 DebugError (NULL, 0, 1001, "Missing option", "-o missing output directory name");
114 goto Fail;
115 }
116
117 mOptions.OutputDirectory = (CHAR8 *) malloc (strlen (Argv[Index]) + strlen ("\\") + 1);
118 if (mOptions.OutputDirectory == NULL) {
119 DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL);
120 goto Fail;
121 }
122 strcpy (mOptions.OutputDirectory, Argv[Index]);
123
124 CHAR8 lastChar = mOptions.OutputDirectory[strlen(mOptions.OutputDirectory) - 1];
125 if ((lastChar != '/') && (lastChar != '\\')) {
126 if (strchr(mOptions.OutputDirectory, '/') != NULL) {
127 strcat (mOptions.OutputDirectory, "/");
128 } else {
129 strcat (mOptions.OutputDirectory, "\\");
130 }
131 }
132 DebugMsg (NULL, 0, 9, (CHAR8 *) "Output Directory", (CHAR8 *) "%s", mOptions.OutputDirectory);
133 } else if (stricmp(Argv[Index], "-b") == 0 || stricmp(Argv[Index], "--create-ifr-package") == 0 || stricmp(Argv[Index], "-ibin") == 0) {
134 mOptions.CreateIfrPkgFile = TRUE;
135 } else if (stricmp(Argv[Index], "-n") == 0 || stricmp(Argv[Index], "--no-pre-processing") == 0 || stricmp(Argv[Index], "-nopp") == 0) {
136 mOptions.SkipCPreprocessor = TRUE;
137 } else if (stricmp(Argv[Index], "-f") == 0 || stricmp(Argv[Index], "--pre-processing-flag") == 0 || stricmp(Argv[Index], "-ppflag") == 0) {
138 Index++;
139 if ((Index >= Argc) || (Argv[Index][0] == '-')) {
140 DebugError (NULL, 0, 1001, "Missing option", "-od - missing C-preprocessor argument");
141 goto Fail;
142 }
143
144 AppendCPreprocessorOptions (Argv[Index]);
145 } else if (stricmp(Argv[Index], "-c") == 0 || stricmp(Argv[Index], "--compatible-framework") == 0) {
146 mOptions.CompatibleMode = TRUE;
147 } else if (stricmp(Argv[Index], "-s") == 0|| stricmp(Argv[Index], "--string-db") == 0) {
148 Index++;
149 if ((Index >= Argc) || (Argv[Index][0] == '-')) {
150 DebugError (NULL, 0, 1001, "Missing option", "-s missing input string file name");
151 goto Fail;
152 }
153 gCVfrStringDB.SetStringFileName(Argv[Index]);
154 DebugMsg (NULL, 0, 9, (CHAR8 *) "Input string file path", (CHAR8 *) "%s", Argv[Index]);
155 } else if ((stricmp (Argv[Index], "-g") == 0) || (stricmp (Argv[Index], "--guid") == 0)) {
156 Index++;
157 Status = StringToGuid (Argv[Index], &mOptions.OverrideClassGuid);
158 if (EFI_ERROR (Status)) {
159 DebugError (NULL, 0, 1000, "Invalid format:", "%s", Argv[Index]);
160 goto Fail;
161 }
162 mOptions.HasOverrideClassGuid = TRUE;
163 } else if (stricmp(Argv[Index], "-w") == 0 || stricmp(Argv[Index], "--warning-as-error") == 0) {
164 mOptions.WarningAsError = TRUE;
165 } else if (stricmp(Argv[Index], "-a") == 0 ||stricmp(Argv[Index], "--autodefault") == 0) {
166 mOptions.AutoDefault = TRUE;
167 } else if (stricmp(Argv[Index], "-d") == 0 ||stricmp(Argv[Index], "--checkdefault") == 0) {
168 mOptions.CheckDefault = TRUE;
169 } else {
170 DebugError (NULL, 0, 1000, "Unknown option", "unrecognized option %s", Argv[Index]);
171 goto Fail;
172 }
173 }
174
175 if (Index != Argc - 1) {
176 DebugError (NULL, 0, 1001, "Missing option", "VFR file name is not specified.");
177 goto Fail;
178 } else {
179 mOptions.VfrFileName = (CHAR8 *) malloc (strlen (Argv[Index]) + 1);
180 if (mOptions.VfrFileName == NULL) {
181 DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL);
182 goto Fail;
183 }
184 strcpy (mOptions.VfrFileName, Argv[Index]);
185
186 if (mOptions.OutputDirectory == NULL) {
187 mOptions.OutputDirectory = (CHAR8 *) malloc (1);
188 if (mOptions.OutputDirectory == NULL) {
189 DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL);
190 goto Fail;
191 }
192 mOptions.OutputDirectory[0] = '\0';
193 }
194 }
195
196 if (SetBaseFileName() != 0) {
197 goto Fail;
198 }
199 if (SetPkgOutputFileName () != 0) {
200 goto Fail;
201 }
202 if (SetCOutputFileName() != 0) {
203 goto Fail;
204 }
205 if (SetPreprocessorOutputFileName () != 0) {
206 goto Fail;
207 }
208 if (SetRecordListFileName () != 0) {
209 goto Fail;
210 }
211 return;
212
213 Fail:
214 SET_RUN_STATUS (STATUS_DEAD);
215
216 mOptions.CreateRecordListFile = FALSE;
217 mOptions.CreateIfrPkgFile = FALSE;
218
219 if (mOptions.VfrFileName != NULL) {
220 free (mOptions.VfrFileName);
221 mOptions.VfrFileName = NULL;
222 }
223 if (mOptions.VfrBaseFileName != NULL) {
224 free (mOptions.VfrBaseFileName);
225 mOptions.VfrBaseFileName = NULL;
226 }
227 if (mOptions.OutputDirectory != NULL) {
228 free (mOptions.OutputDirectory);
229 mOptions.OutputDirectory = NULL;
230 }
231 if (mOptions.PkgOutputFileName != NULL) {
232 free (mOptions.PkgOutputFileName);
233 mOptions.PkgOutputFileName = NULL;
234 }
235 if (mOptions.COutputFileName != NULL) {
236 free (mOptions.COutputFileName);
237 mOptions.COutputFileName = NULL;
238 }
239 if (mOptions.PreprocessorOutputFileName != NULL) {
240 free (mOptions.PreprocessorOutputFileName);
241 mOptions.PreprocessorOutputFileName = NULL;
242 }
243 if (mOptions.RecordListFile != NULL) {
244 free (mOptions.RecordListFile);
245 mOptions.RecordListFile = NULL;
246 }
247 if (mOptions.IncludePaths != NULL) {
248 delete mOptions.IncludePaths;
249 mOptions.IncludePaths = NULL;
250 }
251 if (mOptions.CPreprocessorOptions != NULL) {
252 delete mOptions.CPreprocessorOptions;
253 mOptions.CPreprocessorOptions = NULL;
254 }
255 }
256
257 VOID
258 CVfrCompiler::AppendIncludePath (
259 IN CHAR8 *PathStr
260 )
261 {
262 UINT32 Len = 0;
263 CHAR8 *IncludePaths = NULL;
264
265 Len = strlen (" -I ") + strlen (PathStr) + 1;
266 if (mOptions.IncludePaths != NULL) {
267 Len += strlen (mOptions.IncludePaths);
268 }
269 IncludePaths = new CHAR8[Len];
270 if (IncludePaths == NULL) {
271 DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL);
272 return;
273 }
274 IncludePaths[0] = '\0';
275 if (mOptions.IncludePaths != NULL) {
276 strcat (IncludePaths, mOptions.IncludePaths);
277 }
278 strcat (IncludePaths, " -I ");
279 strcat (IncludePaths, PathStr);
280 if (mOptions.IncludePaths != NULL) {
281 delete[] mOptions.IncludePaths;
282 }
283 mOptions.IncludePaths = IncludePaths;
284 }
285
286 VOID
287 CVfrCompiler::AppendCPreprocessorOptions (
288 IN CHAR8 *Options
289 )
290 {
291 UINT32 Len = 0;
292 CHAR8 *Opt = NULL;
293
294 Len = strlen (Options) + strlen (" ") + 1;
295 if (mOptions.CPreprocessorOptions != NULL) {
296 Len += strlen (mOptions.CPreprocessorOptions);
297 }
298 Opt = new CHAR8[Len];
299 if (Opt == NULL) {
300 DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL);
301 return;
302 }
303 Opt[0] = 0;
304 if (mOptions.CPreprocessorOptions != NULL) {
305 strcat (Opt, mOptions.CPreprocessorOptions);
306 }
307 strcat (Opt, " ");
308 strcat (Opt, Options);
309 if (mOptions.CPreprocessorOptions != NULL) {
310 delete[] mOptions.CPreprocessorOptions;
311 }
312 mOptions.CPreprocessorOptions = Opt;
313 }
314
315 INT8
316 CVfrCompiler::SetBaseFileName (
317 VOID
318 )
319 {
320 CHAR8 *pFileName, *pPath, *pExt;
321
322 if (mOptions.VfrFileName == NULL) {
323 return -1;
324 }
325
326 pFileName = mOptions.VfrFileName;
327 while (
328 ((pPath = strchr (pFileName, '\\')) != NULL) ||
329 ((pPath = strchr (pFileName, '/')) != NULL)
330 )
331 {
332 pFileName = pPath + 1;
333 }
334
335 if (pFileName == NULL) {
336 return -1;
337 }
338
339 if ((pExt = strchr (pFileName, '.')) == NULL) {
340 return -1;
341 }
342
343 *pExt = '\0';
344
345 mOptions.VfrBaseFileName = (CHAR8 *) malloc (strlen (pFileName) + 1);
346 if (mOptions.VfrBaseFileName == NULL) {
347 *pExt = '.';
348 return -1;
349 }
350
351 strcpy (mOptions.VfrBaseFileName, pFileName);
352 *pExt = '.';
353
354 return 0;
355 }
356
357 INT8
358 CVfrCompiler::SetPkgOutputFileName (
359 VOID
360 )
361 {
362 INTN Length;
363
364 if (mOptions.VfrBaseFileName == NULL) {
365 return -1;
366 }
367
368 Length = strlen (mOptions.OutputDirectory) +
369 strlen (mOptions.VfrBaseFileName) +
370 strlen (VFR_PACKAGE_FILENAME_EXTENSION) +
371 1;
372
373 mOptions.PkgOutputFileName = (CHAR8 *) malloc (Length);
374 if (mOptions.PkgOutputFileName == NULL) {
375 return -1;
376 }
377
378 strcpy (mOptions.PkgOutputFileName, mOptions.OutputDirectory);
379 strcat (mOptions.PkgOutputFileName, mOptions.VfrBaseFileName);
380 strcat (mOptions.PkgOutputFileName, VFR_PACKAGE_FILENAME_EXTENSION);
381
382 return 0;
383 }
384
385 INT8
386 CVfrCompiler::SetCOutputFileName (
387 VOID
388 )
389 {
390 INTN Length;
391
392 if (mOptions.VfrBaseFileName == NULL) {
393 return -1;
394 }
395
396 Length = strlen (mOptions.OutputDirectory) +
397 strlen (mOptions.VfrBaseFileName) +
398 strlen (".c") +
399 1;
400
401 mOptions.COutputFileName = (CHAR8 *) malloc (Length);
402 if (mOptions.COutputFileName == NULL) {
403 return -1;
404 }
405
406 strcpy (mOptions.COutputFileName, mOptions.OutputDirectory);
407 strcat (mOptions.COutputFileName, mOptions.VfrBaseFileName);
408 strcat (mOptions.COutputFileName, ".c");
409
410 return 0;
411 }
412
413 INT8
414 CVfrCompiler::SetPreprocessorOutputFileName (
415 VOID
416 )
417 {
418 INTN Length;
419
420 if (mOptions.VfrBaseFileName == NULL) {
421 return -1;
422 }
423
424 Length = strlen (mOptions.OutputDirectory) +
425 strlen (mOptions.VfrBaseFileName) +
426 strlen (VFR_PREPROCESS_FILENAME_EXTENSION) +
427 1;
428
429 mOptions.PreprocessorOutputFileName = (CHAR8 *) malloc (Length);
430 if (mOptions.PreprocessorOutputFileName == NULL) {
431 return -1;
432 }
433
434 strcpy (mOptions.PreprocessorOutputFileName, mOptions.OutputDirectory);
435 strcat (mOptions.PreprocessorOutputFileName, mOptions.VfrBaseFileName);
436 strcat (mOptions.PreprocessorOutputFileName, VFR_PREPROCESS_FILENAME_EXTENSION);
437
438 return 0;
439 }
440
441 INT8
442 CVfrCompiler::SetRecordListFileName (
443 VOID
444 )
445 {
446 INTN Length;
447
448 if (mOptions.VfrBaseFileName == NULL) {
449 return -1;
450 }
451
452 Length = strlen (mOptions.OutputDirectory) +
453 strlen (mOptions.VfrBaseFileName) +
454 strlen (VFR_RECORDLIST_FILENAME_EXTENSION) +
455 1;
456
457 mOptions.RecordListFile = (CHAR8 *) malloc (Length);
458 if (mOptions.RecordListFile == NULL) {
459 return -1;
460 }
461
462 strcpy (mOptions.RecordListFile, mOptions.OutputDirectory);
463 strcat (mOptions.RecordListFile, mOptions.VfrBaseFileName);
464 strcat (mOptions.RecordListFile, VFR_RECORDLIST_FILENAME_EXTENSION);
465
466 return 0;
467 }
468
469 CVfrCompiler::CVfrCompiler (
470 IN INT32 Argc,
471 IN CHAR8 **Argv
472 )
473 {
474 mPreProcessCmd = (CHAR8 *) PREPROCESSOR_COMMAND;
475 mPreProcessOpt = (CHAR8 *) PREPROCESSOR_OPTIONS;
476
477 SET_RUN_STATUS (STATUS_STARTED);
478
479 OptionInitialization(Argc, Argv);
480
481 if ((IS_RUN_STATUS(STATUS_FAILED)) || (IS_RUN_STATUS(STATUS_DEAD))) {
482 return;
483 }
484
485 SET_RUN_STATUS(STATUS_INITIALIZED);
486 }
487
488 CVfrCompiler::~CVfrCompiler (
489 VOID
490 )
491 {
492 if (mOptions.VfrFileName != NULL) {
493 free (mOptions.VfrFileName);
494 mOptions.VfrFileName = NULL;
495 }
496
497 if (mOptions.VfrBaseFileName != NULL) {
498 free (mOptions.VfrBaseFileName);
499 mOptions.VfrBaseFileName = NULL;
500 }
501
502 if (mOptions.OutputDirectory != NULL) {
503 free (mOptions.OutputDirectory);
504 mOptions.OutputDirectory = NULL;
505 }
506
507 if (mOptions.PkgOutputFileName != NULL) {
508 free (mOptions.PkgOutputFileName);
509 mOptions.PkgOutputFileName = NULL;
510 }
511
512 if (mOptions.COutputFileName != NULL) {
513 free (mOptions.COutputFileName);
514 mOptions.COutputFileName = NULL;
515 }
516
517 if (mOptions.PreprocessorOutputFileName != NULL) {
518 free (mOptions.PreprocessorOutputFileName);
519 mOptions.PreprocessorOutputFileName = NULL;
520 }
521
522 if (mOptions.RecordListFile != NULL) {
523 free (mOptions.RecordListFile);
524 mOptions.RecordListFile = NULL;
525 }
526
527 if (mOptions.IncludePaths != NULL) {
528 delete[] mOptions.IncludePaths;
529 mOptions.IncludePaths = NULL;
530 }
531
532 if (mOptions.CPreprocessorOptions != NULL) {
533 delete[] mOptions.CPreprocessorOptions;
534 mOptions.CPreprocessorOptions = NULL;
535 }
536
537 SET_RUN_STATUS(STATUS_DEAD);
538 }
539
540 VOID
541 CVfrCompiler::Usage (
542 VOID
543 )
544 {
545 UINT32 Index;
546 CONST CHAR8 *Help[] = {
547 " ",
548 "VfrCompile version " VFR_COMPILER_VERSION "Build " __BUILD_VERSION,
549 "Copyright (c) 2004-2016 Intel Corporation. All rights reserved.",
550 " ",
551 "Usage: VfrCompile [options] VfrFile",
552 " ",
553 "Options:",
554 " -h, --help prints this help",
555 " --version prints version info",
556 " -l create an output IFR listing file",
557 " -o DIR, --output-directory DIR",
558 " deposit all output files to directory OutputDir",
559 " default is current directory",
560 " -b, --create-ifr-package",
561 " create an IFR HII pack file",
562 " -n, --no-pre-processing",
563 " do not preprocessing input file",
564 " -c, --compatible-framework",
565 " compatible framework vfr file",
566 " -s, --string-db",
567 " input uni string package file",
568 " -g, --guid",
569 " override class guid input",
570 " format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
571 " -w --warning-as-error",
572 " treat warning as an error",
573 " -a --autodefaut generate default value for question opcode if some default is missing",
574 " -d --checkdefault check the default information in a question opcode",
575 NULL
576 };
577 for (Index = 0; Help[Index] != NULL; Index++) {
578 fprintf (stdout, "%s\n", Help[Index]);
579 }
580 }
581
582 VOID
583 CVfrCompiler::Version (
584 VOID
585 )
586 {
587 UINT32 Index;
588 CONST CHAR8 *Help[] = {
589 "VfrCompile version " VFR_COMPILER_VERSION "Build " __BUILD_VERSION,
590 NULL
591 };
592 for (Index = 0; Help[Index] != NULL; Index++) {
593 fprintf (stdout, "%s\n", Help[Index]);
594 }
595 }
596
597 VOID
598 CVfrCompiler::PreProcess (
599 VOID
600 )
601 {
602 FILE *pVfrFile = NULL;
603 UINT32 CmdLen = 0;
604 CHAR8 *PreProcessCmd = NULL;
605
606 if (!IS_RUN_STATUS(STATUS_INITIALIZED)) {
607 goto Fail;
608 }
609
610 if (mOptions.SkipCPreprocessor == TRUE) {
611 goto Out;
612 }
613
614 if ((pVfrFile = fopen (LongFilePath (mOptions.VfrFileName), "r")) == NULL) {
615 DebugError (NULL, 0, 0001, "Error opening the input VFR file", "%s", mOptions.VfrFileName);
616 goto Fail;
617 }
618 fclose (pVfrFile);
619
620 CmdLen = strlen (mPreProcessCmd) + strlen (mPreProcessOpt) +
621 strlen (mOptions.VfrFileName) + strlen (mOptions.PreprocessorOutputFileName);
622 if (mOptions.CPreprocessorOptions != NULL) {
623 CmdLen += strlen (mOptions.CPreprocessorOptions);
624 }
625 if (mOptions.IncludePaths != NULL) {
626 CmdLen += strlen (mOptions.IncludePaths);
627 }
628
629 PreProcessCmd = new CHAR8[CmdLen + 10];
630 if (PreProcessCmd == NULL) {
631 DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL);
632 goto Fail;
633 }
634 strcpy (PreProcessCmd, mPreProcessCmd), strcat (PreProcessCmd, " ");
635 strcat (PreProcessCmd, mPreProcessOpt), strcat (PreProcessCmd, " ");
636 if (mOptions.IncludePaths != NULL) {
637 strcat (PreProcessCmd, mOptions.IncludePaths), strcat (PreProcessCmd, " ");
638 }
639 if (mOptions.CPreprocessorOptions != NULL) {
640 strcat (PreProcessCmd, mOptions.CPreprocessorOptions), strcat (PreProcessCmd, " ");
641 }
642 strcat (PreProcessCmd, mOptions.VfrFileName), strcat (PreProcessCmd, " > ");
643 strcat (PreProcessCmd, mOptions.PreprocessorOutputFileName);
644
645 if (system (PreProcessCmd) != 0) {
646 DebugError (NULL, 0, 0003, "Error parsing file", "failed to spawn C preprocessor on VFR file %s\n", PreProcessCmd);
647 goto Fail;
648 }
649
650 delete[] PreProcessCmd;
651
652 Out:
653 SET_RUN_STATUS (STATUS_PREPROCESSED);
654 return;
655
656 Fail:
657 if (!IS_RUN_STATUS(STATUS_DEAD)) {
658 SET_RUN_STATUS (STATUS_FAILED);
659 }
660 delete[] PreProcessCmd;
661 }
662
663 extern UINT8 VfrParserStart (IN FILE *, IN INPUT_INFO_TO_SYNTAX *);
664
665 VOID
666 CVfrCompiler::Compile (
667 VOID
668 )
669 {
670 FILE *pInFile = NULL;
671 CHAR8 *InFileName = NULL;
672 INPUT_INFO_TO_SYNTAX InputInfo;
673
674 if (!IS_RUN_STATUS(STATUS_PREPROCESSED)) {
675 goto Fail;
676 }
677
678 InFileName = (mOptions.SkipCPreprocessor == TRUE) ? mOptions.VfrFileName : mOptions.PreprocessorOutputFileName;
679
680 gCVfrErrorHandle.SetInputFile (InFileName);
681 gCVfrErrorHandle.SetWarningAsError(mOptions.WarningAsError);
682
683 if ((pInFile = fopen (LongFilePath (InFileName), "r")) == NULL) {
684 DebugError (NULL, 0, 0001, "Error opening the input file", "%s", InFileName);
685 goto Fail;
686 }
687
688 InputInfo.CompatibleMode = mOptions.CompatibleMode;
689 if (mOptions.HasOverrideClassGuid) {
690 InputInfo.OverrideClassGuid = &mOptions.OverrideClassGuid;
691 } else {
692 InputInfo.OverrideClassGuid = NULL;
693 }
694
695 if (VfrParserStart (pInFile, &InputInfo) != 0) {
696 goto Fail;
697 }
698
699 fclose (pInFile);
700 pInFile = NULL;
701
702 if (gCFormPkg.HavePendingUnassigned () == TRUE) {
703 gCFormPkg.PendingAssignPrintAll ();
704 goto Fail;
705 }
706
707 SET_RUN_STATUS (STATUS_COMPILEED);
708 return;
709
710 Fail:
711 if (!IS_RUN_STATUS(STATUS_DEAD)) {
712 DebugError (NULL, 0, 0003, "Error parsing", "compile error in file %s", InFileName);
713 SET_RUN_STATUS (STATUS_FAILED);
714 }
715 if (pInFile != NULL) {
716 fclose (pInFile);
717 }
718 }
719
720 VOID
721 CVfrCompiler::AdjustBin (
722 VOID
723 )
724 {
725 EFI_VFR_RETURN_CODE Status;
726
727 if (!IS_RUN_STATUS(STATUS_COMPILEED)) {
728 return;
729 }
730
731 if (gNeedAdjustOpcode) {
732 //
733 // When parsing the Vfr, has created some opcodes, now need to update the record info.
734 //
735 gCIfrRecordInfoDB.IfrUpdateRecordInfoForDynamicOpcode (FALSE);
736 }
737
738 //
739 // Check whether need to check default info for question or auto add default for question.
740 //
741 if (mOptions.AutoDefault || mOptions.CheckDefault) {
742 gCIfrRecordInfoDB.IfrCheckAddDefaultRecord (mOptions.AutoDefault, mOptions.CheckDefault);
743 }
744
745 //
746 // Check Binary Code consistent between Form and IfrRecord
747 //
748
749 //
750 // Get Package Data and IfrRecord Data
751 //
752 gCFormPkg.BuildPkg (gCBuffer);
753 gCIfrRecordInfoDB.IfrRecordOutput (gRBuffer);
754
755 //
756 // Compare Form and Record data
757 //
758 if (gCBuffer.Buffer != NULL && gRBuffer.Buffer != NULL) {
759 UINT32 Index;
760 if (gCBuffer.Size != gRBuffer.Size) {
761 DebugError (NULL, 0, 0001, "Error parsing vfr file", " %s. FormBinary Size 0x%X is not same to RecordBuffer Size 0x%X", mOptions.VfrFileName, gCBuffer.Size, gRBuffer.Size);
762 }
763 for (Index = 0; Index < gCBuffer.Size; Index ++) {
764 if (gCBuffer.Buffer[Index] != gRBuffer.Buffer[Index]) {
765 break;
766 }
767 }
768 if (Index != gCBuffer.Size) {
769 DebugError (NULL, 0, 0001, "Error parsing vfr file", " %s. the 0x%X byte is different between Form and Record", mOptions.VfrFileName, Index);
770 }
771 DebugMsg (NULL, 0, 9, (CHAR8 *) "IFR Buffer", (CHAR8 *) "Form Buffer same to Record Buffer and Size is 0x%X", Index);
772 } else if (gCBuffer.Buffer == NULL && gRBuffer.Buffer == NULL) {
773 //ok
774 } else {
775 DebugError (NULL, 0, 0001, "Error parsing vfr file", " %s.Buffer not allocated.", mOptions.VfrFileName);
776 }
777
778 //
779 // For UEFI mode, not do OpCode Adjust
780 //
781 if (mOptions.CompatibleMode) {
782 //
783 // Adjust Opcode to be compatible with framework vfr
784 //
785 Status = gCIfrRecordInfoDB.IfrRecordAdjust ();
786 if (Status != VFR_RETURN_SUCCESS) {
787 //
788 // Record List Adjust Failed
789 //
790 SET_RUN_STATUS (STATUS_FAILED);
791 return;
792 }
793 //
794 // Re get the IfrRecord Buffer.
795 //
796 gCIfrRecordInfoDB.IfrRecordOutput (gRBuffer);
797 }
798
799 return;
800 }
801
802 VOID
803 CVfrCompiler::GenBinary (
804 VOID
805 )
806 {
807 FILE *pFile = NULL;
808
809 if (!IS_RUN_STATUS(STATUS_COMPILEED)) {
810 goto Fail;
811 }
812
813 if (mOptions.CreateIfrPkgFile == TRUE) {
814 if ((pFile = fopen (LongFilePath (mOptions.PkgOutputFileName), "wb")) == NULL) {
815 DebugError (NULL, 0, 0001, "Error opening file", "%s", mOptions.PkgOutputFileName);
816 goto Fail;
817 }
818 if (gCFormPkg.BuildPkg (pFile, &gRBuffer) != VFR_RETURN_SUCCESS) {
819 fclose (pFile);
820 goto Fail;
821 }
822 fclose (pFile);
823 }
824
825 SET_RUN_STATUS (STATUS_GENBINARY);
826
827 return;
828
829 Fail:
830 if (!IS_RUN_STATUS(STATUS_DEAD)) {
831 SET_RUN_STATUS (STATUS_FAILED);
832 }
833 }
834
835 static const char *gSourceFileHeader[] = {
836 "//",
837 "// DO NOT EDIT -- auto-generated file",
838 "//",
839 "// This file is generated by the vfrcompiler utility",
840 "//",
841 NULL
842 };
843
844 VOID
845 CVfrCompiler::GenCFile (
846 VOID
847 )
848 {
849 FILE *pFile;
850 UINT32 Index;
851
852 if (!IS_RUN_STATUS(STATUS_GENBINARY)) {
853 goto Fail;
854 }
855
856 if (!mOptions.CreateIfrPkgFile || mOptions.CompatibleMode) {
857 if ((pFile = fopen (LongFilePath (mOptions.COutputFileName), "w")) == NULL) {
858 DebugError (NULL, 0, 0001, "Error opening output C file", "%s", mOptions.COutputFileName);
859 goto Fail;
860 }
861
862 for (Index = 0; gSourceFileHeader[Index] != NULL; Index++) {
863 fprintf (pFile, "%s\n", gSourceFileHeader[Index]);
864 }
865
866 if (mOptions.CompatibleMode) {
867 gCVfrBufferConfig.OutputCFile (pFile, mOptions.VfrBaseFileName);
868 }
869
870 if (gCFormPkg.GenCFile (mOptions.VfrBaseFileName, pFile, &gRBuffer) != VFR_RETURN_SUCCESS) {
871 fclose (pFile);
872 goto Fail;
873 }
874 fclose (pFile);
875 }
876
877 SET_RUN_STATUS (STATUS_FINISHED);
878 return;
879
880 Fail:
881 if (!IS_RUN_STATUS(STATUS_DEAD)) {
882 SET_RUN_STATUS (STATUS_FAILED);
883 }
884 }
885
886 VOID
887 CVfrCompiler::GenRecordListFile (
888 VOID
889 )
890 {
891 CHAR8 *InFileName = NULL;
892 FILE *pInFile = NULL;
893 FILE *pOutFile = NULL;
894 CHAR8 LineBuf[MAX_VFR_LINE_LEN];
895 UINT32 LineNo;
896
897 InFileName = (mOptions.SkipCPreprocessor == TRUE) ? mOptions.VfrFileName : mOptions.PreprocessorOutputFileName;
898
899 if (mOptions.CreateRecordListFile == TRUE && InFileName != NULL && mOptions.RecordListFile != NULL) {
900 if ((InFileName[0] == '\0') || (mOptions.RecordListFile[0] == '\0')) {
901 return;
902 }
903
904 if ((pInFile = fopen (LongFilePath (InFileName), "r")) == NULL) {
905 DebugError (NULL, 0, 0001, "Error opening the input VFR preprocessor output file", "%s", InFileName);
906 return;
907 }
908
909 if ((pOutFile = fopen (LongFilePath (mOptions.RecordListFile), "w")) == NULL) {
910 DebugError (NULL, 0, 0001, "Error opening the record list file", "%s", mOptions.RecordListFile);
911 goto Err1;
912 }
913
914 fprintf (pOutFile, "//\n// VFR compiler version " VFR_COMPILER_VERSION __BUILD_VERSION "\n//\n");
915 LineNo = 0;
916 while (!feof (pInFile)) {
917 if (fgets (LineBuf, MAX_VFR_LINE_LEN, pInFile) != NULL) {
918 fprintf (pOutFile, "%s", LineBuf);
919 LineNo++;
920 gCIfrRecordInfoDB.IfrRecordOutput (pOutFile, LineNo);
921 }
922 }
923
924 fprintf (pOutFile, "\n//\n// All Opcode Record List \n//\n");
925 gCIfrRecordInfoDB.IfrRecordOutput (pOutFile, 0);
926 gCVfrVarDataTypeDB.Dump(pOutFile);
927
928 fclose (pOutFile);
929 fclose (pInFile);
930 }
931
932 return;
933
934 Err1:
935 fclose (pInFile);
936 }
937
938 int
939 main (
940 IN int Argc,
941 IN char **Argv
942 )
943 {
944 COMPILER_RUN_STATUS Status;
945
946 SetPrintLevel(WARNING_LOG_LEVEL);
947 CVfrCompiler Compiler(Argc, Argv);
948
949 Compiler.PreProcess();
950 Compiler.Compile();
951 Compiler.AdjustBin();
952 Compiler.GenBinary();
953 Compiler.GenCFile();
954 Compiler.GenRecordListFile ();
955
956 Status = Compiler.RunStatus ();
957 if ((Status == STATUS_DEAD) || (Status == STATUS_FAILED)) {
958 return 2;
959 }
960
961 if (gCBuffer.Buffer != NULL) {
962 delete[] gCBuffer.Buffer;
963 }
964
965 if (gRBuffer.Buffer != NULL) {
966 delete[] gRBuffer.Buffer;
967 }
968
969 return GetUtilityStatus ();
970 }
971
972