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