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