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