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