add_params: Embed inode table and sd_set directly
[wimlib] / src / util.h
1 #ifndef _WIMLIB_UTIL_H
2 #define _WIMLIB_UTIL_H
3
4 #include "config.h"
5 #include "wimlib_tchar.h"
6
7 #include <stdio.h>
8 #include <stdbool.h>
9 #include <stddef.h>
10 #include <inttypes.h>
11 #include <sys/types.h>
12
13 #ifdef __GNUC__
14 #       if defined(__CYGWIN__) || defined(__WIN32__)
15 #               define WIMLIBAPI __declspec(dllexport)
16 #       else
17 #               define WIMLIBAPI __attribute__((visibility("default")))
18 #       endif
19 #       define ALWAYS_INLINE inline __attribute__((always_inline))
20 #       define PACKED __attribute__((packed))
21 #       define FORMAT(type, format_str, args_start) \
22                         /*__attribute__((format(type, format_str, args_start))) */
23 #       if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
24 #               define COLD     __attribute__((cold))
25 #       else
26 #               define COLD
27 #       endif
28 #else
29 #       define WIMLIBAPI
30 #       define ALWAYS_INLINE inline
31 #       define FORMAT(type, format_str, args_start)
32 #       define COLD
33 #       define PACKED
34 #endif /* __GNUC__ */
35
36
37 #if 0
38 #ifdef WITH_FUSE
39 #define atomic_inc(ptr) \
40         __sync_fetch_and_add(ptr, 1)
41
42 #define atomic_dec(ptr) \
43         __sync_sub_and_fetch(ptr, 1)
44 #endif
45 #endif
46
47 #ifndef _NTFS_TYPES_H
48 typedef uint8_t  u8;
49 typedef uint16_t u16;
50 typedef uint32_t u32;
51 typedef uint64_t u64;
52 #endif
53
54
55 /* A pointer to 'utf16lechar' indicates a UTF-16LE encoded string */
56 typedef u16 utf16lechar;
57
58 #define TMALLOC(n) MALLOC((n) * sizeof(tchar))
59
60 /* encoding.c */
61 extern void
62 iconv_global_cleanup();
63
64 extern bool wimlib_mbs_is_utf8;
65
66 #define DECLARE_CHAR_CONVERSION_FUNCTIONS(varname1, varname2,           \
67                                           chartype1, chartype2)         \
68                                                                         \
69 extern int                                                              \
70 varname1##_to_##varname2(const chartype1 *in, size_t in_nbytes,         \
71                          chartype2 **out_ret,                           \
72                          size_t *out_nbytes_ret);                       \
73                                                                         \
74 extern int                                                              \
75 varname1##_to_##varname2##_nbytes(const chartype1 *in, size_t in_nbytes,\
76                                   size_t *out_nbytes_ret);              \
77                                                                         \
78 extern int                                                              \
79 varname1##_to_##varname2##_buf(const chartype1 *in, size_t in_nbytes,   \
80                                chartype2 *out);
81
82
83 #if !TCHAR_IS_UTF16LE
84 DECLARE_CHAR_CONVERSION_FUNCTIONS(utf16le, tstr, utf16lechar, tchar);
85 DECLARE_CHAR_CONVERSION_FUNCTIONS(tstr, utf16le, tchar, utf16lechar);
86 #endif
87
88 extern int
89 utf8_to_tstr_simple(const char *utf8str, tchar **out);
90
91 extern int
92 tstr_to_utf8_simple(const tchar *tstr, char **out);
93
94 #ifndef min
95 #define min(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); \
96                                         (__a < __b) ? __a : __b; })
97 #endif
98
99 #ifndef max
100 #define max(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); \
101                                         (__a > __b) ? __a : __b; })
102 #endif
103
104 #ifndef swap
105 #define swap(a, b) ({typeof(a) _a = a; (a) = (b); (b) = _a;})
106 #endif
107
108 /**
109  * container_of - cast a member of a structure out to the containing structure
110  * @ptr:        the pointer to the member.
111  * @type:       the type of the container struct this is embedded in.
112  * @member:     the name of the member within the struct.
113  *
114  */
115 #ifndef container_of
116 #define container_of(ptr, type, member) ({                      \
117         const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
118         (type *)( (char *)__mptr - offsetof(type,member) );})
119 #endif
120
121 #define DIV_ROUND_UP(numerator, denominator) \
122         (((numerator) + (denominator) - 1) / (denominator))
123
124 #define MODULO_NONZERO(numerator, denominator) \
125         (((numerator) % (denominator)) ? ((numerator) % (denominator)) : (denominator))
126
127 #define ARRAY_LEN(array) (sizeof(array) / sizeof((array)[0]))
128
129 #define ZERO_ARRAY(array) memset(array, 0, sizeof(array))
130
131 /* Used for buffering FILE IO in a few places */
132 #define BUFFER_SIZE 32768
133
134 static inline void FORMAT(printf, 1, 2)
135 dummy_tprintf(const tchar *format, ...)
136 {
137 }
138
139 #ifdef ENABLE_ERROR_MESSAGES
140 extern void
141 wimlib_error(const tchar *format, ...) FORMAT(printf, 1, 2) COLD;
142
143 extern void
144 wimlib_error_with_errno(const tchar *format, ...) FORMAT(printf, 1, 2) COLD;
145
146 extern void
147 wimlib_warning(const tchar *format, ...) FORMAT(printf, 1, 2) COLD;
148
149 extern void
150 wimlib_warning_with_errno(const tchar *format, ...) FORMAT(printf, 1, 2) COLD;
151 #  define ERROR(format, ...)                    wimlib_error(T(format), ## __VA_ARGS__)
152 #  define ERROR_WITH_ERRNO(format, ...)         wimlib_error_with_errno(T(format), ## __VA_ARGS__)
153 #  define WARNING(format, ...)                  wimlib_warning(T(format), ## __VA_ARGS__)
154 #  define WARNING_WITH_ERRNO(format, ...)       wimlib_warning_with_errno(T(format), ## __VA_ARGS__)
155 #else /* ENABLE_ERROR_MESSAGES */
156 #  define ERROR(format, ...)                    dummy_tprintf(T(format), ## __VA_ARGS__)
157 #  define ERROR_WITH_ERRNO(format, ...)         dummy_tprintf(T(format), ## __VA_ARGS__)
158 #  define WARNING(format, ...)                  dummy_tprintf(T(format), ## __VA_ARGS__)
159 #  define WARNING_WITH_ERRNO(format, ...)       dummy_tprintf(T(format), ## __VA_ARGS__)
160 #endif /* !ENABLE_ERROR_MESSAGES */
161
162 #if defined(ENABLE_MORE_DEBUG) && !defined(ENABLE_DEBUG)
163 #  define ENABLE_DEBUG 1
164 #endif
165
166 #if defined(ENABLE_MORE_ASSERTIONS) && !defined(ENABLE_ASSERTIONS)
167 #  define ENABLE_ASSERTIONS 1
168 #endif
169
170 #ifdef ENABLE_DEBUG
171 extern void
172 wimlib_debug(const tchar *file, int line, const char *func,
173              const tchar *format, ...);
174 #  define DEBUG(format, ...) \
175                 wimlib_debug(T(__FILE__), __LINE__, __func__, T(format), ## __VA_ARGS__)
176
177 #else
178 #  define DEBUG(format, ...) dummy_tprintf(T(format), ## __VA_ARGS__)
179 #endif /* !ENABLE_DEBUG */
180
181 #ifdef ENABLE_MORE_DEBUG
182 #  define DEBUG2(format, ...) DEBUG(format, ## __VA_ARGS__)
183 #else
184 #  define DEBUG2(format, ...) dummy_tprintf(T(format), ## __VA_ARGS__)
185 #endif /* !ENABLE_MORE_DEBUG */
186
187 #ifdef ENABLE_ASSERTIONS
188 #include <assert.h>
189 #  define wimlib_assert(expr) assert(expr)
190 #else
191 #  define wimlib_assert(expr)
192 #endif /* !ENABLE_ASSERTIONS */
193
194 #ifdef ENABLE_MORE_ASSERTIONS
195 #  define wimlib_assert2(expr) wimlib_assert(expr)
196 #else
197 #  define wimlib_assert2(expr)
198 #endif /* !ENABLE_MORE_ASSERTIONS */
199
200 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
201
202 #ifdef ENABLE_CUSTOM_MEMORY_ALLOCATOR
203 extern void *(*wimlib_malloc_func)(size_t);
204 extern void (*wimlib_free_func)(void *);
205 extern void *(*wimlib_realloc_func)(void *, size_t);
206 extern void *wimlib_calloc(size_t nmemb, size_t size);
207 #ifdef __WIN32__
208 extern wchar_t *wimlib_wcsdup(const wchar_t *str);
209 #endif
210 extern char *wimlib_strdup(const char *str);
211 #  define       MALLOC  wimlib_malloc_func
212 #  define       FREE    wimlib_free_func
213 #  define       REALLOC wimlib_realloc_func
214 #  define       CALLOC  wimlib_calloc
215 #  define       STRDUP  wimlib_strdup
216 #  define       WSTRDUP wimlib_wcsdup
217 #else /* ENABLE_CUSTOM_MEMORY_ALLOCATOR */
218 #  include <stdlib.h>
219 #  include <string.h>
220 #  define       MALLOC  malloc
221 #  define       FREE    free
222 #  define       REALLOC realloc
223 #  define       CALLOC  calloc
224 #  define       STRDUP  strdup
225 #  define       WSTRDUP wcsdup
226 #endif /* !ENABLE_CUSTOM_MEMORY_ALLOCATOR */
227
228
229 /* util.c */
230 extern void
231 randomize_byte_array(u8 *p, size_t n);
232
233 extern void
234 randomize_char_array_with_alnum(tchar p[], size_t n);
235
236 const tchar *
237 path_basename_with_len(const tchar *path, size_t len);
238
239 const tchar *
240 path_basename(const tchar *path);
241
242 extern const tchar *
243 path_stream_name(const tchar *path);
244
245 static inline void
246 print_byte_field(const u8 field[], size_t len, FILE *out)
247 {
248         while (len--)
249                 tfprintf(out, T("%02hhx"), *field++);
250 }
251
252 static inline u32
253 bsr32(u32 n)
254 {
255 #if defined(__x86__) || defined(__x86_64__)
256         asm("bsrl %0, %0;"
257                         : "=r"(n)
258                         : "0" (n));
259         return n;
260 #else
261         u32 pow = 0;
262         while ((n >>= 1) != 0)
263                 pow++;
264         return pow;
265 #endif
266 }
267
268 #ifdef __WIN32__
269 #  define wimlib_fprintf fwprintf
270 #  define wimlib_printf  wprintf
271 #else /* __WIN32__ */
272 extern int
273 wimlib_fprintf(FILE *fp, const tchar *format, ...) FORMAT(printf, 2, 3);
274
275 extern int
276 wimlib_printf(const tchar *format, ...) FORMAT(printf, 1, 2);
277 #endif /* !__WIN32__ */
278
279 extern void
280 zap_backslashes(tchar *s);
281
282 extern tchar *
283 canonicalize_wim_path(const tchar *wim_path);
284
285 extern tchar *
286 canonicalize_fs_path(const tchar *fs_path);
287
288 static inline u64
289 hash_u64(u64 n)
290 {
291         return n * 0x9e37fffffffc0001ULL;
292 }
293
294 extern size_t
295 full_read(int fd, void *buf, size_t n);
296
297 extern size_t
298 full_write(int fd, const void *buf, size_t n);
299
300 extern size_t
301 full_pread(int fd, void *buf, size_t nbyte, off_t offset);
302
303 extern size_t
304 full_pwrite(int fd, const void *buf, size_t count, off_t offset);
305
306 #ifdef __WIN32__
307 struct iovec {
308         void *iov_base;
309         size_t iov_len;
310 };
311 #else
312 struct iovec;
313 #endif
314
315 extern size_t
316 full_writev(int fd, struct iovec *iov, int iovcnt);
317
318 extern off_t
319 filedes_offset(int fd);
320
321 #ifndef __WIN32__
322 #  define O_BINARY 0
323 #endif
324
325 #endif /* _WIMLIB_UTIL_H */