/** @file
  
  VfrCompiler main class and main function.

Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials                          
are licensed and made available under the terms and conditions of the BSD License         
which accompanies this distribution.  The full text of the license may be found at        
http://opensource.org/licenses/bsd-license.php                                            
                                                                                          
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

**/

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "VfrCompiler.h"
#include "CommonLib.h"
#include "EfiUtilityMsgs.h"

PACKAGE_DATA  gCBuffer;
PACKAGE_DATA  gRBuffer;
CVfrStringDB  gCVfrStringDB;

VOID 
CVfrCompiler::DebugError (
  IN CHAR8         *FileName,
  IN UINT32        LineNumber,
  IN UINT32        MessageCode,
  IN CONST CHAR8   *Text,
  IN CONST CHAR8   *MsgFmt,
  ...
  ) 
{
  va_list List;
  va_start (List, MsgFmt);
  PrintMessage ((CHAR8 *) "ERROR", FileName, LineNumber, MessageCode, (CHAR8 *) Text, (CHAR8 *) MsgFmt, List);
  va_end (List);
}

VOID
CVfrCompiler::SET_RUN_STATUS (
  IN COMPILER_RUN_STATUS Status
  )
{
  mRunStatus = Status;
}

BOOLEAN
CVfrCompiler::IS_RUN_STATUS (
  IN COMPILER_RUN_STATUS Status
  )
{
  return mRunStatus == Status;
}

