• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef BASEDEFS_H
2 #define BASEDEFS_H
3 
4 /**************************************************************************************************
5  * IOWOW library
6  *
7  * MIT License
8  *
9  * Copyright (c) 2012-2022 Softmotions Ltd <info@softmotions.com>
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a copy
12  * of this software and associated documentation files (the "Software"), to deal
13  * in the Software without restriction, including without limitation the rights
14  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15  *  copies of the Software, and to permit persons to whom the Software is
16  * furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included in all
19  * copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27  * SOFTWARE.
28  *************************************************************************************************/
29 
30 /**
31  * @file
32  * @brief Very basic definitions.
33  * @author Anton Adamansky (adamansky@softmotions.com)
34  */
35 
36 #ifdef __cplusplus
37 #define IW_EXTERN_C_START extern "C" {
38 #define IW_EXTERN_C_END   }
39 #else
40 #define IW_EXTERN_C_START
41 #define IW_EXTERN_C_END
42 #endif
43 
44 #define IW_XSTR(s) IW_STR(s)
45 #define IW_STR(s)  #s
46 
47 #define IW_MAX(x__, y__) ({ __typeof__(x__) x = (x__);  __typeof__(y__) y = (y__); x < y ? y : x; })
48 #define IW_MIN(x__, y__) ({ __typeof__(x__) x = (x__);  __typeof__(y__) y = (y__); x < y ? x : y; })
49 #define IW_LLEN(l__)     (sizeof(l__) - 1)
50 
51 #if (defined(_WIN32) || defined(_WIN64))
52 #if (defined(IW_NODLL) || defined(IW_STATIC))
53 #define IW_EXPORT
54 #else
55 #ifdef IW_API_EXPORTS
56 #define IW_EXPORT __declspec(dllexport)
57 #else
58 #define IW_EXPORT __declspec(dllimport)
59 #endif
60 #endif
61 #else
62 #if __GNUC__ >= 4
63 #define IW_EXPORT __attribute__((visibility("default")))
64 #else
65 #define IW_EXPORT
66 #endif
67 #endif
68 
69 #if defined(__GNUC__)
70 #define IW_INLINE static inline __attribute__((always_inline))
71 #else
72 #define IW_INLINE static inline
73 #endif
74 
75 #define IW_SOFT_INLINE static inline
76 
77 #if __GNUC__ >= 4
78 #define WUR      __attribute__((warn_unused_result))
79 #define IW_ALLOC __attribute__((malloc)) __attribute__((warn_unused_result))
80 #define IW_NORET __attribute__((noreturn))
81 #else
82 #define WUR
83 #define IW_ALLOC
84 #define IW_NORET
85 #endif
86 
87 #define IW_CONSTRUCTOR __attribute__((constructor))
88 #define IW_DESTRUCTOR  __attribute__((destructor))
89 
90 #define IW_CLEANUP(func__) __attribute__(cleanup(func__))
91 
92 #define IW_CLEANUP_FUNC(type__, func__)             \
93   static inline void func__ ## _cc(type__ * p) {    \
94     if (*p) {                                       \
95       *p = func__(*p);                              \
96     }                                               \
97   }
98 
99 #define IW_CLEANUP_DESTROY_FUNC(type__, func__)     \
100   static inline void func__ ## _cc(type__ * p) {    \
101     if (*p) {                                       \
102       func__(*p);                                   \
103     }                                               \
104   }
105 
106 
107 #define IW_SENTINEL __attribute__((sentinel))
108 
109 #define IW_ARR_STATIC static
110 #define IW_ARR_CONST  const
111 
112 #ifdef _WIN32
113 #include <windows.h>
114 #define INVALIDHANDLE(h__) \
115   (((h__) == INVALID_HANDLE_VALUE) || (h__) == NULL)
116 #else
117 typedef int HANDLE;
118 #define INVALID_HANDLE_VALUE (-1)
119 #define INVALIDHANDLE(h__) ((h__) < 0 || (h__) == UINT16_MAX)
120 #endif
121 
122 #define IW_ERROR_START 70000
123 
124 #define IWNUMBUF_SIZE 32
125 
126 #ifdef _WIN32
127 #define IW_PATH_CHR '\\'
128 #define IW_PATH_STR "\\"
129 #define IW_LINE_SEP "\r\n"
130 #else
131 #define IW_PATH_CHR '/'
132 #define IW_PATH_STR "/"
133 #define IW_LINE_SEP "\n"
134 #endif
135 
136 #define ZGO(label__, val__)           \
137   ({ __typeof__(val__) v__ = (val__); \
138      if (!v__) goto label__;           \
139      v__; })
140 
141 #define ZRET(ret__, val__)            \
142   ({ __typeof__(val__) v__ = (val__); \
143      if (!v__) return ret__;           \
144      v__; })
145 
146 #ifdef __GNUC__
147 #define RCGO(rc__, label__) if (__builtin_expect((!!(rc__)), 0)) goto label__
148 #else
149 #define RCGO(rc__, label__) if (rc__) goto label__
150 #endif
151 
152 #define RCIF(res__, rc__, rcv__, label__)   \
153   if (res__) {                              \
154     rc__ = (rcv__);                         \
155     goto label__;                           \
156   }
157 
158 #define RCHECK(rc__, label__, expr__) \
159   rc__ = expr__;                       \
160   RCGO(rc__, label__)
161 
162 #define RCC(rc__, label__, expr__) RCHECK(rc__, label__, expr__)
163 
164 #ifndef RCGA
165 #define RCGA(v__, label__)                        \
166   if (!(v__)) {                                   \
167     rc = iwrc_set_errno(IW_ERROR_ALLOC, errno);  \
168     goto label__;                                 \
169   }
170 #endif
171 
172 #ifndef RCA
173 #define RCA(v__, label__) RCGA(v__, label__)
174 #endif
175 
176 #ifndef RCB
177 #define RCB(label__, v__) RCGA(v__, label__)
178 #endif
179 
180 #ifndef RCN
181 #define RCN(label__, v__)                       \
182   if ((v__) < 0) {                                \
183     rc = iwrc_set_errno(IW_ERROR_ERRNO, errno);   \
184     goto label__;                                 \
185   }
186 #endif
187 
188 #ifndef RCT
189 #define RCT(label__, val__)                                         \
190   ({ __typeof__(val__) v__ = (val__);                               \
191      if (v__) {                                                     \
192        rc = iwrc_set_errno(IW_ERROR_THREADING_ERRNO, v__);          \
193        goto label__;                                                \
194      }                                                              \
195    })
196 #endif
197 
198 #ifdef __GNUC__
199 #define RCRET(rc__) if (__builtin_expect((!!(rc__)), 0)) return (rc__)
200 #else
201 #define RCRET(rc__) if (rc__) return (rc__)
202 #endif
203 
204 #define RCR(expr__) \
205   ({ iwrc rc__ = (expr__); RCRET(rc__); 0; })
206 
207 #ifdef __GNUC__
208 #define RCBREAK(rc__) if (__builtin_expect((!!(rc__)), 0)) break
209 #else
210 #define RCBREAK(rc__) if (rc__) break
211 #endif
212 
213 #ifdef __GNUC__
214 #define RCONT(rc__) if (__builtin_expect((!!(rc__)), 0)) continue
215 #else
216 #define RCONT(rc__) if (rc__) continue
217 #endif
218 
219 #ifndef MIN
220 #define MIN(a_, b_) ((a_) < (b_) ? (a_) : (b_))
221 #endif
222 
223 #ifndef MAX
224 #define MAX(a_, b_) ((a_) > (b_) ? (a_) : (b_))
225 #endif
226 
227 /* Align x_ with v_. v_ must be simple power for 2 value. */
228 #define IW_ROUNDUP(x_, v_) (((x_) + (v_) - 1) & ~((v_) - 1))
229 
230 /* Round down align x_ with v_. v_ must be simple power for 2 value. */
231 #define IW_ROUNDOWN(x_, v_) ((x_) - ((x_) & ((v_) - 1)))
232 
233 #ifdef __GNUC__
234 #define IW_LIKELY(x_)   __builtin_expect(!!(x_), 1)
235 #define IW_UNLIKELY(x_) __builtin_expect(!!(x_), 0)
236 #else
237 #define IW_LIKELY(x_)
238 #define IW_UNLIKELY(x_)
239 #endif
240 
241 #if defined(NDEBUG)
242 #define IW_DODEBUG(IW_expr_)
243 #else
244 #define IW_DODEBUG(IW_expr_) \
245   { IW_expr_; }
246 #endif
247 
248 #if __GNUC__ >= 5
249 #define IW_SWAB16(num_) __builtin_bswap16(num_)
250 #else
251 #define IW_SWAB16(num_) \
252   ((((num_) & 0x00ffU) << 8) | (((num_) & 0xff00U) >> 8))
253 #endif
254 
255 #if __GNUC__ >= 4
256 #define IW_SWAB32(num_) __builtin_bswap32(num_)
257 #else
258 #define IW_SWAB32(num_)                                              \
259   ((((num_) & 0x000000ffUL) << 24) | (((num_) & 0x0000ff00UL) << 8)   \
260    | (((num_) & 0x00ff0000UL) >> 8) | (((num_) & 0xff000000UL) >> 24))
261 #endif
262 
263 #if __GNUC__ >= 4
264 #define IW_SWAB64(num_) __builtin_bswap64(num_)
265 #else
266 #define IW_SWAB64(num_)                     \
267   ((((num_) & 0x00000000000000ffULL) << 56)   \
268    | (((num_) & 0x000000000000ff00ULL) << 40)   \
269    | (((num_) & 0x0000000000ff0000ULL) << 24)   \
270    | (((num_) & 0x00000000ff000000ULL) << 8)    \
271    | (((num_) & 0x000000ff00000000ULL) >> 8)    \
272    | (((num_) & 0x0000ff0000000000ULL) >> 24)   \
273    | (((num_) & 0x00ff000000000000ULL) >> 40)   \
274    | (((num_) & 0xff00000000000000ULL) >> 56))
275 #endif
276 
277 #ifdef IW_BIGENDIAN
278 #define IW_HTOIS(num_)  IW_SWAB16(num_)
279 #define IW_HTOIL(num_)  IW_SWAB32(num_)
280 #define IW_HTOILL(num_) IW_SWAB64(num_)
281 #define IW_ITOHS(num_)  IW_SWAB16(num_)
282 #define IW_ITOHL(num_)  IW_SWAB32(num_)
283 #define IW_ITOHLL(num_) IW_SWAB64(num_)
284 #else
285 #define IW_HTOIS(num_)  (num_)
286 #define IW_HTOIL(num_)  (num_)
287 #define IW_HTOILL(num_) (num_)
288 #define IW_ITOHS(num_)  (num_)
289 #define IW_ITOHL(num_)  (num_)
290 #define IW_ITOHLL(num_) (num_)
291 #endif
292 
293 #define IW_WRITEBV(ptr_, v_, m_)  \
294   static_assert(sizeof(v_) == 1, "Mismatch v_ size"); \
295   (v_) = (m_);                          \
296   memcpy(ptr_, &(v_), 1); \
297   (ptr_) += 1
298 
299 #define IW_WRITESV(ptr_, v_, m_)  \
300   static_assert(sizeof(v_) == 2, "Mismatch v_ size"); \
301   (v_) = (m_);                          \
302   (v_) = IW_HTOIS(v_);                \
303   memcpy(ptr_, &(v_), 2); \
304   (ptr_) += 2
305 
306 #define IW_WRITELV(ptr_, v_, m_)  \
307   static_assert(sizeof(v_) == 4, "Mismatch v_ size"); \
308   (v_) = (m_);                          \
309   (v_) = IW_HTOIL(v_);                \
310   memcpy(ptr_, &(v_), 4); \
311   (ptr_) += 4
312 
313 #define IW_WRITELLV(ptr_, v_, m_) \
314   static_assert(sizeof(v_) == 8, "Mismatch v_ size"); \
315   (v_) = (m_);                          \
316   (v_) = IW_HTOILL(v_);               \
317   memcpy((ptr_), &(v_), 8); \
318   (ptr_) += 8
319 
320 #define IW_READBV(ptr_, t_, m_)   \
321   static_assert(sizeof(t_) == 1, "Mismatch t_ size"); \
322   (t_) = 0; \
323   memcpy(&(t_), ptr_, 1);  \
324   (m_) = (t_);   \
325   (ptr_) += 1
326 
327 #define IW_READSV(ptr_, t_, m_)   \
328   static_assert(sizeof(t_) == 2, "Mismatch t_ size"); \
329   (t_) = 0; \
330   memcpy(&(t_), ptr_, 2);  \
331   (m_) = IW_ITOHS(t_);  \
332   (ptr_) += 2
333 
334 #define IW_READLV(ptr_, t_, m_)   \
335   static_assert(sizeof(t_) == 4, "Mismatch t_ size"); \
336   (t_) = 0; \
337   memcpy(&(t_), ptr_, 4);  \
338   (m_) = IW_ITOHL(t_);  \
339   (ptr_) += 4
340 
341 #define IW_READLLV(ptr_, t_, m_)  \
342   static_assert(sizeof(t_) == 8, "Mismatch t_ size"); \
343   (t_) = 0; \
344   memcpy(&(t_), ptr_, 8);  \
345   (m_) = IW_ITOHLL(t_); \
346   (ptr_) += 8
347 
348 #ifndef SIZE_T_MAX
349 #define SIZE_T_MAX ((size_t) -1)
350 #endif
351 
352 #ifndef OFF_T_MIN
353 #define OFF_T_MIN ((off_t) (((uint64_t) 1) << (8 * sizeof(off_t) - 1)))
354 #endif
355 #ifndef OFF_T_MAX
356 #define OFF_T_MAX ((off_t) ~(((uint64_t) 1) << (8 * sizeof(off_t) - 1)))
357 #endif
358 
359 #include <stdint.h>
360 #include <stddef.h>
361 #include <stdbool.h>
362 #include <sys/types.h>
363 
364 #ifdef _WIN32
365 typedef _locale_t locale_t;
366 #endif
367 
368 #if defined(__GNUC__) || defined(__clang__)
369 #define IW_DEPRECATED __attribute__((deprecated))
370 #elif defined(_MSC_VER)
371 #define IW_DEPRECATED __declspec(deprecated)
372 #else
373 #define IW_DEPRECATED
374 #endif
375 
376 /**
377  * @brief The operation result status code.
378  *
379  * Zero status code `0` indicates <em>operation success</em>
380  *
381  * Status code can embed an `errno` code as operation result.
382  * In this case `uint32_t iwrc_strip_errno(iwrc *rc)` used
383  * to fetch embedded errno.
384  *
385  * @see iwlog.h
386  */
387 typedef uint64_t iwrc;
388 
389 /**
390  * @brief A rational number.
391  */
392 typedef struct IW_RNUM {
393   int32_t n;  /**< Numerator */
394   int32_t dn; /**< Denometator */
395 } IW_RNUM;
396 
397 #endif
398