summaryrefslogtreecommitdiff
path: root/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrCompiler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrCompiler.cpp')
-rw-r--r--EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrCompiler.cpp594
1 files changed, 594 insertions, 0 deletions
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrCompiler.cpp b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrCompiler.cpp
new file mode 100644
index 0000000000..b1b19b90bf
--- /dev/null
+++ b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrCompiler.cpp
@@ -0,0 +1,594 @@
+#include "stdio.h"
+#include "string.h"
+#include "process.h"
+#include "VfrCompiler.h"
+
+
+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 INT8 **Argv
+ )
+{
+ INT32 Index;
+
+ mOptions.VfrFileName[0] = '\0';
+ mOptions.RecordListFile[0] = '\0';
+ mOptions.CreateRecordListFile = FALSE;
+ mOptions.CreateIfrPkgFile = FALSE;
+ mOptions.PkgOutputFileName[0] = '\0';
+ mOptions.COutputFileName[0] = '\0';
+ mOptions.OutputDirectory[0] = '\0';
+ mOptions.PreprocessorOutputFileName[0] = '\0';
+ mOptions.VfrBaseFileName[0] = '\0';
+ mOptions.IncludePaths = NULL;
+ mOptions.CPreprocessorOptions = NULL;
+
+ for (Index = 1; (Index < Argc) && (Argv[Index][0] == '-'); Index++) {
+ if ((_stricmp(Argv[Index], "-?") == 0) || (_stricmp(Argv[Index], "-h") == 0)) {
+ Usage ();
+ 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] == '-')) {
+ printf ("%s -i - missing path argument\n", PROGRAM_NAME);
+ goto Fail;
+ }
+
+ AppendIncludePath(Argv[Index]);
+ } else if (_stricmp(Argv[Index], "-od") == 0) {
+ Index++;
+ if ((Index >= Argc) || (Argv[Index][0] == '-')) {
+ printf ("%s -od - missing output directory name\n", PROGRAM_NAME);
+ goto Fail;
+ }
+ strcpy (mOptions.OutputDirectory, Argv[Index]);
+ } else if (_stricmp(Argv[Index], "-ibin") == 0) {
+ mOptions.CreateIfrPkgFile = TRUE;
+ } else if (_stricmp(Argv[Index], "-nostrings") == 0) {
+ } else if (_stricmp(Argv[Index], "-ppflag") == 0) {
+ Index++;
+ if ((Index >= Argc) || (Argv[Index][0] == '-')) {
+ printf ("%s -od - missing C-preprocessor argument\n", PROGRAM_NAME);
+ goto Fail;
+ }
+
+ AppendCPreprocessorOptions (Argv[Index]);
+ } else {
+ printf ("%s unrecognized option %s\n", PROGRAM_NAME, Argv[Index]);
+ Usage ();
+ goto Fail;
+ }
+ }
+
+ if (Index != Argc - 1) {
+ printf ("%s must specify VFR file name", PROGRAM_NAME);
+ Usage ();
+ goto Fail;
+ } else {
+ strcpy (mOptions.VfrFileName, Argv[Index]);
+ }
+
+ 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_FAILED);
+
+ mOptions.VfrFileName[0] = '\0';
+ mOptions.RecordListFile[0] = '\0';
+ mOptions.CreateRecordListFile = FALSE;
+ mOptions.CreateIfrPkgFile = FALSE;
+ mOptions.PkgOutputFileName[0] = '\0';
+ mOptions.COutputFileName[0] = '\0';
+ mOptions.OutputDirectory[0] = '\0';
+ mOptions.PreprocessorOutputFileName[0] = '\0';
+ mOptions.VfrBaseFileName[0] = '\0';
+ if (mOptions.IncludePaths != NULL) {
+ delete mOptions.IncludePaths;
+ mOptions.IncludePaths = NULL;
+ }
+ if (mOptions.CPreprocessorOptions != NULL) {
+ delete mOptions.CPreprocessorOptions;
+ mOptions.CPreprocessorOptions = NULL;
+ }
+}
+
+VOID
+CVfrCompiler::AppendIncludePath (
+ IN INT8 *PathStr
+ )
+{
+ UINT32 Len = 0;
+ INT8 *IncludePaths = NULL;
+
+ Len = strlen (" -I ") + strlen (PathStr) + 1;
+ if (mOptions.IncludePaths != NULL) {
+ Len += strlen (mOptions.IncludePaths);
+ }
+ IncludePaths = new INT8[Len];
+ if (IncludePaths == NULL) {
+ printf ("%s memory allocation failure\n", PROGRAM_NAME);
+ 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 INT8 *Options
+ )
+{
+ UINT32 Len = 0;
+ INT8 *Opt = NULL;
+
+ Len = strlen (Options) + strlen (" ") + 1;
+ if (mOptions.CPreprocessorOptions != NULL) {
+ Len += strlen (mOptions.CPreprocessorOptions);
+ }
+ Opt = new INT8[Len];
+ if (Opt == NULL) {
+ printf ("%s memory allocation failure\n", PROGRAM_NAME);
+ 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
+ )
+{
+ INT8 *pFileName, *pPath, *pExt;
+
+ if (mOptions.VfrFileName[0] == '\0') {
+ return -1;
+ }
+
+ pFileName = mOptions.VfrFileName;
+ while ((pPath = strchr (pFileName, '\\')) != NULL) {
+ pFileName = pPath + 1;
+ }
+
+ if (pFileName == NULL) {
+ return -1;
+ }
+
+ if ((pExt = strchr (pFileName, '.')) == NULL) {
+ return -1;
+ }
+
+ strncpy (mOptions.VfrBaseFileName, pFileName, pExt - pFileName);
+ mOptions.VfrBaseFileName[pExt - pFileName] = '\0';
+
+ return 0;
+}
+
+INT8
+CVfrCompiler::SetPkgOutputFileName (
+ VOID
+ )
+{
+ if (mOptions.VfrBaseFileName[0] == '\0') {
+ 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
+ )
+{
+ if (mOptions.VfrBaseFileName[0] == '\0') {
+ return -1;
+ }
+
+ strcpy (mOptions.COutputFileName, mOptions.OutputDirectory);
+ strcat (mOptions.COutputFileName, mOptions.VfrBaseFileName);
+ strcat (mOptions.COutputFileName, ".c");
+
+ return 0;
+}
+
+INT8
+CVfrCompiler::SetPreprocessorOutputFileName (
+ VOID
+ )
+{
+ if (mOptions.VfrBaseFileName[0] == '\0') {
+ 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
+ )
+{
+ if (mOptions.VfrBaseFileName[0] == '\0') {
+ 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 INT8 **Argv
+ )
+{
+ mPreProcessCmd = PREPROCESSOR_COMMAND;
+ mPreProcessOpt = PREPROCESSOR_OPTIONS;
+
+ 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.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 INT8 *Help[] = {
+ " ",
+ "VfrCompile version " VFR_COMPILER_VERSION,
+ " ",
+ " Usage: VfrCompile {options} [VfrFile]",
+ " ",
+ " where options include:",
+ " -? or -h prints this help",
+ " -l create an output IFR listing file",
+ " -i IncPath add IncPath to the search path for VFR included files",
+ " -od OutputDir deposit all output files to directory OutputDir (default=cwd)",
+ " -ibin create an IFR HII pack file"
+ " -ppflag C-preprocessor argument",
+ " where parameters include:",
+ " VfrFile name of the input VFR script file",
+ " ",
+ NULL
+ };
+ for (Index = 0; Help[Index] != NULL; Index++) {
+ fprintf (stdout, "%s\n", Help[Index]);
+ }
+}
+
+VOID
+CVfrCompiler::PreProcess (
+ VOID
+ )
+{
+ FILE *pVfrFile = NULL;
+ UINT32 CmdLen = 0;
+ INT8 *PreProcessCmd = NULL;
+
+ if (!IS_RUN_STATUS(STATUS_INITIALIZED)) {
+ goto Fail;
+ }
+
+ if ((pVfrFile = fopen (mOptions.VfrFileName, "r")) == NULL) {
+ printf ("%s could not open input VFR file - %s\n", PROGRAM_NAME, 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 INT8[CmdLen + 10];
+ if (PreProcessCmd == NULL) {
+ printf ("%s could not allocate memory\n", PROGRAM_NAME);
+ 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) {
+ printf ("%s failed to spawn C preprocessor on VFR file \n\t - %s\n", PROGRAM_NAME, PreProcessCmd);
+ goto Fail;
+ }
+
+ delete PreProcessCmd;
+ 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 *);
+
+VOID
+CVfrCompiler::Compile (
+ VOID
+ )
+{
+ FILE *VfrFile = NULL;
+
+ if (!IS_RUN_STATUS(STATUS_PREPROCESSED)) {
+ goto Fail;
+ }
+
+ if ((VfrFile = fopen (mOptions.PreprocessorOutputFileName, "r")) == NULL) {
+ printf ("%s failed to open input VFR preprocessor output file - %s\n", PROGRAM_NAME, mOptions.PreprocessorOutputFileName);
+ goto Fail;
+ }
+
+ if (VfrParserStart (VfrFile) != 0) {
+ goto Fail;
+ }
+
+ fclose (VfrFile);
+
+ if (gCFormPkg.HavePendingUnassigned () == TRUE) {
+ gCFormPkg.PendingAssignPrintAll ();
+ goto Fail;
+ }
+
+ SET_RUN_STATUS (STATUS_COMPILEED);
+ return;
+
+Fail:
+ if (!IS_RUN_STATUS(STATUS_DEAD)) {
+ printf ("%s compile error!\n", PROGRAM_NAME);
+ SET_RUN_STATUS (STATUS_FAILED);
+ }
+ if (VfrFile != NULL) {
+ fclose (VfrFile);
+ }
+}
+
+VOID
+CVfrCompiler::GenBinary (
+ VOID
+ )
+{
+ FILE *pFile = NULL;
+
+ if (!IS_RUN_STATUS(STATUS_COMPILEED)) {
+ goto Fail;
+ }
+
+ if (mOptions.CreateIfrPkgFile == TRUE) {
+ if ((pFile = fopen (mOptions.PkgOutputFileName, "wb")) == NULL) {
+ printf ("can not open PkgFileName\n", mOptions.PkgOutputFileName);
+ goto Fail;
+ }
+ if (gCFormPkg.BuildPkg (pFile) != 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 ((pFile = fopen (mOptions.COutputFileName, "w")) == NULL) {
+ printf ("failed to open output C file - %s\n", mOptions.COutputFileName);
+ goto Fail;
+ }
+
+ for (Index = 0; gSourceFileHeader[Index] != NULL; Index++) {
+ fprintf (pFile, "%s\n", gSourceFileHeader[Index]);
+ }
+
+ gCVfrBufferConfig.OutputCFile (pFile, mOptions.VfrBaseFileName);
+
+ if (gCFormPkg.GenCFile (mOptions.VfrBaseFileName, pFile) != 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
+ )
+{
+ FILE *pInFile = NULL;
+ FILE *pOutFile = NULL;
+ INT8 LineBuf[MAX_LINE_LEN];
+ UINT32 LineNo;
+
+ if (mOptions.CreateRecordListFile == TRUE) {
+ if ((mOptions.PreprocessorOutputFileName[0] == '\0') || (mOptions.RecordListFile[0] == '\0')) {
+ return;
+ }
+
+ if ((pInFile = fopen (mOptions.PreprocessorOutputFileName, "r")) == NULL) {
+ printf ("%s failed to open input VFR preprocessor output file - %s\n", PROGRAM_NAME, mOptions.PreprocessorOutputFileName);
+ return;
+ }
+
+ if ((pOutFile = fopen (mOptions.RecordListFile, "w")) == NULL) {
+ printf ("%s failed to open record list file for writing - %s\n", PROGRAM_NAME, mOptions.RecordListFile);
+ goto Err1;
+ }
+
+ fprintf (pOutFile, "//\n// VFR compiler version " VFR_COMPILER_VERSION "\n//\n");
+ LineNo = 0;
+ while (!feof (pInFile)) {
+ if (fgets (LineBuf, MAX_LINE_LEN, pInFile) != NULL) {
+ fprintf (pOutFile, "%s", LineBuf);
+ LineNo++;
+ gCIfrRecordInfoDB.IfrRecordOutput (pOutFile, LineNo);
+ }
+ }
+
+ fclose (pOutFile);
+ fclose (pInFile);
+ }
+
+ return;
+
+Err1:
+ fclose (pInFile);
+}
+
+INT32
+main (
+ IN INT32 Argc,
+ IN INT8 **Argv
+ )
+{
+ COMPILER_RUN_STATUS Status;
+ CVfrCompiler Compiler(Argc, Argv);
+
+ Compiler.PreProcess();
+ Compiler.Compile();
+ Compiler.GenBinary();
+ Compiler.GenCFile();
+ Compiler.GenRecordListFile ();
+
+ Status = Compiler.RunStatus ();
+ if ((Status == STATUS_DEAD) || (Status == STATUS_FAILED)) {
+ return 2;
+ }
+
+ return 0;
+}
+