• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

aremmell / libsir / 1153

25 Jul 2023 04:30AM UTC coverage: 80.118% (-14.7%) from 94.801%
1153

push

travis-ci

aremmell
fix ternary

1 of 1 new or added line in 1 file covered. (100.0%)

2571 of 3209 relevant lines covered (80.12%)

24530.87 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.83
/include/sir/helpers.h
1
/*
2
 * helpers.h
3
 *
4
 * Author:    Ryan M. Lederman <lederman@gmail.com>
5
 * Copyright: Copyright (c) 2018-2023
6
 * Version:   2.2.1
7
 * License:   The MIT License (MIT)
8
 *
9
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
10
 * this software and associated documentation files (the "Software"), to deal in
11
 * the Software without restriction, including without limitation the rights to
12
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
13
 * the Software, and to permit persons to whom the Software is furnished to do so,
14
 * subject to the following conditions:
15
 *
16
 * The above copyright notice and this permission notice shall be included in all
17
 * copies or substantial portions of the Software.
18
 *
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
21
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
22
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
23
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
 */
26
#ifndef _SIR_HELPERS_H_INCLUDED
27
# define _SIR_HELPERS_H_INCLUDED
28

29
# include "sir/types.h"
30

31
/** Computes the size of an array. */
32
# define _sir_countof(arr) (sizeof(arr) / sizeof(arr[0]))
33

34
/** Creates an error code that (hopefully) doesn't conflict with any of those
35
 * defined by the platform. */
36
# define _sir_mkerror(code) (((uint32_t)((code) & 0x7fff) << 16) | 0x80000000)
37

38
/** Validates an internal error. */
39
static inline
40
bool _sir_validerror(uint32_t err) {
123,881✔
41
    uint32_t masked = err & 0x8fffffff;
123,881✔
42
    return masked >= 0x80000000 && masked <= 0x8fff0000;
123,881✔
43
}
44

45
/** Extracts just the code from an internal error. */
46
static inline
47
uint16_t _sir_geterrcode(uint32_t err) {
42,582✔
48
    return (err >> 16) & 0x7fff;
42,582✔
49
}
50

51
/** Evil macro used for _sir_lv wrappers. */
52
# define _SIR_L_START(format) \
53
    bool r = false; \
54
    va_list args = {0}; \
55
    va_start(args, format); \
56
    \
57
    if (_sir_validptr(format)) { \
58

59
/** Evil macro used for _sir_lv wrappers. */
60
# define _SIR_L_END(args) \
61
    } \
62
    va_end(args);
63

64
/** Evil macros used to enter/leave locked sections. */
65
# define _SIR_LOCK_SECTION(type, name, mid, ret) \
66
    type* name = _sir_locksection(mid); \
67
    if (!name) { \
68
        (void)_sir_seterror(_SIR_E_INTERNAL); \
69
        return ret; \
70
    }
71

72
/** Evil macros used to enter/leave locked sections. */
73
# define _SIR_UNLOCK_SECTION(mid) \
74
    _sir_unlocksection(mid);
75

76
/** Squelches warnings about unreferenced parameters. */
77
# define SIR_UNUSED(param) (void)param
78

79
/** Combines SIR_ASSERT and SIR_UNUSED, which are frequently used together. */
80
# define SIR_ASSERT_UNUSED(assertion, var) SIR_ASSERT(assertion); SIR_UNUSED(var)
81

82
/** Returns a printable string even if NULL. */
83
# define _SIR_PRNSTR(str) (str ? str : "<null>")
84

85
/** Even more evil macros used for binary searching arrays. */
86
# define _SIR_DECLARE_BIN_SEARCH(low, high) \
87
    size_t _low  = low; \
88
    size_t _high = high; \
89
    size_t _mid  = (_low + _high) / 2;
90

91
# define _SIR_BEGIN_BIN_SEARCH() do {
92
# define _SIR_ITERATE_BIN_SEARCH(comparison) \
93
    if (_low == _high) \
94
        break; \
95
    \
96
    if (0 > comparison && (_mid - 1) >= _low) { \
97
        _high = _mid - 1; \
98
    } else if ((_mid + 1) <= _high) { \
99
        _low = _mid + 1; \
100
    } else { \
101
        break; \
102
    } \
103
    \
104
    _mid = (_low + _high) / 2;
105
# define _SIR_END_BIN_SEARCH() \
106
    } while (true);
107

108
/* Validates a pointer and optionally fails if it's invalid. */
109
bool __sir_validptr(const void* restrict p, bool fail);
110

111
/** Validates a pointer-to-pointer and optionally fails if it's invalid. */
112
bool __sir_validptrptr(const void* restrict* pp, bool fail);
113

114
/** Validates a pointer but ignores whether it's invalid. */
115
# define _sir_validptrnofail(p) __sir_validptr(p, false)
116

117
/** Validates a pointer and fails if it's invalid. */
118
# define _sir_validptr(p) __sir_validptr((const void* restrict)p, true)
119

