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