+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- VfrCompile.g\r
-\r
-Abstract:\r
-\r
- PCCTS parser and lexer definitions for the EFI VFR forms compiler\r
- \r
---*/ \r
-\r
-#header<<\r
-\r
-#include "Tiano.h"\r
-#include "EfiUtilityMsgs.h"\r
-#include "EfiVfr.h"\r
-#include "VfrServices.h"\r
-#include EFI_PROTOCOL_DEFINITION (Hii)\r
-\r
-#include <ctype.h>\r
-#include <direct.h>\r
-#include <process.h> // for spawn functions\r
-\r
->>\r
-\r
-<<\r
-\r
-//\r
-// Base info for DLG-generated scanner\r
-//\r
-#include "DLexerBase.h" \r
-\r
-//\r
-// Include the scanner file generated by DLG\r
-//\r
-#include "DLGLexer.h" \r
-\r
-class DLGLexerVfr : public DLGLexer\r
-{\r
-public:\r
- DLGLexerVfr (DLGFileInput *F) : DLGLexer (F) {};\r
- INT32 errstd (char *Text) \r
- { \r
- printf ("unrecognized input '%s'\n", Text); \r
- }\r
-};\r
-\r
-//\r
-// Base token definitions for ANTLR\r
-//\r
-#include "AToken.h"\r
-\r
-//\r
-// This is how we invoke the C preprocessor on the VFR source file\r
-// to resolve #defines, #includes, etc. To make C source files\r
-// shareable between VFR and drivers, define VFRCOMPILE so that\r
-// #ifdefs can be used in shared .h files.\r
-//\r
-#define PREPROCESSOR_COMMAND "cl.exe "\r
-#define PREPROCESSOR_OPTIONS "/nologo /E /TC /DVFRCOMPILE "\r
-\r
-typedef ANTLRCommonToken ANTLRToken;\r
-\r
-//\r
-// Specify the filename extensions for the files we generate.\r
-//\r
-#define VFR_BINARY_FILENAME_EXTENSION ".c"\r
-#define VFR_LIST_FILENAME_EXTENSION ".lst"\r
-#define VFR_PREPROCESS_FILENAME_EXTENSION ".i"\r
-\r
-static \r
-VOID \r
-Usage ();\r
-\r
-static \r
-STATUS \r
-ProcessArgs (\r
- int Argc, \r
- char *Argv[]\r
- );\r
-\r
-static \r
-VOID \r
-Cleanup ();\r
-\r
-//\r
-// Globals\r
-//\r
-OPTIONS gOptions;\r
-\r
-int \r
-main (\r
- int argc, \r
- char **argv\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Application entry point function. Parse command-line arguments, \r
- invoke the parser, clean up, and return.\r
-\r
-Arguments:\r
- argc - standard argc passed to main() per C conventions\r
- argv - standard argv passed to main() per C conventions\r
-\r
-Returns:\r
- STATUS_SUCCESS - program executed with no errors or warnings\r
- STATUS_WARNING - program executed with warnings\r
- STATUS_ERROR - non-recoverable errors encountered while processing\r
-\r
---*/\r
-{\r
- FILE *VfrFptr;\r
- char *Cmd;\r
- char *Cptr;\r
- int Len;\r
- STATUS Status;\r
- \r
- //\r
- // Set our program name for the error printing routines.\r
- // Then set printing limits.\r
- //\r
- SetUtilityName (UTILITY_NAME);\r
- SetPrintLimits (20, 20, 30);\r
- //\r
- // Process the command-line arguments\r
- //\r
- if (ProcessArgs (argc, argv) != STATUS_SUCCESS) {\r
- Usage ();\r
- Cleanup();\r
- return STATUS_ERROR;\r
- }\r
- VfrFptr = NULL;\r
- //\r
- // Verify the VFR script file exists\r
- //\r
- if ((VfrFptr = fopen (gOptions.VfrFileName, "r")) == NULL) {\r
- Error (UTILITY_NAME, 0, 0, gOptions.VfrFileName, "could not open input VFR file");\r
- Cleanup();\r
- return STATUS_ERROR;\r
- }\r
- //\r
- // Now close the file and make a system call to run the preprocessor\r
- // on it.\r
- //\r
- fclose (VfrFptr);\r
- Len = strlen (PREPROCESSOR_OPTIONS) + strlen (gOptions.VfrFileName) + 10 +\r
- strlen (PREPROCESSOR_COMMAND) + strlen (gOptions.PreprocessorOutputFileName);\r
- if (gOptions.CPreprocessorOptions != NULL) {\r
- Len += strlen (gOptions.CPreprocessorOptions) + 1;\r
- }\r
- if (gOptions.IncludePaths != NULL) {\r
- Len += strlen (gOptions.IncludePaths) + 1;\r
- }\r
- Cmd = (char *)malloc (Len);\r
- if (Cmd == NULL) {\r
- Error (UTILITY_NAME, 0, 0, NULL, "could not allocate memory");\r
- Cleanup();\r
- return STATUS_ERROR;\r
- } \r
- strcpy (Cmd, PREPROCESSOR_COMMAND PREPROCESSOR_OPTIONS);\r
- if (gOptions.IncludePaths != NULL) {\r
- strcat (Cmd, gOptions.IncludePaths);\r
- strcat (Cmd, " ");\r
- }\r
- if (gOptions.CPreprocessorOptions != NULL) {\r
- strcat (Cmd, gOptions.CPreprocessorOptions);\r
- strcat (Cmd, " ");\r
- }\r
- strcat (Cmd, gOptions.VfrFileName);\r
- strcat (Cmd, " > ");\r
- strcat (Cmd, gOptions.PreprocessorOutputFileName);\r
- Status = system (Cmd);\r
- if (Status != 0) {\r
- Error (UTILITY_NAME, 0, 0, gOptions.VfrFileName, "failed to spawn C preprocessor on VFR file");\r
- printf ("Command: '%s %s'\n", PREPROCESSOR_COMMAND, Cmd);\r
- Cleanup();\r
- return STATUS_ERROR;\r
- }\r
- free (Cmd);\r
- //\r
- // Open the preprocessor output file\r
- //\r
- if ((VfrFptr = fopen (gOptions.PreprocessorOutputFileName, "r")) == NULL) {\r
- Error (UTILITY_NAME, 0, 0, "failed to open input VFR preprocessor output file", \r
- gOptions.PreprocessorOutputFileName);\r
- Cleanup();\r
- return STATUS_ERROR;\r
- }\r
- //\r
- // Define input VFR file\r
- //\r
- DLGFileInput InputFile (VfrFptr);\r
- //\r
- // Define an instance of the scanner \r
- //\r
- DLGLexerVfr Scanner (&InputFile);\r
- //\r
- // Define token buffer between scanner and parser\r
- //\r
- ANTLRTokenBuffer Pipe (&Scanner); \r
- //\r
- // Create a token to use as a model\r
- //\r
- ANTLRToken Tok; \r
- //\r
- // Tell the scanner what type the token is\r
- //\r
- Scanner.setToken (&Tok); \r
- //\r
- // Create an instance of our parser\r
- //\r
- EfiVfrParser Parser (&Pipe); \r
- //\r
- // Initialize the parser \r
- //\r
- Parser.init ();\r
- Status = GetUtilityStatus ();\r
- if (Status != STATUS_SUCCESS) {\r
- Cleanup();\r
- return Status;\r
- } \r
- //\r
- // Start the first rule \r
- //\r
- Parser.program ();\r
- //\r
- // Close the input script file\r
- //\r
- fclose (VfrFptr);\r
- Parser.WriteIfrBytes ();\r
- //\r
- // Call cleanup, which does some extra checking of the script\r
- //\r
- Parser.Cleanup ();\r
- Cleanup();\r
- //\r
- // If we had an error somewhere, delete our output files so that\r
- // a subsequent build will rebuild them.\r
- //\r
- Status = GetUtilityStatus ();\r
- if (Status == STATUS_ERROR) {\r
- remove (gOptions.IfrOutputFileName);\r
- }\r
- return Status;\r
-}\r
-static\r
-VOID\r
-Cleanup ()\r
-/*++\r
-\r
-Routine Description:\r
- Free up memory allocated during parsing.\r
-\r
-Arguments:\r
- None\r
-\r
-Returns:\r
- None\r
-\r
---*/\r
-{\r
- //\r
- // Free up our string we allocated to track the include paths\r
- //\r
- if (gOptions.IncludePaths != NULL) {\r
- free (gOptions.IncludePaths);\r
- gOptions.IncludePaths = NULL;\r
- }\r
- //\r
- // Free up our string we allocated to track preprocessor options\r
- //\r
- if (gOptions.CPreprocessorOptions != NULL) {\r
- free (gOptions.CPreprocessorOptions);\r
- gOptions.CPreprocessorOptions = NULL;\r
- }\r
-} \r
-\r
-static\r
-STATUS\r
-ProcessArgs (\r
- int Argc, \r
- char *Argv[]\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Process the command-line arguments.\r
-\r
-Arguments:\r
- Argc - standard argc passed to main()\r
- Argv - standard argv passed to main()\r
-\r
-Returns:\r
- STATUS_SUCCESS - program should continue (all args ok)\r
-\r
---*/\r
-{\r
- char *IncludePaths;\r
- char *CPreprocessorOptions;\r
- int Len; \r
- char CopyStr[MAX_PATH];\r
- char *Cptr;\r
-\r
- //\r
- // Put options in known state.\r
- //\r
- memset ((char *)&gOptions, 0, sizeof (OPTIONS));\r
- //\r
- // Go through all the arguments that start with '-'\r
- //\r
- Argc--;\r
- Argv++;\r
- while ((Argc > 0) && (Argv[0][0] == '-')) {\r
- //\r
- // -? or -h help option -- return an error for printing usage\r
- //\r
- if ((_stricmp (Argv[0], "-?") == 0) || (_stricmp (Argv[0], "-h") == 0)) {\r
- return STATUS_ERROR;\r
- break;\r
- //\r
- // -l to create a listing output file\r
- //\r
- } else if (_stricmp (Argv[0], "-l") == 0) {\r
- gOptions.CreateListFile = 1;\r
- //\r
- // -I include_path option for finding include files. We'll pass this\r
- // to the preprocessor. Turn them all into a single include string.\r
- //\r
- } else if (_stricmp (Argv[0], "-i") == 0) {\r
- if ((Argc < 2) || (Argv[1][0] == '-')) {\r
- Error (UTILITY_NAME, 0, 0, Argv[0], "missing path argument");\r
- return STATUS_ERROR;\r
- }\r
- Argc--;\r
- Argv++;\r
- Len = strlen (" -I ");\r
- Len += strlen (Argv[0]) + 2;\r
- if (gOptions.IncludePaths != NULL) {\r
- Len += strlen (gOptions.IncludePaths);\r
- }\r
- IncludePaths = (INT8 *)malloc (Len);\r
- if (IncludePaths == NULL) {\r
- Error (UTILITY_NAME, 0, 0, NULL, "memory allocation failure");\r
- return STATUS_ERROR;\r
- }\r
- IncludePaths[0] = 0;\r
- if (gOptions.IncludePaths != NULL) {\r
- strcpy (IncludePaths, gOptions.IncludePaths);\r
- free (gOptions.IncludePaths);\r
- }\r
- strcat (IncludePaths, " -I ");\r
- strcat (IncludePaths, Argv[0]);\r
- gOptions.IncludePaths = IncludePaths;\r
- //\r
- // -od OutputDirectory to define a common directory for output files\r
- //\r
- } else if (_stricmp (Argv[0], "-od") == 0) {\r
- if ((Argc < 2) || (Argv[1][0] == '-')) {\r
- Error (UTILITY_NAME, 0, 0, Argv[0], "missing output directory name");\r
- return STATUS_ERROR;\r
- }\r
- Argc--;\r
- Argv++;\r
- strcpy (gOptions.OutputDirectory, Argv[0]);\r
- } else if (_stricmp (Argv[0], "-ibin") == 0) {\r
- gOptions.CreateIfrBinFile = 1;\r
- } else if (_stricmp (Argv[0], "-nostrings") == 0) {\r
- // deprecated option\r
- //\r
- // -ppflag C-preprocessor-flag option for passing options to the C preprocessor.\r
- // Turn them all into a single string.\r
- //\r
- } else if (_stricmp (Argv[0], "-ppflag") == 0) {\r
- if (Argc < 2) {\r
- Error (UTILITY_NAME, 0, 0, Argv[0], "missing C-preprocessor argument");\r
- return STATUS_ERROR;\r
- }\r
- Argc--;\r
- Argv++;\r
- Len = strlen (Argv[0]) + 2;\r
- if (gOptions.CPreprocessorOptions != NULL) {\r
- Len += strlen (gOptions.CPreprocessorOptions);\r
- }\r
- CPreprocessorOptions = (INT8 *)malloc (Len);\r
- if (CPreprocessorOptions == NULL) {\r
- Error (UTILITY_NAME, 0, 0, NULL, "memory allocation failure");\r
- return STATUS_ERROR;\r
- }\r
- CPreprocessorOptions[0] = 0;\r
- if (gOptions.CPreprocessorOptions != NULL) {\r
- strcpy (CPreprocessorOptions, gOptions.CPreprocessorOptions);\r
- free (gOptions.CPreprocessorOptions);\r
- }\r
- strcat (CPreprocessorOptions, " ");\r
- strcat (CPreprocessorOptions, Argv[0]);\r
- gOptions.CPreprocessorOptions = CPreprocessorOptions;\r
- } else {\r
- Error (UTILITY_NAME, 0, 0, Argv[0], "unrecognized option");\r
- return STATUS_ERROR;\r
- }\r
- Argc--;\r
- Argv++;\r
- }\r
- //\r
- // Must specify at least the vfr file name\r
- //\r
- if (Argc > 1) {\r
- Error (UTILITY_NAME, 0, 0, Argv[1], "unrecognized argument after VFR file name");\r
- return STATUS_ERROR;\r
- } else if (Argc < 1) {\r
- Error (UTILITY_NAME, 0, 0, NULL, "must specify VFR file name");\r
- return STATUS_ERROR;\r
- }\r
- strcpy (gOptions.VfrFileName, Argv[0]);\r
- \r
- strcpy (CopyStr, gOptions.VfrFileName);\r
- Cptr = CopyStr + strlen (CopyStr) - 1;\r
- for (;(Cptr > CopyStr) && (*Cptr != '\\') && (*Cptr != ':'); Cptr--);\r
- if (Cptr == CopyStr) {\r
- strcpy (gOptions.VfrBaseFileName, Cptr);\r
- } else {\r
- strcpy (gOptions.VfrBaseFileName, Cptr+1);\r
- }\r
- //\r
- // Terminate the vfr file basename at the extension\r
- //\r
- for (Cptr = gOptions.VfrBaseFileName; *Cptr && (*Cptr != '.'); Cptr++) {\r
- }\r
- *Cptr = 0; \r
- //\r
- // If they defined an output directory, prepend all output files\r
- // with the working directory. Output files of interest:\r
- // VfrListFileName -- list file\r
- // IfrOutputFileName -- IFR bytes \r
- // StringOutputFileName -- string bytes\r
- // StringListFileName -- not used\r
- // StringDefineFileName -- #defines of string identifiers\r
- //\r
- // We have two cases:\r
- // 1. Output directory (-od) not specified, in which case output files\r
- // go to the current working directory.\r
- // 2. Output directory specified, in which case the output files\r
- // go directly to the specified directory.\r
- //\r
- if (gOptions.OutputDirectory[0] == 0) {\r
- CopyStr[0] = 0;\r
- _getcwd (CopyStr, sizeof (CopyStr));\r
- strcpy (gOptions.OutputDirectory, CopyStr);\r
- }\r
- //\r
- // Make sure output directory has a trailing backslash\r
- //\r
- if (gOptions.OutputDirectory[strlen (gOptions.OutputDirectory) - 1] != '\\') {\r
- strcat (gOptions.OutputDirectory, "\\");\r
- }\r
- //\r
- // Create the base output file name as: path\base, copy it to all the output\r
- // filenames, and then add the appropriate extension to each.\r
- //\r
- strcpy (gOptions.VfrListFileName, gOptions.OutputDirectory);\r
- strcat (gOptions.VfrListFileName, gOptions.VfrBaseFileName);\r
- strcpy (gOptions.IfrOutputFileName, gOptions.VfrListFileName);\r
- strcpy (gOptions.PreprocessorOutputFileName, gOptions.VfrListFileName);\r
- strcat (gOptions.VfrListFileName, VFR_LIST_FILENAME_EXTENSION);\r
- strcat (gOptions.IfrOutputFileName, VFR_BINARY_FILENAME_EXTENSION);\r
- strcat (gOptions.PreprocessorOutputFileName, VFR_PREPROCESS_FILENAME_EXTENSION);\r
- \r
- //\r
- // We set a default list file name, so if they do not\r
- // want a list file, null out the name now.\r
- //\r
- if (gOptions.CreateListFile == 0) {\r
- gOptions.VfrListFileName[0] = 0;\r
- }\r
- return STATUS_SUCCESS;\r
-}\r
-static \r
-VOID \r
-Usage ()\r
-/*++\r
-\r
-Routine Description:\r
- Print utility usage instructions\r
-\r
-Arguments:\r
- None\r
-\r
-Returns:\r
- None\r
-\r
---*/\r
-{\r
- int Index;\r
- const char *Str[] = {\r
- UTILITY_NAME" "UTILITY_VERSION" - Intel VFR Compiler Utility",\r
- " Copyright (C), 2004 - 2008 Intel Corporation",\r
-#if ( defined(UTILITY_BUILD) && defined(UTILITY_VENDOR) )\r
- " Built from "UTILITY_BUILD", project of "UTILITY_VENDOR,\r
-#endif\r
- "",\r
- "Usage:",\r
- " "UTILITY_NAME" [OPTION] VFRFILE",\r
- "Description:",\r
- " Compile VFRFILE.",\r
- "Options:",\r
- " -? or -h print this help",\r
- " -l create an output IFR listing file",\r
- " -i IncPath add IncPath to the search path for VFR included files",\r
- " -od OutputDir deposit all output files to directory OutputDir (default=cwd)",\r
- " -ibin create an IFR HII pack file",\r
- " -ppflag CFlags pass Flags as C-preprocessor-flag",\r
- " -v or -version print version information",\r
- NULL\r
- };\r
-\r
- for (Index = 0; Str[Index] != NULL; Index++) {\r
- fprintf (stdout, "%s\n", Str[Index]);\r
- }\r
-}\r
- \r
->>\r
-\r
-\r
-#lexaction\r
-<<\r
-\r
-#include "EfiVfr.h"\r
-\r
-PARSER_LINE_DEFINITION *gLineDefinition = NULL;\r
-PARSER_LINE_DEFINITION *gLastLineDefinition = NULL;\r
-\r
-VOID\r
-AddFileLine (\r
- char *TokenString,\r
- UINT32 TokenLine\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- During the lexer phase, if we encounter a #line statement output by\r
- the preprocessor, this function gets called. We'll save off the info \r
- for error reporting purposes. The preprocessor line information has the\r
- form:\r
- \r
- #line 3 "FileName.c" \r
-\r
-Arguments:\r
- TokenString - the parsed string as shown above\r
- TokenLine - the line number in the preprocessed output file \r
- \r
-Returns:\r
- NA\r
-\r
---*/\r
-{\r
- PARSER_LINE_DEFINITION *LineDef;\r
- INT8 *Cptr;\r
- \r
- //\r
- // Allocate a structure in which we can keep track of this line information.\r
- //\r
- LineDef = (PARSER_LINE_DEFINITION *)malloc (sizeof (PARSER_LINE_DEFINITION));\r
- memset ((char *)LineDef, 0, sizeof (PARSER_LINE_DEFINITION));\r
- LineDef->TokenLineNum = TokenLine;\r
- LineDef->HashLineNum = atoi (TokenString + 6);\r
- //\r
- // Find the quotes in the filename, then allocate space in the line\r
- // def structure for a copy of the filename. Finally, copy it without\r
- // quotes to the line def.\r
- //\r
- for (Cptr = TokenString + 7; *Cptr && (*Cptr != '"'); Cptr++);\r
- if (*Cptr == '"') {\r
- LineDef->FileName = (INT8 *)malloc (strlen (Cptr));\r
- Cptr++;\r
- strcpy (LineDef->FileName, Cptr);\r
- for (Cptr = LineDef->FileName; *Cptr && (*Cptr != '"'); Cptr++);\r
- *Cptr = 0; \r
- //\r
- // Now add this new one to the list\r
- //\r
- if (gLineDefinition == NULL) {\r
- gLineDefinition = LineDef;\r
- } else {\r
- gLastLineDefinition->Next = LineDef;\r
- }\r
- gLastLineDefinition = LineDef;\r
- } else {\r
- Error (UTILITY_NAME, 0, 0, "invalid line definition in preprocessor output file", TokenString);\r
- free (LineDef);\r
- return;\r
- }\r
-}\r
-char *\r
-ConvertLineNumber (\r
- UINT32 *LineNum\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Given the line number in the preprocessor-output file, use the line number\r
- information we've saved to determine the source file name and line number\r
- where the code originally came from. This is required for error reporting.\r
-\r
-Arguments:\r
- LineNum - the line number in the preprocessor-output file.\r
-\r
-Returns:\r
- Returns a pointer to the source file name. Also returns the line number \r
- in the provided LineNum argument\r
-\r
---*/\r
-{\r
- PARSER_LINE_DEFINITION *LineDef;\r
- //\r
- // Step through our linked list of #line information we saved off. \r
- // For each one, look at its line number, and the line number of the\r
- // next record, and see if the passed-in line number is in the range.\r
- // If it is, then convert the line number to the appropriate line number\r
- // of the original source file.\r
- //\r
- for (LineDef = gLineDefinition; LineDef != NULL; LineDef = LineDef->Next) {\r
- //\r
- // The given LineNum is the line number from the .i file.\r
- // Find a line definition whose range includes this line number,\r
- // convert the line number, and return the filename.\r
- //\r
- if (LineDef->TokenLineNum <= *LineNum) {\r
- if (LineDef->Next != NULL) {\r
- if (LineDef->Next->TokenLineNum > *LineNum) {\r
- *LineNum = *LineNum - LineDef->TokenLineNum + LineDef->HashLineNum;\r
- return LineDef->FileName;\r
- }\r
- } else {\r
- //\r
- // Last one in the list of line definitions, so has to be right\r
- //\r
- *LineNum = *LineNum - LineDef->TokenLineNum + LineDef->HashLineNum;\r
- return LineDef->FileName;\r
- }\r
- }\r
- }\r
- return NULL;\r
-}\r
-\r
->>\r
-\r
-//\r
-// Define a lexical class for parsing quoted strings. Basically\r
-// starts with a double quote, and ends with a double quote that\r
-// is not preceeded with a backslash.\r
-//\r
-#lexclass QUOTED_STRING\r
-#token TheString "~[\"]*\"" << mode (START); >> \r
-\r
-//\r
-// Define a lexical class for parsing "#pragma pack" statements. \r
-// We do this just for convenience (since we skip them here) so\r
-// that users can include some minimal .h files.\r
-//\r
-#lexclass PRAGMA_PACK\r
-#token "pack" << skip (); >>\r
-#token "[\ \t]" << skip (); >> \r
-#token "\(" << skip (); >>\r
-#token "[0-9]*" << skip (); >>\r
-#token "\)" << skip (); mode (START); >>\r
-\r
-//\r
-// Define a lexclass for skipping over C++ style comments\r
-//\r
-#lexclass CPP_COMMENT\r
-#token "~[\n]*" << skip (); >>\r
-#token "\n" << skip (); mode (START); newline (); >>\r
-\r
-//\r
-// Standard lexclass is START\r
-//\r
-#lexclass START\r
-\r
-//\r
-// Find start of C++ style comments\r
-//\r
-#token "//" << skip (); mode (CPP_COMMENT); >>\r
-\r
-//\r
-// Skip whitespace\r
-//\r
-#token "[\ \t]" << skip (); >> \r
-\r
-//\r
-// Skip over newlines, but count them\r
-//\r
-#token "\n" << skip (); newline (); >>\r
-\r
-//\r
-// Skip pragma pack statements\r
-//\r
-#token "\#pragma" << skip (); mode(PRAGMA_PACK); >>\r
-\r
-//\r
-// Skip over 'extern' in any included .H file\r
-//\r
-#token "extern" << skip (); >>\r
-\r
-//\r
-// Tokens for the different keywords. Syntax is:\r
-// TokenName("ErrorMessageText") "TokenString"\r
-// where:\r
-// TokenName is the token name (must be capitalized) that is used in the rules\r
-// ErrorMessageText is the string the compiler emits when it detects a syntax error\r
-// TokenString is the actual matching string used in the user script\r
-//\r
-#token LineDefinition "#line\ [0-9]+\ \"~[\"]+\"[\ \t]*\n" << AddFileLine (begexpr (), line ()); skip (); >>\r
-#token FormSet("formset") "formset"\r
-#token EndFormSet("endformset") "endformset"\r
-#token Title("title") "title"\r
-#token FormId("formid") "formid"\r
-#token OneOf("oneof") "oneof"\r
-#token Prompt("prompt") "prompt"\r
-#token OrderedList("orderedlist") "orderedlist"\r
-#token EndList("endlist") "endlist"\r
-#token EndForm("endform") "endform"\r
-#token EndOneOf("endoneof") "endoneof"\r
-#token Form("form") "form"\r
-#token Subtitle("subtitle") "subtitle"\r
-#token Help("help") "help"\r
-#token VarId("varid") "varid"\r
-#token Text("text") "text"\r
-#token Option("option") "option"\r
-#token Value("value") "value"\r
-#token Flags("flags") "flags"\r
-#token Date("date") "date"\r
-#token EndDate("enddate") "enddate"\r
-#token Year("year") "year"\r
-#token Month("month") "month"\r
-#token Day("day") "day"\r
-#token Time("time") "time"\r
-#token EndTime("endtime") "endtime"\r
-#token Hour("hour") "hour"\r
-#token Minute("minute") "minute"\r
-#token Second("second") "second"\r
-#token AND("AND") "AND"\r
-#token OR("OR") "OR"\r
-#token GrayOutIf("grayoutif") "grayoutif"\r
-#token NOT("NOT") "NOT"\r
-#token Label("label") "label"\r
-#token Timeout("timeout") "timeout"\r
-#token Inventory("inventory") "inventory"\r
-#token StringToken("STRING_TOKEN") "STRING_TOKEN"\r
-#token NonNvDataMap("_NON_NV_DATA_MAP") "_NON_NV_DATA_MAP"\r
-#token Struct("struct") "struct"\r
-#token Uint64("UINT64") "UINT64"\r
-#token Uint32("UINT32") "UINT32"\r
-#token Uint16("UINT16") "UINT16"\r
-#token Char16("CHAR16") "CHAR16"\r
-#token Uint8("UINT8") "UINT8"\r
-#token Guid("guid") "guid"\r
-#token CheckBox("checkbox") "checkbox"\r
-#token EndCheckBox("endcheckbox") "endcheckbox"\r
-#token Numeric("numeric") "numeric"\r
-#token EndNumeric("endnumeric") "endnumeric" \r
-#token Minimum("minimum") "minimum" \r
-#token Maximum("maximum") "maximum" \r
-#token Step("step") "step" \r
-#token Default("default") "default" \r
-#token Password("password") "password" \r
-#token EndPassword("endpassword") "endpassword" \r
-#token String("string") "string" \r
-#token EndString("endstring") "endstring" \r
-#token MinSize("minsize") "minsize" \r
-#token MaxSize("maxsize") "maxsize" \r
-#token Encoding("encoding") "encoding"\r
-#token SuppressIf("suppressif") "suppressif"\r
-#token Hidden("hidden") "hidden"\r
-#token Goto("goto") "goto"\r
-#token InconsistentIf "inconsistentif"\r
-#token EndIf("endif") "endif"\r
-#token IdEqId("ideqid") "ideqid"\r
-#token IdEqVal("ideqval") "ideqval"\r
-#token VarEqVal("vareqval") "vareqval"\r
-#token Var("var") "var"\r
-#token IdEqValList("ideqvallist") "ideqvallist"\r
-#token Length("length") "length"\r
-#token Values("values") "values"\r
-#token Key("key") "key"\r
-#token DefaultFlag("DEFAULT") "DEFAULT"\r
-#token ManufacturingFlag("MANUFACTURING") "MANUFACTURING"\r
-#token InteractiveFlag("INTERACTIVE") "INTERACTIVE"\r
-#token NVAccessFlag("NV_ACCESS") "NV_ACCESS"\r
-#token ResetRequiredFlag("RESET_REQUIRED") "RESET_REQUIRED"\r
-#token LateCheckFlag("LATE_CHECK") "LATE_CHECK"\r
-#token Class("class") "class"\r
-#token Subclass("subclass") "subclass"\r
-#token TypeDef("typedef") "typedef"\r
-#token Restore("restore") "restore"\r
-#token Save("save") "save"\r
-#token Defaults("defaults") "defaults"\r
-#token Banner("banner") "banner"\r
-#token Align("align") "align"\r
-#token Left("left") "left"\r
-#token Right("right") "right"\r
-#token Center("center") "center"\r
-#token Line("line") "line"\r
-#token VarStore("varstore") "varstore"\r
-#token Name("name") "name"\r
-#token Oem("oem") "oem"\r
-#token True("TRUE") "TRUE"\r
-#token False("FALSE") "FALSE"\r
-#token GreaterThan(">") ">"\r
-#token GreaterEqual(">=") ">="\r
-#token LessThan("<") "<"\r
-#token LessEqual("<=") "<="\r
-\r
-//\r
-// Define the class and subclass tokens\r
-//\r
-#token ClassNonDevice("NONDEVICE") "NON_DEVICE"\r
-#token ClassDiskDevice("DISK_DEVICE") "DISK_DEVICE"\r
-#token ClassVideoDevice("VIDEO_DEVICE") "VIDEO_DEVICE"\r
-#token ClassNetworkDevice("NETWORK_DEVICE") "NETWORK_DEVICE"\r
-#token ClassInputDevice("INPUT_DEVICE") "INPUT_DEVICE"\r
-#token ClassOnBoardDevice("ONBOARD_DEVICE") "ONBOARD_DEVICE"\r
-#token ClassOtherDevice("OTHER_DEVICE") "OTHER_DEVICE"\r
-\r
-#token SubclassSetupApplication("SETUP_APPLICATION") "SETUP_APPLICATION"\r
-#token SubclassGeneralApplication("GENERAL_APPLICATION") "GENERAL_APPLICATION"\r
-#token SubclassFrontPage("FRONT_PAGE") "FRONT_PAGE"\r
-#token SubclassSingleUse("SINGLE_USE") "SINGLE_USE"\r
-\r
-#token LanguageIdentifier("language identifier") "[a-z][a-z][a-z]" // 3 lowercase characters\r
-#token StringIdentifier("string identifier") "[A-Za-z_][A-Za-z_0-9]*"\r
-#token Number("numeric value") "(0x[0-9A-Fa-f]+) | [0-9]+"\r
-#token OpenBrace("{") "\{"\r
-#token CloseBrace("}") "\}"\r
-#token OpenParen("(") "\("\r
-#token CloseParen(")") "\)"\r
-#token OpenBracket("[") "\["\r
-#token CloseBracket("]") "\]"\r
-\r
-//\r
-// Define all other invalid characters so that they get through the lexical phase\r
-// and we can catch them during the parse phase. We get much better error\r
-// messages then. \r
-//\r
-#token InvalidCharacters("invalid characters") "~[;:=,\.\|]" \r
-\r
-//\r
-// This is the overall definition of a VFR form definition script.\r
-//\r
-program :\r
- ( dataStructDefinition )*\r
- formSetStatement \r
- ( vfrStatementVarStore )*\r
- ( formDefinition )*\r
- EFS:EndFormSet ";" << WriteOpByte (EFS->getLine(), EFI_IFR_END_FORM_SET_OP); >>\r
- "@" // end of file\r
- ;\r
- \r
-formSetStatement :\r
- FS:FormSet << WriteOpByte (FS->getLine(), EFI_IFR_FORM_SET_OP); >>\r
- Guid "=" \r
- OpenBrace \r
- G1:Number ","\r
- G2:Number ","\r
- G3:Number ","\r
- G4:Number ","\r
- G5:Number ","\r
- G6:Number ","\r
- G7:Number ","\r
- G8:Number ","\r
- G9:Number ","\r
- G10:Number ","\r
- G11:Number \r
- CloseBrace << WriteGuidValue (G1->getLine (), G1->getText (), G2->getText (), G3->getText (),\r
- G4->getText (), G5->getText (), G6->getText (), G7->getText (),\r
- G8->getText (), G9->getText (), G10->getText (), G11->getText ()\r
- );\r
- >>\r
- ","\r
- Title "=" getStringId ","\r
- Help "=" getStringId ","\r
- //\r
- // insert padding for an EFI_PHYSICAL_ADDRESS (UINT64)\r
- //\r
- << WriteDWord (0, 0); WriteDWord (0, 0); >>\r
- Class "=" CVAL:classDefinition "," << WriteClass (); >>\r
- Subclass "=" SVAL:subclassDefinition "," << WriteSubclass (); >>\r
- << WriteWord (mNvDataStructSize); >>\r
- ; \r
-\r
-//\r
-// A form can be of multiple classes, thus allow CLASS_A | CLASS_B | CLASS_C\r
-//\r
-classDefinition :\r
- validClassNames ( "\|" validClassNames )*\r
- ;\r
- \r
-validClassNames :\r
- CND:ClassNonDevice << SetClass (CND->getLine(), EFI_NON_DEVICE_CLASS); >>\r
- | CDD:ClassDiskDevice << SetClass (CDD->getLine(), EFI_DISK_DEVICE_CLASS); >>\r
- | CVD:ClassVideoDevice << SetClass (CVD->getLine(), EFI_VIDEO_DEVICE_CLASS); >>\r
- | CNW:ClassNetworkDevice << SetClass (CNW->getLine(), EFI_NETWORK_DEVICE_CLASS); >>\r
- | CID:ClassInputDevice << SetClass (CID->getLine(), EFI_INPUT_DEVICE_CLASS); >>\r
- | COB:ClassOnBoardDevice << SetClass (COB->getLine(), EFI_ON_BOARD_DEVICE_CLASS); >>\r
- | COD:ClassOtherDevice << SetClass (COD->getLine(), EFI_OTHER_DEVICE_CLASS); >>\r
- | CNUM:Number << SetClass (CNUM->getLine(), GetNumber (CNUM->getText(), CNUM->getLine(), 4)); >>\r
- ; << PrintErrorMessage (LT(1)->getLine(), LT(1)->getText(), "invalid class"); >>\r
-\r
-//\r
-// A form can only be of one subclass type.\r
-//\r
-subclassDefinition :\r
- SSA:SubclassSetupApplication << SetSubclass (SSA->getLine(), EFI_SETUP_APPLICATION_SUBCLASS); >>\r
- | SGA:SubclassGeneralApplication << SetSubclass (SGA->getLine(), EFI_GENERAL_APPLICATION_SUBCLASS); >>\r
- | SFP:SubclassFrontPage << SetSubclass (SFP->getLine(), EFI_FRONT_PAGE_SUBCLASS); >>\r
- | SSU:SubclassSingleUse << SetSubclass (SSU->getLine(), EFI_SINGLE_USE_SUBCLASS); >>\r
- | SNUM:Number << SetSubclass (SNUM->getLine(), GetNumber (SNUM->getText(), SNUM->getLine(), 4)); >>\r
- ; << PrintErrorMessage (LT(1)->getLine(), LT(1)->getText(), "invalid subclass"); >>\r
-\r
-//\r
-// Parse a C type data structure for storing VFR setup data. Allow:\r
-// typedef struct _XXX_ {\r
-// (fields)\r
-// } MY_NV_DATA;\r
-//\r
-dataStructDefinition :\r
- << int IsNonNV = 0; >>\r
- { TypeDef } \r
- S:Struct \r
- (\r
- NonNvDataMap << IsNonNV = 1; >>\r
- |\r
- { StringIdentifier }\r
- ) << StartStructDefinition (IsNonNV, S->getLine()); >>\r
- OpenBrace \r
- dataStructFields \r
- CloseBrace NAME:StringIdentifier << EndStructDefinition (NAME->getText(), NAME->getLine()); >>\r
- ";"\r
- ;\r
-\r
-dataStructFields :\r
- ( dataStructField64 | dataStructField32 | dataStructField16 | dataStructField8 ) *\r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-// UINT64 Name[4];\r
-// UINT64 Name;\r
-//\r
-// Used while parsing the NV data map structures.\r
-//\r
-dataStructField64 :\r
- << int ArrayLength = 1; char IsArray = 0; >>\r
- "UINT64" \r
- NAME:StringIdentifier \r
- ( ";" | OpenBracket IVal:Number CloseBracket ";" << ArrayLength = GetNumber (IVal->getText(), IVal->getLine(), 4); IsArray = 1; >> ) \r
- << AddStructField (NAME->getText(), NAME->getLine(), 8, ArrayLength, IsArray); >>\r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-// UINT32 Name[4];\r
-// UINT32 Name;\r
-//\r
-// Used while parsing the NV data map structures.\r
-//\r
-dataStructField32 :\r
- << int ArrayLength = 1; char IsArray = 0; >>\r
- "UINT32" \r
- NAME:StringIdentifier \r
- ( ";" | OpenBracket IVal:Number CloseBracket ";" << ArrayLength = GetNumber (IVal->getText(), IVal->getLine(), 4); IsArray = 1; >> ) \r
- << AddStructField (NAME->getText(), NAME->getLine(), 4, ArrayLength, IsArray); >>\r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-// UINT16 Name[4];\r
-// UINT16 Name;\r
-//\r
-// Used while parsing the NV data map structures.\r
-//\r
-dataStructField16 :\r
- << int ArrayLength = 1; char IsArray = 0; >>\r
- ( "UINT16" | "CHAR16" )\r
- NAME:StringIdentifier \r
- ( ";" | OpenBracket IVal:Number CloseBracket ";" << ArrayLength = GetNumber (IVal->getText(), IVal->getLine(), 4); IsArray = 1; >> ) \r
- << AddStructField (NAME->getText(), NAME->getLine(), 2, ArrayLength, IsArray); >>\r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-// UINT8 Name[4];\r
-// UINT8 Name;\r
-//\r
-// Used while parsing the NV data map structures.\r
-//\r
-dataStructField8 :\r
- << int ArrayLength = 1; char IsArray = 0; >>\r
- "UINT8" \r
- NAME:StringIdentifier \r
- ( ";" | OpenBracket IVal:Number CloseBracket ";" << ArrayLength = GetNumber (IVal->getText(), IVal->getLine(), 4); IsArray = 1; >> ) \r
- << AddStructField (NAME->getText(), NAME->getLine(), 1, ArrayLength, IsArray); >>\r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-// form formid = 1,\r
-// title = STRING_TOKEN(STR_FORM_TITLE);\r
-// -- form statements --\r
-// endform;\r
-//\r
-// The Form ID cannot be 0\r
-//\r
-formDefinition :\r
- FRM:Form FormId << WriteOpByte (FRM->getLine(), EFI_IFR_FORM_OP); >> \r
- "=" \r
- VAL:Number << WriteWord (GetNumber (VAL->getText(), VAL->getLine(), 2)); AddFormId (GetNumber (VAL->getText(), VAL->getLine(), 2), VAL->getLine()); >>\r
- ","\r
- Title "=" getStringId ";" // writes string identifier\r
- ( vfrStatements )*\r
- ENDF:EndForm ";" << WriteOpByte (ENDF->getLine(), EFI_IFR_END_FORM_OP); >>\r
- ;\r
-\r
-//\r
-// VFR statements in a formset\r
-//\r
-vfrStatements :\r
- vfrStatementSubTitle | \r
- vfrStatementOneOf |\r
- vfrStatementTextText |\r
- vfrStatementCheckBox |\r
- vfrStatementNumeric |\r
- vfrStatementDate |\r
- vfrStatementTime |\r
- vfrStatementPassword |\r
- vfrStatementString |\r
- vfrStatementSuppressIf |\r
- vfrStatementHidden |\r
- vfrStatementGoto | \r
- vfrStatementGrayOutIf |\r
- vfrStatementInconsistentIf |\r
- vfrStatementLabel |\r
- vfrStatementBanner |\r
- vfrStatementInventory |\r
- vfrStatementOrderedList |\r
- vfrStatementOem |\r
- vfrStatementSaveRestoreDefaults\r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-// label 100;\r
-//\r
-vfrStatementLabel :\r
- OPID:Label << WriteOpByte (OPID->getLine(), EFI_IFR_LABEL_OP); >>\r
- VAL:Number << \r
- WriteWord (GetNumber (VAL->getText(), VAL->getLine(), 2)); \r
- AddLabel (GetNumber (VAL->getText(), VAL->getLine(), 2), VAL->getLine());\r
- >>\r
- ";"\r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-// oem 0x12, 0x34, 0x56;\r
-//\r
-vfrStatementOem :\r
- OPID:Oem << WriteOpByte (OPID->getLine(), EFI_IFR_OEM_DEFINED_OP); >>\r
- ( VAL1:Number << WriteByte (GetNumber (VAL1->getText(), VAL1->getLine(), 1), 0); >> )\r
- ( "," VAL2:Number << WriteByte (GetNumber (VAL2->getText(), VAL2->getLine(), 1), 0); >> )*\r
- ";"\r
- ;\r
- \r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-// inconsistentif NOT .... AND NOT .... OR ... endif;\r
-//\r
-vfrStatementInconsistentIf : \r
- << ResetFlags (); >>\r
- IIFOP:InconsistentIf << WriteOpByte (IIFOP->getLine(), EFI_IFR_INCONSISTENT_IF_OP); >>\r
- Prompt "=" getStringId ","\r
- { \r
- FF:Flags "=" flagsField ( "\|" flagsField )* "," \r
- }\r
- << WriteFlags (); >> // write the flags field\r
- vfrBooleanExpression\r
- EOP:EndIf ";" << WriteOpByte (EOP->getLine(), EFI_IFR_END_IF_OP); >>\r
- ;\r
-\r
-//*****************************************************************************\r
-// \r
-// PARSE:\r
-// TRUE AND (ideqval SomeStruct.SomeMember >= 0x10 OR \r
-// ideqid SomeStruct.SomeMember < SomeStruct.SomeOtherMember) AND\r
-// (ideqlist SomeStruct.SomeOtherMember == 0x10, 0x20, 0x30 OR\r
-// vareqval var(VAR_EQ_TEST_NAME) == 0x1)\r
-//\r
-// For supporting complex express, divide the vfrBooleanExpression to two parts\r
-// so that pred-LL(k) parser can parse incrementally.\r
-//\r
-vfrBooleanExpression :\r
- leftPartVfrBooleanExp { rightPartVfrBooleanExp }\r
- ;\r
- \r
-leftPartVfrBooleanExp :\r
- OpenParen vfrBooleanExpression CloseParen |\r
- (ideqval | ideqid | ideqvallist | vareqval | truefalse) |\r
- NOPID:NOT leftPartVfrBooleanExp << WriteOpByte (NOPID->getLine(), EFI_IFR_NOT_OP); >>\r
- ;\r
-\r
-rightPartVfrBooleanExp :\r
- AOPID:AND vfrBooleanExpression << WriteOpByte (AOPID->getLine(), EFI_IFR_AND_OP); >> |\r
- OOPID:OR vfrBooleanExpression << WriteOpByte (OOPID->getLine(), EFI_IFR_OR_OP); >>\r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-// TRUE\r
-//\r
-truefalse :\r
- TOPID:True << WriteOpByte (TOPID->getLine(), EFI_IFR_TRUE_OP); >> |\r
- FOPID:False << WriteOpByte (FOPID->getLine(), EFI_IFR_FALSE_OP); >>\r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-// varstore MY_STRUCT_NAME, key = 0x1234, name = "MyVariableName", guid = {...};\r
-//\r
-vfrStatementVarStore : \r
- OP:VarStore << WriteOpByte (OP->getLine(), EFI_IFR_VARSTORE_OP); >>\r
- STRUCT_NAME:StringIdentifier ","\r
- Key "=" KNUM:Number ","\r
- Name "=" VAR_NAME:StringIdentifier "," \r
- Guid "=" \r
- OpenBrace \r
- G1:Number ","\r
- G2:Number ","\r
- G3:Number ","\r
- G4:Number ","\r
- G5:Number ","\r
- G6:Number ","\r
- G7:Number ","\r
- G8:Number ","\r
- G9:Number ","\r
- G10:Number ","\r
- G11:Number \r
- CloseBrace << WriteGuidValue (G1->getLine (), G1->getText (), G2->getText (), G3->getText (),\r
- G4->getText (), G5->getText (), G6->getText (), G7->getText (),\r
- G8->getText (), G9->getText (), G10->getText (), G11->getText ()\r
- );\r
- WriteWord (GetNumber (KNUM->getText(), KNUM->getLine(), 2)); \r
- AddVarStore (STRUCT_NAME->getText(), VAR_NAME->getText(), GetNumber (KNUM->getText(), KNUM->getLine(), 2), STRUCT_NAME->getLine());\r
- >>\r
- \r
- ";"\r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE: \r
-// vareqval var(0x100) == 0x20\r
-//\r
-vareqval : \r
- OPID:VarEqVal << WriteOpByte (OPID->getLine(), EFI_IFR_EQ_VAR_VAL_OP); >>\r
- Var OpenParen \r
- VAR:Number << WriteWord (GetNumber (VAR->getText(), VAR->getLine(), 2)); >>\r
- CloseParen\r
- compareNumber\r
- ;\r
-\r
-ideqval : \r
- OPID:IdEqVal << WriteOpByte (OPID->getLine(), EFI_IFR_EQ_ID_VAL_OP); >>\r
- vfrStructFieldName[0]\r
- compareNumber\r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-// ideqid MyNVData3.Field16A == MyNVData3.Field16B\r
-//\r
-// NOTE: Before processing the second variable store in the ideqid statement, set a global flag\r
-// so that when we parse the second variable we set the secondary variable store id.\r
-//\r
-ideqid : \r
- OPID:IdEqId << WriteOpByte (OPID->getLine(), EFI_IFR_EQ_ID_ID_OP); >>\r
- vfrStructFieldName[0]\r
- compareVfrStructFieldNameNL0\r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// compareNumber is the combination of compare operation and Number\r
-//\r
-compareNumber :\r
- (\r
- "=="\r
- VAL1:Number << WriteWord (GetNumber (VAL1->getText(), VAL1->getLine(), 2)); >>\r
- ) |\r
- (\r
- GTOPID:GreaterThan\r
- VAL2:Number << WriteWord (GetNumber (VAL2->getText(), VAL2->getLine(), 2));\r
- WriteOpByte (GTOPID->getLine(), EFI_IFR_GT_OP); >>\r
- ) |\r
- (\r
- GEOPID:GreaterEqual\r
- VAL3:Number << WriteWord (GetNumber (VAL3->getText(), VAL3->getLine(), 2));\r
- WriteOpByte (GEOPID->getLine(), EFI_IFR_GE_OP); >>\r
- ) |\r
- (\r
- LTOPID:LessThan\r
- VAL4:Number << WriteWord (GetNumber (VAL4->getText(), VAL4->getLine(), 2));\r
- WriteOpByte (LTOPID->getLine(), EFI_IFR_GE_OP);\r
- WriteOpByte (LTOPID->getLine(), EFI_IFR_NOT_OP); >>\r
- ) |\r
- (\r
- LEOPID:LessEqual\r
- VAL5:Number << WriteWord (GetNumber (VAL5->getText(), VAL5->getLine(), 2));\r
- WriteOpByte (LEOPID->getLine(), EFI_IFR_GT_OP);\r
- WriteOpByte (LEOPID->getLine(), EFI_IFR_NOT_OP); >>\r
- )\r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// compareVfrStructFieldNameNL0 is the combination of compare operation and vfrStructFieldNameNL[0]\r
-//\r
-compareVfrStructFieldNameNL0 :\r
- (\r
- "==" << mIdEqIdStmt = 1; >>\r
- vfrStructFieldNameNL[0] << mIdEqIdStmt = 0; >>\r
- ) |\r
- (\r
- GTOPID:GreaterThan << mIdEqIdStmt = 1; >>\r
- vfrStructFieldNameNL[0] << mIdEqIdStmt = 0;\r
- WriteOpByte (GTOPID->getLine(), EFI_IFR_GT_OP); >>\r
- ) |\r
- (\r
- GEOPID:GreaterEqual << mIdEqIdStmt = 1; >>\r
- vfrStructFieldNameNL[0] << mIdEqIdStmt = 0;\r
- WriteOpByte (GEOPID->getLine(), EFI_IFR_GE_OP); >>\r
- ) |\r
- (\r
- LTOPID:LessThan << mIdEqIdStmt = 1; >>\r
- vfrStructFieldNameNL[0] << mIdEqIdStmt = 0;\r
- WriteOpByte (LTOPID->getLine(), EFI_IFR_GE_OP);\r
- WriteOpByte (LTOPID->getLine(), EFI_IFR_NOT_OP); >>\r
- ) |\r
- (\r
- LEOPID:LessEqual << mIdEqIdStmt = 1; >>\r
- vfrStructFieldNameNL[0] << mIdEqIdStmt = 0;\r
- WriteOpByte (LEOPID->getLine(), EFI_IFR_GT_OP);\r
- WriteOpByte (LEOPID->getLine(), EFI_IFR_NOT_OP); >>\r
- )\r
- ;\r
- \r
-\r
-ideqvallist : \r
- OPID:IdEqValList << WriteOpByte (OPID->getLine(), EFI_IFR_EQ_ID_LIST_OP); >>\r
- vfrStructFieldName[0] \r
- "=="\r
- ( VAL:Number << QueueIdEqValList (GetNumber (VAL->getText(), VAL->getLine(), 2)); >> ) +\r
- << FlushQueueIdEqValList(); >>\r
- ;\r
- \r
-vfrStatementGoto : \r
- << UINT32 LineNum, KeyValue = 0; ResetFlags (); >>\r
- IDG:Goto << WriteOpByte (IDG->getLine(), EFI_IFR_REF_OP); >>\r
- VAL:Number "," << WriteWord (GetNumber (VAL->getText(), VAL->getLine(), 2)); \r
- AddGotoReference (GetNumber (VAL->getText(), VAL->getLine(), 2), VAL->getLine());\r
- >>\r
- KP:Prompt "=" getStringId "," << LineNum = KP->getLine(); >>\r
- Help "=" getStringId\r
- { \r
- "," \r
- FF:Flags "=" flagsField ( "\|" flagsField )* << LineNum = FF->getLine(); >>\r
- }\r
- {\r
- "," Key "=" KNUM:Number << LineNum = KNUM->getLine(); KeyValue = GetNumber(KNUM->getText(), LineNum, 2); >>\r
- }\r
- << WriteFlagsKey (KeyValue, LineNum); >>\r
- ";"\r
- ;\r
- \r
-vfrStatementHidden : \r
- IDH:Hidden << WriteOpByte (IDH->getLine(), EFI_IFR_HIDDEN_OP); >>\r
- Value "="\r
- VAL:Number "," << WriteWord (GetNumber (VAL->getText(), VAL->getLine(), 2)); >>\r
- Key "="\r
- KVAL:Number << WriteWord (GetNumber (KVAL->getText(), KVAL->getLine(), 2)); >>\r
- ";"\r
- ; \r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-// suppressif <boolean_expression> { grayoutif } <statements>+ endif;\r
-// Note:\r
-// You can have: suppressif:grayoutif:statements:endif\r
-// suppressif:grayoutif:endif -- serves no purpose\r
-// suppressif:statements:endif\r
-// suppressif:endif -- serves no purpose\r
-//\r
-vfrStatementSuppressIf : \r
- << ResetFlags (); >>\r
- OPID:SuppressIf << WriteOpByte (OPID->getLine(), EFI_IFR_SUPPRESS_IF_OP); SetIfStart (OPID->getLine()); >>\r
- { \r
- FF:Flags "=" flagsField ( "\|" flagsField )* ","\r
- }\r
- << WriteFlags (); >> // write the flags field \r
- vfrBooleanExpression\r
- ";"\r
- { suppressIfGrayOutIf } ( suppressIfAndGrayoutIfSubstatements )+\r
- ENDOP:EndIf ";" << WriteOpByte (ENDOP->getLine(), EFI_IFR_END_IF_OP); SetIfStart (0); >>\r
- ;\r
-\r
-//\r
-// This is the form for a grayoutif nested in a suppressif statement\r
-//\r
-suppressIfGrayOutIf :\r
- << ResetFlags (); >>\r
- OPID:GrayOutIf << WriteOpByte (OPID->getLine(), EFI_IFR_GRAYOUT_IF_OP); >>\r
- { \r
- FF:Flags "=" flagsField ( "\|" flagsField )* "," \r
- }\r
- << WriteFlags (); >> // write the flags field\r
- vfrBooleanExpression\r
- ";"\r
- ; \r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-// grayoutif { flags = n, } <boolean_expression> endif;\r
-// Note:\r
-// You can have: grayoutif:suppressif:statements:endif\r
-// grayoutif:statements:endif\r
-//\r
-//\r
-vfrStatementGrayOutIf :\r
- << ResetFlags (); >>\r
- OPID:GrayOutIf << WriteOpByte (OPID->getLine(), EFI_IFR_GRAYOUT_IF_OP); SetIfStart (OPID->getLine()); >>\r
- { \r
- FF:Flags "=" flagsField ( "\|" flagsField )* "," \r
- }\r
- << WriteFlags (); >> // write the flags field\r
- vfrBooleanExpression\r
- ";"\r
- { grayoutIfSuppressIf } ( suppressIfAndGrayoutIfSubstatements )+ \r
- ENDOP:EndIf ";" << WriteOpByte (ENDOP->getLine(), EFI_IFR_END_IF_OP); SetIfStart (0); >>\r
- ;\r
-\r
-//\r
-// This is the format for a suppressif nested in a grayoutif\r
-//\r
-grayoutIfSuppressIf : \r
- << ResetFlags (); >>\r
- OPID:SuppressIf << WriteOpByte (OPID->getLine(), EFI_IFR_SUPPRESS_IF_OP); >>\r
- { \r
- FF:Flags "=" flagsField ( "\|" flagsField )* ","\r
- }\r
- << WriteFlags (); >> // write the flags field\r
- vfrBooleanExpression\r
- ";"\r
- ;\r
-\r
-//\r
-// These are the VFR statements that are valid inside a suppressif or grayoutif statement.\r
-//\r
-suppressIfAndGrayoutIfSubstatements :\r
- vfrStatementOneOf |\r
- vfrStatementTextText |\r
- vfrStatementCheckBox |\r
- vfrStatementNumeric |\r
- vfrStatementDate |\r
- vfrStatementTime |\r
- vfrStatementPassword |\r
- vfrStatementString |\r
- vfrStatementHidden |\r
- vfrStatementGoto | \r
- vfrStatementLabel |\r
- vfrStatementInventory |\r
- vfrStatementOrderedList |\r
- vfrStatementSaveRestoreDefaults\r
- ; \r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-//\r
-// password varid = MyNvData.Password,\r
-// prompt = STRING_TOKEN(STR_PASSWORD_PROMPT),\r
-// help = STRING_TOKEN(STR_PASSWORD_HELP),\r
-// minsize = 6,\r
-// maxsize = 20,\r
-// encoding = 1,\r
-// endpassword; \r
- \r
-vfrStatementPassword : \r
- << UINT32 KeyValue = 0; UINT32 LineNum; ResetFlags (); >>\r
- IDPW:Password << WriteOpByte (IDPW->getLine(), EFI_IFR_PASSWORD_OP); >>\r
- VarId "=" vfrStructFieldNameArray[0] ","\r
- Prompt "=" getStringId ","\r
- KH:Help "=" getStringId "," << LineNum = KH->getLine(); >>\r
- { \r
- FF:Flags "=" flagsField ( "\|" flagsField )* "," << LineNum = FF->getLine(); >>\r
- }\r
- {\r
- Key "=" KNUM:Number "," << LineNum = KNUM->getLine(); KeyValue = GetNumber(KNUM->getText(), LineNum, 2); >>\r
- }\r
- << WriteFlagsKey (KeyValue, LineNum); >>\r
- MinSize "=" MIN:Number "," << WriteByte (GetNumber (MIN->getText(), MIN->getLine(), 1), 0); >>\r
- MaxSize "=" MAX:Number "," << WriteByte (GetNumber (MAX->getText(), MAX->getLine(), 1), 0); >>\r
- Encoding "=" ENC:Number "," << WriteWord (GetNumber (ENC->getText(), ENC->getLine(), 2)); >>\r
- EndPassword ";" \r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-//\r
-// string varid = MyNv.String,\r
-// prompt = STRING_TOKEN(STR_STRING_PROMPT),\r
-// help = STRING_TOKEN(STR_STRING_HELP),\r
-// flags = INTERACTIVE,\r
-// key = 0x1234,\r
-// minsize = 6,\r
-// maxsize = 0x14,\r
-// endstring; \r
-//\r
-// Since flags and key are optional, we can't use Flags->getLine(). Therefore for error\r
-// reporting we save the line number of the "help" keyword.\r
-//\r
-vfrStatementString : \r
- << unsigned int KeyValue = 0; UINT32 LineNum; ResetFlags (); >>\r
- IDS:String << WriteOpByte (IDS->getLine(), EFI_IFR_STRING_OP); >>\r
- VarId "=" vfrStructFieldNameArray[0] ","\r
- Prompt "=" getStringId ","\r
- KH:Help "=" getStringId "," << LineNum = KH->getLine(); >>\r
- { \r
- FF:Flags "=" \r
- flagsField ( "\|" flagsField )* << LineNum = FF->getLine(); >>\r
- "," \r
- }\r
- {\r
- Key "=" KNUM:Number "," << LineNum = KNUM->getLine(); KeyValue = GetNumber(KNUM->getText(), LineNum, 2); >>\r
- }\r
- << WriteFlagsKey (KeyValue, LineNum); >>\r
- MinSize "=" MIN:Number "," << WriteByte (GetNumber (MIN->getText(), MIN->getLine(), 1), 0); >>\r
- MaxSize "=" MAX:Number "," << WriteByte (GetNumber (MAX->getText(), MAX->getLine(), 1), 0); >>\r
- EndString ";"\r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-// numeric varid = MyIfrNVData.HowOldAreYouInYears, \r
-// prompt = STRING_TOKEN(STR_NUMERIC_PROMPT),\r
-// help = STRING_TOKEN(STR_NUMERIC_HELP),\r
-// flags = INTERACTIVE, // flags is optional\r
-// key = 0x1234, // key is optional if (flags & INTERACTIVE = 0)\r
-// minimum = 0x0,\r
-// maximum = 0xf0,\r
-// step = 1, // step is option, and step=1 if not specified\r
-// default = 0; // default is optional, and default=minimum if not specified\r
-// endnumeric;\r
-//\r
-// Make flags and key optional. However if flags includes INTERACTIVE, then a key is required.\r
-// That check is done in WriteFlagsKey() function.\r
-//\r
-vfrStatementNumeric : \r
- << UINT32 LineNum, KeyValue = 0; ResetFlags (); >>\r
- IDN:Numeric << WriteOpByte (IDN->getLine(), EFI_IFR_NUMERIC_OP); >>\r
- VarId "=" vfrStructFieldName[2] ","\r
- Prompt "=" getStringId ","\r
- KH:Help "=" getStringId "," << LineNum = KH->getLine(); >>\r
- { \r
- FF:Flags "=" flagsField ( "\|" flagsField )* "," << LineNum = FF->getLine (); >>\r
- }\r
- {\r
- Key "=" KNUM:Number "," << LineNum = KNUM->getLine(); KeyValue = GetNumber(KNUM->getText(), LineNum, 2); >>\r
- }\r
- << WriteFlagsKey (KeyValue, LineNum); >>\r
- minMaxStepDefault \r
- EndNumeric ";" << WriteMinMaxStepDefault (); >>\r
- ;\r
-\r
-//\r
-// Parse minimum/maximum/step/default statements. Special cases:\r
-// - if step not specified, then the value is 1\r
-// - if default not specified, then the value is the min value specified\r
-// - if max < min, print a warning and swap the values (changes default too)\r
-//\r
-minMaxStepDefault :\r
- << InitMinMaxStepDefault (); >>\r
- Minimum "=" MIN:Number "," << SetMinMaxStepDefault (GetNumber (MIN->getText(), MIN->getLine(), 2), 0, MIN->getLine()); >>\r
- Maximum "=" MAX:Number "," << SetMinMaxStepDefault (GetNumber (MAX->getText(), MAX->getLine(), 2), 1, MAX->getLine()); >>\r
- { Step "=" STEP:Number "," << SetMinMaxStepDefault (GetNumber (STEP->getText(), STEP->getLine(), 2), 2, STEP->getLine()); >> }\r
- { Default "=" DEF:Number "," << SetMinMaxStepDefault (GetNumber (DEF->getText(), DEF->getLine(), 2), 3, DEF->getLine()); >> }\r
- ;\r
-\r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-//\r
-// date year varid = Date.Year, // "Date.Year" is a special case we recognize\r
-// prompt = STRING_TOKEN(STR_DATE_PROMPT),\r
-// help = STRING_TOKEN(STR_DATE_YEAR_HELP),\r
-// minimum = 1939,\r
-// maximum = 2101,\r
-// step = 1,\r
-// default = 1964,\r
-//\r
-// month varid = Date.Month, \r
-// prompt = STRING_TOKEN(STR_DATE_PROMPT),\r
-// help = STRING_TOKEN(STR_DATE_MONTH_HELP),\r
-// minimum = 1,\r
-// maximum = 12,\r
-// step = 1,\r
-// default = 1,\r
-//\r
-// day varid = Date.Day,\r
-// prompt = STRING_TOKEN(STR_DATE_PROMPT),\r
-// help = STRING_TOKEN(STR_DATE_DAY_HELP),\r
-// minimum = 1,\r
-// maximum = 31,\r
-// step = 0x1,\r
-// default = 1,\r
-//\r
-// enddate;\r
-// \r
-vfrStatementDate : \r
- Date \r
- IDY:Year VarId "=" << WriteOpByte (IDY->getLine(), EFI_IFR_DATE_OP); >>\r
- vfrStructFieldName[2] "," \r
- dateTimeSubStatement \r
- IDM:Month VarId "=" << WriteOpByte (IDM->getLine(), EFI_IFR_DATE_OP); >>\r
- vfrStructFieldName[2] "," \r
- dateTimeSubStatement \r
- IDD:Day VarId "=" << WriteOpByte (IDD->getLine(), EFI_IFR_DATE_OP); >> \r
- vfrStructFieldName[2] "," \r
- dateTimeSubStatement \r
- EndDate ";"\r
- ;\r
- \r
-vfrStatementTime : \r
- Time \r
- IDH:Hour VarId "=" << WriteOpByte (IDH->getLine(), EFI_IFR_TIME_OP); >>\r
- vfrStructFieldName[2] "," \r
- dateTimeSubStatement \r
- IDM:Minute VarId "=" << WriteOpByte (IDM->getLine(), EFI_IFR_TIME_OP); >>\r
- vfrStructFieldName[2] "," \r
- dateTimeSubStatement \r
- IDS:Second VarId "=" << WriteOpByte (IDS->getLine(), EFI_IFR_TIME_OP); >>\r
- vfrStructFieldName[2] "," \r
- dateTimeSubStatement\r
- EndTime ";"\r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-//\r
-// text text = STRING_ID;\r
-// text text = STRING_ID, text = STRING_ID;\r
-// text text = STRING_ID, text = STRING_ID, flags = x, key = y;\r
-//\r
-vfrStatementTextText :\r
- << ResetFlags (); >>\r
- IDT:Text << WriteOpByte (IDT->getLine(), EFI_IFR_TEXT_OP); >>\r
- Help "=" getStringId ","\r
- Text "=" \r
- getStringId // writes string identifier\r
- { "," Text "=" getStringId\r
- "," Flags "=" flagsField ( "\|" flagsField )* << WriteFlags (); >>\r
- "," \r
- Key "=" KNUM:Number << WriteWord (GetNumber(KNUM->getText(), KNUM->getLine(), 2)); >>\r
- }\r
- ";" \r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-//\r
-// inventory help = ID, text = ID;\r
-// inventory help = ID, text = id, text = ID;\r
-//\r
-vfrStatementInventory :\r
- IDI:Inventory << WriteOpByte (IDI->getLine(), EFI_IFR_INVENTORY_OP); >>\r
- Help "=" getStringId ","\r
- Text "=" getStringId // writes string identifier\r
- { "," Text "=" getStringId\r
- }\r
- ";" \r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-//\r
-// restore defaults,\r
-// formid = 4,\r
-// prompt = STRING_TOKEN(STR_RESTORE_DEFAULTS_PROMPT),\r
-// help = STRING_TOKEN(STR_RESTORE_DEFAULTS_HELP),\r
-// flags = 0,\r
-// key = 0;\r
-//\r
-// save defaults,\r
-// formid = 4,\r
-// prompt = STRING_TOKEN(STR_SAVE_DEFAULTS_PROMPT),\r
-// help = STRING_TOKEN(STR_SAVE_DEFAULTS_HELP),\r
-// flags = 0,\r
-// key = 0;\r
-//\r
-vfrStatementSaveRestoreDefaults : \r
- << unsigned int KeyValue = 0; UINT32 LineNum; ResetFlags (); >>\r
- ( IDS:Save << WriteOpByte (IDS->getLine(), EFI_IFR_SAVE_DEFAULTS_OP); >>\r
- | IDR:Restore << WriteOpByte (IDR->getLine(), EFI_IFR_RESTORE_DEFAULTS_OP); >>\r
- )\r
- Defaults ","\r
- FormId "=" FRMID:Number "," << WriteWord (GetNumber (FRMID->getText(), FRMID->getLine(), 2)); \r
- AddGotoReference (GetNumber (FRMID->getText(), FRMID->getLine(), 2), FRMID->getLine());\r
- >>\r
- Prompt "=" getStringId ","\r
- KH:Help "=" getStringId << LineNum = KH->getLine(); >>\r
- { \r
- "," FF:Flags "=" flagsField ( "\|" flagsField )* << LineNum = FF->getLine(); >>\r
- }\r
- {\r
- "," Key "=" KNUM:Number << LineNum = KNUM->getLine(); KeyValue = GetNumber(KNUM->getText(), LineNum, 2); >>\r
- }\r
- << WriteFlagsKey (KeyValue, LineNum); >>\r
- ";"\r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-//\r
-// flags = 0x10 | DEFAULT | MANUFACTURING | INTERACTIVE | NV_ACCESS | RESET_REQUIRED | LATE_CHECK\r
-//\r
-// \r
-flagsField :\r
- VAL:Number << SetFlags (GetNumber(VAL->getText(), VAL->getLine(), 4), VAL->getLine()); >>\r
- | IF:InteractiveFlag << SetFlags (EFI_IFR_FLAG_INTERACTIVE, IF->getLine()); >>\r
- | MF:ManufacturingFlag << SetFlags (EFI_IFR_FLAG_MANUFACTURING, MF->getLine()); >>\r
- | DF:DefaultFlag << SetFlags (EFI_IFR_FLAG_DEFAULT, DF->getLine()); >>\r
- | NV:NVAccessFlag << SetFlags (EFI_IFR_FLAG_NV_ACCESS, NV->getLine()); >>\r
- | RR:ResetRequiredFlag << SetFlags (EFI_IFR_FLAG_RESET_REQUIRED, RR->getLine()); >>\r
- | LC:LateCheckFlag << SetFlags (EFI_IFR_FLAG_LATE_CHECK, LC->getLine()); >>\r
- ;\r
-\r
-dateTimeSubStatement :\r
- Prompt "=" getStringId ","\r
- Help "=" getStringId ","\r
- << WriteByte (0, 0); WriteWord (0); >> // bogus flags and key\r
- minMaxStepDefault << WriteMinMaxStepDefault (); >>\r
- ;\r
- \r
-vfrStatementCheckBox : \r
- << UINT32 LineNum, KeyValue = 0; ResetFlags (); >>\r
- IDCB:CheckBox << WriteOpByte (IDCB->getLine(), EFI_IFR_CHECKBOX_OP); >>\r
- VarId "=" vfrStructFieldName[1] ","\r
- Prompt "=" getStringId ","\r
- Help "=" getStringId ","\r
- FF:Flags "=" flagsField ( "\|" flagsField )* "," << LineNum = FF->getLine(); >>\r
- { \r
- Key "=" KV:Number "," << LineNum = KV->getLine(); KeyValue = GetNumber(KV->getText(), LineNum, 2); >>\r
- }\r
- << WriteFlagsKey (KeyValue, LineNum); >>\r
- EndCheckBox ";"\r
- ;\r
- \r
-vfrStatementSubTitle :\r
- IDS:Subtitle Text "=" << WriteOpByte (IDS->getLine(), EFI_IFR_SUBTITLE_OP); >>\r
- getStringId // writes string indentifier\r
- ";"\r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-// banner \r
-// title = STRING_TOKEN(STR_BANNER_TITLE),\r
-// line 1,\r
-// align center; // or left or right\r
-//\r
-// banner, \r
-// title = STRING_TOKEN(STR_BANNER_TITLE), timeout = 100;\r
-//\r
-vfrStatementBanner :\r
- IDB:Banner { "," } << WriteOpByte (IDB->getLine(), EFI_IFR_BANNER_OP); >>\r
- Title "=" getStringId ","\r
- ( \r
- Line VAL:Number "," << WriteWord (GetNumber(VAL->getText(), VAL->getLine(), 2)); >>\r
- Align \r
- ( Left << WriteByte (EFI_IFR_BANNER_ALIGN_LEFT, 0); >>\r
- | Center << WriteByte (EFI_IFR_BANNER_ALIGN_CENTER, 0); >>\r
- | Right << WriteByte (EFI_IFR_BANNER_ALIGN_RIGHT, 0); >>\r
- ) ";"\r
- |\r
- Timeout "=" TO:Number ";" << WriteWord (GetNumber(TO->getText(), TO->getLine(), 2)); >>\r
- << WriteByte (EFI_IFR_BANNER_TIMEOUT, 0); >>\r
- )\r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-// oneof varid = MyNv.OneOfData,\r
-// prompt = STRING_TOKEN(STR_ONE_OF_PROMPT),\r
-// help = STRING_TOKEN(STR_ONE_OF_HELP),\r
-// option text = STRING_TOKEN(STR_ONE_OF_TEXT), \r
-// value = 0, \r
-// flags = DEFAULT | INTERACTIVE;\r
-//\r
-// supressif/grayoutif are supported inside oneof stmt.\r
-// We do not restrict the number of oneOfOptionText to >=2, but >=1.\r
-// The situation that all oneOfOptionText are suppressed is also possiable.\r
-//\r
-vfrStatementOneOf :\r
- << ResetFlags (); >>\r
- IDOO:OneOf << WriteOpByte (IDOO->getLine(), EFI_IFR_ONE_OF_OP); >>\r
- VarId "=" vfrStructFieldName[2] "," \r
- Prompt "=" getStringId "," // writes string identifier\r
- Help "=" getStringId "," // writes string identifier\r
- ( oneOfOptionText )+ // there must be at least 1 option to be choosed, not 2.\r
- IDEOO:EndOneOf ";" << TestOneOfFlags (IDEOO->getLine()); WriteOpByte (IDEOO->getLine(), EFI_IFR_END_ONE_OF_OP); >>\r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-// \r
-// orderedlist varid = MyNv.OrderedListData,\r
-// prompt = STRING_TOKEN(STR_ORDERED_LIST_PROMPT),\r
-// help = STRING_TOKEN(STR_ORDERED_LIST_HELP), \r
-// option text = STRING_TOKEN(STR_ORDERED_LIST_TEXT), value = 0, flags = INTERACTIVE;\r
-// -- additional option text -- \r
-// endlist;\r
-//\r
-vfrStatementOrderedList :\r
- << ResetFlags (); InitOrderedList(); >>\r
- IDOL:OrderedList << WriteOpByte (IDOL->getLine(), EFI_IFR_ORDERED_LIST_OP); >>\r
- VarId "=" vfrStructFieldNameArray[1] "," \r
- Prompt "=" getStringId "," // writes string identifier\r
- Help "=" getStringId "," // writes string identifier\r
- orderedListOptionText ( orderedListOptionText )+\r
- IDEOL:EndList ";" << WriteOpByte (IDEOL->getLine(), EFI_IFR_END_OP); EndOrderedList(IDEOL->getLine()); >>\r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-//\r
-// option text = STRING_TOKEN(STRING_ID), value = 0 flags = 99;\r
-//\r
-// Differs from the oneOfOptionText in that we don't allow the DEFAULT flag to\r
-// be set, and value cannot be 0.\r
-//\r
-orderedListOptionText :\r
- << UINT32 KeyValue = 0; >>\r
- IDO:Option << WriteOpByte (IDO->getLine(), EFI_IFR_ONE_OF_OPTION_OP); >>\r
- Text "=" getStringId "," // writes string identifier\r
- Value "=" WVAL:Number "," << \r
- if (GetNumber(WVAL->getText(), WVAL->getLine(), 2) == 0) {\r
- PrintErrorMessage (WVAL->getLine(), "value=0 is invalid for ordered lists", NULL); \r
- } else {\r
- WriteWord (GetNumber(WVAL->getText(), WVAL->getLine(), 2)); \r
- }\r
- >>\r
- FF:Flags "=" orderedListFlagsField \r
- ("\|" orderedListFlagsField )* \r
- { \r
- "," Key "=" KV:Number << KeyValue = GetNumber (KV->getText(), KV->getLine(), 2); >> \r
- }\r
- << WriteFlagsKey (KeyValue, FF->getLine()); >>\r
- ";" << mOptionCount++; >>\r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-//\r
-// flags = 0x10 | DEFAULT | MANUFACTURING | INTERACTIVE | NV_ACCESS | RESET_REQUIRED | LATE_CHECK\r
-//\r
-// The ordered list flags field cannot have a default.\r
-//\r
-orderedListFlagsField :\r
- VAL:Number << SetFlags (GetNumber(VAL->getText(), VAL->getLine(), 4), VAL->getLine()); >>\r
- | IF:InteractiveFlag << SetFlags (EFI_IFR_FLAG_INTERACTIVE, IF->getLine()); >>\r
- | MF:ManufacturingFlag << SetFlags (EFI_IFR_FLAG_MANUFACTURING, MF->getLine()); >>\r
- | NV:NVAccessFlag << SetFlags (EFI_IFR_FLAG_NV_ACCESS, NV->getLine()); >>\r
- | RR:ResetRequiredFlag << SetFlags (EFI_IFR_FLAG_RESET_REQUIRED, RR->getLine()); >>\r
- | LC:LateCheckFlag << SetFlags (EFI_IFR_FLAG_LATE_CHECK, LC->getLine()); >>\r
- | DF:DefaultFlag << PrintWarningMessage (DF->getLine(), "DEFAULT flag not valid for ordered lists", NULL); >>\r
- ;\r
-\r
-//\r
-// Parse references to VFR structure field names of form "MyNvStructure.Field". \r
-// This implementation is specific to strings, passwords, and references in an \r
-// ordered list statement because we want to specify the size of the entire \r
-// field, rather than just one element. Then call a function to write out its \r
-// offset and length.\r
-//\r
-vfrStructFieldNameArray[int FieldWidth] :\r
- << int ArrayIndex = 1; char IsArrayIndex = 0; >>\r
- SName:StringIdentifier \r
- "." \r
- SFieldName:StringIdentifier \r
- { OpenBracket AIndex:Number CloseBracket << ArrayIndex = GetNumber(AIndex->getText(), AIndex->getLine(), 4); IsArrayIndex = 1; >> }\r
- << \r
- WriteFieldOffset (1, \r
- SName->getText(), \r
- SName->getLine(), \r
- SFieldName->getText(), \r
- SFieldName->getLine(),\r
- ArrayIndex, \r
- IsArrayIndex,\r
- FieldWidth,\r
- 1\r
- ); \r
- >>\r
- ;\r
-\r
-//\r
-// Parse references to VFR structure field names of form "MyNvStructure.Field",\r
-// then call a function to write out its offset and length.\r
-//\r
-vfrStructFieldName[int FieldWidth] :\r
- << int ArrayIndex = 1; char IsArrayIndex = 0; >>\r
- SName:StringIdentifier \r
- "." \r
- SFieldName:StringIdentifier \r
- { OpenBracket AIndex:Number CloseBracket << ArrayIndex = GetNumber(AIndex->getText(), AIndex->getLine(), 4); IsArrayIndex = 1; >> }\r
- << \r
- WriteFieldOffset (1, \r
- SName->getText(), \r
- SName->getLine(), \r
- SFieldName->getText(), \r
- SFieldName->getLine(),\r
- ArrayIndex, \r
- IsArrayIndex,\r
- FieldWidth,\r
- 0\r
- ); \r
- >>\r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-//\r
-// MyNvStructure.FieldName[4]\r
-//\r
-// Parse references to VFR structure field names of form "MyNvStructure.Field",\r
-// then call a function to write out the offset with no length.\r
-//\r
-vfrStructFieldNameNL[int FieldWidth] :\r
- << int ArrayIndex = 1; char IsArrayIndex = 0; >>\r
- SName:StringIdentifier \r
- "." \r
- SFieldName:StringIdentifier \r
- { OpenBracket AIndex:Number CloseBracket << ArrayIndex = GetNumber(AIndex->getText(), AIndex->getLine(), 4); IsArrayIndex = 1; >> }\r
- << \r
- WriteFieldOffset (0, \r
- SName->getText(), \r
- SName->getLine(), \r
- SFieldName->getText(), \r
- SFieldName->getLine(),\r
- ArrayIndex, \r
- IsArrayIndex,\r
- FieldWidth,\r
- 0\r
- ); \r
- >>\r
- ;\r
-\r
-//*****************************************************************************\r
-//\r
-// PARSE:\r
-// suppressif TRUE OR FALSE;\r
-// grayoutif FALSE OR TRUE;\r
-// option text = STRING_TOKEN(STRING_ID), value = 0 flags = 99;\r
-// option text = STRING_TOKEN(STRING_ID2), value = 1 flags = 98;\r
-// endif;\r
-//\r
-oneOfOptionText :\r
- suppressIfOptionText |\r
- grayOutIfOptionText |\r
- commonOptionText\r
- ;\r
-\r
-suppressIfOptionText : \r
- << ResetFlags (); >>\r
- OPID:SuppressIf << WriteOpByte (OPID->getLine(), EFI_IFR_SUPPRESS_IF_OP); SetIfStart (OPID->getLine()); >>\r
- { \r
- FF:Flags "=" flagsField ( "\|" flagsField )* ","\r
- }\r
- << WriteFlags (); >> // write the flags field \r
- vfrBooleanExpression\r
- ";"\r
- { suppressIfGrayOutIf } ( commonOptionText )+\r
- ENDOP:EndIf ";" << WriteOpByte (ENDOP->getLine(), EFI_IFR_END_IF_OP); SetIfStart (0); >>\r
- ;\r
-\r
-grayOutIfOptionText :\r
- << ResetFlags (); >>\r
- OPID:GrayOutIf << WriteOpByte (OPID->getLine(), EFI_IFR_GRAYOUT_IF_OP); SetIfStart (OPID->getLine()); >>\r
- { \r
- FF:Flags "=" flagsField ( "\|" flagsField )* "," \r
- }\r
- << WriteFlags (); >> // write the flags field\r
- vfrBooleanExpression\r
- ";"\r
- { grayoutIfSuppressIf } ( commonOptionText )+ \r
- ENDOP:EndIf ";" << WriteOpByte (ENDOP->getLine(), EFI_IFR_END_IF_OP); SetIfStart (0); >>\r
- ;\r
-\r
-commonOptionText : \r
- << UINT32 KeyValue = 0; >>\r
- IDO:Option << WriteOpByte (IDO->getLine(), EFI_IFR_ONE_OF_OPTION_OP); >>\r
- Text "=" getStringId "," // writes string identifier\r
- Value "=" WVal:Number "," << WriteWord (GetNumber(WVal->getText(), WVal->getLine(), 2)); >>\r
- FF:Flags "=" flagsField ("\|" flagsField )* \r
- { \r
- "," Key "=" KV:Number << KeyValue = GetNumber (KV->getText(), KV->getLine(), 2); >> \r
- }\r
- << WriteFlagsKey (KeyValue, FF->getLine()); >>\r
- ";" << mOptionCount++; >>\r
- ;\r
-\r
-//\r
-// Gets a string identifier. It must be a numeric value of form:\r
-// \r
-// STRING_TOKEN(100)\r
-//\r
-getStringId :\r
- << unsigned short StrId; >>\r
- StringToken OpenParen\r
- IdVal:Number << StrId = GetNumber (IdVal->getText(), IdVal->getLine(), 2); WriteStringIdWord (StrId); >> \r
- CloseParen\r
- ;\r
-\r
-//******************************************************************************\r
-//\r
-// Parser class definition. \r
-// \r
-class EfiVfrParser {\r
-<<\r
-//\r
-// Parser definitions go here \r
-//\r
-private:\r
- STRUCT_DEFINITION *mFirstStructDefinition;\r
- STRUCT_DEFINITION *mLastStructDefinition;\r
- INT32 mNvDataStructSize; \r
- INT32 mNonNvDataStructSize;\r
- //\r
- // Flag to indicate that we're processing a ideqid VFR statement so that\r
- // we can do late checks on the statement.\r
- //\r
- INT32 mIdEqIdStmt;\r
- INT32 mLastNVVariableDataSize;\r
- GOTO_REFERENCE *mGotoReferences;\r
- FORM_ID_VALUE *mFormIdValues;\r
- VfrOpcodeHandler mOpcodeHandler;\r
- UINT16_LIST *mUint16List;\r
- UINT16_LIST *mLastUint16;\r
- UINT16_LIST *mDefinedLabels;\r
- UINT16_LIST *mDefinedVarStoreId;\r
- UINT16_LIST *mLastDefinedVarStoreId;\r
- UINT32 mMinimumValue, mMaximumValue, mStepValue, mDefaultValue;\r
- UINT32 mStmtFlags;\r
- UINT32 mSubStmtFlags;\r
- UINT32 mSubStmtFlagsLineNum;\r
- EFI_GUID mFormSetGuid;\r
- UINT8 mNvDataStructDefined;\r
- UINT16 mClass, mSubclass;\r
- UINT32 mIfStart;\r
- UINT32 mOptionCount; // how many "option" fields in a given statement\r
- UINT32 mLastVarIdSize;\r
- UINT8 mOutput;\r
-public: \r
-\r
-VOID \r
-EfiVfrParser::SetIfStart (\r
- UINT32 LineNum\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Invoked during VFR parsing when an "if" is encountered. Save the\r
- source line number so we can point to it if we don't find a \r
- corresponding endif later.\r
-\r
-Arguments:\r
- LineNum - source line number where the "if" was parsed.\r
-\r
-Returns:\r
- None\r
-\r
---*/\r
-{\r
- mIfStart = LineNum;\r
-}\r
-VOID \r
-EfiVfrParser::SetClass (\r
- UINT32 LineNum, \r
- UINT32 Value\r
- ) \r
-/*++\r
-\r
-Routine Description:\r
- Invoked during VFR parsing when a "class" statement is found. Check the\r
- range on the class value and save it for later.\r
-\r
-Arguments:\r
- LineNum - source line number where the class statement was parsed.\r
- Value - the class value\r
-\r
-Returns:\r
- None\r
-\r
---*/\r
-{\r
- if (Value & 0xFFFF0000) {\r
- PrintWarningMessage (LineNum, NULL, "class value exceeds maximum allowed");\r
- }\r
- mClass |= (UINT16)Value;\r
-}\r
-VOID \r
-EfiVfrParser::SetSubclass (\r
- UINT32 LineNum, \r
- UINT32 Value\r
- ) \r
-/*++\r
-\r
-Routine Description:\r
- Invoked during VFR parsing when a subclass statement is found. Check the\r
- range on the value and save it for later.\r
-\r
-Arguments:\r
- LineNum - source line number where the class statement was parsed.\r
- Value - the subclass value from the VFR statement\r
-\r
-Returns:\r
- None\r
-\r
---*/\r
-{\r
- if (Value & 0xFFFF0000) {\r
- PrintWarningMessage (LineNum, NULL, "subclass value exceeds maximum allowed");\r
- }\r
- mSubclass |= (UINT16)Value;\r
-}\r
-VOID EfiVfrParser::WriteClass ()\r
-{\r
- WriteWord (mClass);\r
- mClass = 0;\r
-}\r
-VOID EfiVfrParser::WriteSubclass ()\r
-{\r
- WriteWord (mSubclass);\r
- mSubclass = 0;\r
-}\r
-VOID EfiVfrParser::WriteIfrBytes ()\r
-{\r
- mOpcodeHandler.WriteIfrBytes ();\r
-}\r
-VOID \r
-EfiVfrParser::WriteFlagsKey (\r
- UINT32 KeyValue, \r
- UINT32 LineNum\r
- ) \r
-/*++\r
-\r
-Routine Description:\r
- Write out the flags and key values from the previous VFR statement.\r
- Many statements take a flags/key pair. If not specified, then 0\r
- values are written out. However do not allow an interactive flags field\r
- to be specified if no key value is specified. Also, if NV_ACCESS flag\r
- is set but INTERACTIVE is not, then set interactive and issue a warning.\r
-\r
-Arguments:\r
- KeyValue - the key value from the VFR statement\r
- LineNum - source line number where the statement was parsed\r
-\r
-Returns:\r
- None\r
-\r
---*/\r
-{\r
- if ((mSubStmtFlags & EFI_IFR_FLAG_INTERACTIVE) && (KeyValue == 0)) {\r
- PrintErrorMessage (LineNum, NULL, "invalid or missing key value - required with INTERACTIVE");\r
- }\r
- if ((mSubStmtFlags & EFI_IFR_FLAG_NV_ACCESS) && !(mSubStmtFlags & EFI_IFR_FLAG_INTERACTIVE)) {\r
- PrintWarningMessage (LineNum, NULL, "NV_ACCESS without INTERACTIVE has no effect -- setting INTERACTIVE");\r
- mSubStmtFlags |= EFI_IFR_FLAG_INTERACTIVE;\r
- }\r
- WriteFlags ();\r
- WriteWord (KeyValue);\r
-}\r
-VOID \r
-EfiVfrParser::InitOrderedList ()\r
-{\r
- mOptionCount = 0;\r
-} \r
-VOID \r
-EfiVfrParser::EndOrderedList (\r
- UINT32 LineNum\r
- )\r
-{\r
- if (mLastVarIdSize < mOptionCount) {\r
- PrintErrorMessage (LineNum, NULL, "number of options exceeds the variable store size");\r
- }\r
-}\r
-VOID \r
-EfiVfrParser::ResetFlags ()\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Flags are set for each substatement in a given one-of statement.\r
- To make sure there are no conflicts, for example setting DEFAULT on\r
- more than one substatement, we keep track of the flags at a statement\r
- level and a substatement level. This function resets the flags so \r
- we get a fresh start.\r
-\r
-Arguments:\r
- None\r
-\r
-Returns:\r
- None\r
-\r
---*/\r
-{\r
- mStmtFlags = 0;\r
- mSubStmtFlagsLineNum = 0;\r
- mSubStmtFlags = 0;\r
-}\r
-//\r
-// Test validity of flags value for a one-of statement.\r
-//\r
-VOID \r
-EfiVfrParser::TestOneOfFlags (\r
- UINT32 LineNum\r
- ) \r
-{\r
- //\r
- // One of the fields must have had the default bit set\r
- //\r
- if ((mStmtFlags & EFI_IFR_FLAG_DEFAULT) == 0) {\r
- PrintWarningMessage (LineNum, "default value must be specified", NULL);\r
- }\r
-}\r
-VOID \r
-EfiVfrParser::SetFlags (\r
- UINT32 Flags, \r
- UINT32 LineNum\r
- ) \r
-{\r
- //\r
- // Check for redefinitions and invalid combinations\r
- //\r
- if (mStmtFlags & Flags & EFI_IFR_FLAG_MANUFACTURING) {\r
- PrintErrorMessage (LineNum, "MANUFACTURING", "a field with this flag already defined");\r
- }\r
- if (mStmtFlags & Flags & EFI_IFR_FLAG_DEFAULT) {\r
- PrintErrorMessage (LineNum, "DEFAULT", "a field with this flag already defined");\r
- }\r
- mSubStmtFlags |= Flags;\r
- mSubStmtFlagsLineNum = LineNum;\r
-}\r
-VOID \r
-EfiVfrParser::WriteFlags ()\r
-{\r
- //\r
- // Check value for validity\r
- //\r
- if (mSubStmtFlags & ~(EFI_IFR_FLAG_DEFAULT | \r
- EFI_IFR_FLAG_MANUFACTURING | \r
- EFI_IFR_FLAG_INTERACTIVE | \r
- EFI_IFR_FLAG_NV_ACCESS | \r
- EFI_IFR_FLAG_RESET_REQUIRED | \r
- EFI_IFR_FLAG_LATE_CHECK )) {\r
- PrintWarningMessage (mSubStmtFlagsLineNum, "invalid bits defined in flag", NULL);\r
- }\r
- WriteByte ((UINT8)mSubStmtFlags, 'F');\r
- //\r
- // We can now clear the substatement flags\r
- //\r
- mStmtFlags |= mSubStmtFlags;\r
- mSubStmtFlags = 0;\r
-}\r
-//\r
-// When we parse a min/max/step/default sequence, save off the values for\r
-// later use. Call this first to init the values.\r
-//\r
-VOID \r
-EfiVfrParser::InitMinMaxStepDefault ()\r
-{\r
- mMinimumValue = 0;\r
- mMaximumValue = 0;\r
- mStepValue = 1;\r
- mDefaultValue = 0;\r
-} \r
-VOID \r
-EfiVfrParser::WriteMinMaxStepDefault ()\r
-{\r
- WriteWord (mMinimumValue);\r
- WriteWord (mMaximumValue);\r
- WriteWord (mStepValue);\r
- WriteWord (mDefaultValue);\r
-} \r
-VOID \r
-EfiVfrParser::SetMinMaxStepDefault (\r
- UINT16 Value, \r
- INT32 MMSD, \r
- INT32 LineNum\r
- ) \r
-{\r
- UINT16 TempValue;\r
- //\r
- // Min specified\r
- //\r
- if (MMSD == 0) {\r
- mMinimumValue = Value;\r
- mDefaultValue = Value;\r
- //\r
- // Max specified\r
- //\r
- } else if (MMSD == 1) {\r
- mMaximumValue = Value;\r
- //\r
- // If min > max, then swap the values. That includes resetting the default\r
- // value as well.\r
- //\r
- if (mMinimumValue > mMaximumValue) {\r
- PrintWarningMessage (LineNum, NULL, "maximum < minimum"); \r
- TempValue = Value;\r
- mMaximumValue = mMinimumValue;\r
- mMinimumValue = TempValue;\r
- mDefaultValue = mMinimumValue;\r
- }\r
- //\r
- // Step specified\r
- //\r
- } else if (MMSD == 2) { \r
- mStepValue = Value;\r
- //\r
- // Default specified. Make sure min <= default <= max.\r
- //\r
- } else if (MMSD == 3) {\r
- mDefaultValue = Value;\r
- if (mMinimumValue > Value) {\r
- PrintErrorMessage (LineNum, NULL, "default value < minimum value");\r
- } else if (Value > mMaximumValue) {\r
- PrintErrorMessage (LineNum, NULL, "default value > maximum value");\r
- }\r
- } else {\r
- PrintErrorMessage (LineNum, "application error", "internal MMSD error"); \r
- }\r
-}\r
-VOID \r
-EfiVfrParser::AddLabel (\r
- UINT32 LabelNumber, \r
- UINT32 LineNum\r
- ) \r
-{\r
- UINT16_LIST *Label;\r
-\r
- //\r
- // Added a label from the user VFR script. Make sure they haven't already \r
- // defined the same label elsewhere\r
- //\r
- for (Label = mDefinedLabels; Label != NULL; Label = Label->Next) {\r
- if (Label->Value == LabelNumber) {\r
- PrintErrorMessage (LineNum, NULL, "label already defined");\r
- PrintErrorMessage (Label->LineNum, NULL, "previous definition of redefined label");\r
- break;\r
- }\r
- }\r
- Label = (UINT16_LIST *)malloc (sizeof (UINT16_LIST));\r
- if (Label == NULL) {\r
- PrintErrorMessage (0, NULL, "memory allocation error");\r
- return;\r
- }\r
- memset ((char *)Label, 0, sizeof (UINT16_LIST));\r
- Label->Value = LabelNumber;\r
- Label->LineNum = LineNum;\r
- Label->Next = mDefinedLabels;\r
- mDefinedLabels = Label;\r
-}\r
-VOID \r
-EfiVfrParser::QueueIdEqValList (\r
- UINT16 Value\r
- )\r
-{\r
- UINT16_LIST *U16;\r
- \r
- U16 = (UINT16_LIST *)malloc (sizeof (UINT16_LIST));\r
- if (U16 == NULL) {\r
- Error (UTILITY_NAME, 0, 0, NULL, "memory allocation failed");\r
- } else {\r
- memset ((char *)U16, 0, sizeof (UINT16_LIST));\r
- U16->Value = Value;\r
- if (mUint16List == NULL) {\r
- mUint16List = U16;\r
- } else {\r
- mLastUint16->Next = U16;\r
- } \r
- mLastUint16 = U16;\r
- }\r
-} \r
-VOID \r
-EfiVfrParser::FlushQueueIdEqValList ()\r
-{\r
- UINT32 Count;\r
- \r
- //\r
- // We queued up a list of IdEqValList items. The IFR requires a count\r
- // followed by the actual values. Do it.\r
- //\r
- Count = 0;\r
- mLastUint16 = mUint16List;\r
- while (mLastUint16 != NULL) {\r
- Count++;\r
- mLastUint16 = mLastUint16->Next;\r
- }\r
- // BUGBUG -- check for more than 16K items?\r
- WriteWord (Count);\r
- //\r
- // Now write the values.\r
- //\r
- mLastUint16 = mUint16List;\r
- while (mLastUint16 != NULL) {\r
- WriteWord ((UINT32)mLastUint16->Value);\r
- mLastUint16 = mLastUint16->Next;\r
- }\r
- //\r
- // Free up the list\r
- // \r
- mLastUint16 = mUint16List;\r
- while (mUint16List != NULL) {\r
- mLastUint16 = mUint16List->Next;\r
- free (mUint16List);\r
- mUint16List = mLastUint16;\r
- }\r
-}\r
-VOID \r
-EfiVfrParser::PrintErrorMessage (\r
- UINT32 LineNum,\r
- INT8 *Msg1,\r
- INT8 *Msg2\r
- )\r
-{\r
- char *FileName;\r
- \r
- if (LineNum != 0) {\r
- FileName = ConvertLineNumber ((UINT32 *)&LineNum);\r
- Error (FileName, LineNum, 0, Msg1, Msg2);\r
- } else {\r
- Error (UTILITY_NAME, 0, 0, Msg1, Msg2);\r
- }\r
-}\r
-VOID \r
-EfiVfrParser::PrintWarningMessage (\r
- UINT32 LineNum,\r
- INT8 *Msg1,\r
- INT8 *Msg2\r
- )\r
-{\r
- char *FileName;\r
- \r
- if (LineNum != 0) {\r
- FileName = ConvertLineNumber ((UINT32 *)&LineNum);\r
- Warning (FileName, LineNum, 0, Msg1, Msg2);\r
- } else {\r
- Warning (UTILITY_NAME, 0, 0, Msg1, Msg2);\r
- }\r
-}\r
-VOID \r
-EfiVfrParser::syn (\r
- ANTLRAbstractToken *Tok, \r
- ANTLRChar *Egroup, \r
- SetWordType *Eset, \r
- ANTLRTokenType ETok, \r
- INT32 Huh\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Called by the parser base class as a result of parse syntax errors.\r
-\r
-Arguments:\r
- Tok - token that caused the error\r
- Egroup - not sure\r
- Eset - index in token table of the expected token\r
- Huh - not sure\r
-\r
-Returns:\r
- NA\r
-\r
---*/\r
-{\r
- char *FileName;\r
- UINT32 LineNum;\r
- \r
- LineNum = Tok->getLine ();\r
- FileName = ConvertLineNumber ((UINT32 *)&LineNum);\r
- //\r
- // Sometimes the token number is 0, in which case I don't know what to\r
- // print.\r
- //\r
- if (ETok == 0) {\r
- Error (FileName, LineNum, 0, Tok->getText (), "unexpected token");\r
- } else {\r
- //\r
- // If we were expecting an endif, then report the line where the corresponding\r
- // IF began.\r
- //\r
- if ((strcmp (_token_tbl[ETok], "endif") == 0) && (mIfStart != 0)) {\r
- LineNum = mIfStart;\r
- FileName = ConvertLineNumber (&LineNum);\r
- Error (FileName, LineNum, 0, "statement missing corresponding endif", NULL);\r
- } else {\r
- Error (FileName, LineNum, 0, Tok->getText (), "expected %s", _token_tbl[ETok]);\r
- }\r
- }\r
-}\r
-\r
-VOID \r
-EfiVfrParser::init() \r
-/*++\r
-\r
-Routine Description:\r
- Initializations function for our parser.\r
-\r
-Arguments:\r
- None.\r
-\r
-Returns:\r
- None.\r
-\r
---*/\r
-{\r
- ANTLRParser::init();\r
-\r
- //\r
- // Used for queuing a variable list of UINT16's\r
- //\r
- mUint16List = NULL;\r
- mLastUint16 = NULL;\r
- mFirstStructDefinition = NULL;\r
- mLastStructDefinition = NULL;\r
- mNvDataStructSize = 0;\r
- mNonNvDataStructSize = 0;\r
- mNvDataStructDefined = 0;\r
- mGotoReferences = NULL;\r
- mFormIdValues = NULL;\r
- mDefinedLabels = NULL;\r
- mClass = 0;\r
- mSubclass = 0;\r
- mIfStart = 0;\r
- mDefinedVarStoreId = NULL;\r
- mLastDefinedVarStoreId = NULL;\r
- mIdEqIdStmt = 0;\r
- mLastNVVariableDataSize = 0;\r
- \r
- memset ((char *)&mFormSetGuid, 0, sizeof (EFI_GUID));\r
-}\r
-//\r
-// Destructor for the parser.\r
-//\r
-EfiVfrParser::~EfiVfrParser(VOID)\r
-{\r
- Cleanup();\r
-}\r
-VOID\r
-EfiVfrParser::Cleanup (VOID)\r
-/*++\r
-\r
-Routine Description:\r
- Free memory allocated during parsing\r
-\r
-Arguments:\r
- None.\r
-\r
-Returns:\r
- None.\r
-\r
---*/\r
-{\r
- STRUCT_DEFINITION *NextStruct;\r
- STRUCT_FIELD_DEFINITION *NextField;\r
- UINT8 Buff[6];\r
- UINT16_LIST *NextU16List;\r
- \r
- //\r
- // Free up the structure definitions if any\r
- //\r
- while (mFirstStructDefinition != NULL) {\r
- //\r
- // Free up all the fields for this struct\r
- //\r
- while (mFirstStructDefinition->Field != NULL) {\r
- NextField = mFirstStructDefinition->Field->Next;\r
- free (mFirstStructDefinition->Field->Name);\r
- free (mFirstStructDefinition->Field);\r
- mFirstStructDefinition->Field = NextField;\r
- }\r
- NextStruct = mFirstStructDefinition->Next;\r
- free (mFirstStructDefinition->Name);\r
- free (mFirstStructDefinition);\r
- mFirstStructDefinition = NextStruct;\r
- }\r
- //\r
- // Free up the goto references and form id defines\r
- //\r
- FreeGotoReferences ();\r
- //\r
- // Free up label list\r
- //\r
- while (mDefinedLabels != NULL) {\r
- NextU16List = mDefinedLabels->Next;\r
- delete (mDefinedLabels);\r
- mDefinedLabels = NextU16List;\r
- }\r
- //\r
- // Free up the list of defined variable storage IDs\r
- //\r
- while (mDefinedVarStoreId != NULL) {\r
- NextU16List = mDefinedVarStoreId->Next;\r
- delete (mDefinedVarStoreId);\r
- mDefinedVarStoreId = NextU16List;\r
- }\r
-}\r
-\r
-INT32 \r
-EfiVfrParser::AtoX (\r
- INT8 *HexString, \r
- INT32 NumBytes, \r
- UINT32 *HexValue\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Given a pointer to a ascii hex string, convert to a number with the given\r
- number of bytes.\r
-\r
-Arguments:\r
- HexString - pointer to a string of format 30BCA\r
- Size - number of bytes to convert\r
- HexValue - return result\r
-\r
-Returns:\r
- The number of bytes converted.\r
-\r
---*/\r
-{\r
- INT32 Count;\r
- INT32 Value;\r
-\r
- *HexValue = 0;\r
- Count = 0;\r
- while (Count < NumBytes) {\r
- if ((*HexString >= '0') && (*HexString <= '9')) {\r
- Value = *HexString - '0';\r
- } else if ((*HexString >= 'a') && (*HexString <= 'f')) {\r
- Value = *HexString - 'a' + 10;\r
- } else if ((*HexString >= 'A') && (*HexString <= 'F')) {\r
- Value = *HexString - 'A' + 10;\r
- } else {\r
- return Count;\r
- }\r
- HexString++;\r
- *HexValue = (*HexValue << 4) | Value;\r
- if ((*HexString >= '0') && (*HexString <= '9')) {\r
- Value = *HexString - '0';\r
- } else if ((*HexString >= 'a') && (*HexString <= 'f')) {\r
- Value = *HexString - 'a' + 10;\r
- } else if ((*HexString >= 'A') && (*HexString <= 'F')) {\r
- Value = *HexString - 'A' + 10;\r
- } else {\r
- return Count;\r
- }\r
- *HexValue = (*HexValue << 4) | Value;\r
- HexString++;\r
- Count++;\r
- }\r
- return Count;\r
-}\r
-VOID \r
-EfiVfrParser::WriteGuidValue (\r
- UINT32 TokenLineNum,\r
- INT8 *G1, \r
- INT8 *G2,\r
- INT8 *G3,\r
- INT8 *G4,\r
- INT8 *G5,\r
- INT8 *G6,\r
- INT8 *G7,\r
- INT8 *G8,\r
- INT8 *G9,\r
- INT8 *G10,\r
- INT8 *G11\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- A Guid was parsed, likely of format:\r
- #define MY_GUID { 0x12345678, 0xAABB, 0xCCDD, 0xEE, 0xFF, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 }\r
-\r
- Write out the value.\r
-\r
-Arguments:\r
- TokenLineNum - line number where the guid was used\r
- G1-G11 - the 11 fields of the guid value\r
-\r
-Returns:\r
- None.\r
-\r
---*/\r
-{\r
- UINT32 Value;\r
- INT32 Loop;\r
- INT8 *Cptr;\r
-\r
- mFormSetGuid.Data1 = GetNumber (G1, TokenLineNum, 4);\r
- mFormSetGuid.Data2 = (UINT16)GetNumber (G2, TokenLineNum, 2);\r
- mFormSetGuid.Data3 = (UINT16)GetNumber (G3, TokenLineNum, 2);\r
- mFormSetGuid.Data4[0] = (UINT8)GetNumber (G4, TokenLineNum, 1);\r
- mFormSetGuid.Data4[1] = (UINT8)GetNumber (G5, TokenLineNum, 1);\r
- mFormSetGuid.Data4[2] = (UINT8)GetNumber (G6, TokenLineNum, 1);\r
- mFormSetGuid.Data4[3] = (UINT8)GetNumber (G7, TokenLineNum, 1);\r
- mFormSetGuid.Data4[4] = (UINT8)GetNumber (G8, TokenLineNum, 1);\r
- mFormSetGuid.Data4[5] = (UINT8)GetNumber (G9, TokenLineNum, 1);\r
- mFormSetGuid.Data4[6] = (UINT8)GetNumber (G10, TokenLineNum, 1);\r
- mFormSetGuid.Data4[7] = (UINT8)GetNumber (G11, TokenLineNum, 1);\r
- \r
- WriteDWord (mFormSetGuid.Data1, 'G');\r
- WriteWord (mFormSetGuid.Data2);\r
- WriteWord (mFormSetGuid.Data3);\r
- WriteByte (mFormSetGuid.Data4[0], 0);\r
- WriteByte (mFormSetGuid.Data4[1], 0);\r
- WriteByte (mFormSetGuid.Data4[2], 0);\r
- WriteByte (mFormSetGuid.Data4[3], 0);\r
- WriteByte (mFormSetGuid.Data4[4], 0);\r
- WriteByte (mFormSetGuid.Data4[5], 0);\r
- WriteByte (mFormSetGuid.Data4[6], 0);\r
- WriteByte (mFormSetGuid.Data4[7], 0);\r
-}\r
-VOID \r
-EfiVfrParser::WriteFieldOffset (\r
- INT8 WriteLength,\r
- INT8 *StructName, \r
- INT32 LineNum1, \r
- INT8 *FieldName, \r
- INT32 LineNum2,\r
- INT32 ArrayIndex,\r
- INT8 IsArrayIndex,\r
- INT32 FieldWidth,\r
- INT8 WriteArraySize\r
- ) \r
-/*++\r
-\r
-Routine Description:\r
- A VFR script referenced the NV store structure. Given the structure's name\r
- and the field's name, write the offset of the field to the output file.\r
-\r
-Arguments:\r
- WriteLength - write the field length byte out\r
- StructName - name of the NV store structure\r
- LineNum1 - line number in the VFR where we are (for error printing)\r
- FieldName - the name of the field within the NV store structure\r
- LineNum2 - line number in the VFR where FieldName is referenced \r
- ArrayIndex - the index specified, for example NV_DATA.Field[ArrayIndex]\r
- IsArrayIndex - non-zero if an array index was specified\r
- FieldWidth - expected size for the Field (1 byte? 2 bytes?)\r
- WriteArraySize - write the size of the entire field, not the size of a single element\r
-\r
-Returns:\r
- None.\r
-\r
---*/\r
-{\r
- STRUCT_DEFINITION *StructDef;\r
- STRUCT_FIELD_DEFINITION *FieldDef;\r
- UINT32 Offset;\r
- UINT32 VarSize;\r
- INT8 Msg[100];\r
- //\r
- // If we're writing an array size, then they better have referenced the field without an\r
- // index. \r
- //\r
- if (WriteArraySize && IsArrayIndex) {\r
- sprintf (Msg, "array index specified where an array is required");\r
- PrintErrorMessage (LineNum2, FieldName, Msg);\r
- return;\r
- }\r
-\r
- //\r
- // The reference index starts at 1 not 0\r
- //\r
- if (IsArrayIndex && (ArrayIndex < 1)) {\r
- printf ("WARNING: array index shouldn't be less than 1");\r
- }\r
- //\r
- // Look through our list of known structures for a match\r
- //\r
- for (StructDef = mFirstStructDefinition; StructDef != NULL; StructDef = StructDef->Next) {\r
- //\r
- // Check for matching structure name\r
- //\r
- if (strcmp (StructDef->Name, StructName) == 0) {\r
- //\r
- // Mark it as referenced (for debug purposes only). Check the\r
- // flag that indicates that we have already found a varstore VFR\r
- // statement for it.\r
- //\r
- StructDef->Referenced++;\r
- if (StructDef->VarStoreIdValid == 0) {\r
- //\r
- // Set it valid so we don't flag it multiple times, then emit the error\r
- //\r
- StructDef->VarStoreIdValid = 1;\r
- PrintErrorMessage (LineNum1, StructName, "varstore statement missing for this variable store");\r
- }\r
- //\r
- // Let the opcode-handler know which variable storage we're now using\r
- //\r
- if (mIdEqIdStmt) {\r
- mOpcodeHandler.SetSecondaryVarStoreId (StructDef->VarStoreId);\r
- } else {\r
- mOpcodeHandler.SetVarStoreId (StructDef->VarStoreId);\r
- }\r
- //\r
- // Found matching structure name. Now find the matching field name\r
- //\r
- for (FieldDef = StructDef->Field; FieldDef != NULL; FieldDef = FieldDef->Next) {\r
- if (strcmp (FieldDef->Name, FieldName) == 0) {\r
- //\r
- // Make sure the variable size is valid\r
- //\r
- if ((FieldWidth != 0) && (FieldDef->DataSize > FieldWidth)) {\r
- sprintf (Msg, "field width exceeds %d byte%c", FieldWidth, FieldWidth == 1 ? ' ' : 's');\r
- PrintErrorMessage (LineNum2, FieldName, Msg);\r
- }\r
- //\r
- // If they specified an index (MyVfrData.FieldX[10]), then make sure that the\r
- // data structure was declared as an array, and that the index is in bounds.\r
- // If they did not specify an index, then we'll assume 0. This is required for\r
- // strings.\r
- //\r
- if (IsArrayIndex) {\r
- VarSize = FieldDef->DataSize;\r
- if (FieldDef->IsArray == 0) {\r
- PrintErrorMessage (LineNum2, FieldName, "field is not declared as an array");\r
- return;\r
- }\r
- if (FieldDef->ArrayLength < ArrayIndex) {\r
- PrintErrorMessage (LineNum2, FieldName, "array index exceeds declared size of field");\r
- return;\r
- }\r
- } else {\r
- if (FieldDef->IsArray) {\r
- VarSize = FieldDef->DataSize * FieldDef->ArrayLength;\r
- } else {\r
- VarSize = FieldDef->DataSize;\r
- }\r
- }\r
- //\r
- // If we're in the middle of a ideqid VFR statement, then this is the second\r
- // variable ID that we're now processing. Make sure that its size is the same\r
- // as the first variable.\r
- // \r
- if (mIdEqIdStmt) {\r
- if (mLastVarIdSize != VarSize) {\r
- PrintErrorMessage (LineNum2, FieldName, "variables must have the same size");\r
- return;\r
- }\r
- }\r
- mLastVarIdSize = VarSize;\r
- //\r
- // If we're supposed to write an array size, then require it to be an array\r
- //\r
- if (WriteArraySize && !FieldDef->IsArray) {\r
- PrintErrorMessage (LineNum2, FieldName, "array required");\r
- return;\r
- }\r
- //\r
- // Write the variable offset and size. If we're in the non-NV structure, then\r
- // set the offset beyond the NV data structure size.\r
- //\r
- Offset = FieldDef->Offset + FieldDef->DataSize * (ArrayIndex - 1);\r
- if (StructDef->IsNonNV) Offset += mNvDataStructSize; \r
- WriteWord (Offset);\r
- if (WriteLength) {\r
- if (WriteArraySize) {\r
- if (FieldDef->DataSize * FieldDef->ArrayLength > 255) {\r
- PrintErrorMessage (LineNum2, FieldName, "array size exceeds 255 maximum encoding limit");\r
- return;\r
- }\r
- WriteByte (FieldDef->DataSize * FieldDef->ArrayLength, 0);\r
- } else {\r
- WriteByte (FieldDef->DataSize, 0);\r
- }\r
- }\r
- return;\r
- }\r
- }\r
- sprintf (Msg, "structure %s does not have a field named '%s'", StructName, FieldName);\r
- PrintErrorMessage (LineNum2, Msg, NULL);\r
- PrintErrorMessage (StructDef->LineNum, "see structure definition", NULL);\r
- return;\r
- }\r
- }\r
- //\r
- // The structure was not found in the defined list. See if it's the "Date" structure\r
- //\r
- if (strcmp (StructName, "Date") == 0) {\r
- //\r
- // BUGBUG -- remove support for Date and Time as valid structure \r
- // names. They should use the NON_NV_DATA_MAP structure for this.\r
- //\r
- // Someone specified Date.Years|Months|Days\r
- // BUGBUG -- define some constants for the IDs used here\r
- // Length == 0 implies that this is not user NV data storage.\r
- //\r
- if (strcmp (FieldName, "Year") == 0) {\r
- //\r
- // Write ID (offset), ID, and size\r
- //\r
- WriteWord (mNvDataStructSize + mNonNvDataStructSize + 0);\r
- if (WriteLength) {\r
- WriteByte (0, 0);\r
- }\r
- } else if (strcmp (FieldName, "Month") == 0) {\r
- //\r
- // Write ID (offset), ID, and size\r
- //\r
- WriteWord (mNvDataStructSize + mNonNvDataStructSize + 2);\r
- if (WriteLength) {\r
- WriteByte (0, 0);\r
- }\r
- } else if (strcmp (FieldName, "Day") == 0) {\r
- //\r
- // Write ID (offset), ID, and size\r
- //\r
- WriteWord (mNvDataStructSize + mNonNvDataStructSize + 4);\r
- if (WriteLength) {\r
- WriteByte (0, 0);\r
- }\r
- } else {\r
- PrintErrorMessage (LineNum1, FieldName, "expected valid field name TheYear/TheMonth/TheDay");\r
- }\r
- return;\r
- } else if (strcmp (StructName, "Time") == 0) {\r
- //\r
- // Someone specified Time.Hours|Minutes|Seconds\r
- // BUGBUG -- define some constants for the IDs used here\r
- //\r
- if (strcmp (FieldName, "Hours") == 0) {\r
- //\r
- // Write ID (offset), ID, and size\r
- //\r
- WriteWord (mNvDataStructSize + mNonNvDataStructSize + 6);\r
- if (WriteLength) {\r
- WriteByte (0, 0);\r
- }\r
- } else if (strcmp (FieldName, "Minutes") == 0) {\r
- //\r
- // Write ID (offset), ID, and size\r
- //\r
- WriteWord (mNvDataStructSize + mNonNvDataStructSize + 8);\r
- if (WriteLength) {\r
- WriteByte (0, 0);\r
- }\r
- } else if (strcmp (FieldName, "Seconds") == 0) {\r
- //\r
- // Write ID (offset), ID, and size\r
- //\r
- WriteWord (mNvDataStructSize + mNonNvDataStructSize + 10);\r
- if (WriteLength) {\r
- WriteByte (0, 0);\r
- }\r
- } else {\r
- PrintErrorMessage (LineNum1, FieldName, "expected valid field name Hours/Minutes/Seconds");\r
- }\r
- return;\r
- } else {\r
- PrintErrorMessage (LineNum1, StructName, "undefined structure");\r
- return;\r
- }\r
-}\r
-VOID\r
-EfiVfrParser::StartStructDefinition (\r
- INT32 IsNonNV,\r
- INT32 LineNum\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Called when we encounter a new "struct _MY_STRUCT..." statement while parsing. \r
- Initialize internal data and structures for parsing the fields of the structure.\r
-\r
-Arguments:\r
- LineNum - line number in the source file (for error reporting purposes)\r
- IsNonNv - flag indicating (if nonzero) that the variable referred to is not in\r
- the standard NV store.\r
-Returns:\r
- None\r
-\r
---*/\r
-{\r
- STRUCT_DEFINITION *StructDef;\r
- //\r
- // Allocate memory for the structure record\r
- //\r
- StructDef = (STRUCT_DEFINITION *)malloc (sizeof (STRUCT_DEFINITION));\r
- memset (StructDef, 0, sizeof (STRUCT_DEFINITION));\r
- StructDef->LineNum = LineNum;\r
- //\r
- // Set flag indicating non-NV data structure or not\r
- //\r
- StructDef->IsNonNV = IsNonNV;\r
- //\r
- // Add it to the end of our linked list. If it's the first one\r
- // defined, then it's the default varstore ID, so set it valid.\r
- //\r
- if (mFirstStructDefinition == NULL) {\r
- mFirstStructDefinition = StructDef;\r
- StructDef->VarStoreIdValid = 1;\r
- } else {\r
- mLastStructDefinition->Next = StructDef;\r
- }\r
- mLastStructDefinition = StructDef;\r
-}\r
-VOID\r
-EfiVfrParser::EndStructDefinition (\r
- INT8 *StructName,\r
- INT32 LineNum\r
- )\r
-{\r
- STRUCT_DEFINITION *StructDef;\r
- STRUCT_FIELD_DEFINITION *FieldDef;\r
- UINT32 Offset;\r
- //\r
- // Make sure they have not already defined a structure with this name\r
- //\r
- for (StructDef = mFirstStructDefinition; StructDef != NULL; StructDef = StructDef->Next) {\r
- if ((StructDef->Name != NULL) && (strcmp (StructDef->Name, StructName) == 0)) {\r
- PrintErrorMessage (LineNum, StructName, "structure with this name already defined");\r
- //\r
- // Fall through and fill in the rest of the structure information. We do\r
- // this because the structure has already been added to our global list,\r
- // so will be used elsewhere, so we want it to contain valid fields.\r
- //\r
- }\r
- } \r
- //\r
- // Allocate memory for the structure name \r
- //\r
- mLastStructDefinition->Name = (char *)malloc (strlen (StructName) + 1);\r
- strcpy (mLastStructDefinition->Name, StructName);\r
- //\r
- // Compute the structure size, and the offsets to each field\r
- //\r
- Offset = 0;\r
- for (FieldDef = mLastStructDefinition->Field; FieldDef != NULL; FieldDef = FieldDef->Next) {\r
- FieldDef->Offset = Offset;\r
- Offset += FieldDef->ArrayLength * FieldDef->DataSize;\r
- }\r
- mLastStructDefinition->Size = Offset;\r
- //\r
- // Go through all the structure we have so far and figure out (if we can)\r
- // the size of the non-NV storage. We also assume that the first structure\r
- // definition is the primary/default storage for the VFR form.\r
- //\r
- if (mNonNvDataStructSize == 0) {\r
- for (StructDef = mFirstStructDefinition; StructDef != NULL; StructDef = StructDef->Next) {\r
- if (StructDef->IsNonNV) {\r
- mNonNvDataStructSize = StructDef->Size;\r
- break;\r
- }\r
- }\r
- }\r
- if (mNvDataStructSize == 0) {\r
- for (StructDef = mFirstStructDefinition; StructDef != NULL; StructDef = StructDef->Next) {\r
- if (StructDef->IsNonNV == 0) {\r
- mNvDataStructSize = StructDef->Size;\r
- break;\r
- }\r
- }\r
- }\r
-}\r
-VOID \r
-EfiVfrParser::AddStructField (\r
- INT8 *FieldName, \r
- INT32 LineNum, \r
- INT32 DataSize,\r
- INT32 ArrayLength,\r
- INT8 IsArray\r
- ) \r
-/*++\r
-\r
-Routine Description:\r
- We're parsing the VFR structure definition. Add another defined field to \r
- our definition.\r
-\r
-Arguments:\r
- FieldName - name of the field in the structure.\r
- LineNum - the line number from the input (preprocessor output) file\r
- DataSize - the size of the field (1, 2, or 4 bytes)\r
- ArrayLength - the number of elements (for array)\r
- IsArray - non-zero if the field is an array\r
-\r
-Returns:\r
- None.\r
-\r
---*/\r
-{\r
- STRUCT_FIELD_DEFINITION *FieldDef;\r
- STRUCT_FIELD_DEFINITION *Temp;\r
- //\r
- // Make sure we don't already have a field of this name in our structure\r
- //\r
- for (FieldDef = mLastStructDefinition->Field; FieldDef != NULL; FieldDef = FieldDef->Next) {\r
- if (strcmp (FieldDef->Name, FieldName) == 0) {\r
- PrintErrorMessage (LineNum, FieldName, "field with this name already defined");\r
- return;\r
- }\r
- } \r
- //\r
- // If it's an array, then they better not have a size of 0. For example:\r
- // UINT8 MyBytes[0];\r
- //\r
- if (IsArray && (ArrayLength <= 0)) {\r
- PrintErrorMessage (LineNum, FieldName, "invalid array size");\r
- return;\r
- } \r
- //\r
- // Allocate memory for a new structure field definition\r
- // \r
- FieldDef = (STRUCT_FIELD_DEFINITION *)malloc (sizeof (STRUCT_FIELD_DEFINITION));\r
- memset ((char *)FieldDef, 0, sizeof (STRUCT_FIELD_DEFINITION));\r
- FieldDef->ArrayLength = ArrayLength;\r
- FieldDef->DataSize = DataSize;\r
- FieldDef->IsArray = IsArray;\r
- FieldDef->Name = (char *)malloc (strlen (FieldName) + 1);\r
- strcpy (FieldDef->Name, FieldName);\r
- //\r
- // Add it to the end of the field list for the currently active structure\r
- //\r
- if (mLastStructDefinition->Field == NULL) {\r
- mLastStructDefinition->Field = FieldDef;\r
- } else {\r
- mLastStructDefinition->LastField->Next = FieldDef;\r
- }\r
- mLastStructDefinition->LastField = FieldDef;\r
-}\r
-VOID\r
-EfiVfrParser::AddVarStore (\r
- INT8 *StructName, // actual name of the structure\r
- INT8 *VarName, // actual NV variable name\r
- UINT16 VarStoreId, // key value\r
- INT32 LineNum // parse line number (for error reporting)\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Called while parsing a varstore statement. Add the variable store \r
- to our linked list.\r
-\r
-Arguments:\r
- StructName - the name of the typedef'ed structure to use\r
- VarName - the NV variable name as specified in the varstore statement\r
- VarStoreId - the variable store ID as specified in the varstore statememt\r
- LineNum - the line number from the input (preprocessor output) file\r
-\r
-Returns:\r
- None.\r
-\r
---*/\r
-{\r
- STRUCT_DEFINITION *StructDef;\r
- UINT16_LIST *L16Ptr;\r
- //\r
- // Go through our list of previously-defined variable store IDs and\r
- // make sure this one is not a duplicate in name or key value.\r
- //\r
- for (L16Ptr = mDefinedVarStoreId; L16Ptr != NULL; L16Ptr = L16Ptr->Next) {\r
- if (L16Ptr->Value == VarStoreId) {\r
- PrintErrorMessage (LineNum, "variable storage key already used", NULL);\r
- PrintErrorMessage (L16Ptr->LineNum, "previous usage of storage key", NULL);\r
- }\r
- }\r
- // \r
- // Key value of 0 is invalid since that's assigned by default to the default\r
- // variable store (the first structure parsed).\r
- //\r
- if (VarStoreId == 0) {\r
- PrintErrorMessage (LineNum, "variable storage key of 0 is invalid", NULL);\r
- }\r
- //\r
- // Create a new element to add to the list\r
- //\r
- L16Ptr = (UINT16_LIST *)malloc(sizeof (UINT16_LIST));\r
- memset (L16Ptr, 0, sizeof (UINT16_LIST));\r
- L16Ptr->LineNum = LineNum;\r
- L16Ptr->Value = VarStoreId;\r
- if (mDefinedVarStoreId == NULL) {\r
- mDefinedVarStoreId = L16Ptr;\r
- } else {\r
- mLastDefinedVarStoreId->Next = L16Ptr;\r
- }\r
- mLastDefinedVarStoreId = L16Ptr;\r
- //\r
- // Find the structure definition with this name\r
- //\r
- for (StructDef = mFirstStructDefinition; StructDef != NULL; StructDef = StructDef->Next) {\r
- if (strcmp (StructDef->Name, StructName) == 0) {\r
- //\r
- // Make sure they did not already define a variable storage ID \r
- // for this structure.\r
- //\r
- if (StructDef->VarStoreId != 0) {\r
- PrintErrorMessage (LineNum, StructName, "variable storage already defined for this structure");\r
- PrintErrorMessage (StructDef->VarStoreLineNum, StructName, "previous definition for variable storage");\r
- }\r
- StructDef->VarStoreId = VarStoreId;\r
- StructDef->VarStoreIdValid = 1;\r
- StructDef->VarStoreLineNum = LineNum;\r
- WriteWord (StructDef->Size);\r
- while (*VarName) {\r
- WriteByte(*VarName, 0);\r
- VarName++;\r
- }\r
- WriteByte(0,0);\r
- return;\r
- }\r
- } \r
- PrintErrorMessage (LineNum, StructName, "structure with this name not defined");\r
-}\r
-VOID \r
-EfiVfrParser::WriteDWord (\r
- UINT32 Value, \r
- UINT8 KeyByte\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- During parsing, we came upon some code that requires a 32-bit value be\r
- written to the VFR binary file. Queue up the 4 bytes.\r
-\r
-Arguments:\r
- Value - the 32-bit value to write\r
- KeyByte - a single character which gets written out beside the first byte.\r
- This is used to tag the data in the output file so that during \r
- debug you have an idea what the value is.\r
-\r
-Returns:\r
- None.\r
-\r
---*/\r
-{\r
- //\r
- // Write 4 bytes, little endian. Specify a key byte only on the first one\r
- //\r
- mOpcodeHandler.AddByte ((UINT8)Value, KeyByte);\r
- Value \>>= 8;\r
- mOpcodeHandler.AddByte ((UINT8)Value, 0);\r
- Value \>>= 8;\r
- mOpcodeHandler.AddByte ((UINT8)Value, 0);\r
- Value \>>= 8;\r
- mOpcodeHandler.AddByte ((UINT8)Value, 0);\r
-}\r
-VOID \r
-EfiVfrParser::WriteOpByte (\r
- UINT32 LineNum,\r
- UINT8 ByteValue\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- \r
- During parsing, we came upon a new VFR opcode. At this point we flush\r
- the output queue and then queue up this byte (with 'O' for opcode tag).\r
-\r
-Arguments:\r
-\r
- ByteValue - opcode value\r
-\r
-Returns:\r
-\r
- None.\r
-\r
---*/\r
-{\r
- mOpcodeHandler.AddOpcodeByte (ByteValue, LineNum);\r
-}\r
-VOID \r
-EfiVfrParser::WriteByte (\r
- UINT8 ByteValue, \r
- UINT8 Key\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- \r
- During parsing of the VFR we spoonfeed this function with bytes to write to\r
- the output VFR binary file. This function simply queues up the bytes, and\r
- the queue gets flushed each time a new VFR opcode is encountered.\r
-\r
-Arguments:\r
-\r
- ByteValue - raw byte to write\r
- Key - character to tag the byte with when we write ByteValue to the\r
- output file.\r
-\r
-Returns:\r
-\r
- None.\r
-\r
---*/\r
-{\r
- mOpcodeHandler.AddByte (ByteValue, Key);\r
-}\r
-VOID \r
-EfiVfrParser::WriteWord (\r
- UINT32 Value\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- During VFR parsing we came upon a case where we need to write out a \r
- 16-bit value. Queue it up.\r
-\r
-Arguments:\r
- Value - value to write.\r
-\r
-Returns:\r
- None.\r
-\r
---*/\r
-{\r
- mOpcodeHandler.AddByte ((UINT8)Value, 0);\r
- mOpcodeHandler.AddByte ((UINT8)((Value \>> 8) & 0xFF), 0);\r
-}\r
-VOID \r
-EfiVfrParser::WriteStringIdWord (\r
- UINT16 WordValue\r
- )\r
-{\r
- mOpcodeHandler.AddByte ((UINT8)WordValue, 'S');\r
- mOpcodeHandler.AddByte ((UINT8)((WordValue \>> 8) & 0xFF), 0);\r
-}\r
-VOID\r
-EfiVfrParser::FreeGotoReferences ()\r
-/*++\r
-\r
-Routine Description:\r
- Called during cleanup to free up the memory we allocated when\r
- keeping track of VFR goto statements.\r
-\r
-Arguments:\r
- None\r
-\r
-Returns:\r
- None\r
-\r
---*/\r
-{\r
- GOTO_REFERENCE *CurrRef;\r
- GOTO_REFERENCE *NextRef;\r
- FORM_ID_VALUE *CurrFormId;\r
- FORM_ID_VALUE *NextFormId;\r
- UINT8 Found;\r
- INT8 Name[20];\r
-\r
- //\r
- // Go through all the "goto" references and make sure there was a \r
- // form ID of that value defined.\r
- //\r
- for (CurrRef = mGotoReferences; CurrRef != NULL; CurrRef = CurrRef->Next) {\r
- Found = 0;\r
- for (CurrFormId = mFormIdValues; CurrFormId != NULL; CurrFormId = CurrFormId->Next) {\r
- if (CurrRef->Value == CurrFormId->Value) {\r
- Found = 1;\r
- break;\r
- }\r
- }\r
- if (!Found) {\r
- sprintf (Name, "%d", (UINT32)CurrRef->Value);\r
- PrintErrorMessage (CurrRef->RefLineNum, Name, "undefined form ID");\r
- } \r
- } \r
- //\r
- // Now free up the form id and goto references\r
- //\r
- CurrFormId = mFormIdValues;\r
- while (CurrFormId != NULL) {\r
- NextFormId = CurrFormId->Next;\r
- free (CurrFormId);\r
- CurrFormId = NextFormId;\r
- }\r
- mFormIdValues = NULL;\r
- CurrRef = mGotoReferences;\r
- while (CurrRef != NULL) {\r
- NextRef = CurrRef->Next;\r
- free (CurrRef);\r
- CurrRef = NextRef;\r
- } \r
- mGotoReferences = NULL;\r
-}\r
-VOID\r
-EfiVfrParser::AddGotoReference (\r
- UINT32 GotoNumber,\r
- UINT32 LineNum\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- During VFR parsing we came upon a goto statement. Since we support\r
- forward references, save the referenced label and at the end of parsing\r
- we'll check that the label was actually defined somewhere.\r
-\r
-Arguments:\r
- GotoNumber - the label number referenced\r
- LineNum - the line number where the reference was made (used for\r
- error reporting)\r
-\r
-Returns:\r
- None\r
-\r
---*/\r
-{\r
- GOTO_REFERENCE *NewRef;\r
- \r
- NewRef = (GOTO_REFERENCE *)malloc (sizeof (GOTO_REFERENCE));\r
- if (NewRef == NULL) {\r
- Error (UTILITY_NAME, 0, 0, NULL, "memory allocation failure");\r
- return;\r
- }\r
- memset ((char *)NewRef, 0, sizeof (GOTO_REFERENCE));\r
- NewRef->Value = (UINT16)GotoNumber;\r
- NewRef->RefLineNum = LineNum;\r
- NewRef->Next = mGotoReferences;\r
- mGotoReferences = NewRef;\r
-}\r
-VOID\r
-EfiVfrParser::AddFormId (\r
- INT32 FormIdValue,\r
- UINT32 LineNum\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- This function is called when we parse "form formid = 3" statements.\r
- We save the form ID valud so we can verify that duplicates are not\r
- defined. Also, these are the targets of goto statements, so when we're\r
- done parsing the script we also go through all the goto statements to\r
- check that there was a target FormId defined as referenced by each\r
- goto statement.\r
- \r
- Note that formid = 0 is invalid.\r
-\r
-Arguments:\r
- FormIdValue - the parsed value for the Form ID\r
- LineNum - line number of the source file we're parsing\r
-\r
-Returns:\r
- NA\r
-\r
---*/\r
-{\r
- FORM_ID_VALUE *NewFormId;\r
- char *FileName;\r
- char *FileName2;\r
- UINT32 LineNum2; \r
- //\r
- // Verify that FormId != 0\r
- //\r
- if (FormIdValue == 0) {\r
- FileName = ConvertLineNumber (&LineNum);\r
- Error (FileName, LineNum, 0, "form ID cannot be 0", NULL);\r
- return;\r
- }\r
- //\r
- // First go through all previously defined form IDs and make sure they have not defined\r
- // duplicates.\r
- //\r
- for (NewFormId = mFormIdValues; NewFormId != NULL; NewFormId = NewFormId->Next) {\r
- if ((UINT16)FormIdValue == NewFormId->Value) {\r
- FileName = ConvertLineNumber (&LineNum);\r
- LineNum2 = NewFormId->LineNum;\r
- FileName2 = ConvertLineNumber (&LineNum2);\r
- Error (FileName, LineNum, 0, NULL, "form ID %d already defined", FormIdValue);\r
- Error (FileName2, LineNum2, 0, NULL, "form ID %d previous definition", FormIdValue);\r
- return;\r
- }\r
- }\r
- //\r
- // Allocate memory for a new one \r
- //\r
- NewFormId = (FORM_ID_VALUE *)malloc (sizeof (FORM_ID_VALUE));\r
- if (NewFormId == NULL) {\r
- Error (UTILITY_NAME, 0, 0, NULL, "memory allocation failure");\r
- return;\r
- }\r
- memset ((char *)NewFormId, 0, sizeof (FORM_ID_VALUE));\r
- NewFormId->LineNum = LineNum;\r
- NewFormId->Next = mFormIdValues;\r
- NewFormId->Value = (UINT16)FormIdValue;\r
- mFormIdValues = NewFormId;\r
-}\r
-UINT32\r
-EfiVfrParser::GetNumber (\r
- INT8 *NumStr,\r
- UINT32 LineNum,\r
- UINT32 NumBytes\r
- )\r
-{\r
- UINT32 Value;\r
- \r
- if ((NumStr[0] == '0') && (NumStr[1] == 'x')) {\r
- AtoX (NumStr + 2, 4, &Value);\r
- } else {\r
- Value = (UINT32)atoi (NumStr);\r
- }\r
- //\r
- // Check range\r
- //\r
- if ((NumBytes < 4) && (Value & ((UINT32)0xFFFFFFFF << (NumBytes * 8)))) {\r
- PrintErrorMessage (LineNum, NumStr, "value out of range");\r
- return 0;\r
- }\r
- return Value;\r
-}\r
-\r
->>\r
-\r
-} // end grammar class\r
-\r
-\r