audk/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrCompiler.cpp

595 lines
14 KiB
C++

#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;
}