VOID
CVfrCompiler::OptionInitialization (
  IN INT32      Argc, 
  IN CHAR8      **Argv
  )
{
  INT32         Index;
  EFI_STATUS    Status;

  Status = EFI_SUCCESS;
  SetUtilityName ((CHAR8*) PROGRAM_NAME);

  mOptions.VfrFileName                   = NULL;
  mOptions.RecordListFile                = NULL;
  mOptions.CreateRecordListFile          = FALSE;
  mOptions.CreateIfrPkgFile              = FALSE;
  mOptions.PkgOutputFileName             = NULL;
  mOptions.COutputFileName               = NULL;
  mOptions.OutputDirectory               = NULL;
  mOptions.PreprocessorOutputFileName    = NULL;
  mOptions.VfrBaseFileName               = NULL;
  mOptions.IncludePaths                  = NULL;
  mOptions.SkipCPreprocessor             = TRUE;
  mOptions.CPreprocessorOptions          = NULL;
  mOptions.CompatibleMode                = FALSE;
  mOptions.HasOverrideClassGuid          = FALSE;
  mOptions.WarningAsError                = FALSE;
  mOptions.AutoDefault                   = FALSE;
  mOptions.CheckDefault                  = FALSE;
  memset (&mOptions.OverrideClassGuid, 0, sizeof (EFI_GUID));
  
  if (Argc == 1) {
    Usage ();
    SET_RUN_STATUS (STATUS_DEAD);
    return;
  }

  for (Index = 1; (Index < Argc) && (Argv[Index][0] == '-'); Index++) {
    if ((stricmp(Argv[Index], "-h") == 0) || (stricmp(Argv[Index], "--help") == 0)) {
      Usage ();
      SET_RUN_STATUS (STATUS_DEAD);
      return;
    } else if (stricmp(Argv[Index], "--version") == 0) {
      Version ();
      SET_RUN_STATUS (STATUS_DEAD);
      return;
    } else if (stricmp(Argv[Index], "-l") == 0) {
      mOptions.CreateRecordListFile = TRUE;
      gCIfrRecordInfoDB.TurnOn ();
    } else if (stricmp(Argv[Index], "-i") == 0) {
      Index++;
      if ((Index >= Argc) || (Argv[Index][0] == '-')) {
        DebugError (NULL, 0, 1001, "Missing option", "-i missing path argument"); 
        goto Fail;
      }

      AppendIncludePath(Argv[Index]);
    } else if (stricmp(Argv[Index], "-o") == 0 || stricmp(Argv[Index], "--output-directory") == 0 || stricmp(Argv[Index], "-od") == 0) {
      Index++;
      if ((Index >= Argc) || (Argv[Index][0] == '-')) {
        DebugError (NULL, 0, 1001, "Missing option", "-o missing output directory name");
        goto Fail;
      }

      mOptions.OutputDirectory = (CHAR8 *) malloc (strlen (Argv[Index]) + strlen ("\\") + 1);
      if (mOptions.OutputDirectory == NULL) {
        DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL);
        goto Fail;
      }
      strcpy (mOptions.OutputDirectory, Argv[Index]);
      
      CHAR8 lastChar = mOptions.OutputDirectory[strlen(mOptions.OutputDirectory) - 1];
      if ((lastChar != '/') && (lastChar != '\\')) {
        if (strchr(mOptions.OutputDirectory, '/') != NULL) {
          strcat (mOptions.OutputDirectory, "/");
        } else {
          strcat (mOptions.OutputDirectory, "\\");
        }
      }
      DebugMsg (NULL, 0, 9, (CHAR8 *) "Output Directory", (CHAR8 *) "%s", mOptions.OutputDirectory);
    } else if (stricmp(Argv[Index], "-b") == 0 || stricmp(Argv[Index], "--create-ifr-package") == 0 || stricmp(Argv[Index], "-ibin") == 0) {
      mOptions.CreateIfrPkgFile = TRUE;
    } else if (stricmp(Argv[Index], "-n") == 0 || stricmp(Argv[Index], "--no-pre-processing") == 0 || stricmp(Argv[Index], "-nopp") == 0) {
      mOptions.SkipCPreprocessor = TRUE;
    } else if (stricmp(Argv[Index], "-f") == 0 || stricmp(Argv[Index], "--pre-processing-flag") == 0 || stricmp(Argv[Index], "-ppflag") == 0) {
      Index++;
      if ((Index >= Argc) || (Argv[Index][0] == '-')) {
        DebugError (NULL, 0, 1001, "Missing option", "-od - missing C-preprocessor argument");
        goto Fail;
      }

      AppendCPreprocessorOptions (Argv[Index]);
    } else if (stricmp(Argv[Index], "-c") == 0 || stricmp(Argv[Index], "--compatible-framework") == 0) {
      mOptions.CompatibleMode = TRUE;
    } else if (stricmp(Argv[Index], "-s") == 0|| stricmp(Argv[Index], "--string-db") == 0) {
      Index++;
      if ((Index >= Argc) || (Argv[Index][0] == '-')) {
        DebugError (NULL, 0, 1001, "Missing option", "-s missing input string file name");
        goto Fail;
      }
      gCVfrStringDB.SetStringFileName(Argv[Index]);
      DebugMsg (NULL, 0, 9, (CHAR8 *) "Input string file path", (CHAR8 *) "%s", Argv[Index]);
    } else if ((stricmp (Argv[Index], "-g") == 0) || (stricmp (Argv[Index], "--guid") == 0)) {
      Index++;
      Status = StringToGuid (Argv[Index], &mOptions.OverrideClassGuid);
      if (EFI_ERROR (Status)) {
        DebugError (NULL, 0, 1000, "Invalid format:", "%s", Argv[Index]);
        goto Fail;
      }
      mOptions.HasOverrideClassGuid = TRUE;
    } else if (stricmp(Argv[Index], "-w") == 0 || stricmp(Argv[Index], "--warning-as-error") == 0) {
      mOptions.WarningAsError = TRUE;
    } else if (stricmp(Argv[Index], "-a") == 0 ||stricmp(Argv[Index], "--autodefault") == 0) {
      mOptions.AutoDefault = TRUE;
    } else if (stricmp(Argv[Index], "-d") == 0 ||stricmp(Argv[Index], "--checkdefault") == 0) {
      mOptions.CheckDefault = TRUE;
    } else {
      DebugError (NULL, 0, 1000, "Unknown option", "unrecognized option %s", Argv[Index]);
      goto Fail;
    }
  }

  if (Index != Argc - 1) {
    DebugError (NULL, 0, 1001, "Missing option", "VFR file name is not specified.");
    goto Fail;
  } else {
    mOptions.VfrFileName = (CHAR8 *) malloc (strlen (Argv[Index]) + 1);
    if (mOptions.VfrFileName == NULL) {
      DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL);
      goto Fail;
    }
    strcpy (mOptions.VfrFileName, Argv[Index]);

    if (mOptions.OutputDirectory == NULL) {
      mOptions.OutputDirectory = (CHAR8 *) malloc (1);
      if (mOptions.OutputDirectory == NULL) {
        DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL);
        goto Fail;
      }
      mOptions.OutputDirectory[0] = '\0';
    }
  }

  if (SetBaseFileName() != 0) {
    goto Fail;
  }
  if (SetPkgOutputFileName () != 0) {
    goto Fail;
  }
  if (SetCOutputFileName() != 0) {
    goto Fail;
  }
  if (SetPreprocessorOutputFileName () != 0) {
    goto Fail;
  }
  if (SetRecordListFileName () != 0) {
    goto Fail;
  }
  return;

