1 /** 2 * \file libyasm/file.h 3 * \brief YASM file helpers. 4 * 5 * \license 6 * Copyright (C) 2001-2007 Peter Johnson 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * - Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * - Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 * \endlicense 29 */ 30 #ifndef YASM_FILE_H 31 #define YASM_FILE_H 32 33 #ifndef YASM_LIB_DECL 34 #define YASM_LIB_DECL 35 #endif 36 37 /** Re2c scanner state. */ 38 typedef struct yasm_scanner { 39 unsigned char *bot; /**< Bottom of scan buffer */ 40 unsigned char *tok; /**< Start of token */ 41 unsigned char *ptr; /**< Scan marker */ 42 unsigned char *cur; /**< Cursor (1 past end of token) */ 43 unsigned char *lim; /**< Limit of good data */ 44 unsigned char *top; /**< Top of scan buffer */ 45 unsigned char *eof; /**< End of file */ 46 } yasm_scanner; 47 48 /** Initialize scanner state. 49 * \param scanner Re2c scanner state 50 */ 51 YASM_LIB_DECL 52 void yasm_scanner_initialize(yasm_scanner *scanner); 53 54 /** Frees any memory used by scanner state; does not free state itself. 55 * \param scanner Re2c scanner state 56 */ 57 YASM_LIB_DECL 58 void yasm_scanner_delete(yasm_scanner *scanner); 59 60 /** Fill a scanner state structure with data coming from an input function. 61 * \param scanner Re2c scanner state 62 * \param cursor Re2c scan cursor 63 * \param input_func Input function to read data; takes buffer and maximum 64 * number of bytes, returns number of bytes read. 65 * \param input_func_data Data to pass as the first parameter to input_func 66 * \return 1 if this was the first time this function was called on this 67 * scanner state, 0 otherwise. 68 */ 69 YASM_LIB_DECL 70 int yasm_fill_helper 71 (yasm_scanner *scanner, unsigned char **cursor, 72 size_t (*input_func) (void *d, unsigned char *buf, size_t max), 73 void *input_func_data); 74 75 /** Unescape a string with C-style escapes. Handles b, f, n, r, t, and hex 76 * and octal escapes. String is updated in-place. 77 * Edge cases: 78 * - hex escapes: reads as many hex digits as possible, takes last 2 as value. 79 * - oct escapes: takes up to 3 digits 0-9 and scales appropriately, with 80 * warning. 81 * \param str C-style string (updated in place) 82 * \param len length of string (updated with new length) 83 */ 84 YASM_LIB_DECL 85 void yasm_unescape_cstring(unsigned char *str, size_t *len); 86 87 /** Split a UNIX pathname into head (directory) and tail (base filename) 88 * portions. 89 * \internal 90 * \param path pathname 91 * \param tail (returned) base filename 92 * \return Length of head (directory). 93 */ 94 YASM_LIB_DECL 95 size_t yasm__splitpath_unix(const char *path, /*@out@*/ const char **tail); 96 97 /** Split a Windows pathname into head (directory) and tail (base filename) 98 * portions. 99 * \internal 100 * \param path pathname 101 * \param tail (returned) base filename 102 * \return Length of head (directory). 103 */ 104 YASM_LIB_DECL 105 size_t yasm__splitpath_win(const char *path, /*@out@*/ const char **tail); 106 107 /** Split a pathname into head (directory) and tail (base filename) portions. 108 * Unless otherwise defined, defaults to yasm__splitpath_unix(). 109 * \internal 110 * \param path pathname 111 * \param tail (returned) base filename 112 * \return Length of head (directory). 113 */ 114 #ifndef yasm__splitpath 115 # if defined (_WIN32) || defined (WIN32) || defined (__MSDOS__) || \ 116 defined (__DJGPP__) || defined (__OS2__) 117 # define yasm__splitpath(path, tail) yasm__splitpath_win(path, tail) 118 # else 119 # define yasm__splitpath(path, tail) yasm__splitpath_unix(path, tail) 120 # endif 121 #endif 122 123 /** Get the current working directory. 124 * \internal 125 * \return Current working directory pathname (newly allocated). 126 */ 127 YASM_LIB_DECL 128 /*@only@*/ char *yasm__getcwd(void); 129 130 /** Convert a relative or absolute pathname into an absolute pathname. 131 * \internal 132 * \param path pathname 133 * \return Absolute version of path (newly allocated). 134 */ 135 YASM_LIB_DECL 136 /*@only@*/ char *yasm__abspath(const char *path); 137 138 /** Build a UNIX pathname that is equivalent to accessing the "to" pathname 139 * when you're in the directory containing "from". Result is relative if both 140 * from and to are relative. 141 * \internal 142 * \param from from pathname 143 * \param to to pathname 144 * \return Combined path (newly allocated). 145 */ 146 YASM_LIB_DECL 147 char *yasm__combpath_unix(const char *from, const char *to); 148 149 /** Build a Windows pathname that is equivalent to accessing the "to" pathname 150 * when you're in the directory containing "from". Result is relative if both 151 * from and to are relative. 152 * \internal 153 * \param from from pathname 154 * \param to to pathname 155 * \return Combined path (newly allocated). 156 */ 157 YASM_LIB_DECL 158 char *yasm__combpath_win(const char *from, const char *to); 159 160 /** Build a pathname that is equivalent to accessing the "to" pathname 161 * when you're in the directory containing "from". Result is relative if both 162 * from and to are relative. 163 * Unless otherwise defined, defaults to yasm__combpath_unix(). 164 * \internal 165 * \param from from pathname 166 * \param to to pathname 167 * \return Combined path (newly allocated). 168 */ 169 #ifndef yasm__combpath 170 # if defined (_WIN32) || defined (WIN32) || defined (__MSDOS__) || \ 171 defined (__DJGPP__) || defined (__OS2__) 172 # define yasm__combpath(from, to) yasm__combpath_win(from, to) 173 # else 174 # define yasm__combpath(from, to) yasm__combpath_unix(from, to) 175 # endif 176 #endif 177 178 /** Recursively create tree of directories needed for pathname. 179 * \internal 180 * \param path pathname 181 * \param win handle windows paths 182 * \return Length of directory portion of pathname. 183 */ 184 YASM_LIB_DECL 185 size_t yasm__createpath_common(const char *path, int win); 186 187 /** Recursively create tree of directories needed for pathname. 188 * Unless otherwise defined, defaults to yasm__createpath_unix(). 189 * \internal 190 * \param path pathname 191 * \return Length of directory portion of pathname. 192 */ 193 #ifndef yasm__createpath 194 # if defined (_WIN32) || defined (WIN32) || defined (__MSDOS__) || \ 195 defined (__DJGPP__) || defined (__OS2__) 196 # define yasm__createpath(path) yasm__createpath_common(path, 1) 197 # else 198 # define yasm__createpath(path) yasm__createpath_common(path, 0) 199 # endif 200 #endif 201 202 /** Try to find and open an include file, searching through include paths. 203 * First iname is looked for relative to the directory containing "from", then 204 * it's looked for relative to each of the include paths. 205 * 206 * All pathnames may be either absolute or relative; from, oname, and 207 * include paths, if relative, are relative from the current working directory. 208 * 209 * First match wins; the full pathname (newly allocated) to the opened file 210 * is saved into oname, and the fopen'ed FILE * is returned. If not found, 211 * NULL is returned. 212 * 213 * \param iname file to include 214 * \param from file doing the including 215 * \param mode fopen mode string 216 * \param oname full pathname of included file (may be relative). NULL 217 * may be passed if this is unwanted. 218 * \return fopen'ed include file, or NULL if not found. 219 */ 220 YASM_LIB_DECL 221 /*@null@*/ FILE *yasm_fopen_include 222 (const char *iname, const char *from, const char *mode, 223 /*@null@*/ /*@out@*/ /*@only@*/ char **oname); 224 225 /** Delete any stored include paths added by yasm_add_include_path(). 226 */ 227 YASM_LIB_DECL 228 void yasm_delete_include_paths(void); 229 230 /** Iterate through include paths. 231 */ 232 YASM_LIB_DECL 233 const char * yasm_get_include_dir(void **iter); 234 235 /** Add an include path for use by yasm_fopen_include(). 236 * If path is relative, it is treated by yasm_fopen_include() as relative to 237 * the current working directory. 238 * 239 * \param path path to add 240 */ 241 YASM_LIB_DECL 242 void yasm_add_include_path(const char *path); 243 244 /** Write an 8-bit value to a buffer, incrementing buffer pointer. 245 * \note Only works properly if ptr is an (unsigned char *). 246 * \param ptr buffer 247 * \param val 8-bit value 248 */ 249 #define YASM_WRITE_8(ptr, val) \ 250 *((ptr)++) = (unsigned char)((val) & 0xFF) 251 252 /** Write a 16-bit value to a buffer in little endian, incrementing buffer 253 * pointer. 254 * \note Only works properly if ptr is an (unsigned char *). 255 * \param ptr buffer 256 * \param val 16-bit value 257 */ 258 #define YASM_WRITE_16_L(ptr, val) \ 259 do { \ 260 *((ptr)++) = (unsigned char)((val) & 0xFF); \ 261 *((ptr)++) = (unsigned char)(((val) >> 8) & 0xFF); \ 262 } while (0) 263 264 /** Write a 32-bit value to a buffer in little endian, incrementing buffer 265 * pointer. 266 * \note Only works properly if ptr is an (unsigned char *). 267 * \param ptr buffer 268 * \param val 32-bit value 269 */ 270 #define YASM_WRITE_32_L(ptr, val) \ 271 do { \ 272 *((ptr)++) = (unsigned char)((val) & 0xFF); \ 273 *((ptr)++) = (unsigned char)(((val) >> 8) & 0xFF); \ 274 *((ptr)++) = (unsigned char)(((val) >> 16) & 0xFF); \ 275 *((ptr)++) = (unsigned char)(((val) >> 24) & 0xFF); \ 276 } while (0) 277 278 /** Write a 16-bit value to a buffer in big endian, incrementing buffer 279 * pointer. 280 * \note Only works properly if ptr is an (unsigned char *). 281 * \param ptr buffer 282 * \param val 16-bit value 283 */ 284 #define YASM_WRITE_16_B(ptr, val) \ 285 do { \ 286 *((ptr)++) = (unsigned char)(((val) >> 8) & 0xFF); \ 287 *((ptr)++) = (unsigned char)((val) & 0xFF); \ 288 } while (0) 289 290 /** Write a 32-bit value to a buffer in big endian, incrementing buffer 291 * pointer. 292 * \note Only works properly if ptr is an (unsigned char *). 293 * \param ptr buffer 294 * \param val 32-bit value 295 */ 296 #define YASM_WRITE_32_B(ptr, val) \ 297 do { \ 298 *((ptr)++) = (unsigned char)(((val) >> 24) & 0xFF); \ 299 *((ptr)++) = (unsigned char)(((val) >> 16) & 0xFF); \ 300 *((ptr)++) = (unsigned char)(((val) >> 8) & 0xFF); \ 301 *((ptr)++) = (unsigned char)((val) & 0xFF); \ 302 } while (0) 303 304 305 /** Write an 8-bit value to a buffer. Does not increment buffer pointer. 306 * \note Only works properly if ptr is an (unsigned char *). 307 * \param ptr buffer 308 * \param val 8-bit value 309 */ 310 #define YASM_SAVE_8(ptr, val) \ 311 *(ptr) = (unsigned char)((val) & 0xFF) 312 313 /** Write a 16-bit value to a buffer in little endian. Does not increment 314 * buffer pointer. 315 * \note Only works properly if ptr is an (unsigned char *). 316 * \param ptr buffer 317 * \param val 16-bit value 318 */ 319 #define YASM_SAVE_16_L(ptr, val) \ 320 do { \ 321 *(ptr) = (unsigned char)((val) & 0xFF); \ 322 *((ptr)+1) = (unsigned char)(((val) >> 8) & 0xFF); \ 323 } while (0) 324 325 /** Write a 32-bit value to a buffer in little endian. Does not increment 326 * buffer pointer. 327 * \note Only works properly if ptr is an (unsigned char *). 328 * \param ptr buffer 329 * \param val 32-bit value 330 */ 331 #define YASM_SAVE_32_L(ptr, val) \ 332 do { \ 333 *(ptr) = (unsigned char)((val) & 0xFF); \ 334 *((ptr)+1) = (unsigned char)(((val) >> 8) & 0xFF); \ 335 *((ptr)+2) = (unsigned char)(((val) >> 16) & 0xFF); \ 336 *((ptr)+3) = (unsigned char)(((val) >> 24) & 0xFF); \ 337 } while (0) 338 339 /** Write a 16-bit value to a buffer in big endian. Does not increment buffer 340 * pointer. 341 * \note Only works properly if ptr is an (unsigned char *). 342 * \param ptr buffer 343 * \param val 16-bit value 344 */ 345 #define YASM_SAVE_16_B(ptr, val) \ 346 do { \ 347 *(ptr) = (unsigned char)(((val) >> 8) & 0xFF); \ 348 *((ptr)+1) = (unsigned char)((val) & 0xFF); \ 349 } while (0) 350 351 /** Write a 32-bit value to a buffer in big endian. Does not increment buffer 352 * pointer. 353 * \note Only works properly if ptr is an (unsigned char *). 354 * \param ptr buffer 355 * \param val 32-bit value 356 */ 357 #define YASM_SAVE_32_B(ptr, val) \ 358 do { \ 359 *(ptr) = (unsigned char)(((val) >> 24) & 0xFF); \ 360 *((ptr)+1) = (unsigned char)(((val) >> 16) & 0xFF); \ 361 *((ptr)+2) = (unsigned char)(((val) >> 8) & 0xFF); \ 362 *((ptr)+3) = (unsigned char)((val) & 0xFF); \ 363 } while (0) 364 365 /** Direct-to-file version of YASM_SAVE_16_L(). 366 * \note Using the macro multiple times with a single fwrite() call will 367 * probably be faster than calling this function many times. 368 * \param val 16-bit value 369 * \param f file 370 * \return 1 if the write was successful, 0 if not (just like fwrite()). 371 */ 372 YASM_LIB_DECL 373 size_t yasm_fwrite_16_l(unsigned short val, FILE *f); 374 375 /** Direct-to-file version of YASM_SAVE_32_L(). 376 * \note Using the macro multiple times with a single fwrite() call will 377 * probably be faster than calling this function many times. 378 * \param val 32-bit value 379 * \param f file 380 * \return 1 if the write was successful, 0 if not (just like fwrite()). 381 */ 382 YASM_LIB_DECL 383 size_t yasm_fwrite_32_l(unsigned long val, FILE *f); 384 385 /** Direct-to-file version of YASM_SAVE_16_B(). 386 * \note Using the macro multiple times with a single fwrite() call will 387 * probably be faster than calling this function many times. 388 * \param val 16-bit value 389 * \param f file 390 * \return 1 if the write was successful, 0 if not (just like fwrite()). 391 */ 392 YASM_LIB_DECL 393 size_t yasm_fwrite_16_b(unsigned short val, FILE *f); 394 395 /** Direct-to-file version of YASM_SAVE_32_B(). 396 * \note Using the macro multiple times with a single fwrite() call will 397 * probably be faster than calling this function many times. 398 * \param val 32-bit value 399 * \param f file 400 * \return 1 if the write was successful, 0 if not (just like fwrite()). 401 */ 402 YASM_LIB_DECL 403 size_t yasm_fwrite_32_b(unsigned long val, FILE *f); 404 405 /** Read an 8-bit value from a buffer, incrementing buffer pointer. 406 * \note Only works properly if ptr is an (unsigned char *). 407 * \param ptr buffer 408 * \param val 8-bit value 409 */ 410 #define YASM_READ_8(val, ptr) \ 411 (val) = *((ptr)++) & 0xFF 412 413 /** Read a 16-bit value from a buffer in little endian, incrementing buffer 414 * pointer. 415 * \note Only works properly if ptr is an (unsigned char *). 416 * \param ptr buffer 417 * \param val 16-bit value 418 */ 419 #define YASM_READ_16_L(val, ptr) \ 420 do { \ 421 (val) = *((ptr)++) & 0xFF; \ 422 (val) |= (*((ptr)++) & 0xFF) << 8; \ 423 } while (0) 424 425 /** Read a 32-bit value from a buffer in little endian, incrementing buffer 426 * pointer. 427 * \note Only works properly if ptr is an (unsigned char *). 428 * \param ptr buffer 429 * \param val 32-bit value 430 */ 431 #define YASM_READ_32_L(val, ptr) \ 432 do { \ 433 (val) = *((ptr)++) & 0xFF; \ 434 (val) |= (*((ptr)++) & 0xFF) << 8; \ 435 (val) |= (*((ptr)++) & 0xFF) << 16; \ 436 (val) |= (*((ptr)++) & 0xFF) << 24; \ 437 } while (0) 438 439 /** Read a 16-bit value from a buffer in big endian, incrementing buffer 440 * pointer. 441 * \note Only works properly if ptr is an (unsigned char *). 442 * \param ptr buffer 443 * \param val 16-bit value 444 */ 445 #define YASM_READ_16_B(val, ptr) \ 446 do { \ 447 (val) = (*((ptr)++) & 0xFF) << 8; \ 448 (val) |= *((ptr)++) & 0xFF; \ 449 } while (0) 450 451 /** Read a 32-bit value from a buffer in big endian, incrementing buffer 452 * pointer. 453 * \note Only works properly if ptr is an (unsigned char *). 454 * \param ptr buffer 455 * \param val 32-bit value 456 */ 457 #define YASM_READ_32_B(val, ptr) \ 458 do { \ 459 (val) = (*((ptr)++) & 0xFF) << 24; \ 460 (val) |= (*((ptr)++) & 0xFF) << 16; \ 461 (val) |= (*((ptr)++) & 0xFF) << 8; \ 462 (val) |= *((ptr)++) & 0xFF; \ 463 } while (0) 464 465 /** Read an 8-bit value from a buffer. Does not increment buffer pointer. 466 * \note Only works properly if ptr is an (unsigned char *). 467 * \param ptr buffer 468 * \param val 8-bit value 469 */ 470 #define YASM_LOAD_8(val, ptr) \ 471 (val) = *(ptr) & 0xFF 472 473 /** Read a 16-bit value from a buffer in little endian. Does not increment 474 * buffer pointer. 475 * \note Only works properly if ptr is an (unsigned char *). 476 * \param ptr buffer 477 * \param val 16-bit value 478 */ 479 #define YASM_LOAD_16_L(val, ptr) \ 480 do { \ 481 (val) = *(ptr) & 0xFF; \ 482 (val) |= (*((ptr)+1) & 0xFF) << 8; \ 483 } while (0) 484 485 /** Read a 32-bit value from a buffer in little endian. Does not increment 486 * buffer pointer. 487 * \note Only works properly if ptr is an (unsigned char *). 488 * \param ptr buffer 489 * \param val 32-bit value 490 */ 491 #define YASM_LOAD_32_L(val, ptr) \ 492 do { \ 493 (val) = (unsigned long)(*(ptr) & 0xFF); \ 494 (val) |= (unsigned long)((*((ptr)+1) & 0xFF) << 8); \ 495 (val) |= (unsigned long)((*((ptr)+2) & 0xFF) << 16); \ 496 (val) |= (unsigned long)((*((ptr)+3) & 0xFF) << 24); \ 497 } while (0) 498 499 /** Read a 16-bit value from a buffer in big endian. Does not increment buffer 500 * pointer. 501 * \note Only works properly if ptr is an (unsigned char *). 502 * \param ptr buffer 503 * \param val 16-bit value 504 */ 505 #define YASM_LOAD_16_B(val, ptr) \ 506 do { \ 507 (val) = (*(ptr) & 0xFF) << 8; \ 508 (val) |= *((ptr)+1) & 0xFF; \ 509 } while (0) 510 511 /** Read a 32-bit value from a buffer in big endian. Does not increment buffer 512 * pointer. 513 * \note Only works properly if ptr is an (unsigned char *). 514 * \param ptr buffer 515 * \param val 32-bit value 516 */ 517 #define YASM_LOAD_32_B(val, ptr) \ 518 do { \ 519 (val) = (unsigned long)((*(ptr) & 0xFF) << 24); \ 520 (val) |= (unsigned long)((*((ptr)+1) & 0xFF) << 16); \ 521 (val) |= (unsigned long)((*((ptr)+2) & 0xFF) << 8); \ 522 (val) |= (unsigned long)(*((ptr)+3) & 0xFF); \ 523 } while (0) 524 525 #endif 526