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

aremmell / libsir / 266

29 Aug 2023 12:36PM UTC coverage: 94.955% (-0.06%) from 95.017%
266

Pull #241

gitlab-ci

web-flow
Merge branch 'master' into maybe-enums
Pull Request #241: Change sir_level and sir_option to defines, rather than enum

86 of 86 new or added lines in 9 files covered. (100.0%)

3030 of 3191 relevant lines covered (94.95%)

603446.22 hits per line

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

92.22
/src/sirhelpers.c
1
/*
2
 * sirhelpers.c
3
 *
4
 * Author:    Ryan M. Lederman <lederman@gmail.com>
5
 * Copyright: Copyright (c) 2018-2023
6
 * Version:   2.2.3
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
#include "sir/helpers.h"
27
#include "sir/errors.h"
28

29
bool __sir_validptrptr(const void* restrict* pp, bool fail) {
254,120✔
30
    bool valid = NULL != pp;
254,120✔
31
    if (!valid && fail) {
254,120✔
32
        (void)_sir_seterror(_SIR_E_NULLPTR);
×
33
        SIR_ASSERT("!NULL pointer");
34
    }
35
    return valid;
254,172✔
36
}
37

38
bool __sir_validptr(const void* restrict p, bool fail) {
72,189,291✔
39
    bool valid = NULL != p;
72,189,291✔
40
    if (!valid && fail) {
72,189,291✔
41
        (void)_sir_seterror(_SIR_E_NULLPTR);
154✔
42
        SIR_ASSERT(!"NULL pointer");
147✔
43
    }
44
    return valid;
72,195,396✔
45
}
46

47
void __sir_safefree(void** pp) {
877,713✔
48
    if (!pp || !*pp)
877,713✔
49
        return;
234,283✔
50

51
    free(*pp);
601,017✔
52
    *pp = NULL;
601,017✔
53
}
54

55
void _sir_safeclose(int* restrict fd) {
177✔
56
    if (!fd || 0 > *fd)
177✔
57
        return;
×
58

59
    if (-1 == close(*fd))
177✔
60
        (void)_sir_handleerr(errno);
×
61

62
    *fd = -1;
177✔
63
}
64

65
void _sir_safefclose(FILE* restrict* restrict f) {
35,857✔
66
    if (!f || !*f)
35,857✔
67
        return;
4✔
68

69
    if (0 != fclose(*f))
35,853✔
70
        (void)_sir_handleerr(errno);
×
71

72
    *f = NULL;
35,853✔
73
}
74

75
bool _sir_validfd(int fd) {
106✔
76
    /** stdin, stdout, stderr use up 0, 1, 2 */
77
    if (2 >= fd)
106✔
78
        return _sir_handleerr(EBADF);
66✔
79

80
#if !defined(__WIN__)
81
    int ret = fcntl(fd, F_GETFL);
40✔
82
#else /* __WIN__ */
83
# if !defined(SIR_MSVCRT_MINGW)
84
    invalparamfn old = _set_thread_local_invalid_parameter_handler(_sir_invalidparameter);
85
# endif
86
    struct _stat st;
87
    int ret = _fstat(fd, &st);
88
# if !defined(SIR_MSVCRT_MINGW)
89
    _set_thread_local_invalid_parameter_handler(old);
90
# endif
91
#endif
92
    return (-1 != ret || EBADF != errno) ? true : _sir_handleerr(errno);
40✔
93
}
94

