Cleanup: re-use test for ELEM & STR_ELEM
[blender.git] / source / blender / blenlib / BLI_string.h
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19
20 #ifndef __BLI_STRING_H__
21 #define __BLI_STRING_H__
22
23 /** \file
24  * \ingroup bli
25  */
26
27 #include <stdarg.h>
28 #include <inttypes.h>
29
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33
34 #include "BLI_compiler_attrs.h"
35 #include "BLI_utildefines_variadic.h"
36
37 char *BLI_strdupn(const char *str, const size_t len) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
38     ATTR_NONNULL();
39
40 char *BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC;
41
42 char *BLI_strdupcat(const char *__restrict str1,
43                     const char *__restrict str2) ATTR_WARN_UNUSED_RESULT
44     ATTR_NONNULL() ATTR_MALLOC;
45
46 char *BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy)
47     ATTR_NONNULL();
48
49 char *BLI_strncpy_ensure_pad(char *__restrict dst,
50                              const char *__restrict src,
51                              const char pad,
52                              size_t maxncpy) ATTR_NONNULL();
53
54 size_t BLI_strncpy_rlen(char *__restrict dst,
55                         const char *__restrict src,
56                         const size_t maxncpy) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
57
58 size_t BLI_strcpy_rlen(char *__restrict dst, const char *__restrict src) ATTR_WARN_UNUSED_RESULT
59     ATTR_NONNULL();
60
61 char *BLI_str_quoted_substrN(const char *__restrict str,
62                              const char *__restrict prefix) ATTR_WARN_UNUSED_RESULT
63     ATTR_NONNULL() ATTR_MALLOC;
64
65 char *BLI_str_replaceN(const char *__restrict str,
66                        const char *__restrict substr_old,
67                        const char *__restrict substr_new) ATTR_WARN_UNUSED_RESULT
68     ATTR_NONNULL() ATTR_MALLOC;
69
70 void BLI_str_replace_char(char *string, char src, char dst) ATTR_NONNULL();
71
72 size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format, ...)
73     ATTR_NONNULL(1, 3) ATTR_PRINTF_FORMAT(3, 4);
74 size_t BLI_snprintf_rlen(char *__restrict dst, size_t maxncpy, const char *__restrict format, ...)
75     ATTR_NONNULL(1, 3) ATTR_PRINTF_FORMAT(3, 4);
76
77 size_t BLI_vsnprintf(char *__restrict dst,
78                      size_t maxncpy,
79                      const char *__restrict format,
80                      va_list arg) ATTR_PRINTF_FORMAT(3, 0);
81 size_t BLI_vsnprintf_rlen(char *__restrict buffer,
82                           size_t maxncpy,
83                           const char *__restrict format,
84                           va_list arg) ATTR_PRINTF_FORMAT(3, 0);
85
86 char *BLI_sprintfN(const char *__restrict format, ...) ATTR_WARN_UNUSED_RESULT
87     ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1, 2);
88
89 size_t BLI_strescape(char *__restrict dst, const char *__restrict src, const size_t maxncpy)
90     ATTR_NONNULL();
91
92 size_t BLI_str_format_int_grouped(char dst[16], int num) ATTR_NONNULL();
93 size_t BLI_str_format_uint64_grouped(char dst[16], uint64_t num) ATTR_NONNULL();
94 void BLI_str_format_byte_unit(char dst[15], long long int size, const bool base_10) ATTR_NONNULL();
95
96 int BLI_strcaseeq(const char *a, const char *b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
97 char *BLI_strcasestr(const char *s, const char *find) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
98 char *BLI_strncasestr(const char *s, const char *find, size_t len) ATTR_WARN_UNUSED_RESULT
99     ATTR_NONNULL();
100 int BLI_strcasecmp(const char *s1, const char *s2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
101 int BLI_strncasecmp(const char *s1, const char *s2, size_t len) ATTR_WARN_UNUSED_RESULT
102     ATTR_NONNULL();
103 int BLI_natstrcmp(const char *s1, const char *s2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
104 int BLI_strcmp_ignore_pad(const char *str1,
105                           const char *str2,
106                           const char pad) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
107
108 size_t BLI_strnlen(const char *str, const size_t maxlen) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
109
110 void BLI_str_tolower_ascii(char *str, const size_t len) ATTR_NONNULL();
111 void BLI_str_toupper_ascii(char *str, const size_t len) ATTR_NONNULL();
112 void BLI_str_rstrip(char *str) ATTR_NONNULL();
113 int BLI_str_rstrip_float_zero(char *str, const char pad) ATTR_NONNULL();
114
115 int BLI_str_index_in_array_n(const char *__restrict str,
116                              const char **__restrict str_array,
117                              const int str_array_len) ATTR_NONNULL();
118 int BLI_str_index_in_array(const char *__restrict str, const char **__restrict str_array)
119     ATTR_NONNULL();
120
121 bool BLI_str_endswith(const char *__restrict str, const char *__restrict end) ATTR_NONNULL();
122 bool BLI_strn_endswith(const char *__restrict str, const char *__restrict end, size_t length)
123     ATTR_NONNULL();
124
125 size_t BLI_str_partition(const char *str, const char delim[], const char **sep, const char **suf)
126     ATTR_NONNULL();
127 size_t BLI_str_rpartition(const char *str, const char delim[], const char **sep, const char **suf)
128     ATTR_NONNULL();
129 size_t BLI_str_partition_ex(const char *str,
130                             const char *end,
131                             const char delim[],
132                             const char **sep,
133                             const char **suf,
134                             const bool from_right) ATTR_NONNULL(1, 3, 4, 5);
135
136 int BLI_string_find_split_words(const char *str,
137                                 const size_t len,
138                                 const char delim,
139                                 int r_words[][2],
140                                 int words_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
141
142 /** \name String Copy/Format Macros
143  * Avoid repeating destination with `sizeof(..)`.
144  * \note `ARRAY_SIZE` allows pointers on some platforms.
145  * \{ */
146 #define STRNCPY(dst, src) BLI_strncpy(dst, src, ARRAY_SIZE(dst))
147 #define STRNCPY_RLEN(dst, src) BLI_strncpy_rlen(dst, src, ARRAY_SIZE(dst))
148 #define SNPRINTF(dst, format, ...) BLI_snprintf(dst, ARRAY_SIZE(dst), format, __VA_ARGS__)
149 #define SNPRINTF_RLEN(dst, format, ...) \
150   BLI_snprintf_rlen(dst, ARRAY_SIZE(dst), format, __VA_ARGS__)
151 #define STR_CONCAT(dst, len, suffix) \
152   len += BLI_strncpy_rlen(dst + len, suffix, ARRAY_SIZE(dst) - len)
153 #define STR_CONCATF(dst, len, format, ...) \
154   len += BLI_snprintf_rlen(dst + len, ARRAY_SIZE(dst) - len, format, __VA_ARGS__)
155 /** \} */
156
157 /* -------------------------------------------------------------------- */
158 /** \name Equal to Any Element (STR_ELEM) Macro
159  *
160  * Follows #ELEM macro convention.
161  * \{ */
162
163 /* Manual line breaks for readability. */
164 /* clang-format off */
165 /* STR_ELEM#(v, ...): is the first arg equal any others? */
166 /* Internal helpers. */
167 #define _VA_STR_ELEM2(v, a) (strcmp(v, a) == 0)
168 #define _VA_STR_ELEM3(v, a, b) \
169   (_VA_STR_ELEM2(v, a) || (_VA_STR_ELEM2(v, b)))
170 #define _VA_STR_ELEM4(v, a, b, c) \
171   (_VA_STR_ELEM3(v, a, b) || (_VA_STR_ELEM2(v, c)))
172 #define _VA_STR_ELEM5(v, a, b, c, d) \
173   (_VA_STR_ELEM4(v, a, b, c) || (_VA_STR_ELEM2(v, d)))
174 #define _VA_STR_ELEM6(v, a, b, c, d, e) \
175   (_VA_STR_ELEM5(v, a, b, c, d) || (_VA_STR_ELEM2(v, e)))
176 #define _VA_STR_ELEM7(v, a, b, c, d, e, f) \
177   (_VA_STR_ELEM6(v, a, b, c, d, e) || (_VA_STR_ELEM2(v, f)))
178 #define _VA_STR_ELEM8(v, a, b, c, d, e, f, g) \
179   (_VA_STR_ELEM7(v, a, b, c, d, e, f) || (_VA_STR_ELEM2(v, g)))
180 #define _VA_STR_ELEM9(v, a, b, c, d, e, f, g, h) \
181   (_VA_STR_ELEM8(v, a, b, c, d, e, f, g) || (_VA_STR_ELEM2(v, h)))
182 #define _VA_STR_ELEM10(v, a, b, c, d, e, f, g, h, i) \
183   (_VA_STR_ELEM9(v, a, b, c, d, e, f, g, h) || (_VA_STR_ELEM2(v, i)))
184 #define _VA_STR_ELEM11(v, a, b, c, d, e, f, g, h, i, j) \
185   (_VA_STR_ELEM10(v, a, b, c, d, e, f, g, h, i) || (_VA_STR_ELEM2(v, j)))
186 #define _VA_STR_ELEM12(v, a, b, c, d, e, f, g, h, i, j, k) \
187   (_VA_STR_ELEM11(v, a, b, c, d, e, f, g, h, i, j) || (_VA_STR_ELEM2(v, k)))
188 #define _VA_STR_ELEM13(v, a, b, c, d, e, f, g, h, i, j, k, l) \
189   (_VA_STR_ELEM12(v, a, b, c, d, e, f, g, h, i, j, k) || (_VA_STR_ELEM2(v, l)))
190 #define _VA_STR_ELEM14(v, a, b, c, d, e, f, g, h, i, j, k, l, m) \
191   (_VA_STR_ELEM13(v, a, b, c, d, e, f, g, h, i, j, k, l) || (_VA_STR_ELEM2(v, m)))
192 #define _VA_STR_ELEM15(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n) \
193   (_VA_STR_ELEM14(v, a, b, c, d, e, f, g, h, i, j, k, l, m) || (_VA_STR_ELEM2(v, n)))
194 #define _VA_STR_ELEM16(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) \
195   (_VA_STR_ELEM15(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n) || (_VA_STR_ELEM2(v, o)))
196 #define _VA_STR_ELEM17(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) \
197   (_VA_STR_ELEM16(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) || (_VA_STR_ELEM2(v, p)))
198 /* clang-format on */
199
200 /* reusable STR_ELEM macro */
201 #define STR_ELEM(...) VA_NARGS_CALL_OVERLOAD(_VA_STR_ELEM, __VA_ARGS__)
202
203 /** \} */
204
205 #ifdef __cplusplus
206 }
207 #endif
208
209 #endif /* __BLI_STRING_H__ */