aslfiles.c revision 1.14 1 /******************************************************************************
2 *
3 * Module Name: aslfiles - File support functions
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2019, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44 #include "aslcompiler.h"
45 #include "acapps.h"
46
47 #define _COMPONENT ACPI_COMPILER
48 ACPI_MODULE_NAME ("aslfiles")
49
50 /* Local prototypes */
51
52 static FILE *
53 FlOpenIncludeWithPrefix (
54 char *PrefixDir,
55 ACPI_PARSE_OBJECT *Op,
56 char *Filename);
57
58 static BOOLEAN
59 FlInputFileExists (
60 char *InputFilename);
61
62 #ifdef ACPI_OBSOLETE_FUNCTIONS
63 ACPI_STATUS
64 FlParseInputPathname (
65 char *InputFilename);
66 #endif
67
68
69 /*******************************************************************************
70 *
71 * FUNCTION: FlInitOneFile
72 *
73 * PARAMETERS: InputFilename - The user-specified ASL source file to be
74 * compiled
75 *
76 * RETURN: Status
77 *
78 * DESCRIPTION: Initialize global file structure for one input file. This file
79 * structure contains references to input, output, debugging, and
80 * other miscellaneous files that are associated for a single
81 * input ASL file.
82 *
83 ******************************************************************************/
84
85 ACPI_STATUS
86 FlInitOneFile (
87 char *InputFilename)
88 {
89 UINT32 i;
90 ASL_GLOBAL_FILE_NODE *NewFileNode;
91
92
93 if (FlInputFileExists (InputFilename))
94 {
95 AslError (ASL_ERROR, ASL_MSG_DUPLICATE_INPUT_FILE, NULL, InputFilename);
96 return (AE_ALREADY_EXISTS);
97 }
98
99 NewFileNode = ACPI_CAST_PTR (ASL_GLOBAL_FILE_NODE,
100 UtLocalCacheCalloc (sizeof (ASL_GLOBAL_FILE_NODE)));
101
102 if (!NewFileNode)
103 {
104 AslError (ASL_ERROR, ASL_MSG_MEMORY_ALLOCATION, NULL, NULL);
105 return (AE_NO_MEMORY);
106 }
107
108 NewFileNode->ParserErrorDetected = FALSE;
109 NewFileNode->Next = AslGbl_FilesList;
110
111 AslGbl_FilesList = NewFileNode;
112 AslGbl_Files = NewFileNode->Files;
113
114 for (i = 0; i < ASL_NUM_FILES; i++)
115 {
116 AslGbl_Files[i].Handle = NULL;
117 AslGbl_Files[i].Filename = NULL;
118 }
119
120 AslGbl_Files[ASL_FILE_STDOUT].Handle = stdout;
121 AslGbl_Files[ASL_FILE_STDOUT].Filename = "STDOUT";
122
123 if (AslGbl_VerboseErrors)
124 {
125 AslGbl_Files[ASL_FILE_STDERR].Handle = stderr;
126 }
127 else
128 {
129 AslGbl_Files[ASL_FILE_STDERR].Handle = stdout;
130 }
131
132 AslGbl_Files[ASL_FILE_STDERR].Filename = "STDERR";
133 return (AE_OK);
134 }
135
136
137 /*******************************************************************************
138 *
139 * FUNCTION: FlInputFileExists
140 *
141 * PARAMETERS: Filename - File name to be searched
142 *
143 * RETURN: Status
144 *
145 * DESCRIPTION: Returns true if the file name already exists.
146 *
147 ******************************************************************************/
148
149 static BOOLEAN
150 FlInputFileExists (
151 char *Filename)
152 {
153 ASL_GLOBAL_FILE_NODE *Current = AslGbl_FilesList;
154
155
156 while (Current)
157 {
158 if (!strcmp (Filename, Current->Files[ASL_FILE_INPUT].Filename))
159 {
160 return (TRUE);
161 }
162
163 Current = Current->Next;
164 }
165
166 return (FALSE);
167 }
168
169
170 /*******************************************************************************
171 *
172 * FUNCTION: FlSwitchFileSet
173 *
174 * PARAMETERS: Op - Parse node for the LINE asl statement
175 *
176 * RETURN: None.
177 *
178 * DESCRIPTION: Set the current line number
179 *
180 ******************************************************************************/
181
182 ASL_FILE_SWITCH_STATUS
183 FlSwitchFileSet (
184 char *InputFilename)
185 {
186 ASL_GLOBAL_FILE_NODE *Current = AslGbl_FilesList;
187 char *PrevFilename = Current->Files[ASL_FILE_INPUT].Filename;
188
189
190 while (Current)
191 {
192 if (!strcmp(Current->Files[ASL_FILE_INPUT].Filename, InputFilename))
193 {
194 AslGbl_Files = Current->Files;
195 AslGbl_TableSignature = Current->TableSignature;
196 AslGbl_TableId = Current->TableId;
197
198 if (!strcmp (InputFilename, PrevFilename))
199 {
200 return (SWITCH_TO_SAME_FILE);
201 }
202 else
203 {
204 return (SWITCH_TO_DIFFERENT_FILE);
205 }
206 }
207
208 Current = Current->Next;
209 }
210
211 return (FILE_NOT_FOUND);
212 }
213
214
215 /*******************************************************************************
216 *
217 * FUNCTION: FlGetFileHandle
218 *
219 * PARAMETERS: OutFileId - denotes file type of output handle
220 * InFileId - denotes file type of the input Filename
221 * Filename
222 *
223 * RETURN: File handle
224 *
225 * DESCRIPTION: Get the file handle for a particular filename/FileId. This
226 * function also allows the caller to specify the file Id of the
227 * desired type.
228 *
229 ******************************************************************************/
230
231 FILE *
232 FlGetFileHandle (
233 UINT32 OutFileId,
234 UINT32 InFileId,
235 char *Filename)
236 {
237 ASL_GLOBAL_FILE_NODE *Current = AslGbl_FilesList;
238
239
240 if (!Filename)
241 {
242 return (NULL);
243 }
244
245 while (Current)
246 {
247 if (!strcmp (Current->Files[InFileId].Filename, Filename))
248 {
249 return (Current->Files[OutFileId].Handle);
250 }
251
252 Current = Current->Next;
253 }
254
255 return (NULL);
256 }
257
258
259 /*******************************************************************************
260 *
261 * FUNCTION: FlGetFileNode
262 *
263 * PARAMETERS: FileId - File type (ID) of the input Filename
264 * Filename - File to search for
265 *
266 * RETURN: A global file node
267 *
268 * DESCRIPTION: Get the file node for a particular filename/FileId.
269 *
270 ******************************************************************************/
271
272 ASL_GLOBAL_FILE_NODE *
273 FlGetFileNode (
274 UINT32 FileId,
275 char *Filename)
276 {
277 ASL_GLOBAL_FILE_NODE *Current = AslGbl_FilesList;
278
279
280 if (!Filename)
281 {
282 return (NULL);
283 }
284
285 while (Current)
286 {
287 if (!strcmp (Current->Files[FileId].Filename, Filename))
288 {
289 return (Current);
290 }
291
292 Current = Current->Next;
293 }
294
295 return (NULL);
296 }
297
298
299 /*******************************************************************************
300 *
301 * FUNCTION: FlGetCurrentFileNode
302 *
303 * PARAMETERS: None
304 *
305 * RETURN: Global file node
306 *
307 * DESCRIPTION: Get the current input file node
308 *
309 ******************************************************************************/
310
311 ASL_GLOBAL_FILE_NODE *
312 FlGetCurrentFileNode (
313 void)
314 {
315 return (FlGetFileNode (
316 ASL_FILE_INPUT,AslGbl_Files[ASL_FILE_INPUT].Filename));
317 }
318
319
320 /*******************************************************************************
321 *
322 * FUNCTION: FlSetLineNumber
323 *
324 * PARAMETERS: Op - Parse node for the LINE asl statement
325 *
326 * RETURN: None.
327 *
328 * DESCRIPTION: Set the current line number
329 *
330 ******************************************************************************/
331
332 void
333 FlSetLineNumber (
334 UINT32 LineNumber)
335 {
336
337 DbgPrint (ASL_PARSE_OUTPUT, "\n#line: New line number %u (old %u)\n",
338 LineNumber, AslGbl_LogicalLineNumber);
339
340 AslGbl_CurrentLineNumber = LineNumber;
341 }
342
343
344 /*******************************************************************************
345 *
346 * FUNCTION: FlSetFilename
347 *
348 * PARAMETERS: Op - Parse node for the LINE asl statement
349 *
350 * RETURN: None.
351 *
352 * DESCRIPTION: Set the current filename
353 *
354 ******************************************************************************/
355
356 void
357 FlSetFilename (
358 char *Filename)
359 {
360
361 DbgPrint (ASL_PARSE_OUTPUT, "\n#line: New filename %s (old %s)\n",
362 Filename, AslGbl_Files[ASL_FILE_INPUT].Filename);
363
364 /* No need to free any existing filename */
365
366 AslGbl_Files[ASL_FILE_INPUT].Filename = Filename;
367 }
368
369
370 /*******************************************************************************
371 *
372 * FUNCTION: FlAddIncludeDirectory
373 *
374 * PARAMETERS: Dir - Directory pathname string
375 *
376 * RETURN: None
377 *
378 * DESCRIPTION: Add a directory the list of include prefix directories.
379 *
380 ******************************************************************************/
381
382 void
383 FlAddIncludeDirectory (
384 char *Dir)
385 {
386 ASL_INCLUDE_DIR *NewDir;
387 ASL_INCLUDE_DIR *NextDir;
388 ASL_INCLUDE_DIR *PrevDir = NULL;
389 UINT32 NeedsSeparator = 0;
390 size_t DirLength;
391
392
393 DirLength = strlen (Dir);
394 if (!DirLength)
395 {
396 return;
397 }
398
399 /* Make sure that the pathname ends with a path separator */
400
401 if ((Dir[DirLength-1] != '/') &&
402 (Dir[DirLength-1] != '\\'))
403 {
404 NeedsSeparator = 1;
405 }
406
407 NewDir = ACPI_CAST_PTR (ASL_INCLUDE_DIR,
408 UtLocalCacheCalloc (sizeof (ASL_INCLUDE_DIR)));
409 NewDir->Dir = UtLocalCacheCalloc (DirLength + 1 + NeedsSeparator);
410 strcpy (NewDir->Dir, Dir);
411 if (NeedsSeparator)
412 {
413 strcat (NewDir->Dir, "/");
414 }
415
416 /*
417 * Preserve command line ordering of -I options by adding new elements
418 * at the end of the list
419 */
420 NextDir = AslGbl_IncludeDirList;
421 while (NextDir)
422 {
423 PrevDir = NextDir;
424 NextDir = NextDir->Next;
425 }
426
427 if (PrevDir)
428 {
429 PrevDir->Next = NewDir;
430 }
431 else
432 {
433 AslGbl_IncludeDirList = NewDir;
434 }
435 }
436
437
438 /*******************************************************************************
439 *
440 * FUNCTION: FlMergePathnames
441 *
442 * PARAMETERS: PrefixDir - Prefix directory pathname. Can be NULL or
443 * a zero length string.
444 * FilePathname - The include filename from the source ASL.
445 *
446 * RETURN: Merged pathname string
447 *
448 * DESCRIPTION: Merge two pathnames that (probably) have common elements, to
449 * arrive at a minimal length string. Merge can occur if the
450 * FilePathname is relative to the PrefixDir.
451 *
452 ******************************************************************************/
453
454 char *
455 FlMergePathnames (
456 char *PrefixDir,
457 char *FilePathname)
458 {
459 char *CommonPath;
460 char *Pathname;
461 char *LastElement;
462
463
464 DbgPrint (ASL_PARSE_OUTPUT, "Include: Prefix path - \"%s\"\n"
465 "Include: FilePathname - \"%s\"\n",
466 PrefixDir, FilePathname);
467
468 /*
469 * If there is no prefix directory or if the file pathname is absolute,
470 * just return the original file pathname
471 */
472 if (!PrefixDir || (!*PrefixDir) ||
473 (*FilePathname == '/') ||
474 (FilePathname[1] == ':'))
475 {
476 Pathname = UtLocalCacheCalloc (strlen (FilePathname) + 1);
477 strcpy (Pathname, FilePathname);
478 goto ConvertBackslashes;
479 }
480
481 /* Need a local copy of the prefix directory path */
482
483 CommonPath = UtLocalCacheCalloc (strlen (PrefixDir) + 1);
484 strcpy (CommonPath, PrefixDir);
485
486 /*
487 * Walk forward through the file path, and simultaneously backward
488 * through the prefix directory path until there are no more
489 * relative references at the start of the file path.
490 */
491 while (*FilePathname && (!strncmp (FilePathname, "../", 3)))
492 {
493 /* Remove last element of the prefix directory path */
494
495 LastElement = strrchr (CommonPath, '/');
496 if (!LastElement)
497 {
498 goto ConcatenatePaths;
499 }
500
501 *LastElement = 0; /* Terminate CommonPath string */
502 FilePathname += 3; /* Point to next path element */
503 }
504
505 /*
506 * Remove the last element of the prefix directory path (it is the same as
507 * the first element of the file pathname), and build the final merged
508 * pathname.
509 */
510 LastElement = strrchr (CommonPath, '/');
511 if (LastElement)
512 {
513 *LastElement = 0;
514 }
515
516 /* Build the final merged pathname */
517
518 ConcatenatePaths:
519 Pathname = UtLocalCacheCalloc (
520 strlen (CommonPath) + strlen (FilePathname) + 2);
521 if (LastElement && *CommonPath)
522 {
523 strcpy (Pathname, CommonPath);
524 strcat (Pathname, "/");
525 }
526 strcat (Pathname, FilePathname);
527
528 /* Convert all backslashes to normal slashes */
529
530 ConvertBackslashes:
531 UtConvertBackslashes (Pathname);
532
533 DbgPrint (ASL_PARSE_OUTPUT, "Include: Merged Pathname - \"%s\"\n",
534 Pathname);
535 return (Pathname);
536 }
537
538
539 /*******************************************************************************
540 *
541 * FUNCTION: FlOpenIncludeWithPrefix
542 *
543 * PARAMETERS: PrefixDir - Prefix directory pathname. Can be a zero
544 * length string.
545 * Filename - The include filename from the source ASL.
546 *
547 * RETURN: Valid file descriptor if successful. Null otherwise.
548 *
549 * DESCRIPTION: Open an include file and push it on the input file stack.
550 *
551 ******************************************************************************/
552
553 static FILE *
554 FlOpenIncludeWithPrefix (
555 char *PrefixDir,
556 ACPI_PARSE_OBJECT *Op,
557 char *Filename)
558 {
559 FILE *IncludeFile;
560 char *Pathname;
561 UINT32 OriginalLineNumber;
562
563
564 /* Build the full pathname to the file */
565
566 Pathname = FlMergePathnames (PrefixDir, Filename);
567
568 DbgPrint (ASL_PARSE_OUTPUT, "Include: Opening file - \"%s\"\n\n",
569 Pathname);
570
571 /* Attempt to open the file, push if successful */
572
573 IncludeFile = fopen (Pathname, "r");
574 if (!IncludeFile)
575 {
576 return (NULL);
577 }
578
579 /*
580 * Check the entire include file for any # preprocessor directives.
581 * This is because there may be some confusion between the #include
582 * preprocessor directive and the ASL Include statement. A file included
583 * by the ASL include cannot contain preprocessor directives because
584 * the preprocessor has already run by the time the ASL include is
585 * recognized (by the compiler, not the preprocessor.)
586 *
587 * Note: DtGetNextLine strips/ignores comments.
588 * Save current line number since DtGetNextLine modifies it.
589 */
590 AslGbl_CurrentLineNumber--;
591 OriginalLineNumber = AslGbl_CurrentLineNumber;
592
593 while (DtGetNextLine (IncludeFile, DT_ALLOW_MULTILINE_QUOTES) != ASL_EOF)
594 {
595 if (AslGbl_CurrentLineBuffer[0] == '#')
596 {
597 AslError (ASL_ERROR, ASL_MSG_INCLUDE_FILE,
598 Op, "use #include instead");
599 }
600 }
601
602 AslGbl_CurrentLineNumber = OriginalLineNumber;
603
604 /* Must seek back to the start of the file */
605
606 fseek (IncludeFile, 0, SEEK_SET);
607
608 /* Push the include file on the open input file stack */
609
610 AslPushInputFileStack (IncludeFile, Pathname);
611 return (IncludeFile);
612 }
613
614
615 /*******************************************************************************
616 *
617 * FUNCTION: FlOpenIncludeFile
618 *
619 * PARAMETERS: Op - Parse node for the INCLUDE ASL statement
620 *
621 * RETURN: None.
622 *
623 * DESCRIPTION: Open an include file and push it on the input file stack.
624 *
625 ******************************************************************************/
626
627 void
628 FlOpenIncludeFile (
629 ACPI_PARSE_OBJECT *Op)
630 {
631 FILE *IncludeFile;
632 ASL_INCLUDE_DIR *NextDir;
633
634
635 /* Op must be valid */
636
637 if (!Op)
638 {
639 AslCommonError (ASL_ERROR, ASL_MSG_INCLUDE_FILE_OPEN,
640 AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
641 AslGbl_InputByteCount, AslGbl_CurrentColumn,
642 AslGbl_Files[ASL_FILE_INPUT].Filename, " - Null parse node");
643
644 return;
645 }
646
647 /*
648 * Flush out the "include ()" statement on this line, start
649 * the actual include file on the next line
650 */
651 AslResetCurrentLineBuffer ();
652 FlPrintFile (ASL_FILE_SOURCE_OUTPUT, "\n");
653 AslGbl_CurrentLineOffset++;
654
655
656 /* Attempt to open the include file */
657
658 /* If the file specifies an absolute path, just open it */
659
660 if ((Op->Asl.Value.String[0] == '/') ||
661 (Op->Asl.Value.String[0] == '\\') ||
662 (Op->Asl.Value.String[1] == ':'))
663 {
664 IncludeFile = FlOpenIncludeWithPrefix ("", Op, Op->Asl.Value.String);
665 if (!IncludeFile)
666 {
667 goto ErrorExit;
668 }
669 return;
670 }
671
672 /*
673 * The include filename is not an absolute path.
674 *
675 * First, search for the file within the "local" directory -- meaning
676 * the same directory that contains the source file.
677 *
678 * Construct the file pathname from the global directory name.
679 */
680 IncludeFile = FlOpenIncludeWithPrefix (
681 AslGbl_DirectoryPath, Op, Op->Asl.Value.String);
682 if (IncludeFile)
683 {
684 return;
685 }
686
687 /*
688 * Second, search for the file within the (possibly multiple) directories
689 * specified by the -I option on the command line.
690 */
691 NextDir = AslGbl_IncludeDirList;
692 while (NextDir)
693 {
694 IncludeFile = FlOpenIncludeWithPrefix (
695 NextDir->Dir, Op, Op->Asl.Value.String);
696 if (IncludeFile)
697 {
698 return;
699 }
700
701 NextDir = NextDir->Next;
702 }
703
704 /* We could not open the include file after trying very hard */
705
706 ErrorExit:
707 snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "%s, %s", Op->Asl.Value.String, strerror (errno));
708 AslError (ASL_ERROR, ASL_MSG_INCLUDE_FILE_OPEN, Op, AslGbl_MsgBuffer);
709 }
710
711
712 /*******************************************************************************
713 *
714 * FUNCTION: FlOpenInputFile
715 *
716 * PARAMETERS: InputFilename - The user-specified ASL source file to be
717 * compiled
718 *
719 * RETURN: Status
720 *
721 * DESCRIPTION: Open the specified input file, and save the directory path to
722 * the file so that include files can be opened in
723 * the same directory.
724 *
725 ******************************************************************************/
726
727 ACPI_STATUS
728 FlOpenInputFile (
729 char *InputFilename)
730 {
731
732 /* Open the input ASL file, text mode */
733
734 FlOpenFile (ASL_FILE_INPUT, InputFilename, "rt");
735 AslCompilerin = AslGbl_Files[ASL_FILE_INPUT].Handle;
736
737 return (AE_OK);
738 }
739
740
741 /*******************************************************************************
742 *
743 * FUNCTION: FlOpenAmlOutputFile
744 *
745 * PARAMETERS: FilenamePrefix - The user-specified ASL source file
746 *
747 * RETURN: Status
748 *
749 * DESCRIPTION: Create the output filename (*.AML) and open the file. The file
750 * is created in the same directory as the parent input file.
751 *
752 ******************************************************************************/
753
754 ACPI_STATUS
755 FlOpenAmlOutputFile (
756 char *FilenamePrefix)
757 {
758 char *Filename;
759
760
761 /* Output filename usually comes from the ASL itself */
762
763 Filename = AslGbl_Files[ASL_FILE_AML_OUTPUT].Filename;
764 if (!Filename)
765 {
766 /* Create the output AML filename */
767 if (!AcpiGbl_CaptureComments)
768 {
769 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_AML_CODE);
770 }
771 else
772 {
773 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_CONVERT_AML);
774 }
775 if (!Filename)
776 {
777 AslCommonError (ASL_ERROR, ASL_MSG_OUTPUT_FILENAME,
778 0, 0, 0, 0, NULL, NULL);
779 return (AE_ERROR);
780 }
781
782 AslGbl_Files[ASL_FILE_AML_OUTPUT].Filename = Filename;
783 }
784
785 /* Open the output AML file in binary mode */
786
787 FlOpenFile (ASL_FILE_AML_OUTPUT, Filename, "w+b");
788 return (AE_OK);
789 }
790
791
792 /*******************************************************************************
793 *
794 * FUNCTION: FlOpenMiscOutputFiles
795 *
796 * PARAMETERS: FilenamePrefix - The user-specified ASL source file
797 *
798 * RETURN: Status
799 *
800 * DESCRIPTION: Create and open the various output files needed, depending on
801 * the command line options
802 *
803 ******************************************************************************/
804
805 ACPI_STATUS
806 FlOpenMiscOutputFiles (
807 char *FilenamePrefix)
808 {
809 char *Filename;
810
811
812 /* Create/Open a map file if requested */
813
814 if (AslGbl_MapfileFlag)
815 {
816 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_MAP);
817 if (!Filename)
818 {
819 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
820 0, 0, 0, 0, NULL, NULL);
821 return (AE_ERROR);
822 }
823
824 /* Open the hex file, text mode (closed at compiler exit) */
825
826 FlOpenFile (ASL_FILE_MAP_OUTPUT, Filename, "w+t");
827
828 AslCompilerSignon (ASL_FILE_MAP_OUTPUT);
829 AslCompilerFileHeader (ASL_FILE_MAP_OUTPUT);
830 }
831
832 /* All done for disassembler */
833
834 if (AslGbl_FileType == ASL_INPUT_TYPE_BINARY_ACPI_TABLE)
835 {
836 return (AE_OK);
837 }
838
839 /* Create/Open a hex output file if asked */
840
841 if (AslGbl_HexOutputFlag)
842 {
843 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_HEX_DUMP);
844 if (!Filename)
845 {
846 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
847 0, 0, 0, 0, NULL, NULL);
848 return (AE_ERROR);
849 }
850
851 /* Open the hex file, text mode */
852
853 FlOpenFile (ASL_FILE_HEX_OUTPUT, Filename, "w+t");
854
855 AslCompilerSignon (ASL_FILE_HEX_OUTPUT);
856 AslCompilerFileHeader (ASL_FILE_HEX_OUTPUT);
857 }
858
859 /* Create/Open a debug output file if asked */
860
861 if (AslGbl_DebugFlag)
862 {
863 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_DEBUG);
864 if (!Filename)
865 {
866 AslCommonError (ASL_ERROR, ASL_MSG_DEBUG_FILENAME,
867 0, 0, 0, 0, NULL, NULL);
868 return (AE_ERROR);
869 }
870
871 /* Open the debug file as STDERR, text mode */
872
873 AslGbl_Files[ASL_FILE_DEBUG_OUTPUT].Filename = Filename;
874 AslGbl_Files[ASL_FILE_DEBUG_OUTPUT].Handle =
875 freopen (Filename, "w+t", stderr);
876
877 if (!AslGbl_Files[ASL_FILE_DEBUG_OUTPUT].Handle)
878 {
879 /*
880 * A problem with freopen is that on error, we no longer
881 * have stderr and cannot emit normal error messages.
882 * Emit error to stdout, close files, and exit.
883 */
884 fprintf (stdout,
885 "\nCould not open debug output file: %s\n\n", Filename);
886
887 CmCleanupAndExit ();
888 exit (1);
889 }
890
891 AslCompilerSignon (ASL_FILE_DEBUG_OUTPUT);
892 AslCompilerFileHeader (ASL_FILE_DEBUG_OUTPUT);
893 }
894
895 /* Create/Open a cross-reference output file if asked */
896
897 if (AslGbl_CrossReferenceOutput)
898 {
899 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_XREF);
900 if (!Filename)
901 {
902 AslCommonError (ASL_ERROR, ASL_MSG_DEBUG_FILENAME,
903 0, 0, 0, 0, NULL, NULL);
904 return (AE_ERROR);
905 }
906
907 FlOpenFile (ASL_FILE_XREF_OUTPUT, Filename, "w+t");
908
909 AslCompilerSignon (ASL_FILE_XREF_OUTPUT);
910 AslCompilerFileHeader (ASL_FILE_XREF_OUTPUT);
911 }
912
913 /* Create/Open a listing output file if asked */
914
915 if (AslGbl_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 temp file if preprocessor enabled */
934
935 if (AslGbl_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 /*
949 * Create the "user" preprocessor output file if -li flag set.
950 * Note, this file contains no embedded #line directives.
951 */
952 if (AslGbl_PreprocessorOutputFlag)
953 {
954 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_PREPROC_USER);
955 if (!Filename)
956 {
957 AslCommonError (ASL_ERROR, ASL_MSG_PREPROCESSOR_FILENAME,
958 0, 0, 0, 0, NULL, NULL);
959 return (AE_ERROR);
960 }
961
962 FlOpenFile (ASL_FILE_PREPROCESSOR_USER, Filename, "w+t");
963 }
964
965 /* All done for data table compiler */
966
967 if (AslGbl_FileType == ASL_INPUT_TYPE_ASCII_DATA)
968 {
969 return (AE_OK);
970 }
971
972 /* Create/Open a combined source output file */
973
974 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_SOURCE);
975 if (!Filename)
976 {
977 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
978 0, 0, 0, 0, NULL, NULL);
979 return (AE_ERROR);
980 }
981
982 /*
983 * Open the source output file, binary mode (so that LF does not get
984 * expanded to CR/LF on some systems, messing up our seek
985 * calculations.)
986 */
987 FlOpenFile (ASL_FILE_SOURCE_OUTPUT, Filename, "w+b");
988
989 /*
990 // TBD: TEMP
991 // AslCompilerin = AslGbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle;
992 */
993 /* Create/Open a assembly code source output file if asked */
994
995 if (AslGbl_AsmOutputFlag)
996 {
997 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_ASM_SOURCE);
998 if (!Filename)
999 {
1000 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
1001 0, 0, 0, 0, NULL, NULL);
1002 return (AE_ERROR);
1003 }
1004
1005 /* Open the assembly code source file, text mode */
1006
1007 FlOpenFile (ASL_FILE_ASM_SOURCE_OUTPUT, Filename, "w+t");
1008
1009 AslCompilerSignon (ASL_FILE_ASM_SOURCE_OUTPUT);
1010 AslCompilerFileHeader (ASL_FILE_ASM_SOURCE_OUTPUT);
1011 }
1012
1013 /* Create/Open a C code source output file if asked */
1014
1015 if (AslGbl_C_OutputFlag)
1016 {
1017 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_C_SOURCE);
1018 if (!Filename)
1019 {
1020 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
1021 0, 0, 0, 0, NULL, NULL);
1022 return (AE_ERROR);
1023 }
1024
1025 /* Open the C code source file, text mode */
1026
1027 FlOpenFile (ASL_FILE_C_SOURCE_OUTPUT, Filename, "w+t");
1028
1029 FlPrintFile (ASL_FILE_C_SOURCE_OUTPUT, "/*\n");
1030 AslCompilerSignon (ASL_FILE_C_SOURCE_OUTPUT);
1031 AslCompilerFileHeader (ASL_FILE_C_SOURCE_OUTPUT);
1032 }
1033
1034 /* Create/Open a C code source output file for the offset table if asked */
1035
1036 if (AslGbl_C_OffsetTableFlag)
1037 {
1038 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_C_OFFSET);
1039 if (!Filename)
1040 {
1041 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
1042 0, 0, 0, 0, NULL, NULL);
1043 return (AE_ERROR);
1044 }
1045
1046 /* Open the C code source file, text mode */
1047
1048 FlOpenFile (ASL_FILE_C_OFFSET_OUTPUT, Filename, "w+t");
1049
1050 FlPrintFile (ASL_FILE_C_OFFSET_OUTPUT, "/*\n");
1051 AslCompilerSignon (ASL_FILE_C_OFFSET_OUTPUT);
1052 AslCompilerFileHeader (ASL_FILE_C_OFFSET_OUTPUT);
1053 }
1054
1055 /* Create/Open a assembly include output file if asked */
1056
1057 if (AslGbl_AsmIncludeOutputFlag)
1058 {
1059 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_ASM_INCLUDE);
1060 if (!Filename)
1061 {
1062 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
1063 0, 0, 0, 0, NULL, NULL);
1064 return (AE_ERROR);
1065 }
1066
1067 /* Open the assembly include file, text mode */
1068
1069 FlOpenFile (ASL_FILE_ASM_INCLUDE_OUTPUT, Filename, "w+t");
1070
1071 AslCompilerSignon (ASL_FILE_ASM_INCLUDE_OUTPUT);
1072 AslCompilerFileHeader (ASL_FILE_ASM_INCLUDE_OUTPUT);
1073 }
1074
1075 /* Create/Open a C include output file if asked */
1076
1077 if (AslGbl_C_IncludeOutputFlag)
1078 {
1079 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_C_INCLUDE);
1080 if (!Filename)
1081 {
1082 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
1083 0, 0, 0, 0, NULL, NULL);
1084 return (AE_ERROR);
1085 }
1086
1087 /* Open the C include file, text mode */
1088
1089 FlOpenFile (ASL_FILE_C_INCLUDE_OUTPUT, Filename, "w+t");
1090
1091 FlPrintFile (ASL_FILE_C_INCLUDE_OUTPUT, "/*\n");
1092 AslCompilerSignon (ASL_FILE_C_INCLUDE_OUTPUT);
1093 AslCompilerFileHeader (ASL_FILE_C_INCLUDE_OUTPUT);
1094 }
1095
1096 /* Create a namespace output file if asked */
1097
1098 if (AslGbl_NsOutputFlag)
1099 {
1100 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_NAMESPACE);
1101 if (!Filename)
1102 {
1103 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
1104 0, 0, 0, 0, NULL, NULL);
1105 return (AE_ERROR);
1106 }
1107
1108 /* Open the namespace file, text mode */
1109
1110 FlOpenFile (ASL_FILE_NAMESPACE_OUTPUT, Filename, "w+t");
1111
1112 AslCompilerSignon (ASL_FILE_NAMESPACE_OUTPUT);
1113 AslCompilerFileHeader (ASL_FILE_NAMESPACE_OUTPUT);
1114 }
1115
1116 /* Create a debug file for the converter */
1117
1118 if (AcpiGbl_DebugAslConversion)
1119 {
1120 Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_CONVERT_DEBUG);
1121 if (!Filename)
1122 {
1123 AslCommonError (ASL_ERROR, ASL_MSG_LISTING_FILENAME,
1124 0, 0, 0, 0, NULL, NULL);
1125 return (AE_ERROR);
1126 }
1127
1128 /* Open the converter debug file, text mode */
1129
1130 FlOpenFile (ASL_FILE_CONV_DEBUG_OUTPUT, Filename, "w+t");
1131
1132 AslCompilerSignon (ASL_FILE_CONV_DEBUG_OUTPUT);
1133 AslCompilerFileHeader (ASL_FILE_CONV_DEBUG_OUTPUT);
1134
1135 AcpiGbl_ConvDebugFile = AslGbl_Files[ASL_FILE_CONV_DEBUG_OUTPUT].Handle;
1136 }
1137
1138 return (AE_OK);
1139 }
1140
1141
1142 #ifdef ACPI_OBSOLETE_FUNCTIONS
1143 /*******************************************************************************
1144 *
1145 * FUNCTION: FlParseInputPathname
1146 *
1147 * PARAMETERS: InputFilename - The user-specified ASL source file to be
1148 * compiled
1149 *
1150 * RETURN: Status
1151 *
1152 * DESCRIPTION: Split the input path into a directory and filename part
1153 * 1) Directory part used to open include files
1154 * 2) Filename part used to generate output filenames
1155 *
1156 ******************************************************************************/
1157
1158 ACPI_STATUS
1159 FlParseInputPathname (
1160 char *InputFilename)
1161 {
1162 char *Substring;
1163
1164
1165 if (!InputFilename)
1166 {
1167 return (AE_OK);
1168 }
1169
1170 /* Get the path to the input filename's directory */
1171
1172 AslGbl_DirectoryPath = strdup (InputFilename);
1173 if (!AslGbl_DirectoryPath)
1174 {
1175 return (AE_NO_MEMORY);
1176 }
1177
1178 Substring = strrchr (AslGbl_DirectoryPath, '\\');
1179 if (!Substring)
1180 {
1181 Substring = strrchr (AslGbl_DirectoryPath, '/');
1182 if (!Substring)
1183 {
1184 Substring = strrchr (AslGbl_DirectoryPath, ':');
1185 }
1186 }
1187
1188 if (!Substring)
1189 {
1190 AslGbl_DirectoryPath[0] = 0;
1191 if (AslGbl_UseDefaultAmlFilename)
1192 {
1193 AslGbl_OutputFilenamePrefix = strdup (InputFilename);
1194 }
1195 }
1196 else
1197 {
1198 if (AslGbl_UseDefaultAmlFilename)
1199 {
1200 AslGbl_OutputFilenamePrefix = strdup (Substring + 1);
1201 }
1202 *(Substring+1) = 0;
1203 }
1204
1205 UtConvertBackslashes (AslGbl_OutputFilenamePrefix);
1206 return (AE_OK);
1207 }
1208 #endif
1209