1 /****************************************************************************** 2 * 3 * Module Name: aslfiles - File support functions 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2021, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include "aslcompiler.h" 45 #include "acapps.h" 46 47 #define _COMPONENT ACPI_COMPILER 48 ACPI_MODULE_NAME ("aslfiles") 49 50 /* Local prototypes */ 51 52 static FILE * 53 FlOpenIncludeWithPrefix ( 54 char *PrefixDir, 55 ACPI_PARSE_OBJECT *Op, 56 char *Filename); 57 58 static BOOLEAN 59 FlInputFileExists ( 60 char *InputFilename); 61 62 #ifdef ACPI_OBSOLETE_FUNCTIONS 63 ACPI_STATUS 64 FlParseInputPathname ( 65 char *InputFilename); 66 #endif 67 68 69 /******************************************************************************* 70 * 71 * FUNCTION: FlInitOneFile 72 * 73 * PARAMETERS: InputFilename - The user-specified ASL source file to be 74 * compiled 75 * 76 * RETURN: Status 77 * 78 * DESCRIPTION: Initialize global file structure for one input file. This file 79 * structure contains references to input, output, debugging, and 80 * other miscellaneous files that are associated for a single 81 * input ASL file. 82 * 83 ******************************************************************************/ 84 85 ACPI_STATUS 86 FlInitOneFile ( 87 char *InputFilename) 88 { 89 UINT32 i; 90 ASL_GLOBAL_FILE_NODE *NewFileNode; 91 92 93 if (FlInputFileExists (InputFilename)) 94 { 95 AslError (ASL_ERROR, ASL_MSG_DUPLICATE_INPUT_FILE, NULL, InputFilename); 96 return (AE_ALREADY_EXISTS); 97 } 98 99 NewFileNode = ACPI_CAST_PTR (ASL_GLOBAL_FILE_NODE, 100 UtLocalCacheCalloc (sizeof (ASL_GLOBAL_FILE_NODE))); 101 102 NewFileNode->ParserErrorDetected = FALSE; 103 NewFileNode->Next = AslGbl_FilesList; 104 105 AslGbl_FilesList = NewFileNode; 106 AslGbl_Files = NewFileNode->Files; 107 108 for (i = 0; i < ASL_NUM_FILES; i++) 109 { 110 AslGbl_Files[i].Handle = NULL; 111 AslGbl_Files[i].Filename = NULL; 112 } 113 114 AslGbl_Files[ASL_FILE_STDOUT].Handle = stdout; 115 AslGbl_Files[ASL_FILE_STDOUT].Filename = "STDOUT"; 116 117 if (AslGbl_VerboseErrors) 118 { 119 AslGbl_Files[ASL_FILE_STDERR].Handle = stderr; 120 } 121 else 122 { 123 AslGbl_Files[ASL_FILE_STDERR].Handle = stdout; 124 } 125 126 AslGbl_Files[ASL_FILE_STDERR].Filename = "STDERR"; 127 return (AE_OK); 128 } 129 130 131 /******************************************************************************* 132 * 133 * FUNCTION: FlInputFileExists 134 * 135 * PARAMETERS: Filename - File name to be searched 136 * 137 * RETURN: Status 138 * 139 * DESCRIPTION: Returns true if the file name already exists. 140 * 141 ******************************************************************************/ 142 143 static BOOLEAN 144 FlInputFileExists ( 145 char *Filename) 146 { 147 ASL_GLOBAL_FILE_NODE *Current = AslGbl_FilesList; 148 149 150 while (Current) 151 { 152 if (!strcmp (Filename, Current->Files[ASL_FILE_INPUT].Filename)) 153 { 154 return (TRUE); 155 } 156 157 Current = Current->Next; 158 } 159 160 return (FALSE); 161 } 162 163 164 /******************************************************************************* 165 * 166 * FUNCTION: FlSwitchFileSet 167 * 168 * PARAMETERS: Op - Parse node for the LINE asl statement 169 * 170 * RETURN: None. 171 * 172 * DESCRIPTION: Set the current line number 173 * 174 ******************************************************************************/ 175 176 ASL_FILE_SWITCH_STATUS 177 FlSwitchFileSet ( 178 char *InputFilename) 179 { 180 ASL_GLOBAL_FILE_NODE *Current = AslGbl_FilesList; 181 char *PrevFilename = Current->Files[ASL_FILE_INPUT].Filename; 182 183 184 while (Current) 185 { 186 if (!strcmp(Current->Files[ASL_FILE_INPUT].Filename, InputFilename)) 187 { 188 AslGbl_Files = Current->Files; 189 AslGbl_TableSignature = Current->TableSignature; 190 AslGbl_TableId = Current->TableId; 191 192 if (!strcmp (InputFilename, PrevFilename)) 193 { 194 return (SWITCH_TO_SAME_FILE); 195 } 196 else 197 { 198 return (SWITCH_TO_DIFFERENT_FILE); 199 } 200 } 201 202 Current = Current->Next; 203 } 204 205 return (FILE_NOT_FOUND); 206 } 207 208 209 /******************************************************************************* 210 * 211 * FUNCTION: FlGetFileHandle 212 * 213 * PARAMETERS: OutFileId - denotes file type of output handle 214 * InFileId - denotes file type of the input Filename 215 * Filename 216 * 217 * RETURN: File handle 218 * 219 * DESCRIPTION: Get the file handle for a particular filename/FileId. This 220 * function also allows the caller to specify the file Id of the 221 * desired type. 222 * 223 ******************************************************************************/ 224 225 FILE * 226 FlGetFileHandle ( 227 UINT32 OutFileId, 228 UINT32 InFileId, 229 char *Filename) 230 { 231 ASL_GLOBAL_FILE_NODE *Current = AslGbl_FilesList; 232 233 234 if (!Filename) 235 { 236 return (NULL); 237 } 238 239 while (Current) 240 { 241 if (!strcmp (Current->Files[InFileId].Filename, Filename)) 242 { 243 return (Current->Files[OutFileId].Handle); 244 } 245 246 Current = Current->Next; 247 } 248 249 return (NULL); 250 } 251 252 253 /******************************************************************************* 254 * 255 * FUNCTION: FlGetFileNode 256 * 257 * PARAMETERS: FileId - File type (ID) of the input Filename 258 * Filename - File to search for 259 * 260 * RETURN: A global file node 261 * 262 * DESCRIPTION: Get the file node for a particular filename/FileId. 263 * 264 ******************************************************************************/ 265 266 ASL_GLOBAL_FILE_NODE * 267 FlGetFileNode ( 268 UINT32 FileId, 269 char *Filename) 270 { 271 ASL_GLOBAL_FILE_NODE *Current = AslGbl_FilesList; 272 273 274 if (!Filename) 275 { 276 return (NULL); 277 } 278 279 while (Current) 280 { 281 if (!strcmp (Current->Files[FileId].Filename, Filename)) 282 { 283 return (Current); 284 } 285 286 Current = Current->Next; 287 } 288 289 return (NULL); 290 } 291 292 293 /******************************************************************************* 294 * 295 * FUNCTION: FlGetCurrentFileNode 296 * 297 * PARAMETERS: None 298 * 299 * RETURN: Global file node 300 * 301 * DESCRIPTION: Get the current input file node 302 * 303 ******************************************************************************/ 304 305 ASL_GLOBAL_FILE_NODE * 306 FlGetCurrentFileNode ( 307 void) 308 { 309 ASL_GLOBAL_FILE_NODE *FileNode = 310 FlGetFileNode (ASL_FILE_INPUT,AslGbl_Files[ASL_FILE_INPUT].Filename); 311 312 313 if (!FileNode) 314 { 315 /* 316 * If the current file node does not exist after initializing the file 317 * node structures, something went wrong and this is an unrecoverable 318 * condition. 319 */ 320 FlFileError (ASL_FILE_INPUT, ASL_MSG_COMPILER_INTERNAL); 321 AslAbort (); 322 } 323 324 return (FileNode); 325 } 326 327 328 /******************************************************************************* 329 * 330 * FUNCTION: FlSetLineNumber 331 * 332 * PARAMETERS: Op - Parse node for the LINE asl statement 333 * 334 * RETURN: None. 335 * 336 * DESCRIPTION: Set the current line number 337 * 338 ******************************************************************************/ 339 340 void 341 FlSetLineNumber ( 342 UINT32 LineNumber) 343 { 344 345 DbgPrint (ASL_PARSE_OUTPUT, "\n#line: New line number %u (old %u)\n", 346 LineNumber, AslGbl_LogicalLineNumber); 347 348 AslGbl_CurrentLineNumber = LineNumber; 349 } 350 351 352 /******************************************************************************* 353 * 354 * FUNCTION: FlSetFilename 355 * 356 * PARAMETERS: Op - Parse node for the LINE asl statement 357 * 358 * RETURN: None. 359 * 360 * DESCRIPTION: Set the current filename 361 * 362 ******************************************************************************/ 363 364 void 365 FlSetFilename ( 366 char *Filename) 367 { 368 369 DbgPrint (ASL_PARSE_OUTPUT, "\n#line: New filename %s (old %s)\n", 370 Filename, AslGbl_Files[ASL_FILE_INPUT].Filename); 371 372 /* No need to free any existing filename */ 373 374 AslGbl_Files[ASL_FILE_INPUT].Filename = Filename; 375 } 376 377 378 /******************************************************************************* 379 * 380 * FUNCTION: FlAddIncludeDirectory 381 * 382 * PARAMETERS: Dir - Directory pathname string 383 * 384 * RETURN: None 385 * 386 * DESCRIPTION: Add a directory the list of include prefix directories. 387 * 388 ******************************************************************************/ 389 390 void 391 FlAddIncludeDirectory ( 392 char *Dir) 393 { 394 ASL_INCLUDE_DIR *NewDir; 395 ASL_INCLUDE_DIR *NextDir; 396 ASL_INCLUDE_DIR *PrevDir = NULL; 397 UINT32 NeedsSeparator = 0; 398 size_t DirLength; 399 400 401 DirLength = strlen (Dir); 402 if (!DirLength) 403 { 404 return; 405 } 406 407 /* Make sure that the pathname ends with a path separator */ 408 409 if ((Dir[DirLength-1] != '/') && 410 (Dir[DirLength-1] != '\\')) 411 { 412 NeedsSeparator = 1; 413 } 414 415 NewDir = ACPI_CAST_PTR (ASL_INCLUDE_DIR, 416 UtLocalCacheCalloc (sizeof (ASL_INCLUDE_DIR))); 417 NewDir->Dir = UtLocalCacheCalloc (DirLength + 1 + NeedsSeparator); 418 strcpy (NewDir->Dir, Dir); 419 if (NeedsSeparator) 420 { 421 strcat (NewDir->Dir, "/"); 422 } 423 424 /* 425 * Preserve command line ordering of -I options by adding new elements 426 * at the end of the list 427 */ 428 NextDir = AslGbl_IncludeDirList; 429 while (NextDir) 430 { 431 PrevDir = NextDir; 432 NextDir = NextDir->Next; 433 } 434 435 if (PrevDir) 436 { 437 PrevDir->Next = NewDir; 438 } 439 else 440 { 441 AslGbl_IncludeDirList = NewDir; 442 } 443 } 444 445 446 /******************************************************************************* 447 * 448 * FUNCTION: FlMergePathnames 449 * 450 * PARAMETERS: PrefixDir - Prefix directory pathname. Can be NULL or 451 * a zero length string. 452 * FilePathname - The include filename from the source ASL. 453 * 454 * RETURN: Merged pathname string 455 * 456 * DESCRIPTION: Merge two pathnames that (probably) have common elements, to 457 * arrive at a minimal length string. Merge can occur if the 458 * FilePathname is relative to the PrefixDir. 459 * 460 ******************************************************************************/ 461 462 char * 463 FlMergePathnames ( 464 char *PrefixDir, 465 char *FilePathname) 466 { 467 char *CommonPath; 468 char *Pathname; 469 char *LastElement; 470 471 472 DbgPrint (ASL_PARSE_OUTPUT, "Include: Prefix path - \"%s\"\n" 473 "Include: FilePathname - \"%s\"\n", 474 PrefixDir, FilePathname); 475 476 /* 477 * If there is no prefix directory or if the file pathname is absolute, 478 * just return the original file pathname 479 */ 480 if (!PrefixDir || (!*PrefixDir) || 481 (*FilePathname == '/') || 482 (FilePathname[1] == ':')) 483 { 484 Pathname = UtLocalCacheCalloc (strlen (FilePathname) + 1); 485 strcpy (Pathname, FilePathname); 486 goto ConvertBackslashes; 487 } 488 489 /* Need a local copy of the prefix directory path */ 490 491 CommonPath = UtLocalCacheCalloc (strlen (PrefixDir) + 1); 492 strcpy (CommonPath, PrefixDir); 493 494 /* 495 * Walk forward through the file path, and simultaneously backward 496 * through the prefix directory path until there are no more 497 * relative references at the start of the file path. 498 */ 499 while (*FilePathname && (!strncmp (FilePathname, "../", 3))) 500 { 501 /* Remove last element of the prefix directory path */ 502 503 LastElement = strrchr (CommonPath, '/'); 504 if (!LastElement) 505 { 506 goto ConcatenatePaths; 507 } 508 509 *LastElement = 0; /* Terminate CommonPath string */ 510 FilePathname += 3; /* Point to next path element */ 511 } 512 513 /* 514 * Remove the last element of the prefix directory path (it is the same as 515 * the first element of the file pathname), and build the final merged 516 * pathname. 517 */ 518 LastElement = strrchr (CommonPath, '/'); 519 if (LastElement) 520 { 521 *LastElement = 0; 522 } 523 524 /* Build the final merged pathname */ 525 526 ConcatenatePaths: 527 Pathname = UtLocalCacheCalloc ( 528 strlen (CommonPath) + strlen (FilePathname) + 2); 529 if (LastElement && *CommonPath) 530 { 531 strcpy (Pathname, CommonPath); 532 strcat (Pathname, "/"); 533 } 534 strcat (Pathname, FilePathname); 535 536 /* Convert all backslashes to normal slashes */ 537 538 ConvertBackslashes: 539 UtConvertBackslashes (Pathname); 540 541 DbgPrint (ASL_PARSE_OUTPUT, "Include: Merged Pathname - \"%s\"\n", 542 Pathname); 543 return (Pathname); 544 } 545 546 547 /******************************************************************************* 548 * 549 * FUNCTION: FlOpenIncludeWithPrefix 550 * 551 * PARAMETERS: PrefixDir - Prefix directory pathname. Can be a zero 552 * length string. 553 * Filename - The include filename from the source ASL. 554 * 555 * RETURN: Valid file descriptor if successful. Null otherwise. 556 * 557 * DESCRIPTION: Open an include file and push it on the input file stack. 558 * 559 ******************************************************************************/ 560 561 static FILE * 562 FlOpenIncludeWithPrefix ( 563 char *PrefixDir, 564 ACPI_PARSE_OBJECT *Op, 565 char *Filename) 566 { 567 FILE *IncludeFile; 568 char *Pathname; 569 UINT32 OriginalLineNumber; 570 571 572 /* Build the full pathname to the file */ 573 574 Pathname = FlMergePathnames (PrefixDir, Filename); 575 576 DbgPrint (ASL_PARSE_OUTPUT, "Include: Opening file - \"%s\"\n\n", 577 Pathname); 578 579 /* Attempt to open the file, push if successful */ 580 581 IncludeFile = fopen (Pathname, "r"); 582 if (!IncludeFile) 583 { 584 return (NULL); 585 } 586 587 /* 588 * Check the entire include file for any # preprocessor directives. 589 * This is because there may be some confusion between the #include 590 * preprocessor directive and the ASL Include statement. A file included 591 * by the ASL include cannot contain preprocessor directives because 592 * the preprocessor has already run by the time the ASL include is 593 * recognized (by the compiler, not the preprocessor.) 594 * 595 * Note: DtGetNextLine strips/ignores comments. 596 * Save current line number since DtGetNextLine modifies it. 597 */ 598 AslGbl_CurrentLineNumber--; 599 OriginalLineNumber = AslGbl_CurrentLineNumber; 600 601 while (DtGetNextLine (IncludeFile, DT_ALLOW_MULTILINE_QUOTES) != ASL_EOF) 602 { 603 if (AslGbl_CurrentLineBuffer[0] == '#') 604 { 605 AslError (ASL_ERROR, ASL_MSG_INCLUDE_FILE, 606 Op, "use #include instead"); 607 } 608 } 609 610 AslGbl_CurrentLineNumber = OriginalLineNumber; 611 612 /* Must seek back to the start of the file */ 613 614 fseek (IncludeFile, 0, SEEK_SET); 615 616 /* Push the include file on the open input file stack */ 617 618 AslPushInputFileStack (IncludeFile, Pathname); 619 return (IncludeFile); 620 } 621 622 623 /******************************************************************************* 624 * 625 * FUNCTION: FlOpenIncludeFile 626 * 627 * PARAMETERS: Op - Parse node for the INCLUDE ASL statement 628 * 629 * RETURN: None. 630 * 631 * DESCRIPTION: Open an include file and push it on the input file stack. 632 * 633 ******************************************************************************/ 634 635 void 636 FlOpenIncludeFile ( 637 ACPI_PARSE_OBJECT *Op) 638 { 639 FILE *IncludeFile; 640 ASL_INCLUDE_DIR *NextDir; 641 642 643 /* Op must be valid */ 644 645 if (!Op) 646 { 647 AslCommonError (ASL_ERROR, ASL_MSG_INCLUDE_FILE_OPEN, 648 AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber, 649 AslGbl_InputByteCount, AslGbl_CurrentColumn, 650 AslGbl_Files[ASL_FILE_INPUT].Filename, " - Null parse node"); 651 652 return; 653 } 654 655 /* 656 * Flush out the "include ()" statement on this line, start 657 * the actual include file on the next line 658 */ 659 AslResetCurrentLineBuffer (); 660 FlPrintFile (ASL_FILE_SOURCE_OUTPUT, "\n"); 661 AslGbl_CurrentLineOffset++; 662 663 664 /* Attempt to open the include file */ 665 666 /* If the file specifies an absolute path, just open it */ 667 668 if ((Op->Asl.Value.String[0] == '/') || 669 (Op->Asl.Value.String[0] == '\\') || 670 (Op->Asl.Value.String[1] == ':')) 671 { 672 IncludeFile = FlOpenIncludeWithPrefix ("", Op, Op->Asl.Value.String); 673 if (!IncludeFile) 674 { 675 goto ErrorExit; 676 } 677 return; 678 } 679 680 /* 681 * The include filename is not an absolute path. 682 * 683 * First, search for the file within the "local" directory -- meaning 684 * the same directory that contains the source file. 685 * 686 * Construct the file pathname from the global directory name. 687 */ 688 IncludeFile = FlOpenIncludeWithPrefix ( 689 AslGbl_DirectoryPath, Op, Op->Asl.Value.String); 690 if (IncludeFile) 691 { 692 return; 693 } 694 695 /* 696 * Second, search for the file within the (possibly multiple) directories 697 * specified by the -I option on the command line. 698 */ 699 NextDir = AslGbl_IncludeDirList; 700 while (NextDir) 701 { 702 IncludeFile = FlOpenIncludeWithPrefix ( 703 NextDir->Dir, Op, Op->Asl.Value.String); 704 if (IncludeFile) 705 { 706 return; 707 } 708 709 NextDir = NextDir->Next; 710 } 711 712 /* We could not open the include file after trying very hard */ 713 714 ErrorExit: 715 snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "%s, %s", Op->Asl.Value.String, strerror (errno)); 716 AslError (ASL_ERROR, ASL_MSG_INCLUDE_FILE_OPEN, Op, AslGbl_MsgBuffer); 717 } 718 719 720 /******************************************************************************* 721 * 722 * FUNCTION: FlOpenInputFile 723 * 724 * PARAMETERS: InputFilename - The user-specified ASL source file to be 725 * compiled 726 * 727 * RETURN: Status 728 * 729 * DESCRIPTION: Open the specified input file, and save the directory path to 730 * the file so that include files can be opened in 731 * the same directory. 732 * 733 ******************************************************************************/ 734 735 ACPI_STATUS 736 FlOpenInputFile ( 737 char *InputFilename) 738 { 739 740 /* Open the input ASL file, text mode */ 741 742 FlOpenFile (ASL_FILE_INPUT, InputFilename, "rt"); 743 AslCompilerin = AslGbl_Files[ASL_FILE_INPUT].Handle; 744 745 return (AE_OK); 746 } 747 748 749 /******************************************************************************* 750 * 751 * FUNCTION: FlOpenAmlOutputFile 752 * 753 * PARAMETERS: FilenamePrefix - The user-specified ASL source file 754 * 755 * RETURN: Status 756 * 757 * DESCRIPTION: Create the output filename (*.AML) and open the file. The file 758 * is created in the same directory as the parent input file. 759 * 760 ******************************************************************************/ 761 762 ACPI_STATUS 763 FlOpenAmlOutputFile ( 764 char *FilenamePrefix) 765 { 766 char *Filename; 767 768 769 /* Output filename usually comes from the ASL itself */ 770 771 Filename = AslGbl_Files[ASL_FILE_AML_OUTPUT].Filename; 772 if (!Filename) 773 { 774 /* Create the output AML filename */ 775 if (!AcpiGbl_CaptureComments) 776 { 777 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_AML_CODE); 778 } 779 else 780 { 781 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_CONVERT_AML); 782 } 783 if (!Filename) 784 { 785 AslCommonError (ASL_ERROR, ASL_MSG_OUTPUT_FILENAME, 786 0, 0, 0, 0, NULL, NULL); 787 return (AE_ERROR); 788 } 789 790 AslGbl_Files[ASL_FILE_AML_OUTPUT].Filename = Filename; 791 } 792 793 /* Open the output AML file in binary mode */ 794 795 FlOpenFile (ASL_FILE_AML_OUTPUT, Filename, "w+b"); 796 return (AE_OK); 797 } 798 799 800 /******************************************************************************* 801 * 802 * FUNCTION: FlOpenMiscOutputFiles 803 * 804 * PARAMETERS: FilenamePrefix - The user-specified ASL source file 805 * 806 * RETURN: Status 807 * 808 * DESCRIPTION: Create and open the various output files needed, depending on 809 * the command line options 810 * 811 ******************************************************************************/ 812 813 ACPI_STATUS 814 FlOpenMiscOutputFiles ( 815 char *FilenamePrefix) 816 { 817 char *Filename; 818 819 820 /* Create/Open a map file if requested */ 821 822 if (AslGbl_MapfileFlag) 823 { 824 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_MAP); 825 if (!Filename) 826 { 827 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME, 828 0, 0, 0, 0, NULL, NULL); 829 return (AE_ERROR); 830 } 831 832 /* Open the hex file, text mode (closed at compiler exit) */ 833 834 FlOpenFile (ASL_FILE_MAP_OUTPUT, Filename, "w+t"); 835 836 AslCompilerSignon (ASL_FILE_MAP_OUTPUT); 837 AslCompilerFileHeader (ASL_FILE_MAP_OUTPUT); 838 } 839 840 /* All done for disassembler */ 841 842 if (AslGbl_FileType == ASL_INPUT_TYPE_BINARY_ACPI_TABLE) 843 { 844 return (AE_OK); 845 } 846 847 /* Create/Open a hex output file if asked */ 848 849 if (AslGbl_HexOutputFlag) 850 { 851 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_HEX_DUMP); 852 if (!Filename) 853 { 854 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME, 855 0, 0, 0, 0, NULL, NULL); 856 return (AE_ERROR); 857 } 858 859 /* Open the hex file, text mode */ 860 861 FlOpenFile (ASL_FILE_HEX_OUTPUT, Filename, "w+t"); 862 863 AslCompilerSignon (ASL_FILE_HEX_OUTPUT); 864 AslCompilerFileHeader (ASL_FILE_HEX_OUTPUT); 865 } 866 867 /* Create/Open a debug output file if asked */ 868 869 if (AslGbl_DebugFlag) 870 { 871 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_DEBUG); 872 if (!Filename) 873 { 874 AslCommonError (ASL_ERROR, ASL_MSG_DEBUG_FILENAME, 875 0, 0, 0, 0, NULL, NULL); 876 return (AE_ERROR); 877 } 878 879 /* Open the debug file as STDERR, text mode */ 880 881 AslGbl_Files[ASL_FILE_DEBUG_OUTPUT].Filename = Filename; 882 AslGbl_Files[ASL_FILE_DEBUG_OUTPUT].Handle = 883 freopen (Filename, "w+t", stderr); 884 885 if (!AslGbl_Files[ASL_FILE_DEBUG_OUTPUT].Handle) 886 { 887 /* 888 * A problem with freopen is that on error, we no longer 889 * have stderr and cannot emit normal error messages. 890 * Emit error to stdout, close files, and exit. 891 */ 892 fprintf (stdout, 893 "\nCould not open debug output file: %s\n\n", Filename); 894 895 CmCleanupAndExit (); 896 exit (1); 897 } 898 899 AslCompilerSignon (ASL_FILE_DEBUG_OUTPUT); 900 AslCompilerFileHeader (ASL_FILE_DEBUG_OUTPUT); 901 } 902 903 /* Create/Open a cross-reference output file if asked */ 904 905 if (AslGbl_CrossReferenceOutput) 906 { 907 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_XREF); 908 if (!Filename) 909 { 910 AslCommonError (ASL_ERROR, ASL_MSG_DEBUG_FILENAME, 911 0, 0, 0, 0, NULL, NULL); 912 return (AE_ERROR); 913 } 914 915 FlOpenFile (ASL_FILE_XREF_OUTPUT, Filename, "w+t"); 916 917 AslCompilerSignon (ASL_FILE_XREF_OUTPUT); 918 AslCompilerFileHeader (ASL_FILE_XREF_OUTPUT); 919 } 920 921 /* Create/Open a listing output file if asked */ 922 923 if (AslGbl_ListingFlag) 924 { 925 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_LISTING); 926 if (!Filename) 927 { 928 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME, 929 0, 0, 0, 0, NULL, NULL); 930 return (AE_ERROR); 931 } 932 933 /* Open the listing file, text mode */ 934 935 FlOpenFile (ASL_FILE_LISTING_OUTPUT, Filename, "w+t"); 936 937 AslCompilerSignon (ASL_FILE_LISTING_OUTPUT); 938 AslCompilerFileHeader (ASL_FILE_LISTING_OUTPUT); 939 } 940 941 /* Create the preprocessor output temp file if preprocessor enabled */ 942 943 if (AslGbl_PreprocessFlag) 944 { 945 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_PREPROCESSOR); 946 if (!Filename) 947 { 948 AslCommonError (ASL_ERROR, ASL_MSG_PREPROCESSOR_FILENAME, 949 0, 0, 0, 0, NULL, NULL); 950 return (AE_ERROR); 951 } 952 953 FlOpenFile (ASL_FILE_PREPROCESSOR, Filename, "w+t"); 954 } 955 956 /* 957 * Create the "user" preprocessor output file if -li flag set. 958 * Note, this file contains no embedded #line directives. 959 */ 960 if (AslGbl_PreprocessorOutputFlag) 961 { 962 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_PREPROC_USER); 963 if (!Filename) 964 { 965 AslCommonError (ASL_ERROR, ASL_MSG_PREPROCESSOR_FILENAME, 966 0, 0, 0, 0, NULL, NULL); 967 return (AE_ERROR); 968 } 969 970 FlOpenFile (ASL_FILE_PREPROCESSOR_USER, Filename, "w+t"); 971 } 972 973 /* All done for data table compiler */ 974 975 if (AslGbl_FileType == ASL_INPUT_TYPE_ASCII_DATA) 976 { 977 return (AE_OK); 978 } 979 980 /* Create/Open a combined source output file */ 981 982 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_SOURCE); 983 if (!Filename) 984 { 985 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME, 986 0, 0, 0, 0, NULL, NULL); 987 return (AE_ERROR); 988 } 989 990 /* 991 * Open the source output file, binary mode (so that LF does not get 992 * expanded to CR/LF on some systems, messing up our seek 993 * calculations.) 994 */ 995 FlOpenFile (ASL_FILE_SOURCE_OUTPUT, Filename, "w+b"); 996 997 /* 998 // TBD: TEMP 999 // AslCompilerin = AslGbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle; 1000 */ 1001 /* Create/Open a assembly code source output file if asked */ 1002 1003 if (AslGbl_AsmOutputFlag) 1004 { 1005 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_ASM_SOURCE); 1006 if (!Filename) 1007 { 1008 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME, 1009 0, 0, 0, 0, NULL, NULL); 1010 return (AE_ERROR); 1011 } 1012 1013 /* Open the assembly code source file, text mode */ 1014 1015 FlOpenFile (ASL_FILE_ASM_SOURCE_OUTPUT, Filename, "w+t"); 1016 1017 AslCompilerSignon (ASL_FILE_ASM_SOURCE_OUTPUT); 1018 AslCompilerFileHeader (ASL_FILE_ASM_SOURCE_OUTPUT); 1019 } 1020 1021 /* Create/Open a C code source output file if asked */ 1022 1023 if (AslGbl_C_OutputFlag) 1024 { 1025 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_C_SOURCE); 1026 if (!Filename) 1027 { 1028 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME, 1029 0, 0, 0, 0, NULL, NULL); 1030 return (AE_ERROR); 1031 } 1032 1033 /* Open the C code source file, text mode */ 1034 1035 FlOpenFile (ASL_FILE_C_SOURCE_OUTPUT, Filename, "w+t"); 1036 1037 FlPrintFile (ASL_FILE_C_SOURCE_OUTPUT, "/*\n"); 1038 AslCompilerSignon (ASL_FILE_C_SOURCE_OUTPUT); 1039 AslCompilerFileHeader (ASL_FILE_C_SOURCE_OUTPUT); 1040 } 1041 1042 /* Create/Open a C code source output file for the offset table if asked */ 1043 1044 if (AslGbl_C_OffsetTableFlag) 1045 { 1046 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_C_OFFSET); 1047 if (!Filename) 1048 { 1049 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME, 1050 0, 0, 0, 0, NULL, NULL); 1051 return (AE_ERROR); 1052 } 1053 1054 /* Open the C code source file, text mode */ 1055 1056 FlOpenFile (ASL_FILE_C_OFFSET_OUTPUT, Filename, "w+t"); 1057 1058 FlPrintFile (ASL_FILE_C_OFFSET_OUTPUT, "/*\n"); 1059 AslCompilerSignon (ASL_FILE_C_OFFSET_OUTPUT); 1060 AslCompilerFileHeader (ASL_FILE_C_OFFSET_OUTPUT); 1061 } 1062 1063 /* Create/Open a assembly include output file if asked */ 1064 1065 if (AslGbl_AsmIncludeOutputFlag) 1066 { 1067 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_ASM_INCLUDE); 1068 if (!Filename) 1069 { 1070 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME, 1071 0, 0, 0, 0, NULL, NULL); 1072 return (AE_ERROR); 1073 } 1074 1075 /* Open the assembly include file, text mode */ 1076 1077 FlOpenFile (ASL_FILE_ASM_INCLUDE_OUTPUT, Filename, "w+t"); 1078 1079 AslCompilerSignon (ASL_FILE_ASM_INCLUDE_OUTPUT); 1080 AslCompilerFileHeader (ASL_FILE_ASM_INCLUDE_OUTPUT); 1081 } 1082 1083 /* Create/Open a C include output file if asked */ 1084 1085 if (AslGbl_C_IncludeOutputFlag) 1086 { 1087 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_C_INCLUDE); 1088 if (!Filename) 1089 { 1090 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME, 1091 0, 0, 0, 0, NULL, NULL); 1092 return (AE_ERROR); 1093 } 1094 1095 /* Open the C include file, text mode */ 1096 1097 FlOpenFile (ASL_FILE_C_INCLUDE_OUTPUT, Filename, "w+t"); 1098 1099 FlPrintFile (ASL_FILE_C_INCLUDE_OUTPUT, "/*\n"); 1100 AslCompilerSignon (ASL_FILE_C_INCLUDE_OUTPUT); 1101 AslCompilerFileHeader (ASL_FILE_C_INCLUDE_OUTPUT); 1102 } 1103 1104 /* Create a namespace output file if asked */ 1105 1106 if (AslGbl_NsOutputFlag) 1107 { 1108 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_NAMESPACE); 1109 if (!Filename) 1110 { 1111 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME, 1112 0, 0, 0, 0, NULL, NULL); 1113 return (AE_ERROR); 1114 } 1115 1116 /* Open the namespace file, text mode */ 1117 1118 FlOpenFile (ASL_FILE_NAMESPACE_OUTPUT, Filename, "w+t"); 1119 1120 AslCompilerSignon (ASL_FILE_NAMESPACE_OUTPUT); 1121 AslCompilerFileHeader (ASL_FILE_NAMESPACE_OUTPUT); 1122 } 1123 1124 /* Create a debug file for the converter */ 1125 1126 if (AcpiGbl_DebugAslConversion) 1127 { 1128 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_CONVERT_DEBUG); 1129 if (!Filename) 1130 { 1131 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME, 1132 0, 0, 0, 0, NULL, NULL); 1133 return (AE_ERROR); 1134 } 1135 1136 /* Open the converter debug file, text mode */ 1137 1138 FlOpenFile (ASL_FILE_CONV_DEBUG_OUTPUT, Filename, "w+t"); 1139 1140 AslCompilerSignon (ASL_FILE_CONV_DEBUG_OUTPUT); 1141 AslCompilerFileHeader (ASL_FILE_CONV_DEBUG_OUTPUT); 1142 1143 AcpiGbl_ConvDebugFile = AslGbl_Files[ASL_FILE_CONV_DEBUG_OUTPUT].Handle; 1144 } 1145 1146 return (AE_OK); 1147 } 1148 1149 1150 #ifdef ACPI_OBSOLETE_FUNCTIONS 1151 /******************************************************************************* 1152 * 1153 * FUNCTION: FlParseInputPathname 1154 * 1155 * PARAMETERS: InputFilename - The user-specified ASL source file to be 1156 * compiled 1157 * 1158 * RETURN: Status 1159 * 1160 * DESCRIPTION: Split the input path into a directory and filename part 1161 * 1) Directory part used to open include files 1162 * 2) Filename part used to generate output filenames 1163 * 1164 ******************************************************************************/ 1165 1166 ACPI_STATUS 1167 FlParseInputPathname ( 1168 char *InputFilename) 1169 { 1170 char *Substring; 1171 1172 1173 if (!InputFilename) 1174 { 1175 return (AE_OK); 1176 } 1177 1178 /* Get the path to the input filename's directory */ 1179 1180 AslGbl_DirectoryPath = strdup (InputFilename); 1181 if (!AslGbl_DirectoryPath) 1182 { 1183 return (AE_NO_MEMORY); 1184 } 1185 1186 Substring = strrchr (AslGbl_DirectoryPath, '\\'); 1187 if (!Substring) 1188 { 1189 Substring = strrchr (AslGbl_DirectoryPath, '/'); 1190 if (!Substring) 1191 { 1192 Substring = strrchr (AslGbl_DirectoryPath, ':'); 1193 } 1194 } 1195 1196 if (!Substring) 1197 { 1198 AslGbl_DirectoryPath[0] = 0; 1199 if (AslGbl_UseDefaultAmlFilename) 1200 { 1201 AslGbl_OutputFilenamePrefix = strdup (InputFilename); 1202 } 1203 } 1204 else 1205 { 1206 if (AslGbl_UseDefaultAmlFilename) 1207 { 1208 AslGbl_OutputFilenamePrefix = strdup (Substring + 1); 1209 } 1210 *(Substring+1) = 0; 1211 } 1212 1213 UtConvertBackslashes (AslGbl_OutputFilenamePrefix); 1214 return (AE_OK); 1215 } 1216 #endif 1217