120
/** Validates a pointer-to-function and fails if it's invalid. */
121
# define _sir_validfnptr(fnp) __sir_validptrptr((const void* restrict*)&fnp, true)
122

123
/** Validates a pointer-to-pointer and fails if it's invalid. */
124
# define _sir_validptrptr(pp) __sir_validptrptr((const void* restrict*)pp, true)
125

126
/** Checks a bitmask for a specific set of bits. */
127
static inline
128
bool _sir_bittest(uint32_t flags, uint32_t test) {
534,186✔
129
    return (flags & test) == test;
534,186✔
130
}
131

132
/** Sets a specific set of bits high in a bitmask. */
133
static inline
134
bool _sir_setbitshigh(uint32_t* flags, uint32_t set) {
216✔
135
    if (!flags)
216✔
136
        return false;
×
137

138
    *flags |= set;
216✔
139
    return true;
216✔
140
}
141

142
/** Sets a specific set of bits low in a bitmask. */
143
static inline
144
bool _sir_setbitslow(uint32_t* flags, uint32_t set) {
138✔
145
    if (!flags)
138✔
146
        return false;
×
147

148
    *flags &= ~set;
138✔
149
    return true;
138✔
150
}
151

152
/** Calls free and sets the pointer to NULL. */
153
void __sir_safefree(void** pp);
154

155
/** Wraps __sir_safefree with a cast to void**. */
156
# define _sir_safefree(pp) __sir_safefree((void**)pp)
157

158
/** Calls close and sets the descriptor to -1. */
159
void _sir_safeclose(int* restrict fd);
160

161
/** Calls fclose and sets the stream pointer to NULL. */
162
void _sir_safefclose(FILE* restrict* restrict f);
163

164
/** Validates a log file descriptor. */
165
bool _sir_validfd(int fd);
166

167
/** Validates a file identifier */
168
static inline
169
bool _sir_validfileid(sirfileid id) {
173,740✔
170
    return 0 != id;
173,740✔
171
}
172

173
/** Validates a plugin identifier */
174
static inline
175
bool _sir_validpluginid(sirpluginid id) {
176
    return 0 != id;
177
}
178

179
/** Validates a sir_update_config_data structure. */
180
bool _sir_validupdatedata(sir_update_config_data* data);
181

182
/** Validates a set of ::sir_level flags. */
183
bool _sir_validlevels(sir_levels levels);
184

185
/** Validates a single ::sir_level. */
186
bool _sir_validlevel(sir_level level);
187

188
/** Applies default ::sir_level flags if applicable. */
189
static inline
190
void _sir_defaultlevels(sir_levels* levels, sir_levels def) {
6,852✔
191
    if (levels && SIRL_DEFAULT == *levels)
6,852✔
192
        *levels = def;
102✔
193
}
6,852✔
194

195
/** Applies default ::sir_options flags if applicable. */
196
static inline
197
void _sir_defaultopts(sir_options* opts, sir_options def) {
24,689✔
198
    if (opts && SIRO_DEFAULT == *opts)
24,689✔
199
        *opts = def;
302✔
200
}
24,689✔
201

202
/** Validates a set of ::sir_option flags. */
203
bool _sir_validopts(sir_options opts);
204

205
/** Validates a ::sir_textattr. */
206
bool _sir_validtextattr(sir_textattr attr);
207

208
/** Validates a ::sir_textcolor based on color mode. */
209
bool _sir_validtextcolor(sir_colormode mode, sir_textcolor color);
210

211
/** Validates a ::sir_colormode. */
212
bool _sir_validcolormode(sir_colormode mode);
213

214
/** Converts a SIRTC_* value to a 16-color mode ANSI foreground color. */
215
static inline
216
sir_textcolor _sir_mkansifgcolor(sir_textcolor fg) {
52,213✔
217
    return SIRTC_DEFAULT == fg ? 39 : fg < 8 ? fg + 30 : fg + 82;
52,213✔
218
}
219

220
/** Converts a SIRTC_* value to a 16-color mode ANSI background color. */
221
static inline
222
sir_textcolor _sir_mkansibgcolor(sir_textcolor bg) {
52,213✔
223
    return SIRTC_DEFAULT == bg ? 49 : bg < 8 ? bg + 40 : bg + 92;
52,213✔
224
}
225

226
/** Returns the appropriate ANSI command for the specified foreground color. */
227
static inline
228
sir_textcolor _sir_getansifgcmd(sir_textcolor fg) {
1,587✔
229
    return SIRTC_DEFAULT == fg ? 39 : 38;
1,587✔
230
}
231

232
/** Returns the appropriate ANSI command for the specified background color. */
233
static inline
234
sir_textcolor _sir_getansibgcmd(sir_textcolor bg) {
1,587✔
235
    return SIRTC_DEFAULT == bg ? 49 : 48;
1,587✔
236
}
237

238
/** Extracts the red component out of an RGB color mode ::sir_textcolor. */
239
# define _sir_getredfromcolor(color) (uint8_t)(((color) >> 16) & 0x000000ff)
240

