adfile.c revision 306536
1/******************************************************************************
2 *
3 * Module Name: adfile - Application-level disassembler file support routines
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2016, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
45#include <contrib/dev/acpica/include/acpi.h>
46#include <contrib/dev/acpica/include/accommon.h>
47#include <contrib/dev/acpica/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
57static INT32
58AdWriteBuffer (
59    char                    *Filename,
60    char                    *Buffer,
61    UINT32                  Length);
62
63static 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
79char *
80AdGenerateFilename (
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
121static INT32
122AdWriteBuffer (
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
164void
165AdWriteTable (
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
195char *
196FlGenerateFilename (
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 = UtStringCacheCalloc ((ACPI_SIZE)
210        strlen (InputFilename) + strlen (Suffix) + 2);
211    if (!NewFilename)
212    {
213        return (NULL);
214    }
215
216    strcpy (NewFilename, InputFilename);
217
218    /* Try to find the last dot in the filename */
219
220    DirectoryPosition = strrchr (NewFilename, '/');
221    Position = strrchr (NewFilename, '.');
222
223    if (Position && (Position > DirectoryPosition))
224    {
225        /* Tack on the new suffix */
226
227        Position++;
228        *Position = 0;
229        strcat (Position, Suffix);
230    }
231    else
232    {
233        /* No dot, add one and then the suffix */
234
235        strcat (NewFilename, ".");
236        strcat (NewFilename, Suffix);
237    }
238
239    return (NewFilename);
240}
241
242
243/*******************************************************************************
244 *
245 * FUNCTION:    FlStrdup
246 *
247 * DESCRIPTION: Local strdup function
248 *
249 ******************************************************************************/
250
251static char *
252FlStrdup (
253    char                *String)
254{
255    char                *NewString;
256
257
258    NewString = UtStringCacheCalloc ((ACPI_SIZE) strlen (String) + 1);
259    if (!NewString)
260    {
261        return (NULL);
262    }
263
264    strcpy (NewString, String);
265    return (NewString);
266}
267
268
269/*******************************************************************************
270 *
271 * FUNCTION:    FlSplitInputPathname
272 *
273 * PARAMETERS:  InputFilename       - The user-specified ASL source file to be
274 *                                    compiled
275 *              OutDirectoryPath    - Where the directory path prefix is
276 *                                    returned
277 *              OutFilename         - Where the filename part is returned
278 *
279 * RETURN:      Status
280 *
281 * DESCRIPTION: Split the input path into a directory and filename part
282 *              1) Directory part used to open include files
283 *              2) Filename part used to generate output filenames
284 *
285 ******************************************************************************/
286
287ACPI_STATUS
288FlSplitInputPathname (
289    char                    *InputPath,
290    char                    **OutDirectoryPath,
291    char                    **OutFilename)
292{
293    char                    *Substring;
294    char                    *DirectoryPath;
295    char                    *Filename;
296
297
298    if (OutDirectoryPath)
299    {
300        *OutDirectoryPath = NULL;
301    }
302
303    if (!InputPath)
304    {
305        return (AE_OK);
306    }
307
308    /* Get the path to the input filename's directory */
309
310    DirectoryPath = FlStrdup (InputPath);
311    if (!DirectoryPath)
312    {
313        return (AE_NO_MEMORY);
314    }
315
316    /* Convert backslashes to slashes in the entire path */
317
318    UtConvertBackslashes (DirectoryPath);
319
320    /* Backup to last slash or colon */
321
322    Substring = strrchr (DirectoryPath, '/');
323    if (!Substring)
324    {
325        Substring = strrchr (DirectoryPath, ':');
326    }
327
328    /* Extract the simple filename */
329
330    if (!Substring)
331    {
332        Filename = FlStrdup (DirectoryPath);
333        DirectoryPath[0] = 0;
334    }
335    else
336    {
337        Filename = FlStrdup (Substring + 1);
338        *(Substring+1) = 0;
339    }
340
341    if (!Filename)
342    {
343        return (AE_NO_MEMORY);
344    }
345
346    if (OutDirectoryPath)
347    {
348        *OutDirectoryPath = DirectoryPath;
349    }
350
351    if (OutFilename)
352    {
353        *OutFilename = Filename;
354        return (AE_OK);
355    }
356
357    return (AE_OK);
358}
359