1 /******************************************************************************
2  *
3  * Module Name: aslfiles - File support functions
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2015, 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 #include "dtcompiler.h"
47 
48 #define _COMPONENT          ACPI_COMPILER
49         ACPI_MODULE_NAME    ("aslfiles")
50 
51 /* Local prototypes */
52 
53 static FILE *
54 FlOpenIncludeWithPrefix (
55     char                    *PrefixDir,
56     ACPI_PARSE_OBJECT       *Op,
57     char                    *Filename);
58 
59 
60 #ifdef ACPI_OBSOLETE_FUNCTIONS
61 ACPI_STATUS
62 FlParseInputPathname (
63     char                    *InputFilename);
64 #endif
65 
66 
67 /*******************************************************************************
68  *
69  * FUNCTION:    FlSetLineNumber
70  *
71  * PARAMETERS:  Op        - Parse node for the LINE asl statement
72  *
73  * RETURN:      None.
74  *
75  * DESCRIPTION: Set the current line number
76  *
77  ******************************************************************************/
78 
79 void
80 FlSetLineNumber (
81     UINT32                  LineNumber)
82 {
83 
84     DbgPrint (ASL_PARSE_OUTPUT, "\n#line: New line number %u (old %u)\n",
85          LineNumber, Gbl_LogicalLineNumber);
86 
87     Gbl_CurrentLineNumber = LineNumber;
88 }
89 
90 
91 /*******************************************************************************
92  *
93  * FUNCTION:    FlSetFilename
94  *
95  * PARAMETERS:  Op        - Parse node for the LINE asl statement
96  *
97  * RETURN:      None.
98  *
99  * DESCRIPTION: Set the current filename
100  *
101  ******************************************************************************/
102 
103 void
104 FlSetFilename (
105     char                    *Filename)
106 {
107 
108     DbgPrint (ASL_PARSE_OUTPUT, "\n#line: New filename %s (old %s)\n",
109          Filename, Gbl_Files[ASL_FILE_INPUT].Filename);
110 
111     /* No need to free any existing filename */
112 
113     Gbl_Files[ASL_FILE_INPUT].Filename = Filename;
114 }
115 
116 
117 /*******************************************************************************
118  *
119  * FUNCTION:    FlAddIncludeDirectory
120  *
121  * PARAMETERS:  Dir             - Directory pathname string
122  *
123  * RETURN:      None
124  *
125  * DESCRIPTION: Add a directory the list of include prefix directories.
126  *
127  ******************************************************************************/
128 
129 void
130 FlAddIncludeDirectory (
131     char                    *Dir)
132 {
133     ASL_INCLUDE_DIR         *NewDir;
134     ASL_INCLUDE_DIR         *NextDir;
135     ASL_INCLUDE_DIR         *PrevDir = NULL;
136     UINT32                  NeedsSeparator = 0;
137     size_t                  DirLength;
138 
139 
140     DirLength = strlen (Dir);
141     if (!DirLength)
142     {
143         return;
144     }
145 
146     /* Make sure that the pathname ends with a path separator */
147 
148     if ((Dir[DirLength-1] != '/') &&
149         (Dir[DirLength-1] != '\\'))
150     {
151         NeedsSeparator = 1;
152     }
153 
154     NewDir = ACPI_ALLOCATE_ZEROED (sizeof (ASL_INCLUDE_DIR));
155     NewDir->Dir = ACPI_ALLOCATE (DirLength + 1 + NeedsSeparator);
156     strcpy (NewDir->Dir, Dir);
157     if (NeedsSeparator)
158     {
159         strcat (NewDir->Dir, "/");
160     }
161 
162     /*
163      * Preserve command line ordering of -I options by adding new elements
164      * at the end of the list
165      */
166     NextDir = Gbl_IncludeDirList;
167     while (NextDir)
168     {
169         PrevDir = NextDir;
170         NextDir = NextDir->Next;
171     }
172 
173     if (PrevDir)
174     {
175         PrevDir->Next = NewDir;
176     }
177     else
178     {
179         Gbl_IncludeDirList = NewDir;
180     }
181 }
182 
183 
184 /*******************************************************************************
185  *
186  * FUNCTION:    FlMergePathnames
187  *
188  * PARAMETERS:  PrefixDir       - Prefix directory pathname. Can be NULL or
189  *                                a zero length string.
190  *              FilePathname    - The include filename from the source ASL.
191  *
192  * RETURN:      Merged pathname string
193  *
194  * DESCRIPTION: Merge two pathnames that (probably) have common elements, to
195  *              arrive at a minimal length string. Merge can occur if the
196  *              FilePathname is relative to the PrefixDir.
197  *
198  ******************************************************************************/
199 
200 char *
201 FlMergePathnames (
202     char                    *PrefixDir,
203     char                    *FilePathname)
204 {
205     char                    *CommonPath;
206     char                    *Pathname;
207     char                    *LastElement;
208 
209 
210     DbgPrint (ASL_PARSE_OUTPUT, "Include: Prefix path - \"%s\"\n"
211         "Include: FilePathname - \"%s\"\n",
212          PrefixDir, FilePathname);
213 
214     /*
215      * If there is no prefix directory or if the file pathname is absolute,
216      * just return the original file pathname
217      */
218     if (!PrefixDir || (!*PrefixDir) ||
219         (*FilePathname == '/') ||
220          (FilePathname[1] == ':'))
221     {
222         Pathname = UtStringCacheCalloc (strlen (FilePathname) + 1);
223         strcpy (Pathname, FilePathname);
224         goto ConvertBackslashes;
225     }
226 
227     /* Need a local copy of the prefix directory path */
228 
229     CommonPath = UtStringCacheCalloc (strlen (PrefixDir) + 1);
230     strcpy (CommonPath, PrefixDir);
231 
232     /*
233      * Walk forward through the file path, and simultaneously backward
234      * through the prefix directory path until there are no more
235      * relative references at the start of the file path.
236      */
237     while (*FilePathname && (!strncmp (FilePathname, "../", 3)))
238     {
239         /* Remove last element of the prefix directory path */
240 
241         LastElement = strrchr (CommonPath, '/');
242         if (!LastElement)
243         {
244             goto ConcatenatePaths;
245         }
246 
247         *LastElement = 0;   /* Terminate CommonPath string */
248         FilePathname += 3;  /* Point to next path element */
249     }
250 
251     /*
252      * Remove the last element of the prefix directory path (it is the same as
253      * the first element of the file pathname), and build the final merged
254      * pathname.
255      */
256     LastElement = strrchr (CommonPath, '/');
257     if (LastElement)
258     {
259         *LastElement = 0;
260     }
261 
262     /* Build the final merged pathname */
263 
264 ConcatenatePaths:
265     Pathname = UtStringCacheCalloc (strlen (CommonPath) + strlen (FilePathname) + 2);
266     if (LastElement && *CommonPath)
267     {
268         strcpy (Pathname, CommonPath);
269         strcat (Pathname, "/");
270     }
271     strcat (Pathname, FilePathname);
272 
273     /* Convert all backslashes to normal slashes */
274 
275 ConvertBackslashes:
276     UtConvertBackslashes (Pathname);
277 
278     DbgPrint (ASL_PARSE_OUTPUT, "Include: Merged Pathname - \"%s\"\n",
279          Pathname);
280     return (Pathname);
281 }
282 
283 
284 /*******************************************************************************
285  *
286  * FUNCTION:    FlOpenIncludeWithPrefix
287  *
288  * PARAMETERS:  PrefixDir       - Prefix directory pathname. Can be a zero
289  *                                length string.
290  *              Filename        - The include filename from the source ASL.
291  *
292  * RETURN:      Valid file descriptor if successful. Null otherwise.
293  *
294  * DESCRIPTION: Open an include file and push it on the input file stack.
295  *
296  ******************************************************************************/
297 
298 static FILE *
299 FlOpenIncludeWithPrefix (
300     char                    *PrefixDir,
301     ACPI_PARSE_OBJECT       *Op,
302     char                    *Filename)
303 {
304     FILE                    *IncludeFile;
305     char                    *Pathname;
306     UINT32                  OriginalLineNumber;
307 
308 
309     /* Build the full pathname to the file */
310 
311     Pathname = FlMergePathnames (PrefixDir, Filename);
312 
313     DbgPrint (ASL_PARSE_OUTPUT, "Include: Opening file - \"%s\"\n\n",
314         Pathname);
315 
316     /* Attempt to open the file, push if successful */
317 
318     IncludeFile = fopen (Pathname, "r");
319     if (!IncludeFile)
320     {
321         fprintf (stderr, "Could not open include file %s\n", Pathname);
322         ACPI_FREE (Pathname);
323         return (NULL);
324     }
325 
326     /*
327      * Check the entire include file for any # preprocessor directives.
328      * This is because there may be some confusion between the #include
329      * preprocessor directive and the ASL Include statement. A file included
330      * by the ASL include cannot contain preprocessor directives because
331      * the preprocessor has already run by the time the ASL include is
332      * recognized (by the compiler, not the preprocessor.)
333      *
334      * Note: DtGetNextLine strips/ignores comments.
335      * Save current line number since DtGetNextLine modifies it.
336      */
337     Gbl_CurrentLineNumber--;
338     OriginalLineNumber = Gbl_CurrentLineNumber;
339     while (DtGetNextLine (IncludeFile, DT_ALLOW_MULTILINE_QUOTES) != ASL_EOF)
340     {
341         if (Gbl_CurrentLineBuffer[0] == '#')
342         {
343             AslError (ASL_ERROR, ASL_MSG_INCLUDE_FILE,
344                 Op, "use #include instead");
345         }
346     }
347     Gbl_CurrentLineNumber = OriginalLineNumber;
348 
349     /* Must seek back to the start of the file */
350 
351     fseek (IncludeFile, 0, SEEK_SET);
352 
353     /* Push the include file on the open input file stack */
354 
355     AslPushInputFileStack (IncludeFile, Pathname);
356     return (IncludeFile);
357 }
358 
359 
360 /*******************************************************************************
361  *
362  * FUNCTION:    FlOpenIncludeFile
363  *
364  * PARAMETERS:  Op        - Parse node for the INCLUDE ASL statement
365  *
366  * RETURN:      None.
367  *
368  * DESCRIPTION: Open an include file and push it on the input file stack.
369  *
370  ******************************************************************************/
371 
372 void
373 FlOpenIncludeFile (
374     ACPI_PARSE_OBJECT       *Op)
375 {
376     FILE                    *IncludeFile;
377     ASL_INCLUDE_DIR         *NextDir;
378 
379 
380     /* Op must be valid */
381 
382     if (!Op)
383     {
384         AslCommonError (ASL_ERROR, ASL_MSG_INCLUDE_FILE_OPEN,
385             Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
386             Gbl_InputByteCount, Gbl_CurrentColumn,
387             Gbl_Files[ASL_FILE_INPUT].Filename, " - Null parse node");
388 
389         return;
390     }
391 
392     /*
393      * Flush out the "include ()" statement on this line, start
394      * the actual include file on the next line
395      */
396     AslResetCurrentLineBuffer ();
397     FlPrintFile (ASL_FILE_SOURCE_OUTPUT, "\n");
398     Gbl_CurrentLineOffset++;
399 
400 
401     /* Attempt to open the include file */
402 
403     /* If the file specifies an absolute path, just open it */
404 
405     if ((Op->Asl.Value.String[0] == '/')  ||
406         (Op->Asl.Value.String[0] == '\\') ||
407         (Op->Asl.Value.String[1] == ':'))
408     {
409         IncludeFile = FlOpenIncludeWithPrefix ("", Op, Op->Asl.Value.String);
410         if (!IncludeFile)
411         {
412             goto ErrorExit;
413         }
414         return;
415     }
416 
417     /*
418      * The include filename is not an absolute path.
419      *
420      * First, search for the file within the "local" directory -- meaning
421      * the same directory that contains the source file.
422      *
423      * Construct the file pathname from the global directory name.
424      */
425     IncludeFile = FlOpenIncludeWithPrefix (Gbl_DirectoryPath, Op, Op->Asl.Value.String);
426     if (IncludeFile)
427     {
428         return;
429     }
430 
431     /*
432      * Second, search for the file within the (possibly multiple) directories
433      * specified by the -I option on the command line.
434      */
435     NextDir = Gbl_IncludeDirList;
436     while (NextDir)
437     {
438         IncludeFile = FlOpenIncludeWithPrefix (NextDir->Dir, Op, Op->Asl.Value.String);
439         if (IncludeFile)
440         {
441             return;
442         }
443 
444         NextDir = NextDir->Next;
445     }
446 
447     /* We could not open the include file after trying very hard */
448 
449 ErrorExit:
450     sprintf (MsgBuffer, "%s, %s", Op->Asl.Value.String, strerror (errno));
451     AslError (ASL_ERROR, ASL_MSG_INCLUDE_FILE_OPEN, Op, MsgBuffer);
452 }
453 
454 
455 /*******************************************************************************
456  *
457  * FUNCTION:    FlOpenInputFile
458  *
459  * PARAMETERS:  InputFilename       - The user-specified ASL source file to be
460  *                                    compiled
461  *
462  * RETURN:      Status
463  *
464  * DESCRIPTION: Open the specified input file, and save the directory path to
465  *              the file so that include files can be opened in
466  *              the same directory.
467  *
468  ******************************************************************************/
469 
470 ACPI_STATUS
471 FlOpenInputFile (
472     char                    *InputFilename)
473 {
474 
475     /* Open the input ASL file, text mode */
476 
477     FlOpenFile (ASL_FILE_INPUT, InputFilename, "rt");
478     AslCompilerin = Gbl_Files[ASL_FILE_INPUT].Handle;
479 
480     return (AE_OK);
481 }
482 
483 
484 /*******************************************************************************
485  *
486  * FUNCTION:    FlOpenAmlOutputFile
487  *
488  * PARAMETERS:  FilenamePrefix       - The user-specified ASL source file
489  *
490  * RETURN:      Status
491  *
492  * DESCRIPTION: Create the output filename (*.AML) and open the file. The file
493  *              is created in the same directory as the parent input file.
494  *
495  ******************************************************************************/
496 
497 ACPI_STATUS
498 FlOpenAmlOutputFile (
499     char                    *FilenamePrefix)
500 {
501     char                    *Filename;
502 
503 
504     /* Output filename usually comes from the ASL itself */
505 
506     Filename = Gbl_Files[ASL_FILE_AML_OUTPUT].Filename;
507     if (!Filename)
508     {
509         /* Create the output AML filename */
510 
511         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_AML_CODE);
512         if (!Filename)
513         {
514             AslCommonError (ASL_ERROR, ASL_MSG_OUTPUT_FILENAME,
515                 0, 0, 0, 0, NULL, NULL);
516             return (AE_ERROR);
517         }
518 
519         Gbl_Files[ASL_FILE_AML_OUTPUT].Filename = Filename;
520     }
521 
522     /* Open the output AML file in binary mode */
523 
524     FlOpenFile (ASL_FILE_AML_OUTPUT, Filename, "w+b");
525     return (AE_OK);
526 }
527 
528 
529 /*******************************************************************************
530  *
531  * FUNCTION:    FlOpenMiscOutputFiles
532  *
533  * PARAMETERS:  FilenamePrefix       - The user-specified ASL source file
534  *
535  * RETURN:      Status
536  *
537  * DESCRIPTION: Create and open the various output files needed, depending on
538  *              the command line options
539  *
540  ******************************************************************************/
541 
542 ACPI_STATUS
543 FlOpenMiscOutputFiles (
544     char                    *FilenamePrefix)
545 {
546     char                    *Filename;
547 
548 
549      /* Create/Open a map file if requested */
550 
551     if (Gbl_MapfileFlag)
552     {
553         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_MAP);
554         if (!Filename)
555         {
556             AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
557                 0, 0, 0, 0, NULL, NULL);
558             return (AE_ERROR);
559         }
560 
561         /* Open the hex file, text mode (closed at compiler exit) */
562 
563         FlOpenFile (ASL_FILE_MAP_OUTPUT, Filename, "w+t");
564 
565         AslCompilerSignon (ASL_FILE_MAP_OUTPUT);
566         AslCompilerFileHeader (ASL_FILE_MAP_OUTPUT);
567     }
568 
569     /* All done for disassembler */
570 
571     if (Gbl_FileType == ASL_INPUT_TYPE_ACPI_TABLE)
572     {
573         return (AE_OK);
574     }
575 
576     /* Create/Open a hex output file if asked */
577 
578     if (Gbl_HexOutputFlag)
579     {
580         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_HEX_DUMP);
581         if (!Filename)
582         {
583             AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
584                 0, 0, 0, 0, NULL, NULL);
585             return (AE_ERROR);
586         }
587 
588         /* Open the hex file, text mode */
589 
590         FlOpenFile (ASL_FILE_HEX_OUTPUT, Filename, "w+t");
591 
592         AslCompilerSignon (ASL_FILE_HEX_OUTPUT);
593         AslCompilerFileHeader (ASL_FILE_HEX_OUTPUT);
594     }
595 
596     /* Create/Open a debug output file if asked */
597 
598     if (Gbl_DebugFlag)
599     {
600         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_DEBUG);
601         if (!Filename)
602         {
603             AslCommonError (ASL_ERROR, ASL_MSG_DEBUG_FILENAME,
604                 0, 0, 0, 0, NULL, NULL);
605             return (AE_ERROR);
606         }
607 
608         /* Open the debug file as STDERR, text mode */
609 
610         Gbl_Files[ASL_FILE_DEBUG_OUTPUT].Filename = Filename;
611         Gbl_Files[ASL_FILE_DEBUG_OUTPUT].Handle =
612             freopen (Filename, "w+t", stderr);
613 
614         if (!Gbl_Files[ASL_FILE_DEBUG_OUTPUT].Handle)
615         {
616             /*
617              * A problem with freopen is that on error, we no longer
618              * have stderr and cannot emit normal error messages.
619              * Emit error to stdout, close files, and exit.
620              */
621             fprintf (stdout,
622                 "\nCould not open debug output file: %s\n\n", Filename);
623 
624             CmCleanupAndExit ();
625             exit (1);
626         }
627 
628         AslCompilerSignon (ASL_FILE_DEBUG_OUTPUT);
629         AslCompilerFileHeader (ASL_FILE_DEBUG_OUTPUT);
630     }
631 
632     /* Create/Open a listing output file if asked */
633 
634     if (Gbl_ListingFlag)
635     {
636         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_LISTING);
637         if (!Filename)
638         {
639             AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
640                 0, 0, 0, 0, NULL, NULL);
641             return (AE_ERROR);
642         }
643 
644         /* Open the listing file, text mode */
645 
646         FlOpenFile (ASL_FILE_LISTING_OUTPUT, Filename, "w+t");
647 
648         AslCompilerSignon (ASL_FILE_LISTING_OUTPUT);
649         AslCompilerFileHeader (ASL_FILE_LISTING_OUTPUT);
650     }
651 
652     /* Create the preprocessor output temp file if preprocessor enabled */
653 
654     if (Gbl_PreprocessFlag)
655     {
656         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_PREPROCESSOR);
657         if (!Filename)
658         {
659             AslCommonError (ASL_ERROR, ASL_MSG_PREPROCESSOR_FILENAME,
660                 0, 0, 0, 0, NULL, NULL);
661             return (AE_ERROR);
662         }
663 
664         FlOpenFile (ASL_FILE_PREPROCESSOR, Filename, "w+t");
665     }
666 
667     /*
668      * Create the "user" preprocessor output file if -li flag set.
669      * Note, this file contains no embedded #line directives.
670      */
671     if (Gbl_PreprocessorOutputFlag)
672     {
673         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_PREPROC_USER);
674         if (!Filename)
675         {
676             AslCommonError (ASL_ERROR, ASL_MSG_PREPROCESSOR_FILENAME,
677                 0, 0, 0, 0, NULL, NULL);
678             return (AE_ERROR);
679         }
680 
681         FlOpenFile (ASL_FILE_PREPROCESSOR_USER, Filename, "w+t");
682     }
683 
684     /* All done for data table compiler */
685 
686     if (Gbl_FileType == ASL_INPUT_TYPE_ASCII_DATA)
687     {
688         return (AE_OK);
689     }
690 
691     /* Create/Open a combined source output file */
692 
693     Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_SOURCE);
694     if (!Filename)
695     {
696         AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
697             0, 0, 0, 0, NULL, NULL);
698         return (AE_ERROR);
699     }
700 
701     /*
702      * Open the source output file, binary mode (so that LF does not get
703      * expanded to CR/LF on some systems, messing up our seek
704      * calculations.)
705      */
706     FlOpenFile (ASL_FILE_SOURCE_OUTPUT, Filename, "w+b");
707 
708 /*
709 // TBD: TEMP
710 //    AslCompilerin = Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle;
711 */
712     /* Create/Open a assembly code source output file if asked */
713 
714     if (Gbl_AsmOutputFlag)
715     {
716         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_ASM_SOURCE);
717         if (!Filename)
718         {
719             AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
720                 0, 0, 0, 0, NULL, NULL);
721             return (AE_ERROR);
722         }
723 
724         /* Open the assembly code source file, text mode */
725 
726         FlOpenFile (ASL_FILE_ASM_SOURCE_OUTPUT, Filename, "w+t");
727 
728         AslCompilerSignon (ASL_FILE_ASM_SOURCE_OUTPUT);
729         AslCompilerFileHeader (ASL_FILE_ASM_SOURCE_OUTPUT);
730     }
731 
732     /* Create/Open a C code source output file if asked */
733 
734     if (Gbl_C_OutputFlag)
735     {
736         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_C_SOURCE);
737         if (!Filename)
738         {
739             AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
740                 0, 0, 0, 0, NULL, NULL);
741             return (AE_ERROR);
742         }
743 
744         /* Open the C code source file, text mode */
745 
746         FlOpenFile (ASL_FILE_C_SOURCE_OUTPUT, Filename, "w+t");
747 
748         FlPrintFile (ASL_FILE_C_SOURCE_OUTPUT, "/*\n");
749         AslCompilerSignon (ASL_FILE_C_SOURCE_OUTPUT);
750         AslCompilerFileHeader (ASL_FILE_C_SOURCE_OUTPUT);
751     }
752 
753     /* Create/Open a C code source output file for the offset table if asked */
754 
755     if (Gbl_C_OffsetTableFlag)
756     {
757         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_C_OFFSET);
758         if (!Filename)
759         {
760             AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
761                 0, 0, 0, 0, NULL, NULL);
762             return (AE_ERROR);
763         }
764 
765         /* Open the C code source file, text mode */
766 
767         FlOpenFile (ASL_FILE_C_OFFSET_OUTPUT, Filename, "w+t");
768 
769         FlPrintFile (ASL_FILE_C_OFFSET_OUTPUT, "/*\n");
770         AslCompilerSignon (ASL_FILE_C_OFFSET_OUTPUT);
771         AslCompilerFileHeader (ASL_FILE_C_OFFSET_OUTPUT);
772     }
773 
774     /* Create/Open a assembly include output file if asked */
775 
776     if (Gbl_AsmIncludeOutputFlag)
777     {
778         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_ASM_INCLUDE);
779         if (!Filename)
780         {
781             AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
782                 0, 0, 0, 0, NULL, NULL);
783             return (AE_ERROR);
784         }
785 
786         /* Open the assembly include file, text mode */
787 
788         FlOpenFile (ASL_FILE_ASM_INCLUDE_OUTPUT, Filename, "w+t");
789 
790         AslCompilerSignon (ASL_FILE_ASM_INCLUDE_OUTPUT);
791         AslCompilerFileHeader (ASL_FILE_ASM_INCLUDE_OUTPUT);
792     }
793 
794     /* Create/Open a C include output file if asked */
795 
796     if (Gbl_C_IncludeOutputFlag)
797     {
798         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_C_INCLUDE);
799         if (!Filename)
800         {
801             AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
802                 0, 0, 0, 0, NULL, NULL);
803             return (AE_ERROR);
804         }
805 
806         /* Open the C include file, text mode */
807 
808         FlOpenFile (ASL_FILE_C_INCLUDE_OUTPUT, Filename, "w+t");
809 
810         FlPrintFile (ASL_FILE_C_INCLUDE_OUTPUT, "/*\n");
811         AslCompilerSignon (ASL_FILE_C_INCLUDE_OUTPUT);
812         AslCompilerFileHeader (ASL_FILE_C_INCLUDE_OUTPUT);
813     }
814 
815     /* Create a namespace output file if asked */
816 
817     if (Gbl_NsOutputFlag)
818     {
819         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_NAMESPACE);
820         if (!Filename)
821         {
822             AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
823                 0, 0, 0, 0, NULL, NULL);
824             return (AE_ERROR);
825         }
826 
827         /* Open the namespace file, text mode */
828 
829         FlOpenFile (ASL_FILE_NAMESPACE_OUTPUT, Filename, "w+t");
830 
831         AslCompilerSignon (ASL_FILE_NAMESPACE_OUTPUT);
832         AslCompilerFileHeader (ASL_FILE_NAMESPACE_OUTPUT);
833     }
834 
835     return (AE_OK);
836 }
837 
838 
839 #ifdef ACPI_OBSOLETE_FUNCTIONS
840 /*******************************************************************************
841  *
842  * FUNCTION:    FlParseInputPathname
843  *
844  * PARAMETERS:  InputFilename       - The user-specified ASL source file to be
845  *                                    compiled
846  *
847  * RETURN:      Status
848  *
849  * DESCRIPTION: Split the input path into a directory and filename part
850  *              1) Directory part used to open include files
851  *              2) Filename part used to generate output filenames
852  *
853  ******************************************************************************/
854 
855 ACPI_STATUS
856 FlParseInputPathname (
857     char                    *InputFilename)
858 {
859     char                    *Substring;
860 
861 
862     if (!InputFilename)
863     {
864         return (AE_OK);
865     }
866 
867     /* Get the path to the input filename's directory */
868 
869     Gbl_DirectoryPath = strdup (InputFilename);
870     if (!Gbl_DirectoryPath)
871     {
872         return (AE_NO_MEMORY);
873     }
874 
875     Substring = strrchr (Gbl_DirectoryPath, '\\');
876     if (!Substring)
877     {
878         Substring = strrchr (Gbl_DirectoryPath, '/');
879         if (!Substring)
880         {
881             Substring = strrchr (Gbl_DirectoryPath, ':');
882         }
883     }
884 
885     if (!Substring)
886     {
887         Gbl_DirectoryPath[0] = 0;
888         if (Gbl_UseDefaultAmlFilename)
889         {
890             Gbl_OutputFilenamePrefix = strdup (InputFilename);
891         }
892     }
893     else
894     {
895         if (Gbl_UseDefaultAmlFilename)
896         {
897             Gbl_OutputFilenamePrefix = strdup (Substring + 1);
898         }
899         *(Substring+1) = 0;
900     }
901 
902     UtConvertBackslashes (Gbl_OutputFilenamePrefix);
903     return (AE_OK);
904 }
905 #endif
906