]> wimlib.net Git - wimlib/blob - src/util.h
b56fa4fa33e487350a249607a65b5723d3f0c132
[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 #       if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
22 #               define COLD     __attribute__((cold))
23 #       else
24 #               define COLD
25 #       endif
26 #else
27 #       define WIMLIBAPI
28 #       define ALWAYS_INLINE inline
29 #       define FORMAT(type, format_str, args_start)
30 #       define COLD
31 #       define PACKED
32 #endif /* __GNUC__ */
33
34
35 #if 0
36 #ifdef WITH_FUSE
37 #define atomic_inc(ptr) \
38         __sync_fetch_and_add(ptr, 1)
39
40 #define atomic_dec(ptr) \
41         __sync_sub_and_fetch(ptr, 1)
42 #endif
43 #endif
44
45 #ifndef _NTFS_TYPES_H
46 typedef uint8_t  u8;
47 typedef uint16_t u16;
48 typedef uint32_t u32;
49 typedef uint64_t u64;
50 #endif
51
52 #ifndef min
53 #define min(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); \
54                                         (__a < __b) ? __a : __b; })
55 #endif
56
57 #ifndef max
58 #define max(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); \
59                                         (__a > __b) ? __a : __b; })
60 #endif
61
62 #ifndef swap
63 #define swap(a, b) ({typeof(a) _a = a; (a) = (b); (b) = _a;})
64 #endif
65
66 /**
67  * container_of - cast a member of a structure out to the containing structure
68  * @ptr:        the pointer to the member.
69  * @type:       the type of the container struct this is embedded in.
70  * @member:     the name of the member within the struct.
71  *
72  */
73 #ifndef container_of
74 #define container_of(ptr, type, member) ({                      \
75         const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
76         (type *)( (char *)__mptr - offsetof(type,member) );})
77 #endif
78
79 #define DIV_ROUND_UP(numerator, denominator) \
80         (((numerator) + (denominator) - 1) / (denominator))
81
82 #define MODULO_NONZERO(numerator, denominator) \
83         (((numerator) % (denominator)) ? ((numerator) % (denominator)) : (denominator))
84
85 #define ARRAY_LEN(array) (sizeof(array) / sizeof((array)[0]))
86
87 #define ZERO_ARRAY(array) memset(array, 0, sizeof(array))
88
89 /* Used for buffering FILE IO in a few places */
90 #define BUFFER_SIZE 4096
91
92 static inline void FORMAT(printf, 1, 2)
93 dummy_printf(const char *format, ...)
94 {
95 }
96
97 #ifdef ENABLE_ERROR_MESSAGES
98 extern void wimlib_error(const char *format, ...)
99                 FORMAT(printf, 1, 2) COLD;
100 extern void wimlib_error_with_errno(const char *format, ...)
101                 FORMAT(printf, 1, 2) COLD;
102 extern void wimlib_warning(const char *format, ...)
103                 FORMAT(printf, 1, 2) COLD;
104 extern void wimlib_warning_with_errno(const char *format, ...)
105                 FORMAT(printf, 1, 2) COLD;
106 #       define ERROR                    wimlib_error
107 #       define ERROR_WITH_ERRNO         wimlib_error_with_errno
108 #       define WARNING                  wimlib_warning
109 #       define WARNING_WITH_ERRNO       wimlib_warning
110 #else
111 #       define ERROR(format, ...)               dummy_printf
112 #       define ERROR_WITH_ERRNO(format, ...)    dummy_printf
113 #       define WARNING(format, ...)             dummy_printf
114 #       define WARNING_WITH_ERRNO(format, ...)  dummy_printf
115 #endif /* ENABLE_ERROR_MESSAGES */
116
117 #if defined(ENABLE_DEBUG) || defined(ENABLE_MORE_DEBUG)
118 #       include <errno.h>
119 #       define DEBUG(format, ...)                                       \
120         ({                                                              \
121                 int __errno_save = errno;                               \
122                 fprintf(stdout, "[%s %d] %s(): " format,                \
123                         __FILE__, __LINE__, __func__, ## __VA_ARGS__);  \
124                 putchar('\n');                                          \
125                 fflush(stdout);                                         \
126                 errno = __errno_save;                                   \
127         })
128
129 #else
130 #       define DEBUG(format, ...) dummy_printf(format, ## __VA_ARGS__)
131 #endif /* ENABLE_DEBUG || ENABLE_MORE_DEBUG */
132
133 #ifdef ENABLE_MORE_DEBUG
134 #       define DEBUG2(format, ...) DEBUG(format, ## __VA_ARGS__)
135 #else
136 #       define DEBUG2(format, ...) dummy_printf(format, ## __VA_ARGS__)
137 #endif /* ENABLE_DEBUG */
138
139 #ifdef ENABLE_ASSERTIONS
140 #include <assert.h>
141 #       define wimlib_assert(expr) assert(expr)
142 #else
143 #       define wimlib_assert(expr)
144 #endif
145
146 #ifdef ENABLE_MORE_ASSERTIONS
147 #define wimlib_assert2(expr) wimlib_assert(expr)
148 #else
149 #define wimlib_assert2(expr)
150 #endif
151
152 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
153
154 #ifdef ENABLE_CUSTOM_MEMORY_ALLOCATOR
155 extern void *(*wimlib_malloc_func)(size_t);
156 extern void (*wimlib_free_func)(void *);
157 extern void *(*wimlib_realloc_func)(void *, size_t);
158 extern void *wimlib_calloc(size_t nmemb, size_t size);
159 extern char *wimlib_strdup(const char *str);
160 #       define  MALLOC  wimlib_malloc_func
161 #       define  FREE    wimlib_free_func
162 #       define  REALLOC wimlib_realloc_func
163 #       define  CALLOC  wimlib_calloc
164 #       define  STRDUP  wimlib_strdup
165 #else
166 #       include <stdlib.h>
167 #       include <string.h>
168 #       define  MALLOC  malloc
169 #       define  FREE    free
170 #       define  REALLOC realloc
171 #       define  CALLOC  calloc
172 #       define  STRDUP  strdup
173 #endif /* ENABLE_CUSTOM_MEMORY_ALLOCATOR */
174
175
176 /* encoding.c */
177
178 #if defined(WITH_NTFS_3G) || defined(__WIN32__)
179 static inline int iconv_global_init()
180 {
181         return 0;
182 }
183
184 static inline void iconv_global_cleanup() { }
185 #else
186 extern int iconv_global_init();
187 extern void iconv_global_cleanup();
188 #endif
189
190 extern int utf16_to_utf8(const char *utf16_str, size_t utf16_nbytes,
191                          char **utf8_str_ret, size_t *utf8_nbytes_ret);
192
193 extern int utf8_to_utf16(const char *utf8_str, size_t utf8_nbytes,
194                          char **utf16_str_ret, size_t *utf16_nbytes_ret);
195
196 /* util.c */
197 extern void randomize_byte_array(u8 *p, size_t n);
198
199 extern void randomize_char_array_with_alnum(char p[], size_t n);
200
201 extern const char *path_next_part(const char *path,
202                                   size_t *first_part_len_ret);
203
204 extern const char *path_basename(const char *path);
205
206 extern const char *path_stream_name(const char *path);
207
208 extern void to_parent_name(char buf[], size_t len);
209
210 extern void print_string(const void *string, size_t len);
211
212 extern int get_num_path_components(const char *path);
213
214 static inline void print_byte_field(const u8 field[], size_t len)
215 {
216         while (len--)
217                 printf("%02hhx", *field++);
218 }
219
220 static inline u32 bsr32(u32 n)
221 {
222 #if defined(__x86__) || defined(__x86_64__)
223         asm("bsrl %0, %0;"
224                         : "=r"(n)
225                         : "0" (n));
226         return n;
227 #else
228         u32 pow = 0;
229         while ((n >>= 1) != 0)
230                 pow++;
231         return pow;
232 #endif
233 }
234
235 #endif /* _WIMLIB_UTIL_H */