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

aremmell / libsir / 926

26 Sep 2023 04:39PM UTC coverage: 95.095% (-0.03%) from 95.12%
926

Pull #309

gitlab-ci

web-flow
Merge branch 'master' into 092423/vscode-tasks
Pull Request #309: VS Code Tasks

3722 of 3914 relevant lines covered (95.09%)

524402.66 hits per line

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

91.67
/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.4
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
void __sir_safefree(void** pp) {
1,736,962✔
30
    if (!pp || !*pp)
1,736,962✔
31
        return;
456,939✔
32

33
    free(*pp);
1,237,650✔
34
    *pp = NULL;
1,237,650✔
35
}
36

37
void _sir_safeclose(int* restrict fd) {
142✔
38
    if (!fd || 0 > *fd)
142✔
39
        return;
×
40

41
    if (-1 == close(*fd))
142✔
42
        (void)_sir_handleerr(errno);
×
43

44
    *fd = -1;
142✔
45
}
46

47
void _sir_safefclose(FILE* restrict* restrict f) {
72,999✔
48
    if (!f || !*f)
72,999✔
49
        return;
30,467✔
50

51
    if (0 != fclose(*f))
36,498✔
52
        (void)_sir_handleerr(errno);
×
53

54
    *f = NULL;
36,498✔
55
}
56

57
bool _sir_validfd(int fd) {
106✔
58
    /** stdin, stdout, stderr use up 0, 1, 2 */
59
    if (2 >= fd)
106✔
60
        return _sir_handleerr(EBADF);
66✔
61

62
#if !defined(__WIN__)
63
    int ret = fcntl(fd, F_GETFL);
40✔
64
#else /* __WIN__ */
65
# if !defined(SIR_MSVCRT_MINGW)
66
    invalparamfn old = _set_thread_local_invalid_parameter_handler(_sir_invalidparameter);
67
# endif
68
    struct _stat st;
69
    int ret = _fstat(fd, &st);
70
# if !defined(SIR_MSVCRT_MINGW)
71
    _set_thread_local_invalid_parameter_handler(old);
72
# endif
73
#endif
74
    return (-1 != ret || EBADF != errno) ? true : _sir_handleerr(errno);
40✔
75
}
76

77
/** Validates a sir_update_config_data structure. */
78
bool __sir_validupdatedata(const sir_update_config_data* data, const char* func,
146,659✔
79
    const char* file, uint32_t line) {
80
    if (!_sir_validptr(data))
146,659✔
81
        return false;
×
82

83
    bool valid = true;
122,271✔
84
    if ((data->fields & SIRU_ALL) == 0U || (data->fields & ~SIRU_ALL) != 0U)
146,642✔
85
        valid = false;
×
86

87
    if (valid && _sir_bittest(data->fields, SIRU_LEVELS))
146,640✔
88
        valid = _sir_validptrnofail(data->levels) &&
2,556✔
89
                _sir_validlevels(*data->levels);
1,278✔
90

91
    if (valid && _sir_bittest(data->fields, SIRU_OPTIONS))
146,641✔
92
        valid = _sir_validptrnofail(data->opts) &&
290,242✔
93
                _sir_validopts(*data->opts);
145,106✔
94

95
    if (valid && _sir_bittest(data->fields, SIRU_SYSLOG_ID))
146,532✔
96
        valid = _sir_validstrnofail(data->sl_identity);
105✔
97

98
    if (valid && _sir_bittest(data->fields, SIRU_SYSLOG_CAT))
146,513✔
99
        valid = _sir_validstrnofail(data->sl_category);
80✔
100

101
    if (!valid) {
146,511✔
102
        SIR_ASSERT(valid);
×
103
        (void)__sir_seterror(_SIR_E_INVALID, func, file, line);
1✔
104
    }
105

106
    return valid;
122,194✔
107
}
108

109
bool __sir_validlevels(sir_levels levels, const char* func,
77,290✔
110
    const char* file, uint32_t line) {
111
    if ((SIRL_ALL == levels || SIRL_NONE == levels) ||
79,051✔
112
        ((_sir_bittest(levels, SIRL_INFO)           ||
3,259✔
113
         _sir_bittest(levels, SIRL_DEBUG)           ||
2,303✔
114
         _sir_bittest(levels, SIRL_NOTICE)          ||
1,783✔
115
         _sir_bittest(levels, SIRL_WARN)            ||
1,462✔
116
         _sir_bittest(levels, SIRL_ERROR)           ||
995✔
117
         _sir_bittest(levels, SIRL_CRIT)            ||
477✔
118
         _sir_bittest(levels, SIRL_ALERT)           ||
297✔
119
         _sir_bittest(levels, SIRL_EMERG))          &&
2,145✔
120
         ((levels & ~SIRL_ALL) == 0U)))
121
         return true;
64,506✔
122

123
    _sir_selflog("invalid levels: %04"PRIx16, levels);
94✔
124
    return __sir_seterror(_SIR_E_LEVELS, func, file, line);
99✔
125
}
126

