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