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