12 # if defined(__CYGWIN__) || defined(__WIN32__)
13 # define WIMLIBAPI __declspec(dllexport)
15 # define WIMLIBAPI __attribute__((visibility("default")))
17 # define ALWAYS_INLINE inline __attribute__((always_inline))
18 # define PACKED __attribute__((packed))
19 //# define FORMAT(type, format_str, args_start) \
20 //__attribute__((format(type, format_str, args_start)))
21 # define FORMAT(type, format_str, args_start)
22 # if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
23 # define COLD __attribute__((cold))
29 # define ALWAYS_INLINE inline
30 # define FORMAT(type, format_str, args_start)
38 #define atomic_inc(ptr) \
39 __sync_fetch_and_add(ptr, 1)
41 #define atomic_dec(ptr) \
42 __sync_sub_and_fetch(ptr, 1)
54 /* A pointer to 'utf16lechar' indicates a UTF-16LE encoded string */
55 typedef u16 utf16lechar;
60 /* For Windows builds, the "tchar" type will be 2 bytes and will be equivalent
61 * to "wchar_t" and "utf16lechar". All indicate one code unit of a UTF16-LE
63 typedef wchar_t tchar;
64 # define TCHAR_IS_UTF16LE 1
65 # define T(text) L##text /* Make a string literal into a wide string */
66 # define TS "ls" /* Format a string of "tchar" */
67 # define WS "ls" /* Format a UTF-16LE string (same as above) */
69 /* For Windows builds, the following definitions replace the "tchar" functions
70 * with the "wide-character" functions. */
71 # define tmemchr wmemchr
72 # define tmemcpy wmemcpy
73 # define tstrcpy wcscpy
74 # define tprintf wprintf
75 # define tsprintf swprintf
76 # define tfprintf fwprintf
77 # define tvfprintf vfwprintf
78 # define istalpha iswalpha
79 # define tstrcmp wcscmp
80 # define tstrchr wcschr
81 # define tstrrchr wcsrchr
82 # define tstrlen wcslen
83 # define tmemcmp wmemcmp
84 # define tstrftime wcsftime
85 # define tputchar putwchar
88 # define tfputs fputws
89 # define tfopen _wfopen
90 # define tstat _wstati64
91 # define tstrtol wcstol
92 # define tunlink _wunlink
93 /* The following "tchar" functions do not have exact wide-character equivalents
94 * on Windows so require parameter rearrangement or redirection to a replacement
95 * function defined ourselves. */
96 # define TSTRDUP WSTRDUP
97 # define tmkdir(path, mode) _wmkdir(path)
98 # define tstrerror_r(errnum, buf, bufsize) _wcserror_s(buf, bufsize, errnum)
99 # define trename win32_rename_replacement
100 # define ttruncate win32_truncate_replacement
102 /* For non-Windows builds, the "tchar" type will be one byte and will specify a
103 * string in the locale-dependent multibyte encoding. However, only UTF-8 is
104 * well supported in this library. */
106 # define TCHAR_IS_UTF16LE 0
107 # define T(text) text /* In this case, strings of "tchar" are simply strings of
109 # define TS "s" /* Similarly, a string of "tchar" is printed just as a
111 # define WS "W" /* UTF-16LE strings must be printed using a special
112 extension implemented by wimlib itself. Note that
113 "ls" will not work here because a string of wide
114 characters on non-Windows systems is typically not
116 /* For non-Windows builds, replace the "tchar" functions with the regular old
117 * string functions. */
118 # define tmemchr memchr
119 # define tmemcpy memcpy
120 # define tstrcpy strcpy
121 # define tprintf printf
122 # define tsprintf sprintf
123 # define tfprintf fprintf
124 # define tvfprintf vfprintf
125 # define istalpha isalpha
126 # define tstrcmp strcmp
127 # define tstrchr strchr
128 # define tstrrchr strrchr
129 # define tstrlen strlen
130 # define tmemcmp memcmp
131 # define tstrftime strftime
132 # define tputchar putchar
135 # define tfputs fputs
136 # define tfopen fopen
138 # define tunlink unlink
139 # define tstrtol strtol
140 # define tmkdir mkdir
141 # define TSTRDUP STRDUP
142 # define tstrerror_r strerror_r
143 # define trename rename
144 # define ttruncate truncate
147 #define TMALLOC(n) MALLOC((n) * sizeof(tchar))
150 utf16le_strlen(const utf16lechar *s);
154 iconv_global_cleanup();
156 extern bool wimlib_mbs_is_utf8;
158 #define DECLARE_CHAR_CONVERSION_FUNCTIONS(varname1, varname2, \
159 chartype1, chartype2) \
162 varname1##_to_##varname2##_nbytes(const chartype1 *in, size_t in_nbytes,\
163 size_t *out_nbytes_ret); \
166 varname1##_to_##varname2##_buf(const chartype1 *in, size_t in_nbytes, \
170 varname1##_to_##varname2(const chartype1 *in, size_t in_nbytes, \
171 chartype2 **out_ret, \
172 size_t *out_nbytes_ret); \
174 #if !TCHAR_IS_UTF16LE
175 DECLARE_CHAR_CONVERSION_FUNCTIONS(utf16le, tstr, utf16lechar, tchar);
179 utf8_to_tstr_simple(const utf8char *utf8str, tchar **out);
182 tstr_to_utf8_simple(const tchar *tstr, utf8char **out);
185 #define min(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); \
186 (__a < __b) ? __a : __b; })
190 #define max(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); \
191 (__a > __b) ? __a : __b; })
195 #define swap(a, b) ({typeof(a) _a = a; (a) = (b); (b) = _a;})
199 * container_of - cast a member of a structure out to the containing structure
200 * @ptr: the pointer to the member.
201 * @type: the type of the container struct this is embedded in.
202 * @member: the name of the member within the struct.
206 #define container_of(ptr, type, member) ({ \
207 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
208 (type *)( (char *)__mptr - offsetof(type,member) );})
211 #define DIV_ROUND_UP(numerator, denominator) \
212 (((numerator) + (denominator) - 1) / (denominator))
214 #define MODULO_NONZERO(numerator, denominator) \
215 (((numerator) % (denominator)) ? ((numerator) % (denominator)) : (denominator))
217 #define ARRAY_LEN(array) (sizeof(array) / sizeof((array)[0]))
219 #define ZERO_ARRAY(array) memset(array, 0, sizeof(array))
221 /* Used for buffering FILE IO in a few places */
222 #define BUFFER_SIZE 4096
224 static inline void FORMAT(printf, 1, 2)
225 dummy_printf(const char *format, ...)
229 #ifdef ENABLE_ERROR_MESSAGES
231 wimlib_error(const tchar *format, ...) FORMAT(printf, 1, 2) COLD;
234 wimlib_error_with_errno(const tchar *format, ...) FORMAT(printf, 1, 2) COLD;
237 wimlib_warning(const tchar *format, ...) FORMAT(printf, 1, 2) COLD;
240 wimlib_warning_with_errno(const tchar *format, ...) FORMAT(printf, 1, 2) COLD;
241 # define ERROR(format, ...) wimlib_error(T(format), ## __VA_ARGS__)
242 # define ERROR_WITH_ERRNO(format, ...) wimlib_error_with_errno(T(format), ## __VA_ARGS__)
243 # define WARNING(format, ...) wimlib_warning(T(format), ## __VA_ARGS__)
244 # define WARNING_WITH_ERRNO(format, ...) wimlib_warning(T(format), ## __VA_ARGS__)
245 #else /* ENABLE_ERROR_MESSAGES */
246 # define ERROR(format, ...) dummy_printf(format, ## __VA_ARGS__)
247 # define ERROR_WITH_ERRNO(format, ...) dummy_printf(format, ## __VA_ARGS__)
248 # define WARNING(format, ...) dummy_printf(format, ## __VA_ARGS__)
249 # define WARNING_WITH_ERRNO(format, ...) dummy_printf(format, ## __VA_ARGS__)
250 #endif /* !ENABLE_ERROR_MESSAGES */
252 #if defined(ENABLE_MORE_DEBUG) && !defined(ENABLE_DEBUG)
253 # define ENABLE_DEBUG 1
256 #if defined(ENABLE_MORE_ASSERTIONS) && !defined(ENABLE_ASSERTIONS)
257 # define ENABLE_ASSERTIONS 1
262 wimlib_debug(const tchar *file, int line, const char *func,
263 const tchar *format, ...);
264 # define DEBUG(format, ...) \
265 wimlib_debug(T(__FILE__), __LINE__, __func__, T(format), ## __VA_ARGS__);
268 # define DEBUG(format, ...) dummy_printf(format, ## __VA_ARGS__)
269 #endif /* !ENABLE_DEBUG */
271 #ifdef ENABLE_MORE_DEBUG
272 # define DEBUG2(format, ...) DEBUG(format, ## __VA_ARGS__)
274 # define DEBUG2(format, ...) dummy_printf(format, ## __VA_ARGS__)
275 #endif /* !ENABLE_MORE_DEBUG */
277 #ifdef ENABLE_ASSERTIONS
279 # define wimlib_assert(expr) assert(expr)
281 # define wimlib_assert(expr)
282 #endif /* !ENABLE_ASSERTIONS */
284 #ifdef ENABLE_MORE_ASSERTIONS
285 # define wimlib_assert2(expr) wimlib_assert(expr)
287 # define wimlib_assert2(expr)
288 #endif /* !ENABLE_MORE_ASSERTIONS */
290 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
292 #ifdef ENABLE_CUSTOM_MEMORY_ALLOCATOR
293 extern void *(*wimlib_malloc_func)(size_t);
294 extern void (*wimlib_free_func)(void *);
295 extern void *(*wimlib_realloc_func)(void *, size_t);
296 extern void *wimlib_calloc(size_t nmemb, size_t size);
298 extern wchar_t *wimlib_wcsdup(const wchar_t *str);
300 extern char *wimlib_strdup(const char *str);
301 # define MALLOC wimlib_malloc_func
302 # define FREE wimlib_free_func
303 # define REALLOC wimlib_realloc_func
304 # define CALLOC wimlib_calloc
305 # define STRDUP wimlib_strdup
306 # define WSTRDUP wimlib_wcsdup
307 #else /* ENABLE_CUSTOM_MEMORY_ALLOCATOR */
310 # define MALLOC malloc
312 # define REALLOC realloc
313 # define CALLOC calloc
314 # define STRDUP strdup
315 # define WSTRDUP wcsdup
316 #endif /* !ENABLE_CUSTOM_MEMORY_ALLOCATOR */
321 randomize_byte_array(u8 *p, size_t n);
324 randomize_char_array_with_alnum(tchar p[], size_t n);
327 path_next_part(const tchar *path, size_t *first_part_len_ret);
330 path_basename(const tchar *path);
333 path_stream_name(const tchar *path);
336 to_parent_name(tchar *buf, size_t len);
339 print_string(const void *string, size_t len);
342 get_num_path_components(const char *path);
345 print_byte_field(const u8 field[], size_t len)
348 tprintf(T("%02hhx"), *field++);
354 #if defined(__x86__) || defined(__x86_64__)
361 while ((n >>= 1) != 0)
368 wimlib_fprintf(FILE *fp, const tchar *format, ...)
369 //FORMAT(printf, 2, 3)
373 wimlib_printf(const tchar *format, ...)
374 //FORMAT(printf, 1, 2)
377 #endif /* _WIMLIB_UTIL_H */