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