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