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