241
/** Sets the red component in an RGB color mode ::sir_textcolor. */
242
# define _sir_setredincolor(color, red) (color |= (((red) << 16) & 0x00ff0000))
243

244
/** Extracts the green component out of an RGB color mode ::sir_textcolor. */
245
# define _sir_getgreenfromcolor(color) (uint8_t)(((color) >> 8) & 0x000000ff)
246

247
/** Sets the green component in an RGB color mode ::sir_textcolor. */
248
# define _sir_setgreenincolor(color, green) ((color) |= (((green) << 8) & 0x0000ff00))
249

250
/** Extracts the blue component out of an RGB color mode ::sir_textcolor. */
251
# define _sir_getbluefromcolor(color) (uint8_t)((color) & 0x000000ff)
252

253
/** Sets the blue component in an RGB color mode ::sir_textcolor. */
254
# define _sir_setblueincolor(color, blue) ((color) |= ((blue) & 0x000000ff))
255

256
/** Sets the red, blue, and green components in an RGB color mode ::sir_textcolor. */
257
static inline
258
sir_textcolor _sir_makergb(sir_textcolor r, sir_textcolor g, sir_textcolor b) {
1,542✔
259
    sir_textcolor retval = 0;
×
260
    _sir_setredincolor(retval, r);
1,542✔
261
    _sir_setgreenincolor(retval, g);
1,542✔
262
    _sir_setblueincolor(retval, b);
1,542✔
263
    return retval;
1,542✔
264
}
265

266
/** Validates a string pointer and optionally fails if it's invalid. */
267
bool __sir_validstr(const char* restrict str, bool fail);
268

269
/** Validates a string pointer and fails if it's invalid. */
270
# define _sir_validstr(str) __sir_validstr(str, true)
271

272
/** Validates a string pointer but ignores whether it's invalid. */
273
# define _sir_validstrnofail(str) __sir_validstr(str, false)
274

275
/** Places a null terminator at the first index in a string buffer. */
276
static inline
277
void _sir_resetstr(char* str) {
113,158✔
278
    str[0] = '\0';
113,158✔
279
}
113,158✔
280

281
/**
282
 * Wrapper for strncmp. Just easier to read and use if you only wish to
283
 * test for equality. Not case-sensitive.
284
 */
285
static inline
286
bool _sir_strsame(const char* lhs, const char* rhs, size_t count) {
63✔
287
    return 0 == strncmp(lhs, rhs, count);
63✔
288
}
289

290
/**
291
 * Wrapper for str[n,l]cpy/strncpy_s. Determines which one to use
292
 * based on preprocessor macros.
293
 */
294
int _sir_strncpy(char* restrict dest, size_t destsz,
295
    const char* restrict src, size_t count);
296

297
/**
298
 * Wrapper for str[n,l]cat/strncat_s. Determines which one to use
299
 * based on preprocessor macros.
300
 */
301
int _sir_strncat(char* restrict dest, size_t destsz,
302
    const char* restrict src, size_t count);
303

304
/**
305
 * Wrapper for fopen/fopen_s. Determines which one to use
306
 * based on preprocessor macros.
307
 */
308
int _sir_fopen(FILE* restrict* restrict streamptr, const char* restrict filename,
309
    const char* restrict mode);
310

311
/**
312
 * Wrapper for localtime/localtime_s. Determines which one to use
313
 * based on preprocessor macros.
314
 */
315
struct tm* _sir_localtime(const time_t* restrict timer, struct tm* restrict buf);
316

317
/**
318
 * A portable "press any key to continue" implementation; On Windows, uses _getch().
319
 * otherwise, uses tcgetattr()/tcsetattr() and getchar().
320
 */
321
bool _sir_getchar(char* input);
322

323
/**
324
 * Implementation of the 32-bit FNV-1a OWHF (http://isthe.com/chongo/tech/comp/fnv/)
325
 */
326
static inline
327
uint32_t FNV32_1a(const uint8_t* data, size_t len) {
6,272✔
328
    uint32_t hash = 2166136261U;
26✔
329
    for (size_t n = 0; n < len; n++) {
180,908✔
330
        hash ^= (uint32_t)data[n];
174,636✔
331
        hash *= 16777619U;
174,636✔
332
    }
333
    return hash;
6,272✔
334
}
335

336
/**
337
 * Implementation of the 64-bit FNV-1a OWHF (http://isthe.com/chongo/tech/comp/fnv/)
338
 * watered down to only handle null-terminated strings.
339
 */
340
static inline
341
uint64_t FNV64_1a(const char* str)
18,846✔
342
{
343
    uint64_t hash = 14695981039346656037UL;
26✔
344
    for (const char* c = str; *c; c++) {
401,482✔
345
        hash ^= (uint64_t)(unsigned char)(*c);
382,636✔
346
        hash *= 1099511628211UL;
382,636✔
347
    }
348
    return hash;
18,846✔
349
}
350

351
#endif /* !_SIR_HELPERS_H_INCLUDED */
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc