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