1 /****************************************************************************** 2 * 3 * Module Name: aslfiles - File support functions 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2023, 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 (!((Current->FileType == ASL_INPUT_TYPE_ASCII_DATA) && 242 (InFileId == ASL_FILE_SOURCE_OUTPUT)) && 243 !strcmp (Current->Files[InFileId].Filename, Filename)) 244 { 245 return (Current->Files[OutFileId].Handle); 246 } 247 248 Current = Current->Next; 249 } 250 251 return (NULL); 252 } 253 254 255 /******************************************************************************* 256 * 257 * FUNCTION: FlGetFileNode 258 * 259 * PARAMETERS: FileId - File type (ID) of the input Filename 260 * Filename - File to search for 261 * 262 * RETURN: A global file node 263 * 264 * DESCRIPTION: Get the file node for a particular filename/FileId. 265 * 266 ******************************************************************************/ 267 268 ASL_GLOBAL_FILE_NODE * 269 FlGetFileNode ( 270 UINT32 FileId, 271 char *Filename) 272 { 273 ASL_GLOBAL_FILE_NODE *Current = AslGbl_FilesList; 274 275 276 if (!Filename) 277 { 278 return (NULL); 279 } 280 281 while (Current) 282 { 283 if (!strcmp (Current->Files[FileId].Filename, Filename)) 284 { 285 return (Current); 286 } 287 288 Current = Current->Next; 289 } 290 291 return (NULL); 292 } 293 294 295 /******************************************************************************* 296 * 297 * FUNCTION: FlGetCurrentFileNode 298 * 299 * PARAMETERS: None 300 * 301 * RETURN: Global file node 302 * 303 * DESCRIPTION: Get the current input file node 304 * 305 ******************************************************************************/ 306 307 ASL_GLOBAL_FILE_NODE * 308 FlGetCurrentFileNode ( 309 void) 310 { 311 ASL_GLOBAL_FILE_NODE *FileNode = 312 FlGetFileNode (ASL_FILE_INPUT,AslGbl_Files[ASL_FILE_INPUT].Filename); 313 314 315 if (!FileNode) 316 { 317 /* 318 * If the current file node does not exist after initializing the file 319 * node structures, something went wrong and this is an unrecoverable 320 * condition. 321 */ 322 FlFileError (ASL_FILE_INPUT, ASL_MSG_COMPILER_INTERNAL); 323 AslAbort (); 324 } 325 326 return (FileNode); 327 } 328 329 330 /******************************************************************************* 331 * 332 * FUNCTION: FlSetLineNumber 333 * 334 * PARAMETERS: Op - Parse node for the LINE asl statement 335 * 336 * RETURN: None. 337 * 338 * DESCRIPTION: Set the current line number 339 * 340 ******************************************************************************/ 341 342 void 343 FlSetLineNumber ( 344 UINT32 LineNumber) 345 { 346 347 DbgPrint (ASL_PARSE_OUTPUT, "\n#line: New line number %u (old %u)\n", 348 LineNumber, AslGbl_LogicalLineNumber); 349 350 AslGbl_CurrentLineNumber = LineNumber; 351 } 352 353 354 /******************************************************************************* 355 * 356 * FUNCTION: FlSetFilename 357 * 358 * PARAMETERS: Op - Parse node for the LINE asl statement 359 * 360 * RETURN: None. 361 * 362 * DESCRIPTION: Set the current filename 363 * 364 ******************************************************************************/ 365 366 void 367 FlSetFilename ( 368 char *Filename) 369 { 370 371 DbgPrint (ASL_PARSE_OUTPUT, "\n#line: New filename %s (old %s)\n", 372 Filename, AslGbl_Files[ASL_FILE_INPUT].Filename); 373 374 /* No need to free any existing filename */ 375 376 AslGbl_Files[ASL_FILE_INPUT].Filename = Filename; 377 } 378 379 380 /******************************************************************************* 381 * 382 * FUNCTION: FlAddIncludeDirectory 383 * 384 * PARAMETERS: Dir - Directory pathname string 385 * 386 * RETURN: None 387 * 388 * DESCRIPTION: Add a directory the list of include prefix directories. 389 * 390 ******************************************************************************/ 391 392 void 393 FlAddIncludeDirectory ( 394 char *Dir) 395 { 396 ASL_INCLUDE_DIR *NewDir; 397 ASL_INCLUDE_DIR *NextDir; 398 ASL_INCLUDE_DIR *PrevDir = NULL; 399 UINT32 NeedsSeparator = 0; 400 size_t DirLength; 401 402 403 DirLength = strlen (Dir); 404 if (!DirLength) 405 { 406 return; 407 } 408 409 /* Make sure that the pathname ends with a path separator */ 410 411 if ((Dir[DirLength-1] != '/') && 412 (Dir[DirLength-1] != '\\')) 413 { 414 NeedsSeparator = 1; 415 } 416 417 NewDir = ACPI_CAST_PTR (ASL_INCLUDE_DIR, 418 UtLocalCacheCalloc (sizeof (ASL_INCLUDE_DIR))); 419 NewDir->Dir = UtLocalCacheCalloc (DirLength + 1 + NeedsSeparator); 420 strcpy (NewDir->Dir, Dir); 421 if (NeedsSeparator) 422 { 423 strcat (NewDir->Dir, "/"); 424 } 425 426 /* 427 * Preserve command line ordering of -I options by adding new elements 428 * at the end of the list 429 */ 430 NextDir = AslGbl_IncludeDirList; 431 while (NextDir) 432 { 433 PrevDir = NextDir; 434 NextDir = NextDir->Next; 435 } 436 437 if (PrevDir) 438 { 439 PrevDir->Next = NewDir; 440 } 441 else 442 { 443 AslGbl_IncludeDirList = NewDir; 444 } 445 } 446 447 448 /******************************************************************************* 449 * 450 * FUNCTION: FlMergePathnames 451 * 452 * PARAMETERS: PrefixDir - Prefix directory pathname. Can be NULL or 453 * a zero length string. 454 * FilePathname - The include filename from the source ASL. 455 * 456 * RETURN: Merged pathname string 457 * 458 * DESCRIPTION: Merge two pathnames that (probably) have common elements, to 459 * arrive at a minimal length string. Merge can occur if the 460 * FilePathname is relative to the PrefixDir. 461 * 462 ******************************************************************************/ 463 464 char * 465 FlMergePathnames ( 466 char *PrefixDir, 467 char *FilePathname) 468 { 469 char *CommonPath; 470 char *Pathname; 471 char *LastElement; 472 473 474 DbgPrint (ASL_PARSE_OUTPUT, "Include: Prefix path - \"%s\"\n" 475 "Include: FilePathname - \"%s\"\n", 476 PrefixDir, FilePathname); 477 478 /* 479 * If there is no prefix directory or if the file pathname is absolute, 480 * just return the original file pathname 481 */ 482 if (!PrefixDir || (!*PrefixDir) || 483 (*FilePathname == '/') || 484 (FilePathname[1] == ':')) 485 { 486 Pathname = UtLocalCacheCalloc (strlen (FilePathname) + 1); 487 strcpy (Pathname, FilePathname); 488 goto ConvertBackslashes; 489 } 490 491 /* Need a local copy of the prefix directory path */ 492 493 CommonPath = UtLocalCacheCalloc (strlen (PrefixDir) + 1); 494 strcpy (CommonPath, PrefixDir); 495 496 /* 497 * Walk forward through the file path, and simultaneously backward 498 * through the prefix directory path until there are no more 499 * relative references at the start of the file path. 500 */ 501 while (*FilePathname && (!strncmp (FilePathname, "../", 3))) 502 { 503 /* Remove last element of the prefix directory path */ 504 505 LastElement = strrchr (CommonPath, '/'); 506 if (!LastElement) 507 { 508 goto ConcatenatePaths; 509 } 510 511 *LastElement = 0; /* Terminate CommonPath string */ 512 FilePathname += 3; /* Point to next path element */ 513 } 514 515 /* 516 * Remove the last element of the prefix directory path (it is the same as 517 * the first element of the file pathname), and build the final merged 518 * pathname. 519 */ 520 LastElement = strrchr (CommonPath, '/'); 521 if (LastElement) 522 { 523 *LastElement = 0; 524 } 525 526 /* Build the final merged pathname */ 527 528 ConcatenatePaths: 529 Pathname = UtLocalCacheCalloc ( 530 strlen (CommonPath) + strlen (FilePathname) + 2); 531 if (LastElement && *CommonPath) 532 { 533 strcpy (Pathname, CommonPath); 534 strcat (Pathname, "/"); 535 } 536 strcat (Pathname, FilePathname); 537 538 /* Convert all backslashes to normal slashes */ 539 540 ConvertBackslashes: 541 UtConvertBackslashes (Pathname); 542 543 DbgPrint (ASL_PARSE_OUTPUT, "Include: Merged Pathname - \"%s\"\n", 544 Pathname); 545 return (Pathname); 546 } 547 548 549 /******************************************************************************* 550 * 551 * FUNCTION: FlOpenIncludeWithPrefix 552 * 553 * PARAMETERS: PrefixDir - Prefix directory pathname. Can be a zero 554 * length string. 555 * Filename - The include filename from the source ASL. 556 * 557 * RETURN: Valid file descriptor if successful. Null otherwise. 558 * 559 * DESCRIPTION: Open an include file and push it on the input file stack. 560 * 561 ******************************************************************************/ 562 563 static FILE * 564 FlOpenIncludeWithPrefix ( 565 char *PrefixDir, 566 ACPI_PARSE_OBJECT *Op, 567 char *Filename) 568 { 569 FILE *IncludeFile; 570 char *Pathname; 571 UINT32 OriginalLineNumber; 572 573 574 /* Build the full pathname to the file */ 575 576 Pathname = FlMergePathnames (PrefixDir, Filename); 577 578 DbgPrint (ASL_PARSE_OUTPUT, "Include: Opening file - \"%s\"\n\n", 579 Pathname); 580 581 /* Attempt to open the file, push if successful */ 582 583 IncludeFile = fopen (Pathname, "r"); 584 if (!IncludeFile) 585 { 586 return (NULL); 587 } 588 589 /* 590 * Check the entire include file for any # preprocessor directives. 591 * This is because there may be some confusion between the #include 592 * preprocessor directive and the ASL Include statement. A file included 593 * by the ASL include cannot contain preprocessor directives because 594 * the preprocessor has already run by the time the ASL include is 595 * recognized (by the compiler, not the preprocessor.) 596 * 597 * Note: DtGetNextLine strips/ignores comments. 598 * Save current line number since DtGetNextLine modifies it. 599 */ 600 AslGbl_CurrentLineNumber--; 601 OriginalLineNumber = AslGbl_CurrentLineNumber; 602 603 while (DtGetNextLine (IncludeFile, DT_ALLOW_MULTILINE_QUOTES) != ASL_EOF) 604 { 605 if (AslGbl_CurrentLineBuffer[0] == '#') 606 { 607 AslError (ASL_ERROR, ASL_MSG_INCLUDE_FILE, 608 Op, "use #include instead"); 609 } 610 } 611 612 AslGbl_CurrentLineNumber = OriginalLineNumber; 613 614 /* Must seek back to the start of the file */ 615 616 fseek (IncludeFile, 0, SEEK_SET); 617 618 /* Push the include file on the open input file stack */ 619 620 AslPushInputFileStack (IncludeFile, Pathname); 621 return (IncludeFile); 622 } 623 624 625 /******************************************************************************* 626 * 627 * FUNCTION: FlOpenIncludeFile 628 * 629 * PARAMETERS: Op - Parse node for the INCLUDE ASL statement 630 * 631 * RETURN: None. 632 * 633 * DESCRIPTION: Open an include file and push it on the input file stack. 634 * 635 ******************************************************************************/ 636 637 void 638 FlOpenIncludeFile ( 639 ACPI_PARSE_OBJECT *Op) 640 { 641 FILE *IncludeFile; 642 ASL_INCLUDE_DIR *NextDir; 643 644 645 /* Op must be valid */ 646 647 if (!Op) 648 { 649 AslCommonError (ASL_ERROR, ASL_MSG_INCLUDE_FILE_OPEN, 650 AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber, 651 AslGbl_InputByteCount, AslGbl_CurrentColumn, 652 AslGbl_Files[ASL_FILE_INPUT].Filename, " - Null parse node"); 653 654 return; 655 } 656 657 /* 658 * Flush out the "include ()" statement on this line, start 659 * the actual include file on the next line 660 */ 661 AslResetCurrentLineBuffer (); 662 FlPrintFile (ASL_FILE_SOURCE_OUTPUT, "\n"); 663 AslGbl_CurrentLineOffset++; 664 665 666 /* Attempt to open the include file */ 667 668 /* If the file specifies an absolute path, just open it */ 669 670 if ((Op->Asl.Value.String[0] == '/') || 671 (Op->Asl.Value.String[0] == '\\') || 672 (Op->Asl.Value.String[1] == ':')) 673 { 674 IncludeFile = FlOpenIncludeWithPrefix ("", Op, Op->Asl.Value.String); 675 if (!IncludeFile) 676 { 677 goto ErrorExit; 678 } 679 return; 680 } 681 682 /* 683 * The include filename is not an absolute path. 684 * 685 * First, search for the file within the "local" directory -- meaning 686 * the same directory that contains the source file. 687 * 688 * Construct the file pathname from the global directory name. 689 */ 690 IncludeFile = FlOpenIncludeWithPrefix ( 691 AslGbl_DirectoryPath, Op, Op->Asl.Value.String); 692 if (IncludeFile) 693 { 694 return; 695 } 696 697 /* 698 * Second, search for the file within the (possibly multiple) directories 699 * specified by the -I option on the command line. 700 */ 701 NextDir = AslGbl_IncludeDirList; 702 while (NextDir) 703 { 704 IncludeFile = FlOpenIncludeWithPrefix ( 705 NextDir->Dir, Op, Op->Asl.Value.String); 706 if (IncludeFile) 707 { 708 return; 709 } 710 711 NextDir = NextDir->Next; 712 } 713 714 /* We could not open the include file after trying very hard */ 715 716 ErrorExit: 717 snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "%s, %s", Op->Asl.Value.String, strerror (errno)); 718 AslError (ASL_ERROR, ASL_MSG_INCLUDE_FILE_OPEN, Op, AslGbl_MsgBuffer); 719 } 720 721 722 /******************************************************************************* 723 * 724 * FUNCTION: FlOpenInputFile 725 * 726 * PARAMETERS: InputFilename - The user-specified ASL source file to be 727 * compiled 728 * 729 * RETURN: Status 730 * 731 * DESCRIPTION: Open the specified input file, and save the directory path to 732 * the file so that include files can be opened in the same 733 * directory. NOTE: File is opened in text mode. 734 * 735 ******************************************************************************/ 736 737 ACPI_STATUS 738 FlOpenInputFile ( 739 char *InputFilename) 740 { 741 742 /* Open the input ASL file, text mode */ 743 744 FlOpenFile (ASL_FILE_INPUT, InputFilename, "rt"); 745 AslCompilerin = AslGbl_Files[ASL_FILE_INPUT].Handle; 746 747 return (AE_OK); 748 } 749 750 751 /******************************************************************************* 752 * 753 * FUNCTION: FlOpenAmlOutputFile 754 * 755 * PARAMETERS: FilenamePrefix - The user-specified ASL source file 756 * 757 * RETURN: Status 758 * 759 * DESCRIPTION: Create the output filename (*.AML) and open the file. The file 760 * is created in the same directory as the parent input file. 761 * 762 ******************************************************************************/ 763 764 ACPI_STATUS 765 FlOpenAmlOutputFile ( 766 char *FilenamePrefix) 767 { 768 char *Filename; 769 770 771 /* Output filename usually comes from the ASL itself */ 772 773 Filename = AslGbl_Files[ASL_FILE_AML_OUTPUT].Filename; 774 if (!Filename) 775 { 776 /* Create the output AML filename */ 777 if (!AcpiGbl_CaptureComments) 778 { 779 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_AML_CODE); 780 } 781 else 782 { 783 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_CONVERT_AML); 784 } 785 if (!Filename) 786 { 787 AslCommonError (ASL_ERROR, ASL_MSG_OUTPUT_FILENAME, 788 0, 0, 0, 0, NULL, NULL); 789 return (AE_ERROR); 790 } 791 792 AslGbl_Files[ASL_FILE_AML_OUTPUT].Filename = Filename; 793 } 794 795 /* Open the output AML file in binary mode */ 796 797 FlOpenFile (ASL_FILE_AML_OUTPUT, Filename, "w+b"); 798 return (AE_OK); 799 } 800 801 802 /******************************************************************************* 803 * 804 * FUNCTION: FlOpenMiscOutputFiles 805 * 806 * PARAMETERS: FilenamePrefix - The user-specified ASL source file 807 * 808 * RETURN: Status 809 * 810 * DESCRIPTION: Create and open the various output files needed, depending on 811 * the command line options 812 * 813 ******************************************************************************/ 814 815 ACPI_STATUS 816 FlOpenMiscOutputFiles ( 817 char *FilenamePrefix) 818 { 819 char *Filename; 820 821 822 /* Create/Open a map file if requested */ 823 824 if (AslGbl_MapfileFlag) 825 { 826 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_MAP); 827 if (!Filename) 828 { 829 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME, 830 0, 0, 0, 0, NULL, NULL); 831 return (AE_ERROR); 832 } 833 834 /* Open the hex file, text mode (closed at compiler exit) */ 835 836 FlOpenFile (ASL_FILE_MAP_OUTPUT, Filename, "w+t"); 837 838 AslCompilerSignon (ASL_FILE_MAP_OUTPUT); 839 AslCompilerFileHeader (ASL_FILE_MAP_OUTPUT); 840 } 841 842 /* All done for disassembler */ 843 844 if (AslGbl_FileType == ASL_INPUT_TYPE_BINARY_ACPI_TABLE) 845 { 846 return (AE_OK); 847 } 848 849 /* Create/Open a hex output file if asked */ 850 851 if (AslGbl_HexOutputFlag) 852 { 853 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_HEX_DUMP); 854 if (!Filename) 855 { 856 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME, 857 0, 0, 0, 0, NULL, NULL); 858 return (AE_ERROR); 859 } 860 861 /* Open the hex file, text mode */ 862 863 FlOpenFile (ASL_FILE_HEX_OUTPUT, Filename, "w+t"); 864 865 AslCompilerSignon (ASL_FILE_HEX_OUTPUT); 866 AslCompilerFileHeader (ASL_FILE_HEX_OUTPUT); 867 } 868 869 /* Create/Open a debug output file if asked */ 870 871 if (AslGbl_DebugFlag) 872 { 873 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_DEBUG); 874 if (!Filename) 875 { 876 AslCommonError (ASL_ERROR, ASL_MSG_DEBUG_FILENAME, 877 0, 0, 0, 0, NULL, NULL); 878 return (AE_ERROR); 879 } 880 881 /* Open the debug file as STDERR, text mode */ 882 883 AslGbl_Files[ASL_FILE_DEBUG_OUTPUT].Filename = Filename; 884 AslGbl_Files[ASL_FILE_DEBUG_OUTPUT].Handle = 885 freopen (Filename, "w+t", stderr); 886 887 if (!AslGbl_Files[ASL_FILE_DEBUG_OUTPUT].Handle) 888 { 889 /* 890 * A problem with freopen is that on error, we no longer 891 * have stderr and cannot emit normal error messages. 892 * Emit error to stdout, close files, and exit. 893 */ 894 fprintf (stdout, 895 "\nCould not open debug output file: %s\n\n", Filename); 896 897 CmCleanupAndExit (); 898 exit (1); 899 } 900 901 AslCompilerSignon (ASL_FILE_DEBUG_OUTPUT); 902 AslCompilerFileHeader (ASL_FILE_DEBUG_OUTPUT); 903 } 904 905 /* Create/Open a cross-reference output file if asked */ 906 907 if (AslGbl_CrossReferenceOutput) 908 { 909 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_XREF); 910 if (!Filename) 911 { 912 AslCommonError (ASL_ERROR, ASL_MSG_DEBUG_FILENAME, 913 0, 0, 0, 0, NULL, NULL); 914 return (AE_ERROR); 915 } 916 917 FlOpenFile (ASL_FILE_XREF_OUTPUT, Filename, "w+t"); 918 919 AslCompilerSignon (ASL_FILE_XREF_OUTPUT); 920 AslCompilerFileHeader (ASL_FILE_XREF_OUTPUT); 921 } 922 923 /* Create/Open a listing output file if asked */ 924 925 if (AslGbl_ListingFlag) 926 { 927 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_LISTING); 928 if (!Filename) 929 { 930 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME, 931 0, 0, 0, 0, NULL, NULL); 932 return (AE_ERROR); 933 } 934 935 /* Open the listing file, text mode */ 936 937 FlOpenFile (ASL_FILE_LISTING_OUTPUT, Filename, "w+t"); 938 939 AslCompilerSignon (ASL_FILE_LISTING_OUTPUT); 940 AslCompilerFileHeader (ASL_FILE_LISTING_OUTPUT); 941 } 942 943 /* Create the preprocessor output temp file if preprocessor enabled */ 944 945 if (AslGbl_PreprocessFlag) 946 { 947 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_PREPROCESSOR); 948 if (!Filename) 949 { 950 AslCommonError (ASL_ERROR, ASL_MSG_PREPROCESSOR_FILENAME, 951 0, 0, 0, 0, NULL, NULL); 952 return (AE_ERROR); 953 } 954 955 FlOpenFile (ASL_FILE_PREPROCESSOR, Filename, "w+t"); 956 } 957 958 /* 959 * Create the "user" preprocessor output file if -li flag set. 960 * Note, this file contains no embedded #line directives. 961 */ 962 if (AslGbl_PreprocessorOutputFlag) 963 { 964 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_PREPROC_USER); 965 if (!Filename) 966 { 967 AslCommonError (ASL_ERROR, ASL_MSG_PREPROCESSOR_FILENAME, 968 0, 0, 0, 0, NULL, NULL); 969 return (AE_ERROR); 970 } 971 972 FlOpenFile (ASL_FILE_PREPROCESSOR_USER, Filename, "w+t"); 973 } 974 975 /* All done for data table compiler */ 976 977 if (AslGbl_FileType == ASL_INPUT_TYPE_ASCII_DATA) 978 { 979 return (AE_OK); 980 } 981 982 /* Create/Open a combined source output file */ 983 984 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_SOURCE); 985 if (!Filename) 986 { 987 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME, 988 0, 0, 0, 0, NULL, NULL); 989 return (AE_ERROR); 990 } 991 992 /* 993 * Open the source output file, binary mode (so that LF does not get 994 * expanded to CR/LF on some systems, messing up our seek 995 * calculations.) 996 */ 997 FlOpenFile (ASL_FILE_SOURCE_OUTPUT, Filename, "w+b"); 998 999 /* 1000 // TBD: TEMP 1001 // AslCompilerin = AslGbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle; 1002 */ 1003 /* Create/Open a assembly code source output file if asked */ 1004 1005 if (AslGbl_AsmOutputFlag) 1006 { 1007 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_ASM_SOURCE); 1008 if (!Filename) 1009 { 1010 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME, 1011 0, 0, 0, 0, NULL, NULL); 1012 return (AE_ERROR); 1013 } 1014 1015 /* Open the assembly code source file, text mode */ 1016 1017 FlOpenFile (ASL_FILE_ASM_SOURCE_OUTPUT, Filename, "w+t"); 1018 1019 AslCompilerSignon (ASL_FILE_ASM_SOURCE_OUTPUT); 1020 AslCompilerFileHeader (ASL_FILE_ASM_SOURCE_OUTPUT); 1021 } 1022 1023 /* Create/Open a C code source output file if asked */ 1024 1025 if (AslGbl_C_OutputFlag) 1026 { 1027 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_C_SOURCE); 1028 if (!Filename) 1029 { 1030 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME, 1031 0, 0, 0, 0, NULL, NULL); 1032 return (AE_ERROR); 1033 } 1034 1035 /* Open the C code source file, text mode */ 1036 1037 FlOpenFile (ASL_FILE_C_SOURCE_OUTPUT, Filename, "w+t"); 1038 1039 FlPrintFile (ASL_FILE_C_SOURCE_OUTPUT, "/*\n"); 1040 AslCompilerSignon (ASL_FILE_C_SOURCE_OUTPUT); 1041 AslCompilerFileHeader (ASL_FILE_C_SOURCE_OUTPUT); 1042 } 1043 1044 /* Create/Open a C code source output file for the offset table if asked */ 1045 1046 if (AslGbl_C_OffsetTableFlag) 1047 { 1048 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_C_OFFSET); 1049 if (!Filename) 1050 { 1051 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME, 1052 0, 0, 0, 0, NULL, NULL); 1053 return (AE_ERROR); 1054 } 1055 1056 /* Open the C code source file, text mode */ 1057 1058 FlOpenFile (ASL_FILE_C_OFFSET_OUTPUT, Filename, "w+t"); 1059 1060 FlPrintFile (ASL_FILE_C_OFFSET_OUTPUT, "/*\n"); 1061 AslCompilerSignon (ASL_FILE_C_OFFSET_OUTPUT); 1062 AslCompilerFileHeader (ASL_FILE_C_OFFSET_OUTPUT); 1063 } 1064 1065 /* Create/Open a assembly include output file if asked */ 1066 1067 if (AslGbl_AsmIncludeOutputFlag) 1068 { 1069 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_ASM_INCLUDE); 1070 if (!Filename) 1071 { 1072 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME, 1073 0, 0, 0, 0, NULL, NULL); 1074 return (AE_ERROR); 1075 } 1076 1077 /* Open the assembly include file, text mode */ 1078 1079 FlOpenFile (ASL_FILE_ASM_INCLUDE_OUTPUT, Filename, "w+t"); 1080 1081 AslCompilerSignon (ASL_FILE_ASM_INCLUDE_OUTPUT); 1082 AslCompilerFileHeader (ASL_FILE_ASM_INCLUDE_OUTPUT); 1083 } 1084 1085 /* Create/Open a C include output file if asked */ 1086 1087 if (AslGbl_C_IncludeOutputFlag) 1088 { 1089 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_C_INCLUDE); 1090 if (!Filename) 1091 { 1092 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME, 1093 0, 0, 0, 0, NULL, NULL); 1094 return (AE_ERROR); 1095 } 1096 1097 /* Open the C include file, text mode */ 1098 1099 FlOpenFile (ASL_FILE_C_INCLUDE_OUTPUT, Filename, "w+t"); 1100 1101 FlPrintFile (ASL_FILE_C_INCLUDE_OUTPUT, "/*\n"); 1102 AslCompilerSignon (ASL_FILE_C_INCLUDE_OUTPUT); 1103 AslCompilerFileHeader (ASL_FILE_C_INCLUDE_OUTPUT); 1104 } 1105 1106 /* Create a namespace output file if asked */ 1107 1108 if (AslGbl_NsOutputFlag) 1109 { 1110 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_NAMESPACE); 1111 if (!Filename) 1112 { 1113 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME, 1114 0, 0, 0, 0, NULL, NULL); 1115 return (AE_ERROR); 1116 } 1117 1118 /* Open the namespace file, text mode */ 1119 1120 FlOpenFile (ASL_FILE_NAMESPACE_OUTPUT, Filename, "w+t"); 1121 1122 AslCompilerSignon (ASL_FILE_NAMESPACE_OUTPUT); 1123 AslCompilerFileHeader (ASL_FILE_NAMESPACE_OUTPUT); 1124 } 1125 1126 /* Create a debug file for the converter */ 1127 1128 if (AcpiGbl_DebugAslConversion) 1129 { 1130 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_CONVERT_DEBUG); 1131 if (!Filename) 1132 { 1133 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME, 1134 0, 0, 0, 0, NULL, NULL); 1135 return (AE_ERROR); 1136 } 1137 1138 /* Open the converter debug file, text mode */ 1139 1140 FlOpenFile (ASL_FILE_CONV_DEBUG_OUTPUT, Filename, "w+t"); 1141 1142 AslCompilerSignon (ASL_FILE_CONV_DEBUG_OUTPUT); 1143 AslCompilerFileHeader (ASL_FILE_CONV_DEBUG_OUTPUT); 1144 1145 AcpiGbl_ConvDebugFile = AslGbl_Files[ASL_FILE_CONV_DEBUG_OUTPUT].Handle; 1146 } 1147 1148 return (AE_OK); 1149 } 1150 1151 1152 #ifdef ACPI_OBSOLETE_FUNCTIONS 1153 /******************************************************************************* 1154 * 1155 * FUNCTION: FlParseInputPathname 1156 * 1157 * PARAMETERS: InputFilename - The user-specified ASL source file to be 1158 * compiled 1159 * 1160 * RETURN: Status 1161 * 1162 * DESCRIPTION: Split the input path into a directory and filename part 1163 * 1) Directory part used to open include files 1164 * 2) Filename part used to generate output filenames 1165 * 1166 ******************************************************************************/ 1167 1168 ACPI_STATUS 1169 FlParseInputPathname ( 1170 char *InputFilename) 1171 { 1172 char *Substring; 1173 1174 1175 if (!InputFilename) 1176 { 1177 return (AE_OK); 1178 } 1179 1180 /* Get the path to the input filename's directory */ 1181 1182 AslGbl_DirectoryPath = strdup (InputFilename); 1183 if (!AslGbl_DirectoryPath) 1184 { 1185 return (AE_NO_MEMORY); 1186 } 1187 1188 Substring = strrchr (AslGbl_DirectoryPath, '\\'); 1189 if (!Substring) 1190 { 1191 Substring = strrchr (AslGbl_DirectoryPath, '/'); 1192 if (!Substring) 1193 { 1194 Substring = strrchr (AslGbl_DirectoryPath, ':'); 1195 } 1196 } 1197 1198 if (!Substring) 1199 { 1200 AslGbl_DirectoryPath[0] = 0; 1201 if (AslGbl_UseDefaultAmlFilename) 1202 { 1203 AslGbl_OutputFilenamePrefix = strdup (InputFilename); 1204 } 1205 } 1206 else 1207 { 1208 if (AslGbl_UseDefaultAmlFilename) 1209 { 1210 AslGbl_OutputFilenamePrefix = strdup (Substring + 1); 1211 } 1212 *(Substring+1) = 0; 1213 } 1214 1215 UtConvertBackslashes (AslGbl_OutputFilenamePrefix); 1216 return (AE_OK); 1217 } 1218 #endif 1219