xref: /freebsd/sys/contrib/dev/acpica/compiler/aslfiles.c (revision f0cfa1b168014f56c02b83e5f28412cc5f78d117)
1 /******************************************************************************
2  *
3  * Module Name: aslfiles - File support functions
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************
115  *
116  * Alternatively, you may choose to be licensed under the terms of the
117  * following license:
118  *
119  * Redistribution and use in source and binary forms, with or without
120  * modification, are permitted provided that the following conditions
121  * are met:
122  * 1. Redistributions of source code must retain the above copyright
123  *    notice, this list of conditions, and the following disclaimer,
124  *    without modification.
125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126  *    substantially similar to the "NO WARRANTY" disclaimer below
127  *    ("Disclaimer") and any redistribution must be conditioned upon
128  *    including a substantially similar Disclaimer requirement for further
129  *    binary redistribution.
130  * 3. Neither the names of the above-listed copyright holders nor the names
131  *    of any contributors may be used to endorse or promote products derived
132  *    from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145  *
146  * Alternatively, you may choose to be licensed under the terms of the
147  * GNU General Public License ("GPL") version 2 as published by the Free
148  * Software Foundation.
149  *
150  *****************************************************************************/
151 
152 #include <contrib/dev/acpica/compiler/aslcompiler.h>
153 #include <contrib/dev/acpica/include/acapps.h>
154 
155 #define _COMPONENT          ACPI_COMPILER
156         ACPI_MODULE_NAME    ("aslfiles")
157 
158 /* Local prototypes */
159 
160 static FILE *
161 FlOpenIncludeWithPrefix (
162     char                    *PrefixDir,
163     ACPI_PARSE_OBJECT       *Op,
164     char                    *Filename);
165 
166 #ifdef ACPI_OBSOLETE_FUNCTIONS
167 ACPI_STATUS
168 FlParseInputPathname (
169     char                    *InputFilename);
170 #endif
171 
172 
173 /*******************************************************************************
174  *
175  * FUNCTION:    FlSetLineNumber
176  *
177  * PARAMETERS:  Op        - Parse node for the LINE asl statement
178  *
179  * RETURN:      None.
180  *
181  * DESCRIPTION: Set the current line number
182  *
183  ******************************************************************************/
184 
185 void
186 FlSetLineNumber (
187     UINT32                  LineNumber)
188 {
189 
190     DbgPrint (ASL_PARSE_OUTPUT, "\n#line: New line number %u (old %u)\n",
191          LineNumber, Gbl_LogicalLineNumber);
192 
193     Gbl_CurrentLineNumber = LineNumber;
194 }
195 
196 
197 /*******************************************************************************
198  *
199  * FUNCTION:    FlSetFilename
200  *
201  * PARAMETERS:  Op        - Parse node for the LINE asl statement
202  *
203  * RETURN:      None.
204  *
205  * DESCRIPTION: Set the current filename
206  *
207  ******************************************************************************/
208 
209 void
210 FlSetFilename (
211     char                    *Filename)
212 {
213 
214     DbgPrint (ASL_PARSE_OUTPUT, "\n#line: New filename %s (old %s)\n",
215          Filename, Gbl_Files[ASL_FILE_INPUT].Filename);
216 
217     /* No need to free any existing filename */
218 
219     Gbl_Files[ASL_FILE_INPUT].Filename = Filename;
220 }
221 
222 
223 /*******************************************************************************
224  *
225  * FUNCTION:    FlAddIncludeDirectory
226  *
227  * PARAMETERS:  Dir             - Directory pathname string
228  *
229  * RETURN:      None
230  *
231  * DESCRIPTION: Add a directory the list of include prefix directories.
232  *
233  ******************************************************************************/
234 
235 void
236 FlAddIncludeDirectory (
237     char                    *Dir)
238 {
239     ASL_INCLUDE_DIR         *NewDir;
240     ASL_INCLUDE_DIR         *NextDir;
241     ASL_INCLUDE_DIR         *PrevDir = NULL;
242     UINT32                  NeedsSeparator = 0;
243     size_t                  DirLength;
244 
245 
246     DirLength = strlen (Dir);
247     if (!DirLength)
248     {
249         return;
250     }
251 
252     /* Make sure that the pathname ends with a path separator */
253 
254     if ((Dir[DirLength-1] != '/') &&
255         (Dir[DirLength-1] != '\\'))
256     {
257         NeedsSeparator = 1;
258     }
259 
260     NewDir = ACPI_ALLOCATE_ZEROED (sizeof (ASL_INCLUDE_DIR));
261     NewDir->Dir = ACPI_ALLOCATE (DirLength + 1 + NeedsSeparator);
262     strcpy (NewDir->Dir, Dir);
263     if (NeedsSeparator)
264     {
265         strcat (NewDir->Dir, "/");
266     }
267 
268     /*
269      * Preserve command line ordering of -I options by adding new elements
270      * at the end of the list
271      */
272     NextDir = Gbl_IncludeDirList;
273     while (NextDir)
274     {
275         PrevDir = NextDir;
276         NextDir = NextDir->Next;
277     }
278 
279     if (PrevDir)
280     {
281         PrevDir->Next = NewDir;
282     }
283     else
284     {
285         Gbl_IncludeDirList = NewDir;
286     }
287 }
288 
289 
290 /*******************************************************************************
291  *
292  * FUNCTION:    FlMergePathnames
293  *
294  * PARAMETERS:  PrefixDir       - Prefix directory pathname. Can be NULL or
295  *                                a zero length string.
296  *              FilePathname    - The include filename from the source ASL.
297  *
298  * RETURN:      Merged pathname string
299  *
300  * DESCRIPTION: Merge two pathnames that (probably) have common elements, to
301  *              arrive at a minimal length string. Merge can occur if the
302  *              FilePathname is relative to the PrefixDir.
303  *
304  ******************************************************************************/
305 
306 char *
307 FlMergePathnames (
308     char                    *PrefixDir,
309     char                    *FilePathname)
310 {
311     char                    *CommonPath;
312     char                    *Pathname;
313     char                    *LastElement;
314 
315 
316     DbgPrint (ASL_PARSE_OUTPUT, "Include: Prefix path - \"%s\"\n"
317         "Include: FilePathname - \"%s\"\n",
318          PrefixDir, FilePathname);
319 
320     /*
321      * If there is no prefix directory or if the file pathname is absolute,
322      * just return the original file pathname
323      */
324     if (!PrefixDir || (!*PrefixDir) ||
325         (*FilePathname == '/') ||
326          (FilePathname[1] == ':'))
327     {
328         Pathname = UtLocalCacheCalloc (strlen (FilePathname) + 1);
329         strcpy (Pathname, FilePathname);
330         goto ConvertBackslashes;
331     }
332 
333     /* Need a local copy of the prefix directory path */
334 
335     CommonPath = UtLocalCacheCalloc (strlen (PrefixDir) + 1);
336     strcpy (CommonPath, PrefixDir);
337 
338     /*
339      * Walk forward through the file path, and simultaneously backward
340      * through the prefix directory path until there are no more
341      * relative references at the start of the file path.
342      */
343     while (*FilePathname && (!strncmp (FilePathname, "../", 3)))
344     {
345         /* Remove last element of the prefix directory path */
346 
347         LastElement = strrchr (CommonPath, '/');
348         if (!LastElement)
349         {
350             goto ConcatenatePaths;
351         }
352 
353         *LastElement = 0;   /* Terminate CommonPath string */
354         FilePathname += 3;  /* Point to next path element */
355     }
356 
357     /*
358      * Remove the last element of the prefix directory path (it is the same as
359      * the first element of the file pathname), and build the final merged
360      * pathname.
361      */
362     LastElement = strrchr (CommonPath, '/');
363     if (LastElement)
364     {
365         *LastElement = 0;
366     }
367 
368     /* Build the final merged pathname */
369 
370 ConcatenatePaths:
371     Pathname = UtLocalCacheCalloc (
372         strlen (CommonPath) + strlen (FilePathname) + 2);
373     if (LastElement && *CommonPath)
374     {
375         strcpy (Pathname, CommonPath);
376         strcat (Pathname, "/");
377     }
378     strcat (Pathname, FilePathname);
379 
380     /* Convert all backslashes to normal slashes */
381 
382 ConvertBackslashes:
383     UtConvertBackslashes (Pathname);
384 
385     DbgPrint (ASL_PARSE_OUTPUT, "Include: Merged Pathname - \"%s\"\n",
386          Pathname);
387     return (Pathname);
388 }
389 
390 
391 /*******************************************************************************
392  *
393  * FUNCTION:    FlOpenIncludeWithPrefix
394  *
395  * PARAMETERS:  PrefixDir       - Prefix directory pathname. Can be a zero
396  *                                length string.
397  *              Filename        - The include filename from the source ASL.
398  *
399  * RETURN:      Valid file descriptor if successful. Null otherwise.
400  *
401  * DESCRIPTION: Open an include file and push it on the input file stack.
402  *
403  ******************************************************************************/
404 
405 static FILE *
406 FlOpenIncludeWithPrefix (
407     char                    *PrefixDir,
408     ACPI_PARSE_OBJECT       *Op,
409     char                    *Filename)
410 {
411     FILE                    *IncludeFile;
412     char                    *Pathname;
413     UINT32                  OriginalLineNumber;
414 
415 
416     /* Build the full pathname to the file */
417 
418     Pathname = FlMergePathnames (PrefixDir, Filename);
419 
420     DbgPrint (ASL_PARSE_OUTPUT, "Include: Opening file - \"%s\"\n\n",
421         Pathname);
422 
423     /* Attempt to open the file, push if successful */
424 
425     IncludeFile = fopen (Pathname, "r");
426     if (!IncludeFile)
427     {
428         fprintf (stderr, "Could not open include file %s\n", Pathname);
429         ACPI_FREE (Pathname);
430         return (NULL);
431     }
432 
433     /*
434      * Check the entire include file for any # preprocessor directives.
435      * This is because there may be some confusion between the #include
436      * preprocessor directive and the ASL Include statement. A file included
437      * by the ASL include cannot contain preprocessor directives because
438      * the preprocessor has already run by the time the ASL include is
439      * recognized (by the compiler, not the preprocessor.)
440      *
441      * Note: DtGetNextLine strips/ignores comments.
442      * Save current line number since DtGetNextLine modifies it.
443      */
444     Gbl_CurrentLineNumber--;
445     OriginalLineNumber = Gbl_CurrentLineNumber;
446 
447     while (DtGetNextLine (IncludeFile, DT_ALLOW_MULTILINE_QUOTES) != ASL_EOF)
448     {
449         if (Gbl_CurrentLineBuffer[0] == '#')
450         {
451             AslError (ASL_ERROR, ASL_MSG_INCLUDE_FILE,
452                 Op, "use #include instead");
453         }
454     }
455 
456     Gbl_CurrentLineNumber = OriginalLineNumber;
457 
458     /* Must seek back to the start of the file */
459 
460     fseek (IncludeFile, 0, SEEK_SET);
461 
462     /* Push the include file on the open input file stack */
463 
464     AslPushInputFileStack (IncludeFile, Pathname);
465     return (IncludeFile);
466 }
467 
468 
469 /*******************************************************************************
470  *
471  * FUNCTION:    FlOpenIncludeFile
472  *
473  * PARAMETERS:  Op        - Parse node for the INCLUDE ASL statement
474  *
475  * RETURN:      None.
476  *
477  * DESCRIPTION: Open an include file and push it on the input file stack.
478  *
479  ******************************************************************************/
480 
481 void
482 FlOpenIncludeFile (
483     ACPI_PARSE_OBJECT       *Op)
484 {
485     FILE                    *IncludeFile;
486     ASL_INCLUDE_DIR         *NextDir;
487 
488 
489     /* Op must be valid */
490 
491     if (!Op)
492     {
493         AslCommonError (ASL_ERROR, ASL_MSG_INCLUDE_FILE_OPEN,
494             Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
495             Gbl_InputByteCount, Gbl_CurrentColumn,
496             Gbl_Files[ASL_FILE_INPUT].Filename, " - Null parse node");
497 
498         return;
499     }
500 
501     /*
502      * Flush out the "include ()" statement on this line, start
503      * the actual include file on the next line
504      */
505     AslResetCurrentLineBuffer ();
506     FlPrintFile (ASL_FILE_SOURCE_OUTPUT, "\n");
507     Gbl_CurrentLineOffset++;
508 
509 
510     /* Attempt to open the include file */
511 
512     /* If the file specifies an absolute path, just open it */
513 
514     if ((Op->Asl.Value.String[0] == '/')  ||
515         (Op->Asl.Value.String[0] == '\\') ||
516         (Op->Asl.Value.String[1] == ':'))
517     {
518         IncludeFile = FlOpenIncludeWithPrefix ("", Op, Op->Asl.Value.String);
519         if (!IncludeFile)
520         {
521             goto ErrorExit;
522         }
523         return;
524     }
525 
526     /*
527      * The include filename is not an absolute path.
528      *
529      * First, search for the file within the "local" directory -- meaning
530      * the same directory that contains the source file.
531      *
532      * Construct the file pathname from the global directory name.
533      */
534     IncludeFile = FlOpenIncludeWithPrefix (
535         Gbl_DirectoryPath, Op, Op->Asl.Value.String);
536     if (IncludeFile)
537     {
538         return;
539     }
540 
541     /*
542      * Second, search for the file within the (possibly multiple) directories
543      * specified by the -I option on the command line.
544      */
545     NextDir = Gbl_IncludeDirList;
546     while (NextDir)
547     {
548         IncludeFile = FlOpenIncludeWithPrefix (
549             NextDir->Dir, Op, Op->Asl.Value.String);
550         if (IncludeFile)
551         {
552             return;
553         }
554 
555         NextDir = NextDir->Next;
556     }
557 
558     /* We could not open the include file after trying very hard */
559 
560 ErrorExit:
561     sprintf (MsgBuffer, "%s, %s", Op->Asl.Value.String, strerror (errno));
562     AslError (ASL_ERROR, ASL_MSG_INCLUDE_FILE_OPEN, Op, MsgBuffer);
563 }
564 
565 
566 /*******************************************************************************
567  *
568  * FUNCTION:    FlOpenInputFile
569  *
570  * PARAMETERS:  InputFilename       - The user-specified ASL source file to be
571  *                                    compiled
572  *
573  * RETURN:      Status
574  *
575  * DESCRIPTION: Open the specified input file, and save the directory path to
576  *              the file so that include files can be opened in
577  *              the same directory.
578  *
579  ******************************************************************************/
580 
581 ACPI_STATUS
582 FlOpenInputFile (
583     char                    *InputFilename)
584 {
585 
586     /* Open the input ASL file, text mode */
587 
588     FlOpenFile (ASL_FILE_INPUT, InputFilename, "rt");
589     AslCompilerin = Gbl_Files[ASL_FILE_INPUT].Handle;
590 
591     return (AE_OK);
592 }
593 
594 
595 /*******************************************************************************
596  *
597  * FUNCTION:    FlOpenAmlOutputFile
598  *
599  * PARAMETERS:  FilenamePrefix       - The user-specified ASL source file
600  *
601  * RETURN:      Status
602  *
603  * DESCRIPTION: Create the output filename (*.AML) and open the file. The file
604  *              is created in the same directory as the parent input file.
605  *
606  ******************************************************************************/
607 
608 ACPI_STATUS
609 FlOpenAmlOutputFile (
610     char                    *FilenamePrefix)
611 {
612     char                    *Filename;
613 
614 
615     /* Output filename usually comes from the ASL itself */
616 
617     Filename = Gbl_Files[ASL_FILE_AML_OUTPUT].Filename;
618     if (!Filename)
619     {
620         /* Create the output AML filename */
621         if (!Gbl_CaptureComments)
622         {
623             Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_AML_CODE);
624         }
625         else
626         {
627             Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_CONVERT_AML);
628         }
629         if (!Filename)
630         {
631             AslCommonError (ASL_ERROR, ASL_MSG_OUTPUT_FILENAME,
632                 0, 0, 0, 0, NULL, NULL);
633             return (AE_ERROR);
634         }
635 
636         Gbl_Files[ASL_FILE_AML_OUTPUT].Filename = Filename;
637     }
638 
639     /* Open the output AML file in binary mode */
640 
641     FlOpenFile (ASL_FILE_AML_OUTPUT, Filename, "w+b");
642     return (AE_OK);
643 }
644 
645 
646 /*******************************************************************************
647  *
648  * FUNCTION:    FlOpenMiscOutputFiles
649  *
650  * PARAMETERS:  FilenamePrefix       - The user-specified ASL source file
651  *
652  * RETURN:      Status
653  *
654  * DESCRIPTION: Create and open the various output files needed, depending on
655  *              the command line options
656  *
657  ******************************************************************************/
658 
659 ACPI_STATUS
660 FlOpenMiscOutputFiles (
661     char                    *FilenamePrefix)
662 {
663     char                    *Filename;
664 
665 
666      /* Create/Open a map file if requested */
667 
668     if (Gbl_MapfileFlag)
669     {
670         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_MAP);
671         if (!Filename)
672         {
673             AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
674                 0, 0, 0, 0, NULL, NULL);
675             return (AE_ERROR);
676         }
677 
678         /* Open the hex file, text mode (closed at compiler exit) */
679 
680         FlOpenFile (ASL_FILE_MAP_OUTPUT, Filename, "w+t");
681 
682         AslCompilerSignon (ASL_FILE_MAP_OUTPUT);
683         AslCompilerFileHeader (ASL_FILE_MAP_OUTPUT);
684     }
685 
686     /* All done for disassembler */
687 
688     if (Gbl_FileType == ASL_INPUT_TYPE_BINARY_ACPI_TABLE)
689     {
690         return (AE_OK);
691     }
692 
693     /* Create/Open a hex output file if asked */
694 
695     if (Gbl_HexOutputFlag)
696     {
697         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_HEX_DUMP);
698         if (!Filename)
699         {
700             AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
701                 0, 0, 0, 0, NULL, NULL);
702             return (AE_ERROR);
703         }
704 
705         /* Open the hex file, text mode */
706 
707         FlOpenFile (ASL_FILE_HEX_OUTPUT, Filename, "w+t");
708 
709         AslCompilerSignon (ASL_FILE_HEX_OUTPUT);
710         AslCompilerFileHeader (ASL_FILE_HEX_OUTPUT);
711     }
712 
713     /* Create/Open a debug output file if asked */
714 
715     if (Gbl_DebugFlag)
716     {
717         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_DEBUG);
718         if (!Filename)
719         {
720             AslCommonError (ASL_ERROR, ASL_MSG_DEBUG_FILENAME,
721                 0, 0, 0, 0, NULL, NULL);
722             return (AE_ERROR);
723         }
724 
725         /* Open the debug file as STDERR, text mode */
726 
727         Gbl_Files[ASL_FILE_DEBUG_OUTPUT].Filename = Filename;
728         Gbl_Files[ASL_FILE_DEBUG_OUTPUT].Handle =
729             freopen (Filename, "w+t", stderr);
730 
731         if (!Gbl_Files[ASL_FILE_DEBUG_OUTPUT].Handle)
732         {
733             /*
734              * A problem with freopen is that on error, we no longer
735              * have stderr and cannot emit normal error messages.
736              * Emit error to stdout, close files, and exit.
737              */
738             fprintf (stdout,
739                 "\nCould not open debug output file: %s\n\n", Filename);
740 
741             CmCleanupAndExit ();
742             exit (1);
743         }
744 
745         AslCompilerSignon (ASL_FILE_DEBUG_OUTPUT);
746         AslCompilerFileHeader (ASL_FILE_DEBUG_OUTPUT);
747     }
748 
749     /* Create/Open a cross-reference output file if asked */
750 
751     if (Gbl_CrossReferenceOutput)
752     {
753         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_XREF);
754         if (!Filename)
755         {
756             AslCommonError (ASL_ERROR, ASL_MSG_DEBUG_FILENAME,
757                 0, 0, 0, 0, NULL, NULL);
758             return (AE_ERROR);
759         }
760 
761         FlOpenFile (ASL_FILE_XREF_OUTPUT, Filename, "w+t");
762 
763         AslCompilerSignon (ASL_FILE_XREF_OUTPUT);
764         AslCompilerFileHeader (ASL_FILE_XREF_OUTPUT);
765     }
766 
767     /* Create/Open a listing output file if asked */
768 
769     if (Gbl_ListingFlag)
770     {
771         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_LISTING);
772         if (!Filename)
773         {
774             AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
775                 0, 0, 0, 0, NULL, NULL);
776             return (AE_ERROR);
777         }
778 
779         /* Open the listing file, text mode */
780 
781         FlOpenFile (ASL_FILE_LISTING_OUTPUT, Filename, "w+t");
782 
783         AslCompilerSignon (ASL_FILE_LISTING_OUTPUT);
784         AslCompilerFileHeader (ASL_FILE_LISTING_OUTPUT);
785     }
786 
787     /* Create the preprocessor output temp file if preprocessor enabled */
788 
789     if (Gbl_PreprocessFlag)
790     {
791         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_PREPROCESSOR);
792         if (!Filename)
793         {
794             AslCommonError (ASL_ERROR, ASL_MSG_PREPROCESSOR_FILENAME,
795                 0, 0, 0, 0, NULL, NULL);
796             return (AE_ERROR);
797         }
798 
799         FlOpenFile (ASL_FILE_PREPROCESSOR, Filename, "w+t");
800     }
801 
802     /*
803      * Create the "user" preprocessor output file if -li flag set.
804      * Note, this file contains no embedded #line directives.
805      */
806     if (Gbl_PreprocessorOutputFlag)
807     {
808         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_PREPROC_USER);
809         if (!Filename)
810         {
811             AslCommonError (ASL_ERROR, ASL_MSG_PREPROCESSOR_FILENAME,
812                 0, 0, 0, 0, NULL, NULL);
813             return (AE_ERROR);
814         }
815 
816         FlOpenFile (ASL_FILE_PREPROCESSOR_USER, Filename, "w+t");
817     }
818 
819     /* All done for data table compiler */
820 
821     if (Gbl_FileType == ASL_INPUT_TYPE_ASCII_DATA)
822     {
823         return (AE_OK);
824     }
825 
826     /* Create/Open a combined source output file */
827 
828     Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_SOURCE);
829     if (!Filename)
830     {
831         AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
832             0, 0, 0, 0, NULL, NULL);
833         return (AE_ERROR);
834     }
835 
836     /*
837      * Open the source output file, binary mode (so that LF does not get
838      * expanded to CR/LF on some systems, messing up our seek
839      * calculations.)
840      */
841     FlOpenFile (ASL_FILE_SOURCE_OUTPUT, Filename, "w+b");
842 
843 /*
844 // TBD: TEMP
845 //    AslCompilerin = Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle;
846 */
847     /* Create/Open a assembly code source output file if asked */
848 
849     if (Gbl_AsmOutputFlag)
850     {
851         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_ASM_SOURCE);
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 assembly code source file, text mode */
860 
861         FlOpenFile (ASL_FILE_ASM_SOURCE_OUTPUT, Filename, "w+t");
862 
863         AslCompilerSignon (ASL_FILE_ASM_SOURCE_OUTPUT);
864         AslCompilerFileHeader (ASL_FILE_ASM_SOURCE_OUTPUT);
865     }
866 
867     /* Create/Open a C code source output file if asked */
868 
869     if (Gbl_C_OutputFlag)
870     {
871         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_C_SOURCE);
872         if (!Filename)
873         {
874             AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
875                 0, 0, 0, 0, NULL, NULL);
876             return (AE_ERROR);
877         }
878 
879         /* Open the C code source file, text mode */
880 
881         FlOpenFile (ASL_FILE_C_SOURCE_OUTPUT, Filename, "w+t");
882 
883         FlPrintFile (ASL_FILE_C_SOURCE_OUTPUT, "/*\n");
884         AslCompilerSignon (ASL_FILE_C_SOURCE_OUTPUT);
885         AslCompilerFileHeader (ASL_FILE_C_SOURCE_OUTPUT);
886     }
887 
888     /* Create/Open a C code source output file for the offset table if asked */
889 
890     if (Gbl_C_OffsetTableFlag)
891     {
892         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_C_OFFSET);
893         if (!Filename)
894         {
895             AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
896                 0, 0, 0, 0, NULL, NULL);
897             return (AE_ERROR);
898         }
899 
900         /* Open the C code source file, text mode */
901 
902         FlOpenFile (ASL_FILE_C_OFFSET_OUTPUT, Filename, "w+t");
903 
904         FlPrintFile (ASL_FILE_C_OFFSET_OUTPUT, "/*\n");
905         AslCompilerSignon (ASL_FILE_C_OFFSET_OUTPUT);
906         AslCompilerFileHeader (ASL_FILE_C_OFFSET_OUTPUT);
907     }
908 
909     /* Create/Open a assembly include output file if asked */
910 
911     if (Gbl_AsmIncludeOutputFlag)
912     {
913         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_ASM_INCLUDE);
914         if (!Filename)
915         {
916             AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
917                 0, 0, 0, 0, NULL, NULL);
918             return (AE_ERROR);
919         }
920 
921         /* Open the assembly include file, text mode */
922 
923         FlOpenFile (ASL_FILE_ASM_INCLUDE_OUTPUT, Filename, "w+t");
924 
925         AslCompilerSignon (ASL_FILE_ASM_INCLUDE_OUTPUT);
926         AslCompilerFileHeader (ASL_FILE_ASM_INCLUDE_OUTPUT);
927     }
928 
929     /* Create/Open a C include output file if asked */
930 
931     if (Gbl_C_IncludeOutputFlag)
932     {
933         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_C_INCLUDE);
934         if (!Filename)
935         {
936             AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
937                 0, 0, 0, 0, NULL, NULL);
938             return (AE_ERROR);
939         }
940 
941         /* Open the C include file, text mode */
942 
943         FlOpenFile (ASL_FILE_C_INCLUDE_OUTPUT, Filename, "w+t");
944 
945         FlPrintFile (ASL_FILE_C_INCLUDE_OUTPUT, "/*\n");
946         AslCompilerSignon (ASL_FILE_C_INCLUDE_OUTPUT);
947         AslCompilerFileHeader (ASL_FILE_C_INCLUDE_OUTPUT);
948     }
949 
950     /* Create a namespace output file if asked */
951 
952     if (Gbl_NsOutputFlag)
953     {
954         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_NAMESPACE);
955         if (!Filename)
956         {
957             AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
958                 0, 0, 0, 0, NULL, NULL);
959             return (AE_ERROR);
960         }
961 
962         /* Open the namespace file, text mode */
963 
964         FlOpenFile (ASL_FILE_NAMESPACE_OUTPUT, Filename, "w+t");
965 
966         AslCompilerSignon (ASL_FILE_NAMESPACE_OUTPUT);
967         AslCompilerFileHeader (ASL_FILE_NAMESPACE_OUTPUT);
968     }
969 
970     /* Create a debug file for the converter */
971 
972     if (AcpiGbl_DebugAslConversion)
973     {
974         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_CONVERT_DEBUG);
975         if (!Filename)
976         {
977             AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
978                 0, 0, 0, 0, NULL, NULL);
979             return (AE_ERROR);
980         }
981 
982         /* Open the converter debug file, text mode */
983 
984         FlOpenFile (ASL_FILE_CONV_DEBUG_OUTPUT, Filename, "w+t");
985 
986         AslCompilerSignon (ASL_FILE_CONV_DEBUG_OUTPUT);
987         AslCompilerFileHeader (ASL_FILE_CONV_DEBUG_OUTPUT);
988 
989         AcpiGbl_ConvDebugFile = Gbl_Files[ASL_FILE_CONV_DEBUG_OUTPUT].Handle;
990     }
991 
992     return (AE_OK);
993 }
994 
995 
996 #ifdef ACPI_OBSOLETE_FUNCTIONS
997 /*******************************************************************************
998  *
999  * FUNCTION:    FlParseInputPathname
1000  *
1001  * PARAMETERS:  InputFilename       - The user-specified ASL source file to be
1002  *                                    compiled
1003  *
1004  * RETURN:      Status
1005  *
1006  * DESCRIPTION: Split the input path into a directory and filename part
1007  *              1) Directory part used to open include files
1008  *              2) Filename part used to generate output filenames
1009  *
1010  ******************************************************************************/
1011 
1012 ACPI_STATUS
1013 FlParseInputPathname (
1014     char                    *InputFilename)
1015 {
1016     char                    *Substring;
1017 
1018 
1019     if (!InputFilename)
1020     {
1021         return (AE_OK);
1022     }
1023 
1024     /* Get the path to the input filename's directory */
1025 
1026     Gbl_DirectoryPath = strdup (InputFilename);
1027     if (!Gbl_DirectoryPath)
1028     {
1029         return (AE_NO_MEMORY);
1030     }
1031 
1032     Substring = strrchr (Gbl_DirectoryPath, '\\');
1033     if (!Substring)
1034     {
1035         Substring = strrchr (Gbl_DirectoryPath, '/');
1036         if (!Substring)
1037         {
1038             Substring = strrchr (Gbl_DirectoryPath, ':');
1039         }
1040     }
1041 
1042     if (!Substring)
1043     {
1044         Gbl_DirectoryPath[0] = 0;
1045         if (Gbl_UseDefaultAmlFilename)
1046         {
1047             Gbl_OutputFilenamePrefix = strdup (InputFilename);
1048         }
1049     }
1050     else
1051     {
1052         if (Gbl_UseDefaultAmlFilename)
1053         {
1054             Gbl_OutputFilenamePrefix = strdup (Substring + 1);
1055         }
1056         *(Substring+1) = 0;
1057     }
1058 
1059     UtConvertBackslashes (Gbl_OutputFilenamePrefix);
1060     return (AE_OK);
1061 }
1062 #endif
1063