Fail:
  SET_RUN_STATUS (STATUS_DEAD);

  mOptions.CreateRecordListFile          = FALSE;
  mOptions.CreateIfrPkgFile              = FALSE;

  if (mOptions.VfrFileName != NULL) {
    free (mOptions.VfrFileName);
    mOptions.VfrFileName                 = NULL;
  }
  if (mOptions.VfrBaseFileName != NULL) {
    free (mOptions.VfrBaseFileName);
    mOptions.VfrBaseFileName             = NULL;
  }
  if (mOptions.OutputDirectory != NULL) {
    free (mOptions.OutputDirectory);
    mOptions.OutputDirectory             = NULL;
  }
  if (mOptions.PkgOutputFileName != NULL) {
    free (mOptions.PkgOutputFileName);
    mOptions.PkgOutputFileName           = NULL;
  }
  if (mOptions.COutputFileName != NULL) {
    free (mOptions.COutputFileName);
    mOptions.COutputFileName             = NULL;
  }
  if (mOptions.PreprocessorOutputFileName != NULL) {
    free (mOptions.PreprocessorOutputFileName);
    mOptions.PreprocessorOutputFileName  = NULL;
  }
  if (mOptions.RecordListFile != NULL) {
    free (mOptions.RecordListFile);
    mOptions.RecordListFile              = NULL;
  }
  if (mOptions.IncludePaths != NULL) {
    delete mOptions.IncludePaths;
    mOptions.IncludePaths                = NULL;
  } 
  if (mOptions.CPreprocessorOptions != NULL) {
    delete mOptions.CPreprocessorOptions;
    mOptions.CPreprocessorOptions        = NULL;
  }
}

VOID
CVfrCompiler::AppendIncludePath (
  IN CHAR8      *PathStr
  )
{
  UINT32  Len           = 0;
  CHAR8   *IncludePaths = NULL;

  Len = strlen (" -I ") + strlen (PathStr) + 1;
  if (mOptions.IncludePaths != NULL) {
    Len += strlen (mOptions.IncludePaths);
  }
  IncludePaths = new CHAR8[Len];
  if (IncludePaths == NULL) {
    DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL);
    return;
  }
  IncludePaths[0] = '\0';
  if (mOptions.IncludePaths != NULL) {
    strcat (IncludePaths, mOptions.IncludePaths);
  }
  strcat (IncludePaths, " -I ");
  strcat (IncludePaths, PathStr);
  if (mOptions.IncludePaths != NULL) {
    delete[] mOptions.IncludePaths;
  }
  mOptions.IncludePaths = IncludePaths;
}

VOID
CVfrCompiler::AppendCPreprocessorOptions (
  IN CHAR8      *Options
  )
{
  UINT32  Len           = 0;
  CHAR8   *Opt          = NULL;

  Len = strlen (Options) + strlen (" ") + 1;
  if (mOptions.CPreprocessorOptions != NULL) {
    Len += strlen (mOptions.CPreprocessorOptions);
  }
  Opt = new CHAR8[Len];
  if (Opt == NULL) {
    DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL);
    return;
  }
  Opt[0] = 0;
  if (mOptions.CPreprocessorOptions != NULL) {
    strcat (Opt, mOptions.CPreprocessorOptions);
  }
  strcat (Opt, " ");
  strcat (Opt, Options);
  if (mOptions.CPreprocessorOptions != NULL) {
    delete[] mOptions.CPreprocessorOptions;
  }
  mOptions.CPreprocessorOptions = Opt;
}

INT8
CVfrCompiler::SetBaseFileName (
  VOID
  )
{
  CHAR8         *pFileName, *pPath, *pExt;

  if (mOptions.VfrFileName == NULL) {
    return -1;
  }

  pFileName = mOptions.VfrFileName;
  while (
    ((pPath = strchr (pFileName, '\\')) != NULL) ||
    ((pPath = strchr (pFileName, '/')) != NULL)
    )
  {
    pFileName = pPath + 1;
  }

  if (pFileName == NULL) {
    return -1;
  }

  if ((pExt = strchr (pFileName, '.')) == NULL) {
    return -1;
  }

  *pExt = '\0';

  mOptions.VfrBaseFileName = (CHAR8 *) malloc (strlen (pFileName) + 1);
  if (mOptions.VfrBaseFileName == NULL) {
    *pExt = '.';
    return -1;
  }

  strcpy (mOptions.VfrBaseFileName, pFileName);
  *pExt = '.';

  return 0;
}

INT8
CVfrCompiler::SetPkgOutputFileName (
  VOID
  )
{
  INTN Length;

  if (mOptions.VfrBaseFileName == NULL) {
    return -1;
  }

  Length = strlen (mOptions.OutputDirectory) +
           strlen (mOptions.VfrBaseFileName) +
           strlen (VFR_PACKAGE_FILENAME_EXTENSION) +
           1;

  mOptions.PkgOutputFileName = (CHAR8 *) malloc (Length);
  if (mOptions.PkgOutputFileName == NULL) {
    return -1;
  }

  strcpy (mOptions.PkgOutputFileName, mOptions.OutputDirectory);
  strcat (mOptions.PkgOutputFileName, mOptions.VfrBaseFileName);
  strcat (mOptions.PkgOutputFileName, VFR_PACKAGE_FILENAME_EXTENSION);

  return 0;
}

INT8
CVfrCompiler::SetCOutputFileName (
  VOID
  )
{
  INTN Length;

  if (mOptions.VfrBaseFileName == NULL) {
    return -1;
  }

  Length = strlen (mOptions.OutputDirectory) +
           strlen (mOptions.VfrBaseFileName) +
           strlen (".c") +
           1;

  mOptions.COutputFileName = (CHAR8 *) malloc (Length);
  if (mOptions.COutputFileName == NULL) {
    return -1;
  }

  strcpy (mOptions.COutputFileName, mOptions.OutputDirectory);
  strcat (mOptions.COutputFileName, mOptions.VfrBaseFileName);
  strcat (mOptions.COutputFileName, ".c");

  return 0;
}

INT8
CVfrCompiler::SetPreprocessorOutputFileName (
  VOID
  )
{
  INTN Length;

  if (mOptions.VfrBaseFileName == NULL) {
    return -1;
  }

  Length = strlen (mOptions.OutputDirectory) +
           strlen (mOptions.VfrBaseFileName) +
           strlen (VFR_PREPROCESS_FILENAME_EXTENSION) +
           1;

  mOptions.PreprocessorOutputFileName = (CHAR8 *) malloc (Length);
  if (mOptions.PreprocessorOutputFileName == NULL) {
    return -1;
  }

  strcpy (mOptions.PreprocessorOutputFileName, mOptions.OutputDirectory);
  strcat (mOptions.PreprocessorOutputFileName, mOptions.VfrBaseFileName);
  strcat (mOptions.PreprocessorOutputFileName, VFR_PREPROCESS_FILENAME_EXTENSION);

  return 0;
}

INT8
CVfrCompiler::SetRecordListFileName (
  VOID
  )
{
  INTN Length;

  if (mOptions.VfrBaseFileName == NULL) {
    return -1;
  }

  Length = strlen (mOptions.OutputDirectory) +
           strlen (mOptions.VfrBaseFileName) +
           strlen (VFR_RECORDLIST_FILENAME_EXTENSION) +
           1;

  mOptions.RecordListFile = (CHAR8 *) malloc (Length);
  if (mOptions.RecordListFile == NULL) {
    return -1;
  }

  strcpy (mOptions.RecordListFile, mOptions.OutputDirectory);
  strcat (mOptions.RecordListFile, mOptions.VfrBaseFileName);
  strcat (mOptions.RecordListFile, VFR_RECORDLIST_FILENAME_EXTENSION);

  return 0;
}

