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