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

aremmell / libsir / 268

29 Aug 2023 01:09PM UTC coverage: 94.865% (-0.03%) from 94.892%
268

Pull #239

gitlab-ci

web-flow
Merge branch 'master' into johnsonjh/20230825/fix2

Signed-off-by: Jeffrey H. Johnson <trnsz@pobox.com>
Pull Request #239: Enable Oracle Lint and additional compiler warnings

10 of 10 new or added lines in 4 files covered. (100.0%)

3030 of 3194 relevant lines covered (94.87%)

604256.23 hits per line

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

91.12
/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) {
258,011✔
30
    bool valid = NULL != pp;
258,011✔
31
    if (!valid && fail) {
258,011✔
32
        (void)_sir_seterror(_SIR_E_NULLPTR);
×
33
        SIR_ASSERT(!(bool)"NULL pointer!");
×
34
    }
35
    return valid;
258,022✔
36
}
37

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

47
void __sir_safefree(void** pp) {
898,378✔
48
    if (!pp || !*pp)
898,378✔
49
        return;
239,469✔
50

51
    free(*pp);
616,377✔
52
    *pp = NULL;
616,377✔
53
}
54

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

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

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

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

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

72
    *f = NULL;
36,359✔
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) {
145,698✔
100
    if (!_sir_validptr(data))
145,698✔
101
        return false;
×
102

103
    bool valid = true;
121,471✔
104
    if ((data->fields & SIRU_ALL) == 0u ||
145,655✔
105
          (data->fields & ~SIRU_ALL) != 0u) /* implicit-conversion */
121,482✔
106
        valid = false;
×
107

108
    if (valid && _sir_bittest(data->fields, SIRU_LEVELS))
145,655✔
109
        valid &= (_sir_validptrnofail(data->levels) &&
2,522✔
110
            _sir_validlevels(*data->levels));
1,261✔
111

112
    if (valid && _sir_bittest(data->fields, SIRU_OPTIONS))
145,650✔
113
        valid &= (_sir_validptrnofail(data->opts) &&
288,124✔
114
            _sir_validopts(*data->opts));
144,095✔
115

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

119
    if (valid && _sir_bittest(data->fields, SIRU_SYSLOG_CAT))
145,439✔
120
        valid &= _sir_validstrnofail(data->sl_category);
94✔
121

122
    if (!valid) {
145,422✔
123
        (void)_sir_seterror(_SIR_E_INVALID);
16✔
124
        SIR_ASSERT(!(bool)"invalid sir_update_config_data!");
×
125
    }
126

127
    return valid;
121,300✔
128
}
129

