• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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