CVfrCompiler::CVfrCompiler (
  IN INT32      Argc, 
  IN CHAR8      **Argv
  )
{
  mPreProcessCmd = (CHAR8 *) PREPROCESSOR_COMMAND;
  mPreProcessOpt = (CHAR8 *) PREPROCESSOR_OPTIONS;

  SET_RUN_STATUS (STATUS_STARTED);

  OptionInitialization(Argc, Argv);

  if ((IS_RUN_STATUS(STATUS_FAILED)) || (IS_RUN_STATUS(STATUS_DEAD))) {
    return;
  }

  SET_RUN_STATUS(STATUS_INITIALIZED);
}

CVfrCompiler::~CVfrCompiler (
  VOID
  )
{
  if (mOptions.VfrFileName != NULL) {
    free (mOptions.VfrFileName);
    mOptions.VfrFileName = NULL;
  }

  if (mOptions.VfrBaseFileName != NULL) {
    free (mOptions.VfrBaseFileName);
    mOptions.VfrBaseFileName = NULL;
  }

  if (mOptions.OutputDirectory != NULL) {
    free (mOptions.OutputDirectory);
    mOptions.OutputDirectory = NULL;
  }

  if (mOptions.PkgOutputFileName != NULL) {
    free (mOptions.PkgOutputFileName);
    mOptions.PkgOutputFileName = NULL;
  }

  if (mOptions.COutputFileName != NULL) {
    free (mOptions.COutputFileName);
    mOptions.COutputFileName = NULL;
  }

  if (mOptions.PreprocessorOutputFileName != NULL) {
    free (mOptions.PreprocessorOutputFileName);
    mOptions.PreprocessorOutputFileName = NULL;
  }

  if (mOptions.RecordListFile != NULL) {
    free (mOptions.RecordListFile);
    mOptions.RecordListFile = NULL;
  }

  if (mOptions.IncludePaths != NULL) {
    delete[] mOptions.IncludePaths;
    mOptions.IncludePaths = NULL;
  }

  if (mOptions.CPreprocessorOptions != NULL) {
    delete[] mOptions.CPreprocessorOptions;
    mOptions.CPreprocessorOptions = NULL;
  }

  SET_RUN_STATUS(STATUS_DEAD);
}

VOID 
CVfrCompiler::Usage (
  VOID
  )
{
  UINT32 Index;
  CONST  CHAR8 *Help[] = {
    " ", 
    "VfrCompile version " VFR_COMPILER_VERSION "Build " __BUILD_VERSION,
    "Copyright (c) 2004-2016 Intel Corporation. All rights reserved.",
    " ",
    "Usage: VfrCompile [options] VfrFile",
    " ",
    "Options:",
    "  -h, --help     prints this help",
    "  --version      prints version info",
    "  -l             create an output IFR listing file",
    "  -o DIR, --output-directory DIR",
    "                 deposit all output files to directory OutputDir",
    "                 default is current directory",
    "  -b, --create-ifr-package",
    "                 create an IFR HII pack file",
    "  -n, --no-pre-processing",
    "                 do not preprocessing input file",
    "  -c, --compatible-framework",
    "                 compatible framework vfr file",
    "  -s, --string-db",
    "                 input uni string package file",
    "  -g, --guid",
    "                 override class guid input",
    "                 format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "  -w  --warning-as-error",
    "                 treat warning as an error",
    "  -a  --autodefaut    generate default value for question opcode if some default is missing",
    "  -d  --checkdefault  check the default information in a question opcode",
    NULL
    };
  for (Index = 0; Help[Index] != NULL; Index++) {
    fprintf (stdout, "%s\n", Help[Index]);
  }
}

VOID 
CVfrCompiler::Version (
  VOID
  )
{
  UINT32 Index;
  CONST  CHAR8 *Help[] = {
    "VfrCompile version " VFR_COMPILER_VERSION "Build " __BUILD_VERSION,
    NULL
    };
  for (Index = 0; Help[Index] != NULL; Index++) {
    fprintf (stdout, "%s\n", Help[Index]);
  }
}