130
bool _sir_validlevels(sir_levels levels) {
77,279✔
131
    if ((SIRL_ALL == levels || SIRL_NONE == levels) ||
78,965✔
132
        ((_sir_bittest(levels, SIRL_INFO)           ||
3,170✔
133
         _sir_bittest(levels, SIRL_DEBUG)           ||
2,344✔
134
         _sir_bittest(levels, SIRL_NOTICE)          ||
1,924✔
135
         _sir_bittest(levels, SIRL_WARN)            ||
1,580✔
136
         _sir_bittest(levels, SIRL_ERROR)           ||
1,059✔
137
         _sir_bittest(levels, SIRL_CRIT)            ||
582✔
138
         _sir_bittest(levels, SIRL_ALERT)           ||
349✔
139
         _sir_bittest(levels, SIRL_EMERG))          &&
2,061✔
140
         ((levels & ~SIRL_ALL) == 0u)))
141
         return true;
64,252✔
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,555,881✔
148
    if (SIRL_INFO   == level || SIRL_DEBUG == level ||
4,555,881✔
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,467,798✔
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) {
220,313✔
162
    if ((SIRO_ALL == opts || SIRO_MSGONLY == opts) ||
342,578✔
163
        ((_sir_bittest(opts, SIRO_NOTIME)          ||
236,906✔
164
         _sir_bittest(opts, SIRO_NOHOST)           ||
108,739✔
165
         _sir_bittest(opts, SIRO_NOLEVEL)          ||
664✔
166
         _sir_bittest(opts, SIRO_NONAME)           ||
548✔
167
         _sir_bittest(opts, SIRO_NOMSEC)           ||
434✔
168
         _sir_bittest(opts, SIRO_NOPID)            ||
307✔
169
         _sir_bittest(opts, SIRO_NOTID)            ||
186✔
170
         _sir_bittest(opts, SIRO_NOHDR))           &&
88✔
171
         ((opts & ~(SIRO_MSGONLY | SIRO_NOHDR)) == 0u))) /* implicit-conversion */
146,414✔
172
         return true;
183,273✔
173

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

178
bool _sir_validtextattr(sir_textattr attr) {
167,821✔
179
    switch(attr) {
167,821✔
180
        case SIRTA_NORMAL:
140,523✔
181
        case SIRTA_BOLD:
182
        case SIRTA_DIM:
183
        case SIRTA_EMPH:
184
        case SIRTA_ULINE:
185
            return true;
140,523✔
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) {
335,576✔
194
    bool valid = false;
281,027✔
195
    switch (mode) {
335,576✔
196
        case SIRCM_16:
312,344✔
197
            /* in 16-color mode:
198
             * compare to 30..37, 39, 40..47, 49, 90..97, 100..107. */
199
            valid = SIRTC_DEFAULT == color ||
312,344✔
200
                    (color >= 30u && color <= 37u) || color == 39u ||
312,344✔
201
                    (color >= 40u && color <= 47u) || color == 49u ||
134,454✔
202
                    (color >= 90u && color <= 97u) || (color >= 100u && color <= 107u);
521,926✔
203
            break;
260,963✔
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) {
284,195✔
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;
335,576✔
227
}
228

229
bool _sir_validcolormode(sir_colormode mode) {
168,621✔
230
    switch (mode) {
168,621✔
231
        case SIRCM_16:
141,212✔
232
        case SIRCM_256:
233
        case SIRCM_RGB:
234
            return true;
141,212✔
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,466,643✔
244
    bool valid = str && (*str != '\0');
45,466,643✔
245
    if (!valid && fail) {
45,466,643✔
246
        (void)_sir_seterror(_SIR_E_STRING);
20,874✔
247
        SIR_ASSERT(!(bool)"invalid string!");
20,870✔
248
    }
249
    return valid;
45,469,322✔
250
}
251

252
int _sir_strncpy(char* restrict dest, size_t destsz, const char* restrict src, size_t count) {
2,173,987✔
253
    if (_sir_validptr(dest) && _sir_validstr(src)) {
2,173,987✔
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,150,132✔
264
        SIR_ASSERT_UNUSED(cpy < destsz, cpy);
2,166,026✔
265
        return 0;
2,173,974✔
266
#endif
267
    }
268

269
    return -1;
10✔
270
}
271

272
int _sir_strncat(char* restrict dest, size_t destsz, const char* restrict src, size_t count) {
25,258,385✔
273
    if (_sir_validptr(dest) && _sir_validstr(src)) {
25,258,385✔
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,862,686✔
284
        SIR_ASSERT_UNUSED(cat < destsz, cat);
25,116,630✔
285
        return 0;
25,238,366✔
286
#endif
287
    }
288

289
    return -1;
20,726✔
290
}
291

292
int _sir_fopen(FILE* restrict* restrict streamptr, const char* restrict filename,
36,449✔
293
    const char* restrict mode) {
294
    if (_sir_validptrptr(streamptr) && _sir_validstr(filename) && _sir_validstr(mode)) {
36,449✔
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);
36,449✔
304
        if (!*streamptr) {
36,449✔
305
            (void)_sir_handleerr(errno);
69✔
306
            return -1;
69✔
307
        }
308
        return 0;
30,207✔
309
#endif
310
    }
311

312
    return -1;
×
313
}
314

315
struct tm* _sir_localtime(const time_t* restrict timer, struct tm* restrict buf) {
2,175,330✔
316
    if (_sir_validptr(timer) && _sir_validptr(buf)) {
2,175,330✔
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,175,329✔
336
# else
337
        struct tm* ret = localtime(timer);
338
# endif
339
        if (!ret)
2,175,333✔
340
            (void)_sir_handleerr(errno);
×
341

342
        return ret;
2,175,333✔
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