33#ifndef _SIR_HELPERS_H_INCLUDED
34# define _SIR_HELPERS_H_INCLUDED
36# include "sir/types.h"
37# include "sir/errors.h"
39# if defined(__cplusplus)
44# define _sir_countof(arr) (sizeof(arr) / sizeof(arr[0]))
47# define _SIR_L_START(format) \
51 if (!_sir_validptr(format)) \
53 va_start(args, format); \
57# define _SIR_L_END() \
61# define _SIR_LOCK_SECTION(type, name, mid, ret) \
62 type* name = _sir_locksection(mid); \
65 (void)_sir_seterror(_SIR_E_INTERNAL); \
71# define _SIR_UNLOCK_SECTION(mid) \
72 _sir_unlocksection(mid)
75# define SIR_UNUSED(param) (void)param
78# define SIR_ASSERT_UNUSED(assertion, var) SIR_ASSERT(assertion); SIR_UNUSED(var)
81# define _SIR_PRNSTR(str) (str ? str : "<null>")
84# define _SIR_DECLARE_BIN_SEARCH(low, high) \
85 size_t _low = low, _high = high; \
86 size_t _mid = (_low + _high) / 2
88# define _SIR_BEGIN_BIN_SEARCH() do {
90# define _SIR_ITERATE_BIN_SEARCH(comparison) \
93 if (0 > comparison && (_mid - 1) >= _low) { \
95 } else if ((_mid + 1) <= _high) { \
100 _mid = (_low + _high) / 2
102# define _SIR_END_BIN_SEARCH() \
107bool __sir_validptr(
const void* restrict p,
bool fail,
const char* func,
108 const char* file, uint32_t line) {
109 bool valid = NULL != p;
110 if (fail && !valid) {
111 (void)__sir_seterror(_SIR_E_NULLPTR, func, file, line);
112 SIR_ASSERT(!valid && fail);
119bool __sir_validptrptr(
const void* restrict* pp,
bool fail,
const char* func,
120 const char* file, uint32_t line) {
121 bool valid = NULL != pp;
122 if (fail && !valid) {
123 (void)__sir_seterror(_SIR_E_NULLPTR, func, file, line);
124 SIR_ASSERT(!valid && fail);
130# define _sir_validptrnofail(p) \
131 __sir_validptr(p, false, __func__, __file__, __LINE__)
134# define _sir_validptr(p) \
135 __sir_validptr((const void* restrict)p, true, __func__, __file__, __LINE__)
138# define _sir_validfnptr(fnp) \
139 __sir_validptrptr((const void* restrict*)&fnp, true, __func__, __file__, __LINE__)
142# define _sir_validptrptr(pp) \
143 __sir_validptrptr((const void* restrict*)pp, true, __func__, __file__, __LINE__)
147bool _sir_bittest(uint32_t flags, uint32_t test) {
148 return (flags & test) == test;
153void _sir_setbitshigh(uint32_t* flags, uint32_t set) {
160void _sir_setbitslow(uint32_t* flags, uint32_t set) {
167# define _sir_eqland(b, expr) ((b) = (expr) && (b))
170void __sir_safefree(
void** pp);
173# define _sir_safefree(pp) __sir_safefree((void**)pp)
176void _sir_safeclose(
int* restrict fd);
179void _sir_safefclose(FILE* restrict* restrict f);
182bool _sir_validfd(
int fd);
198 const char* file, uint32_t line);
201# define _sir_validupdatedata(data) \
202 __sir_validupdatedata(data, __func__, __file__, __LINE__)
205bool __sir_validlevels(
sir_levels levels,
const char* func,
const char* file,
209# define _sir_validlevels(levels) \
210 __sir_validlevels(levels, __func__, __file__, __LINE__)
213bool __sir_validlevel(
sir_level level,
const char* func,
const char* file,
217# define _sir_validlevel(level) \
218 __sir_validlevel(level, __func__, __file__, __LINE__)
235bool __sir_validopts(
sir_options opts,
const char* func,
const char* file,
239# define _sir_validopts(opts) \
240 __sir_validopts(opts, __func__, __file__, __LINE__)
243bool __sir_validtextattr(
sir_textattr attr,
const char* func,
const char* file,
247# define _sir_validtextattr(attr) \
248 __sir_validtextattr(attr, __func__, __file__, __LINE__)
252 const char* file, uint32_t line);
255# define _sir_validtextcolor(mode, color) \
256 __sir_validtextcolor(mode, color, __func__, __file__, __LINE__)
259bool __sir_validcolormode(
sir_colormode mode,
const char* func,
const char* file,
263# define _sir_validcolormode(mode) \
264 __sir_validcolormode(mode, __func__, __file__, __LINE__)
269 return SIRTC_DEFAULT == fg ? 39 : fg < 8 ? fg + 30 : fg + 82;
275 return SIRTC_DEFAULT == bg ? 49 : bg < 8 ? bg + 40 : bg + 92;
291# define _sir_getredfromcolor(color) (uint8_t)(((color) >> 16) & 0x000000ffU)
294# define _sir_setredincolor(color, red) (color |= (((red) << 16) & 0x00ff0000U))
297# define _sir_getgreenfromcolor(color) (uint8_t)(((color) >> 8) & 0x000000ffU)
300# define _sir_setgreenincolor(color, green) ((color) |= (((green) << 8) & 0x0000ff00U))
303# define _sir_getbluefromcolor(color) (uint8_t)((color) & 0x000000ffU)
306# define _sir_setblueincolor(color, blue) ((color) |= ((blue) & 0x000000ffU))
312 _sir_setredincolor(retval, r);
313 _sir_setgreenincolor(retval, g);
314 _sir_setblueincolor(retval, b);
320bool __sir_validstr(
const char* restrict str,
bool fail,
const char* func,
321 const char* file, uint32_t line) {
322 bool valid = str && *str !=
'\0';
323 if (fail && !valid) {
324 SIR_ASSERT(!valid && fail);
325 (void)__sir_seterror(_SIR_E_STRING, func, file, line);
331# define _sir_validstr(str) \
332 __sir_validstr(str, true, __func__, __file__, __LINE__)
335# define _sir_validstrnofail(str) \
336 __sir_validstr(str, false, __func__, __file__, __LINE__)
340void _sir_resetstr(
char* str) {
350bool _sir_strsame(
const char* lhs,
const char* rhs,
size_t count) {
351 return 0 == strncmp(lhs, rhs, count);
358int _sir_strncpy(
char* restrict dest,
size_t destsz,
359 const char* restrict src,
size_t count);
365int _sir_strncat(
char* restrict dest,
size_t destsz,
366 const char* restrict src,
size_t count);
372int _sir_fopen(FILE* restrict* restrict streamptr,
const char* restrict filename,
373 const char* restrict mode);
380struct tm* _sir_localtime(
const time_t* timer,
struct tm* buf) {
383# if defined(__HAVE_STDC_SECURE_OR_EXT1__) && !defined(__EMBARCADEROC__)
384# if !defined(__WIN__)
385 struct tm* ret = localtime_s(timer, buf);
387 (void)_sir_handleerr(errno);
391 errno_t ret = localtime_s(buf, timer);
393 (void)_sir_handleerr(ret);
399# if !defined(__WIN__) || \
400 (defined(__EMBARCADEROC__) && (__clang_major__ < 15))
401 struct tm* ret = localtime_r(timer, buf);
403 struct tm* ret = localtime(timer);
406 (void)_sir_handleerr(errno);
412# if defined(__GNUC__)
413__attribute__ ((format (strftime, 3, 0)))
416bool _sir_formattime(time_t now,
char* buffer,
const char* format) {
417 if (!buffer || !format)
419# if defined(__GNUC__) && !defined(__clang__) && \
420 !(defined(__OPEN64__) || defined(__OPENCC__) || defined(__PCC__))
421# pragma GCC diagnostic push
422# pragma GCC diagnostic ignored "-Wformat-nonliteral"
425 const struct tm* ptb = _sir_localtime(&now, &timebuf);
426 return NULL != ptb && 0 != strftime(buffer,
SIR_MAXTIME, format, ptb);
427# if defined(__GNUC__) && !defined(__clang__) && \
428 !(defined(__OPEN64__) || defined(__OPENCC__) || defined(__PCC__))
429# pragma GCC diagnostic pop
437bool _sir_getchar(
char* input);
442# define _sir_snprintf_trunc(dst, size, ...) \
444 volatile size_t _n = size; \
445 if (!snprintf(dst, _n, __VA_ARGS__)) { (void)_n; }; \
452uint32_t FNV32_1a(
const uint8_t* data,
size_t len) {
453 uint32_t hash = 2166136261U;
454 for (
size_t n = 0; n < len; n++) {
455 hash ^= (uint32_t)data[n];
456 hash = (uint32_t)(hash * 16777619ULL);
465# if defined(__clang__)
466SANITIZE_SUPPRESS(
"unsigned-integer-overflow")
469uint64_t FNV64_1a(
const char* str) {
470 uint64_t hash = 14695981039346656037ULL;
471 for (
const char* c = str; *c; c++) {
472 hash ^= (uint64_t)(
unsigned char)(*c);
473 hash *= 1099511628211ULL;
482void* _sir_explicit_memset(
void *ptr,
int c,
size_t len);
487char* _sir_strremove(
char *str,
const char *sub);
494char* _sir_strsqueeze(
char *str);
499char* _sir_strredact(
char *str,
const char *sub,
const char c);
504char* _sir_strreplace(
char *str,
const char c,
const char n);
510size_t _sir_strcreplace(
char *str,
const char c,
const char n, int32_t max);
512# if defined(__cplusplus)
#define SIR_MAXTIME
The size, in characters, of the buffer used to hold time format strings.
Definition config.h:347
uint16_t sir_level
The sir_level type.
Definition types.h:71
uint32_t sirfileid
Log file identifier type.
Definition types.h:49
sir_textattr
Attributes for stdio output.
Definition types.h:107
sir_colormode
Color mode selection.
Definition types.h:99
#define SIRO_DEFAULT
Default options for this type of destination.
Definition types.h:90
#define SIRL_DEFAULT
Default levels for this type of destination.
Definition types.h:68
uint16_t sir_levels
sir_level bitmask type.
Definition types.h:74
uint32_t sir_textcolor
stdio text color type.
Definition types.h:141
uint32_t sirpluginid
Plugin module identifier type.
Definition types.h:52
uint32_t sir_options
sir_option bitmask type.
Definition types.h:96
@ SIRTC_DEFAULT
Represents the default color.
Definition types.h:137
Encapsulates dynamic updating of current configuration.
Definition types.h:478