]> wimlib.net Git - wimlib/blob - src/util.h
Encodings update (IN PROGRESS)
[wimlib] / src / util.h
1 #ifndef _WIMLIB_UTIL_H
2 #define _WIMLIB_UTIL_H
3
4 #include <stdio.h>
5 #include <stdbool.h>
6 #include <stddef.h>
7 #include <inttypes.h>
8 #include <sys/types.h>
9 #include "config.h"
10
11 #ifdef __GNUC__
12 #       if defined(__CYGWIN__) || defined(__WIN32__)
13 #               define WIMLIBAPI __declspec(dllexport)
14 #       else
15 #               define WIMLIBAPI __attribute__((visibility("default")))
16 #       endif
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))
24 #       else
25 #               define COLD
26 #       endif
27 #else
28 #       define WIMLIBAPI
29 #       define ALWAYS_INLINE inline
30 #       define FORMAT(type, format_str, args_start)
31 #       define COLD
32 #       define PACKED
33 #endif /* __GNUC__ */
34
35
36 #if 0
37 #ifdef WITH_FUSE
38 #define atomic_inc(ptr) \
39         __sync_fetch_and_add(ptr, 1)
40
41 #define atomic_dec(ptr) \
42         __sync_sub_and_fetch(ptr, 1)
43 #endif
44 #endif
45
46 #ifndef _NTFS_TYPES_H
47 typedef uint8_t  u8;
48 typedef uint16_t u16;
49 typedef uint32_t u32;
50 typedef uint64_t u64;
51 #endif
52
53
54 /* A pointer to 'utf16lechar' indicates a UTF-16LE encoded string */
55 typedef u16 utf16lechar;
56
57 typedef u8 utf8char;
58
59 #ifdef __WIN32__
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
62  * string. */
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) */
68
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
86 #  define tputc    putwc
87 #  define tputs    _putws
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
101 #else
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. */
105 typedef char tchar;
106 #  define TCHAR_IS_UTF16LE 0
107 #  define T(text) text /* In this case, strings of "tchar" are simply strings of
108                           char */
109 #  define TS "s"       /* Similarly, a string of "tchar" is printed just as a
110                           normal string. */
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
115                           UTF-16LE. */
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
133 #  define tputc    putc
134 #  define tputs    puts
135 #  define tfputs   fputs
136 #  define tfopen   fopen
137 #  define tstat    stat
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
145 #endif
146
147 #define TMALLOC(n) MALLOC((n) * sizeof(tchar))
148
149 extern size_t
150 utf16le_strlen(const utf16lechar *s);
151
152 /* encoding.c */
153 extern void
154 iconv_global_cleanup();
155
156 extern bool wimlib_mbs_is_utf8;
157
158 #define DECLARE_CHAR_CONVERSION_FUNCTIONS(varname1, varname2,           \
159                                           chartype1, chartype2)         \
160                                                                         \
161 extern int                                                              \
162 varname1##_to_##varname2##_nbytes(const chartype1 *in, size_t in_nbytes,\
163                                   size_t *out_nbytes_ret);              \
164                                                                         \
165 extern int                                                              \
166 varname1##_to_##varname2##_buf(const chartype1 *in, size_t in_nbytes,   \
167                                chartype2 *out);                         \
168                                                                         \
169 extern int                                                              \
170 varname1##_to_##varname2(const chartype1 *in, size_t in_nbytes,         \
171                          chartype2 **out_ret,                           \
172                          size_t *out_nbytes_ret);                       \
173
174 #if !TCHAR_IS_UTF16LE
175 DECLARE_CHAR_CONVERSION_FUNCTIONS(utf16le, tstr, utf16lechar, tchar);
176 #endif
177
178 extern int
179 utf8_to_tstr_simple(const utf8char *utf8str, tchar **out);
180
181 extern int
182 tstr_to_utf8_simple(const tchar *tstr, utf8char **out);
183
184 #ifndef min
185 #define min(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); \
186                                         (__a < __b) ? __a : __b; })
187 #endif
188
189 #ifndef max
190 #define max(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); \
191                                         (__a > __b) ? __a : __b; })
192 #endif
193
194 #ifndef swap
195 #define swap(a, b) ({typeof(a) _a = a; (a) = (b); (b) = _a;})
196 #endif
197
198 /**
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.
203  *
204  */
205 #ifndef container_of
206 #define container_of(ptr, type, member) ({                      \
207         const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
208         (type *)( (char *)__mptr - offsetof(type,member) );})
209 #endif
210
211 #define DIV_ROUND_UP(numerator, denominator) \
212         (((numerator) + (denominator) - 1) / (denominator))
213
214 #define MODULO_NONZERO(numerator, denominator) \
215         (((numerator) % (denominator)) ? ((numerator) % (denominator)) : (denominator))
216
217 #define ARRAY_LEN(array) (sizeof(array) / sizeof((array)[0]))
218
219 #define ZERO_ARRAY(array) memset(array, 0, sizeof(array))
220
221 /* Used for buffering FILE IO in a few places */
222 #define BUFFER_SIZE 4096
223
224 static inline void FORMAT(printf, 1, 2)
225 dummy_printf(const char *format, ...)
226 {
227 }
228
229 #ifdef ENABLE_ERROR_MESSAGES
230 extern void
231 wimlib_error(const tchar *format, ...) FORMAT(printf, 1, 2) COLD;
232
233 extern void
234 wimlib_error_with_errno(const tchar *format, ...) FORMAT(printf, 1, 2) COLD;
235
236 extern void
237 wimlib_warning(const tchar *format, ...) FORMAT(printf, 1, 2) COLD;
238
239 extern void
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 */
251
252 #if defined(ENABLE_MORE_DEBUG) && !defined(ENABLE_DEBUG)
253 #  define ENABLE_DEBUG 1
254 #endif
255
256 #if defined(ENABLE_MORE_ASSERTIONS) && !defined(ENABLE_ASSERTIONS)
257 #  define ENABLE_ASSERTIONS 1
258 #endif
259
260 #ifdef ENABLE_DEBUG
261 extern void
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__);
266
267 #else
268 #  define DEBUG(format, ...) dummy_printf(format, ## __VA_ARGS__)
269 #endif /* !ENABLE_DEBUG */
270
271 #ifdef ENABLE_MORE_DEBUG
272 #  define DEBUG2(format, ...) DEBUG(format, ## __VA_ARGS__)
273 #else
274 #  define DEBUG2(format, ...) dummy_printf(format, ## __VA_ARGS__)
275 #endif /* !ENABLE_MORE_DEBUG */
276
277 #ifdef ENABLE_ASSERTIONS
278 #include <assert.h>
279 #  define wimlib_assert(expr) assert(expr)
280 #else
281 #  define wimlib_assert(expr)
282 #endif /* !ENABLE_ASSERTIONS */
283
284 #ifdef ENABLE_MORE_ASSERTIONS
285 #  define wimlib_assert2(expr) wimlib_assert(expr)
286 #else
287 #  define wimlib_assert2(expr)
288 #endif /* !ENABLE_MORE_ASSERTIONS */
289
290 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
291
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);
297 #ifdef __WIN32__
298 extern wchar_t *wimlib_wcsdup(const wchar_t *str);
299 #endif
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 */
308 #  include <stdlib.h>
309 #  include <string.h>
310 #  define       MALLOC  malloc
311 #  define       FREE    free
312 #  define       REALLOC realloc
313 #  define       CALLOC  calloc
314 #  define       STRDUP  strdup
315 #  define       WSTRDUP wcsdup
316 #endif /* !ENABLE_CUSTOM_MEMORY_ALLOCATOR */
317
318
319 /* util.c */
320 extern void
321 randomize_byte_array(u8 *p, size_t n);
322
323 extern void
324 randomize_char_array_with_alnum(tchar p[], size_t n);
325
326 extern const tchar *
327 path_next_part(const tchar *path, size_t *first_part_len_ret);
328
329 const tchar *
330 path_basename_with_len(const tchar *path, size_t len);
331
332 const tchar *
333 path_basename(const tchar *path);
334
335 extern const tchar *
336 path_stream_name(const tchar *path);
337
338 extern void
339 to_parent_name(tchar *buf, size_t len);
340
341 extern void
342 print_string(const void *string, size_t len);
343
344 extern int
345 get_num_path_components(const char *path);
346
347 static inline void
348 print_byte_field(const u8 field[], size_t len)
349 {
350         while (len--)
351                 tprintf(T("%02hhx"), *field++);
352 }
353
354 static inline u32
355 bsr32(u32 n)
356 {
357 #if defined(__x86__) || defined(__x86_64__)
358         asm("bsrl %0, %0;"
359                         : "=r"(n)
360                         : "0" (n));
361         return n;
362 #else
363         u32 pow = 0;
364         while ((n >>= 1) != 0)
365                 pow++;
366         return pow;
367 #endif
368 }
369
370 extern int
371 wimlib_fprintf(FILE *fp, const tchar *format, ...)
372         //FORMAT(printf, 2, 3)
373         ;
374
375 extern int
376 wimlib_printf(const tchar *format, ...)
377         //FORMAT(printf, 1, 2)
378         ;
379
380 #endif /* _WIMLIB_UTIL_H */