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