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