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