1 /*++ 2 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 8 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. 11 12 Module Name: 13 14 GenDepex.c 15 16 Abstract: 17 18 Generate Dependency Expression ("GenDepex") 19 20 Infix to Postfix Algorithm 21 22 This code has been scrubbed to be free of having any EFI core tree dependencies. 23 It should build in any environment that supports a standard C-library w/ string 24 operations and File I/O services. 25 26 As an example of usage, consider the following: 27 28 The input user file could be something like "Sample.DXS" whose contents are 29 30 #include "Tiano.h" 31 32 DEPENDENCY_START 33 NOT (DISK_IO_PROTOCOL AND SIMPLE_FILE_SYSTEM_PROTOCOL) 34 OR EFI_PXE_BASE_CODE_PROTOCOL 35 DEPENDENCY_END 36 37 This file is then washed through the C-preprocessor, viz., 38 39 cl /EP Sample.DXS > Sample.TMP1 40 41 This yields the following file "Sample.TMP1" whose contents are 42 43 DEPENDENCY_START 44 NOT ({ 0xce345171, 0xba0b, 0x11d2, 0x8e, 0x4f, 0x0, 0xa0, 0xc9, 0x69, 0x72, 45 0x3b } AND { 0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 46 0x72, 0x3b }) OR { 0x03c4e603, 0xac28, 0x11d3, 0x9a, 0x2d, 0x00, 0x90, 0x27, 47 0x3f, 0xc1, 0x4d } 48 DEPENDENCY_END 49 50 This file, in turn, will be fed into the utility, viz., 51 52 GenDepex Sample.TMP1 Sample.TMP2 53 54 With a file that is 55 bytes long: 55 56 55 bytes for the grammar binary 57 PUSH opcode - 1 byte 58 GUID Instance - 16 bytes 59 PUSH opcode - 1 byte 60 GUID Instance - 16 bytes 61 AND opcode - 1 byte 62 NOT opcode - 1 byte 63 PUSH opcode - 1 byte 64 GUID Instance - 16 bytes 65 OR opcode - 1 byte 66 END opcode - 1 byte 67 68 The file "Sample.TMP2" could be fed via a Section-builder utility 69 (GenSection) that would be used for the creation of a dependency 70 section file (.DPX) which in turn would be used by a generate FFS 71 utility (GenFfsFile) to produce a DXE driver/core (.DXE) or 72 a DXE application (.APP) file. 73 74 Complies with Tiano C Coding Standards Document, version 0.31, 12 Dec 2000. 75 76 --*/ 77 78 #include "GenDepex.h" 79 80 // 81 // Utility Name 82 // 83 #define UTILITY_NAME "GenDepex" 84 85 // 86 // Utility version information 87 // 88 #define UTILITY_VERSION "v1.0" 89 90 extern 91 BOOLEAN 92 ParseDepex ( 93 IN INT8 *Pbegin, 94 IN UINT32 length 95 ); 96 97 VOID 98 PrintGenDepexUtilityInfo ( 99 VOID 100 ) 101 /*++ 102 103 Routine Description: 104 105 Displays the standard utility information to SDTOUT. 106 107 Arguments: 108 109 None 110 111 Returns: 112 113 None 114 115 --*/ 116 { 117 int Index; 118 const char *Str[] = { 119 UTILITY_NAME" "UTILITY_VERSION" - Intel Generate Dependency Expression Utility", 120 " Copyright (C), 1996 - 2008 Intel Corporation", 121 122 #if ( defined(UTILITY_BUILD) && defined(UTILITY_VENDOR) ) 123 " Built from "UTILITY_BUILD", project of "UTILITY_VENDOR, 124 #endif 125 NULL 126 }; 127 for (Index = 0; Str[Index] != NULL; Index++) { 128 fprintf (stdout, "%s\n", Str[Index]); 129 } 130 } 131 132 VOID 133 PrintGenDepexUsageInfo ( 134 VOID 135 ) 136 /*++ 137 138 Routine Description: 139 140 Displays the utility usage syntax to STDOUT. 141 142 Arguments: 143 144 None 145 146 Returns: 147 148 None 149 150 --*/ 151 { 152 int Index; 153 const char *Str[] = { 154 "", 155 "Usage:", 156 " "UTILITY_NAME" [OPTION]...", 157 "Options:", 158 " -I INFILE The input pre-processed dependency text files name", 159 " -O OUTFILE The output binary dependency files name", 160 " -P BOUNDARY The padding integer value to align the output file size", 161 NULL 162 }; 163 164 PrintGenDepexUtilityInfo (); 165 for (Index = 0; Str[Index] != NULL; Index++) { 166 fprintf (stdout, "%s\n", Str[Index]); 167 } 168 } 169 170 DEPENDENCY_OPCODE 171 PopOpCode ( 172 IN OUT VOID **Stack 173 ) 174 /*++ 175 176 Routine Description: 177 178 Pop an element from the Opcode stack. 179 180 Arguments: 181 182 Stack Current top of the OpCode stack location 183 184 Returns: 185 186 DEPENDENCY_OPCODE OpCode at the top of the OpCode stack. 187 Stack New top of the OpCode stack location 188 189 190 --*/ 191 { 192 DEPENDENCY_OPCODE *OpCodePtr; 193 194 OpCodePtr = *Stack; 195 OpCodePtr--; 196 *Stack = OpCodePtr; 197 return *OpCodePtr; 198 } 199 200 VOID 201 PushOpCode ( 202 IN OUT VOID **Stack, 203 IN DEPENDENCY_OPCODE OpCode 204 ) 205 /*++ 206 207 Routine Description: 208 209 Push an element onto the Opcode Stack 210 211 Arguments: 212 213 Stack Current top of the OpCode stack location 214 OpCode OpCode to push onto the stack 215 216 Returns: 217 218 Stack New top of the OpCode stack location 219 220 --*/ 221 { 222 DEPENDENCY_OPCODE *OpCodePtr; 223 224 OpCodePtr = *Stack; 225 *OpCodePtr = OpCode; 226 OpCodePtr++; 227 *Stack = OpCodePtr; 228 } 229 230 EFI_STATUS 231 GenerateDependencyExpression ( 232 IN FILE *InFile, 233 IN OUT FILE *OutFile, 234 IN UINT8 Padding OPTIONAL 235 ) 236 /*++ 237 238 Routine Description: 239 240 This takes the pre-compiled dependency text file and 241 converts it into a binary dependency file. 242 243 The BNF for the dependency expression is as follows 244 (from the DXE 1.0 Draft specification). 245 246 The inputted BNF grammar is thus: 247 <depex> ::= sor <dep> | 248 before GUID <dep> | 249 after GUID <dep> | 250 <bool> 251 252 <dep> ::= <bool> | 253 254 <bool> ::= <bool> and <term> | 255 <bool> or <term> | 256 <term> 257 258 <term> ::= not <factor> | 259 <factor> 260 261 <factor> ::= ( <bool> ) | 262 <term> <term> | 263 GUID | 264 <boolval> 265 266 <boolval> ::= true | 267 false 268 269 The outputed binary grammer is thus: 270 <depex> ::= sor <dep> | 271 before <depinst> <dep> | 272 after <depinst> <dep> | 273 <bool> 274 275 <dep> ::= <bool> | 276 277 <bool> ::= <bool> and <term> | 278 <bool> or <term> | <term> 279 280 <term> ::= not <factor> | 281 <factor> 282 283 <factor> ::= ( <bool> ) | 284 <term> <term> | 285 <boolval> | 286 <depinst> | 287 <termval> 288 289 <boolval> ::= true | 290 false 291 292 <depinst> ::= push GUID 293 294 <termval> ::= end 295 296 BugBug: A correct grammer is parsed correctly. A file that violates the 297 grammer may parse when it should generate an error. There is some 298 error checking and it covers most of the case when it's an include 299 of definition issue. An ill formed expresion may not be detected. 300 301 Arguments: 302 303 InFile - Input pre-compiled text file of the dependency expression. 304 This needs to be in ASCII. 305 The file pointer can not be NULL. 306 307 OutFile - Binary dependency file. 308 The file pointer can not be NULL. 309 310 Padding - OPTIONAL integer value to pad the output file to. 311 312 313 Returns: 314 315 EFI_SUCCESS The function completed successfully. 316 EFI_INVALID_PARAMETER One of the parameters in the text file was invalid. 317 EFI_OUT_OF_RESOURCES Unable to allocate memory. 318 EFI_ABORTED An misc error occurred. 319 320 --*/ 321 { 322 INT8 *Ptrx; 323 INT8 *Pend; 324 INT8 *EvaluationStack; 325 INT8 *StackPtr; 326 INT8 *Buffer; 327 INT8 Line[LINESIZE]; 328 UINTN Index; 329 UINTN OutFileSize; 330 UINTN FileSize; 331 UINTN Results; 332 BOOLEAN NotDone; 333 BOOLEAN Before_Flag; 334 BOOLEAN After_Flag; 335 BOOLEAN Dep_Flag; 336 BOOLEAN SOR_Flag; 337 EFI_GUID Guid; 338 UINTN ArgCountParsed; 339 DEPENDENCY_OPCODE Opcode; 340 341 Before_Flag = FALSE; 342 After_Flag = FALSE; 343 Dep_Flag = FALSE; 344 SOR_Flag = FALSE; 345 346 memset (Line, 0, LINESIZE); 347 348 OutFileSize = 0; 349 350 EvaluationStack = (INT8 *) malloc (EVAL_STACK_SIZE); 351 352 if (EvaluationStack != NULL) { 353 StackPtr = EvaluationStack; 354 } else { 355 printf ("Unable to allocate memory to EvaluationStack - Out of resources\n"); 356 return EFI_OUT_OF_RESOURCES; 357 } 358 359 Results = (UINTN) fseek (InFile, 0, SEEK_END); 360 361 if (Results != 0) { 362 printf ("FSEEK failed - Aborted\n"); 363 return EFI_ABORTED; 364 } 365 366 FileSize = ftell (InFile); 367 368 if (FileSize == -1L) { 369 printf ("FTELL failed - Aborted\n"); 370 return EFI_ABORTED; 371 } 372 373 Buffer = (INT8 *) malloc (FileSize + BUFFER_SIZE); 374 375 if (Buffer == NULL) { 376 printf ("Unable to allocate memory to Buffer - Out of resources\n"); 377 free (EvaluationStack); 378 379 Results = (UINTN) fclose (InFile); 380 if (Results != 0) { 381 printf ("FCLOSE failed\n"); 382 } 383 384 Results = (UINTN) fclose (OutFile); 385 if (Results != 0) { 386 printf ("FCLOSE failed\n"); 387 } 388 389 return EFI_OUT_OF_RESOURCES; 390 } 391 392 Results = (UINTN) fseek (InFile, 0, SEEK_SET); 393 394 if (Results != 0) { 395 printf ("FSEEK failed - Aborted\n"); 396 return EFI_ABORTED; 397 } 398 399 fread (Buffer, FileSize, 1, InFile); 400 401 Ptrx = Buffer; 402 Pend = Ptrx + FileSize - strlen (DEPENDENCY_END); 403 Index = FileSize; 404 405 NotDone = TRUE; 406 while ((Index--) && NotDone) { 407 408 if (strncmp (Pend, DEPENDENCY_END, strlen (DEPENDENCY_END)) == 0) { 409 NotDone = FALSE; 410 } else { 411 Pend--; 412 } 413 } 414 415 if (NotDone) { 416 printf ("Couldn't find end string %s\n", DEPENDENCY_END); 417 418 Results = (UINTN) fclose (InFile); 419 if (Results != 0) { 420 printf ("FCLOSE failed\n"); 421 } 422 423 Results = (UINTN) fclose (OutFile); 424 if (Results != 0) { 425 printf ("FCLOSE failed\n"); 426 } 427 428 free (Buffer); 429 free (EvaluationStack); 430 431 return EFI_INVALID_PARAMETER; 432 } 433 434 Index = FileSize; 435 436 NotDone = TRUE; 437 while ((Index--) && NotDone) { 438 439 if (strncmp (Ptrx, DEPENDENCY_START, strlen (DEPENDENCY_START)) == 0) { 440 Ptrx += strlen (DEPENDENCY_START); 441 NotDone = FALSE; 442 // 443 // BUGBUG -- should Index be decremented by sizeof(DEPENDENCY_START)? 444 // 445 } else { 446 Ptrx++; 447 } 448 } 449 450 if (NotDone) { 451 printf ("Couldn't find start string %s\n", DEPENDENCY_START); 452 453 Results = (UINTN) fclose (InFile); 454 if (Results != 0) { 455 printf ("FCLOSE failed\n"); 456 } 457 458 Results = (UINTN) fclose (OutFile); 459 if (Results != 0) { 460 printf ("FCLOSE failed\n"); 461 } 462 463 free (Buffer); 464 free (EvaluationStack); 465 466 return EFI_INVALID_PARAMETER; 467 } 468 // 469 // validate the syntax of expression 470 // 471 if (!ParseDepex (Ptrx, Pend - Ptrx - 1)) { 472 printf ("The syntax of expression is wrong\n"); 473 474 Results = (UINTN) fclose (InFile); 475 if (Results != 0) { 476 printf ("FCLOSE failed\n"); 477 } 478 479 Results = (UINTN) fclose (OutFile); 480 if (Results != 0) { 481 printf ("FCLOSE failed\n"); 482 } 483 484 free (Buffer); 485 free (EvaluationStack); 486 487 return EFI_INVALID_PARAMETER; 488 } 489 490 NotDone = TRUE; 491 492 while ((Index--) && NotDone) { 493 494 if (*Ptrx == ' ') { 495 Ptrx++; 496 } else if (*Ptrx == '\n' || *Ptrx == '\r') { 497 Ptrx++; 498 } else if (strncmp (Ptrx, OPERATOR_SOR, strlen (OPERATOR_SOR)) == 0) { 499 // 500 // Checks for some invalid dependencies 501 // 502 if (Before_Flag) { 503 504 printf ("A BEFORE operator was detected.\n"); 505 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); 506 return EFI_INVALID_PARAMETER; 507 508 } else if (After_Flag) { 509 510 printf ("An AFTER operator was detected.\n"); 511 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); 512 return EFI_INVALID_PARAMETER; 513 514 } else if (SOR_Flag) { 515 516 printf ("Another SOR operator was detected.\n"); 517 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); 518 return EFI_INVALID_PARAMETER; 519 520 } else if (Dep_Flag) { 521 522 printf ("The Schedule On Request - SOR operator must be the first operator following DEPENDENCY_START\n"); 523 return EFI_INVALID_PARAMETER; 524 525 } else { 526 // 527 // BUGBUG - This was not in the spec but is in the CORE code 528 // An OPERATOR_SOR has to be first - following the DEPENDENCY_START 529 // 530 fputc (EFI_DEP_SOR, OutFile); 531 OutFileSize++; 532 Ptrx += strlen (OPERATOR_SOR); 533 SOR_Flag = TRUE; 534 535 } 536 } else if (strncmp (Ptrx, OPERATOR_BEFORE, strlen (OPERATOR_BEFORE)) == 0) { 537 // 538 // Checks for some invalid dependencies 539 // 540 if (Before_Flag) { 541 542 printf ("Another BEFORE operator was detected.\n"); 543 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); 544 return EFI_INVALID_PARAMETER; 545 546 } else if (After_Flag) { 547 548 printf ("An AFTER operator was detected.\n"); 549 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); 550 return EFI_INVALID_PARAMETER; 551 552 } else if (SOR_Flag) { 553 554 printf ("A SOR operator was detected.\n"); 555 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); 556 return EFI_INVALID_PARAMETER; 557 558 } else if (Dep_Flag) { 559 560 printf ("The BEFORE operator must be the first operator following DEPENDENCY_START\n"); 561 return EFI_INVALID_PARAMETER; 562 563 } else { 564 fputc (EFI_DEP_BEFORE, OutFile); 565 OutFileSize++; 566 Ptrx += strlen (OPERATOR_BEFORE); 567 Before_Flag = TRUE; 568 } 569 } else if (strncmp (Ptrx, OPERATOR_AFTER, strlen (OPERATOR_AFTER)) == 0) { 570 // 571 // Checks for some invalid dependencies 572 // 573 if (Before_Flag) { 574 575 printf ("A BEFORE operator was detected.\n"); 576 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); 577 return EFI_INVALID_PARAMETER; 578 579 } else if (After_Flag) { 580 581 printf ("Another AFTER operator was detected.\n"); 582 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); 583 return EFI_INVALID_PARAMETER; 584 585 } else if (SOR_Flag) { 586 587 printf ("A SOR operator was detected.\n"); 588 printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); 589 return EFI_INVALID_PARAMETER; 590 591 } else if (Dep_Flag) { 592 593 printf ("The AFTER operator must be the first operator following DEPENDENCY_START\n"); 594 return EFI_INVALID_PARAMETER; 595 596 } else { 597 fputc (EFI_DEP_AFTER, OutFile); 598 OutFileSize++; 599 Ptrx += strlen (OPERATOR_AFTER); 600 Dep_Flag = TRUE; 601 After_Flag = TRUE; 602 } 603 } else if (strncmp (Ptrx, OPERATOR_AND, strlen (OPERATOR_AND)) == 0) { 604 while (StackPtr != EvaluationStack) { 605 Opcode = PopOpCode ((VOID **) &StackPtr); 606 if (Opcode != DXE_DEP_LEFT_PARENTHESIS) { 607 fputc (Opcode, OutFile); 608 OutFileSize++; 609 } else { 610 PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS); 611 break; 612 } 613 } 614 615 PushOpCode ((VOID **) &StackPtr, EFI_DEP_AND); 616 Ptrx += strlen (OPERATOR_AND); 617 Dep_Flag = TRUE; 618 619 } else if (strncmp (Ptrx, OPERATOR_OR, strlen (OPERATOR_OR)) == 0) { 620 while (StackPtr != EvaluationStack) { 621 Opcode = PopOpCode ((VOID **) &StackPtr); 622 if (Opcode != DXE_DEP_LEFT_PARENTHESIS) { 623 fputc (Opcode, OutFile); 624 OutFileSize++; 625 } else { 626 PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS); 627 break; 628 } 629 } 630 631 PushOpCode ((VOID **) &StackPtr, EFI_DEP_OR); 632 Ptrx += strlen (OPERATOR_OR); 633 Dep_Flag = TRUE; 634 635 } else if (strncmp (Ptrx, OPERATOR_NOT, strlen (OPERATOR_NOT)) == 0) { 636 while (StackPtr != EvaluationStack) { 637 Opcode = PopOpCode ((VOID **) &StackPtr); 638 if (Opcode != DXE_DEP_LEFT_PARENTHESIS) { 639 fputc (Opcode, OutFile); 640 OutFileSize++; 641 } else { 642 PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS); 643 break; 644 } 645 } 646 647 PushOpCode ((VOID **) &StackPtr, EFI_DEP_NOT); 648 Ptrx += strlen (OPERATOR_NOT); 649 Dep_Flag = TRUE; 650 651 } else if (*Ptrx == '\t') { 652 653 printf ("File contains tabs. This violates the coding standard\n"); 654 return EFI_INVALID_PARAMETER; 655 656 } else if (*Ptrx == '\n') { 657 // 658 // Skip the newline character in the file 659 // 660 Ptrx++; 661 662 } else if (strncmp (Ptrx, OPERATOR_LEFT_PARENTHESIS, strlen (OPERATOR_LEFT_PARENTHESIS)) == 0) { 663 PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS); 664 665 Ptrx += strlen (OPERATOR_LEFT_PARENTHESIS); 666 Dep_Flag = TRUE; 667 668 } else if (strncmp (Ptrx, OPERATOR_RIGHT_PARENTHESIS, strlen (OPERATOR_RIGHT_PARENTHESIS)) == 0) { 669 while (StackPtr != EvaluationStack) { 670 Opcode = PopOpCode ((VOID **) &StackPtr); 671 if (Opcode != DXE_DEP_LEFT_PARENTHESIS) { 672 fputc (Opcode, OutFile); 673 OutFileSize++; 674 } else { 675 break; 676 } 677 } 678 679 Ptrx += strlen (OPERATOR_RIGHT_PARENTHESIS); 680 Dep_Flag = TRUE; 681 682 } else if (strncmp (Ptrx, OPERATOR_TRUE, strlen (OPERATOR_TRUE)) == 0) { 683 684 fputc (EFI_DEP_TRUE, OutFile); 685 686 OutFileSize++; 687 688 // 689 // OutFileSize += sizeof (EFI_DEP_TRUE); 690 // 691 Dep_Flag = TRUE; 692 693 Ptrx += strlen (OPERATOR_TRUE); 694 695 } else if (strncmp (Ptrx, OPERATOR_FALSE, strlen (OPERATOR_FALSE)) == 0) { 696 697 fputc (EFI_DEP_FALSE, OutFile); 698 699 OutFileSize++; 700 701 // 702 // OutFileSize += sizeof (EFI_DEP_FALSE); 703 // 704 Dep_Flag = TRUE; 705 706 Ptrx += strlen (OPERATOR_FALSE); 707 708 } else if (*Ptrx == '{') { 709 Ptrx++; 710 711 if (*Ptrx == ' ') { 712 Ptrx++; 713 } 714 715 ArgCountParsed = sscanf ( 716 Ptrx, 717 "%x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x", 718 &Guid.Data1, 719 &Guid.Data2, 720 &Guid.Data3, 721 &Guid.Data4[0], 722 &Guid.Data4[1], 723 &Guid.Data4[2], 724 &Guid.Data4[3], 725 &Guid.Data4[4], 726 &Guid.Data4[5], 727 &Guid.Data4[6], 728 &Guid.Data4[7] 729 ); 730 731 if (ArgCountParsed != 11) { 732 printf ("We have found an illegal GUID\n"); 733 printf ("Fix your depex\n"); 734 exit (-1); 735 } 736 737 while (*Ptrx != '}') { 738 Ptrx++; 739 } 740 // 741 // Absorb the closing } 742 // 743 Ptrx++; 744 745 // 746 // Don't provide a PUSH Opcode for the Before and After case 747 // 748 if ((!Before_Flag) && (!After_Flag)) { 749 fputc (EFI_DEP_PUSH, OutFile); 750 OutFileSize++; 751 } 752 753 fwrite (&Guid, sizeof (EFI_GUID), 1, OutFile); 754 755 OutFileSize += sizeof (EFI_GUID); 756 Dep_Flag = TRUE; 757 758 } else if (strncmp (Ptrx, DEPENDENCY_END, strlen (DEPENDENCY_END)) == 0) { 759 NotDone = FALSE; 760 } else { 761 // 762 // Not a valid construct. Null terminate somewhere out there and 763 // print an error message. 764 // 765 *(Ptrx + 20) = 0; 766 printf (UTILITY_NAME" ERROR: Unrecognized input at: \"%s\"...\n", Ptrx); 767 return EFI_INVALID_PARAMETER; 768 } 769 } 770 // 771 // DRAIN(); 772 // 773 while (StackPtr != EvaluationStack) { 774 fputc (PopOpCode ((VOID **) &StackPtr), OutFile); 775 OutFileSize++; 776 } 777 778 if (OutFileSize == 0) { 779 printf ("Grammer contains no operators or constants\n"); 780 return EFI_INVALID_PARAMETER; 781 } 782 783 fputc (EFI_DEP_END, OutFile); 784 785 OutFileSize++; 786 787 // 788 // Checks for invalid padding values 789 // 790 if (Padding < 0) { 791 792 printf ("The inputted padding value was %d\n", Padding); 793 printf ("The optional padding value can not be less than ZERO\n"); 794 return EFI_INVALID_PARAMETER; 795 796 } else if (Padding > 0) { 797 798 while ((OutFileSize % Padding) != 0) { 799 800 fputc (' ', OutFile); 801 OutFileSize++; 802 } 803 } 804 805 Results = (UINTN) fclose (InFile); 806 if (Results != 0) { 807 printf ("FCLOSE failed\n"); 808 } 809 810 Results = (UINTN) fclose (OutFile); 811 if (Results != 0) { 812 printf ("FCLOSE failed\n"); 813 } 814 815 free (Buffer); 816 free (EvaluationStack); 817 818 return EFI_SUCCESS; 819 } // End GenerateDependencyExpression function 820 821 EFI_STATUS 822 main ( 823 IN UINTN argc, 824 IN CHAR8 *argv[] 825 ) 826 /*++ 827 828 Routine Description: 829 830 Parse user entries. Print some rudimentary help 831 832 Arguments: 833 834 argc The count of input arguments 835 argv The input arguments string array 836 837 Returns: 838 839 EFI_SUCCESS The function completed successfully. 840 EFI_INVALID_PARAMETER One of the input parameters was invalid or one of the parameters in the text file was invalid. 841 EFI_OUT_OF_RESOURCES Unable to allocate memory. 842 EFI_ABORTED Unable to open/create a file or a misc error. 843 844 --*/ 845 // TODO: ] - add argument and description to function comment 846 { 847 FILE *OutFile; 848 FILE *InFile; 849 UINT8 Padding; 850 UINTN Index; 851 BOOLEAN Input_Flag; 852 BOOLEAN Output_Flag; 853 BOOLEAN Pad_Flag; 854 855 InFile = NULL; 856 OutFile = NULL; 857 Padding = 0; 858 Input_Flag = FALSE; 859 Output_Flag = FALSE; 860 Pad_Flag = FALSE; 861 862 // 863 // Output the calling arguments 864 // 865 //printf ("\n\n"); 866 //for (Index = 0; Index < argc; Index++) { 867 // printf ("%s ", argv[Index]); 868 //} 869 // 870 //printf ("\n\n"); 871 872 if (argc < 5) { 873 printf ("Not enough arguments\n"); 874 PrintGenDepexUsageInfo (); 875 return EFI_INVALID_PARAMETER; 876 } 877 878 for (Index = 1; Index < argc - 1; Index++) { 879 880 if ((strcmp (argv[Index], "-I") == 0) || (strcmp (argv[Index], "-i") == 0)) { 881 882 if (!Input_Flag) { 883 884 InFile = fopen (argv[Index + 1], "rb"); 885 Input_Flag = TRUE; 886 887 } else { 888 printf ("GenDepex only allows one INPUT (-I) argument\n"); 889 return EFI_INVALID_PARAMETER; 890 } 891 892 } else if ((strcmp (argv[Index], "-O") == 0) || (strcmp (argv[Index], "-o") == 0)) { 893 894 if (!Output_Flag) { 895 896 OutFile = fopen (argv[Index + 1], "wb"); 897 Output_Flag = TRUE; 898 899 } else { 900 printf ("GenDepex only allows one OUTPUT (-O) argument\n"); 901 return EFI_INVALID_PARAMETER; 902 } 903 904 } else if ((strcmp (argv[Index], "-P") == 0) || (strcmp (argv[Index], "-p") == 0)) { 905 906 if (!Pad_Flag) { 907 908 Padding = (UINT8) atoi (argv[Index + 1]); 909 Pad_Flag = TRUE; 910 911 } else { 912 printf ("GenDepex only allows one PADDING (-P) argument\n"); 913 return EFI_INVALID_PARAMETER; 914 } 915 } 916 } 917 918 PrintGenDepexUtilityInfo (); 919 920 if (InFile == NULL) { 921 printf ("Can not open <INFILE> for reading.\n"); 922 PrintGenDepexUsageInfo (); 923 return EFI_ABORTED; 924 } 925 926 if (OutFile == NULL) { 927 printf ("Can not open <OUTFILE> for writting.\n"); 928 PrintGenDepexUsageInfo (); 929 return EFI_ABORTED; 930 } 931 932 return GenerateDependencyExpression (InFile, OutFile, Padding); 933 } 934