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