95
/** Validates a sir_update_config_data structure. */
96
#if defined(__clang__) /* only Clang has implicit-conversion; GCC BZ#87454 */
97
SANITIZE_SUPPRESS("implicit-conversion")
98
#endif
99
bool _sir_validupdatedata(sir_update_config_data* data) {
143,418✔
100
    if (!_sir_validptr(data))
143,418✔
101
        return false;
×
102

103
    bool valid = true;
118,919✔
104
    if ((data->fields & SIRU_ALL) == 0u ||
143,380✔
105
          (data->fields & ~SIRU_ALL) != 0u) /* implicit-conversion */
118,933✔
106
        valid = false;
×
107

108
    if (valid && _sir_bittest(data->fields, SIRU_LEVELS))
143,380✔
109
        valid &= (_sir_validptrnofail(data->levels) &&
2,524✔
110
            _sir_validlevels(*data->levels));
1,262✔
111

112
    if (valid && _sir_bittest(data->fields, SIRU_OPTIONS))
143,383✔
113
        valid &= (_sir_validptrnofail(data->opts) &&
283,751✔
114
            _sir_validopts(*data->opts));
141,865✔
115

116
    if (valid && _sir_bittest(data->fields, SIRU_SYSLOG_ID))
143,255✔
117
        valid &= _sir_validstrnofail(data->sl_identity);
116✔
118

119
    if (valid && _sir_bittest(data->fields, SIRU_SYSLOG_CAT))
143,232✔
120
        valid &= _sir_validstrnofail(data->sl_category);
92✔
121

122
    if (!valid) {
143,216✔
123
        (void)_sir_seterror(_SIR_E_INVALID);
19✔
124
        SIR_ASSERT("!invalid sir_update_config_data");
125
    }
126

127
    return valid;
118,914✔
128
}
129

130
bool _sir_validlevels(sir_levels levels) {
76,280✔
131
    if ((SIRL_ALL == levels || SIRL_NONE == levels) ||
77,963✔
132
        ((_sir_bittest(levels, SIRL_INFO)           ||
3,160✔
133
         _sir_bittest(levels, SIRL_DEBUG)           ||
2,329✔
134
         _sir_bittest(levels, SIRL_NOTICE)          ||
1,910✔
135
         _sir_bittest(levels, SIRL_WARN)            ||
1,573✔
136
         _sir_bittest(levels, SIRL_ERROR)           ||
1,057✔
137
         _sir_bittest(levels, SIRL_CRIT)            ||
582✔
138
         _sir_bittest(levels, SIRL_ALERT)           ||
354✔
139
         _sir_bittest(levels, SIRL_EMERG))          &&
2,062✔
140
         ((levels & ~SIRL_ALL) == 0u)))
141
         return true;
63,493✔
142

143
    _sir_selflog("invalid levels: %04"PRIx16, levels);
94✔
144
    return _sir_seterror(_SIR_E_LEVELS);
99✔
145
}
146

147
bool _sir_validlevel(sir_level level) {
4,551,317✔
148
    if (SIRL_INFO   == level || SIRL_DEBUG == level ||
4,551,317✔
149
        SIRL_NOTICE == level || SIRL_WARN  == level ||
7,137✔
150
        SIRL_ERROR  == level || SIRL_CRIT  == level ||
4,265✔
151
        SIRL_ALERT  == level || SIRL_EMERG == level)
1,428✔
152
        return true;
4,463,160✔
153

154
    _sir_selflog("invalid level: %04"PRIx16, level);
21✔
155
    return _sir_seterror(_SIR_E_LEVELS);
22✔
156
}
157

158
#if defined(__clang__) /* only Clang has implicit-conversion; GCC BZ#87454 */
159
SANITIZE_SUPPRESS("implicit-conversion")
160
#endif
161
bool _sir_validopts(sir_options opts) {
217,079✔
162
    if ((SIRO_ALL == opts || SIRO_MSGONLY == opts) ||
336,793✔
163
        ((_sir_bittest(opts, SIRO_NOTIME)          ||
232,817✔
164
         _sir_bittest(opts, SIRO_NOHOST)           ||
106,987✔
165
         _sir_bittest(opts, SIRO_NOLEVEL)          ||
672✔
166
         _sir_bittest(opts, SIRO_NONAME)           ||
550✔
167
         _sir_bittest(opts, SIRO_NOMSEC)           ||
430✔
168
         _sir_bittest(opts, SIRO_NOPID)            ||
305✔
169
         _sir_bittest(opts, SIRO_NOTID)            ||
186✔
170
         _sir_bittest(opts, SIRO_NOHDR))           &&
88✔
171
         ((opts & ~(SIRO_MSGONLY | SIRO_NOHDR)) == 0u))) /* implicit-conversion */
144,221✔
172
         return true;
180,027✔
173

174
    _sir_selflog("invalid options: %08"PRIx32, opts);
238✔
175
    return _sir_seterror(_SIR_E_OPTIONS);
320✔
176
}
177