127
bool __sir_validlevel(sir_level level, const char* func, const char* file,
4,561,049✔
128
    uint32_t line) {
129
    if (SIRL_INFO   == level || SIRL_DEBUG == level ||
4,561,049✔
130
        SIRL_NOTICE == level || SIRL_WARN  == level ||
7,182✔
131
        SIRL_ERROR  == level || SIRL_CRIT  == level ||
4,292✔
132
        SIRL_ALERT  == level || SIRL_EMERG == level)
1,437✔
133
        return true;
4,472,590✔
134

135
    _sir_selflog("invalid level: %04"PRIx16, level);
21✔
136
    return __sir_seterror(_SIR_E_LEVELS, func, file, line);
22✔
137
}
138

139
bool __sir_validopts(sir_options opts, const char* func, const char* file,
221,327✔
140
    uint32_t line) {
141
    if ((SIRO_ALL == opts || SIRO_MSGONLY == opts) ||
344,671✔
142
        ((_sir_bittest(opts, SIRO_NOTIME)          ||
238,867✔
143
         _sir_bittest(opts, SIRO_NOHOST)           ||
109,416✔
144
         _sir_bittest(opts, SIRO_NOLEVEL)          ||
690✔
145
         _sir_bittest(opts, SIRO_NONAME)           ||
556✔
146
         _sir_bittest(opts, SIRO_NOMSEC)           ||
433✔
147
         _sir_bittest(opts, SIRO_NOPID)            ||
326✔
148
         _sir_bittest(opts, SIRO_NOTID)            ||
189✔
149
         _sir_bittest(opts, SIRO_NOHDR))           &&
88✔
150
         ((opts & ~(SIRO_MSGONLY | SIRO_NOHDR)) == 0U)))
147,792✔
151
         return true;
184,384✔
152

153
    _sir_selflog("invalid options: %08"PRIx32, opts);
258✔
154
    return __sir_seterror(_SIR_E_OPTIONS, func, file, line);
325✔
155
}
156

157
bool __sir_validtextattr(sir_textattr attr, const char* func, const char* file,
169,230✔
158
    uint32_t line) {
159
    switch(attr) {
169,230✔
160
        case SIRTA_NORMAL:
141,788✔
161
        case SIRTA_BOLD:
162
        case SIRTA_DIM:
163
        case SIRTA_EMPH:
164
        case SIRTA_ULINE:
165
            return true;
141,788✔
166
        default: {
22✔
167
            _sir_selflog("invalid text attr: %d", attr);
21✔
168
            return __sir_seterror(_SIR_E_TEXTATTR, func, file, line);
22✔
169
        }
170
    }
171
}
172

173
bool __sir_validtextcolor(sir_colormode mode, sir_textcolor color, const char* func,
338,394✔
174
    const char* file, uint32_t line) {
175
    bool valid = false;
283,557✔
176
    switch (mode) {
338,394✔
177
        case SIRCM_16:
315,162✔
178
            /* in 16-color mode:
179
             * compare to 30..37, 39, 40..47, 49, 90..97, 100..107. */
180
            valid = SIRTC_DEFAULT == color ||
315,162✔
181
                    (color >= 30U && color <= 37U) || color == 39U ||
315,162✔
182
                    (color >= 40U && color <= 47U) || color == 49U ||
136,193✔
183
                    (color >= 90U && color <= 97U) || (color >= 100U && color <= 107U);
526,986✔
184
            break;
263,493✔
185
        case SIRCM_256:
11,572✔
186
            /* in 256-color mode: compare to 0..255. sir_textcolor is unsigned,
187
             * so only need to ensure it's <= 255. */
188
            valid = SIRTC_DEFAULT == color || color <= 255U;
11,572✔
189
            break;
11,572✔
190
        case SIRCM_RGB: {
11,660✔
191
            /* in RGB-color mode: mask and compare to 0x00ffffff. */
192
            valid = SIRTC_DEFAULT == color || ((color & 0xff000000U) == 0U);
11,660✔
193
            break;
11,660✔
194
        }
195
        case SIRCM_INVALID: // GCOVR_EXCL_START
196
        default:
197
            valid = false;
198
            break;
199
    } // GCOVR_EXCL_STOP
200

201
    if (!valid) {
286,725✔
202
        _sir_selflog("invalid text color for mode %d %08"PRIx32" (%"PRIu32")",
21✔
203
            mode, color, color);
204
        (void)__sir_seterror(_SIR_E_TEXTCOLOR, func, file, line);
22✔
205
    }
206

207
    return valid;
338,394✔
208
}
209

210
bool __sir_validcolormode(sir_colormode mode, const char* func, const char* file,
170,119✔
211
    uint32_t line) {
212
    switch (mode) {
170,119✔
213
        case SIRCM_16:
142,557✔
214
        case SIRCM_256:
215
        case SIRCM_RGB:
216
            return true;
142,557✔
217
        case SIRCM_INVALID:
22✔
218
        default: {
219
            _sir_selflog("invalid color mode: %d", mode);
21✔
220
            return __sir_seterror(_SIR_E_COLORMODE, func, file, line);
22✔
221
        }
222
    }
223
}
224

225
int _sir_strncpy(char* restrict dest, size_t destsz, const char* restrict src,
4,342,334✔
226
    size_t count) {
227
    if (_sir_validptr(dest) && _sir_validstr(src)) {
4,342,334✔
228
#if defined(__HAVE_STDC_SECURE_OR_EXT1__)
229
        int ret = strncpy_s(dest, destsz, src, count);
230
        if (0 != ret) {
231
            (void)_sir_handleerr(ret);
232
            return -1;
233
        }
234
        return 0;
235
#else
236
        SIR_UNUSED(count);
237
        size_t cpy = strlcpy(dest, src, destsz);
4,224,058✔
238
        SIR_ASSERT_UNUSED(cpy < destsz, cpy);
4,250,020✔
239
        return 0;
4,263,006✔
240
#endif
241
    }
242

243
    return -1;
79,317✔
244
}
245

246
int _sir_strncat(char* restrict dest, size_t destsz, const char* restrict src,
29,200,194✔
247
    size_t count) {
248
    if (_sir_validptr(dest) && _sir_validstr(src)) {
29,200,194✔
249
#if defined(__HAVE_STDC_SECURE_OR_EXT1__)
250
        int ret = strncat_s(dest, destsz, src, count);
251
        if (0 != ret) {
252
            (void)_sir_handleerr(ret);
253
            return -1;
254
        }
255
        return 0;
256
#else
257
        SIR_UNUSED(count);
258
        size_t cat = strlcat(dest, src, destsz);
28,830,384✔
259
        SIR_ASSERT_UNUSED(cat < destsz, cat);
29,074,197✔
260
        return 0;
29,196,012✔
261
#endif
262
    }
263

264
    return -1;
6,043✔
265
}
266

267
int _sir_fopen(FILE* restrict* restrict streamptr, const char* restrict filename,
36,552✔
268
    const char* restrict mode) {
269
    if (_sir_validptrptr(streamptr) && _sir_validstr(filename) && _sir_validstr(mode)) {
36,552✔
270
#if defined(__HAVE_STDC_SECURE_OR_EXT1__)
271
        int ret = fopen_s(streamptr, filename, mode);
272
        if (0 != ret) {
273
            (void)_sir_handleerr(ret);
274
            return -1;
275
        }
276
        return 0;
277
#else
278
        *streamptr = fopen(filename, mode);
36,552✔
279
        if (!*streamptr) {
36,552✔
280
            (void)_sir_handleerr(errno);
92✔
281
            return -1;
92✔
282
        }
283
        return 0;
30,426✔
284
#endif
285
    }
286

287
    return -1;
×
288
}
289

290
bool _sir_getchar(char* input) {
1✔
291
    if (!_sir_validptr(input))
1✔
292
        return false;
×
293

294
#if defined(__WIN__)
295
# if defined(__EMBARCADEROC__)
296
     *input = (char)getch();
297
# else
298
     *input = (char)_getch();
299
# endif
300
     return true;
301
#else /* !__WIN__ */
302
    struct termios cur = {0};
1✔
303
    if (0 != tcgetattr(STDIN_FILENO, &cur))
1✔
304
        return _sir_handleerr(errno);
×
305

306
    struct termios new = {0};
×
307
    memcpy(&new, &cur, sizeof(struct termios));
×
308
    new.c_lflag &= ~(ICANON | ECHO);
1✔
309

310
    if (0 != tcsetattr(STDIN_FILENO, TCSANOW, &new))
1✔
311
        return _sir_handleerr(errno);
×
312

313
    *input = (char)getchar();
1✔
314

315
    return 0 == tcsetattr(STDIN_FILENO, TCSANOW, &cur) ? true
1✔
316
        : _sir_handleerr(errno);
1✔
317
#endif
318
}
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