xref: /freebsd/sys/contrib/dev/acpica/compiler/aslfiles.c (revision c6ec7d31830ab1c80edae95ad5e4b9dba10c47ac)
1 /******************************************************************************
2  *
3  * Module Name: aslfiles - file I/O suppoert
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2012, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
45 #include <contrib/dev/acpica/include/acapps.h>
46 
47 #define _COMPONENT          ACPI_COMPILER
48         ACPI_MODULE_NAME    ("aslfiles")
49 
50 /* Local prototypes */
51 
52 FILE *
53 FlOpenIncludeWithPrefix (
54     char                    *PrefixDir,
55     char                    *Filename);
56 
57 
58 #ifdef ACPI_OBSOLETE_FUNCTIONS
59 ACPI_STATUS
60 FlParseInputPathname (
61     char                    *InputFilename);
62 #endif
63 
64 
65 /*******************************************************************************
66  *
67  * FUNCTION:    AslAbort
68  *
69  * PARAMETERS:  None
70  *
71  * RETURN:      None
72  *
73  * DESCRIPTION: Dump the error log and abort the compiler. Used for serious
74  *              I/O errors
75  *
76  ******************************************************************************/
77 
78 void
79 AslAbort (
80     void)
81 {
82 
83     AePrintErrorLog (ASL_FILE_STDERR);
84     if (Gbl_DebugFlag)
85     {
86         /* Print error summary to stdout also */
87 
88         AePrintErrorLog (ASL_FILE_STDOUT);
89     }
90 
91     exit (1);
92 }
93 
94 
95 /*******************************************************************************
96  *
97  * FUNCTION:    FlFileError
98  *
99  * PARAMETERS:  FileId              - Index into file info array
100  *              ErrorId             - Index into error message array
101  *
102  * RETURN:      None
103  *
104  * DESCRIPTION: Decode errno to an error message and add the entire error
105  *              to the error log.
106  *
107  ******************************************************************************/
108 
109 void
110 FlFileError (
111     UINT32                  FileId,
112     UINT8                   ErrorId)
113 {
114 
115     sprintf (MsgBuffer, "\"%s\" (%s)", Gbl_Files[FileId].Filename,
116         strerror (errno));
117     AslCommonError (ASL_ERROR, ErrorId, 0, 0, 0, 0, NULL, MsgBuffer);
118 }
119 
120 
121 /*******************************************************************************
122  *
123  * FUNCTION:    FlOpenFile
124  *
125  * PARAMETERS:  FileId              - Index into file info array
126  *              Filename            - file pathname to open
127  *              Mode                - Open mode for fopen
128  *
129  * RETURN:      None
130  *
131  * DESCRIPTION: Open a file.
132  *              NOTE: Aborts compiler on any error.
133  *
134  ******************************************************************************/
135 
136 void
137 FlOpenFile (
138     UINT32                  FileId,
139     char                    *Filename,
140     char                    *Mode)
141 {
142     FILE                    *File;
143 
144 
145     File = fopen (Filename, Mode);
146     if (!File)
147     {
148         FlFileError (FileId, ASL_MSG_OPEN);
149         AslAbort ();
150     }
151 
152     Gbl_Files[FileId].Filename = Filename;
153     Gbl_Files[FileId].Handle   = File;
154 }
155 
156 
157 /*******************************************************************************
158  *
159  * FUNCTION:    FlGetFileSize
160  *
161  * PARAMETERS:  FileId              - Index into file info array
162  *
163  * RETURN:      File Size
164  *
165  * DESCRIPTION: Get current file size. Uses seek-to-EOF. File must be open.
166  *
167  ******************************************************************************/
168 
169 UINT32
170 FlGetFileSize (
171     UINT32                  FileId)
172 {
173     FILE                    *fp;
174     UINT32                  FileSize;
175     long                    Offset;
176 
177 
178     fp = Gbl_Files[FileId].Handle;
179     Offset = ftell (fp);
180 
181     fseek (fp, 0, SEEK_END);
182     FileSize = (UINT32) ftell (fp);
183 
184     /* Restore file pointer */
185 
186     fseek (fp, Offset, SEEK_SET);
187     return (FileSize);
188 }
189 
190 
191 /*******************************************************************************
192  *
193  * FUNCTION:    FlReadFile
194  *
195  * PARAMETERS:  FileId              - Index into file info array
196  *              Buffer              - Where to place the data
197  *              Length              - Amount to read
198  *
199  * RETURN:      Status. AE_ERROR indicates EOF.
200  *
201  * DESCRIPTION: Read data from an open file.
202  *              NOTE: Aborts compiler on any error.
203  *
204  ******************************************************************************/
205 
206 ACPI_STATUS
207 FlReadFile (
208     UINT32                  FileId,
209     void                    *Buffer,
210     UINT32                  Length)
211 {
212     UINT32                  Actual;
213 
214 
215     /* Read and check for error */
216 
217     Actual = fread (Buffer, 1, Length, Gbl_Files[FileId].Handle);
218     if (Actual < Length)
219     {
220         if (feof (Gbl_Files[FileId].Handle))
221         {
222             /* End-of-file, just return error */
223 
224             return (AE_ERROR);
225         }
226 
227         FlFileError (FileId, ASL_MSG_READ);
228         AslAbort ();
229     }
230 
231     return (AE_OK);
232 }
233 
234 
235 /*******************************************************************************
236  *
237  * FUNCTION:    FlWriteFile
238  *
239  * PARAMETERS:  FileId              - Index into file info array
240  *              Buffer              - Data to write
241  *              Length              - Amount of data to write
242  *
243  * RETURN:      None
244  *
245  * DESCRIPTION: Write data to an open file.
246  *              NOTE: Aborts compiler on any error.
247  *
248  ******************************************************************************/
249 
250 void
251 FlWriteFile (
252     UINT32                  FileId,
253     void                    *Buffer,
254     UINT32                  Length)
255 {
256     UINT32                  Actual;
257 
258 
259     /* Write and check for error */
260 
261     Actual = fwrite ((char *) Buffer, 1, Length, Gbl_Files[FileId].Handle);
262     if (Actual != Length)
263     {
264         FlFileError (FileId, ASL_MSG_WRITE);
265         AslAbort ();
266     }
267 }
268 
269 
270 /*******************************************************************************
271  *
272  * FUNCTION:    FlPrintFile
273  *
274  * PARAMETERS:  FileId              - Index into file info array
275  *              Format              - Printf format string
276  *              ...                 - Printf arguments
277  *
278  * RETURN:      None
279  *
280  * DESCRIPTION: Formatted write to an open file.
281  *              NOTE: Aborts compiler on any error.
282  *
283  ******************************************************************************/
284 
285 void
286 FlPrintFile (
287     UINT32                  FileId,
288     char                    *Format,
289     ...)
290 {
291     INT32                   Actual;
292     va_list                 Args;
293 
294 
295     va_start (Args, Format);
296 
297     Actual = vfprintf (Gbl_Files[FileId].Handle, Format, Args);
298     va_end (Args);
299 
300     if (Actual == -1)
301     {
302         FlFileError (FileId, ASL_MSG_WRITE);
303         AslAbort ();
304     }
305 }
306 
307 
308 /*******************************************************************************
309  *
310  * FUNCTION:    FlSeekFile
311  *
312  * PARAMETERS:  FileId              - Index into file info array
313  *              Offset              - Absolute byte offset in file
314  *
315  * RETURN:      None
316  *
317  * DESCRIPTION: Seek to absolute offset
318  *              NOTE: Aborts compiler on any error.
319  *
320  ******************************************************************************/
321 
322 void
323 FlSeekFile (
324     UINT32                  FileId,
325     long                    Offset)
326 {
327     int                     Error;
328 
329 
330     Error = fseek (Gbl_Files[FileId].Handle, Offset, SEEK_SET);
331     if (Error)
332     {
333         FlFileError (FileId, ASL_MSG_SEEK);
334         AslAbort ();
335     }
336 }
337 
338 
339 /*******************************************************************************
340  *
341  * FUNCTION:    FlCloseFile
342  *
343  * PARAMETERS:  FileId              - Index into file info array
344  *
345  * RETURN:      None
346  *
347  * DESCRIPTION: Close an open file. Aborts compiler on error
348  *
349  ******************************************************************************/
350 
351 void
352 FlCloseFile (
353     UINT32                  FileId)
354 {
355     int                     Error;
356 
357 
358     if (!Gbl_Files[FileId].Handle)
359     {
360         return;
361     }
362 
363     Error = fclose (Gbl_Files[FileId].Handle);
364     if (Error)
365     {
366         FlFileError (FileId, ASL_MSG_CLOSE);
367         AslAbort ();
368     }
369 
370     Gbl_Files[FileId].Handle = NULL;
371     return;
372 }
373 
374 
375 /*******************************************************************************
376  *
377  * FUNCTION:    FlDeleteFile
378  *
379  * PARAMETERS:  FileId              - Index into file info array
380  *
381  * RETURN:      None
382  *
383  * DESCRIPTION: Delete a file.
384  *
385  ******************************************************************************/
386 
387 void
388 FlDeleteFile (
389     UINT32                  FileId)
390 {
391     ASL_FILE_INFO           *Info = &Gbl_Files[FileId];
392 
393 
394     if (!Info->Filename)
395     {
396         return;
397     }
398 
399     if (remove (Info->Filename))
400     {
401         printf ("%s (%s file) ",
402             Info->Filename, Info->Description);
403         perror ("Could not delete");
404     }
405 
406     Info->Filename = NULL;
407     return;
408 }
409 
410 
411 /*******************************************************************************
412  *
413  * FUNCTION:    FlSetLineNumber
414  *
415  * PARAMETERS:  Op        - Parse node for the LINE asl statement
416  *
417  * RETURN:      None.
418  *
419  * DESCRIPTION: Set the current line number
420  *
421  ******************************************************************************/
422 
423 void
424 FlSetLineNumber (
425     UINT32                  LineNumber)
426 {
427 
428     DbgPrint (ASL_PARSE_OUTPUT, "\n#line: New line number %u (old %u)\n",
429          LineNumber, Gbl_LogicalLineNumber);
430 
431     Gbl_CurrentLineNumber = LineNumber;
432     Gbl_LogicalLineNumber = LineNumber;
433 }
434 
435 
436 /*******************************************************************************
437  *
438  * FUNCTION:    FlSetFilename
439  *
440  * PARAMETERS:  Op        - Parse node for the LINE asl statement
441  *
442  * RETURN:      None.
443  *
444  * DESCRIPTION: Set the current filename
445  *
446  ******************************************************************************/
447 
448 void
449 FlSetFilename (
450     char                    *Filename)
451 {
452 
453     DbgPrint (ASL_PARSE_OUTPUT, "\n#line: New filename %s (old %s)\n",
454          Filename, Gbl_Files[ASL_FILE_INPUT].Filename);
455 
456     Gbl_Files[ASL_FILE_INPUT].Filename = Filename;
457 }
458 
459 
460 /*******************************************************************************
461  *
462  * FUNCTION:    FlAddIncludeDirectory
463  *
464  * PARAMETERS:  Dir             - Directory pathname string
465  *
466  * RETURN:      None
467  *
468  * DESCRIPTION: Add a directory the list of include prefix directories.
469  *
470  ******************************************************************************/
471 
472 void
473 FlAddIncludeDirectory (
474     char                    *Dir)
475 {
476     ASL_INCLUDE_DIR         *NewDir;
477     ASL_INCLUDE_DIR         *NextDir;
478     ASL_INCLUDE_DIR         *PrevDir = NULL;
479     UINT32                  NeedsSeparator = 0;
480     size_t                  DirLength;
481 
482 
483     DirLength = strlen (Dir);
484     if (!DirLength)
485     {
486         return;
487     }
488 
489     /* Make sure that the pathname ends with a path separator */
490 
491     if ((Dir[DirLength-1] != '/') &&
492         (Dir[DirLength-1] != '\\'))
493     {
494         NeedsSeparator = 1;
495     }
496 
497     NewDir = ACPI_ALLOCATE_ZEROED (sizeof (ASL_INCLUDE_DIR));
498     NewDir->Dir = ACPI_ALLOCATE (DirLength + 1 + NeedsSeparator);
499     strcpy (NewDir->Dir, Dir);
500     if (NeedsSeparator)
501     {
502         strcat (NewDir->Dir, "/");
503     }
504 
505     /*
506      * Preserve command line ordering of -I options by adding new elements
507      * at the end of the list
508      */
509     NextDir = Gbl_IncludeDirList;
510     while (NextDir)
511     {
512         PrevDir = NextDir;
513         NextDir = NextDir->Next;
514     }
515 
516     if (PrevDir)
517     {
518         PrevDir->Next = NewDir;
519     }
520     else
521     {
522         Gbl_IncludeDirList = NewDir;
523     }
524 }
525 
526 
527 /*******************************************************************************
528  *
529  * FUNCTION:    FlMergePathnames
530  *
531  * PARAMETERS:  PrefixDir       - Prefix directory pathname. Can be NULL or
532  *                                a zero length string.
533  *              FilePathname    - The include filename from the source ASL.
534  *
535  * RETURN:      Merged pathname string
536  *
537  * DESCRIPTION: Merge two pathnames that (probably) have common elements, to
538  *              arrive at a minimal length string. Merge can occur if the
539  *              FilePathname is relative to the PrefixDir.
540  *
541  ******************************************************************************/
542 
543 char *
544 FlMergePathnames (
545     char                    *PrefixDir,
546     char                    *FilePathname)
547 {
548     char                    *CommonPath;
549     char                    *Pathname;
550     char                    *LastElement;
551 
552 
553     DbgPrint (ASL_PARSE_OUTPUT, "Include: Prefix path - \"%s\"\n"
554         "Include: FilePathname - \"%s\"\n",
555          PrefixDir, FilePathname);
556 
557     /*
558      * If there is no prefix directory or if the file pathname is absolute,
559      * just return the original file pathname
560      */
561     if (!PrefixDir || (!*PrefixDir) ||
562         (*FilePathname == '/') ||
563          (FilePathname[1] == ':'))
564     {
565         Pathname = ACPI_ALLOCATE (strlen (FilePathname) + 1);
566         strcpy (Pathname, FilePathname);
567         goto ConvertBackslashes;
568     }
569 
570     /* Need a local copy of the prefix directory path */
571 
572     CommonPath = ACPI_ALLOCATE (strlen (PrefixDir) + 1);
573     strcpy (CommonPath, PrefixDir);
574 
575     /*
576      * Walk forward through the file path, and simultaneously backward
577      * through the prefix directory path until there are no more
578      * relative references at the start of the file path.
579      */
580     while (*FilePathname && (!strncmp (FilePathname, "../", 3)))
581     {
582         /* Remove last element of the prefix directory path */
583 
584         LastElement = strrchr (CommonPath, '/');
585         if (!LastElement)
586         {
587             goto ConcatenatePaths;
588         }
589 
590         *LastElement = 0;   /* Terminate CommonPath string */
591         FilePathname += 3;  /* Point to next path element */
592     }
593 
594     /*
595      * Remove the last element of the prefix directory path (it is the same as
596      * the first element of the file pathname), and build the final merged
597      * pathname.
598      */
599     LastElement = strrchr (CommonPath, '/');
600     if (LastElement)
601     {
602         *LastElement = 0;
603     }
604 
605     /* Build the final merged pathname */
606 
607 ConcatenatePaths:
608     Pathname = ACPI_ALLOCATE_ZEROED (strlen (CommonPath) + strlen (FilePathname) + 2);
609     if (LastElement && *CommonPath)
610     {
611         strcpy (Pathname, CommonPath);
612         strcat (Pathname, "/");
613     }
614     strcat (Pathname, FilePathname);
615     ACPI_FREE (CommonPath);
616 
617     /* Convert all backslashes to normal slashes */
618 
619 ConvertBackslashes:
620     UtConvertBackslashes (Pathname);
621 
622     DbgPrint (ASL_PARSE_OUTPUT, "Include: Merged Pathname - \"%s\"\n",
623          Pathname);
624     return (Pathname);
625 }
626 
627 
628 /*******************************************************************************
629  *
630  * FUNCTION:    FlOpenIncludeWithPrefix
631  *
632  * PARAMETERS:  PrefixDir       - Prefix directory pathname. Can be a zero
633  *                                length string.
634  *              Filename        - The include filename from the source ASL.
635  *
636  * RETURN:      Valid file descriptor if successful. Null otherwise.
637  *
638  * DESCRIPTION: Open an include file and push it on the input file stack.
639  *
640  ******************************************************************************/
641 
642 FILE *
643 FlOpenIncludeWithPrefix (
644     char                    *PrefixDir,
645     char                    *Filename)
646 {
647     FILE                    *IncludeFile;
648     char                    *Pathname;
649 
650 
651     /* Build the full pathname to the file */
652 
653     Pathname = FlMergePathnames (PrefixDir, Filename);
654 
655     DbgPrint (ASL_PARSE_OUTPUT, "Include: Opening file - \"%s\"\n\n",
656         Pathname);
657 
658     /* Attempt to open the file, push if successful */
659 
660     IncludeFile = fopen (Pathname, "r");
661     if (!IncludeFile)
662     {
663         fprintf (stderr, "Could not open include file %s\n", Pathname);
664         ACPI_FREE (Pathname);
665         return (NULL);
666     }
667 
668     /* Push the include file on the open input file stack */
669 
670     AslPushInputFileStack (IncludeFile, Pathname);
671     return (IncludeFile);
672 }
673 
674 
675 /*******************************************************************************
676  *
677  * FUNCTION:    FlOpenIncludeFile
678  *
679  * PARAMETERS:  Op        - Parse node for the INCLUDE ASL statement
680  *
681  * RETURN:      None.
682  *
683  * DESCRIPTION: Open an include file and push it on the input file stack.
684  *
685  ******************************************************************************/
686 
687 void
688 FlOpenIncludeFile (
689     ACPI_PARSE_OBJECT       *Op)
690 {
691     FILE                    *IncludeFile;
692     ASL_INCLUDE_DIR         *NextDir;
693 
694 
695     /* Op must be valid */
696 
697     if (!Op)
698     {
699         AslCommonError (ASL_ERROR, ASL_MSG_INCLUDE_FILE_OPEN,
700             Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
701             Gbl_InputByteCount, Gbl_CurrentColumn,
702             Gbl_Files[ASL_FILE_INPUT].Filename, " - Null parse node");
703 
704         return;
705     }
706 
707     /*
708      * Flush out the "include ()" statement on this line, start
709      * the actual include file on the next line
710      */
711     AslResetCurrentLineBuffer ();
712     FlPrintFile (ASL_FILE_SOURCE_OUTPUT, "\n");
713     Gbl_CurrentLineOffset++;
714 
715 
716     /* Attempt to open the include file */
717 
718     /* If the file specifies an absolute path, just open it */
719 
720     if ((Op->Asl.Value.String[0] == '/')  ||
721         (Op->Asl.Value.String[0] == '\\') ||
722         (Op->Asl.Value.String[1] == ':'))
723     {
724         IncludeFile = FlOpenIncludeWithPrefix ("", Op->Asl.Value.String);
725         if (!IncludeFile)
726         {
727             goto ErrorExit;
728         }
729         return;
730     }
731 
732     /*
733      * The include filename is not an absolute path.
734      *
735      * First, search for the file within the "local" directory -- meaning
736      * the same directory that contains the source file.
737      *
738      * Construct the file pathname from the global directory name.
739      */
740     IncludeFile = FlOpenIncludeWithPrefix (Gbl_DirectoryPath, Op->Asl.Value.String);
741     if (IncludeFile)
742     {
743         return;
744     }
745 
746     /*
747      * Second, search for the file within the (possibly multiple) directories
748      * specified by the -I option on the command line.
749      */
750     NextDir = Gbl_IncludeDirList;
751     while (NextDir)
752     {
753         IncludeFile = FlOpenIncludeWithPrefix (NextDir->Dir, Op->Asl.Value.String);
754         if (IncludeFile)
755         {
756             return;
757         }
758 
759         NextDir = NextDir->Next;
760     }
761 
762     /* We could not open the include file after trying very hard */
763 
764 ErrorExit:
765     sprintf (MsgBuffer, "%s, %s", Op->Asl.Value.String, strerror (errno));
766     AslError (ASL_ERROR, ASL_MSG_INCLUDE_FILE_OPEN, Op, MsgBuffer);
767 }
768 
769 
770 /*******************************************************************************
771  *
772  * FUNCTION:    FlOpenInputFile
773  *
774  * PARAMETERS:  InputFilename       - The user-specified ASL source file to be
775  *                                    compiled
776  *
777  * RETURN:      Status
778  *
779  * DESCRIPTION: Open the specified input file, and save the directory path to
780  *              the file so that include files can be opened in
781  *              the same directory.
782  *
783  ******************************************************************************/
784 
785 ACPI_STATUS
786 FlOpenInputFile (
787     char                    *InputFilename)
788 {
789 
790     /* Open the input ASL file, text mode */
791 
792     FlOpenFile (ASL_FILE_INPUT, InputFilename, "rt");
793     AslCompilerin = Gbl_Files[ASL_FILE_INPUT].Handle;
794 
795     return (AE_OK);
796 }
797 
798 
799 /*******************************************************************************
800  *
801  * FUNCTION:    FlOpenAmlOutputFile
802  *
803  * PARAMETERS:  FilenamePrefix       - The user-specified ASL source file
804  *
805  * RETURN:      Status
806  *
807  * DESCRIPTION: Create the output filename (*.AML) and open the file. The file
808  *              is created in the same directory as the parent input file.
809  *
810  ******************************************************************************/
811 
812 ACPI_STATUS
813 FlOpenAmlOutputFile (
814     char                    *FilenamePrefix)
815 {
816     char                    *Filename;
817 
818 
819     /* Output filename usually comes from the ASL itself */
820 
821     Filename = Gbl_Files[ASL_FILE_AML_OUTPUT].Filename;
822     if (!Filename)
823     {
824         /* Create the output AML filename */
825 
826         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_AML_CODE);
827         if (!Filename)
828         {
829             AslCommonError (ASL_ERROR, ASL_MSG_OUTPUT_FILENAME,
830                 0, 0, 0, 0, NULL, NULL);
831             return (AE_ERROR);
832         }
833     }
834 
835     /* Open the output AML file in binary mode */
836 
837     FlOpenFile (ASL_FILE_AML_OUTPUT, Filename, "w+b");
838     return (AE_OK);
839 }
840 
841 
842 /*******************************************************************************
843  *
844  * FUNCTION:    FlOpenMiscOutputFiles
845  *
846  * PARAMETERS:  FilenamePrefix       - The user-specified ASL source file
847  *
848  * RETURN:      Status
849  *
850  * DESCRIPTION: Create and open the various output files needed, depending on
851  *              the command line options
852  *
853  ******************************************************************************/
854 
855 ACPI_STATUS
856 FlOpenMiscOutputFiles (
857     char                    *FilenamePrefix)
858 {
859     char                    *Filename;
860 
861 
862     /* Create/Open a hex output file if asked */
863 
864     if (Gbl_HexOutputFlag)
865     {
866         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_HEX_DUMP);
867         if (!Filename)
868         {
869             AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
870                 0, 0, 0, 0, NULL, NULL);
871             return (AE_ERROR);
872         }
873 
874         /* Open the hex file, text mode */
875 
876         FlOpenFile (ASL_FILE_HEX_OUTPUT, Filename, "w+t");
877 
878         AslCompilerSignon (ASL_FILE_HEX_OUTPUT);
879         AslCompilerFileHeader (ASL_FILE_HEX_OUTPUT);
880     }
881 
882     /* Create/Open a debug output file if asked */
883 
884     if (Gbl_DebugFlag)
885     {
886         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_DEBUG);
887         if (!Filename)
888         {
889             AslCommonError (ASL_ERROR, ASL_MSG_DEBUG_FILENAME,
890                 0, 0, 0, 0, NULL, NULL);
891             return (AE_ERROR);
892         }
893 
894         /* Open the debug file as STDERR, text mode */
895 
896         /* TBD: hide this behind a FlReopenFile function */
897 
898         Gbl_Files[ASL_FILE_DEBUG_OUTPUT].Filename = Filename;
899         Gbl_Files[ASL_FILE_DEBUG_OUTPUT].Handle =
900             freopen (Filename, "w+t", stderr);
901 
902         if (!Gbl_Files[ASL_FILE_DEBUG_OUTPUT].Handle)
903         {
904             AslCommonError (ASL_ERROR, ASL_MSG_DEBUG_FILENAME,
905                 0, 0, 0, 0, NULL, NULL);
906             return (AE_ERROR);
907         }
908 
909         AslCompilerSignon (ASL_FILE_DEBUG_OUTPUT);
910         AslCompilerFileHeader (ASL_FILE_DEBUG_OUTPUT);
911     }
912 
913     /* Create/Open a listing output file if asked */
914 
915     if (Gbl_ListingFlag)
916     {
917         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_LISTING);
918         if (!Filename)
919         {
920             AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
921                 0, 0, 0, 0, NULL, NULL);
922             return (AE_ERROR);
923         }
924 
925         /* Open the listing file, text mode */
926 
927         FlOpenFile (ASL_FILE_LISTING_OUTPUT, Filename, "w+t");
928 
929         AslCompilerSignon (ASL_FILE_LISTING_OUTPUT);
930         AslCompilerFileHeader (ASL_FILE_LISTING_OUTPUT);
931     }
932 
933     /* Create the preprocessor output file if preprocessor enabled */
934 
935     if (Gbl_PreprocessFlag)
936     {
937         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_PREPROCESSOR);
938         if (!Filename)
939         {
940             AslCommonError (ASL_ERROR, ASL_MSG_PREPROCESSOR_FILENAME,
941                 0, 0, 0, 0, NULL, NULL);
942             return (AE_ERROR);
943         }
944 
945         FlOpenFile (ASL_FILE_PREPROCESSOR, Filename, "w+t");
946     }
947 
948     /* All done for data table compiler */
949 
950     if (Gbl_FileType == ASL_INPUT_TYPE_ASCII_DATA)
951     {
952         return (AE_OK);
953     }
954 
955     /* Create/Open a combined source output file */
956 
957     Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_SOURCE);
958     if (!Filename)
959     {
960         AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
961             0, 0, 0, 0, NULL, NULL);
962         return (AE_ERROR);
963     }
964 
965     /*
966      * Open the source output file, binary mode (so that LF does not get
967      * expanded to CR/LF on some systems, messing up our seek
968      * calculations.)
969      */
970     FlOpenFile (ASL_FILE_SOURCE_OUTPUT, Filename, "w+b");
971 
972 /*
973 // TBD: TEMP
974 //    AslCompilerin = Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle;
975 */
976     /* Create/Open a assembly code source output file if asked */
977 
978     if (Gbl_AsmOutputFlag)
979     {
980         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_ASM_SOURCE);
981         if (!Filename)
982         {
983             AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
984                 0, 0, 0, 0, NULL, NULL);
985             return (AE_ERROR);
986         }
987 
988         /* Open the assembly code source file, text mode */
989 
990         FlOpenFile (ASL_FILE_ASM_SOURCE_OUTPUT, Filename, "w+t");
991 
992         AslCompilerSignon (ASL_FILE_ASM_SOURCE_OUTPUT);
993         AslCompilerFileHeader (ASL_FILE_ASM_SOURCE_OUTPUT);
994     }
995 
996     /* Create/Open a C code source output file if asked */
997 
998     if (Gbl_C_OutputFlag)
999     {
1000         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_C_SOURCE);
1001         if (!Filename)
1002         {
1003             AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
1004                 0, 0, 0, 0, NULL, NULL);
1005             return (AE_ERROR);
1006         }
1007 
1008         /* Open the C code source file, text mode */
1009 
1010         FlOpenFile (ASL_FILE_C_SOURCE_OUTPUT, Filename, "w+t");
1011 
1012         FlPrintFile (ASL_FILE_C_SOURCE_OUTPUT, "/*\n");
1013         AslCompilerSignon (ASL_FILE_C_SOURCE_OUTPUT);
1014         AslCompilerFileHeader (ASL_FILE_C_SOURCE_OUTPUT);
1015     }
1016 
1017     /* Create/Open a assembly include output file if asked */
1018 
1019     if (Gbl_AsmIncludeOutputFlag)
1020     {
1021         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_ASM_INCLUDE);
1022         if (!Filename)
1023         {
1024             AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
1025                 0, 0, 0, 0, NULL, NULL);
1026             return (AE_ERROR);
1027         }
1028 
1029         /* Open the assembly include file, text mode */
1030 
1031         FlOpenFile (ASL_FILE_ASM_INCLUDE_OUTPUT, Filename, "w+t");
1032 
1033         AslCompilerSignon (ASL_FILE_ASM_INCLUDE_OUTPUT);
1034         AslCompilerFileHeader (ASL_FILE_ASM_INCLUDE_OUTPUT);
1035     }
1036 
1037     /* Create/Open a C include output file if asked */
1038 
1039     if (Gbl_C_IncludeOutputFlag)
1040     {
1041         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_C_INCLUDE);
1042         if (!Filename)
1043         {
1044             AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
1045                 0, 0, 0, 0, NULL, NULL);
1046             return (AE_ERROR);
1047         }
1048 
1049         /* Open the C include file, text mode */
1050 
1051         FlOpenFile (ASL_FILE_C_INCLUDE_OUTPUT, Filename, "w+t");
1052 
1053         FlPrintFile (ASL_FILE_C_INCLUDE_OUTPUT, "/*\n");
1054         AslCompilerSignon (ASL_FILE_C_INCLUDE_OUTPUT);
1055         AslCompilerFileHeader (ASL_FILE_C_INCLUDE_OUTPUT);
1056     }
1057 
1058     /* Create a namespace output file if asked */
1059 
1060     if (Gbl_NsOutputFlag)
1061     {
1062         Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_NAMESPACE);
1063         if (!Filename)
1064         {
1065             AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
1066                 0, 0, 0, 0, NULL, NULL);
1067             return (AE_ERROR);
1068         }
1069 
1070         /* Open the namespace file, text mode */
1071 
1072         FlOpenFile (ASL_FILE_NAMESPACE_OUTPUT, Filename, "w+t");
1073 
1074         AslCompilerSignon (ASL_FILE_NAMESPACE_OUTPUT);
1075         AslCompilerFileHeader (ASL_FILE_NAMESPACE_OUTPUT);
1076     }
1077 
1078     return (AE_OK);
1079 }
1080 
1081 
1082 #ifdef ACPI_OBSOLETE_FUNCTIONS
1083 /*******************************************************************************
1084  *
1085  * FUNCTION:    FlParseInputPathname
1086  *
1087  * PARAMETERS:  InputFilename       - The user-specified ASL source file to be
1088  *                                    compiled
1089  *
1090  * RETURN:      Status
1091  *
1092  * DESCRIPTION: Split the input path into a directory and filename part
1093  *              1) Directory part used to open include files
1094  *              2) Filename part used to generate output filenames
1095  *
1096  ******************************************************************************/
1097 
1098 ACPI_STATUS
1099 FlParseInputPathname (
1100     char                    *InputFilename)
1101 {
1102     char                    *Substring;
1103 
1104 
1105     if (!InputFilename)
1106     {
1107         return (AE_OK);
1108     }
1109 
1110     /* Get the path to the input filename's directory */
1111 
1112     Gbl_DirectoryPath = strdup (InputFilename);
1113     if (!Gbl_DirectoryPath)
1114     {
1115         return (AE_NO_MEMORY);
1116     }
1117 
1118     Substring = strrchr (Gbl_DirectoryPath, '\\');
1119     if (!Substring)
1120     {
1121         Substring = strrchr (Gbl_DirectoryPath, '/');
1122         if (!Substring)
1123         {
1124             Substring = strrchr (Gbl_DirectoryPath, ':');
1125         }
1126     }
1127 
1128     if (!Substring)
1129     {
1130         Gbl_DirectoryPath[0] = 0;
1131         if (Gbl_UseDefaultAmlFilename)
1132         {
1133             Gbl_OutputFilenamePrefix = strdup (InputFilename);
1134         }
1135     }
1136     else
1137     {
1138         if (Gbl_UseDefaultAmlFilename)
1139         {
1140             Gbl_OutputFilenamePrefix = strdup (Substring + 1);
1141         }
1142         *(Substring+1) = 0;
1143     }
1144 
1145     return (AE_OK);
1146 }
1147 #endif
1148