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