123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525 |
- /**
- * \file libyasm/file.h
- * \brief YASM file helpers.
- *
- * \license
- * Copyright (C) 2001-2007 Peter Johnson
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- * \endlicense
- */
- #ifndef YASM_FILE_H
- #define YASM_FILE_H
- #ifndef YASM_LIB_DECL
- #define YASM_LIB_DECL
- #endif
- /** Re2c scanner state. */
- typedef struct yasm_scanner {
- unsigned char *bot; /**< Bottom of scan buffer */
- unsigned char *tok; /**< Start of token */
- unsigned char *ptr; /**< Scan marker */
- unsigned char *cur; /**< Cursor (1 past end of token) */
- unsigned char *lim; /**< Limit of good data */
- unsigned char *top; /**< Top of scan buffer */
- unsigned char *eof; /**< End of file */
- } yasm_scanner;
- /** Initialize scanner state.
- * \param scanner Re2c scanner state
- */
- YASM_LIB_DECL
- void yasm_scanner_initialize(yasm_scanner *scanner);
- /** Frees any memory used by scanner state; does not free state itself.
- * \param scanner Re2c scanner state
- */
- YASM_LIB_DECL
- void yasm_scanner_delete(yasm_scanner *scanner);
- /** Fill a scanner state structure with data coming from an input function.
- * \param scanner Re2c scanner state
- * \param cursor Re2c scan cursor
- * \param input_func Input function to read data; takes buffer and maximum
- * number of bytes, returns number of bytes read.
- * \param input_func_data Data to pass as the first parameter to input_func
- * \return 1 if this was the first time this function was called on this
- * scanner state, 0 otherwise.
- */
- YASM_LIB_DECL
- int yasm_fill_helper
- (yasm_scanner *scanner, unsigned char **cursor,
- size_t (*input_func) (void *d, unsigned char *buf, size_t max),
- void *input_func_data);
- /** Unescape a string with C-style escapes. Handles b, f, n, r, t, and hex
- * and octal escapes. String is updated in-place.
- * Edge cases:
- * - hex escapes: reads as many hex digits as possible, takes last 2 as value.
- * - oct escapes: takes up to 3 digits 0-9 and scales appropriately, with
- * warning.
- * \param str C-style string (updated in place)
- * \param len length of string (updated with new length)
- */
- YASM_LIB_DECL
- void yasm_unescape_cstring(unsigned char *str, size_t *len);
- /** Split a UNIX pathname into head (directory) and tail (base filename)
- * portions.
- * \internal
- * \param path pathname
- * \param tail (returned) base filename
- * \return Length of head (directory).
- */
- YASM_LIB_DECL
- size_t yasm__splitpath_unix(const char *path, /*@out@*/ const char **tail);
- /** Split a Windows pathname into head (directory) and tail (base filename)
- * portions.
- * \internal
- * \param path pathname
- * \param tail (returned) base filename
- * \return Length of head (directory).
- */
- YASM_LIB_DECL
- size_t yasm__splitpath_win(const char *path, /*@out@*/ const char **tail);
- /** Split a pathname into head (directory) and tail (base filename) portions.
- * Unless otherwise defined, defaults to yasm__splitpath_unix().
- * \internal
- * \param path pathname
- * \param tail (returned) base filename
- * \return Length of head (directory).
- */
- #ifndef yasm__splitpath
- # if defined (_WIN32) || defined (WIN32) || defined (__MSDOS__) || \
- defined (__DJGPP__) || defined (__OS2__)
- # define yasm__splitpath(path, tail) yasm__splitpath_win(path, tail)
- # else
- # define yasm__splitpath(path, tail) yasm__splitpath_unix(path, tail)
- # endif
- #endif
- /** Get the current working directory.
- * \internal
- * \return Current working directory pathname (newly allocated).
- */
- YASM_LIB_DECL
- /*@only@*/ char *yasm__getcwd(void);
- /** Convert a relative or absolute pathname into an absolute pathname.
- * \internal
- * \param path pathname
- * \return Absolute version of path (newly allocated).
- */
- YASM_LIB_DECL
- /*@only@*/ char *yasm__abspath(const char *path);
- /** Build a UNIX pathname that is equivalent to accessing the "to" pathname
- * when you're in the directory containing "from". Result is relative if both
- * from and to are relative.
- * \internal
- * \param from from pathname
- * \param to to pathname
- * \return Combined path (newly allocated).
- */
- YASM_LIB_DECL
- char *yasm__combpath_unix(const char *from, const char *to);
- /** Build a Windows pathname that is equivalent to accessing the "to" pathname
- * when you're in the directory containing "from". Result is relative if both
- * from and to are relative.
- * \internal
- * \param from from pathname
- * \param to to pathname
- * \return Combined path (newly allocated).
- */
- YASM_LIB_DECL
- char *yasm__combpath_win(const char *from, const char *to);
- /** Build a pathname that is equivalent to accessing the "to" pathname
- * when you're in the directory containing "from". Result is relative if both
- * from and to are relative.
- * Unless otherwise defined, defaults to yasm__combpath_unix().
- * \internal
- * \param from from pathname
- * \param to to pathname
- * \return Combined path (newly allocated).
- */
- #ifndef yasm__combpath
- # if defined (_WIN32) || defined (WIN32) || defined (__MSDOS__) || \
- defined (__DJGPP__) || defined (__OS2__)
- # define yasm__combpath(from, to) yasm__combpath_win(from, to)
- # else
- # define yasm__combpath(from, to) yasm__combpath_unix(from, to)
- # endif
- #endif
- /** Recursively create tree of directories needed for pathname.
- * \internal
- * \param path pathname
- * \param win handle windows paths
- * \return Length of directory portion of pathname.
- */
- YASM_LIB_DECL
- size_t yasm__createpath_common(const char *path, int win);
- /** Recursively create tree of directories needed for pathname.
- * Unless otherwise defined, defaults to yasm__createpath_unix().
- * \internal
- * \param path pathname
- * \return Length of directory portion of pathname.
- */
- #ifndef yasm__createpath
- # if defined (_WIN32) || defined (WIN32) || defined (__MSDOS__) || \
- defined (__DJGPP__) || defined (__OS2__)
- # define yasm__createpath(path) yasm__createpath_common(path, 1)
- # else
- # define yasm__createpath(path) yasm__createpath_common(path, 0)
- # endif
- #endif
- /** Try to find and open an include file, searching through include paths.
- * First iname is looked for relative to the directory containing "from", then
- * it's looked for relative to each of the include paths.
- *
- * All pathnames may be either absolute or relative; from, oname, and
- * include paths, if relative, are relative from the current working directory.
- *
- * First match wins; the full pathname (newly allocated) to the opened file
- * is saved into oname, and the fopen'ed FILE * is returned. If not found,
- * NULL is returned.
- *
- * \param iname file to include
- * \param from file doing the including
- * \param mode fopen mode string
- * \param oname full pathname of included file (may be relative). NULL
- * may be passed if this is unwanted.
- * \return fopen'ed include file, or NULL if not found.
- */
- YASM_LIB_DECL
- /*@null@*/ FILE *yasm_fopen_include
- (const char *iname, const char *from, const char *mode,
- /*@null@*/ /*@out@*/ /*@only@*/ char **oname);
- /** Delete any stored include paths added by yasm_add_include_path().
- */
- YASM_LIB_DECL
- void yasm_delete_include_paths(void);
- /** Iterate through include paths.
- */
- YASM_LIB_DECL
- const char * yasm_get_include_dir(void **iter);
- /** Add an include path for use by yasm_fopen_include().
- * If path is relative, it is treated by yasm_fopen_include() as relative to
- * the current working directory.
- *
- * \param path path to add
- */
- YASM_LIB_DECL
- void yasm_add_include_path(const char *path);
- /** Write an 8-bit value to a buffer, incrementing buffer pointer.
- * \note Only works properly if ptr is an (unsigned char *).
- * \param ptr buffer
- * \param val 8-bit value
- */
- #define YASM_WRITE_8(ptr, val) \
- *((ptr)++) = (unsigned char)((val) & 0xFF)
- /** Write a 16-bit value to a buffer in little endian, incrementing buffer
- * pointer.
- * \note Only works properly if ptr is an (unsigned char *).
- * \param ptr buffer
- * \param val 16-bit value
- */
- #define YASM_WRITE_16_L(ptr, val) \
- do { \
- *((ptr)++) = (unsigned char)((val) & 0xFF); \
- *((ptr)++) = (unsigned char)(((val) >> 8) & 0xFF); \
- } while (0)
- /** Write a 32-bit value to a buffer in little endian, incrementing buffer
- * pointer.
- * \note Only works properly if ptr is an (unsigned char *).
- * \param ptr buffer
- * \param val 32-bit value
- */
- #define YASM_WRITE_32_L(ptr, val) \
- do { \
- *((ptr)++) = (unsigned char)((val) & 0xFF); \
- *((ptr)++) = (unsigned char)(((val) >> 8) & 0xFF); \
- *((ptr)++) = (unsigned char)(((val) >> 16) & 0xFF); \
- *((ptr)++) = (unsigned char)(((val) >> 24) & 0xFF); \
- } while (0)
- /** Write a 16-bit value to a buffer in big endian, incrementing buffer
- * pointer.
- * \note Only works properly if ptr is an (unsigned char *).
- * \param ptr buffer
- * \param val 16-bit value
- */
- #define YASM_WRITE_16_B(ptr, val) \
- do { \
- *((ptr)++) = (unsigned char)(((val) >> 8) & 0xFF); \
- *((ptr)++) = (unsigned char)((val) & 0xFF); \
- } while (0)
- /** Write a 32-bit value to a buffer in big endian, incrementing buffer
- * pointer.
- * \note Only works properly if ptr is an (unsigned char *).
- * \param ptr buffer
- * \param val 32-bit value
- */
- #define YASM_WRITE_32_B(ptr, val) \
- do { \
- *((ptr)++) = (unsigned char)(((val) >> 24) & 0xFF); \
- *((ptr)++) = (unsigned char)(((val) >> 16) & 0xFF); \
- *((ptr)++) = (unsigned char)(((val) >> 8) & 0xFF); \
- *((ptr)++) = (unsigned char)((val) & 0xFF); \
- } while (0)
- /** Write an 8-bit value to a buffer. Does not increment buffer pointer.
- * \note Only works properly if ptr is an (unsigned char *).
- * \param ptr buffer
- * \param val 8-bit value
- */
- #define YASM_SAVE_8(ptr, val) \
- *(ptr) = (unsigned char)((val) & 0xFF)
- /** Write a 16-bit value to a buffer in little endian. Does not increment
- * buffer pointer.
- * \note Only works properly if ptr is an (unsigned char *).
- * \param ptr buffer
- * \param val 16-bit value
- */
- #define YASM_SAVE_16_L(ptr, val) \
- do { \
- *(ptr) = (unsigned char)((val) & 0xFF); \
- *((ptr)+1) = (unsigned char)(((val) >> 8) & 0xFF); \
- } while (0)
- /** Write a 32-bit value to a buffer in little endian. Does not increment
- * buffer pointer.
- * \note Only works properly if ptr is an (unsigned char *).
- * \param ptr buffer
- * \param val 32-bit value
- */
- #define YASM_SAVE_32_L(ptr, val) \
- do { \
- *(ptr) = (unsigned char)((val) & 0xFF); \
- *((ptr)+1) = (unsigned char)(((val) >> 8) & 0xFF); \
- *((ptr)+2) = (unsigned char)(((val) >> 16) & 0xFF); \
- *((ptr)+3) = (unsigned char)(((val) >> 24) & 0xFF); \
- } while (0)
- /** Write a 16-bit value to a buffer in big endian. Does not increment buffer
- * pointer.
- * \note Only works properly if ptr is an (unsigned char *).
- * \param ptr buffer
- * \param val 16-bit value
- */
- #define YASM_SAVE_16_B(ptr, val) \
- do { \
- *(ptr) = (unsigned char)(((val) >> 8) & 0xFF); \
- *((ptr)+1) = (unsigned char)((val) & 0xFF); \
- } while (0)
- /** Write a 32-bit value to a buffer in big endian. Does not increment buffer
- * pointer.
- * \note Only works properly if ptr is an (unsigned char *).
- * \param ptr buffer
- * \param val 32-bit value
- */
- #define YASM_SAVE_32_B(ptr, val) \
- do { \
- *(ptr) = (unsigned char)(((val) >> 24) & 0xFF); \
- *((ptr)+1) = (unsigned char)(((val) >> 16) & 0xFF); \
- *((ptr)+2) = (unsigned char)(((val) >> 8) & 0xFF); \
- *((ptr)+3) = (unsigned char)((val) & 0xFF); \
- } while (0)
- /** Direct-to-file version of YASM_SAVE_16_L().
- * \note Using the macro multiple times with a single fwrite() call will
- * probably be faster than calling this function many times.
- * \param val 16-bit value
- * \param f file
- * \return 1 if the write was successful, 0 if not (just like fwrite()).
- */
- YASM_LIB_DECL
- size_t yasm_fwrite_16_l(unsigned short val, FILE *f);
- /** Direct-to-file version of YASM_SAVE_32_L().
- * \note Using the macro multiple times with a single fwrite() call will
- * probably be faster than calling this function many times.
- * \param val 32-bit value
- * \param f file
- * \return 1 if the write was successful, 0 if not (just like fwrite()).
- */
- YASM_LIB_DECL
- size_t yasm_fwrite_32_l(unsigned long val, FILE *f);
- /** Direct-to-file version of YASM_SAVE_16_B().
- * \note Using the macro multiple times with a single fwrite() call will
- * probably be faster than calling this function many times.
- * \param val 16-bit value
- * \param f file
- * \return 1 if the write was successful, 0 if not (just like fwrite()).
- */
- YASM_LIB_DECL
- size_t yasm_fwrite_16_b(unsigned short val, FILE *f);
- /** Direct-to-file version of YASM_SAVE_32_B().
- * \note Using the macro multiple times with a single fwrite() call will
- * probably be faster than calling this function many times.
- * \param val 32-bit value
- * \param f file
- * \return 1 if the write was successful, 0 if not (just like fwrite()).
- */
- YASM_LIB_DECL
- size_t yasm_fwrite_32_b(unsigned long val, FILE *f);
- /** Read an 8-bit value from a buffer, incrementing buffer pointer.
- * \note Only works properly if ptr is an (unsigned char *).
- * \param ptr buffer
- * \param val 8-bit value
- */
- #define YASM_READ_8(val, ptr) \
- (val) = *((ptr)++) & 0xFF
- /** Read a 16-bit value from a buffer in little endian, incrementing buffer
- * pointer.
- * \note Only works properly if ptr is an (unsigned char *).
- * \param ptr buffer
- * \param val 16-bit value
- */
- #define YASM_READ_16_L(val, ptr) \
- do { \
- (val) = *((ptr)++) & 0xFF; \
- (val) |= (*((ptr)++) & 0xFF) << 8; \
- } while (0)
- /** Read a 32-bit value from a buffer in little endian, incrementing buffer
- * pointer.
- * \note Only works properly if ptr is an (unsigned char *).
- * \param ptr buffer
- * \param val 32-bit value
- */
- #define YASM_READ_32_L(val, ptr) \
- do { \
- (val) = *((ptr)++) & 0xFF; \
- (val) |= (*((ptr)++) & 0xFF) << 8; \
- (val) |= (*((ptr)++) & 0xFF) << 16; \
- (val) |= (*((ptr)++) & 0xFF) << 24; \
- } while (0)
- /** Read a 16-bit value from a buffer in big endian, incrementing buffer
- * pointer.
- * \note Only works properly if ptr is an (unsigned char *).
- * \param ptr buffer
- * \param val 16-bit value
- */
- #define YASM_READ_16_B(val, ptr) \
- do { \
- (val) = (*((ptr)++) & 0xFF) << 8; \
- (val) |= *((ptr)++) & 0xFF; \
- } while (0)
- /** Read a 32-bit value from a buffer in big endian, incrementing buffer
- * pointer.
- * \note Only works properly if ptr is an (unsigned char *).
- * \param ptr buffer
- * \param val 32-bit value
- */
- #define YASM_READ_32_B(val, ptr) \
- do { \
- (val) = (*((ptr)++) & 0xFF) << 24; \
- (val) |= (*((ptr)++) & 0xFF) << 16; \
- (val) |= (*((ptr)++) & 0xFF) << 8; \
- (val) |= *((ptr)++) & 0xFF; \
- } while (0)
- /** Read an 8-bit value from a buffer. Does not increment buffer pointer.
- * \note Only works properly if ptr is an (unsigned char *).
- * \param ptr buffer
- * \param val 8-bit value
- */
- #define YASM_LOAD_8(val, ptr) \
- (val) = *(ptr) & 0xFF
- /** Read a 16-bit value from a buffer in little endian. Does not increment
- * buffer pointer.
- * \note Only works properly if ptr is an (unsigned char *).
- * \param ptr buffer
- * \param val 16-bit value
- */
- #define YASM_LOAD_16_L(val, ptr) \
- do { \
- (val) = *(ptr) & 0xFF; \
- (val) |= (*((ptr)+1) & 0xFF) << 8; \
- } while (0)
- /** Read a 32-bit value from a buffer in little endian. Does not increment
- * buffer pointer.
- * \note Only works properly if ptr is an (unsigned char *).
- * \param ptr buffer
- * \param val 32-bit value
- */
- #define YASM_LOAD_32_L(val, ptr) \
- do { \
- (val) = (unsigned long)(*(ptr) & 0xFF); \
- (val) |= (unsigned long)((*((ptr)+1) & 0xFF) << 8); \
- (val) |= (unsigned long)((*((ptr)+2) & 0xFF) << 16); \
- (val) |= (unsigned long)((*((ptr)+3) & 0xFF) << 24); \
- } while (0)
- /** Read a 16-bit value from a buffer in big endian. Does not increment buffer
- * pointer.
- * \note Only works properly if ptr is an (unsigned char *).
- * \param ptr buffer
- * \param val 16-bit value
- */
- #define YASM_LOAD_16_B(val, ptr) \
- do { \
- (val) = (*(ptr) & 0xFF) << 8; \
- (val) |= *((ptr)+1) & 0xFF; \
- } while (0)
- /** Read a 32-bit value from a buffer in big endian. Does not increment buffer
- * pointer.
- * \note Only works properly if ptr is an (unsigned char *).
- * \param ptr buffer
- * \param val 32-bit value
- */
- #define YASM_LOAD_32_B(val, ptr) \
- do { \
- (val) = (unsigned long)((*(ptr) & 0xFF) << 24); \
- (val) |= (unsigned long)((*((ptr)+1) & 0xFF) << 16); \
- (val) |= (unsigned long)((*((ptr)+2) & 0xFF) << 8); \
- (val) |= (unsigned long)(*((ptr)+3) & 0xFF); \
- } while (0)
- #endif
|