178
bool _sir_validtextattr(sir_textattr attr) {
165,824✔
179
    switch(attr) {
165,824✔
180
        case SIRTA_NORMAL:
138,526✔
181
        case SIRTA_BOLD:
182
        case SIRTA_DIM:
183
        case SIRTA_EMPH:
184
        case SIRTA_ULINE:
185
            return true;
138,526✔
186
        default: {
22✔
187
            _sir_selflog("invalid text attr: %d", attr);
21✔
188
            return _sir_seterror(_SIR_E_TEXTATTR);
22✔
189
        }
190
    }
191
}
192

193
bool _sir_validtextcolor(sir_colormode mode, sir_textcolor color) {
331,582✔
194
    bool valid = false;
277,033✔
195
    switch (mode) {
331,582✔
196
        case SIRCM_16:
308,350✔
197
            /* in 16-color mode:
198
             * compare to 30..37, 39, 40..47, 49, 90..97, 100..107. */
199
            valid = SIRTC_DEFAULT == color ||
308,350✔
200
                    (color >= 30u && color <= 37u) || color == 39u ||
308,350✔
201
                    (color >= 40u && color <= 47u) || color == 49u ||
132,457✔
202
                    (color >= 90u && color <= 97u) || (color >= 100u && color <= 107u);
513,938✔
203
            break;
256,969✔
204
        case SIRCM_256:
11,572✔
205
            /* in 256-color mode: compare to 0..255. sir_textcolor is unsigned,
206
             * so only need to ensure it's <= 255. */
207
            valid = SIRTC_DEFAULT == color || color <= 255u;
11,572✔
208
            break;
11,572✔
209
        case SIRCM_RGB: {
11,660✔
210
            /* in RGB-color mode: mask and compare to 0x00ffffff. */
211
            valid = SIRTC_DEFAULT == color || ((color & 0xff000000u) == 0u);
11,660✔
212
            break;
11,660✔
213
        }
214
        case SIRCM_INVALID: // GCOVR_EXCL_START
215
        default:
216
            valid = false;
217
            break;
218
    } // GCOVR_EXCL_STOP
219

220
    if (!valid) {
280,201✔
221
        _sir_selflog("invalid text color for mode %d %08"PRIx32" (%"PRIu32")",
21✔
222
            mode, color, color);
223
        (void)_sir_seterror(_SIR_E_TEXTCOLOR);
22✔
224
    }
225

226
    return valid;
331,582✔
227
}
228

229
bool _sir_validcolormode(sir_colormode mode) {
166,624✔
230
    switch (mode) {
166,624✔
231
        case SIRCM_16:
139,215✔
232
        case SIRCM_256:
233
        case SIRCM_RGB:
234
            return true;
139,215✔
235
        case SIRCM_INVALID:
22✔
236
        default: {
237
            _sir_selflog("invalid color mode: %d", mode);
21✔
238
            return _sir_seterror(_SIR_E_COLORMODE);
22✔
239
        }
240
    }
241
}
242

243
bool __sir_validstr(const char* restrict str, bool fail) {
45,348,801✔
244
    bool valid = str && (*str != '\0');
45,348,801✔
245
    if (!valid && fail) {
45,348,801✔
246
        (void)_sir_seterror(_SIR_E_STRING);
19,027✔
247
        SIR_ASSERT(!"invalid string");
19,024✔
248
    }
249
    return valid;
45,352,402✔
250
}
251

252
int _sir_strncpy(char* restrict dest, size_t destsz, const char* restrict src, size_t count) {
2,172,789✔
253
    if (_sir_validptr(dest) && _sir_validstr(src)) {
2,172,789✔
254
#if defined(__HAVE_STDC_SECURE_OR_EXT1__)
255
        int ret = strncpy_s(dest, destsz, src, count);
256
        if (0 != ret) {
257
            (void)_sir_handleerr(ret);
258
            return -1;
259
        }
260
        return 0;
261
#else
262
        SIR_UNUSED(count);
263
        size_t cpy = strlcpy(dest, src, destsz);
2,148,912✔
264
        SIR_ASSERT_UNUSED(cpy < destsz, cpy);
2,164,808✔
265
        return 0;
2,172,757✔
266
#endif
267
    }
268

269
    return -1;
30✔
270
}
271

