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