VOID
CVfrCompiler::PreProcess (
  VOID
  )
{
  FILE    *pVfrFile      = NULL;
  UINT32  CmdLen         = 0;
  CHAR8   *PreProcessCmd = NULL;

  if (!IS_RUN_STATUS(STATUS_INITIALIZED)) {
    goto Fail;
  }

  if (mOptions.SkipCPreprocessor == TRUE) {
    goto Out;
  }

  if ((pVfrFile = fopen (LongFilePath (mOptions.VfrFileName), "r")) == NULL) {
    DebugError (NULL, 0, 0001, "Error opening the input VFR file", "%s", mOptions.VfrFileName);
    goto Fail;
  }
  fclose (pVfrFile);

  CmdLen = strlen (mPreProcessCmd) + strlen (mPreProcessOpt) + 
  	       strlen (mOptions.VfrFileName) + strlen (mOptions.PreprocessorOutputFileName);
  if (mOptions.CPreprocessorOptions != NULL) {
    CmdLen += strlen (mOptions.CPreprocessorOptions);
  }
  if (mOptions.IncludePaths != NULL) {
    CmdLen += strlen (mOptions.IncludePaths);
  }

  PreProcessCmd = new CHAR8[CmdLen + 10];
  if (PreProcessCmd == NULL) {
    DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL);
    goto Fail;
  }
  strcpy (PreProcessCmd, mPreProcessCmd), strcat (PreProcessCmd, " ");
  strcat (PreProcessCmd, mPreProcessOpt), strcat (PreProcessCmd, " ");
  if (mOptions.IncludePaths != NULL) {
    strcat (PreProcessCmd, mOptions.IncludePaths), strcat (PreProcessCmd, " ");
  }
  if (mOptions.CPreprocessorOptions != NULL) {
    strcat (PreProcessCmd, mOptions.CPreprocessorOptions), strcat (PreProcessCmd, " ");
  }
  strcat (PreProcessCmd, mOptions.VfrFileName), strcat (PreProcessCmd, " > ");
  strcat (PreProcessCmd, mOptions.PreprocessorOutputFileName);

  if (system (PreProcessCmd) != 0) {
    DebugError (NULL, 0, 0003, "Error parsing file", "failed to spawn C preprocessor on VFR file %s\n", PreProcessCmd);
    goto Fail;
  }

  delete[] PreProcessCmd;

Out:
  SET_RUN_STATUS (STATUS_PREPROCESSED);
  return;

Fail:
  if (!IS_RUN_STATUS(STATUS_DEAD)) {
    SET_RUN_STATUS (STATUS_FAILED);
  }
  delete[] PreProcessCmd;
}

extern UINT8 VfrParserStart (IN FILE *, IN INPUT_INFO_TO_SYNTAX *);

VOID
CVfrCompiler::Compile (
  VOID
  )
{
  FILE  *pInFile    = NULL;
  CHAR8 *InFileName = NULL;
  INPUT_INFO_TO_SYNTAX InputInfo;

  if (!IS_RUN_STATUS(STATUS_PREPROCESSED)) {
    goto Fail;
  }

  InFileName = (mOptions.SkipCPreprocessor == TRUE) ? mOptions.VfrFileName : mOptions.PreprocessorOutputFileName;

  gCVfrErrorHandle.SetInputFile (InFileName);
  gCVfrErrorHandle.SetWarningAsError(mOptions.WarningAsError);

  if ((pInFile = fopen (LongFilePath (InFileName), "r")) == NULL) {
    DebugError (NULL, 0, 0001, "Error opening the input file", "%s", InFileName);
    goto Fail;
  }

  InputInfo.CompatibleMode = mOptions.CompatibleMode;
  if (mOptions.HasOverrideClassGuid) {
    InputInfo.OverrideClassGuid = &mOptions.OverrideClassGuid;
  } else {
    InputInfo.OverrideClassGuid = NULL;
  }

  if (VfrParserStart (pInFile, &InputInfo) != 0) {
    goto Fail;
  }

  fclose (pInFile);
  pInFile = NULL;

  if (gCFormPkg.HavePendingUnassigned () == TRUE) {
    gCFormPkg.PendingAssignPrintAll ();
    goto Fail;
  }

  SET_RUN_STATUS (STATUS_COMPILEED);
  return;

Fail:
  if (!IS_RUN_STATUS(STATUS_DEAD)) {
    DebugError (NULL, 0, 0003, "Error parsing", "compile error in file %s", InFileName);
    SET_RUN_STATUS (STATUS_FAILED);
  }
  if (pInFile != NULL) {
    fclose (pInFile);
  }
}

