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