1 /****************************************************************************** 2 * 3 * Module Name: adfile - Application-level disassembler file support routines 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2018, 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 "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 * 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 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 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 * 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 * 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 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 * 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