VOID
CVfrCompiler::AdjustBin (
  VOID
  )
{
  EFI_VFR_RETURN_CODE Status;

  if (!IS_RUN_STATUS(STATUS_COMPILEED)) {
    return;
  }

  if (gNeedAdjustOpcode) {
    //
    // When parsing the Vfr, has created some opcodes, now need to update the record info.
    //
    gCIfrRecordInfoDB.IfrUpdateRecordInfoForDynamicOpcode (FALSE);
  }

  //
  // Check whether need to check default info for question or auto add default for question.
  //
  if (mOptions.AutoDefault || mOptions.CheckDefault) {
    gCIfrRecordInfoDB.IfrCheckAddDefaultRecord (mOptions.AutoDefault, mOptions.CheckDefault);
  }

  //
  // Check Binary Code consistent between Form and IfrRecord
  //

  //
  // Get Package Data and IfrRecord Data
  //
  gCFormPkg.BuildPkg (gCBuffer);
  gCIfrRecordInfoDB.IfrRecordOutput (gRBuffer); 

  //
  // Compare Form and Record data
  //
  if (gCBuffer.Buffer != NULL && gRBuffer.Buffer != NULL) {
    UINT32 Index;
    if (gCBuffer.Size != gRBuffer.Size) {
      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);
    }
    for (Index = 0; Index < gCBuffer.Size; Index ++) {
      if (gCBuffer.Buffer[Index] != gRBuffer.Buffer[Index]) {
        break;
      }
    }
    if (Index != gCBuffer.Size) {
      DebugError (NULL, 0, 0001, "Error parsing vfr file", " %s. the 0x%X byte is different between Form and Record", mOptions.VfrFileName, Index);
    }
    DebugMsg (NULL, 0, 9, (CHAR8 *) "IFR Buffer", (CHAR8 *) "Form Buffer same to Record Buffer and Size is 0x%X", Index);
  } else if (gCBuffer.Buffer == NULL && gRBuffer.Buffer == NULL) {
    //ok
  } else {
    DebugError (NULL, 0, 0001, "Error parsing vfr file", " %s.Buffer not allocated.", mOptions.VfrFileName);
  }

  //
  // For UEFI mode, not do OpCode Adjust
  //
  if (mOptions.CompatibleMode) {
    //
    // Adjust Opcode to be compatible with framework vfr
    //
    Status = gCIfrRecordInfoDB.IfrRecordAdjust ();
    if (Status != VFR_RETURN_SUCCESS) {
      //
      // Record List Adjust Failed
      //
      SET_RUN_STATUS (STATUS_FAILED);
      return;
    }
    //
    // Re get the IfrRecord Buffer.
    //
    gCIfrRecordInfoDB.IfrRecordOutput (gRBuffer); 
  }

  return;
}

VOID
CVfrCompiler::GenBinary (
  VOID
  )
{
  FILE                    *pFile = NULL;

  if (!IS_RUN_STATUS(STATUS_COMPILEED)) {
    goto Fail;
  }

  if (mOptions.CreateIfrPkgFile == TRUE) {
    if ((pFile = fopen (LongFilePath (mOptions.PkgOutputFileName), "wb")) == NULL) {
      DebugError (NULL, 0, 0001, "Error opening file", "%s", mOptions.PkgOutputFileName);
      goto Fail;
    }
    if (gCFormPkg.BuildPkg (pFile, &gRBuffer) != VFR_RETURN_SUCCESS) {
      fclose (pFile);
      goto Fail;
    }
    fclose (pFile);
  }

  SET_RUN_STATUS (STATUS_GENBINARY);

  return;

Fail:
  if (!IS_RUN_STATUS(STATUS_DEAD)) {
    SET_RUN_STATUS (STATUS_FAILED);
  }
}

static const char *gSourceFileHeader[] = {
  "//",
  "//  DO NOT EDIT -- auto-generated file",
  "//",
  "//  This file is generated by the vfrcompiler utility",
  "//",
  NULL
};

