Neovim Home
src
nvim
macros.h
Go to the documentation of this file.
1
#ifndef NVIM_MACROS_H
2
#define NVIM_MACROS_H
3
4
#include "auto/config.h"
5
6
// EXTERN is only defined in main.c. That's where global variables are
7
// actually defined and initialized.
8
#ifndef EXTERN
9
# define EXTERN extern
10
# define INIT(...)
11
#else
12
# ifndef INIT
13
# define INIT(...) __VA_ARGS__
14
# define COMMA ,
15
# endif
16
#endif
17
18
#ifndef MIN
19
# define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
20
#endif
21
#ifndef MAX
22
# define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
23
#endif
24
32
#define S_LEN(s) (s), (sizeof(s) - 1)
33
35
#define LINEEMPTY(p) (*ml_get(p) == NUL)
36
37
// toupper() and tolower() that use the current locale.
38
// Careful: Only call TOUPPER_LOC() and TOLOWER_LOC() with a character in the
39
// range 0 - 255. toupper()/tolower() on some systems can't handle others.
40
// Note: It is often better to use mb_tolower() and mb_toupper(), because many
41
// toupper() and tolower() implementations only work for ASCII.
42
#define TOUPPER_LOC toupper
43
#define TOLOWER_LOC tolower
44
45
// toupper() and tolower() for ASCII only and ignore the current locale.
46
#define TOUPPER_ASC(c) (((c) < 'a' || (c) > 'z') ? (c) : (c) - ('a' - 'A'))
47
#define TOLOWER_ASC(c) (((c) < 'A' || (c) > 'Z') ? (c) : (c) + ('a' - 'A'))
48
49
// Like isalpha() but reject non-ASCII characters. Can't be used with a
50
// special key (negative value).
51
#define ASCII_ISLOWER(c) ((unsigned)(c) >= 'a' && (unsigned)(c) <= 'z')
52
#define ASCII_ISUPPER(c) ((unsigned)(c) >= 'A' && (unsigned)(c) <= 'Z')
53
#define ASCII_ISALPHA(c) (ASCII_ISUPPER(c) || ASCII_ISLOWER(c))
54
#define ASCII_ISALNUM(c) (ASCII_ISALPHA(c) || ascii_isdigit(c))
55
56
// Returns empty string if it is NULL.
57
#define EMPTY_IF_NULL(x) (char *)((x) ? (x) : (char_u *)"")
58
67
#define LANGMAP_ADJUST(c, condition) \
68
do { \
69
if (*p_langmap \
70
&& (condition) \
71
&& (p_lrm || (vgetc_busy ? typebuf_maplen() == 0 : KeyTyped)) \
72
&& !KeyStuffed \
73
&& (c) >= 0) \
74
{ \
75
if ((c) < 256) \
76
c = langmap_mapchar[c]; \
77
else \
78
c = langmap_adjust_mb(c); \
79
} \
80
} while (0)
81
82
#define WRITEBIN "wb" // no CR-LF translation
83
#define READBIN "rb"
84
#define APPENDBIN "ab"
85
86
// mch_open_rw(): invoke os_open() with third argument for user R/W.
87
#if defined(UNIX) // open in rw------- mode
88
# define MCH_OPEN_RW(n, f) os_open((n), (f), (mode_t)0600)
89
#elif defined(WIN32)
90
# define MCH_OPEN_RW(n, f) os_open((n), (f), S_IREAD | S_IWRITE)
91
#else
92
# define MCH_OPEN_RW(n, f) os_open((n), (f), 0)
93
#endif
94
95
#define REPLACE_NORMAL(s) (((s) & REPLACE_FLAG) && !((s) & VREPLACE_FLAG))
96
97
// MB_PTR_ADV(): advance a pointer to the next character, taking care of
98
// multi-byte characters if needed. Skip over composing chars.
99
#define MB_PTR_ADV(p) (p += utfc_ptr2len((char *)p))
100
101
// Advance multi-byte pointer, do not skip over composing chars.
102
#define MB_CPTR_ADV(p) (p += utf_ptr2len((char *)p))
103
104
// MB_PTR_BACK(): backup a pointer to the previous character, taking care of
105
// multi-byte characters if needed. Only use with "p" > "s" !
106
#define MB_PTR_BACK(s, p) \
107
(p -= utf_head_off((char_u *)(s), (char_u *)(p) - 1) + 1)
108
109
// MB_CHAR2BYTES(): convert character to bytes and advance pointer to bytes
110
#define MB_CHAR2BYTES(c, b) ((b) += utf_char2bytes((c), ((char *)b)))
111
112
#define RESET_BINDING(wp) \
113
do { \
114
(wp)->w_p_scb = false; \
115
(wp)->w_p_crb = false; \
116
} while (0)
117
126
#define ARRAY_SIZE(arr) \
127
((sizeof(arr)/sizeof((arr)[0])) \
128
/ ((size_t)(!(sizeof(arr) % sizeof((arr)[0])))))
129
134
#define ARRAY_LAST_ENTRY(arr) (arr)[ARRAY_SIZE(arr) - 1]
135
136
// Duplicated in os/win_defs.h to avoid include-order sensitivity.
137
#define RGB_(r, g, b) (((r) << 16) | ((g) << 8) | (b))
138
139
#define STR_(x) #x
140
#define STR(x) STR_(x)
141
142
#ifndef __has_include
143
# define NVIM_HAS_INCLUDE(x) 0
144
#else
145
# define NVIM_HAS_INCLUDE __has_include
146
#endif
147
148
#ifndef __has_attribute
149
# define NVIM_HAS_ATTRIBUTE(x) 0
150
#elif defined(__clang__) && __clang__ == 1 \
151
&& (__clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ <= 5))
152
// Starting in Clang 3.6, __has_attribute was fixed to only report true for
153
// GNU-style attributes. Prior to that, it reported true if _any_ backend
154
// supported the attribute.
155
# define NVIM_HAS_ATTRIBUTE(x) 0
156
#else
157
# define NVIM_HAS_ATTRIBUTE __has_attribute
158
#endif
159
160
#if NVIM_HAS_ATTRIBUTE(fallthrough) \
161
&& (!defined(__apple_build_version__) || __apple_build_version__ >= 7000000)
162
# define FALLTHROUGH {} __attribute__((fallthrough))
163
#else
164
# define FALLTHROUGH
165
#endif
166
167
// -V:STRUCT_CAST:641
168
177
#define STRUCT_CAST(Type, obj) ((Type *)(obj))
178
179
// Type of uv_buf_t.len is platform-dependent.
180
// Related: https://github.com/libuv/libuv/pull/1236
181
#if defined(WIN32)
182
# define UV_BUF_LEN(x) (ULONG)(x)
183
#else
184
# define UV_BUF_LEN(x) (x)
185
#endif
186
187
// Type of read()/write() `count` param is platform-dependent.
188
#if defined(WIN32)
189
# define IO_COUNT(x) (unsigned)(x)
190
#else
191
# define IO_COUNT(x) (x)
192
#endif
193
197
#if defined(__clang__) && __clang__ == 1
198
# define PRAGMA_DIAG_PUSH_IGNORE_MISSING_PROTOTYPES \
199
_Pragma("clang diagnostic push") \
200
_Pragma("clang diagnostic ignored \"-Wmissing-prototypes\"")
201
# ifdef HAVE_WIMPLICIT_FALLTHROUGH_FLAG
202
# define PRAGMA_DIAG_PUSH_IGNORE_IMPLICIT_FALLTHROUGH \
203
_Pragma("clang diagnostic push") \
204
_Pragma("clang diagnostic ignored \"-Wimplicit-fallthrough\"")
205
# else
206
# define PRAGMA_DIAG_PUSH_IGNORE_IMPLICIT_FALLTHROUGH \
207
_Pragma("clang diagnostic push")
208
# endif
209
# define PRAGMA_DIAG_POP \
210
_Pragma("clang diagnostic pop")
211
#elif defined(__GNUC__)
212
# define PRAGMA_DIAG_PUSH_IGNORE_MISSING_PROTOTYPES \
213
_Pragma("GCC diagnostic push") \
214
_Pragma("GCC diagnostic ignored \"-Wmissing-prototypes\"")
215
# ifdef HAVE_WIMPLICIT_FALLTHROUGH_FLAG
216
# define PRAGMA_DIAG_PUSH_IGNORE_IMPLICIT_FALLTHROUGH \
217
_Pragma("GCC diagnostic push") \
218
_Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
219
# else
220
# define PRAGMA_DIAG_PUSH_IGNORE_IMPLICIT_FALLTHROUGH \
221
_Pragma("GCC diagnostic push")
222
# endif
223
# define PRAGMA_DIAG_POP \
224
_Pragma("GCC diagnostic pop")
225
#else
226
# define PRAGMA_DIAG_PUSH_IGNORE_MISSING_PROTOTYPES
227
# define PRAGMA_DIAG_PUSH_IGNORE_IMPLICIT_FALLTHROUGH
228
# define PRAGMA_DIAG_POP
229
#endif
230
231
#define EMPTY_POS(a) ((a).lnum == 0 && (a).col == 0 && (a).coladd == 0)
232
233
#endif // NVIM_MACROS_H