1118611Snjl/******************************************************************************
2118611Snjl *
3245582Sjkim * Module Name: aslfiles - File support functions
4118611Snjl *
5118611Snjl *****************************************************************************/
6118611Snjl
7217365Sjkim/*
8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
9118611Snjl * All rights reserved.
10118611Snjl *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
25118611Snjl *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
29118611Snjl *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
43118611Snjl
44151937Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
45193529Sjkim#include <contrib/dev/acpica/include/acapps.h>
46306536Sjkim#include <contrib/dev/acpica/compiler/dtcompiler.h>
47118611Snjl
48118611Snjl#define _COMPONENT          ACPI_COMPILER
49118611Snjl        ACPI_MODULE_NAME    ("aslfiles")
50118611Snjl
51151937Sjkim/* Local prototypes */
52118611Snjl
53284460Sjkimstatic FILE *
54197104SjkimFlOpenIncludeWithPrefix (
55197104Sjkim    char                    *PrefixDir,
56284460Sjkim    ACPI_PARSE_OBJECT       *Op,
57197104Sjkim    char                    *Filename);
58151937Sjkim
59151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS
60151937SjkimACPI_STATUS
61151937SjkimFlParseInputPathname (
62151937Sjkim    char                    *InputFilename);
63151937Sjkim#endif
64151937Sjkim
65151937Sjkim
66118611Snjl/*******************************************************************************
67118611Snjl *
68118611Snjl * FUNCTION:    FlSetLineNumber
69118611Snjl *
70118611Snjl * PARAMETERS:  Op        - Parse node for the LINE asl statement
71118611Snjl *
72118611Snjl * RETURN:      None.
73118611Snjl *
74118611Snjl * DESCRIPTION: Set the current line number
75118611Snjl *
76118611Snjl ******************************************************************************/
77118611Snjl
78118611Snjlvoid
79118611SnjlFlSetLineNumber (
80234623Sjkim    UINT32                  LineNumber)
81118611Snjl{
82118611Snjl
83234623Sjkim    DbgPrint (ASL_PARSE_OUTPUT, "\n#line: New line number %u (old %u)\n",
84234623Sjkim         LineNumber, Gbl_LogicalLineNumber);
85234623Sjkim
86234623Sjkim    Gbl_CurrentLineNumber = LineNumber;
87118611Snjl}
88118611Snjl
89118611Snjl
90118611Snjl/*******************************************************************************
91118611Snjl *
92234623Sjkim * FUNCTION:    FlSetFilename
93234623Sjkim *
94234623Sjkim * PARAMETERS:  Op        - Parse node for the LINE asl statement
95234623Sjkim *
96234623Sjkim * RETURN:      None.
97234623Sjkim *
98234623Sjkim * DESCRIPTION: Set the current filename
99234623Sjkim *
100234623Sjkim ******************************************************************************/
101234623Sjkim
102234623Sjkimvoid
103234623SjkimFlSetFilename (
104234623Sjkim    char                    *Filename)
105234623Sjkim{
106234623Sjkim
107234623Sjkim    DbgPrint (ASL_PARSE_OUTPUT, "\n#line: New filename %s (old %s)\n",
108234623Sjkim         Filename, Gbl_Files[ASL_FILE_INPUT].Filename);
109234623Sjkim
110281075Sdim    /* No need to free any existing filename */
111281075Sdim
112234623Sjkim    Gbl_Files[ASL_FILE_INPUT].Filename = Filename;
113234623Sjkim}
114234623Sjkim
115234623Sjkim
116234623Sjkim/*******************************************************************************
117234623Sjkim *
118197104Sjkim * FUNCTION:    FlAddIncludeDirectory
119197104Sjkim *
120197104Sjkim * PARAMETERS:  Dir             - Directory pathname string
121197104Sjkim *
122197104Sjkim * RETURN:      None
123197104Sjkim *
124197104Sjkim * DESCRIPTION: Add a directory the list of include prefix directories.
125197104Sjkim *
126197104Sjkim ******************************************************************************/
127197104Sjkim
128197104Sjkimvoid
129197104SjkimFlAddIncludeDirectory (
130197104Sjkim    char                    *Dir)
131197104Sjkim{
132197104Sjkim    ASL_INCLUDE_DIR         *NewDir;
133197104Sjkim    ASL_INCLUDE_DIR         *NextDir;
134197104Sjkim    ASL_INCLUDE_DIR         *PrevDir = NULL;
135197104Sjkim    UINT32                  NeedsSeparator = 0;
136197104Sjkim    size_t                  DirLength;
137197104Sjkim
138197104Sjkim
139197104Sjkim    DirLength = strlen (Dir);
140197104Sjkim    if (!DirLength)
141197104Sjkim    {
142197104Sjkim        return;
143197104Sjkim    }
144197104Sjkim
145197104Sjkim    /* Make sure that the pathname ends with a path separator */
146197104Sjkim
147197104Sjkim    if ((Dir[DirLength-1] != '/') &&
148197104Sjkim        (Dir[DirLength-1] != '\\'))
149197104Sjkim    {
150197104Sjkim        NeedsSeparator = 1;
151197104Sjkim    }
152197104Sjkim
153197104Sjkim    NewDir = ACPI_ALLOCATE_ZEROED (sizeof (ASL_INCLUDE_DIR));
154197104Sjkim    NewDir->Dir = ACPI_ALLOCATE (DirLength + 1 + NeedsSeparator);
155197104Sjkim    strcpy (NewDir->Dir, Dir);
156197104Sjkim    if (NeedsSeparator)
157197104Sjkim    {
158197104Sjkim        strcat (NewDir->Dir, "/");
159197104Sjkim    }
160197104Sjkim
161197104Sjkim    /*
162197104Sjkim     * Preserve command line ordering of -I options by adding new elements
163197104Sjkim     * at the end of the list
164197104Sjkim     */
165197104Sjkim    NextDir = Gbl_IncludeDirList;
166197104Sjkim    while (NextDir)
167197104Sjkim    {
168197104Sjkim        PrevDir = NextDir;
169197104Sjkim        NextDir = NextDir->Next;
170197104Sjkim    }
171197104Sjkim
172197104Sjkim    if (PrevDir)
173197104Sjkim    {
174197104Sjkim        PrevDir->Next = NewDir;
175197104Sjkim    }
176197104Sjkim    else
177197104Sjkim    {
178197104Sjkim        Gbl_IncludeDirList = NewDir;
179197104Sjkim    }
180197104Sjkim}
181197104Sjkim
182197104Sjkim
183197104Sjkim/*******************************************************************************
184197104Sjkim *
185235945Sjkim * FUNCTION:    FlMergePathnames
186235945Sjkim *
187235945Sjkim * PARAMETERS:  PrefixDir       - Prefix directory pathname. Can be NULL or
188235945Sjkim *                                a zero length string.
189235945Sjkim *              FilePathname    - The include filename from the source ASL.
190235945Sjkim *
191235945Sjkim * RETURN:      Merged pathname string
192235945Sjkim *
193235945Sjkim * DESCRIPTION: Merge two pathnames that (probably) have common elements, to
194235945Sjkim *              arrive at a minimal length string. Merge can occur if the
195235945Sjkim *              FilePathname is relative to the PrefixDir.
196235945Sjkim *
197235945Sjkim ******************************************************************************/
198235945Sjkim
199235945Sjkimchar *
200235945SjkimFlMergePathnames (
201235945Sjkim    char                    *PrefixDir,
202235945Sjkim    char                    *FilePathname)
203235945Sjkim{
204235945Sjkim    char                    *CommonPath;
205235945Sjkim    char                    *Pathname;
206235945Sjkim    char                    *LastElement;
207235945Sjkim
208235945Sjkim
209235945Sjkim    DbgPrint (ASL_PARSE_OUTPUT, "Include: Prefix path - \"%s\"\n"
210235945Sjkim        "Include: FilePathname - \"%s\"\n",
211235945Sjkim         PrefixDir, FilePathname);
212235945Sjkim
213235945Sjkim    /*
214235945Sjkim     * If there is no prefix directory or if the file pathname is absolute,
215235945Sjkim     * just return the original file pathname
216235945Sjkim     */
217235945Sjkim    if (!PrefixDir || (!*PrefixDir) ||
218235945Sjkim        (*FilePathname == '/') ||
219235945Sjkim         (FilePathname[1] == ':'))
220235945Sjkim    {
221281075Sdim        Pathname = UtStringCacheCalloc (strlen (FilePathname) + 1);
222235945Sjkim        strcpy (Pathname, FilePathname);
223235945Sjkim        goto ConvertBackslashes;
224235945Sjkim    }
225235945Sjkim
226235945Sjkim    /* Need a local copy of the prefix directory path */
227235945Sjkim
228281075Sdim    CommonPath = UtStringCacheCalloc (strlen (PrefixDir) + 1);
229235945Sjkim    strcpy (CommonPath, PrefixDir);
230235945Sjkim
231235945Sjkim    /*
232235945Sjkim     * Walk forward through the file path, and simultaneously backward
233235945Sjkim     * through the prefix directory path until there are no more
234235945Sjkim     * relative references at the start of the file path.
235235945Sjkim     */
236235945Sjkim    while (*FilePathname && (!strncmp (FilePathname, "../", 3)))
237235945Sjkim    {
238235945Sjkim        /* Remove last element of the prefix directory path */
239235945Sjkim
240235945Sjkim        LastElement = strrchr (CommonPath, '/');
241235945Sjkim        if (!LastElement)
242235945Sjkim        {
243235945Sjkim            goto ConcatenatePaths;
244235945Sjkim        }
245235945Sjkim
246235945Sjkim        *LastElement = 0;   /* Terminate CommonPath string */
247235945Sjkim        FilePathname += 3;  /* Point to next path element */
248235945Sjkim    }
249235945Sjkim
250235945Sjkim    /*
251235945Sjkim     * Remove the last element of the prefix directory path (it is the same as
252235945Sjkim     * the first element of the file pathname), and build the final merged
253235945Sjkim     * pathname.
254235945Sjkim     */
255235945Sjkim    LastElement = strrchr (CommonPath, '/');
256235945Sjkim    if (LastElement)
257235945Sjkim    {
258235945Sjkim        *LastElement = 0;
259235945Sjkim    }
260235945Sjkim
261235945Sjkim    /* Build the final merged pathname */
262235945Sjkim
263235945SjkimConcatenatePaths:
264306536Sjkim    Pathname = UtStringCacheCalloc (
265306536Sjkim        strlen (CommonPath) + strlen (FilePathname) + 2);
266235945Sjkim    if (LastElement && *CommonPath)
267235945Sjkim    {
268235945Sjkim        strcpy (Pathname, CommonPath);
269235945Sjkim        strcat (Pathname, "/");
270235945Sjkim    }
271235945Sjkim    strcat (Pathname, FilePathname);
272235945Sjkim
273235945Sjkim    /* Convert all backslashes to normal slashes */
274235945Sjkim
275235945SjkimConvertBackslashes:
276235945Sjkim    UtConvertBackslashes (Pathname);
277235945Sjkim
278235945Sjkim    DbgPrint (ASL_PARSE_OUTPUT, "Include: Merged Pathname - \"%s\"\n",
279235945Sjkim         Pathname);
280235945Sjkim    return (Pathname);
281235945Sjkim}
282235945Sjkim
283235945Sjkim
284235945Sjkim/*******************************************************************************
285235945Sjkim *
286197104Sjkim * FUNCTION:    FlOpenIncludeWithPrefix
287197104Sjkim *
288197104Sjkim * PARAMETERS:  PrefixDir       - Prefix directory pathname. Can be a zero
289197104Sjkim *                                length string.
290197104Sjkim *              Filename        - The include filename from the source ASL.
291197104Sjkim *
292197104Sjkim * RETURN:      Valid file descriptor if successful. Null otherwise.
293197104Sjkim *
294197104Sjkim * DESCRIPTION: Open an include file and push it on the input file stack.
295197104Sjkim *
296197104Sjkim ******************************************************************************/
297197104Sjkim
298284460Sjkimstatic FILE *
299197104SjkimFlOpenIncludeWithPrefix (
300197104Sjkim    char                    *PrefixDir,
301284460Sjkim    ACPI_PARSE_OBJECT       *Op,
302197104Sjkim    char                    *Filename)
303197104Sjkim{
304197104Sjkim    FILE                    *IncludeFile;
305197104Sjkim    char                    *Pathname;
306306536Sjkim    UINT32                  OriginalLineNumber;
307197104Sjkim
308197104Sjkim
309197104Sjkim    /* Build the full pathname to the file */
310197104Sjkim
311235945Sjkim    Pathname = FlMergePathnames (PrefixDir, Filename);
312197104Sjkim
313235945Sjkim    DbgPrint (ASL_PARSE_OUTPUT, "Include: Opening file - \"%s\"\n\n",
314197104Sjkim        Pathname);
315197104Sjkim
316197104Sjkim    /* Attempt to open the file, push if successful */
317197104Sjkim
318197104Sjkim    IncludeFile = fopen (Pathname, "r");
319243347Sjkim    if (!IncludeFile)
320197104Sjkim    {
321243347Sjkim        fprintf (stderr, "Could not open include file %s\n", Pathname);
322243347Sjkim        ACPI_FREE (Pathname);
323243347Sjkim        return (NULL);
324197104Sjkim    }
325197104Sjkim
326284460Sjkim    /*
327306536Sjkim     * Check the entire include file for any # preprocessor directives.
328284460Sjkim     * This is because there may be some confusion between the #include
329306536Sjkim     * preprocessor directive and the ASL Include statement. A file included
330306536Sjkim     * by the ASL include cannot contain preprocessor directives because
331306536Sjkim     * the preprocessor has already run by the time the ASL include is
332306536Sjkim     * recognized (by the compiler, not the preprocessor.)
333306536Sjkim     *
334306536Sjkim     * Note: DtGetNextLine strips/ignores comments.
335306536Sjkim     * Save current line number since DtGetNextLine modifies it.
336284460Sjkim     */
337306536Sjkim    Gbl_CurrentLineNumber--;
338306536Sjkim    OriginalLineNumber = Gbl_CurrentLineNumber;
339306536Sjkim
340306536Sjkim    while (DtGetNextLine (IncludeFile, DT_ALLOW_MULTILINE_QUOTES) != ASL_EOF)
341284460Sjkim    {
342284460Sjkim        if (Gbl_CurrentLineBuffer[0] == '#')
343284460Sjkim        {
344284460Sjkim            AslError (ASL_ERROR, ASL_MSG_INCLUDE_FILE,
345284460Sjkim                Op, "use #include instead");
346284460Sjkim        }
347284460Sjkim    }
348284460Sjkim
349306536Sjkim    Gbl_CurrentLineNumber = OriginalLineNumber;
350306536Sjkim
351284460Sjkim    /* Must seek back to the start of the file */
352284460Sjkim
353284460Sjkim    fseek (IncludeFile, 0, SEEK_SET);
354284460Sjkim
355243347Sjkim    /* Push the include file on the open input file stack */
356243347Sjkim
357243347Sjkim    AslPushInputFileStack (IncludeFile, Pathname);
358243347Sjkim    return (IncludeFile);
359197104Sjkim}
360197104Sjkim
361197104Sjkim
362197104Sjkim/*******************************************************************************
363197104Sjkim *
364118611Snjl * FUNCTION:    FlOpenIncludeFile
365118611Snjl *
366118611Snjl * PARAMETERS:  Op        - Parse node for the INCLUDE ASL statement
367118611Snjl *
368118611Snjl * RETURN:      None.
369118611Snjl *
370118611Snjl * DESCRIPTION: Open an include file and push it on the input file stack.
371118611Snjl *
372118611Snjl ******************************************************************************/
373118611Snjl
374118611Snjlvoid
375118611SnjlFlOpenIncludeFile (
376118611Snjl    ACPI_PARSE_OBJECT       *Op)
377118611Snjl{
378197104Sjkim    FILE                    *IncludeFile;
379197104Sjkim    ASL_INCLUDE_DIR         *NextDir;
380118611Snjl
381118611Snjl
382118611Snjl    /* Op must be valid */
383118611Snjl
384118611Snjl    if (!Op)
385118611Snjl    {
386118611Snjl        AslCommonError (ASL_ERROR, ASL_MSG_INCLUDE_FILE_OPEN,
387118611Snjl            Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
388118611Snjl            Gbl_InputByteCount, Gbl_CurrentColumn,
389118611Snjl            Gbl_Files[ASL_FILE_INPUT].Filename, " - Null parse node");
390118611Snjl
391118611Snjl        return;
392118611Snjl    }
393118611Snjl
394118611Snjl    /*
395118611Snjl     * Flush out the "include ()" statement on this line, start
396118611Snjl     * the actual include file on the next line
397118611Snjl     */
398234623Sjkim    AslResetCurrentLineBuffer ();
399118611Snjl    FlPrintFile (ASL_FILE_SOURCE_OUTPUT, "\n");
400118611Snjl    Gbl_CurrentLineOffset++;
401118611Snjl
402118611Snjl
403197104Sjkim    /* Attempt to open the include file */
404197104Sjkim
405197104Sjkim    /* If the file specifies an absolute path, just open it */
406197104Sjkim
407197104Sjkim    if ((Op->Asl.Value.String[0] == '/')  ||
408197104Sjkim        (Op->Asl.Value.String[0] == '\\') ||
409197104Sjkim        (Op->Asl.Value.String[1] == ':'))
410118611Snjl    {
411284460Sjkim        IncludeFile = FlOpenIncludeWithPrefix ("", Op, Op->Asl.Value.String);
412197104Sjkim        if (!IncludeFile)
413197104Sjkim        {
414197104Sjkim            goto ErrorExit;
415197104Sjkim        }
416118611Snjl        return;
417118611Snjl    }
418118611Snjl
419197104Sjkim    /*
420197104Sjkim     * The include filename is not an absolute path.
421197104Sjkim     *
422197104Sjkim     * First, search for the file within the "local" directory -- meaning
423197104Sjkim     * the same directory that contains the source file.
424197104Sjkim     *
425197104Sjkim     * Construct the file pathname from the global directory name.
426197104Sjkim     */
427306536Sjkim    IncludeFile = FlOpenIncludeWithPrefix (
428306536Sjkim        Gbl_DirectoryPath, Op, Op->Asl.Value.String);
429197104Sjkim    if (IncludeFile)
430197104Sjkim    {
431197104Sjkim        return;
432197104Sjkim    }
433118611Snjl
434197104Sjkim    /*
435197104Sjkim     * Second, search for the file within the (possibly multiple) directories
436197104Sjkim     * specified by the -I option on the command line.
437197104Sjkim     */
438197104Sjkim    NextDir = Gbl_IncludeDirList;
439197104Sjkim    while (NextDir)
440197104Sjkim    {
441306536Sjkim        IncludeFile = FlOpenIncludeWithPrefix (
442306536Sjkim            NextDir->Dir, Op, Op->Asl.Value.String);
443197104Sjkim        if (IncludeFile)
444197104Sjkim        {
445197104Sjkim            return;
446197104Sjkim        }
447197104Sjkim
448197104Sjkim        NextDir = NextDir->Next;
449197104Sjkim    }
450197104Sjkim
451197104Sjkim    /* We could not open the include file after trying very hard */
452197104Sjkim
453197104SjkimErrorExit:
454197104Sjkim    sprintf (MsgBuffer, "%s, %s", Op->Asl.Value.String, strerror (errno));
455197104Sjkim    AslError (ASL_ERROR, ASL_MSG_INCLUDE_FILE_OPEN, Op, MsgBuffer);
456118611Snjl}
457118611Snjl
458118611Snjl
459118611Snjl/*******************************************************************************
460118611Snjl *
461118611Snjl * FUNCTION:    FlOpenInputFile
462118611Snjl *
463118611Snjl * PARAMETERS:  InputFilename       - The user-specified ASL source file to be
464118611Snjl *                                    compiled
465118611Snjl *
466118611Snjl * RETURN:      Status
467118611Snjl *
468118611Snjl * DESCRIPTION: Open the specified input file, and save the directory path to
469118611Snjl *              the file so that include files can be opened in
470118611Snjl *              the same directory.
471118611Snjl *
472118611Snjl ******************************************************************************/
473118611Snjl
474118611SnjlACPI_STATUS
475118611SnjlFlOpenInputFile (
476118611Snjl    char                    *InputFilename)
477118611Snjl{
478118611Snjl
479118611Snjl    /* Open the input ASL file, text mode */
480118611Snjl
481237412Sjkim    FlOpenFile (ASL_FILE_INPUT, InputFilename, "rt");
482118611Snjl    AslCompilerin = Gbl_Files[ASL_FILE_INPUT].Handle;
483118611Snjl
484118611Snjl    return (AE_OK);
485118611Snjl}
486118611Snjl
487118611Snjl
488118611Snjl/*******************************************************************************
489118611Snjl *
490118611Snjl * FUNCTION:    FlOpenAmlOutputFile
491118611Snjl *
492118611Snjl * PARAMETERS:  FilenamePrefix       - The user-specified ASL source file
493118611Snjl *
494118611Snjl * RETURN:      Status
495118611Snjl *
496241973Sjkim * DESCRIPTION: Create the output filename (*.AML) and open the file. The file
497118611Snjl *              is created in the same directory as the parent input file.
498118611Snjl *
499118611Snjl ******************************************************************************/
500118611Snjl
501118611SnjlACPI_STATUS
502118611SnjlFlOpenAmlOutputFile (
503118611Snjl    char                    *FilenamePrefix)
504118611Snjl{
505118611Snjl    char                    *Filename;
506118611Snjl
507118611Snjl
508118611Snjl    /* Output filename usually comes from the ASL itself */
509118611Snjl
510118611Snjl    Filename = Gbl_Files[ASL_FILE_AML_OUTPUT].Filename;
511118611Snjl    if (!Filename)
512118611Snjl    {
513118611Snjl        /* Create the output AML filename */
514118611Snjl
515118611Snjl        Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_AML_CODE);
516118611Snjl        if (!Filename)
517118611Snjl        {
518151937Sjkim            AslCommonError (ASL_ERROR, ASL_MSG_OUTPUT_FILENAME,
519151937Sjkim                0, 0, 0, 0, NULL, NULL);
520118611Snjl            return (AE_ERROR);
521118611Snjl        }
522281075Sdim
523281075Sdim        Gbl_Files[ASL_FILE_AML_OUTPUT].Filename = Filename;
524118611Snjl    }
525118611Snjl
526118611Snjl    /* Open the output AML file in binary mode */
527118611Snjl
528118611Snjl    FlOpenFile (ASL_FILE_AML_OUTPUT, Filename, "w+b");
529118611Snjl    return (AE_OK);
530118611Snjl}
531118611Snjl
532118611Snjl
533118611Snjl/*******************************************************************************
534118611Snjl *
535118611Snjl * FUNCTION:    FlOpenMiscOutputFiles
536118611Snjl *
537118611Snjl * PARAMETERS:  FilenamePrefix       - The user-specified ASL source file
538118611Snjl *
539118611Snjl * RETURN:      Status
540118611Snjl *
541118611Snjl * DESCRIPTION: Create and open the various output files needed, depending on
542118611Snjl *              the command line options
543118611Snjl *
544118611Snjl ******************************************************************************/
545118611Snjl
546118611SnjlACPI_STATUS
547118611SnjlFlOpenMiscOutputFiles (
548118611Snjl    char                    *FilenamePrefix)
549118611Snjl{
550118611Snjl    char                    *Filename;
551118611Snjl
552118611Snjl
553306536Sjkim     /* Create/Open a map file if requested */
554306536Sjkim
555306536Sjkim    if (Gbl_MapfileFlag)
556306536Sjkim    {
557306536Sjkim        Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_MAP);
558306536Sjkim        if (!Filename)
559306536Sjkim        {
560306536Sjkim            AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
561306536Sjkim                0, 0, 0, 0, NULL, NULL);
562306536Sjkim            return (AE_ERROR);
563306536Sjkim        }
564306536Sjkim
565306536Sjkim        /* Open the hex file, text mode (closed at compiler exit) */
566306536Sjkim
567306536Sjkim        FlOpenFile (ASL_FILE_MAP_OUTPUT, Filename, "w+t");
568306536Sjkim
569306536Sjkim        AslCompilerSignon (ASL_FILE_MAP_OUTPUT);
570306536Sjkim        AslCompilerFileHeader (ASL_FILE_MAP_OUTPUT);
571306536Sjkim    }
572306536Sjkim
573246849Sjkim    /* All done for disassembler */
574246849Sjkim
575306536Sjkim    if (Gbl_FileType == ASL_INPUT_TYPE_BINARY_ACPI_TABLE)
576246849Sjkim    {
577246849Sjkim        return (AE_OK);
578246849Sjkim    }
579246849Sjkim
580209746Sjkim    /* Create/Open a hex output file if asked */
581209746Sjkim
582209746Sjkim    if (Gbl_HexOutputFlag)
583209746Sjkim    {
584209746Sjkim        Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_HEX_DUMP);
585209746Sjkim        if (!Filename)
586209746Sjkim        {
587209746Sjkim            AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
588209746Sjkim                0, 0, 0, 0, NULL, NULL);
589209746Sjkim            return (AE_ERROR);
590209746Sjkim        }
591209746Sjkim
592209746Sjkim        /* Open the hex file, text mode */
593209746Sjkim
594237412Sjkim        FlOpenFile (ASL_FILE_HEX_OUTPUT, Filename, "w+t");
595209746Sjkim
596209746Sjkim        AslCompilerSignon (ASL_FILE_HEX_OUTPUT);
597209746Sjkim        AslCompilerFileHeader (ASL_FILE_HEX_OUTPUT);
598209746Sjkim    }
599209746Sjkim
600209746Sjkim    /* Create/Open a debug output file if asked */
601209746Sjkim
602209746Sjkim    if (Gbl_DebugFlag)
603209746Sjkim    {
604209746Sjkim        Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_DEBUG);
605209746Sjkim        if (!Filename)
606209746Sjkim        {
607209746Sjkim            AslCommonError (ASL_ERROR, ASL_MSG_DEBUG_FILENAME,
608209746Sjkim                0, 0, 0, 0, NULL, NULL);
609209746Sjkim            return (AE_ERROR);
610209746Sjkim        }
611209746Sjkim
612209746Sjkim        /* Open the debug file as STDERR, text mode */
613209746Sjkim
614209746Sjkim        Gbl_Files[ASL_FILE_DEBUG_OUTPUT].Filename = Filename;
615209746Sjkim        Gbl_Files[ASL_FILE_DEBUG_OUTPUT].Handle =
616209746Sjkim            freopen (Filename, "w+t", stderr);
617209746Sjkim
618233250Sjkim        if (!Gbl_Files[ASL_FILE_DEBUG_OUTPUT].Handle)
619233250Sjkim        {
620281075Sdim            /*
621306536Sjkim             * A problem with freopen is that on error, we no longer
622306536Sjkim             * have stderr and cannot emit normal error messages.
623306536Sjkim             * Emit error to stdout, close files, and exit.
624281075Sdim             */
625306536Sjkim            fprintf (stdout,
626306536Sjkim                "\nCould not open debug output file: %s\n\n", Filename);
627306536Sjkim
628306536Sjkim            CmCleanupAndExit ();
629306536Sjkim            exit (1);
630233250Sjkim        }
631233250Sjkim
632209746Sjkim        AslCompilerSignon (ASL_FILE_DEBUG_OUTPUT);
633209746Sjkim        AslCompilerFileHeader (ASL_FILE_DEBUG_OUTPUT);
634209746Sjkim    }
635209746Sjkim
636306536Sjkim    /* Create/Open a cross-reference output file if asked */
637306536Sjkim
638306536Sjkim    if (Gbl_CrossReferenceOutput)
639306536Sjkim    {
640306536Sjkim        Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_XREF);
641306536Sjkim        if (!Filename)
642306536Sjkim        {
643306536Sjkim            AslCommonError (ASL_ERROR, ASL_MSG_DEBUG_FILENAME,
644306536Sjkim                0, 0, 0, 0, NULL, NULL);
645306536Sjkim            return (AE_ERROR);
646306536Sjkim        }
647306536Sjkim
648306536Sjkim        FlOpenFile (ASL_FILE_XREF_OUTPUT, Filename, "w+t");
649306536Sjkim
650306536Sjkim        AslCompilerSignon (ASL_FILE_XREF_OUTPUT);
651306536Sjkim        AslCompilerFileHeader (ASL_FILE_XREF_OUTPUT);
652306536Sjkim    }
653306536Sjkim
654217365Sjkim    /* Create/Open a listing output file if asked */
655217365Sjkim
656217365Sjkim    if (Gbl_ListingFlag)
657217365Sjkim    {
658217365Sjkim        Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_LISTING);
659217365Sjkim        if (!Filename)
660217365Sjkim        {
661217365Sjkim            AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
662217365Sjkim                0, 0, 0, 0, NULL, NULL);
663217365Sjkim            return (AE_ERROR);
664217365Sjkim        }
665217365Sjkim
666217365Sjkim        /* Open the listing file, text mode */
667217365Sjkim
668237412Sjkim        FlOpenFile (ASL_FILE_LISTING_OUTPUT, Filename, "w+t");
669217365Sjkim
670217365Sjkim        AslCompilerSignon (ASL_FILE_LISTING_OUTPUT);
671217365Sjkim        AslCompilerFileHeader (ASL_FILE_LISTING_OUTPUT);
672217365Sjkim    }
673217365Sjkim
674306536Sjkim    /* Create the preprocessor output temp file if preprocessor enabled */
675233250Sjkim
676234623Sjkim    if (Gbl_PreprocessFlag)
677233250Sjkim    {
678234623Sjkim        Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_PREPROCESSOR);
679234623Sjkim        if (!Filename)
680234623Sjkim        {
681234623Sjkim            AslCommonError (ASL_ERROR, ASL_MSG_PREPROCESSOR_FILENAME,
682234623Sjkim                0, 0, 0, 0, NULL, NULL);
683234623Sjkim            return (AE_ERROR);
684234623Sjkim        }
685234623Sjkim
686237412Sjkim        FlOpenFile (ASL_FILE_PREPROCESSOR, Filename, "w+t");
687233250Sjkim    }
688233250Sjkim
689306536Sjkim    /*
690306536Sjkim     * Create the "user" preprocessor output file if -li flag set.
691306536Sjkim     * Note, this file contains no embedded #line directives.
692306536Sjkim     */
693306536Sjkim    if (Gbl_PreprocessorOutputFlag)
694306536Sjkim    {
695306536Sjkim        Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_PREPROC_USER);
696306536Sjkim        if (!Filename)
697306536Sjkim        {
698306536Sjkim            AslCommonError (ASL_ERROR, ASL_MSG_PREPROCESSOR_FILENAME,
699306536Sjkim                0, 0, 0, 0, NULL, NULL);
700306536Sjkim            return (AE_ERROR);
701306536Sjkim        }
702306536Sjkim
703306536Sjkim        FlOpenFile (ASL_FILE_PREPROCESSOR_USER, Filename, "w+t");
704306536Sjkim    }
705306536Sjkim
706233250Sjkim    /* All done for data table compiler */
707233250Sjkim
708209746Sjkim    if (Gbl_FileType == ASL_INPUT_TYPE_ASCII_DATA)
709209746Sjkim    {
710209746Sjkim        return (AE_OK);
711209746Sjkim    }
712209746Sjkim
713243347Sjkim    /* Create/Open a combined source output file */
714118611Snjl
715118611Snjl    Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_SOURCE);
716118611Snjl    if (!Filename)
717118611Snjl    {
718151937Sjkim        AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
719151937Sjkim            0, 0, 0, 0, NULL, NULL);
720118611Snjl        return (AE_ERROR);
721118611Snjl    }
722118611Snjl
723118611Snjl    /*
724118611Snjl     * Open the source output file, binary mode (so that LF does not get
725118611Snjl     * expanded to CR/LF on some systems, messing up our seek
726118611Snjl     * calculations.)
727118611Snjl     */
728118611Snjl    FlOpenFile (ASL_FILE_SOURCE_OUTPUT, Filename, "w+b");
729118611Snjl
730233250Sjkim/*
731233250Sjkim// TBD: TEMP
732233250Sjkim//    AslCompilerin = Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle;
733233250Sjkim*/
734118611Snjl    /* Create/Open a assembly code source output file if asked */
735118611Snjl
736118611Snjl    if (Gbl_AsmOutputFlag)
737118611Snjl    {
738118611Snjl        Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_ASM_SOURCE);
739118611Snjl        if (!Filename)
740118611Snjl        {
741151937Sjkim            AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
742151937Sjkim                0, 0, 0, 0, NULL, NULL);
743118611Snjl            return (AE_ERROR);
744118611Snjl        }
745118611Snjl
746118611Snjl        /* Open the assembly code source file, text mode */
747118611Snjl
748237412Sjkim        FlOpenFile (ASL_FILE_ASM_SOURCE_OUTPUT, Filename, "w+t");
749118611Snjl
750118611Snjl        AslCompilerSignon (ASL_FILE_ASM_SOURCE_OUTPUT);
751118611Snjl        AslCompilerFileHeader (ASL_FILE_ASM_SOURCE_OUTPUT);
752118611Snjl    }
753118611Snjl
754118611Snjl    /* Create/Open a C code source output file if asked */
755118611Snjl
756118611Snjl    if (Gbl_C_OutputFlag)
757118611Snjl    {
758118611Snjl        Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_C_SOURCE);
759118611Snjl        if (!Filename)
760118611Snjl        {
761151937Sjkim            AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
762151937Sjkim                0, 0, 0, 0, NULL, NULL);
763118611Snjl            return (AE_ERROR);
764118611Snjl        }
765118611Snjl
766118611Snjl        /* Open the C code source file, text mode */
767118611Snjl
768237412Sjkim        FlOpenFile (ASL_FILE_C_SOURCE_OUTPUT, Filename, "w+t");
769118611Snjl
770118611Snjl        FlPrintFile (ASL_FILE_C_SOURCE_OUTPUT, "/*\n");
771118611Snjl        AslCompilerSignon (ASL_FILE_C_SOURCE_OUTPUT);
772118611Snjl        AslCompilerFileHeader (ASL_FILE_C_SOURCE_OUTPUT);
773118611Snjl    }
774118611Snjl
775249112Sjkim    /* Create/Open a C code source output file for the offset table if asked */
776249112Sjkim
777249112Sjkim    if (Gbl_C_OffsetTableFlag)
778249112Sjkim    {
779249112Sjkim        Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_C_OFFSET);
780249112Sjkim        if (!Filename)
781249112Sjkim        {
782249112Sjkim            AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
783249112Sjkim                0, 0, 0, 0, NULL, NULL);
784249112Sjkim            return (AE_ERROR);
785249112Sjkim        }
786249112Sjkim
787249112Sjkim        /* Open the C code source file, text mode */
788249112Sjkim
789249112Sjkim        FlOpenFile (ASL_FILE_C_OFFSET_OUTPUT, Filename, "w+t");
790249112Sjkim
791249112Sjkim        FlPrintFile (ASL_FILE_C_OFFSET_OUTPUT, "/*\n");
792249112Sjkim        AslCompilerSignon (ASL_FILE_C_OFFSET_OUTPUT);
793249112Sjkim        AslCompilerFileHeader (ASL_FILE_C_OFFSET_OUTPUT);
794249112Sjkim    }
795249112Sjkim
796118611Snjl    /* Create/Open a assembly include output file if asked */
797118611Snjl
798118611Snjl    if (Gbl_AsmIncludeOutputFlag)
799118611Snjl    {
800118611Snjl        Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_ASM_INCLUDE);
801118611Snjl        if (!Filename)
802118611Snjl        {
803151937Sjkim            AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
804151937Sjkim                0, 0, 0, 0, NULL, NULL);
805118611Snjl            return (AE_ERROR);
806118611Snjl        }
807118611Snjl
808118611Snjl        /* Open the assembly include file, text mode */
809118611Snjl
810237412Sjkim        FlOpenFile (ASL_FILE_ASM_INCLUDE_OUTPUT, Filename, "w+t");
811118611Snjl
812118611Snjl        AslCompilerSignon (ASL_FILE_ASM_INCLUDE_OUTPUT);
813118611Snjl        AslCompilerFileHeader (ASL_FILE_ASM_INCLUDE_OUTPUT);
814118611Snjl    }
815118611Snjl
816118611Snjl    /* Create/Open a C include output file if asked */
817118611Snjl
818118611Snjl    if (Gbl_C_IncludeOutputFlag)
819118611Snjl    {
820118611Snjl        Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_C_INCLUDE);
821118611Snjl        if (!Filename)
822118611Snjl        {
823151937Sjkim            AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
824151937Sjkim                0, 0, 0, 0, NULL, NULL);
825118611Snjl            return (AE_ERROR);
826118611Snjl        }
827118611Snjl
828118611Snjl        /* Open the C include file, text mode */
829118611Snjl
830237412Sjkim        FlOpenFile (ASL_FILE_C_INCLUDE_OUTPUT, Filename, "w+t");
831118611Snjl
832118611Snjl        FlPrintFile (ASL_FILE_C_INCLUDE_OUTPUT, "/*\n");
833118611Snjl        AslCompilerSignon (ASL_FILE_C_INCLUDE_OUTPUT);
834118611Snjl        AslCompilerFileHeader (ASL_FILE_C_INCLUDE_OUTPUT);
835118611Snjl    }
836118611Snjl
837118611Snjl    /* Create a namespace output file if asked */
838118611Snjl
839118611Snjl    if (Gbl_NsOutputFlag)
840118611Snjl    {
841118611Snjl        Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_NAMESPACE);
842118611Snjl        if (!Filename)
843118611Snjl        {
844151937Sjkim            AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
845151937Sjkim                0, 0, 0, 0, NULL, NULL);
846118611Snjl            return (AE_ERROR);
847118611Snjl        }
848118611Snjl
849118611Snjl        /* Open the namespace file, text mode */
850118611Snjl
851237412Sjkim        FlOpenFile (ASL_FILE_NAMESPACE_OUTPUT, Filename, "w+t");
852118611Snjl
853118611Snjl        AslCompilerSignon (ASL_FILE_NAMESPACE_OUTPUT);
854118611Snjl        AslCompilerFileHeader (ASL_FILE_NAMESPACE_OUTPUT);
855118611Snjl    }
856118611Snjl
857118611Snjl    return (AE_OK);
858118611Snjl}
859118611Snjl
860118611Snjl
861151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS
862151937Sjkim/*******************************************************************************
863151937Sjkim *
864151937Sjkim * FUNCTION:    FlParseInputPathname
865151937Sjkim *
866151937Sjkim * PARAMETERS:  InputFilename       - The user-specified ASL source file to be
867151937Sjkim *                                    compiled
868151937Sjkim *
869151937Sjkim * RETURN:      Status
870151937Sjkim *
871151937Sjkim * DESCRIPTION: Split the input path into a directory and filename part
872151937Sjkim *              1) Directory part used to open include files
873151937Sjkim *              2) Filename part used to generate output filenames
874151937Sjkim *
875151937Sjkim ******************************************************************************/
876151937Sjkim
877151937SjkimACPI_STATUS
878151937SjkimFlParseInputPathname (
879151937Sjkim    char                    *InputFilename)
880151937Sjkim{
881151937Sjkim    char                    *Substring;
882151937Sjkim
883151937Sjkim
884151937Sjkim    if (!InputFilename)
885151937Sjkim    {
886151937Sjkim        return (AE_OK);
887151937Sjkim    }
888151937Sjkim
889151937Sjkim    /* Get the path to the input filename's directory */
890151937Sjkim
891151937Sjkim    Gbl_DirectoryPath = strdup (InputFilename);
892151937Sjkim    if (!Gbl_DirectoryPath)
893151937Sjkim    {
894151937Sjkim        return (AE_NO_MEMORY);
895151937Sjkim    }
896151937Sjkim
897151937Sjkim    Substring = strrchr (Gbl_DirectoryPath, '\\');
898151937Sjkim    if (!Substring)
899151937Sjkim    {
900151937Sjkim        Substring = strrchr (Gbl_DirectoryPath, '/');
901151937Sjkim        if (!Substring)
902151937Sjkim        {
903151937Sjkim            Substring = strrchr (Gbl_DirectoryPath, ':');
904151937Sjkim        }
905151937Sjkim    }
906151937Sjkim
907151937Sjkim    if (!Substring)
908151937Sjkim    {
909151937Sjkim        Gbl_DirectoryPath[0] = 0;
910151937Sjkim        if (Gbl_UseDefaultAmlFilename)
911151937Sjkim        {
912151937Sjkim            Gbl_OutputFilenamePrefix = strdup (InputFilename);
913151937Sjkim        }
914151937Sjkim    }
915151937Sjkim    else
916151937Sjkim    {
917151937Sjkim        if (Gbl_UseDefaultAmlFilename)
918151937Sjkim        {
919151937Sjkim            Gbl_OutputFilenamePrefix = strdup (Substring + 1);
920151937Sjkim        }
921151937Sjkim        *(Substring+1) = 0;
922151937Sjkim    }
923151937Sjkim
924281075Sdim    UtConvertBackslashes (Gbl_OutputFilenamePrefix);
925151937Sjkim    return (AE_OK);
926151937Sjkim}
927151937Sjkim#endif
928