1 /** @file 2 3 VfrCompiler main class and main function. 4 5 Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR> 6 This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 **/ 15 16 #include "stdio.h" 17 #include "stdlib.h" 18 #include "string.h" 19 #include "VfrCompiler.h" 20 #include "CommonLib.h" 21 #include "EfiUtilityMsgs.h" 22 23 PACKAGE_DATA gCBuffer; 24 PACKAGE_DATA gRBuffer; 25 CVfrStringDB gCVfrStringDB; 26 27 VOID 28 CVfrCompiler::DebugError ( 29 IN CHAR8 *FileName, 30 IN UINT32 LineNumber, 31 IN UINT32 MessageCode, 32 IN CONST CHAR8 *Text, 33 IN CONST CHAR8 *MsgFmt, 34 ... 35 ) 36 { 37 va_list List; 38 va_start (List, MsgFmt); 39 PrintMessage ((CHAR8 *) "ERROR", FileName, LineNumber, MessageCode, (CHAR8 *) Text, (CHAR8 *) MsgFmt, List); 40 va_end (List); 41 } 42 43 VOID 44 CVfrCompiler::SET_RUN_STATUS ( 45 IN COMPILER_RUN_STATUS Status 46 ) 47 { 48 mRunStatus = Status; 49 } 50 51 BOOLEAN 52 CVfrCompiler::IS_RUN_STATUS ( 53 IN COMPILER_RUN_STATUS Status 54 ) 55 { 56 return mRunStatus == Status; 57 } 58 59 VOID 60 CVfrCompiler::OptionInitialization ( 61 IN INT32 Argc, 62 IN CHAR8 **Argv 63 ) 64 { 65 INT32 Index; 66 EFI_STATUS Status; 67 68 Status = EFI_SUCCESS; 69 SetUtilityName ((CHAR8*) PROGRAM_NAME); 70 71 mOptions.VfrFileName = NULL; 72 mOptions.RecordListFile = NULL; 73 mOptions.CreateRecordListFile = FALSE; 74 mOptions.CreateIfrPkgFile = FALSE; 75 mOptions.PkgOutputFileName = NULL; 76 mOptions.COutputFileName = NULL; 77 mOptions.OutputDirectory = NULL; 78 mOptions.PreprocessorOutputFileName = NULL; 79 mOptions.VfrBaseFileName = NULL; 80 mOptions.IncludePaths = NULL; 81 mOptions.SkipCPreprocessor = TRUE; 82 mOptions.CPreprocessorOptions = NULL; 83 mOptions.CompatibleMode = FALSE; 84 mOptions.HasOverrideClassGuid = FALSE; 85 mOptions.WarningAsError = FALSE; 86 mOptions.AutoDefault = FALSE; 87 mOptions.CheckDefault = FALSE; 88 memset (&mOptions.OverrideClassGuid, 0, sizeof (EFI_GUID)); 89 90 if (Argc == 1) { 91 Usage (); 92 SET_RUN_STATUS (STATUS_DEAD); 93 return; 94 } 95 96 for (Index = 1; (Index < Argc) && (Argv[Index][0] == '-'); Index++) { 97 if ((stricmp(Argv[Index], "-h") == 0) || (stricmp(Argv[Index], "--help") == 0)) { 98 Usage (); 99 SET_RUN_STATUS (STATUS_DEAD); 100 return; 101 } else if (stricmp(Argv[Index], "--version") == 0) { 102 Version (); 103 SET_RUN_STATUS (STATUS_DEAD); 104 return; 105 } else if (stricmp(Argv[Index], "-l") == 0) { 106 mOptions.CreateRecordListFile = TRUE; 107 gCIfrRecordInfoDB.TurnOn (); 108 } else if (stricmp(Argv[Index], "-i") == 0) { 109 Index++; 110 if ((Index >= Argc) || (Argv[Index][0] == '-')) { 111 DebugError (NULL, 0, 1001, "Missing option", "-i missing path argument"); 112 goto Fail; 113 } 114 115 AppendIncludePath(Argv[Index]); 116 } else if (stricmp(Argv[Index], "-o") == 0 || stricmp(Argv[Index], "--output-directory") == 0 || stricmp(Argv[Index], "-od") == 0) { 117 Index++; 118 if ((Index >= Argc) || (Argv[Index][0] == '-')) { 119 DebugError (NULL, 0, 1001, "Missing option", "-o missing output directory name"); 120 goto Fail; 121 } 122 if (strlen (Argv[Index]) > MAX_PATH - 1) { 123 DebugError (NULL, 0, 1003, "Invalid option value", "Output directory name %s is too long", Argv[Index]); 124 goto Fail; 125 } 126 127 mOptions.OutputDirectory = (CHAR8 *) malloc (strlen (Argv[Index]) + strlen ("\\") + 1); 128 if (mOptions.OutputDirectory == NULL) { 129 DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL); 130 goto Fail; 131 } 132 strcpy (mOptions.OutputDirectory, Argv[Index]); 133 134 CHAR8 lastChar = mOptions.OutputDirectory[strlen(mOptions.OutputDirectory) - 1]; 135 if ((lastChar != '/') && (lastChar != '\\')) { 136 if (strchr(mOptions.OutputDirectory, '/') != NULL) { 137 strcat (mOptions.OutputDirectory, "/"); 138 } else { 139 strcat (mOptions.OutputDirectory, "\\"); 140 } 141 } 142 DebugMsg (NULL, 0, 9, (CHAR8 *) "Output Directory", (CHAR8 *) "%s", mOptions.OutputDirectory); 143 } else if (stricmp(Argv[Index], "-b") == 0 || stricmp(Argv[Index], "--create-ifr-package") == 0 || stricmp(Argv[Index], "-ibin") == 0) { 144 mOptions.CreateIfrPkgFile = TRUE; 145 } else if (stricmp(Argv[Index], "-n") == 0 || stricmp(Argv[Index], "--no-pre-processing") == 0 || stricmp(Argv[Index], "-nopp") == 0) { 146 mOptions.SkipCPreprocessor = TRUE; 147 } else if (stricmp(Argv[Index], "-f") == 0 || stricmp(Argv[Index], "--pre-processing-flag") == 0 || stricmp(Argv[Index], "-ppflag") == 0) { 148 Index++; 149 if ((Index >= Argc) || (Argv[Index][0] == '-')) { 150 DebugError (NULL, 0, 1001, "Missing option", "-od - missing C-preprocessor argument"); 151 goto Fail; 152 } 153 154 AppendCPreprocessorOptions (Argv[Index]); 155 } else if (stricmp(Argv[Index], "-c") == 0 || stricmp(Argv[Index], "--compatible-framework") == 0) { 156 mOptions.CompatibleMode = TRUE; 157 } else if (stricmp(Argv[Index], "-s") == 0|| stricmp(Argv[Index], "--string-db") == 0) { 158 Index++; 159 if ((Index >= Argc) || (Argv[Index][0] == '-')) { 160 DebugError (NULL, 0, 1001, "Missing option", "-s missing input string file name"); 161 goto Fail; 162 } 163 gCVfrStringDB.SetStringFileName(Argv[Index]); 164 DebugMsg (NULL, 0, 9, (CHAR8 *) "Input string file path", (CHAR8 *) "%s", Argv[Index]); 165 } else if ((stricmp (Argv[Index], "-g") == 0) || (stricmp (Argv[Index], "--guid") == 0)) { 166 Index++; 167 Status = StringToGuid (Argv[Index], &mOptions.OverrideClassGuid); 168 if (EFI_ERROR (Status)) { 169 DebugError (NULL, 0, 1000, "Invalid format:", "%s", Argv[Index]); 170 goto Fail; 171 } 172 mOptions.HasOverrideClassGuid = TRUE; 173 } else if (stricmp(Argv[Index], "-w") == 0 || stricmp(Argv[Index], "--warning-as-error") == 0) { 174 mOptions.WarningAsError = TRUE; 175 } else if (stricmp(Argv[Index], "-a") == 0 ||stricmp(Argv[Index], "--autodefault") == 0) { 176 mOptions.AutoDefault = TRUE; 177 } else if (stricmp(Argv[Index], "-d") == 0 ||stricmp(Argv[Index], "--checkdefault") == 0) { 178 mOptions.CheckDefault = TRUE; 179 } else { 180 DebugError (NULL, 0, 1000, "Unknown option", "unrecognized option %s", Argv[Index]); 181 goto Fail; 182 } 183 } 184 185 if (Index != Argc - 1) { 186 DebugError (NULL, 0, 1001, "Missing option", "VFR file name is not specified."); 187 goto Fail; 188 } else { 189 if (strlen (Argv[Index]) > MAX_PATH) { 190 DebugError (NULL, 0, 1003, "Invalid option value", "VFR file name %s is too long.", Argv[Index]); 191 goto Fail; 192 } 193 mOptions.VfrFileName = (CHAR8 *) malloc (strlen (Argv[Index]) + 1); 194 if (mOptions.VfrFileName == NULL) { 195 DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL); 196 goto Fail; 197 } 198 strcpy (mOptions.VfrFileName, Argv[Index]); 199 200 if (mOptions.OutputDirectory == NULL) { 201 mOptions.OutputDirectory = (CHAR8 *) malloc (1); 202 if (mOptions.OutputDirectory == NULL) { 203 DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL); 204 goto Fail; 205 } 206 mOptions.OutputDirectory[0] = '\0'; 207 } 208 } 209 210 if (SetBaseFileName() != 0) { 211 goto Fail; 212 } 213 if (SetPkgOutputFileName () != 0) { 214 goto Fail; 215 } 216 if (SetCOutputFileName() != 0) { 217 goto Fail; 218 } 219 if (SetPreprocessorOutputFileName () != 0) { 220 goto Fail; 221 } 222 if (SetRecordListFileName () != 0) { 223 goto Fail; 224 } 225 return; 226 227 Fail: 228 SET_RUN_STATUS (STATUS_DEAD); 229 230 mOptions.CreateRecordListFile = FALSE; 231 mOptions.CreateIfrPkgFile = FALSE; 232 233 if (mOptions.VfrFileName != NULL) { 234 free (mOptions.VfrFileName); 235 mOptions.VfrFileName = NULL; 236 } 237 if (mOptions.VfrBaseFileName != NULL) { 238 free (mOptions.VfrBaseFileName); 239 mOptions.VfrBaseFileName = NULL; 240 } 241 if (mOptions.OutputDirectory != NULL) { 242 free (mOptions.OutputDirectory); 243 mOptions.OutputDirectory = NULL; 244 } 245 if (mOptions.PkgOutputFileName != NULL) { 246 free (mOptions.PkgOutputFileName); 247 mOptions.PkgOutputFileName = NULL; 248 } 249 if (mOptions.COutputFileName != NULL) { 250 free (mOptions.COutputFileName); 251 mOptions.COutputFileName = NULL; 252 } 253 if (mOptions.PreprocessorOutputFileName != NULL) { 254 free (mOptions.PreprocessorOutputFileName); 255 mOptions.PreprocessorOutputFileName = NULL; 256 } 257 if (mOptions.RecordListFile != NULL) { 258 free (mOptions.RecordListFile); 259 mOptions.RecordListFile = NULL; 260 } 261 if (mOptions.IncludePaths != NULL) { 262 delete mOptions.IncludePaths; 263 mOptions.IncludePaths = NULL; 264 } 265 if (mOptions.CPreprocessorOptions != NULL) { 266 delete mOptions.CPreprocessorOptions; 267 mOptions.CPreprocessorOptions = NULL; 268 } 269 } 270 271 VOID 272 CVfrCompiler::AppendIncludePath ( 273 IN CHAR8 *PathStr 274 ) 275 { 276 UINT32 Len = 0; 277 CHAR8 *IncludePaths = NULL; 278 279 Len = strlen (" -I ") + strlen (PathStr) + 1; 280 if (mOptions.IncludePaths != NULL) { 281 Len += strlen (mOptions.IncludePaths); 282 } 283 IncludePaths = new CHAR8[Len]; 284 if (IncludePaths == NULL) { 285 DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL); 286 return; 287 } 288 IncludePaths[0] = '\0'; 289 if (mOptions.IncludePaths != NULL) { 290 strcat (IncludePaths, mOptions.IncludePaths); 291 } 292 strcat (IncludePaths, " -I "); 293 strcat (IncludePaths, PathStr); 294 if (mOptions.IncludePaths != NULL) { 295 delete mOptions.IncludePaths; 296 } 297 mOptions.IncludePaths = IncludePaths; 298 } 299 300 VOID 301 CVfrCompiler::AppendCPreprocessorOptions ( 302 IN CHAR8 *Options 303 ) 304 { 305 UINT32 Len = 0; 306 CHAR8 *Opt = NULL; 307 308 Len = strlen (Options) + strlen (" ") + 1; 309 if (mOptions.CPreprocessorOptions != NULL) { 310 Len += strlen (mOptions.CPreprocessorOptions); 311 } 312 Opt = new CHAR8[Len]; 313 if (Opt == NULL) { 314 DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL); 315 return; 316 } 317 Opt[0] = 0; 318 if (mOptions.CPreprocessorOptions != NULL) { 319 strcat (Opt, mOptions.CPreprocessorOptions); 320 } 321 strcat (Opt, " "); 322 strcat (Opt, Options); 323 if (mOptions.CPreprocessorOptions != NULL) { 324 delete mOptions.CPreprocessorOptions; 325 } 326 mOptions.CPreprocessorOptions = Opt; 327 } 328 329 INT8 330 CVfrCompiler::SetBaseFileName ( 331 VOID 332 ) 333 { 334 CHAR8 *pFileName, *pPath, *pExt; 335 336 if (mOptions.VfrFileName == NULL) { 337 return -1; 338 } 339 340 pFileName = mOptions.VfrFileName; 341 while ( 342 ((pPath = strchr (pFileName, '\\')) != NULL) || 343 ((pPath = strchr (pFileName, '/')) != NULL) 344 ) 345 { 346 pFileName = pPath + 1; 347 } 348 349 if (pFileName == NULL) { 350 return -1; 351 } 352 353 if ((pExt = strchr (pFileName, '.')) == NULL) { 354 return -1; 355 } 356 357 *pExt = '\0'; 358 if (strlen (pFileName) > MAX_PATH - 1) { 359 *pExt = '.'; 360 return -1; 361 } 362 363 mOptions.VfrBaseFileName = (CHAR8 *) malloc (strlen (pFileName) + 1); 364 if (mOptions.VfrBaseFileName == NULL) { 365 *pExt = '.'; 366 return -1; 367 } 368 369 strcpy (mOptions.VfrBaseFileName, pFileName); 370 *pExt = '.'; 371 372 return 0; 373 } 374 375 INT8 376 CVfrCompiler::SetPkgOutputFileName ( 377 VOID 378 ) 379 { 380 INTN Length; 381 382 if (mOptions.VfrBaseFileName == NULL) { 383 return -1; 384 } 385 386 Length = strlen (mOptions.OutputDirectory) + 387 strlen (mOptions.VfrBaseFileName) + 388 strlen (VFR_PACKAGE_FILENAME_EXTENSION) + 389 1; 390 if (Length > MAX_PATH) { 391 return -1; 392 } 393 394 mOptions.PkgOutputFileName = (CHAR8 *) malloc (Length); 395 if (mOptions.PkgOutputFileName == NULL) { 396 return -1; 397 } 398 399 strcpy (mOptions.PkgOutputFileName, mOptions.OutputDirectory); 400 strcat (mOptions.PkgOutputFileName, mOptions.VfrBaseFileName); 401 strcat (mOptions.PkgOutputFileName, VFR_PACKAGE_FILENAME_EXTENSION); 402 403 return 0; 404 } 405 406 INT8 407 CVfrCompiler::SetCOutputFileName ( 408 VOID 409 ) 410 { 411 INTN Length; 412 413 if (mOptions.VfrBaseFileName == NULL) { 414 return -1; 415 } 416 417 Length = strlen (mOptions.OutputDirectory) + 418 strlen (mOptions.VfrBaseFileName) + 419 strlen (".c") + 420 1; 421 if (Length > MAX_PATH) { 422 return -1; 423 } 424 425 mOptions.COutputFileName = (CHAR8 *) malloc (Length); 426 if (mOptions.COutputFileName == NULL) { 427 return -1; 428 } 429 430 strcpy (mOptions.COutputFileName, mOptions.OutputDirectory); 431 strcat (mOptions.COutputFileName, mOptions.VfrBaseFileName); 432 strcat (mOptions.COutputFileName, ".c"); 433 434 return 0; 435 } 436 437 INT8 438 CVfrCompiler::SetPreprocessorOutputFileName ( 439 VOID 440 ) 441 { 442 INTN Length; 443 444 if (mOptions.VfrBaseFileName == NULL) { 445 return -1; 446 } 447 448 Length = strlen (mOptions.OutputDirectory) + 449 strlen (mOptions.VfrBaseFileName) + 450 strlen (VFR_PREPROCESS_FILENAME_EXTENSION) + 451 1; 452 if (Length > MAX_PATH) { 453 return -1; 454 } 455 456 mOptions.PreprocessorOutputFileName = (CHAR8 *) malloc (Length); 457 if (mOptions.PreprocessorOutputFileName == NULL) { 458 return -1; 459 } 460 461 strcpy (mOptions.PreprocessorOutputFileName, mOptions.OutputDirectory); 462 strcat (mOptions.PreprocessorOutputFileName, mOptions.VfrBaseFileName); 463 strcat (mOptions.PreprocessorOutputFileName, VFR_PREPROCESS_FILENAME_EXTENSION); 464 465 return 0; 466 } 467 468 INT8 469 CVfrCompiler::SetRecordListFileName ( 470 VOID 471 ) 472 { 473 INTN Length; 474 475 if (mOptions.VfrBaseFileName == NULL) { 476 return -1; 477 } 478 479 Length = strlen (mOptions.OutputDirectory) + 480 strlen (mOptions.VfrBaseFileName) + 481 strlen (VFR_RECORDLIST_FILENAME_EXTENSION) + 482 1; 483 if (Length > MAX_PATH) { 484 return -1; 485 } 486 487 mOptions.RecordListFile = (CHAR8 *) malloc (Length); 488 if (mOptions.RecordListFile == NULL) { 489 return -1; 490 } 491 492 strcpy (mOptions.RecordListFile, mOptions.OutputDirectory); 493 strcat (mOptions.RecordListFile, mOptions.VfrBaseFileName); 494 strcat (mOptions.RecordListFile, VFR_RECORDLIST_FILENAME_EXTENSION); 495 496 return 0; 497 } 498 499 CVfrCompiler::CVfrCompiler ( 500 IN INT32 Argc, 501 IN CHAR8 **Argv 502 ) 503 { 504 mPreProcessCmd = (CHAR8 *) PREPROCESSOR_COMMAND; 505 mPreProcessOpt = (CHAR8 *) PREPROCESSOR_OPTIONS; 506 507 SET_RUN_STATUS (STATUS_STARTED); 508 509 OptionInitialization(Argc, Argv); 510 511 if ((IS_RUN_STATUS(STATUS_FAILED)) || (IS_RUN_STATUS(STATUS_DEAD))) { 512 return; 513 } 514 515 SET_RUN_STATUS(STATUS_INITIALIZED); 516 } 517 518 CVfrCompiler::~CVfrCompiler ( 519 VOID 520 ) 521 { 522 if (mOptions.VfrFileName != NULL) { 523 free (mOptions.VfrFileName); 524 mOptions.VfrFileName = NULL; 525 } 526 527 if (mOptions.VfrBaseFileName != NULL) { 528 free (mOptions.VfrBaseFileName); 529 mOptions.VfrBaseFileName = NULL; 530 } 531 532 if (mOptions.OutputDirectory != NULL) { 533 free (mOptions.OutputDirectory); 534 mOptions.OutputDirectory = NULL; 535 } 536 537 if (mOptions.PkgOutputFileName != NULL) { 538 free (mOptions.PkgOutputFileName); 539 mOptions.PkgOutputFileName = NULL; 540 } 541 542 if (mOptions.COutputFileName != NULL) { 543 free (mOptions.COutputFileName); 544 mOptions.COutputFileName = NULL; 545 } 546 547 if (mOptions.PreprocessorOutputFileName != NULL) { 548 free (mOptions.PreprocessorOutputFileName); 549 mOptions.PreprocessorOutputFileName = NULL; 550 } 551 552 if (mOptions.RecordListFile != NULL) { 553 free (mOptions.RecordListFile); 554 mOptions.RecordListFile = NULL; 555 } 556 557 if (mOptions.IncludePaths != NULL) { 558 delete mOptions.IncludePaths; 559 mOptions.IncludePaths = NULL; 560 } 561 562 if (mOptions.CPreprocessorOptions != NULL) { 563 delete mOptions.CPreprocessorOptions; 564 mOptions.CPreprocessorOptions = NULL; 565 } 566 567 SET_RUN_STATUS(STATUS_DEAD); 568 } 569 570 VOID 571 CVfrCompiler::Usage ( 572 VOID 573 ) 574 { 575 UINT32 Index; 576 CONST CHAR8 *Help[] = { 577 " ", 578 "VfrCompile version " VFR_COMPILER_VERSION "Build " __BUILD_VERSION, 579 "Copyright (c) 2004-2016 Intel Corporation. All rights reserved.", 580 " ", 581 "Usage: VfrCompile [options] VfrFile", 582 " ", 583 "Options:", 584 " -h, --help prints this help", 585 " --version prints version info", 586 " -l create an output IFR listing file", 587 " -o DIR, --output-directory DIR", 588 " deposit all output files to directory OutputDir", 589 " default is current directory", 590 " -b, --create-ifr-package", 591 " create an IFR HII pack file", 592 " -n, --no-pre-processing", 593 " do not preprocessing input file", 594 " -c, --compatible-framework", 595 " compatible framework vfr file", 596 " -s, --string-db", 597 " input uni string package file", 598 " -g, --guid", 599 " override class guid input", 600 " format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", 601 " -w --warning-as-error", 602 " treat warning as an error", 603 " -a --autodefaut generate default value for question opcode if some default is missing", 604 " -d --checkdefault check the default information in a question opcode", 605 NULL 606 }; 607 for (Index = 0; Help[Index] != NULL; Index++) { 608 fprintf (stdout, "%s\n", Help[Index]); 609 } 610 } 611 612 VOID 613 CVfrCompiler::Version ( 614 VOID 615 ) 616 { 617 UINT32 Index; 618 CONST CHAR8 *Help[] = { 619 "VfrCompile version " VFR_COMPILER_VERSION "Build " __BUILD_VERSION, 620 NULL 621 }; 622 for (Index = 0; Help[Index] != NULL; Index++) { 623 fprintf (stdout, "%s\n", Help[Index]); 624 } 625 } 626 627 VOID 628 CVfrCompiler::PreProcess ( 629 VOID 630 ) 631 { 632 FILE *pVfrFile = NULL; 633 UINT32 CmdLen = 0; 634 CHAR8 *PreProcessCmd = NULL; 635 636 if (!IS_RUN_STATUS(STATUS_INITIALIZED)) { 637 goto Fail; 638 } 639 640 if (mOptions.SkipCPreprocessor == TRUE) { 641 goto Out; 642 } 643 644 if ((pVfrFile = fopen (LongFilePath (mOptions.VfrFileName), "r")) == NULL) { 645 DebugError (NULL, 0, 0001, "Error opening the input VFR file", mOptions.VfrFileName); 646 goto Fail; 647 } 648 fclose (pVfrFile); 649 650 CmdLen = strlen (mPreProcessCmd) + strlen (mPreProcessOpt) + 651 strlen (mOptions.VfrFileName) + strlen (mOptions.PreprocessorOutputFileName); 652 if (mOptions.CPreprocessorOptions != NULL) { 653 CmdLen += strlen (mOptions.CPreprocessorOptions); 654 } 655 if (mOptions.IncludePaths != NULL) { 656 CmdLen += strlen (mOptions.IncludePaths); 657 } 658 659 PreProcessCmd = new CHAR8[CmdLen + 10]; 660 if (PreProcessCmd == NULL) { 661 DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL); 662 goto Fail; 663 } 664 strcpy (PreProcessCmd, mPreProcessCmd), strcat (PreProcessCmd, " "); 665 strcat (PreProcessCmd, mPreProcessOpt), strcat (PreProcessCmd, " "); 666 if (mOptions.IncludePaths != NULL) { 667 strcat (PreProcessCmd, mOptions.IncludePaths), strcat (PreProcessCmd, " "); 668 } 669 if (mOptions.CPreprocessorOptions != NULL) { 670 strcat (PreProcessCmd, mOptions.CPreprocessorOptions), strcat (PreProcessCmd, " "); 671 } 672 strcat (PreProcessCmd, mOptions.VfrFileName), strcat (PreProcessCmd, " > "); 673 strcat (PreProcessCmd, mOptions.PreprocessorOutputFileName); 674 675 if (system (PreProcessCmd) != 0) { 676 DebugError (NULL, 0, 0003, "Error parsing file", "failed to spawn C preprocessor on VFR file %s\n", PreProcessCmd); 677 goto Fail; 678 } 679 680 delete[] PreProcessCmd; 681 682 Out: 683 SET_RUN_STATUS (STATUS_PREPROCESSED); 684 return; 685 686 Fail: 687 if (!IS_RUN_STATUS(STATUS_DEAD)) { 688 SET_RUN_STATUS (STATUS_FAILED); 689 } 690 delete[] PreProcessCmd; 691 } 692 693 extern UINT8 VfrParserStart (IN FILE *, IN INPUT_INFO_TO_SYNTAX *); 694 695 VOID 696 CVfrCompiler::Compile ( 697 VOID 698 ) 699 { 700 FILE *pInFile = NULL; 701 CHAR8 *InFileName = NULL; 702 INPUT_INFO_TO_SYNTAX InputInfo; 703 704 if (!IS_RUN_STATUS(STATUS_PREPROCESSED)) { 705 goto Fail; 706 } 707 708 InFileName = (mOptions.SkipCPreprocessor == TRUE) ? mOptions.VfrFileName : mOptions.PreprocessorOutputFileName; 709 710 gCVfrErrorHandle.SetInputFile (InFileName); 711 gCVfrErrorHandle.SetWarningAsError(mOptions.WarningAsError); 712 713 if ((pInFile = fopen (LongFilePath (InFileName), "r")) == NULL) { 714 DebugError (NULL, 0, 0001, "Error opening the input file", InFileName); 715 goto Fail; 716 } 717 718 InputInfo.CompatibleMode = mOptions.CompatibleMode; 719 if (mOptions.HasOverrideClassGuid) { 720 InputInfo.OverrideClassGuid = &mOptions.OverrideClassGuid; 721 } else { 722 InputInfo.OverrideClassGuid = NULL; 723 } 724 725 if (VfrParserStart (pInFile, &InputInfo) != 0) { 726 goto Fail; 727 } 728 729 fclose (pInFile); 730 731 if (gCFormPkg.HavePendingUnassigned () == TRUE) { 732 gCFormPkg.PendingAssignPrintAll (); 733 goto Fail; 734 } 735 736 SET_RUN_STATUS (STATUS_COMPILEED); 737 return; 738 739 Fail: 740 if (!IS_RUN_STATUS(STATUS_DEAD)) { 741 DebugError (NULL, 0, 0003, "Error parsing", "compile error in file %s", InFileName); 742 SET_RUN_STATUS (STATUS_FAILED); 743 } 744 if (pInFile != NULL) { 745 fclose (pInFile); 746 } 747 } 748 749 VOID 750 CVfrCompiler::AdjustBin ( 751 VOID 752 ) 753 { 754 EFI_VFR_RETURN_CODE Status; 755 756 if (!IS_RUN_STATUS(STATUS_COMPILEED)) { 757 return; 758 } 759 760 if (gNeedAdjustOpcode) { 761 // 762 // When parsing the Vfr, has created some opcodes, now need to update the record info. 763 // 764 gCIfrRecordInfoDB.IfrUpdateRecordInfoForDynamicOpcode (FALSE); 765 } 766 767 // 768 // Check whether need to check default info for question or auto add default for question. 769 // 770 if (mOptions.AutoDefault || mOptions.CheckDefault) { 771 gCIfrRecordInfoDB.IfrCheckAddDefaultRecord (mOptions.AutoDefault, mOptions.CheckDefault); 772 } 773 774 // 775 // Check Binary Code consistent between Form and IfrRecord 776 // 777 778 // 779 // Get Package Data and IfrRecord Data 780 // 781 gCFormPkg.BuildPkg (gCBuffer); 782 gCIfrRecordInfoDB.IfrRecordOutput (gRBuffer); 783 784 // 785 // Compare Form and Record data 786 // 787 if (gCBuffer.Buffer != NULL && gRBuffer.Buffer != NULL) { 788 UINT32 Index; 789 if (gCBuffer.Size != gRBuffer.Size) { 790 DebugError (NULL, 0, 0001, "Error parsing vfr file", " %s. FormBinary Size 0x%X is not same to RecordBuffer Size 0x%X", mOptions.VfrFileName, gCBuffer.Size, gRBuffer.Size); 791 } 792 for (Index = 0; Index < gCBuffer.Size; Index ++) { 793 if (gCBuffer.Buffer[Index] != gRBuffer.Buffer[Index]) { 794 break; 795 } 796 } 797 if (Index != gCBuffer.Size) { 798 DebugError (NULL, 0, 0001, "Error parsing vfr file", " %s. the 0x%X byte is different between Form and Record", mOptions.VfrFileName, Index); 799 } 800 DebugMsg (NULL, 0, 9, (CHAR8 *) "IFR Buffer", (CHAR8 *) "Form Buffer same to Record Buffer and Size is 0x%X", Index); 801 } else if (gCBuffer.Buffer == NULL && gRBuffer.Buffer == NULL) { 802 //ok 803 } else { 804 DebugError (NULL, 0, 0001, "Error parsing vfr file", " %s.Buffer not allocated.", mOptions.VfrFileName); 805 } 806 807 // 808 // For UEFI mode, not do OpCode Adjust 809 // 810 if (mOptions.CompatibleMode) { 811 // 812 // Adjust Opcode to be compatible with framework vfr 813 // 814 Status = gCIfrRecordInfoDB.IfrRecordAdjust (); 815 if (Status != VFR_RETURN_SUCCESS) { 816 // 817 // Record List Adjust Failed 818 // 819 SET_RUN_STATUS (STATUS_FAILED); 820 return; 821 } 822 // 823 // Re get the IfrRecord Buffer. 824 // 825 gCIfrRecordInfoDB.IfrRecordOutput (gRBuffer); 826 } 827 828 return; 829 } 830 831 VOID 832 CVfrCompiler::GenBinary ( 833 VOID 834 ) 835 { 836 FILE *pFile = NULL; 837 838 if (!IS_RUN_STATUS(STATUS_COMPILEED)) { 839 goto Fail; 840 } 841 842 if (mOptions.CreateIfrPkgFile == TRUE) { 843 if ((pFile = fopen (LongFilePath (mOptions.PkgOutputFileName), "wb")) == NULL) { 844 DebugError (NULL, 0, 0001, "Error opening file", mOptions.PkgOutputFileName); 845 goto Fail; 846 } 847 if (gCFormPkg.BuildPkg (pFile, &gRBuffer) != VFR_RETURN_SUCCESS) { 848 fclose (pFile); 849 goto Fail; 850 } 851 fclose (pFile); 852 } 853 854 SET_RUN_STATUS (STATUS_GENBINARY); 855 856 return; 857 858 Fail: 859 if (!IS_RUN_STATUS(STATUS_DEAD)) { 860 SET_RUN_STATUS (STATUS_FAILED); 861 } 862 } 863 864 static const char *gSourceFileHeader[] = { 865 "//", 866 "// DO NOT EDIT -- auto-generated file", 867 "//", 868 "// This file is generated by the vfrcompiler utility", 869 "//", 870 NULL 871 }; 872 873 VOID 874 CVfrCompiler::GenCFile ( 875 VOID 876 ) 877 { 878 FILE *pFile; 879 UINT32 Index; 880 881 if (!IS_RUN_STATUS(STATUS_GENBINARY)) { 882 goto Fail; 883 } 884 885 if (!mOptions.CreateIfrPkgFile || mOptions.CompatibleMode) { 886 if ((pFile = fopen (LongFilePath (mOptions.COutputFileName), "w")) == NULL) { 887 DebugError (NULL, 0, 0001, "Error opening output C file", mOptions.COutputFileName); 888 goto Fail; 889 } 890 891 for (Index = 0; gSourceFileHeader[Index] != NULL; Index++) { 892 fprintf (pFile, "%s\n", gSourceFileHeader[Index]); 893 } 894 895 if (mOptions.CompatibleMode) { 896 gCVfrBufferConfig.OutputCFile (pFile, mOptions.VfrBaseFileName); 897 } 898 899 if (gCFormPkg.GenCFile (mOptions.VfrBaseFileName, pFile, &gRBuffer) != VFR_RETURN_SUCCESS) { 900 fclose (pFile); 901 goto Fail; 902 } 903 fclose (pFile); 904 } 905 906 SET_RUN_STATUS (STATUS_FINISHED); 907 return; 908 909 Fail: 910 if (!IS_RUN_STATUS(STATUS_DEAD)) { 911 SET_RUN_STATUS (STATUS_FAILED); 912 } 913 } 914 915 VOID 916 CVfrCompiler::GenRecordListFile ( 917 VOID 918 ) 919 { 920 CHAR8 *InFileName = NULL; 921 FILE *pInFile = NULL; 922 FILE *pOutFile = NULL; 923 CHAR8 LineBuf[MAX_VFR_LINE_LEN]; 924 UINT32 LineNo; 925 926 InFileName = (mOptions.SkipCPreprocessor == TRUE) ? mOptions.VfrFileName : mOptions.PreprocessorOutputFileName; 927 928 if (mOptions.CreateRecordListFile == TRUE) { 929 if ((InFileName[0] == '\0') || (mOptions.RecordListFile[0] == '\0')) { 930 return; 931 } 932 933 if ((pInFile = fopen (LongFilePath (InFileName), "r")) == NULL) { 934 DebugError (NULL, 0, 0001, "Error opening the input VFR preprocessor output file", InFileName); 935 return; 936 } 937 938 if ((pOutFile = fopen (LongFilePath (mOptions.RecordListFile), "w")) == NULL) { 939 DebugError (NULL, 0, 0001, "Error opening the record list file", mOptions.RecordListFile); 940 goto Err1; 941 } 942 943 fprintf (pOutFile, "//\n// VFR compiler version " VFR_COMPILER_VERSION __BUILD_VERSION "\n//\n"); 944 LineNo = 0; 945 while (!feof (pInFile)) { 946 if (fgets (LineBuf, MAX_VFR_LINE_LEN, pInFile) != NULL) { 947 fprintf (pOutFile, "%s", LineBuf); 948 LineNo++; 949 gCIfrRecordInfoDB.IfrRecordOutput (pOutFile, LineNo); 950 } 951 } 952 953 fprintf (pOutFile, "\n//\n// All Opcode Record List \n//\n"); 954 gCIfrRecordInfoDB.IfrRecordOutput (pOutFile, 0); 955 gCVfrVarDataTypeDB.Dump(pOutFile); 956 957 fclose (pOutFile); 958 fclose (pInFile); 959 } 960 961 return; 962 963 Err1: 964 fclose (pInFile); 965 } 966 967 int 968 main ( 969 IN int Argc, 970 IN char **Argv 971 ) 972 { 973 COMPILER_RUN_STATUS Status; 974 975 SetPrintLevel(WARNING_LOG_LEVEL); 976 CVfrCompiler Compiler(Argc, Argv); 977 978 Compiler.PreProcess(); 979 Compiler.Compile(); 980 Compiler.AdjustBin(); 981 Compiler.GenBinary(); 982 Compiler.GenCFile(); 983 Compiler.GenRecordListFile (); 984 985 Status = Compiler.RunStatus (); 986 if ((Status == STATUS_DEAD) || (Status == STATUS_FAILED)) { 987 return 2; 988 } 989 990 if (gCBuffer.Buffer != NULL) { 991 delete gCBuffer.Buffer; 992 } 993 994 if (gRBuffer.Buffer != NULL) { 995 delete gRBuffer.Buffer; 996 } 997 998 return GetUtilityStatus (); 999 } 1000 1001 1002