xref: /freebsd/sys/contrib/dev/acpica/compiler/aslfiles.c (revision 7cd2dcf07629713e5a3d60472cfe4701b705a167)
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 
147     Gbl_Files[FileId].Filename = Filename;
148     Gbl_Files[FileId].Handle   = File;
149 
150     if (!File)
151     {
152         FlFileError (FileId, ASL_MSG_OPEN);
153         AslAbort ();
154     }
155 }
156 
157 
158 /*******************************************************************************
159  *
160  * FUNCTION:    FlGetFileSize
161  *
162  * PARAMETERS:  FileId              - Index into file info array
163  *
164  * RETURN:      File Size
165  *
166  * DESCRIPTION: Get current file size. Uses seek-to-EOF. File must be open.
167  *
168  ******************************************************************************/
169 
170 UINT32
171 FlGetFileSize (
172     UINT32                  FileId)
173 {
174     FILE                    *fp;
175     UINT32                  FileSize;
176     long                    Offset;
177 
178 
179     fp = Gbl_Files[FileId].Handle;
180     Offset = ftell (fp);
181 
182     fseek (fp, 0, SEEK_END);
183     FileSize = (UINT32) ftell (fp);
184 
185     /* Restore file pointer */
186 
187     fseek (fp, Offset, SEEK_SET);
188     return (FileSize);
189 }
190 
191 
192 /*******************************************************************************
193  *
194  * FUNCTION:    FlReadFile
195  *
196  * PARAMETERS:  FileId              - Index into file info array
197  *              Buffer              - Where to place the data
198  *              Length              - Amount to read
199  *
200  * RETURN:      Status. AE_ERROR indicates EOF.
201  *
202  * DESCRIPTION: Read data from an open file.
203  *              NOTE: Aborts compiler on any error.
204  *
205  ******************************************************************************/
206 
207 ACPI_STATUS
208 FlReadFile (
209     UINT32                  FileId,
210     void                    *Buffer,
211     UINT32                  Length)
212 {
213     UINT32                  Actual;
214 
215 
216     /* Read and check for error */
217 
218     Actual = fread (Buffer, 1, Length, Gbl_Files[FileId].Handle);
219     if (Actual != Length)
220     {
221         if (feof (Gbl_Files[FileId].Handle))
222         {
223             /* End-of-file, just return error */
224 
225             return (AE_ERROR);
226         }
227 
228         FlFileError (FileId, ASL_MSG_READ);
229         AslAbort ();
230     }
231 
232     return (AE_OK);
233 }
234 
235 
236 /*******************************************************************************
237  *
238  * FUNCTION:    FlWriteFile
239  *
240  * PARAMETERS:  FileId              - Index into file info array
241  *              Buffer              - Data to write
242  *              Length              - Amount of data to write
243  *
244  * RETURN:      None
245  *
246  * DESCRIPTION: Write data to an open file.
247  *              NOTE: Aborts compiler on any error.
248  *
249  ******************************************************************************/
250 
251 void
252 FlWriteFile (
253     UINT32                  FileId,
254     void                    *Buffer,
255     UINT32                  Length)
256 {
257     UINT32                  Actual;
258 
259 
260     /* Write and check for error */
261 
262     Actual = fwrite ((char *) Buffer, 1, Length, Gbl_Files[FileId].Handle);
263     if (Actual != Length)
264     {
265         FlFileError (FileId, ASL_MSG_WRITE);
266         AslAbort ();
267     }
268 }
269 
270 
271 /*******************************************************************************
272  *
273  * FUNCTION:    FlPrintFile
274  *
275  * PARAMETERS:  FileId              - Index into file info array
276  *              Format              - Printf format string
277  *              ...                 - Printf arguments
278  *
279  * RETURN:      None
280  *
281  * DESCRIPTION: Formatted write to an open file.
282  *              NOTE: Aborts compiler on any error.
283  *
284  ******************************************************************************/
285 
286 void
287 FlPrintFile (
288     UINT32                  FileId,
289     char                    *Format,
290     ...)
291 {
292     INT32                   Actual;
293     va_list                 Args;
294 
295 
296     va_start (Args, Format);
297 
298     Actual = vfprintf (Gbl_Files[FileId].Handle, Format, Args);
299     va_end (Args);
300 
301     if (Actual == -1)
302     {
303         FlFileError (FileId, ASL_MSG_WRITE);
304         AslAbort ();
305     }
306 }
307 
308 
309 /*******************************************************************************
310  *
311  * FUNCTION:    FlSeekFile
312  *
313  * PARAMETERS:  FileId              - Index into file info array
314  *              Offset              - Absolute byte offset in file
315  *
316  * RETURN:      None
317  *
318  * DESCRIPTION: Seek to absolute offset
319  *              NOTE: Aborts compiler on any error.
320  *
321  ******************************************************************************/
322 
323 void
324 FlSeekFile (
325     UINT32                  FileId,
326     long                    Offset)
327 {
328     int                     Error;
329 
330 
331     Error = fseek (Gbl_Files[FileId].Handle, Offset, SEEK_SET);
332     if (Error)
333     {
334         FlFileError (FileId, ASL_MSG_SEEK);
335         AslAbort ();
336     }
337 }
338 
339 
340 /*******************************************************************************
341  *
342  * FUNCTION:    FlCloseFile
343  *
344  * PARAMETERS:  FileId              - Index into file info array
345  *
346  * RETURN:      None
347  *
348  * DESCRIPTION: Close an open file. Aborts compiler on error
349  *
350  ******************************************************************************/
351 
352 void
353 FlCloseFile (
354     UINT32                  FileId)
355 {
356     int                     Error;
357 
358 
359     if (!Gbl_Files[FileId].Handle)
360     {
361         return;
362     }
363 
364     Error = fclose (Gbl_Files[FileId].Handle);
365     if (Error)
366     {
367         FlFileError (FileId, ASL_MSG_CLOSE);
368         AslAbort ();
369     }
370 
371     Gbl_Files[FileId].Handle = NULL;
372     return;
373 }
374 
375 
376 /*******************************************************************************
377  *
378  * FUNCTION:    FlDeleteFile
379  *
380  * PARAMETERS:  FileId              - Index into file info array
381  *
382  * RETURN:      None
383  *
384  * DESCRIPTION: Delete a file.
385  *
386  ******************************************************************************/
387 
388 void
389 FlDeleteFile (
390     UINT32                  FileId)
391 {
392     ASL_FILE_INFO           *Info = &Gbl_Files[FileId];
393 
394 
395     if (!Info->Filename)
396     {
397         return;
398     }
399 
400     if (remove (Info->Filename))
401     {
402         printf ("%s (%s file) ",
403             Info->Filename, Info->Description);
404         perror ("Could not delete");
405     }
406 
407     Info->Filename = NULL;
408     return;
409 }
410 
411 
412 /*******************************************************************************
413  *
414  * FUNCTION:    FlSetLineNumber
415  *
416  * PARAMETERS:  Op        - Parse node for the LINE asl statement
417  *
418  * RETURN:      None.
419  *
420  * DESCRIPTION: Set the current line number
421  *
422  ******************************************************************************/
423 
424 void
425 FlSetLineNumber (
426     UINT32                  LineNumber)
427 {
428 
429     DbgPrint (ASL_PARSE_OUTPUT, "\n#line: New line number %u (old %u)\n",
430          LineNumber, Gbl_LogicalLineNumber);
431 
432     Gbl_CurrentLineNumber = LineNumber;
433     Gbl_LogicalLineNumber = LineNumber;
434 }
435 
436 
437 /*******************************************************************************
438  *
439  * FUNCTION:    FlSetFilename
440  *
441  * PARAMETERS:  Op        - Parse node for the LINE asl statement
442  *
443  * RETURN:      None.
444  *
445  * DESCRIPTION: Set the current filename
446  *
447  ******************************************************************************/
448 
449 void
450 FlSetFilename (
451     char                    *Filename)
452 {
453 
454     DbgPrint (ASL_PARSE_OUTPUT, "\n#line: New filename %s (old %s)\n",
455          Filename, Gbl_Files[ASL_FILE_INPUT].Filename);
456 
457     Gbl_Files[ASL_FILE_INPUT].Filename = Filename;
458 }
459 
460 
461 /*******************************************************************************
462  *
463  * FUNCTION:    FlAddIncludeDirectory
464  *
465  * PARAMETERS:  Dir             - Directory pathname string
466  *
467  * RETURN:      None
468  *
469  * DESCRIPTION: Add a directory the list of include prefix directories.
470  *
471  ******************************************************************************/
472 
473 void
474 FlAddIncludeDirectory (
475     char                    *Dir)
476 {
477     ASL_INCLUDE_DIR         *NewDir;
478     ASL_INCLUDE_DIR         *NextDir;
479     ASL_INCLUDE_DIR         *PrevDir = NULL;
480     UINT32                  NeedsSeparator = 0;
481     size_t                  DirLength;
482 
483 
484     DirLength = strlen (Dir);
485     if (!DirLength)
486     {
487         return;
488     }
489 
490     /* Make sure that the pathname ends with a path separator */
491 
492     if ((Dir[DirLength-1] != '/') &&
493         (Dir[DirLength-1] != '\\'))
494     {
495         NeedsSeparator = 1;
496     }
497 
498     NewDir = ACPI_ALLOCATE_ZEROED (sizeof (ASL_INCLUDE_DIR));
499     NewDir->Dir = ACPI_ALLOCATE (DirLength + 1 + NeedsSeparator);
500     strcpy (NewDir->Dir, Dir);
501     if (NeedsSeparator)
502     {
503         strcat (NewDir->Dir, "/");
504     }
505 
506     /*
507      * Preserve command line ordering of -I options by adding new elements
508      * at the end of the list
509      */
510     NextDir = Gbl_IncludeDirList;
511     while (NextDir)
512     {
513         PrevDir = NextDir;
514         NextDir = NextDir->Next;
515     }
516 
517     if (PrevDir)
518     {
519         PrevDir->Next = NewDir;
520     }
521     else
522     {
523         Gbl_IncludeDirList = NewDir;
524     }
525 }
526 
527 
528 /*******************************************************************************
529  *
530  * FUNCTION:    FlMergePathnames
531  *
532  * PARAMETERS:  PrefixDir       - Prefix directory pathname. Can be NULL or
533  *                                a zero length string.
534  *              FilePathname    - The include filename from the source ASL.
535  *
536  * RETURN:      Merged pathname string
537  *
538  * DESCRIPTION: Merge two pathnames that (probably) have common elements, to
539  *              arrive at a minimal length string. Merge can occur if the
540  *              FilePathname is relative to the PrefixDir.
541  *
542  ******************************************************************************/
543 
544 char *
545 FlMergePathnames (
546     char                    *PrefixDir,
547     char                    *FilePathname)
548 {
549     char                    *CommonPath;
550     char                    *Pathname;
551     char                    *LastElement;
552 
553 
554     DbgPrint (ASL_PARSE_OUTPUT, "Include: Prefix path - \"%s\"\n"
555         "Include: FilePathname - \"%s\"\n",
556          PrefixDir, FilePathname);
557 
558     /*
559      * If there is no prefix directory or if the file pathname is absolute,
560      * just return the original file pathname
561      */
562     if (!PrefixDir || (!*PrefixDir) ||
563         (*FilePathname == '/') ||
564          (FilePathname[1] == ':'))
565     {
566         Pathname = ACPI_ALLOCATE (strlen (FilePathname) + 1);
567         strcpy (Pathname, FilePathname);
568         goto ConvertBackslashes;
569     }
570 
571     /* Need a local copy of the prefix directory path */
572 
573     CommonPath = ACPI_ALLOCATE (strlen (PrefixDir) + 1);
574     strcpy (CommonPath, PrefixDir);
575 
576     /*
577      * Walk forward through the file path, and simultaneously backward
578      * through the prefix directory path until there are no more
579      * relative references at the start of the file path.
580      */
581     while (*FilePathname && (!strncmp (FilePathname, "../", 3)))
582     {
583         /* Remove last element of the prefix directory path */
584 
585         LastElement = strrchr (CommonPath, '/');
586         if (!LastElement)
587         {
588             goto ConcatenatePaths;
589         }
590 
591         *LastElement = 0;   /* Terminate CommonPath string */
592         FilePathname += 3;  /* Point to next path element */
593     }
594 
595     /*
596      * Remove the last element of the prefix directory path (it is the same as
597      * the first element of the file pathname), and build the final merged
598      * pathname.
599      */
600     LastElement = strrchr (CommonPath, '/');
601     if (LastElement)
602     {
603         *LastElement = 0;
604     }
605 
606     /* Build the final merged pathname */
607 
608 ConcatenatePaths:
609     Pathname = ACPI_ALLOCATE_ZEROED (strlen (CommonPath) + strlen (FilePathname) + 2);
610     if (LastElement && *CommonPath)
611     {
612         strcpy (Pathname, CommonPath);
613         strcat (Pathname, "/");
614     }
615     strcat (Pathname, FilePathname);
616     ACPI_FREE (CommonPath);
617 
618     /* Convert all backslashes to normal slashes */
619 
620 ConvertBackslashes:
621     UtConvertBackslashes (Pathname);
622 
623     DbgPrint (ASL_PARSE_OUTPUT, "Include: Merged Pathname - \"%s\"\n",
624          Pathname);
625     return (Pathname);
626 }
627 
628 
629 /*******************************************************************************
630  *
631  * FUNCTION:    FlOpenIncludeWithPrefix
632  *
633  * PARAMETERS:  PrefixDir       - Prefix directory pathname. Can be a zero
634  *                                length string.
635  *              Filename        - The include filename from the source ASL.
636  *
637  * RETURN:      Valid file descriptor if successful. Null otherwise.
638  *
639  * DESCRIPTION: Open an include file and push it on the input file stack.
640  *
641  ******************************************************************************/
642 
643 FILE *
644 FlOpenIncludeWithPrefix (
645     char                    *PrefixDir,
646     char                    *Filename)
647 {
648     FILE                    *IncludeFile;
649     char                    *Pathname;
650 
651 
652     /* Build the full pathname to the file */
653 
654     Pathname = FlMergePathnames (PrefixDir, Filename);
655 
656     DbgPrint (ASL_PARSE_OUTPUT, "Include: Opening file - \"%s\"\n\n",
657         Pathname);
658 
659     /* Attempt to open the file, push if successful */
660 
661     IncludeFile = fopen (Pathname, "r");
662     if (IncludeFile)
663     {
664         /* Push the include file on the open input file stack */
665 
666         AslPushInputFileStack (IncludeFile, Pathname);
667         return (IncludeFile);
668     }
669 
670     ACPI_FREE (Pathname);
671     return (NULL);
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