272
int _sir_strncat(char* restrict dest, size_t destsz, const char* restrict src, size_t count) {
25,188,504✔
273
    if (_sir_validptr(dest) && _sir_validstr(src)) {
25,188,504✔
274
#if defined(__HAVE_STDC_SECURE_OR_EXT1__)
275
        int ret = strncat_s(dest, destsz, src, count);
276
        if (0 != ret) {
277
            (void)_sir_handleerr(ret);
278
            return -1;
279
        }
280
        return 0;
281
#else
282
        SIR_UNUSED(count);
283
        size_t cat = strlcat(dest, src, destsz);
24,796,570✔
284
        SIR_ASSERT_UNUSED(cat < destsz, cat);
25,048,282✔
285
        return 0;
25,171,088✔
286
#endif
287
    }
288

289
    return -1;
18,858✔
290
}
291

292
int _sir_fopen(FILE* restrict* restrict streamptr, const char* restrict filename,
35,943✔
293
    const char* restrict mode) {
294
    if (_sir_validptrptr(streamptr) && _sir_validstr(filename) && _sir_validstr(mode)) {
35,943✔
295
#if defined(__HAVE_STDC_SECURE_OR_EXT1__)
296
        int ret = fopen_s(streamptr, filename, mode);
297
        if (0 != ret) {
298
            (void)_sir_handleerr(ret);
299
            return -1;
300
        }
301
        return 0;
302
#else
303
        *streamptr = fopen(filename, mode);
35,943✔
304
        if (!*streamptr) {
35,943✔
305
            (void)_sir_handleerr(errno);
69✔
306
            return -1;
69✔
307
        }
308
        return 0;
29,821✔
309
#endif
310
    }
311

312
    return -1;
×
313
}
314

315
struct tm* _sir_localtime(const time_t* restrict timer, struct tm* restrict buf) {
2,173,834✔
316
    if (_sir_validptr(timer) && _sir_validptr(buf)) {
2,173,834✔
317
#if defined(__HAVE_STDC_SECURE_OR_EXT1__) && !defined(__EMBARCADEROC__)
318
# if !defined(__WIN__)
319
        struct tm* ret = localtime_s(timer, buf);
320
        if (!ret) {
321
            (void)_sir_handleerr(errno);
322
            return NULL;
323
        }
324
# else /* __WIN__ */
325
        errno_t ret = localtime_s(buf, timer);
326
        if (0 != ret) {
327
            (void)_sir_handleerr(ret);
328
            return NULL;
329
        }
330
# endif
331

332
        return buf;
333
#else /* !__HAVE_STDC_SECURE_OR_EXT1__ */
334
# if !defined(__WIN__) || defined(__EMBARCADEROC__)
335
        struct tm* ret = localtime_r(timer, buf);
2,173,834✔
336
# else
337
        struct tm* ret = localtime(timer);
338
# endif
339
        if (!ret)
2,173,839✔
340
            (void)_sir_handleerr(errno);
×
341

342
        return ret;
2,173,839✔
343
#endif
344
    }
345

346
    return NULL;
×
347
}
348

349
bool _sir_getchar(char* input) {
1✔
350
    if (!_sir_validptr(input))
1✔
351
        return false;
×
352

353
#if defined(__WIN__)
354
# if defined(__EMBARCADEROC__)
355
     *input = (char)getch();
356
# else
357
     *input = (char)_getch();
358
# endif
359
     return true;
360
#else /* !__WIN__ */
361
    struct termios cur = {0}, new = {0};
1✔
362
    if (0 != tcgetattr(STDIN_FILENO, &cur))
1✔
363
        return _sir_handleerr(errno);
×
364

365
    memcpy(&new, &cur, sizeof(struct termios));
×
366
    new.c_lflag &= ~(ICANON | ECHO);
1✔
367

368
    if (0 != tcsetattr(STDIN_FILENO, TCSANOW, &new))
1✔
369
        return _sir_handleerr(errno);
×
370

371
    *input = (char)getchar();
1✔
372

373
    return 0 == tcsetattr(STDIN_FILENO, TCSANOW, &cur) ? true
1✔
374
        : _sir_handleerr(errno);
1✔
375
#endif
376
}
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