xref: /netbsd-src/sys/external/bsd/acpica/dist/common/adfile.c (revision 046a29855e04359424fd074e8313af6b6be8cfb6)
1 /******************************************************************************
2  *
3  * Module Name: adfile - Application-level disassembler file support routines
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 "acpi.h"
46 #include "accommon.h"
47 #include "acapps.h"
48 
49 #include <stdio.h>
50 
51 
52 #define _COMPONENT          ACPI_TOOLS
53         ACPI_MODULE_NAME    ("adfile")
54 
55 /* Local prototypes */
56 
57 static INT32
58 AdWriteBuffer (
59     char                    *Filename,
60     char                    *Buffer,
61     UINT32                  Length);
62 
63 static char                 FilenameBuf[20];
64 
65 
66 /******************************************************************************
67  *
68  * FUNCTION:    AfGenerateFilename
69  *
70  * PARAMETERS:  Prefix              - prefix string
71  *              TableId             - The table ID
72  *
73  * RETURN:      Pointer to the completed string
74  *
75  * DESCRIPTION: Build an output filename from an ACPI table ID string
76  *
77  ******************************************************************************/
78 
79 char *
AdGenerateFilename(char * Prefix,char * TableId)80 AdGenerateFilename (
81     char                    *Prefix,
82     char                    *TableId)
83 {
84     UINT32                  i;
85     UINT32                  j;
86 
87 
88     for (i = 0; Prefix[i]; i++)
89     {
90         FilenameBuf[i] = Prefix[i];
91     }
92 
93     FilenameBuf[i] = '_';
94     i++;
95 
96     for (j = 0; j < 8 && (TableId[j] != ' ') && (TableId[j] != 0); i++, j++)
97     {
98         FilenameBuf[i] = TableId[j];
99     }
100 
101     FilenameBuf[i] = 0;
102     strcat (FilenameBuf, FILE_SUFFIX_BINARY_TABLE);
103     return (FilenameBuf);
104 }
105 
106 
107 /******************************************************************************
108  *
109  * FUNCTION:    AfWriteBuffer
110  *
111  * PARAMETERS:  Filename            - name of file
112  *              Buffer              - data to write
113  *              Length              - length of data
114  *
115  * RETURN:      Actual number of bytes written
116  *
117  * DESCRIPTION: Open a file and write out a single buffer
118  *
119  ******************************************************************************/
120 
121 static INT32
AdWriteBuffer(char * Filename,char * Buffer,UINT32 Length)122 AdWriteBuffer (
123     char                    *Filename,
124     char                    *Buffer,
125     UINT32                  Length)
126 {
127     FILE                    *File;
128     ACPI_SIZE               Actual;
129 
130 
131     File = fopen (Filename, "wb");
132     if (!File)
133     {
134         printf ("Could not open file %s\n", Filename);
135         return (-1);
136     }
137 
138     Actual = fwrite (Buffer, 1, (size_t) Length, File);
139     if (Actual != Length)
140     {
141         printf ("Could not write to file %s\n", Filename);
142     }
143 
144     fclose (File);
145     return ((INT32) Actual);
146 }
147 
148 
149 /******************************************************************************
150  *
151  * FUNCTION:    AfWriteTable
152  *
153  * PARAMETERS:  Table               - pointer to the ACPI table
154  *              Length              - length of the table
155  *              TableName           - the table signature
156  *              OemTableID          - from the table header
157  *
158  * RETURN:      None
159  *
160  * DESCRIPTION: Dump the loaded tables to a file (or files)
161  *
162  ******************************************************************************/
163 
164 void
AdWriteTable(ACPI_TABLE_HEADER * Table,UINT32 Length,char * TableName,char * OemTableId)165 AdWriteTable (
166     ACPI_TABLE_HEADER       *Table,
167     UINT32                  Length,
168     char                    *TableName,
169     char                    *OemTableId)
170 {
171     char                    *Filename;
172 
173 
174     Filename = AdGenerateFilename (TableName, OemTableId);
175     AdWriteBuffer (Filename, (char *) Table, Length);
176 
177     AcpiOsPrintf ("Table [%s] written to \"%s\"\n", TableName, Filename);
178 }
179 
180 
181 /*******************************************************************************
182  *
183  * FUNCTION:    FlGenerateFilename
184  *
185  * PARAMETERS:  InputFilename       - Original ASL source filename
186  *              Suffix              - New extension.
187  *
188  * RETURN:      New filename containing the original base + the new suffix
189  *
190  * DESCRIPTION: Generate a new filename from the ASL source filename and a new
191  *              extension. Used to create the *.LST, *.TXT, etc. files.
192  *
193  ******************************************************************************/
194 
195 char *
FlGenerateFilename(char * InputFilename,char * Suffix)196 FlGenerateFilename (
197     char                    *InputFilename,
198     char                    *Suffix)
199 {
200     char                    *Position;
201     char                    *NewFilename;
202     char                    *DirectoryPosition;
203 
204 
205     /*
206      * Copy the original filename to a new buffer. Leave room for the worst
207      * case where we append the suffix, an added dot and the null terminator.
208      */
209     NewFilename = UtLocalCacheCalloc ((ACPI_SIZE)
210         strlen (InputFilename) + strlen (Suffix) + 2);
211     strcpy (NewFilename, InputFilename);
212 
213     /* Try to find the last dot in the filename */
214 
215     DirectoryPosition = strrchr (NewFilename, '/');
216     Position = strrchr (NewFilename, '.');
217 
218     if (Position && (Position > DirectoryPosition))
219     {
220         /* Tack on the new suffix */
221 
222         Position++;
223         *Position = 0;
224         strcat (Position, Suffix);
225     }
226     else
227     {
228         /* No dot, add one and then the suffix */
229 
230         strcat (NewFilename, ".");
231         strcat (NewFilename, Suffix);
232     }
233 
234     return (NewFilename);
235 }
236 
237 
238 /*******************************************************************************
239  *
240  * FUNCTION:    FlStrdup
241  *
242  * DESCRIPTION: Local strdup function
243  *
244  ******************************************************************************/
245 
246 static char *
FlStrdup(char * String)247 FlStrdup (
248     char                *String)
249 {
250     char                *NewString;
251 
252 
253     NewString = UtLocalCacheCalloc ((ACPI_SIZE) strlen (String) + 1);
254     strcpy (NewString, String);
255     return (NewString);
256 }
257 
258 
259 /*******************************************************************************
260  *
261  * FUNCTION:    FlSplitInputPathname
262  *
263  * PARAMETERS:  InputFilename       - The user-specified ASL source file to be
264  *                                    compiled
265  *              OutDirectoryPath    - Where the directory path prefix is
266  *                                    returned
267  *              OutFilename         - Where the filename part is returned
268  *
269  * RETURN:      Status
270  *
271  * DESCRIPTION: Split the input path into a directory and filename part
272  *              1) Directory part used to open include files
273  *              2) Filename part used to generate output filenames
274  *
275  ******************************************************************************/
276 
277 ACPI_STATUS
FlSplitInputPathname(char * InputPath,char ** OutDirectoryPath,char ** OutFilename)278 FlSplitInputPathname (
279     char                    *InputPath,
280     char                    **OutDirectoryPath,
281     char                    **OutFilename)
282 {
283     char                    *Substring;
284     char                    *DirectoryPath;
285     char                    *Filename;
286 
287 
288     if (OutDirectoryPath)
289     {
290         *OutDirectoryPath = NULL;
291     }
292 
293     if (!InputPath)
294     {
295         return (AE_OK);
296     }
297 
298     /* Get the path to the input filename's directory */
299 
300     DirectoryPath = FlStrdup (InputPath);
301     if (!DirectoryPath)
302     {
303         return (AE_NO_MEMORY);
304     }
305 
306     /* Convert backslashes to slashes in the entire path */
307 
308     UtConvertBackslashes (DirectoryPath);
309 
310     /* Backup to last slash or colon */
311 
312     Substring = strrchr (DirectoryPath, '/');
313     if (!Substring)
314     {
315         Substring = strrchr (DirectoryPath, ':');
316     }
317 
318     /* Extract the simple filename */
319 
320     if (!Substring)
321     {
322         Filename = FlStrdup (DirectoryPath);
323         DirectoryPath[0] = 0;
324     }
325     else
326     {
327         Filename = FlStrdup (Substring + 1);
328         *(Substring+1) = 0;
329     }
330 
331     if (!Filename)
332     {
333         return (AE_NO_MEMORY);
334     }
335 
336     if (OutDirectoryPath)
337     {
338         *OutDirectoryPath = DirectoryPath;
339     }
340 
341     if (OutFilename)
342     {
343         *OutFilename = Filename;
344         return (AE_OK);
345     }
346 
347     return (AE_OK);
348 }
349 
350 
351 /*******************************************************************************
352  *
353  * FUNCTION:    FlGetFileBasename
354  *
355  * PARAMETERS:  FilePathname            - File path to be split
356  *
357  * RETURN:      The extracted base name of the file, in upper case
358  *
359  * DESCRIPTION: Extract the file base name (the file name with no extension)
360  *              from the input pathname.
361  *
362  *              Note: Any backslashes in the pathname should be previously
363  *              converted to forward slashes before calling this function.
364  *
365  ******************************************************************************/
366 
367 char *
FlGetFileBasename(char * FilePathname)368 FlGetFileBasename (
369     char                    *FilePathname)
370 {
371     char                    *FileBasename;
372     char                    *Substring;
373 
374 
375     /* Backup to last slash or colon */
376 
377     Substring = strrchr (FilePathname, '/');
378     if (!Substring)
379     {
380         Substring = strrchr (FilePathname, ':');
381     }
382 
383     /* Extract the full filename (base + extension) */
384 
385     if (Substring)
386     {
387         FileBasename = FlStrdup (Substring + 1);
388     }
389     else
390     {
391         FileBasename = FlStrdup (FilePathname);
392     }
393 
394     /* Remove the filename extension if present */
395 
396     Substring = strchr (FileBasename, '.');
397     if (Substring)
398     {
399         *Substring = 0;
400     }
401 
402     AcpiUtStrupr (FileBasename);
403     return (FileBasename);
404 }
405