3 Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 PCCTS parser and lexer definitions for the EFI VFR forms compiler
25 #include "EfiUtilityMsgs.h"
27 #include "VfrServices.h"
28 #include EFI_PROTOCOL_DEFINITION (Hii)
32 #include <process.h> // for spawn functions
39 // Base info for DLG-generated scanner
41 #include "DLexerBase.h"
44 // Include the scanner file generated by DLG
48 class DLGLexerVfr : public DLGLexer
51 DLGLexerVfr (DLGFileInput *F) : DLGLexer (F) {};
52 INT32 errstd (char *Text)
54 printf ("unrecognized input '%s'\n", Text);
59 // Base token definitions for ANTLR
64 // This is how we invoke the C preprocessor on the VFR source file
65 // to resolve #defines, #includes, etc. To make C source files
66 // shareable between VFR and drivers, define VFRCOMPILE so that
67 // #ifdefs can be used in shared .h files.
69 #define PREPROCESSOR_COMMAND "cl.exe "
70 #define PREPROCESSOR_OPTIONS "/nologo /E /TC /DVFRCOMPILE "
72 typedef ANTLRCommonToken ANTLRToken;
75 // Specify the filename extensions for the files we generate.
77 #define VFR_BINARY_FILENAME_EXTENSION ".c"
78 #define VFR_LIST_FILENAME_EXTENSION ".lst"
79 #define VFR_PREPROCESS_FILENAME_EXTENSION ".i"
109 Application entry point function. Parse command-line arguments,
110 invoke the parser, clean up, and return.
113 argc - standard argc passed to main() per C conventions
114 argv - standard argv passed to main() per C conventions
117 STATUS_SUCCESS - program executed with no errors or warnings
118 STATUS_WARNING - program executed with warnings
119 STATUS_ERROR - non-recoverable errors encountered while processing
130 // Set our program name for the error printing routines.
131 // Then set printing limits.
133 SetUtilityName (UTILITY_NAME);
134 SetPrintLimits (20, 20, 30);
136 // Process the command-line arguments
138 if (ProcessArgs (argc, argv) != STATUS_SUCCESS) {
145 // Verify the VFR script file exists
147 if ((VfrFptr = fopen (gOptions.VfrFileName, "r")) == NULL) {
148 Error (UTILITY_NAME, 0, 0, gOptions.VfrFileName, "could not open input VFR file");
153 // Now close the file and make a system call to run the preprocessor
157 Len = strlen (PREPROCESSOR_OPTIONS) + strlen (gOptions.VfrFileName) + 10 +
158 strlen (PREPROCESSOR_COMMAND) + strlen (gOptions.PreprocessorOutputFileName);
159 if (gOptions.CPreprocessorOptions != NULL) {
160 Len += strlen (gOptions.CPreprocessorOptions) + 1;
162 if (gOptions.IncludePaths != NULL) {
163 Len += strlen (gOptions.IncludePaths) + 1;
165 Cmd = (char *)malloc (Len);
167 Error (UTILITY_NAME, 0, 0, NULL, "could not allocate memory");
171 strcpy (Cmd, PREPROCESSOR_COMMAND PREPROCESSOR_OPTIONS);
172 if (gOptions.IncludePaths != NULL) {
173 strcat (Cmd, gOptions.IncludePaths);
176 if (gOptions.CPreprocessorOptions != NULL) {
177 strcat (Cmd, gOptions.CPreprocessorOptions);
180 strcat (Cmd, gOptions.VfrFileName);
182 strcat (Cmd, gOptions.PreprocessorOutputFileName);
183 Status = system (Cmd);
185 Error (UTILITY_NAME, 0, 0, gOptions.VfrFileName, "failed to spawn C preprocessor on VFR file");
186 printf ("Command: '%s %s'\n", PREPROCESSOR_COMMAND, Cmd);
192 // Open the preprocessor output file
194 if ((VfrFptr = fopen (gOptions.PreprocessorOutputFileName, "r")) == NULL) {
195 Error (UTILITY_NAME, 0, 0, "failed to open input VFR preprocessor output file",
196 gOptions.PreprocessorOutputFileName);
201 // Define input VFR file
203 DLGFileInput InputFile (VfrFptr);
205 // Define an instance of the scanner
207 DLGLexerVfr Scanner (&InputFile);
209 // Define token buffer between scanner and parser
211 ANTLRTokenBuffer Pipe (&Scanner);
213 // Create a token to use as a model
217 // Tell the scanner what type the token is
219 Scanner.setToken (&Tok);
221 // Create an instance of our parser
223 EfiVfrParser Parser (&Pipe);
225 // Initialize the parser
228 Status = GetUtilityStatus ();
229 if (Status != STATUS_SUCCESS) {
234 // Start the first rule
238 // Close the input script file
241 Parser.WriteIfrBytes ();
243 // Call cleanup, which does some extra checking of the script
248 // If we had an error somewhere, delete our output files so that
249 // a subsequent build will rebuild them.
251 Status = GetUtilityStatus ();
252 if (Status == STATUS_ERROR) {
253 remove (gOptions.IfrOutputFileName);
263 Free up memory allocated during parsing.
274 // Free up our string we allocated to track the include paths
276 if (gOptions.IncludePaths != NULL) {
277 free (gOptions.IncludePaths);
278 gOptions.IncludePaths = NULL;
281 // Free up our string we allocated to track preprocessor options
283 if (gOptions.CPreprocessorOptions != NULL) {
284 free (gOptions.CPreprocessorOptions);
285 gOptions.CPreprocessorOptions = NULL;
298 Process the command-line arguments.
301 Argc - standard argc passed to main()
302 Argv - standard argv passed to main()
305 STATUS_SUCCESS - program should continue (all args ok)
310 char *CPreprocessorOptions;
312 char CopyStr[MAX_PATH];
316 // Put options in known state.
318 memset ((char *)&gOptions, 0, sizeof (OPTIONS));
320 // Go through all the arguments that start with '-'
324 while ((Argc > 0) && (Argv[0][0] == '-')) {
326 // -? or -h help option -- return an error for printing usage
328 if ((_stricmp (Argv[0], "-?") == 0) || (_stricmp (Argv[0], "-h") == 0)) {
332 // -l to create a listing output file
334 } else if (_stricmp (Argv[0], "-l") == 0) {
335 gOptions.CreateListFile = 1;
337 // -I include_path option for finding include files. We'll pass this
338 // to the preprocessor. Turn them all into a single include string.
340 } else if (_stricmp (Argv[0], "-i") == 0) {
341 if ((Argc < 2) || (Argv[1][0] == '-')) {
342 Error (UTILITY_NAME, 0, 0, Argv[0], "missing path argument");
347 Len = strlen (" -I ");
348 Len += strlen (Argv[0]) + 2;
349 if (gOptions.IncludePaths != NULL) {
350 Len += strlen (gOptions.IncludePaths);
352 IncludePaths = (INT8 *)malloc (Len);
353 if (IncludePaths == NULL) {
354 Error (UTILITY_NAME, 0, 0, NULL, "memory allocation failure");
358 if (gOptions.IncludePaths != NULL) {
359 strcpy (IncludePaths, gOptions.IncludePaths);
360 free (gOptions.IncludePaths);
362 strcat (IncludePaths, " -I ");
363 strcat (IncludePaths, Argv[0]);
364 gOptions.IncludePaths = IncludePaths;
366 // -od OutputDirectory to define a common directory for output files
368 } else if (_stricmp (Argv[0], "-od") == 0) {
369 if ((Argc < 2) || (Argv[1][0] == '-')) {
370 Error (UTILITY_NAME, 0, 0, Argv[0], "missing output directory name");
375 strcpy (gOptions.OutputDirectory, Argv[0]);
376 } else if (_stricmp (Argv[0], "-ibin") == 0) {
377 gOptions.CreateIfrBinFile = 1;
378 } else if (_stricmp (Argv[0], "-nostrings") == 0) {
381 // -ppflag C-preprocessor-flag option for passing options to the C preprocessor.
382 // Turn them all into a single string.
384 } else if (_stricmp (Argv[0], "-ppflag") == 0) {
386 Error (UTILITY_NAME, 0, 0, Argv[0], "missing C-preprocessor argument");
391 Len = strlen (Argv[0]) + 2;
392 if (gOptions.CPreprocessorOptions != NULL) {
393 Len += strlen (gOptions.CPreprocessorOptions);
395 CPreprocessorOptions = (INT8 *)malloc (Len);
396 if (CPreprocessorOptions == NULL) {
397 Error (UTILITY_NAME, 0, 0, NULL, "memory allocation failure");
400 CPreprocessorOptions[0] = 0;
401 if (gOptions.CPreprocessorOptions != NULL) {
402 strcpy (CPreprocessorOptions, gOptions.CPreprocessorOptions);
403 free (gOptions.CPreprocessorOptions);
405 strcat (CPreprocessorOptions, " ");
406 strcat (CPreprocessorOptions, Argv[0]);
407 gOptions.CPreprocessorOptions = CPreprocessorOptions;
409 Error (UTILITY_NAME, 0, 0, Argv[0], "unrecognized option");
416 // Must specify at least the vfr file name
419 Error (UTILITY_NAME, 0, 0, Argv[1], "unrecognized argument after VFR file name");
421 } else if (Argc < 1) {
422 Error (UTILITY_NAME, 0, 0, NULL, "must specify VFR file name");
425 strcpy (gOptions.VfrFileName, Argv[0]);
427 strcpy (CopyStr, gOptions.VfrFileName);
428 Cptr = CopyStr + strlen (CopyStr) - 1;
429 for (;(Cptr > CopyStr) && (*Cptr != '\\') && (*Cptr != ':'); Cptr--);
430 if (Cptr == CopyStr) {
431 strcpy (gOptions.VfrBaseFileName, Cptr);
433 strcpy (gOptions.VfrBaseFileName, Cptr+1);
436 // Terminate the vfr file basename at the extension
438 for (Cptr = gOptions.VfrBaseFileName; *Cptr && (*Cptr != '.'); Cptr++) {
442 // If they defined an output directory, prepend all output files
443 // with the working directory. Output files of interest:
444 // VfrListFileName -- list file
445 // IfrOutputFileName -- IFR bytes
446 // StringOutputFileName -- string bytes
447 // StringListFileName -- not used
448 // StringDefineFileName -- #defines of string identifiers
450 // We have two cases:
451 // 1. Output directory (-od) not specified, in which case output files
452 // go to the current working directory.
453 // 2. Output directory specified, in which case the output files
454 // go directly to the specified directory.
456 if (gOptions.OutputDirectory[0] == 0) {
458 _getcwd (CopyStr, sizeof (CopyStr));
459 strcpy (gOptions.OutputDirectory, CopyStr);
462 // Make sure output directory has a trailing backslash
464 if (gOptions.OutputDirectory[strlen (gOptions.OutputDirectory) - 1] != '\\') {
465 strcat (gOptions.OutputDirectory, "\\");
468 // Create the base output file name as: path\base, copy it to all the output
469 // filenames, and then add the appropriate extension to each.
471 strcpy (gOptions.VfrListFileName, gOptions.OutputDirectory);
472 strcat (gOptions.VfrListFileName, gOptions.VfrBaseFileName);
473 strcpy (gOptions.IfrOutputFileName, gOptions.VfrListFileName);
474 strcpy (gOptions.PreprocessorOutputFileName, gOptions.VfrListFileName);
475 strcat (gOptions.VfrListFileName, VFR_LIST_FILENAME_EXTENSION);
476 strcat (gOptions.IfrOutputFileName, VFR_BINARY_FILENAME_EXTENSION);
477 strcat (gOptions.PreprocessorOutputFileName, VFR_PREPROCESS_FILENAME_EXTENSION);
480 // We set a default list file name, so if they do not
481 // want a list file, null out the name now.
483 if (gOptions.CreateListFile == 0) {
484 gOptions.VfrListFileName[0] = 0;
486 return STATUS_SUCCESS;
494 Print utility usage instructions
505 const char *Str[] = {
506 UTILITY_NAME" "UTILITY_VERSION" - Intel VFR Compiler Utility",
507 " Copyright (C), 2004 - 2008 Intel Corporation",
508 #if ( defined(UTILITY_BUILD) && defined(UTILITY_VENDOR) )
509 " Built from "UTILITY_BUILD", project of "UTILITY_VENDOR,
513 " "UTILITY_NAME" [OPTION] VFRFILE",
517 " -? or -h print this help",
518 " -l create an output IFR listing file",
519 " -i IncPath add IncPath to the search path for VFR included files",
520 " -od OutputDir deposit all output files to directory OutputDir (default=cwd)",
521 " -ibin create an IFR HII pack file",
522 " -ppflag CFlags pass Flags as C-preprocessor-flag",
523 " -v or -version print version information",
527 for (Index = 0; Str[Index] != NULL; Index++) {
528 fprintf (stdout, "%s\n", Str[Index]);
540 PARSER_LINE_DEFINITION *gLineDefinition = NULL;
541 PARSER_LINE_DEFINITION *gLastLineDefinition = NULL;
551 During the lexer phase, if we encounter a #line statement output by
552 the preprocessor, this function gets called. We'll save off the info
553 for error reporting purposes. The preprocessor line information has the
559 TokenString - the parsed string as shown above
560 TokenLine - the line number in the preprocessed output file
567 PARSER_LINE_DEFINITION *LineDef;
571 // Allocate a structure in which we can keep track of this line information.
573 LineDef = (PARSER_LINE_DEFINITION *)malloc (sizeof (PARSER_LINE_DEFINITION));
574 memset ((char *)LineDef, 0, sizeof (PARSER_LINE_DEFINITION));
575 LineDef->TokenLineNum = TokenLine;
576 LineDef->HashLineNum = atoi (TokenString + 6);
578 // Find the quotes in the filename, then allocate space in the line
579 // def structure for a copy of the filename. Finally, copy it without
580 // quotes to the line def.
582 for (Cptr = TokenString + 7; *Cptr && (*Cptr != '"'); Cptr++);
584 LineDef->FileName = (INT8 *)malloc (strlen (Cptr));
586 strcpy (LineDef->FileName, Cptr);
587 for (Cptr = LineDef->FileName; *Cptr && (*Cptr != '"'); Cptr++);
590 // Now add this new one to the list
592 if (gLineDefinition == NULL) {
593 gLineDefinition = LineDef;
595 gLastLineDefinition->Next = LineDef;
597 gLastLineDefinition = LineDef;
599 Error (UTILITY_NAME, 0, 0, "invalid line definition in preprocessor output file", TokenString);
611 Given the line number in the preprocessor-output file, use the line number
612 information we've saved to determine the source file name and line number
613 where the code originally came from. This is required for error reporting.
616 LineNum - the line number in the preprocessor-output file.
619 Returns a pointer to the source file name. Also returns the line number
620 in the provided LineNum argument
624 PARSER_LINE_DEFINITION *LineDef;
626 // Step through our linked list of #line information we saved off.
627 // For each one, look at its line number, and the line number of the
628 // next record, and see if the passed-in line number is in the range.
629 // If it is, then convert the line number to the appropriate line number
630 // of the original source file.
632 for (LineDef = gLineDefinition; LineDef != NULL; LineDef = LineDef->Next) {
634 // The given LineNum is the line number from the .i file.
635 // Find a line definition whose range includes this line number,
636 // convert the line number, and return the filename.
638 if (LineDef->TokenLineNum <= *LineNum) {
639 if (LineDef->Next != NULL) {
640 if (LineDef->Next->TokenLineNum > *LineNum) {
641 *LineNum = *LineNum - LineDef->TokenLineNum + LineDef->HashLineNum;
642 return LineDef->FileName;
646 // Last one in the list of line definitions, so has to be right
648 *LineNum = *LineNum - LineDef->TokenLineNum + LineDef->HashLineNum;
649 return LineDef->FileName;
659 // Define a lexical class for parsing quoted strings. Basically
660 // starts with a double quote, and ends with a double quote that
661 // is not preceeded with a backslash.
663 #lexclass QUOTED_STRING
664 #token TheString "~[\"]*\"" << mode (START); >>
667 // Define a lexical class for parsing "#pragma pack" statements.
668 // We do this just for convenience (since we skip them here) so
669 // that users can include some minimal .h files.
671 #lexclass PRAGMA_PACK
672 #token "pack" << skip (); >>
673 #token "[\ \t]" << skip (); >>
674 #token "\(" << skip (); >>
675 #token "[0-9]*" << skip (); >>
676 #token "\)" << skip (); mode (START); >>
679 // Define a lexclass for skipping over C++ style comments
681 #lexclass CPP_COMMENT
682 #token "~[\n]*" << skip (); >>
683 #token "\n" << skip (); mode (START); newline (); >>
686 // Standard lexclass is START
691 // Find start of C++ style comments
693 #token "//" << skip (); mode (CPP_COMMENT); >>
698 #token "[\ \t]" << skip (); >>
701 // Skip over newlines, but count them
703 #token "\n" << skip (); newline (); >>
706 // Skip pragma pack statements
708 #token "\#pragma" << skip (); mode(PRAGMA_PACK); >>
711 // Skip over 'extern' in any included .H file
713 #token "extern" << skip (); >>
716 // Tokens for the different keywords. Syntax is:
717 // TokenName("ErrorMessageText") "TokenString"
719 // TokenName is the token name (must be capitalized) that is used in the rules
720 // ErrorMessageText is the string the compiler emits when it detects a syntax error
721 // TokenString is the actual matching string used in the user script
723 #token LineDefinition "#line\ [0-9]+\ \"~[\"]+\"[\ \t]*\n" << AddFileLine (begexpr (), line ()); skip (); >>
724 #token FormSet("formset") "formset"
725 #token EndFormSet("endformset") "endformset"
726 #token Title("title") "title"
727 #token FormId("formid") "formid"
728 #token OneOf("oneof") "oneof"
729 #token Prompt("prompt") "prompt"
730 #token OrderedList("orderedlist") "orderedlist"
731 #token EndList("endlist") "endlist"
732 #token EndForm("endform") "endform"
733 #token EndOneOf("endoneof") "endoneof"
734 #token Form("form") "form"
735 #token Subtitle("subtitle") "subtitle"
736 #token Help("help") "help"
737 #token VarId("varid") "varid"
738 #token Text("text") "text"
739 #token Option("option") "option"
740 #token Value("value") "value"
741 #token Flags("flags") "flags"
742 #token Date("date") "date"
743 #token EndDate("enddate") "enddate"
744 #token Year("year") "year"
745 #token Month("month") "month"
746 #token Day("day") "day"
747 #token Time("time") "time"
748 #token EndTime("endtime") "endtime"
749 #token Hour("hour") "hour"
750 #token Minute("minute") "minute"
751 #token Second("second") "second"
752 #token AND("AND") "AND"
754 #token GrayOutIf("grayoutif") "grayoutif"
755 #token NOT("NOT") "NOT"
756 #token Label("label") "label"
757 #token Timeout("timeout") "timeout"
758 #token Inventory("inventory") "inventory"
759 #token StringToken("STRING_TOKEN") "STRING_TOKEN"
760 #token NonNvDataMap("_NON_NV_DATA_MAP") "_NON_NV_DATA_MAP"
761 #token Struct("struct") "struct"
762 #token Uint64("UINT64") "UINT64"
763 #token Uint32("UINT32") "UINT32"
764 #token Uint16("UINT16") "UINT16"
765 #token Char16("CHAR16") "CHAR16"
766 #token Uint8("UINT8") "UINT8"
767 #token Guid("guid") "guid"
768 #token CheckBox("checkbox") "checkbox"
769 #token EndCheckBox("endcheckbox") "endcheckbox"
770 #token Numeric("numeric") "numeric"
771 #token EndNumeric("endnumeric") "endnumeric"
772 #token Minimum("minimum") "minimum"
773 #token Maximum("maximum") "maximum"
774 #token Step("step") "step"
775 #token Default("default") "default"
776 #token Password("password") "password"
777 #token EndPassword("endpassword") "endpassword"
778 #token String("string") "string"
779 #token EndString("endstring") "endstring"
780 #token MinSize("minsize") "minsize"
781 #token MaxSize("maxsize") "maxsize"
782 #token Encoding("encoding") "encoding"
783 #token SuppressIf("suppressif") "suppressif"
784 #token Hidden("hidden") "hidden"
785 #token Goto("goto") "goto"
786 #token InconsistentIf "inconsistentif"
787 #token EndIf("endif") "endif"
788 #token IdEqId("ideqid") "ideqid"
789 #token IdEqVal("ideqval") "ideqval"
790 #token VarEqVal("vareqval") "vareqval"
791 #token Var("var") "var"
792 #token IdEqValList("ideqvallist") "ideqvallist"
793 #token Length("length") "length"
794 #token Values("values") "values"
795 #token Key("key") "key"
796 #token DefaultFlag("DEFAULT") "DEFAULT"
797 #token ManufacturingFlag("MANUFACTURING") "MANUFACTURING"
798 #token InteractiveFlag("INTERACTIVE") "INTERACTIVE"
799 #token NVAccessFlag("NV_ACCESS") "NV_ACCESS"
800 #token ResetRequiredFlag("RESET_REQUIRED") "RESET_REQUIRED"
801 #token LateCheckFlag("LATE_CHECK") "LATE_CHECK"
802 #token Class("class") "class"
803 #token Subclass("subclass") "subclass"
804 #token TypeDef("typedef") "typedef"
805 #token Restore("restore") "restore"
806 #token Save("save") "save"
807 #token Defaults("defaults") "defaults"
808 #token Banner("banner") "banner"
809 #token Align("align") "align"
810 #token Left("left") "left"
811 #token Right("right") "right"
812 #token Center("center") "center"
813 #token Line("line") "line"
814 #token VarStore("varstore") "varstore"
815 #token Name("name") "name"
816 #token Oem("oem") "oem"
817 #token True("TRUE") "TRUE"
818 #token False("FALSE") "FALSE"
819 #token GreaterThan(">") ">"
820 #token GreaterEqual(">=") ">="
821 #token LessThan("<") "<"
822 #token LessEqual("<=") "<="
825 // Define the class and subclass tokens
827 #token ClassNonDevice("NONDEVICE") "NON_DEVICE"
828 #token ClassDiskDevice("DISK_DEVICE") "DISK_DEVICE"
829 #token ClassVideoDevice("VIDEO_DEVICE") "VIDEO_DEVICE"
830 #token ClassNetworkDevice("NETWORK_DEVICE") "NETWORK_DEVICE"
831 #token ClassInputDevice("INPUT_DEVICE") "INPUT_DEVICE"
832 #token ClassOnBoardDevice("ONBOARD_DEVICE") "ONBOARD_DEVICE"
833 #token ClassOtherDevice("OTHER_DEVICE") "OTHER_DEVICE"
835 #token SubclassSetupApplication("SETUP_APPLICATION") "SETUP_APPLICATION"
836 #token SubclassGeneralApplication("GENERAL_APPLICATION") "GENERAL_APPLICATION"
837 #token SubclassFrontPage("FRONT_PAGE") "FRONT_PAGE"
838 #token SubclassSingleUse("SINGLE_USE") "SINGLE_USE"
840 #token LanguageIdentifier("language identifier") "[a-z][a-z][a-z]" // 3 lowercase characters
841 #token StringIdentifier("string identifier") "[A-Za-z_][A-Za-z_0-9]*"
842 #token Number("numeric value") "(0x[0-9A-Fa-f]+) | [0-9]+"
843 #token OpenBrace("{") "\{"
844 #token CloseBrace("}") "\}"
845 #token OpenParen("(") "\("
846 #token CloseParen(")") "\)"
847 #token OpenBracket("[") "\["
848 #token CloseBracket("]") "\]"
851 // Define all other invalid characters so that they get through the lexical phase
852 // and we can catch them during the parse phase. We get much better error
855 #token InvalidCharacters("invalid characters") "~[;:=,\.\|]"
858 // This is the overall definition of a VFR form definition script.
861 ( dataStructDefinition )*
863 ( vfrStatementVarStore )*
865 EFS:EndFormSet ";" << WriteOpByte (EFS->getLine(), EFI_IFR_END_FORM_SET_OP); >>
870 FS:FormSet << WriteOpByte (FS->getLine(), EFI_IFR_FORM_SET_OP); >>
884 CloseBrace << WriteGuidValue (G1->getLine (), G1->getText (), G2->getText (), G3->getText (),
885 G4->getText (), G5->getText (), G6->getText (), G7->getText (),
886 G8->getText (), G9->getText (), G10->getText (), G11->getText ()
890 Title "=" getStringId ","
891 Help "=" getStringId ","
893 // insert padding for an EFI_PHYSICAL_ADDRESS (UINT64)
895 << WriteDWord (0, 0); WriteDWord (0, 0); >>
896 Class "=" CVAL:classDefinition "," << WriteClass (); >>
897 Subclass "=" SVAL:subclassDefinition "," << WriteSubclass (); >>
898 << WriteWord (mNvDataStructSize); >>
902 // A form can be of multiple classes, thus allow CLASS_A | CLASS_B | CLASS_C
905 validClassNames ( "\|" validClassNames )*
909 CND:ClassNonDevice << SetClass (CND->getLine(), EFI_NON_DEVICE_CLASS); >>
910 | CDD:ClassDiskDevice << SetClass (CDD->getLine(), EFI_DISK_DEVICE_CLASS); >>
911 | CVD:ClassVideoDevice << SetClass (CVD->getLine(), EFI_VIDEO_DEVICE_CLASS); >>
912 | CNW:ClassNetworkDevice << SetClass (CNW->getLine(), EFI_NETWORK_DEVICE_CLASS); >>
913 | CID:ClassInputDevice << SetClass (CID->getLine(), EFI_INPUT_DEVICE_CLASS); >>
914 | COB:ClassOnBoardDevice << SetClass (COB->getLine(), EFI_ON_BOARD_DEVICE_CLASS); >>
915 | COD:ClassOtherDevice << SetClass (COD->getLine(), EFI_OTHER_DEVICE_CLASS); >>
916 | CNUM:Number << SetClass (CNUM->getLine(), GetNumber (CNUM->getText(), CNUM->getLine(), 4)); >>
917 ; << PrintErrorMessage (LT(1)->getLine(), LT(1)->getText(), "invalid class"); >>
920 // A form can only be of one subclass type.
923 SSA:SubclassSetupApplication << SetSubclass (SSA->getLine(), EFI_SETUP_APPLICATION_SUBCLASS); >>
924 | SGA:SubclassGeneralApplication << SetSubclass (SGA->getLine(), EFI_GENERAL_APPLICATION_SUBCLASS); >>
925 | SFP:SubclassFrontPage << SetSubclass (SFP->getLine(), EFI_FRONT_PAGE_SUBCLASS); >>
926 | SSU:SubclassSingleUse << SetSubclass (SSU->getLine(), EFI_SINGLE_USE_SUBCLASS); >>
927 | SNUM:Number << SetSubclass (SNUM->getLine(), GetNumber (SNUM->getText(), SNUM->getLine(), 4)); >>
928 ; << PrintErrorMessage (LT(1)->getLine(), LT(1)->getText(), "invalid subclass"); >>
931 // Parse a C type data structure for storing VFR setup data. Allow:
932 // typedef struct _XXX_ {
936 dataStructDefinition :
937 << int IsNonNV = 0; >>
941 NonNvDataMap << IsNonNV = 1; >>
944 ) << StartStructDefinition (IsNonNV, S->getLine()); >>
947 CloseBrace NAME:StringIdentifier << EndStructDefinition (NAME->getText(), NAME->getLine()); >>
952 ( dataStructField64 | dataStructField32 | dataStructField16 | dataStructField8 ) *
955 //*****************************************************************************
961 // Used while parsing the NV data map structures.
964 << int ArrayLength = 1; char IsArray = 0; >>
966 NAME:StringIdentifier
967 ( ";" | OpenBracket IVal:Number CloseBracket ";" << ArrayLength = GetNumber (IVal->getText(), IVal->getLine(), 4); IsArray = 1; >> )
968 << AddStructField (NAME->getText(), NAME->getLine(), 8, ArrayLength, IsArray); >>
971 //*****************************************************************************
977 // Used while parsing the NV data map structures.
980 << int ArrayLength = 1; char IsArray = 0; >>
982 NAME:StringIdentifier
983 ( ";" | OpenBracket IVal:Number CloseBracket ";" << ArrayLength = GetNumber (IVal->getText(), IVal->getLine(), 4); IsArray = 1; >> )
984 << AddStructField (NAME->getText(), NAME->getLine(), 4, ArrayLength, IsArray); >>
987 //*****************************************************************************
993 // Used while parsing the NV data map structures.
996 << int ArrayLength = 1; char IsArray = 0; >>
997 ( "UINT16" | "CHAR16" )
998 NAME:StringIdentifier
999 ( ";" | OpenBracket IVal:Number CloseBracket ";" << ArrayLength = GetNumber (IVal->getText(), IVal->getLine(), 4); IsArray = 1; >> )
1000 << AddStructField (NAME->getText(), NAME->getLine(), 2, ArrayLength, IsArray); >>
1003 //*****************************************************************************
1009 // Used while parsing the NV data map structures.
1012 << int ArrayLength = 1; char IsArray = 0; >>
1014 NAME:StringIdentifier
1015 ( ";" | OpenBracket IVal:Number CloseBracket ";" << ArrayLength = GetNumber (IVal->getText(), IVal->getLine(), 4); IsArray = 1; >> )
1016 << AddStructField (NAME->getText(), NAME->getLine(), 1, ArrayLength, IsArray); >>
1019 //*****************************************************************************
1023 // title = STRING_TOKEN(STR_FORM_TITLE);
1024 // -- form statements --
1027 // The Form ID cannot be 0
1030 FRM:Form FormId << WriteOpByte (FRM->getLine(), EFI_IFR_FORM_OP); >>
1032 VAL:Number << WriteWord (GetNumber (VAL->getText(), VAL->getLine(), 2)); AddFormId (GetNumber (VAL->getText(), VAL->getLine(), 2), VAL->getLine()); >>
1034 Title "=" getStringId ";" // writes string identifier
1036 ENDF:EndForm ";" << WriteOpByte (ENDF->getLine(), EFI_IFR_END_FORM_OP); >>
1040 // VFR statements in a formset
1043 vfrStatementSubTitle |
1045 vfrStatementTextText |
1046 vfrStatementCheckBox |
1047 vfrStatementNumeric |
1050 vfrStatementPassword |
1051 vfrStatementString |
1052 vfrStatementSuppressIf |
1053 vfrStatementHidden |
1055 vfrStatementGrayOutIf |
1056 vfrStatementInconsistentIf |
1058 vfrStatementBanner |
1059 vfrStatementInventory |
1060 vfrStatementOrderedList |
1062 vfrStatementSaveRestoreDefaults
1065 //*****************************************************************************
1071 OPID:Label << WriteOpByte (OPID->getLine(), EFI_IFR_LABEL_OP); >>
1073 WriteWord (GetNumber (VAL->getText(), VAL->getLine(), 2));
1074 AddLabel (GetNumber (VAL->getText(), VAL->getLine(), 2), VAL->getLine());
1079 //*****************************************************************************
1082 // oem 0x12, 0x34, 0x56;
1085 OPID:Oem << WriteOpByte (OPID->getLine(), EFI_IFR_OEM_DEFINED_OP); >>
1086 ( VAL1:Number << WriteByte (GetNumber (VAL1->getText(), VAL1->getLine(), 1), 0); >> )
1087 ( "," VAL2:Number << WriteByte (GetNumber (VAL2->getText(), VAL2->getLine(), 1), 0); >> )*
1091 //*****************************************************************************
1094 // inconsistentif NOT .... AND NOT .... OR ... endif;
1096 vfrStatementInconsistentIf :
1097 << ResetFlags (); >>
1098 IIFOP:InconsistentIf << WriteOpByte (IIFOP->getLine(), EFI_IFR_INCONSISTENT_IF_OP); >>
1099 Prompt "=" getStringId ","
1101 FF:Flags "=" flagsField ( "\|" flagsField )* ","
1103 << WriteFlags (); >> // write the flags field
1104 vfrBooleanExpression
1105 EOP:EndIf ";" << WriteOpByte (EOP->getLine(), EFI_IFR_END_IF_OP); >>
1108 //*****************************************************************************
1111 // TRUE AND (ideqval SomeStruct.SomeMember >= 0x10 OR
1112 // ideqid SomeStruct.SomeMember < SomeStruct.SomeOtherMember) AND
1113 // (ideqlist SomeStruct.SomeOtherMember == 0x10, 0x20, 0x30 OR
1114 // vareqval var(VAR_EQ_TEST_NAME) == 0x1)
1116 // For supporting complex express, divide the vfrBooleanExpression to two parts
1117 // so that pred-LL(k) parser can parse incrementally.
1119 vfrBooleanExpression :
1120 leftPartVfrBooleanExp { rightPartVfrBooleanExp }
1123 leftPartVfrBooleanExp :
1124 OpenParen vfrBooleanExpression CloseParen |
1125 (ideqval | ideqid | ideqvallist | vareqval | truefalse) |
1126 NOPID:NOT leftPartVfrBooleanExp << WriteOpByte (NOPID->getLine(), EFI_IFR_NOT_OP); >>
1129 rightPartVfrBooleanExp :
1130 AOPID:AND vfrBooleanExpression << WriteOpByte (AOPID->getLine(), EFI_IFR_AND_OP); >> |
1131 OOPID:OR vfrBooleanExpression << WriteOpByte (OOPID->getLine(), EFI_IFR_OR_OP); >>
1134 //*****************************************************************************
1140 TOPID:True << WriteOpByte (TOPID->getLine(), EFI_IFR_TRUE_OP); >> |
1141 FOPID:False << WriteOpByte (FOPID->getLine(), EFI_IFR_FALSE_OP); >>
1144 //*****************************************************************************
1147 // varstore MY_STRUCT_NAME, key = 0x1234, name = "MyVariableName", guid = {...};
1149 vfrStatementVarStore :
1150 OP:VarStore << WriteOpByte (OP->getLine(), EFI_IFR_VARSTORE_OP); >>
1151 STRUCT_NAME:StringIdentifier ","
1152 Key "=" KNUM:Number ","
1153 Name "=" VAR_NAME:StringIdentifier ","
1167 CloseBrace << WriteGuidValue (G1->getLine (), G1->getText (), G2->getText (), G3->getText (),
1168 G4->getText (), G5->getText (), G6->getText (), G7->getText (),
1169 G8->getText (), G9->getText (), G10->getText (), G11->getText ()
1171 WriteWord (GetNumber (KNUM->getText(), KNUM->getLine(), 2));
1172 AddVarStore (STRUCT_NAME->getText(), VAR_NAME->getText(), GetNumber (KNUM->getText(), KNUM->getLine(), 2), STRUCT_NAME->getLine());
1178 //*****************************************************************************
1181 // vareqval var(0x100) == 0x20
1184 OPID:VarEqVal << WriteOpByte (OPID->getLine(), EFI_IFR_EQ_VAR_VAL_OP); >>
1186 VAR:Number << WriteWord (GetNumber (VAR->getText(), VAR->getLine(), 2)); >>
1192 OPID:IdEqVal << WriteOpByte (OPID->getLine(), EFI_IFR_EQ_ID_VAL_OP); >>
1193 vfrStructFieldName[0]
1197 //*****************************************************************************
1200 // ideqid MyNVData3.Field16A == MyNVData3.Field16B
1202 // NOTE: Before processing the second variable store in the ideqid statement, set a global flag
1203 // so that when we parse the second variable we set the secondary variable store id.
1206 OPID:IdEqId << WriteOpByte (OPID->getLine(), EFI_IFR_EQ_ID_ID_OP); >>
1207 vfrStructFieldName[0]
1208 compareVfrStructFieldNameNL0
1211 //*****************************************************************************
1213 // compareNumber is the combination of compare operation and Number
1218 VAL1:Number << WriteWord (GetNumber (VAL1->getText(), VAL1->getLine(), 2)); >>
1222 VAL2:Number << WriteWord (GetNumber (VAL2->getText(), VAL2->getLine(), 2));
1223 WriteOpByte (GTOPID->getLine(), EFI_IFR_GT_OP); >>
1227 VAL3:Number << WriteWord (GetNumber (VAL3->getText(), VAL3->getLine(), 2));
1228 WriteOpByte (GEOPID->getLine(), EFI_IFR_GE_OP); >>
1232 VAL4:Number << WriteWord (GetNumber (VAL4->getText(), VAL4->getLine(), 2));
1233 WriteOpByte (LTOPID->getLine(), EFI_IFR_GE_OP);
1234 WriteOpByte (LTOPID->getLine(), EFI_IFR_NOT_OP); >>
1238 VAL5:Number << WriteWord (GetNumber (VAL5->getText(), VAL5->getLine(), 2));
1239 WriteOpByte (LEOPID->getLine(), EFI_IFR_GT_OP);
1240 WriteOpByte (LEOPID->getLine(), EFI_IFR_NOT_OP); >>
1244 //*****************************************************************************
1246 // compareVfrStructFieldNameNL0 is the combination of compare operation and vfrStructFieldNameNL[0]
1248 compareVfrStructFieldNameNL0 :
1250 "==" << mIdEqIdStmt = 1; >>
1251 vfrStructFieldNameNL[0] << mIdEqIdStmt = 0; >>
1254 GTOPID:GreaterThan << mIdEqIdStmt = 1; >>
1255 vfrStructFieldNameNL[0] << mIdEqIdStmt = 0;
1256 WriteOpByte (GTOPID->getLine(), EFI_IFR_GT_OP); >>
1259 GEOPID:GreaterEqual << mIdEqIdStmt = 1; >>
1260 vfrStructFieldNameNL[0] << mIdEqIdStmt = 0;
1261 WriteOpByte (GEOPID->getLine(), EFI_IFR_GE_OP); >>
1264 LTOPID:LessThan << mIdEqIdStmt = 1; >>
1265 vfrStructFieldNameNL[0] << mIdEqIdStmt = 0;
1266 WriteOpByte (LTOPID->getLine(), EFI_IFR_GE_OP);
1267 WriteOpByte (LTOPID->getLine(), EFI_IFR_NOT_OP); >>
1270 LEOPID:LessEqual << mIdEqIdStmt = 1; >>
1271 vfrStructFieldNameNL[0] << mIdEqIdStmt = 0;
1272 WriteOpByte (LEOPID->getLine(), EFI_IFR_GT_OP);
1273 WriteOpByte (LEOPID->getLine(), EFI_IFR_NOT_OP); >>
1279 OPID:IdEqValList << WriteOpByte (OPID->getLine(), EFI_IFR_EQ_ID_LIST_OP); >>
1280 vfrStructFieldName[0]
1282 ( VAL:Number << QueueIdEqValList (GetNumber (VAL->getText(), VAL->getLine(), 2)); >> ) +
1283 << FlushQueueIdEqValList(); >>
1287 << UINT32 LineNum, KeyValue = 0; ResetFlags (); >>
1288 IDG:Goto << WriteOpByte (IDG->getLine(), EFI_IFR_REF_OP); >>
1289 VAL:Number "," << WriteWord (GetNumber (VAL->getText(), VAL->getLine(), 2));
1290 AddGotoReference (GetNumber (VAL->getText(), VAL->getLine(), 2), VAL->getLine());
1292 KP:Prompt "=" getStringId "," << LineNum = KP->getLine(); >>
1293 Help "=" getStringId
1296 FF:Flags "=" flagsField ( "\|" flagsField )* << LineNum = FF->getLine(); >>
1299 "," Key "=" KNUM:Number << LineNum = KNUM->getLine(); KeyValue = GetNumber(KNUM->getText(), LineNum, 2); >>
1301 << WriteFlagsKey (KeyValue, LineNum); >>
1305 vfrStatementHidden :
1306 IDH:Hidden << WriteOpByte (IDH->getLine(), EFI_IFR_HIDDEN_OP); >>
1308 VAL:Number "," << WriteWord (GetNumber (VAL->getText(), VAL->getLine(), 2)); >>
1310 KVAL:Number << WriteWord (GetNumber (KVAL->getText(), KVAL->getLine(), 2)); >>
1314 //*****************************************************************************
1317 // suppressif <boolean_expression> { grayoutif } <statements>+ endif;
1319 // You can have: suppressif:grayoutif:statements:endif
1320 // suppressif:grayoutif:endif -- serves no purpose
1321 // suppressif:statements:endif
1322 // suppressif:endif -- serves no purpose
1324 vfrStatementSuppressIf :
1325 << ResetFlags (); >>
1326 OPID:SuppressIf << WriteOpByte (OPID->getLine(), EFI_IFR_SUPPRESS_IF_OP); SetIfStart (OPID->getLine()); >>
1328 FF:Flags "=" flagsField ( "\|" flagsField )* ","
1330 << WriteFlags (); >> // write the flags field
1331 vfrBooleanExpression
1333 { suppressIfGrayOutIf } ( suppressIfAndGrayoutIfSubstatements )+
1334 ENDOP:EndIf ";" << WriteOpByte (ENDOP->getLine(), EFI_IFR_END_IF_OP); SetIfStart (0); >>
1338 // This is the form for a grayoutif nested in a suppressif statement
1340 suppressIfGrayOutIf :
1341 << ResetFlags (); >>
1342 OPID:GrayOutIf << WriteOpByte (OPID->getLine(), EFI_IFR_GRAYOUT_IF_OP); >>
1344 FF:Flags "=" flagsField ( "\|" flagsField )* ","
1346 << WriteFlags (); >> // write the flags field
1347 vfrBooleanExpression
1351 //*****************************************************************************
1354 // grayoutif { flags = n, } <boolean_expression> endif;
1356 // You can have: grayoutif:suppressif:statements:endif
1357 // grayoutif:statements:endif
1360 vfrStatementGrayOutIf :
1361 << ResetFlags (); >>
1362 OPID:GrayOutIf << WriteOpByte (OPID->getLine(), EFI_IFR_GRAYOUT_IF_OP); SetIfStart (OPID->getLine()); >>
1364 FF:Flags "=" flagsField ( "\|" flagsField )* ","
1366 << WriteFlags (); >> // write the flags field
1367 vfrBooleanExpression
1369 { grayoutIfSuppressIf } ( suppressIfAndGrayoutIfSubstatements )+
1370 ENDOP:EndIf ";" << WriteOpByte (ENDOP->getLine(), EFI_IFR_END_IF_OP); SetIfStart (0); >>
1374 // This is the format for a suppressif nested in a grayoutif
1376 grayoutIfSuppressIf :
1377 << ResetFlags (); >>
1378 OPID:SuppressIf << WriteOpByte (OPID->getLine(), EFI_IFR_SUPPRESS_IF_OP); >>
1380 FF:Flags "=" flagsField ( "\|" flagsField )* ","
1382 << WriteFlags (); >> // write the flags field
1383 vfrBooleanExpression
1388 // These are the VFR statements that are valid inside a suppressif or grayoutif statement.
1390 suppressIfAndGrayoutIfSubstatements :
1392 vfrStatementTextText |
1393 vfrStatementCheckBox |
1394 vfrStatementNumeric |
1397 vfrStatementPassword |
1398 vfrStatementString |
1399 vfrStatementHidden |
1402 vfrStatementInventory |
1403 vfrStatementOrderedList |
1404 vfrStatementSaveRestoreDefaults
1407 //*****************************************************************************
1411 // password varid = MyNvData.Password,
1412 // prompt = STRING_TOKEN(STR_PASSWORD_PROMPT),
1413 // help = STRING_TOKEN(STR_PASSWORD_HELP),
1419 vfrStatementPassword :
1420 << UINT32 KeyValue = 0; UINT32 LineNum; ResetFlags (); >>
1421 IDPW:Password << WriteOpByte (IDPW->getLine(), EFI_IFR_PASSWORD_OP); >>
1422 VarId "=" vfrStructFieldNameArray[0] ","
1423 Prompt "=" getStringId ","
1424 KH:Help "=" getStringId "," << LineNum = KH->getLine(); >>
1426 FF:Flags "=" flagsField ( "\|" flagsField )* "," << LineNum = FF->getLine(); >>
1429 Key "=" KNUM:Number "," << LineNum = KNUM->getLine(); KeyValue = GetNumber(KNUM->getText(), LineNum, 2); >>
1431 << WriteFlagsKey (KeyValue, LineNum); >>
1432 MinSize "=" MIN:Number "," << WriteByte (GetNumber (MIN->getText(), MIN->getLine(), 1), 0); >>
1433 MaxSize "=" MAX:Number "," << WriteByte (GetNumber (MAX->getText(), MAX->getLine(), 1), 0); >>
1434 Encoding "=" ENC:Number "," << WriteWord (GetNumber (ENC->getText(), ENC->getLine(), 2)); >>
1438 //*****************************************************************************
1442 // string varid = MyNv.String,
1443 // prompt = STRING_TOKEN(STR_STRING_PROMPT),
1444 // help = STRING_TOKEN(STR_STRING_HELP),
1445 // flags = INTERACTIVE,
1451 // Since flags and key are optional, we can't use Flags->getLine(). Therefore for error
1452 // reporting we save the line number of the "help" keyword.
1454 vfrStatementString :
1455 << unsigned int KeyValue = 0; UINT32 LineNum; ResetFlags (); >>
1456 IDS:String << WriteOpByte (IDS->getLine(), EFI_IFR_STRING_OP); >>
1457 VarId "=" vfrStructFieldNameArray[0] ","
1458 Prompt "=" getStringId ","
1459 KH:Help "=" getStringId "," << LineNum = KH->getLine(); >>
1462 flagsField ( "\|" flagsField )* << LineNum = FF->getLine(); >>
1466 Key "=" KNUM:Number "," << LineNum = KNUM->getLine(); KeyValue = GetNumber(KNUM->getText(), LineNum, 2); >>
1468 << WriteFlagsKey (KeyValue, LineNum); >>
1469 MinSize "=" MIN:Number "," << WriteByte (GetNumber (MIN->getText(), MIN->getLine(), 1), 0); >>
1470 MaxSize "=" MAX:Number "," << WriteByte (GetNumber (MAX->getText(), MAX->getLine(), 1), 0); >>
1474 //*****************************************************************************
1477 // numeric varid = MyIfrNVData.HowOldAreYouInYears,
1478 // prompt = STRING_TOKEN(STR_NUMERIC_PROMPT),
1479 // help = STRING_TOKEN(STR_NUMERIC_HELP),
1480 // flags = INTERACTIVE, // flags is optional
1481 // key = 0x1234, // key is optional if (flags & INTERACTIVE = 0)
1484 // step = 1, // step is option, and step=1 if not specified
1485 // default = 0; // default is optional, and default=minimum if not specified
1488 // Make flags and key optional. However if flags includes INTERACTIVE, then a key is required.
1489 // That check is done in WriteFlagsKey() function.
1491 vfrStatementNumeric :
1492 << UINT32 LineNum, KeyValue = 0; ResetFlags (); >>
1493 IDN:Numeric << WriteOpByte (IDN->getLine(), EFI_IFR_NUMERIC_OP); >>
1494 VarId "=" vfrStructFieldName[2] ","
1495 Prompt "=" getStringId ","
1496 KH:Help "=" getStringId "," << LineNum = KH->getLine(); >>
1498 FF:Flags "=" flagsField ( "\|" flagsField )* "," << LineNum = FF->getLine (); >>
1501 Key "=" KNUM:Number "," << LineNum = KNUM->getLine(); KeyValue = GetNumber(KNUM->getText(), LineNum, 2); >>
1503 << WriteFlagsKey (KeyValue, LineNum); >>
1505 EndNumeric ";" << WriteMinMaxStepDefault (); >>
1509 // Parse minimum/maximum/step/default statements. Special cases:
1510 // - if step not specified, then the value is 1
1511 // - if default not specified, then the value is the min value specified
1512 // - if max < min, print a warning and swap the values (changes default too)
1515 << InitMinMaxStepDefault (); >>
1516 Minimum "=" MIN:Number "," << SetMinMaxStepDefault (GetNumber (MIN->getText(), MIN->getLine(), 2), 0, MIN->getLine()); >>
1517 Maximum "=" MAX:Number "," << SetMinMaxStepDefault (GetNumber (MAX->getText(), MAX->getLine(), 2), 1, MAX->getLine()); >>
1518 { Step "=" STEP:Number "," << SetMinMaxStepDefault (GetNumber (STEP->getText(), STEP->getLine(), 2), 2, STEP->getLine()); >> }
1519 { Default "=" DEF:Number "," << SetMinMaxStepDefault (GetNumber (DEF->getText(), DEF->getLine(), 2), 3, DEF->getLine()); >> }
1523 //*****************************************************************************
1527 // date year varid = Date.Year, // "Date.Year" is a special case we recognize
1528 // prompt = STRING_TOKEN(STR_DATE_PROMPT),
1529 // help = STRING_TOKEN(STR_DATE_YEAR_HELP),
1535 // month varid = Date.Month,
1536 // prompt = STRING_TOKEN(STR_DATE_PROMPT),
1537 // help = STRING_TOKEN(STR_DATE_MONTH_HELP),
1543 // day varid = Date.Day,
1544 // prompt = STRING_TOKEN(STR_DATE_PROMPT),
1545 // help = STRING_TOKEN(STR_DATE_DAY_HELP),
1555 IDY:Year VarId "=" << WriteOpByte (IDY->getLine(), EFI_IFR_DATE_OP); >>
1556 vfrStructFieldName[2] ","
1557 dateTimeSubStatement
1558 IDM:Month VarId "=" << WriteOpByte (IDM->getLine(), EFI_IFR_DATE_OP); >>
1559 vfrStructFieldName[2] ","
1560 dateTimeSubStatement
1561 IDD:Day VarId "=" << WriteOpByte (IDD->getLine(), EFI_IFR_DATE_OP); >>
1562 vfrStructFieldName[2] ","
1563 dateTimeSubStatement
1569 IDH:Hour VarId "=" << WriteOpByte (IDH->getLine(), EFI_IFR_TIME_OP); >>
1570 vfrStructFieldName[2] ","
1571 dateTimeSubStatement
1572 IDM:Minute VarId "=" << WriteOpByte (IDM->getLine(), EFI_IFR_TIME_OP); >>
1573 vfrStructFieldName[2] ","
1574 dateTimeSubStatement
1575 IDS:Second VarId "=" << WriteOpByte (IDS->getLine(), EFI_IFR_TIME_OP); >>
1576 vfrStructFieldName[2] ","
1577 dateTimeSubStatement
1581 //*****************************************************************************
1585 // text text = STRING_ID;
1586 // text text = STRING_ID, text = STRING_ID;
1587 // text text = STRING_ID, text = STRING_ID, flags = x, key = y;
1589 vfrStatementTextText :
1590 << ResetFlags (); >>
1591 IDT:Text << WriteOpByte (IDT->getLine(), EFI_IFR_TEXT_OP); >>
1592 Help "=" getStringId ","
1594 getStringId // writes string identifier
1595 { "," Text "=" getStringId
1596 "," Flags "=" flagsField ( "\|" flagsField )* << WriteFlags (); >>
1598 Key "=" KNUM:Number << WriteWord (GetNumber(KNUM->getText(), KNUM->getLine(), 2)); >>
1603 //*****************************************************************************
1607 // inventory help = ID, text = ID;
1608 // inventory help = ID, text = id, text = ID;
1610 vfrStatementInventory :
1611 IDI:Inventory << WriteOpByte (IDI->getLine(), EFI_IFR_INVENTORY_OP); >>
1612 Help "=" getStringId ","
1613 Text "=" getStringId // writes string identifier
1614 { "," Text "=" getStringId
1619 //*****************************************************************************
1623 // restore defaults,
1625 // prompt = STRING_TOKEN(STR_RESTORE_DEFAULTS_PROMPT),
1626 // help = STRING_TOKEN(STR_RESTORE_DEFAULTS_HELP),
1632 // prompt = STRING_TOKEN(STR_SAVE_DEFAULTS_PROMPT),
1633 // help = STRING_TOKEN(STR_SAVE_DEFAULTS_HELP),
1637 vfrStatementSaveRestoreDefaults :
1638 << unsigned int KeyValue = 0; UINT32 LineNum; ResetFlags (); >>
1639 ( IDS:Save << WriteOpByte (IDS->getLine(), EFI_IFR_SAVE_DEFAULTS_OP); >>
1640 | IDR:Restore << WriteOpByte (IDR->getLine(), EFI_IFR_RESTORE_DEFAULTS_OP); >>
1643 FormId "=" FRMID:Number "," << WriteWord (GetNumber (FRMID->getText(), FRMID->getLine(), 2));
1644 AddGotoReference (GetNumber (FRMID->getText(), FRMID->getLine(), 2), FRMID->getLine());
1646 Prompt "=" getStringId ","
1647 KH:Help "=" getStringId << LineNum = KH->getLine(); >>
1649 "," FF:Flags "=" flagsField ( "\|" flagsField )* << LineNum = FF->getLine(); >>
1652 "," Key "=" KNUM:Number << LineNum = KNUM->getLine(); KeyValue = GetNumber(KNUM->getText(), LineNum, 2); >>
1654 << WriteFlagsKey (KeyValue, LineNum); >>
1658 //*****************************************************************************
1662 // flags = 0x10 | DEFAULT | MANUFACTURING | INTERACTIVE | NV_ACCESS | RESET_REQUIRED | LATE_CHECK
1666 VAL:Number << SetFlags (GetNumber(VAL->getText(), VAL->getLine(), 4), VAL->getLine()); >>
1667 | IF:InteractiveFlag << SetFlags (EFI_IFR_FLAG_INTERACTIVE, IF->getLine()); >>
1668 | MF:ManufacturingFlag << SetFlags (EFI_IFR_FLAG_MANUFACTURING, MF->getLine()); >>
1669 | DF:DefaultFlag << SetFlags (EFI_IFR_FLAG_DEFAULT, DF->getLine()); >>
1670 | NV:NVAccessFlag << SetFlags (EFI_IFR_FLAG_NV_ACCESS, NV->getLine()); >>
1671 | RR:ResetRequiredFlag << SetFlags (EFI_IFR_FLAG_RESET_REQUIRED, RR->getLine()); >>
1672 | LC:LateCheckFlag << SetFlags (EFI_IFR_FLAG_LATE_CHECK, LC->getLine()); >>
1675 dateTimeSubStatement :
1676 Prompt "=" getStringId ","
1677 Help "=" getStringId ","
1678 << WriteByte (0, 0); WriteWord (0); >> // bogus flags and key
1679 minMaxStepDefault << WriteMinMaxStepDefault (); >>
1682 vfrStatementCheckBox :
1683 << UINT32 LineNum, KeyValue = 0; ResetFlags (); >>
1684 IDCB:CheckBox << WriteOpByte (IDCB->getLine(), EFI_IFR_CHECKBOX_OP); >>
1685 VarId "=" vfrStructFieldName[1] ","
1686 Prompt "=" getStringId ","
1687 Help "=" getStringId ","
1688 FF:Flags "=" flagsField ( "\|" flagsField )* "," << LineNum = FF->getLine(); >>
1690 Key "=" KV:Number "," << LineNum = KV->getLine(); KeyValue = GetNumber(KV->getText(), LineNum, 2); >>
1692 << WriteFlagsKey (KeyValue, LineNum); >>
1696 vfrStatementSubTitle :
1697 IDS:Subtitle Text "=" << WriteOpByte (IDS->getLine(), EFI_IFR_SUBTITLE_OP); >>
1698 getStringId // writes string indentifier
1702 //*****************************************************************************
1706 // title = STRING_TOKEN(STR_BANNER_TITLE),
1708 // align center; // or left or right
1711 // title = STRING_TOKEN(STR_BANNER_TITLE), timeout = 100;
1713 vfrStatementBanner :
1714 IDB:Banner { "," } << WriteOpByte (IDB->getLine(), EFI_IFR_BANNER_OP); >>
1715 Title "=" getStringId ","
1717 Line VAL:Number "," << WriteWord (GetNumber(VAL->getText(), VAL->getLine(), 2)); >>
1719 ( Left << WriteByte (EFI_IFR_BANNER_ALIGN_LEFT, 0); >>
1720 | Center << WriteByte (EFI_IFR_BANNER_ALIGN_CENTER, 0); >>
1721 | Right << WriteByte (EFI_IFR_BANNER_ALIGN_RIGHT, 0); >>
1724 Timeout "=" TO:Number ";" << WriteWord (GetNumber(TO->getText(), TO->getLine(), 2)); >>
1725 << WriteByte (EFI_IFR_BANNER_TIMEOUT, 0); >>
1729 //*****************************************************************************
1732 // oneof varid = MyNv.OneOfData,
1733 // prompt = STRING_TOKEN(STR_ONE_OF_PROMPT),
1734 // help = STRING_TOKEN(STR_ONE_OF_HELP),
1735 // option text = STRING_TOKEN(STR_ONE_OF_TEXT),
1737 // flags = DEFAULT | INTERACTIVE;
1739 // supressif/grayoutif are supported inside oneof stmt.
1740 // We do not restrict the number of oneOfOptionText to >=2, but >=1.
1741 // The situation that all oneOfOptionText are suppressed is also possiable.
1744 << ResetFlags (); >>
1745 IDOO:OneOf << WriteOpByte (IDOO->getLine(), EFI_IFR_ONE_OF_OP); >>
1746 VarId "=" vfrStructFieldName[2] ","
1747 Prompt "=" getStringId "," // writes string identifier
1748 Help "=" getStringId "," // writes string identifier
1749 ( oneOfOptionText )+ // there must be at least 1 option to be choosed, not 2.
1750 IDEOO:EndOneOf ";" << TestOneOfFlags (IDEOO->getLine()); WriteOpByte (IDEOO->getLine(), EFI_IFR_END_ONE_OF_OP); >>
1753 //*****************************************************************************
1757 // orderedlist varid = MyNv.OrderedListData,
1758 // prompt = STRING_TOKEN(STR_ORDERED_LIST_PROMPT),
1759 // help = STRING_TOKEN(STR_ORDERED_LIST_HELP),
1760 // option text = STRING_TOKEN(STR_ORDERED_LIST_TEXT), value = 0, flags = INTERACTIVE;
1761 // -- additional option text --
1764 vfrStatementOrderedList :
1765 << ResetFlags (); InitOrderedList(); >>
1766 IDOL:OrderedList << WriteOpByte (IDOL->getLine(), EFI_IFR_ORDERED_LIST_OP); >>
1767 VarId "=" vfrStructFieldNameArray[1] ","
1768 Prompt "=" getStringId "," // writes string identifier
1769 Help "=" getStringId "," // writes string identifier
1770 orderedListOptionText ( orderedListOptionText )+
1771 IDEOL:EndList ";" << WriteOpByte (IDEOL->getLine(), EFI_IFR_END_OP); EndOrderedList(IDEOL->getLine()); >>
1774 //*****************************************************************************
1778 // option text = STRING_TOKEN(STRING_ID), value = 0 flags = 99;
1780 // Differs from the oneOfOptionText in that we don't allow the DEFAULT flag to
1781 // be set, and value cannot be 0.
1783 orderedListOptionText :
1784 << UINT32 KeyValue = 0; >>
1785 IDO:Option << WriteOpByte (IDO->getLine(), EFI_IFR_ONE_OF_OPTION_OP); >>
1786 Text "=" getStringId "," // writes string identifier
1787 Value "=" WVAL:Number "," <<
1788 if (GetNumber(WVAL->getText(), WVAL->getLine(), 2) == 0) {
1789 PrintErrorMessage (WVAL->getLine(), "value=0 is invalid for ordered lists", NULL);
1791 WriteWord (GetNumber(WVAL->getText(), WVAL->getLine(), 2));
1794 FF:Flags "=" orderedListFlagsField
1795 ("\|" orderedListFlagsField )*
1797 "," Key "=" KV:Number << KeyValue = GetNumber (KV->getText(), KV->getLine(), 2); >>
1799 << WriteFlagsKey (KeyValue, FF->getLine()); >>
1800 ";" << mOptionCount++; >>
1803 //*****************************************************************************
1807 // flags = 0x10 | DEFAULT | MANUFACTURING | INTERACTIVE | NV_ACCESS | RESET_REQUIRED | LATE_CHECK
1809 // The ordered list flags field cannot have a default.
1811 orderedListFlagsField :
1812 VAL:Number << SetFlags (GetNumber(VAL->getText(), VAL->getLine(), 4), VAL->getLine()); >>
1813 | IF:InteractiveFlag << SetFlags (EFI_IFR_FLAG_INTERACTIVE, IF->getLine()); >>
1814 | MF:ManufacturingFlag << SetFlags (EFI_IFR_FLAG_MANUFACTURING, MF->getLine()); >>
1815 | NV:NVAccessFlag << SetFlags (EFI_IFR_FLAG_NV_ACCESS, NV->getLine()); >>
1816 | RR:ResetRequiredFlag << SetFlags (EFI_IFR_FLAG_RESET_REQUIRED, RR->getLine()); >>
1817 | LC:LateCheckFlag << SetFlags (EFI_IFR_FLAG_LATE_CHECK, LC->getLine()); >>
1818 | DF:DefaultFlag << PrintWarningMessage (DF->getLine(), "DEFAULT flag not valid for ordered lists", NULL); >>
1822 // Parse references to VFR structure field names of form "MyNvStructure.Field".
1823 // This implementation is specific to strings, passwords, and references in an
1824 // ordered list statement because we want to specify the size of the entire
1825 // field, rather than just one element. Then call a function to write out its
1826 // offset and length.
1828 vfrStructFieldNameArray[int FieldWidth] :
1829 << int ArrayIndex = 1; char IsArrayIndex = 0; >>
1830 SName:StringIdentifier
1832 SFieldName:StringIdentifier
1833 { OpenBracket AIndex:Number CloseBracket << ArrayIndex = GetNumber(AIndex->getText(), AIndex->getLine(), 4); IsArrayIndex = 1; >> }
1835 WriteFieldOffset (1,
1838 SFieldName->getText(),
1839 SFieldName->getLine(),
1849 // Parse references to VFR structure field names of form "MyNvStructure.Field",
1850 // then call a function to write out its offset and length.
1852 vfrStructFieldName[int FieldWidth] :
1853 << int ArrayIndex = 1; char IsArrayIndex = 0; >>
1854 SName:StringIdentifier
1856 SFieldName:StringIdentifier
1857 { OpenBracket AIndex:Number CloseBracket << ArrayIndex = GetNumber(AIndex->getText(), AIndex->getLine(), 4); IsArrayIndex = 1; >> }
1859 WriteFieldOffset (1,
1862 SFieldName->getText(),
1863 SFieldName->getLine(),
1872 //*****************************************************************************
1876 // MyNvStructure.FieldName[4]
1878 // Parse references to VFR structure field names of form "MyNvStructure.Field",
1879 // then call a function to write out the offset with no length.
1881 vfrStructFieldNameNL[int FieldWidth] :
1882 << int ArrayIndex = 1; char IsArrayIndex = 0; >>
1883 SName:StringIdentifier
1885 SFieldName:StringIdentifier
1886 { OpenBracket AIndex:Number CloseBracket << ArrayIndex = GetNumber(AIndex->getText(), AIndex->getLine(), 4); IsArrayIndex = 1; >> }
1888 WriteFieldOffset (0,
1891 SFieldName->getText(),
1892 SFieldName->getLine(),
1901 //*****************************************************************************
1904 // suppressif TRUE OR FALSE;
1905 // grayoutif FALSE OR TRUE;
1906 // option text = STRING_TOKEN(STRING_ID), value = 0 flags = 99;
1907 // option text = STRING_TOKEN(STRING_ID2), value = 1 flags = 98;
1911 suppressIfOptionText |
1912 grayOutIfOptionText |
1916 suppressIfOptionText :
1917 << ResetFlags (); >>
1918 OPID:SuppressIf << WriteOpByte (OPID->getLine(), EFI_IFR_SUPPRESS_IF_OP); SetIfStart (OPID->getLine()); >>
1920 FF:Flags "=" flagsField ( "\|" flagsField )* ","
1922 << WriteFlags (); >> // write the flags field
1923 vfrBooleanExpression
1925 { suppressIfGrayOutIf } ( commonOptionText )+
1926 ENDOP:EndIf ";" << WriteOpByte (ENDOP->getLine(), EFI_IFR_END_IF_OP); SetIfStart (0); >>
1929 grayOutIfOptionText :
1930 << ResetFlags (); >>
1931 OPID:GrayOutIf << WriteOpByte (OPID->getLine(), EFI_IFR_GRAYOUT_IF_OP); SetIfStart (OPID->getLine()); >>
1933 FF:Flags "=" flagsField ( "\|" flagsField )* ","
1935 << WriteFlags (); >> // write the flags field
1936 vfrBooleanExpression
1938 { grayoutIfSuppressIf } ( commonOptionText )+
1939 ENDOP:EndIf ";" << WriteOpByte (ENDOP->getLine(), EFI_IFR_END_IF_OP); SetIfStart (0); >>
1943 << UINT32 KeyValue = 0; >>
1944 IDO:Option << WriteOpByte (IDO->getLine(), EFI_IFR_ONE_OF_OPTION_OP); >>
1945 Text "=" getStringId "," // writes string identifier
1946 Value "=" WVal:Number "," << WriteWord (GetNumber(WVal->getText(), WVal->getLine(), 2)); >>
1947 FF:Flags "=" flagsField ("\|" flagsField )*
1949 "," Key "=" KV:Number << KeyValue = GetNumber (KV->getText(), KV->getLine(), 2); >>
1951 << WriteFlagsKey (KeyValue, FF->getLine()); >>
1952 ";" << mOptionCount++; >>
1956 // Gets a string identifier. It must be a numeric value of form:
1958 // STRING_TOKEN(100)
1961 << unsigned short StrId; >>
1962 StringToken OpenParen
1963 IdVal:Number << StrId = GetNumber (IdVal->getText(), IdVal->getLine(), 2); WriteStringIdWord (StrId); >>
1967 //******************************************************************************
1969 // Parser class definition.
1971 class EfiVfrParser {
1974 // Parser definitions go here
1977 STRUCT_DEFINITION *mFirstStructDefinition;
1978 STRUCT_DEFINITION *mLastStructDefinition;
1979 INT32 mNvDataStructSize;
1980 INT32 mNonNvDataStructSize;
1982 // Flag to indicate that we're processing a ideqid VFR statement so that
1983 // we can do late checks on the statement.
1986 INT32 mLastNVVariableDataSize;
1987 GOTO_REFERENCE *mGotoReferences;
1988 FORM_ID_VALUE *mFormIdValues;
1989 VfrOpcodeHandler mOpcodeHandler;
1990 UINT16_LIST *mUint16List;
1991 UINT16_LIST *mLastUint16;
1992 UINT16_LIST *mDefinedLabels;
1993 UINT16_LIST *mDefinedVarStoreId;
1994 UINT16_LIST *mLastDefinedVarStoreId;
1995 UINT32 mMinimumValue, mMaximumValue, mStepValue, mDefaultValue;
1997 UINT32 mSubStmtFlags;
1998 UINT32 mSubStmtFlagsLineNum;
1999 EFI_GUID mFormSetGuid;
2000 UINT8 mNvDataStructDefined;
2001 UINT16 mClass, mSubclass;
2003 UINT32 mOptionCount; // how many "option" fields in a given statement
2004 UINT32 mLastVarIdSize;
2009 EfiVfrParser::SetIfStart (
2014 Routine Description:
2015 Invoked during VFR parsing when an "if" is encountered. Save the
2016 source line number so we can point to it if we don't find a
2017 corresponding endif later.
2020 LineNum - source line number where the "if" was parsed.
2030 EfiVfrParser::SetClass (
2036 Routine Description:
2037 Invoked during VFR parsing when a "class" statement is found. Check the
2038 range on the class value and save it for later.
2041 LineNum - source line number where the class statement was parsed.
2042 Value - the class value
2049 if (Value & 0xFFFF0000) {
2050 PrintWarningMessage (LineNum, NULL, "class value exceeds maximum allowed");
2052 mClass |= (UINT16)Value;
2055 EfiVfrParser::SetSubclass (
2061 Routine Description:
2062 Invoked during VFR parsing when a subclass statement is found. Check the
2063 range on the value and save it for later.
2066 LineNum - source line number where the class statement was parsed.
2067 Value - the subclass value from the VFR statement
2074 if (Value & 0xFFFF0000) {
2075 PrintWarningMessage (LineNum, NULL, "subclass value exceeds maximum allowed");
2077 mSubclass |= (UINT16)Value;
2079 VOID EfiVfrParser::WriteClass ()
2084 VOID EfiVfrParser::WriteSubclass ()
2086 WriteWord (mSubclass);
2089 VOID EfiVfrParser::WriteIfrBytes ()
2091 mOpcodeHandler.WriteIfrBytes ();
2094 EfiVfrParser::WriteFlagsKey (
2100 Routine Description:
2101 Write out the flags and key values from the previous VFR statement.
2102 Many statements take a flags/key pair. If not specified, then 0
2103 values are written out. However do not allow an interactive flags field
2104 to be specified if no key value is specified. Also, if NV_ACCESS flag
2105 is set but INTERACTIVE is not, then set interactive and issue a warning.
2108 KeyValue - the key value from the VFR statement
2109 LineNum - source line number where the statement was parsed
2116 if ((mSubStmtFlags & EFI_IFR_FLAG_INTERACTIVE) && (KeyValue == 0)) {
2117 PrintErrorMessage (LineNum, NULL, "invalid or missing key value - required with INTERACTIVE");
2119 if ((mSubStmtFlags & EFI_IFR_FLAG_NV_ACCESS) && !(mSubStmtFlags & EFI_IFR_FLAG_INTERACTIVE)) {
2120 PrintWarningMessage (LineNum, NULL, "NV_ACCESS without INTERACTIVE has no effect -- setting INTERACTIVE");
2121 mSubStmtFlags |= EFI_IFR_FLAG_INTERACTIVE;
2124 WriteWord (KeyValue);
2127 EfiVfrParser::InitOrderedList ()
2132 EfiVfrParser::EndOrderedList (
2136 if (mLastVarIdSize < mOptionCount) {
2137 PrintErrorMessage (LineNum, NULL, "number of options exceeds the variable store size");
2141 EfiVfrParser::ResetFlags ()
2144 Routine Description:
2146 Flags are set for each substatement in a given one-of statement.
2147 To make sure there are no conflicts, for example setting DEFAULT on
2148 more than one substatement, we keep track of the flags at a statement
2149 level and a substatement level. This function resets the flags so
2150 we get a fresh start.
2161 mSubStmtFlagsLineNum = 0;
2165 // Test validity of flags value for a one-of statement.
2168 EfiVfrParser::TestOneOfFlags (
2173 // One of the fields must have had the default bit set
2175 if ((mStmtFlags & EFI_IFR_FLAG_DEFAULT) == 0) {
2176 PrintWarningMessage (LineNum, "default value must be specified", NULL);
2180 EfiVfrParser::SetFlags (
2186 // Check for redefinitions and invalid combinations
2188 if (mStmtFlags & Flags & EFI_IFR_FLAG_MANUFACTURING) {
2189 PrintErrorMessage (LineNum, "MANUFACTURING", "a field with this flag already defined");
2191 if (mStmtFlags & Flags & EFI_IFR_FLAG_DEFAULT) {
2192 PrintErrorMessage (LineNum, "DEFAULT", "a field with this flag already defined");
2194 mSubStmtFlags |= Flags;
2195 mSubStmtFlagsLineNum = LineNum;
2198 EfiVfrParser::WriteFlags ()
2201 // Check value for validity
2203 if (mSubStmtFlags & ~(EFI_IFR_FLAG_DEFAULT |
2204 EFI_IFR_FLAG_MANUFACTURING |
2205 EFI_IFR_FLAG_INTERACTIVE |
2206 EFI_IFR_FLAG_NV_ACCESS |
2207 EFI_IFR_FLAG_RESET_REQUIRED |
2208 EFI_IFR_FLAG_LATE_CHECK )) {
2209 PrintWarningMessage (mSubStmtFlagsLineNum, "invalid bits defined in flag", NULL);
2211 WriteByte ((UINT8)mSubStmtFlags, 'F');
2213 // We can now clear the substatement flags
2215 mStmtFlags |= mSubStmtFlags;
2219 // When we parse a min/max/step/default sequence, save off the values for
2220 // later use. Call this first to init the values.
2223 EfiVfrParser::InitMinMaxStepDefault ()
2231 EfiVfrParser::WriteMinMaxStepDefault ()
2233 WriteWord (mMinimumValue);
2234 WriteWord (mMaximumValue);
2235 WriteWord (mStepValue);
2236 WriteWord (mDefaultValue);
2239 EfiVfrParser::SetMinMaxStepDefault (
2250 mMinimumValue = Value;
2251 mDefaultValue = Value;
2255 } else if (MMSD == 1) {
2256 mMaximumValue = Value;
2258 // If min > max, then swap the values. That includes resetting the default
2261 if (mMinimumValue > mMaximumValue) {
2262 PrintWarningMessage (LineNum, NULL, "maximum < minimum");
2264 mMaximumValue = mMinimumValue;
2265 mMinimumValue = TempValue;
2266 mDefaultValue = mMinimumValue;
2271 } else if (MMSD == 2) {
2274 // Default specified. Make sure min <= default <= max.
2276 } else if (MMSD == 3) {
2277 mDefaultValue = Value;
2278 if (mMinimumValue > Value) {
2279 PrintErrorMessage (LineNum, NULL, "default value < minimum value");
2280 } else if (Value > mMaximumValue) {
2281 PrintErrorMessage (LineNum, NULL, "default value > maximum value");
2284 PrintErrorMessage (LineNum, "application error", "internal MMSD error");
2288 EfiVfrParser::AddLabel (
2296 // Added a label from the user VFR script. Make sure they haven't already
2297 // defined the same label elsewhere
2299 for (Label = mDefinedLabels; Label != NULL; Label = Label->Next) {
2300 if (Label->Value == LabelNumber) {
2301 PrintErrorMessage (LineNum, NULL, "label already defined");
2302 PrintErrorMessage (Label->LineNum, NULL, "previous definition of redefined label");
2306 Label = (UINT16_LIST *)malloc (sizeof (UINT16_LIST));
2307 if (Label == NULL) {
2308 PrintErrorMessage (0, NULL, "memory allocation error");
2311 memset ((char *)Label, 0, sizeof (UINT16_LIST));
2312 Label->Value = LabelNumber;
2313 Label->LineNum = LineNum;
2314 Label->Next = mDefinedLabels;
2315 mDefinedLabels = Label;
2318 EfiVfrParser::QueueIdEqValList (
2324 U16 = (UINT16_LIST *)malloc (sizeof (UINT16_LIST));
2326 Error (UTILITY_NAME, 0, 0, NULL, "memory allocation failed");
2328 memset ((char *)U16, 0, sizeof (UINT16_LIST));
2330 if (mUint16List == NULL) {
2333 mLastUint16->Next = U16;
2339 EfiVfrParser::FlushQueueIdEqValList ()
2344 // We queued up a list of IdEqValList items. The IFR requires a count
2345 // followed by the actual values. Do it.
2348 mLastUint16 = mUint16List;
2349 while (mLastUint16 != NULL) {
2351 mLastUint16 = mLastUint16->Next;
2353 // BUGBUG -- check for more than 16K items?
2356 // Now write the values.
2358 mLastUint16 = mUint16List;
2359 while (mLastUint16 != NULL) {
2360 WriteWord ((UINT32)mLastUint16->Value);
2361 mLastUint16 = mLastUint16->Next;
2366 mLastUint16 = mUint16List;
2367 while (mUint16List != NULL) {
2368 mLastUint16 = mUint16List->Next;
2370 mUint16List = mLastUint16;
2374 EfiVfrParser::PrintErrorMessage (
2383 FileName = ConvertLineNumber ((UINT32 *)&LineNum);
2384 Error (FileName, LineNum, 0, Msg1, Msg2);
2386 Error (UTILITY_NAME, 0, 0, Msg1, Msg2);
2390 EfiVfrParser::PrintWarningMessage (
2399 FileName = ConvertLineNumber ((UINT32 *)&LineNum);
2400 Warning (FileName, LineNum, 0, Msg1, Msg2);
2402 Warning (UTILITY_NAME, 0, 0, Msg1, Msg2);
2407 ANTLRAbstractToken *Tok,
2410 ANTLRTokenType ETok,
2415 Routine Description:
2416 Called by the parser base class as a result of parse syntax errors.
2419 Tok - token that caused the error
2421 Eset - index in token table of the expected token
2432 LineNum = Tok->getLine ();
2433 FileName = ConvertLineNumber ((UINT32 *)&LineNum);
2435 // Sometimes the token number is 0, in which case I don't know what to
2439 Error (FileName, LineNum, 0, Tok->getText (), "unexpected token");
2442 // If we were expecting an endif, then report the line where the corresponding
2445 if ((strcmp (_token_tbl[ETok], "endif") == 0) && (mIfStart != 0)) {
2447 FileName = ConvertLineNumber (&LineNum);
2448 Error (FileName, LineNum, 0, "statement missing corresponding endif", NULL);
2450 Error (FileName, LineNum, 0, Tok->getText (), "expected %s", _token_tbl[ETok]);
2456 EfiVfrParser::init()
2459 Routine Description:
2460 Initializations function for our parser.
2470 ANTLRParser::init();
2473 // Used for queuing a variable list of UINT16's
2477 mFirstStructDefinition = NULL;
2478 mLastStructDefinition = NULL;
2479 mNvDataStructSize = 0;
2480 mNonNvDataStructSize = 0;
2481 mNvDataStructDefined = 0;
2482 mGotoReferences = NULL;
2483 mFormIdValues = NULL;
2484 mDefinedLabels = NULL;
2488 mDefinedVarStoreId = NULL;
2489 mLastDefinedVarStoreId = NULL;
2491 mLastNVVariableDataSize = 0;
2493 memset ((char *)&mFormSetGuid, 0, sizeof (EFI_GUID));
2496 // Destructor for the parser.
2498 EfiVfrParser::~EfiVfrParser(VOID)
2503 EfiVfrParser::Cleanup (VOID)
2506 Routine Description:
2507 Free memory allocated during parsing
2517 STRUCT_DEFINITION *NextStruct;
2518 STRUCT_FIELD_DEFINITION *NextField;
2520 UINT16_LIST *NextU16List;
2523 // Free up the structure definitions if any
2525 while (mFirstStructDefinition != NULL) {
2527 // Free up all the fields for this struct
2529 while (mFirstStructDefinition->Field != NULL) {
2530 NextField = mFirstStructDefinition->Field->Next;
2531 free (mFirstStructDefinition->Field->Name);
2532 free (mFirstStructDefinition->Field);
2533 mFirstStructDefinition->Field = NextField;
2535 NextStruct = mFirstStructDefinition->Next;
2536 free (mFirstStructDefinition->Name);
2537 free (mFirstStructDefinition);
2538 mFirstStructDefinition = NextStruct;
2541 // Free up the goto references and form id defines
2543 FreeGotoReferences ();
2545 // Free up label list
2547 while (mDefinedLabels != NULL) {
2548 NextU16List = mDefinedLabels->Next;
2549 delete (mDefinedLabels);
2550 mDefinedLabels = NextU16List;
2553 // Free up the list of defined variable storage IDs
2555 while (mDefinedVarStoreId != NULL) {
2556 NextU16List = mDefinedVarStoreId->Next;
2557 delete (mDefinedVarStoreId);
2558 mDefinedVarStoreId = NextU16List;
2563 EfiVfrParser::AtoX (
2570 Routine Description:
2571 Given a pointer to a ascii hex string, convert to a number with the given
2575 HexString - pointer to a string of format 30BCA
2576 Size - number of bytes to convert
2577 HexValue - return result
2580 The number of bytes converted.
2589 while (Count < NumBytes) {
2590 if ((*HexString >= '0') && (*HexString <= '9')) {
2591 Value = *HexString - '0';
2592 } else if ((*HexString >= 'a') && (*HexString <= 'f')) {
2593 Value = *HexString - 'a' + 10;
2594 } else if ((*HexString >= 'A') && (*HexString <= 'F')) {
2595 Value = *HexString - 'A' + 10;
2600 *HexValue = (*HexValue << 4) | Value;
2601 if ((*HexString >= '0') && (*HexString <= '9')) {
2602 Value = *HexString - '0';
2603 } else if ((*HexString >= 'a') && (*HexString <= 'f')) {
2604 Value = *HexString - 'a' + 10;
2605 } else if ((*HexString >= 'A') && (*HexString <= 'F')) {
2606 Value = *HexString - 'A' + 10;
2610 *HexValue = (*HexValue << 4) | Value;
2617 EfiVfrParser::WriteGuidValue (
2618 UINT32 TokenLineNum,
2633 Routine Description:
2634 A Guid was parsed, likely of format:
2635 #define MY_GUID { 0x12345678, 0xAABB, 0xCCDD, 0xEE, 0xFF, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 }
2637 Write out the value.
2640 TokenLineNum - line number where the guid was used
2641 G1-G11 - the 11 fields of the guid value
2652 mFormSetGuid.Data1 = GetNumber (G1, TokenLineNum, 4);
2653 mFormSetGuid.Data2 = (UINT16)GetNumber (G2, TokenLineNum, 2);
2654 mFormSetGuid.Data3 = (UINT16)GetNumber (G3, TokenLineNum, 2);
2655 mFormSetGuid.Data4[0] = (UINT8)GetNumber (G4, TokenLineNum, 1);
2656 mFormSetGuid.Data4[1] = (UINT8)GetNumber (G5, TokenLineNum, 1);
2657 mFormSetGuid.Data4[2] = (UINT8)GetNumber (G6, TokenLineNum, 1);
2658 mFormSetGuid.Data4[3] = (UINT8)GetNumber (G7, TokenLineNum, 1);
2659 mFormSetGuid.Data4[4] = (UINT8)GetNumber (G8, TokenLineNum, 1);
2660 mFormSetGuid.Data4[5] = (UINT8)GetNumber (G9, TokenLineNum, 1);
2661 mFormSetGuid.Data4[6] = (UINT8)GetNumber (G10, TokenLineNum, 1);
2662 mFormSetGuid.Data4[7] = (UINT8)GetNumber (G11, TokenLineNum, 1);
2664 WriteDWord (mFormSetGuid.Data1, 'G');
2665 WriteWord (mFormSetGuid.Data2);
2666 WriteWord (mFormSetGuid.Data3);
2667 WriteByte (mFormSetGuid.Data4[0], 0);
2668 WriteByte (mFormSetGuid.Data4[1], 0);
2669 WriteByte (mFormSetGuid.Data4[2], 0);
2670 WriteByte (mFormSetGuid.Data4[3], 0);
2671 WriteByte (mFormSetGuid.Data4[4], 0);
2672 WriteByte (mFormSetGuid.Data4[5], 0);
2673 WriteByte (mFormSetGuid.Data4[6], 0);
2674 WriteByte (mFormSetGuid.Data4[7], 0);
2677 EfiVfrParser::WriteFieldOffset (
2690 Routine Description:
2691 A VFR script referenced the NV store structure. Given the structure's name
2692 and the field's name, write the offset of the field to the output file.
2695 WriteLength - write the field length byte out
2696 StructName - name of the NV store structure
2697 LineNum1 - line number in the VFR where we are (for error printing)
2698 FieldName - the name of the field within the NV store structure
2699 LineNum2 - line number in the VFR where FieldName is referenced
2700 ArrayIndex - the index specified, for example NV_DATA.Field[ArrayIndex]
2701 IsArrayIndex - non-zero if an array index was specified
2702 FieldWidth - expected size for the Field (1 byte? 2 bytes?)
2703 WriteArraySize - write the size of the entire field, not the size of a single element
2710 STRUCT_DEFINITION *StructDef;
2711 STRUCT_FIELD_DEFINITION *FieldDef;
2716 // If we're writing an array size, then they better have referenced the field without an
2719 if (WriteArraySize && IsArrayIndex) {
2720 sprintf (Msg, "array index specified where an array is required");
2721 PrintErrorMessage (LineNum2, FieldName, Msg);
2726 // The reference index starts at 1 not 0
2728 if (IsArrayIndex && (ArrayIndex < 1)) {
2729 printf ("WARNING: array index shouldn't be less than 1");
2732 // Look through our list of known structures for a match
2734 for (StructDef = mFirstStructDefinition; StructDef != NULL; StructDef = StructDef->Next) {
2736 // Check for matching structure name
2738 if (strcmp (StructDef->Name, StructName) == 0) {
2740 // Mark it as referenced (for debug purposes only). Check the
2741 // flag that indicates that we have already found a varstore VFR
2742 // statement for it.
2744 StructDef->Referenced++;
2745 if (StructDef->VarStoreIdValid == 0) {
2747 // Set it valid so we don't flag it multiple times, then emit the error
2749 StructDef->VarStoreIdValid = 1;
2750 PrintErrorMessage (LineNum1, StructName, "varstore statement missing for this variable store");
2753 // Let the opcode-handler know which variable storage we're now using
2756 mOpcodeHandler.SetSecondaryVarStoreId (StructDef->VarStoreId);
2758 mOpcodeHandler.SetVarStoreId (StructDef->VarStoreId);
2761 // Found matching structure name. Now find the matching field name
2763 for (FieldDef = StructDef->Field; FieldDef != NULL; FieldDef = FieldDef->Next) {
2764 if (strcmp (FieldDef->Name, FieldName) == 0) {
2766 // Make sure the variable size is valid
2768 if ((FieldWidth != 0) && (FieldDef->DataSize > FieldWidth)) {
2769 sprintf (Msg, "field width exceeds %d byte%c", FieldWidth, FieldWidth == 1 ? ' ' : 's');
2770 PrintErrorMessage (LineNum2, FieldName, Msg);
2773 // If they specified an index (MyVfrData.FieldX[10]), then make sure that the
2774 // data structure was declared as an array, and that the index is in bounds.
2775 // If they did not specify an index, then we'll assume 0. This is required for
2779 VarSize = FieldDef->DataSize;
2780 if (FieldDef->IsArray == 0) {
2781 PrintErrorMessage (LineNum2, FieldName, "field is not declared as an array");
2784 if (FieldDef->ArrayLength < ArrayIndex) {
2785 PrintErrorMessage (LineNum2, FieldName, "array index exceeds declared size of field");
2789 if (FieldDef->IsArray) {
2790 VarSize = FieldDef->DataSize * FieldDef->ArrayLength;
2792 VarSize = FieldDef->DataSize;
2796 // If we're in the middle of a ideqid VFR statement, then this is the second
2797 // variable ID that we're now processing. Make sure that its size is the same
2798 // as the first variable.
2801 if (mLastVarIdSize != VarSize) {
2802 PrintErrorMessage (LineNum2, FieldName, "variables must have the same size");
2806 mLastVarIdSize = VarSize;
2808 // If we're supposed to write an array size, then require it to be an array
2810 if (WriteArraySize && !FieldDef->IsArray) {
2811 PrintErrorMessage (LineNum2, FieldName, "array required");
2815 // Write the variable offset and size. If we're in the non-NV structure, then
2816 // set the offset beyond the NV data structure size.
2818 Offset = FieldDef->Offset + FieldDef->DataSize * (ArrayIndex - 1);
2819 if (StructDef->IsNonNV) Offset += mNvDataStructSize;
2822 if (WriteArraySize) {
2823 if (FieldDef->DataSize * FieldDef->ArrayLength > 255) {
2824 PrintErrorMessage (LineNum2, FieldName, "array size exceeds 255 maximum encoding limit");
2827 WriteByte (FieldDef->DataSize * FieldDef->ArrayLength, 0);
2829 WriteByte (FieldDef->DataSize, 0);
2835 sprintf (Msg, "structure %s does not have a field named '%s'", StructName, FieldName);
2836 PrintErrorMessage (LineNum2, Msg, NULL);
2837 PrintErrorMessage (StructDef->LineNum, "see structure definition", NULL);
2842 // The structure was not found in the defined list. See if it's the "Date" structure
2844 if (strcmp (StructName, "Date") == 0) {
2846 // BUGBUG -- remove support for Date and Time as valid structure
2847 // names. They should use the NON_NV_DATA_MAP structure for this.
2849 // Someone specified Date.Years|Months|Days
2850 // BUGBUG -- define some constants for the IDs used here
2851 // Length == 0 implies that this is not user NV data storage.
2853 if (strcmp (FieldName, "Year") == 0) {
2855 // Write ID (offset), ID, and size
2857 WriteWord (mNvDataStructSize + mNonNvDataStructSize + 0);
2861 } else if (strcmp (FieldName, "Month") == 0) {
2863 // Write ID (offset), ID, and size
2865 WriteWord (mNvDataStructSize + mNonNvDataStructSize + 2);
2869 } else if (strcmp (FieldName, "Day") == 0) {
2871 // Write ID (offset), ID, and size
2873 WriteWord (mNvDataStructSize + mNonNvDataStructSize + 4);
2878 PrintErrorMessage (LineNum1, FieldName, "expected valid field name TheYear/TheMonth/TheDay");
2881 } else if (strcmp (StructName, "Time") == 0) {
2883 // Someone specified Time.Hours|Minutes|Seconds
2884 // BUGBUG -- define some constants for the IDs used here
2886 if (strcmp (FieldName, "Hours") == 0) {
2888 // Write ID (offset), ID, and size
2890 WriteWord (mNvDataStructSize + mNonNvDataStructSize + 6);
2894 } else if (strcmp (FieldName, "Minutes") == 0) {
2896 // Write ID (offset), ID, and size
2898 WriteWord (mNvDataStructSize + mNonNvDataStructSize + 8);
2902 } else if (strcmp (FieldName, "Seconds") == 0) {
2904 // Write ID (offset), ID, and size
2906 WriteWord (mNvDataStructSize + mNonNvDataStructSize + 10);
2911 PrintErrorMessage (LineNum1, FieldName, "expected valid field name Hours/Minutes/Seconds");
2915 PrintErrorMessage (LineNum1, StructName, "undefined structure");
2920 EfiVfrParser::StartStructDefinition (
2926 Routine Description:
2927 Called when we encounter a new "struct _MY_STRUCT..." statement while parsing.
2928 Initialize internal data and structures for parsing the fields of the structure.
2931 LineNum - line number in the source file (for error reporting purposes)
2932 IsNonNv - flag indicating (if nonzero) that the variable referred to is not in
2933 the standard NV store.
2939 STRUCT_DEFINITION *StructDef;
2941 // Allocate memory for the structure record
2943 StructDef = (STRUCT_DEFINITION *)malloc (sizeof (STRUCT_DEFINITION));
2944 memset (StructDef, 0, sizeof (STRUCT_DEFINITION));
2945 StructDef->LineNum = LineNum;
2947 // Set flag indicating non-NV data structure or not
2949 StructDef->IsNonNV = IsNonNV;
2951 // Add it to the end of our linked list. If it's the first one
2952 // defined, then it's the default varstore ID, so set it valid.
2954 if (mFirstStructDefinition == NULL) {
2955 mFirstStructDefinition = StructDef;
2956 StructDef->VarStoreIdValid = 1;
2958 mLastStructDefinition->Next = StructDef;
2960 mLastStructDefinition = StructDef;
2963 EfiVfrParser::EndStructDefinition (
2968 STRUCT_DEFINITION *StructDef;
2969 STRUCT_FIELD_DEFINITION *FieldDef;
2972 // Make sure they have not already defined a structure with this name
2974 for (StructDef = mFirstStructDefinition; StructDef != NULL; StructDef = StructDef->Next) {
2975 if ((StructDef->Name != NULL) && (strcmp (StructDef->Name, StructName) == 0)) {
2976 PrintErrorMessage (LineNum, StructName, "structure with this name already defined");
2978 // Fall through and fill in the rest of the structure information. We do
2979 // this because the structure has already been added to our global list,
2980 // so will be used elsewhere, so we want it to contain valid fields.
2985 // Allocate memory for the structure name
2987 mLastStructDefinition->Name = (char *)malloc (strlen (StructName) + 1);
2988 strcpy (mLastStructDefinition->Name, StructName);
2990 // Compute the structure size, and the offsets to each field
2993 for (FieldDef = mLastStructDefinition->Field; FieldDef != NULL; FieldDef = FieldDef->Next) {
2994 FieldDef->Offset = Offset;
2995 Offset += FieldDef->ArrayLength * FieldDef->DataSize;
2997 mLastStructDefinition->Size = Offset;
2999 // Go through all the structure we have so far and figure out (if we can)
3000 // the size of the non-NV storage. We also assume that the first structure
3001 // definition is the primary/default storage for the VFR form.
3003 if (mNonNvDataStructSize == 0) {
3004 for (StructDef = mFirstStructDefinition; StructDef != NULL; StructDef = StructDef->Next) {
3005 if (StructDef->IsNonNV) {
3006 mNonNvDataStructSize = StructDef->Size;
3011 if (mNvDataStructSize == 0) {
3012 for (StructDef = mFirstStructDefinition; StructDef != NULL; StructDef = StructDef->Next) {
3013 if (StructDef->IsNonNV == 0) {
3014 mNvDataStructSize = StructDef->Size;
3021 EfiVfrParser::AddStructField (
3030 Routine Description:
3031 We're parsing the VFR structure definition. Add another defined field to
3035 FieldName - name of the field in the structure.
3036 LineNum - the line number from the input (preprocessor output) file
3037 DataSize - the size of the field (1, 2, or 4 bytes)
3038 ArrayLength - the number of elements (for array)
3039 IsArray - non-zero if the field is an array
3046 STRUCT_FIELD_DEFINITION *FieldDef;
3047 STRUCT_FIELD_DEFINITION *Temp;
3049 // Make sure we don't already have a field of this name in our structure
3051 for (FieldDef = mLastStructDefinition->Field; FieldDef != NULL; FieldDef = FieldDef->Next) {
3052 if (strcmp (FieldDef->Name, FieldName) == 0) {
3053 PrintErrorMessage (LineNum, FieldName, "field with this name already defined");
3058 // If it's an array, then they better not have a size of 0. For example:
3059 // UINT8 MyBytes[0];
3061 if (IsArray && (ArrayLength <= 0)) {
3062 PrintErrorMessage (LineNum, FieldName, "invalid array size");
3066 // Allocate memory for a new structure field definition
3068 FieldDef = (STRUCT_FIELD_DEFINITION *)malloc (sizeof (STRUCT_FIELD_DEFINITION));
3069 memset ((char *)FieldDef, 0, sizeof (STRUCT_FIELD_DEFINITION));
3070 FieldDef->ArrayLength = ArrayLength;
3071 FieldDef->DataSize = DataSize;
3072 FieldDef->IsArray = IsArray;
3073 FieldDef->Name = (char *)malloc (strlen (FieldName) + 1);
3074 strcpy (FieldDef->Name, FieldName);
3076 // Add it to the end of the field list for the currently active structure
3078 if (mLastStructDefinition->Field == NULL) {
3079 mLastStructDefinition->Field = FieldDef;
3081 mLastStructDefinition->LastField->Next = FieldDef;
3083 mLastStructDefinition->LastField = FieldDef;
3086 EfiVfrParser::AddVarStore (
3087 INT8 *StructName, // actual name of the structure
3088 INT8 *VarName, // actual NV variable name
3089 UINT16 VarStoreId, // key value
3090 INT32 LineNum // parse line number (for error reporting)
3094 Routine Description:
3095 Called while parsing a varstore statement. Add the variable store
3099 StructName - the name of the typedef'ed structure to use
3100 VarName - the NV variable name as specified in the varstore statement
3101 VarStoreId - the variable store ID as specified in the varstore statememt
3102 LineNum - the line number from the input (preprocessor output) file
3109 STRUCT_DEFINITION *StructDef;
3110 UINT16_LIST *L16Ptr;
3112 // Go through our list of previously-defined variable store IDs and
3113 // make sure this one is not a duplicate in name or key value.
3115 for (L16Ptr = mDefinedVarStoreId; L16Ptr != NULL; L16Ptr = L16Ptr->Next) {
3116 if (L16Ptr->Value == VarStoreId) {
3117 PrintErrorMessage (LineNum, "variable storage key already used", NULL);
3118 PrintErrorMessage (L16Ptr->LineNum, "previous usage of storage key", NULL);
3122 // Key value of 0 is invalid since that's assigned by default to the default
3123 // variable store (the first structure parsed).
3125 if (VarStoreId == 0) {
3126 PrintErrorMessage (LineNum, "variable storage key of 0 is invalid", NULL);
3129 // Create a new element to add to the list
3131 L16Ptr = (UINT16_LIST *)malloc(sizeof (UINT16_LIST));
3132 memset (L16Ptr, 0, sizeof (UINT16_LIST));
3133 L16Ptr->LineNum = LineNum;
3134 L16Ptr->Value = VarStoreId;
3135 if (mDefinedVarStoreId == NULL) {
3136 mDefinedVarStoreId = L16Ptr;
3138 mLastDefinedVarStoreId->Next = L16Ptr;
3140 mLastDefinedVarStoreId = L16Ptr;
3142 // Find the structure definition with this name
3144 for (StructDef = mFirstStructDefinition; StructDef != NULL; StructDef = StructDef->Next) {
3145 if (strcmp (StructDef->Name, StructName) == 0) {
3147 // Make sure they did not already define a variable storage ID
3148 // for this structure.
3150 if (StructDef->VarStoreId != 0) {
3151 PrintErrorMessage (LineNum, StructName, "variable storage already defined for this structure");
3152 PrintErrorMessage (StructDef->VarStoreLineNum, StructName, "previous definition for variable storage");
3154 StructDef->VarStoreId = VarStoreId;
3155 StructDef->VarStoreIdValid = 1;
3156 StructDef->VarStoreLineNum = LineNum;
3157 WriteWord (StructDef->Size);
3159 WriteByte(*VarName, 0);
3166 PrintErrorMessage (LineNum, StructName, "structure with this name not defined");
3169 EfiVfrParser::WriteDWord (
3175 Routine Description:
3176 During parsing, we came upon some code that requires a 32-bit value be
3177 written to the VFR binary file. Queue up the 4 bytes.
3180 Value - the 32-bit value to write
3181 KeyByte - a single character which gets written out beside the first byte.
3182 This is used to tag the data in the output file so that during
3183 debug you have an idea what the value is.
3191 // Write 4 bytes, little endian. Specify a key byte only on the first one
3193 mOpcodeHandler.AddByte ((UINT8)Value, KeyByte);
3195 mOpcodeHandler.AddByte ((UINT8)Value, 0);
3197 mOpcodeHandler.AddByte ((UINT8)Value, 0);
3199 mOpcodeHandler.AddByte ((UINT8)Value, 0);
3202 EfiVfrParser::WriteOpByte (
3208 Routine Description:
3210 During parsing, we came upon a new VFR opcode. At this point we flush
3211 the output queue and then queue up this byte (with 'O' for opcode tag).
3215 ByteValue - opcode value
3223 mOpcodeHandler.AddOpcodeByte (ByteValue, LineNum);
3226 EfiVfrParser::WriteByte (
3232 Routine Description:
3234 During parsing of the VFR we spoonfeed this function with bytes to write to
3235 the output VFR binary file. This function simply queues up the bytes, and
3236 the queue gets flushed each time a new VFR opcode is encountered.
3240 ByteValue - raw byte to write
3241 Key - character to tag the byte with when we write ByteValue to the
3250 mOpcodeHandler.AddByte (ByteValue, Key);
3253 EfiVfrParser::WriteWord (
3258 Routine Description:
3259 During VFR parsing we came upon a case where we need to write out a
3260 16-bit value. Queue it up.
3263 Value - value to write.
3270 mOpcodeHandler.AddByte ((UINT8)Value, 0);
3271 mOpcodeHandler.AddByte ((UINT8)((Value \>> 8) & 0xFF), 0);
3274 EfiVfrParser::WriteStringIdWord (
3278 mOpcodeHandler.AddByte ((UINT8)WordValue, 'S');
3279 mOpcodeHandler.AddByte ((UINT8)((WordValue \>> 8) & 0xFF), 0);
3282 EfiVfrParser::FreeGotoReferences ()
3285 Routine Description:
3286 Called during cleanup to free up the memory we allocated when
3287 keeping track of VFR goto statements.
3297 GOTO_REFERENCE *CurrRef;
3298 GOTO_REFERENCE *NextRef;
3299 FORM_ID_VALUE *CurrFormId;
3300 FORM_ID_VALUE *NextFormId;
3305 // Go through all the "goto" references and make sure there was a
3306 // form ID of that value defined.
3308 for (CurrRef = mGotoReferences; CurrRef != NULL; CurrRef = CurrRef->Next) {
3310 for (CurrFormId = mFormIdValues; CurrFormId != NULL; CurrFormId = CurrFormId->Next) {
3311 if (CurrRef->Value == CurrFormId->Value) {
3317 sprintf (Name, "%d", (UINT32)CurrRef->Value);
3318 PrintErrorMessage (CurrRef->RefLineNum, Name, "undefined form ID");
3322 // Now free up the form id and goto references
3324 CurrFormId = mFormIdValues;
3325 while (CurrFormId != NULL) {
3326 NextFormId = CurrFormId->Next;
3328 CurrFormId = NextFormId;
3330 mFormIdValues = NULL;
3331 CurrRef = mGotoReferences;
3332 while (CurrRef != NULL) {
3333 NextRef = CurrRef->Next;
3337 mGotoReferences = NULL;
3340 EfiVfrParser::AddGotoReference (
3346 Routine Description:
3347 During VFR parsing we came upon a goto statement. Since we support
3348 forward references, save the referenced label and at the end of parsing
3349 we'll check that the label was actually defined somewhere.
3352 GotoNumber - the label number referenced
3353 LineNum - the line number where the reference was made (used for
3361 GOTO_REFERENCE *NewRef;
3363 NewRef = (GOTO_REFERENCE *)malloc (sizeof (GOTO_REFERENCE));
3364 if (NewRef == NULL) {
3365 Error (UTILITY_NAME, 0, 0, NULL, "memory allocation failure");
3368 memset ((char *)NewRef, 0, sizeof (GOTO_REFERENCE));
3369 NewRef->Value = (UINT16)GotoNumber;
3370 NewRef->RefLineNum = LineNum;
3371 NewRef->Next = mGotoReferences;
3372 mGotoReferences = NewRef;
3375 EfiVfrParser::AddFormId (
3381 Routine Description:
3382 This function is called when we parse "form formid = 3" statements.
3383 We save the form ID valud so we can verify that duplicates are not
3384 defined. Also, these are the targets of goto statements, so when we're
3385 done parsing the script we also go through all the goto statements to
3386 check that there was a target FormId defined as referenced by each
3389 Note that formid = 0 is invalid.
3392 FormIdValue - the parsed value for the Form ID
3393 LineNum - line number of the source file we're parsing
3400 FORM_ID_VALUE *NewFormId;
3405 // Verify that FormId != 0
3407 if (FormIdValue == 0) {
3408 FileName = ConvertLineNumber (&LineNum);
3409 Error (FileName, LineNum, 0, "form ID cannot be 0", NULL);
3413 // First go through all previously defined form IDs and make sure they have not defined
3416 for (NewFormId = mFormIdValues; NewFormId != NULL; NewFormId = NewFormId->Next) {
3417 if ((UINT16)FormIdValue == NewFormId->Value) {
3418 FileName = ConvertLineNumber (&LineNum);
3419 LineNum2 = NewFormId->LineNum;
3420 FileName2 = ConvertLineNumber (&LineNum2);
3421 Error (FileName, LineNum, 0, NULL, "form ID %d already defined", FormIdValue);
3422 Error (FileName2, LineNum2, 0, NULL, "form ID %d previous definition", FormIdValue);
3427 // Allocate memory for a new one
3429 NewFormId = (FORM_ID_VALUE *)malloc (sizeof (FORM_ID_VALUE));
3430 if (NewFormId == NULL) {
3431 Error (UTILITY_NAME, 0, 0, NULL, "memory allocation failure");
3434 memset ((char *)NewFormId, 0, sizeof (FORM_ID_VALUE));
3435 NewFormId->LineNum = LineNum;
3436 NewFormId->Next = mFormIdValues;
3437 NewFormId->Value = (UINT16)FormIdValue;
3438 mFormIdValues = NewFormId;
3441 EfiVfrParser::GetNumber (
3449 if ((NumStr[0] == '0') && (NumStr[1] == 'x')) {
3450 AtoX (NumStr + 2, 4, &Value);
3452 Value = (UINT32)atoi (NumStr);
3457 if ((NumBytes < 4) && (Value & ((UINT32)0xFFFFFFFF << (NumBytes * 8)))) {
3458 PrintErrorMessage (LineNum, NumStr, "value out of range");
3466 } // end grammar class