1/******************************************************************************
2 *
3 * Module Name: adfile - Application-level disassembler file support routines
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2013, 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
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, ACPI_TABLE_FILE_SUFFIX);
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
203
204    /*
205     * Copy the original filename to a new buffer. Leave room for the worst case
206     * where we append the suffix, an added dot and the null terminator.
207     */
208    NewFilename = ACPI_ALLOCATE_ZEROED ((ACPI_SIZE)
209        strlen (InputFilename) + strlen (Suffix) + 2);
210    strcpy (NewFilename, InputFilename);
211
212    /* Try to find the last dot in the filename */
213
214    Position = strrchr (NewFilename, '.');
215    if (Position)
216    {
217        /* Tack on the new suffix */
218
219        Position++;
220        *Position = 0;
221        strcat (Position, Suffix);
222    }
223    else
224    {
225        /* No dot, add one and then the suffix */
226
227        strcat (NewFilename, ".");
228        strcat (NewFilename, Suffix);
229    }
230
231    return (NewFilename);
232}
233
234
235/*******************************************************************************
236 *
237 * FUNCTION:    FlStrdup
238 *
239 * DESCRIPTION: Local strdup function
240 *
241 ******************************************************************************/
242
243static char *
244FlStrdup (
245    char                *String)
246{
247    char                *NewString;
248
249
250    NewString = ACPI_ALLOCATE ((ACPI_SIZE) strlen (String) + 1);
251    if (!NewString)
252    {
253        return (NULL);
254    }
255
256    strcpy (NewString, String);
257    return (NewString);
258}
259
260
261/*******************************************************************************
262 *
263 * FUNCTION:    FlSplitInputPathname
264 *
265 * PARAMETERS:  InputFilename       - The user-specified ASL source file to be
266 *                                    compiled
267 *              OutDirectoryPath    - Where the directory path prefix is
268 *                                    returned
269 *              OutFilename         - Where the filename part is returned
270 *
271 * RETURN:      Status
272 *
273 * DESCRIPTION: Split the input path into a directory and filename part
274 *              1) Directory part used to open include files
275 *              2) Filename part used to generate output filenames
276 *
277 ******************************************************************************/
278
279ACPI_STATUS
280FlSplitInputPathname (
281    char                    *InputPath,
282    char                    **OutDirectoryPath,
283    char                    **OutFilename)
284{
285    char                    *Substring;
286    char                    *DirectoryPath;
287    char                    *Filename;
288
289
290    *OutDirectoryPath = NULL;
291    *OutFilename = NULL;
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    *OutDirectoryPath = DirectoryPath;
337    *OutFilename = Filename;
338    return (AE_OK);
339}
340