This source file includes following definitions.
- __sir_safefree
- _sir_safeclose
- _sir_safefclose
- _sir_validfd
- __sir_validupdatedata
- __sir_validlevels
- __sir_validlevel
- __sir_validopts
- __sir_validtextattr
- __sir_validtextcolor
- __sir_validcolormode
- _sir_strncpy
- _sir_strncat
- _sir_fopen
- _sir_getchar
- _sir_explicit_memset
- _sir_strremove
- _sir_strsqueeze
- _sir_strredact
- _sir_strreplace
- _sir_strcreplace
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 #include "sir/helpers.h"
34 #include "sir/errors.h"
35
36 void __sir_safefree(void** pp) {
37 if (!pp || !*pp)
38 return;
39
40 free(*pp);
41 *pp = NULL;
42 }
43
44 void _sir_safeclose(int* restrict fd) {
45 if (!fd || 0 > *fd)
46 return;
47
48 if (-1 == close(*fd))
49 (void)_sir_handleerr(errno);
50
51 *fd = -1;
52 }
53
54 void _sir_safefclose(FILE* restrict* restrict f) {
55 if (!f || !*f)
56 return;
57
58 if (0 != fclose(*f))
59 (void)_sir_handleerr(errno);
60
61 *f = NULL;
62 }
63
64 bool _sir_validfd(int fd) {
65
66 if (2 >= fd)
67 return _sir_handleerr(EBADF);
68
69 #if !defined(__WIN__)
70 int ret = fcntl(fd, F_GETFL);
71 #else
72 # if !defined(SIR_MSVCRT_MINGW)
73 invalparamfn old = _set_thread_local_invalid_parameter_handler(_sir_invalidparameter);
74 # endif
75 struct _stat st;
76 int ret = _fstat(fd, &st);
77 # if !defined(SIR_MSVCRT_MINGW)
78 _set_thread_local_invalid_parameter_handler(old);
79 # endif
80 #endif
81 return (-1 != ret || EBADF != errno) ? true : _sir_handleerr(errno);
82 }
83
84
85 bool __sir_validupdatedata(const sir_update_config_data* data, const char* func,
86 const char* file, uint32_t line) {
87 if (!_sir_validptr(data))
88 return false;
89
90 bool valid = true;
91 if ((data->fields & SIRU_ALL) == 0U || (data->fields & ~SIRU_ALL) != 0U)
92 valid = false;
93
94 if (valid && _sir_bittest(data->fields, SIRU_LEVELS))
95 valid = _sir_validptrnofail(data->levels) &&
96 _sir_validlevels(*data->levels);
97
98 if (valid && _sir_bittest(data->fields, SIRU_OPTIONS))
99 valid = _sir_validptrnofail(data->opts) &&
100 _sir_validopts(*data->opts);
101
102 if (valid && _sir_bittest(data->fields, SIRU_SYSLOG_ID))
103 valid = _sir_validstrnofail(data->sl_identity);
104
105 if (valid && _sir_bittest(data->fields, SIRU_SYSLOG_CAT))
106 valid = _sir_validstrnofail(data->sl_category);
107
108 if (!valid) {
109 SIR_ASSERT(valid);
110 (void)__sir_seterror(_SIR_E_INVALID, func, file, line);
111 }
112
113 return valid;
114 }
115
116 bool __sir_validlevels(sir_levels levels, const char* func,
117 const char* file, uint32_t line) {
118 if ((SIRL_ALL == levels || SIRL_NONE == levels) ||
119 ((_sir_bittest(levels, SIRL_INFO) ||
120 _sir_bittest(levels, SIRL_DEBUG) ||
121 _sir_bittest(levels, SIRL_NOTICE) ||
122 _sir_bittest(levels, SIRL_WARN) ||
123 _sir_bittest(levels, SIRL_ERROR) ||
124 _sir_bittest(levels, SIRL_CRIT) ||
125 _sir_bittest(levels, SIRL_ALERT) ||
126 _sir_bittest(levels, SIRL_EMERG)) &&
127 ((levels & ~SIRL_ALL) == 0U)))
128 return true;
129
130 _sir_selflog("invalid levels: %04"PRIx16, levels);
131 return __sir_seterror(_SIR_E_LEVELS, func, file, line);
132 }
133
134 bool __sir_validlevel(sir_level level, const char* func, const char* file,
135 uint32_t line) {
136 if (SIRL_INFO == level || SIRL_DEBUG == level ||
137 SIRL_NOTICE == level || SIRL_WARN == level ||
138 SIRL_ERROR == level || SIRL_CRIT == level ||
139 SIRL_ALERT == level || SIRL_EMERG == level)
140 return true;
141
142 _sir_selflog("invalid level: %04"PRIx16, level);
143 return __sir_seterror(_SIR_E_LEVELS, func, file, line);
144 }
145
146 bool __sir_validopts(sir_options opts, const char* func, const char* file,
147 uint32_t line) {
148 if ((SIRO_ALL == opts || SIRO_MSGONLY == opts) ||
149 ((_sir_bittest(opts, SIRO_NOTIME) ||
150 _sir_bittest(opts, SIRO_NOHOST) ||
151 _sir_bittest(opts, SIRO_NOLEVEL) ||
152 _sir_bittest(opts, SIRO_NONAME) ||
153 _sir_bittest(opts, SIRO_NOMSEC) ||
154 _sir_bittest(opts, SIRO_NOPID) ||
155 _sir_bittest(opts, SIRO_NOTID) ||
156 _sir_bittest(opts, SIRO_NOHDR)) &&
157 ((opts & ~(SIRO_MSGONLY | SIRO_NOHDR)) == 0U)))
158 return true;
159
160 _sir_selflog("invalid options: %08"PRIx32, opts);
161 return __sir_seterror(_SIR_E_OPTIONS, func, file, line);
162 }
163
164 bool __sir_validtextattr(sir_textattr attr, const char* func, const char* file,
165 uint32_t line) {
166 switch(attr) {
167 case SIRTA_NORMAL:
168 case SIRTA_BOLD:
169 case SIRTA_DIM:
170 case SIRTA_EMPH:
171 case SIRTA_ULINE:
172 return true;
173 default: {
174 _sir_selflog("invalid text attr: %d", attr);
175 return __sir_seterror(_SIR_E_TEXTATTR, func, file, line);
176 }
177 }
178 }
179
180 bool __sir_validtextcolor(sir_colormode mode, sir_textcolor color, const char* func,
181 const char* file, uint32_t line) {
182 bool valid = false;
183 switch (mode) {
184 case SIRCM_16:
185
186
187 valid = SIRTC_DEFAULT == color ||
188 (color >= 30U && color <= 37U) || color == 39U ||
189 (color >= 40U && color <= 47U) || color == 49U ||
190 (color >= 90U && color <= 97U) || (color >= 100U && color <= 107U);
191 break;
192 case SIRCM_256:
193
194
195 valid = SIRTC_DEFAULT == color || color <= 255U;
196 break;
197 case SIRCM_RGB: {
198
199 valid = SIRTC_DEFAULT == color || ((color & 0xff000000U) == 0U);
200 break;
201 }
202 case SIRCM_INVALID:
203 default:
204 valid = false;
205 break;
206 }
207
208 if (!valid) {
209 _sir_selflog("invalid text color for mode %d %08"PRIx32" (%"PRIu32")",
210 mode, color, color);
211 (void)__sir_seterror(_SIR_E_TEXTCOLOR, func, file, line);
212 }
213
214 return valid;
215 }
216
217 bool __sir_validcolormode(sir_colormode mode, const char* func, const char* file,
218 uint32_t line) {
219 switch (mode) {
220 case SIRCM_16:
221 case SIRCM_256:
222 case SIRCM_RGB:
223 return true;
224 case SIRCM_INVALID:
225 default: {
226 _sir_selflog("invalid color mode: %d", mode);
227 return __sir_seterror(_SIR_E_COLORMODE, func, file, line);
228 }
229 }
230 }
231
232 int _sir_strncpy(char* restrict dest, size_t destsz, const char* restrict src,
233 size_t count) {
234 if (_sir_validptr(dest) && _sir_validstr(src)) {
235 #if defined(__HAVE_STDC_SECURE_OR_EXT1__)
236 int ret = strncpy_s(dest, destsz, src, count);
237 if (0 != ret) {
238 (void)_sir_handleerr(ret);
239 return -1;
240 }
241 return 0;
242 #else
243 SIR_UNUSED(count);
244 size_t cpy = strlcpy(dest, src, destsz);
245 SIR_ASSERT_UNUSED(cpy < destsz, cpy);
246 return 0;
247 #endif
248 }
249
250 return -1;
251 }
252
253 int _sir_strncat(char* restrict dest, size_t destsz, const char* restrict src,
254 size_t count) {
255 if (_sir_validptr(dest) && _sir_validstr(src)) {
256 #if defined(__HAVE_STDC_SECURE_OR_EXT1__)
257 int ret = strncat_s(dest, destsz, src, count);
258 if (0 != ret) {
259 (void)_sir_handleerr(ret);
260 return -1;
261 }
262 return 0;
263 #else
264 SIR_UNUSED(count);
265 size_t cat = strlcat(dest, src, destsz);
266 SIR_ASSERT_UNUSED(cat < destsz, cat);
267 return 0;
268 #endif
269 }
270
271 return -1;
272 }
273
274 int _sir_fopen(FILE* restrict* restrict streamptr, const char* restrict filename,
275 const char* restrict mode) {
276 if (_sir_validptrptr(streamptr) && _sir_validstr(filename) && _sir_validstr(mode)) {
277 #if defined(__HAVE_STDC_SECURE_OR_EXT1__)
278 int ret = fopen_s(streamptr, filename, mode);
279 if (0 != ret) {
280 (void)_sir_handleerr(ret);
281 return -1;
282 }
283 return 0;
284 #else
285 *streamptr = fopen(filename, mode);
286 if (!*streamptr) {
287 (void)_sir_handleerr(errno);
288 return -1;
289 }
290 return 0;
291 #endif
292 }
293
294 return -1;
295 }
296
297 bool _sir_getchar(char* input) {
298 #if defined(__WIN__)
299 # if defined(__EMBARCADEROC__) && (__clang_major__ < 15)
300 if (input)
301 *input = (char)getch();
302 # else
303 if (input)
304 *input = (char)_getch();
305 # endif
306 return true;
307 #else
308 struct termios cur = {0};
309 if (0 != tcgetattr(STDIN_FILENO, &cur))
310 return _sir_handleerr(errno);
311
312 struct termios new = cur;
313 new.c_lflag &= ~(ICANON | ECHO);
314
315 if (0 != tcsetattr(STDIN_FILENO, TCSANOW, &new))
316 return _sir_handleerr(errno);
317
318 int ch = getchar();
319
320 if (NULL != input)
321 *input = (char)ch;
322
323 return 0 == tcsetattr(STDIN_FILENO, TCSANOW, &cur) ? true
324 : _sir_handleerr(errno);
325 #endif
326 }
327
328 #if !defined(GCC_STATIC_ANALYZER)
329 typedef void*(*_sir_explicit_memset_t)(void*, int, size_t);
330 static const volatile _sir_explicit_memset_t _sir_explicit_memset_impl = memset;
331 #else
332 # define _sir_explicit_memset_impl(s, c, n) memset(s, c, n)
333 #endif
334 void* _sir_explicit_memset(void* ptr, int c, size_t len)
335 {
336 return _sir_explicit_memset_impl(ptr, c, len);
337 }
338
339 char* _sir_strremove(char *str, const char *sub) {
340 if (!str)
341 return NULL;
342
343 if (!sub)
344 return str;
345
346 char* r;
347 char* q;
348
349 if (*sub && (q = r = strstr(str, sub)) != NULL) {
350 size_t len = strnlen(sub, strlen(str));
351 const char* p;
352
353 while ((r = strstr(p = r + len, sub)) != NULL)
354 while (p < r)
355 *q++ = *p++;
356
357 while ((*q++ = *p++) != '\0');
358 }
359
360 return str;
361 }
362
363 char* _sir_strsqueeze(char *str) {
364 if (!str)
365 return NULL;
366
367 unsigned long j;
368
369 for (unsigned long i = j = 0; str[i]; ++i)
370 if ((i > 0 && !isspace((unsigned char)(str[i - 1])))
371 || !isspace((unsigned char)(str[i])))
372 str[j++] = str[i];
373
374 str[j] = '\0';
375
376 return str;
377 }
378
379 char* _sir_strredact(char *str, const char *sub, const char c) {
380 if (!str)
381 return NULL;
382
383 if (!sub)
384 return str;
385
386 char *p = strstr(str, sub);
387
388 if (!c || !p)
389 return str;
390
391 (void)_sir_explicit_memset(p, c, strnlen(sub, strlen(str)));
392
393 return _sir_strredact(str, sub, c);
394 }
395
396 char* _sir_strreplace(char *str, const char c, const char n) {
397 if (!str)
398 return NULL;
399
400 char *i = str;
401
402 if (!c || !n)
403 return str;
404
405 while ((i = strchr(i, c)) != NULL)
406 *i++ = n;
407
408 return str;
409 }
410
411 size_t _sir_strcreplace(char *str, const char c, const char n, int32_t max) {
412 char* i = str;
413 size_t cnt = 0;
414
415 if (!str || !c || !n || !max)
416 return cnt;
417
418 while (cnt < (size_t)max && (i = strchr(i, c)) != NULL) {
419 *i++ = n;
420 cnt++;
421 }
422
423 return cnt;
424 }