Commit | Line | Data |
---|---|---|
990570ed | 1 | /* |
ab5be9fa MJ |
2 | * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca> |
3 | * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | |
990570ed | 4 | * |
ab5be9fa | 5 | * SPDX-License-Identifier: GPL-2.0-only |
990570ed | 6 | * |
990570ed DG |
7 | */ |
8 | ||
9 | #ifndef _MACROS_H | |
10 | #define _MACROS_H | |
11 | ||
12 | #include <stdlib.h> | |
93375aa6 | 13 | #include <stddef.h> |
f6835b82 | 14 | #include <string.h> |
639082d2 | 15 | #include <common/compat/string.h> |
990570ed DG |
16 | |
17 | /* | |
18 | * Takes a pointer x and transform it so we can use it to access members | |
19 | * without a function call. Here an example: | |
20 | * | |
21 | * #define GET_SIZE(x) LTTNG_REF(x)->size | |
22 | * | |
23 | * struct { int size; } s; | |
24 | * | |
25 | * printf("size : %d\n", GET_SIZE(&s)); | |
26 | * | |
27 | * For this example we can't use something like this for compatibility purpose | |
28 | * since this will fail: | |
29 | * | |
30 | * #define GET_SIZE(x) x->size; | |
31 | * | |
32 | * This is mostly use for the compatibility layer of lttng-tools. See | |
33 | * poll/epoll for a good example. Since x can be on the stack or allocated | |
34 | * memory using malloc(), we must use generic accessors for compat in order to | |
35 | * *not* use a function to access members and not the variable name. | |
36 | */ | |
37 | #define LTTNG_REF(x) ((typeof(*x) *)(x)) | |
38 | ||
39 | /* | |
40 | * Memory allocation zeroed | |
41 | */ | |
4616a46c MD |
42 | static inline |
43 | void *zmalloc(size_t len) | |
44 | { | |
45 | return calloc(1, len); | |
46 | } | |
990570ed DG |
47 | |
48 | #ifndef ARRAY_SIZE | |
49 | #define ARRAY_SIZE(array) (sizeof(array) / (sizeof((array)[0]))) | |
50 | #endif | |
51 | ||
93375aa6 JG |
52 | #ifndef container_of |
53 | #define container_of(ptr, type, member) \ | |
54 | ({ \ | |
55 | const typeof(((type *)NULL)->member) * __ptr = (ptr); \ | |
56 | (type *)((char *)__ptr - offsetof(type, member)); \ | |
57 | }) | |
58 | #endif | |
59 | ||
54c90d10 DG |
60 | #ifndef LTTNG_PACKED |
61 | #define LTTNG_PACKED __attribute__((__packed__)) | |
62 | #endif | |
63 | ||
1405051a FD |
64 | #ifndef LTTNG_NO_SANITIZE_ADDRESS |
65 | #if defined(__clang__) || defined (__GNUC__) | |
66 | #define LTTNG_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) | |
67 | #else | |
68 | #define LTTNG_NO_SANITIZE_ADDRESS | |
69 | #endif | |
70 | #endif | |
71 | ||
0c634962 | 72 | #define is_signed(type) (((type) -1) < (type) 1) |
159b042f | 73 | |
f8f3885c MD |
74 | #define member_sizeof(type, field) sizeof(((type *) 0)->field) |
75 | ||
a0377dfe | 76 | #define ASSERT_LOCKED(lock) LTTNG_ASSERT(pthread_mutex_trylock(&lock)) |
5e5c14ce | 77 | |
d22ad5f8 SM |
78 | /* Attribute suitable to tag functions as having printf()-like arguments. */ |
79 | #define ATTR_FORMAT_PRINTF(_string_index, _first_to_check) \ | |
80 | __attribute__((format(printf, _string_index, _first_to_check))) | |
81 | ||
411b3154 SM |
82 | /* Attribute suitable to tag functions as having strftime()-like arguments. */ |
83 | #define ATTR_FORMAT_STRFTIME(_string_index) \ | |
84 | __attribute__((format(strftime, _string_index, 0))) | |
85 | ||
d22ad5f8 SM |
86 | /* Macros used to ignore specific compiler diagnostics. */ |
87 | ||
88 | #define DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push") | |
89 | #define DIAGNOSTIC_POP _Pragma("GCC diagnostic pop") | |
90 | ||
91 | #if defined(__clang__) | |
92 | /* Clang */ | |
93 | # define DIAGNOSTIC_IGNORE_SUGGEST_ATTRIBUTE_FORMAT | |
411b3154 SM |
94 | # define DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL \ |
95 | _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"") | |
d22ad5f8 SM |
96 | #else |
97 | /* GCC */ | |
98 | # define DIAGNOSTIC_IGNORE_SUGGEST_ATTRIBUTE_FORMAT \ | |
99 | _Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=format\"") | |
411b3154 SM |
100 | # define DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL \ |
101 | _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"") | |
d22ad5f8 SM |
102 | #endif |
103 | ||
d50d200a SM |
104 | /* Used to make specific C++ functions to C code. */ |
105 | #ifdef __cplusplus | |
106 | #define C_LINKAGE extern "C" | |
107 | #else | |
108 | #define C_LINKAGE | |
109 | #endif | |
110 | ||
f6835b82 MD |
111 | /* |
112 | * lttng_strncpy returns 0 on success, or nonzero on failure. | |
113 | * It checks that the @src string fits into @dst_len before performing | |
114 | * the copy. On failure, no copy has been performed. | |
115 | * | |
116 | * dst_len includes the string's trailing NULL. | |
117 | */ | |
118 | static inline | |
119 | int lttng_strncpy(char *dst, const char *src, size_t dst_len) | |
120 | { | |
c3ef76cd | 121 | if (lttng_strnlen(src, dst_len) >= dst_len) { |
f6835b82 MD |
122 | /* Fail since copying would result in truncation. */ |
123 | return -1; | |
124 | } | |
c3ef76cd | 125 | strcpy(dst, src); |
f6835b82 MD |
126 | return 0; |
127 | } | |
128 | ||
a0377dfe FD |
129 | #ifdef NDEBUG |
130 | /* | |
131 | * Force usage of the assertion condition to prevent unused variable warnings | |
132 | * when `assert()` are disabled by the `NDEBUG` definition. | |
133 | */ | |
134 | # define LTTNG_ASSERT(_cond) ((void) sizeof((void) (_cond), 0)) | |
135 | #else | |
136 | # include <assert.h> | |
137 | # define LTTNG_ASSERT(_cond) assert(_cond) | |
138 | #endif | |
139 | ||
990570ed | 140 | #endif /* _MACROS_H */ |