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