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