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