VOID
CVfrCompiler::GenCFile (
  VOID
  )
{
  FILE                    *pFile;
  UINT32                  Index;

  if (!IS_RUN_STATUS(STATUS_GENBINARY)) {
    goto Fail;
  }
  
  if (!mOptions.CreateIfrPkgFile || mOptions.CompatibleMode) {
    if ((pFile = fopen (LongFilePath (mOptions.COutputFileName), "w")) == NULL) {
      DebugError (NULL, 0, 0001, "Error opening output C file", "%s", mOptions.COutputFileName);
      goto Fail;
    }

    for (Index = 0; gSourceFileHeader[Index] != NULL; Index++) {
      fprintf (pFile, "%s\n", gSourceFileHeader[Index]);
    }

    if (mOptions.CompatibleMode) { 
      gCVfrBufferConfig.OutputCFile (pFile, mOptions.VfrBaseFileName);
    }

    if (gCFormPkg.GenCFile (mOptions.VfrBaseFileName, pFile, &gRBuffer) != VFR_RETURN_SUCCESS) {
      fclose (pFile);
      goto Fail;
    }
    fclose (pFile);
  }

  SET_RUN_STATUS (STATUS_FINISHED);
  return;

Fail:
  if (!IS_RUN_STATUS(STATUS_DEAD)) {
    SET_RUN_STATUS (STATUS_FAILED);
  }
}

VOID
CVfrCompiler::GenRecordListFile (
  VOID
  )
{
  CHAR8  *InFileName = NULL;
  FILE   *pInFile    = NULL;
  FILE   *pOutFile   = NULL;
  CHAR8  LineBuf[MAX_VFR_LINE_LEN];
  UINT32 LineNo;

  InFileName = (mOptions.SkipCPreprocessor == TRUE) ? mOptions.VfrFileName : mOptions.PreprocessorOutputFileName;

  if (mOptions.CreateRecordListFile == TRUE && InFileName != NULL && mOptions.RecordListFile != NULL) {
    if ((InFileName[0] == '\0') || (mOptions.RecordListFile[0] == '\0')) {
      return;
    }

    if ((pInFile = fopen (LongFilePath (InFileName), "r")) == NULL) {
      DebugError (NULL, 0, 0001, "Error opening the input VFR preprocessor output file", "%s", InFileName);
      return;
    }

    if ((pOutFile = fopen (LongFilePath (mOptions.RecordListFile), "w")) == NULL) {
      DebugError (NULL, 0, 0001, "Error opening the record list file", "%s", mOptions.RecordListFile);
      goto Err1;
    }

    fprintf (pOutFile, "//\n//  VFR compiler version " VFR_COMPILER_VERSION __BUILD_VERSION "\n//\n");
    LineNo = 0;
    while (!feof (pInFile)) {
      if (fgets (LineBuf, MAX_VFR_LINE_LEN, pInFile) != NULL) {
        fprintf (pOutFile, "%s", LineBuf);
        LineNo++;
        gCIfrRecordInfoDB.IfrRecordOutput (pOutFile, LineNo);
      }
    }
    
    fprintf (pOutFile, "\n//\n// All Opcode Record List \n//\n");
    gCIfrRecordInfoDB.IfrRecordOutput (pOutFile, 0);
    gCVfrVarDataTypeDB.Dump(pOutFile);

    fclose (pOutFile);
    fclose (pInFile);
  }

  return;

Err1:
  fclose (pInFile);
}

int
main (
  IN int             Argc, 
  IN char            **Argv
  )
{
  COMPILER_RUN_STATUS  Status;

  SetPrintLevel(WARNING_LOG_LEVEL);
  CVfrCompiler         Compiler(Argc, Argv);
  
  Compiler.PreProcess();
  Compiler.Compile();
  Compiler.AdjustBin();
  Compiler.GenBinary();
  Compiler.GenCFile();
  Compiler.GenRecordListFile ();

  Status = Compiler.RunStatus ();
  if ((Status == STATUS_DEAD) || (Status == STATUS_FAILED)) {
    return 2;
  }

  if (gCBuffer.Buffer != NULL) {
    delete[] gCBuffer.Buffer;
  }
  
  if (gRBuffer.Buffer != NULL) {
    delete[] gRBuffer.Buffer;
  }

  return GetUtilityStatus ();
}


