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