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