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

aremmell / libsir / 524

07 Sep 2023 10:00PM UTC coverage: 94.654% (-0.06%) from 94.711%
524

Pull #264

gitlab-ci

web-flow
Merge branch 'master' into johnsonjh/20230906/cbmc2
Pull Request #264: Return false if text styles fail to reset

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

3116 of 3292 relevant lines covered (94.65%)

603931.09 hits per line

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

93.75
/src/sirtextstyle.c
1
/*
2
 * sirtextstyle.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/textstyle.h"
27
#include "sir/internal.h"
28
#include "sir/defaults.h"
29

30
static sir_colormode sir_color_mode = SIRCM_16;
31

32
/** Wrapper around the level-to-style map and the color mode. This is the data
33
 * structure protected by the SIRMI_TEXTSTYLE mutex. */
34
sir_text_style_data sir_text_style_section = {
35
    &sir_level_to_style_map[0],
36
    &sir_color_mode
37
};
38

39
const char* _sir_gettextstyle(sir_level level) {
2,156,913✔
40
    static const size_t low  = 0;
41
    static const size_t high = SIR_NUMLEVELS - 1;
42

43
    _SIR_LOCK_SECTION(sir_text_style_data, data, SIRMI_TEXTSTYLE, NULL);
2,156,913✔
44
    const char* retval = SIR_UNKNOWN;
2,133,174✔
45

46
    _SIR_DECLARE_BIN_SEARCH(low, high);
2,133,174✔
47
    _SIR_BEGIN_BIN_SEARCH()
48

49
    if (data->map[_mid].level == level) {
8,584,109✔
50
        retval = data->map[_mid].str;
2,156,913✔
51
        break;
2,156,913✔
52
    }
53

54
    _SIR_ITERATE_BIN_SEARCH((data->map[_mid].level < level ? 1 : -1));
6,427,196✔
55
    _SIR_END_BIN_SEARCH();
56
    _SIR_UNLOCK_SECTION(SIRMI_TEXTSTYLE);
2,156,913✔
57

58
    return retval;
2,156,913✔
59
}
60

61
bool _sir_settextstyle(sir_level level, const sir_textstyle* style) {
155,512✔
62
    (void)_sir_seterror(_SIR_E_NOERROR);
155,512✔
63

64
    if (!_sir_sanity() || !_sir_validlevel(level))
155,509✔
65
        return false;
×
66

67
    _SIR_LOCK_SECTION(sir_text_style_data, data, SIRMI_TEXTSTYLE, false);
155,509✔
68
    bool updated              = false;
129,975✔
69
    static const size_t low   = 0;
70
    static const size_t high  = SIR_NUMLEVELS - 1;
71

72
    _SIR_DECLARE_BIN_SEARCH(low, high);
129,975✔
73
    _SIR_BEGIN_BIN_SEARCH()
74

75
    if (data->map[_mid].level == level) {
549,870✔
76
        memcpy(&data->map[_mid].style, style, sizeof(sir_textstyle));
155,550✔
77
        updated = _sir_formatstyle(*data->color_mode, style, data->map[_mid].str);
155,550✔
78
        break;
155,550✔
79
    }
80

81
    _SIR_ITERATE_BIN_SEARCH((data->map[_mid].level < level ? 1 : -1));
394,320✔
82
    _SIR_END_BIN_SEARCH();
83
    _SIR_UNLOCK_SECTION(SIRMI_TEXTSTYLE);
155,550✔
84

85
    SIR_ASSERT(updated);
147,025✔
86
    return updated;
138,500✔
87
}
88

89
const sir_textstyle* _sir_getdefstyle(sir_level level) {
12,992✔
90
    switch (level) {
12,992✔
91
        case SIRL_EMERG:  return &sir_lvl_emerg_def_style;
1,399✔
92
        case SIRL_ALERT:  return &sir_lvl_alert_def_style;
1,624✔
93
        case SIRL_CRIT:   return &sir_lvl_crit_def_style;
1,624✔
94
        case SIRL_ERROR:  return &sir_lvl_error_def_style;
1,624✔
95
        case SIRL_WARN:   return &sir_lvl_warn_def_style;
1,624✔
96
        case SIRL_NOTICE: return &sir_lvl_notice_def_style;
1,624✔
97
        case SIRL_INFO:   return &sir_lvl_info_def_style;
1,399✔
98
        case SIRL_DEBUG:  return &sir_lvl_debug_def_style;
1,624✔
99
        // GCOVR_EXCL_START
100
        default: /* this should never happen */
101
            SIR_ASSERT(level);
102
            return &sir_lvl_info_def_style;
103
        // GCOVR_EXCL_STOP
104
    }
105
}
106

107
bool _sir_resettextstyles(void) {
1,624✔
108
    (void)_sir_seterror(_SIR_E_NOERROR);
1,624✔
109

110
    if (!_sir_sanity())
1,624✔
111
        return false;
×
112

113
    _SIR_LOCK_SECTION(sir_text_style_data, data, SIRMI_TEXTSTYLE, false);
1,624✔
114
    bool all_ok = true;
1,399✔
115
    for (size_t n = 0; n < SIR_NUMLEVELS; n++) {
14,616✔
116
        memcpy(&data->map[n].style, _sir_getdefstyle(data->map[n].level),
12,992✔
117
             sizeof(sir_textstyle));
118
        _sir_eqland(all_ok, _sir_formatstyle(*data->color_mode, &data->map[n].style,
12,992✔
119
            data->map[n].str));
120
    }
121

122
    _SIR_UNLOCK_SECTION(SIRMI_TEXTSTYLE);
1,624✔
123
    return all_ok;
1,624✔
124
}
125

126
bool _sir_formatstyle(sir_colormode mode, const sir_textstyle* style,
168,542✔
127
    char buf[SIR_MAXSTYLE]) {
128
    if (!_sir_validtextstyle(mode, style))
168,542✔
129
        return false;
57✔
130

131
    _sir_resetstr(buf);
168,476✔
132

133
    switch (mode) {
168,476✔
134
        case SIRCM_16:
156,860✔
135
            /* \x1b[attr;fg;bgm */
136
            return 0 < snprintf(buf, SIR_MAXSTYLE, "%s%"PRIu8";%"PRIu8";%"PRIu8"m",
287,938✔
137
                SIR_ESC, (uint8_t)style->attr, (uint8_t)_sir_mkansifgcolor(style->fg),
156,860✔
138
                (uint8_t)_sir_mkansibgcolor(style->bg));
156,860✔
139
        case SIRCM_256: {
5,786✔
140
            /* \x1b[attr;38;5;fg;48;5;bgm */
141
            return 0 < snprintf(buf, SIR_MAXSTYLE,
15,780✔
142
                "%s%"PRIu8";%"PRIu8";5;%"PRIu8";%"PRIu8";5;%"PRIu8"m", SIR_ESC,
143
                (uint8_t)style->attr, (uint8_t)_sir_getansifgcmd(style->fg),
5,786✔
144
                (uint8_t)style->fg, (uint8_t)_sir_getansibgcmd(style->bg),
5,786✔
145
                (uint8_t)style->bg);
5,786✔
146
        }
147
        case SIRCM_RGB: {
5,830✔
148
            /* \x1b[attr;38;2;rrr;ggg;bbb;48;2;rrr;ggg;bbbm */
149
            return 0 < snprintf(buf, SIR_MAXSTYLE,
15,900✔
150
                "%s%"PRIu8";%"PRIu8";2;%"PRIu8";%"PRIu8";%"PRIu8";%"PRIu8
151
                ";2;%"PRIu8";%"PRIu8";%"PRIu8"m", SIR_ESC, (uint8_t)style->attr,
5,830✔
152
                (uint8_t)_sir_getansifgcmd(style->fg), _sir_getredfromcolor(style->fg),
5,830✔
153
                _sir_getgreenfromcolor(style->fg), _sir_getbluefromcolor(style->fg),
5,830✔
154
                (uint8_t)_sir_getansibgcmd(style->bg), _sir_getredfromcolor(style->bg),
5,830✔
155
                _sir_getgreenfromcolor(style->bg), _sir_getbluefromcolor(style->bg));
5,830✔
156
        }
157
        case SIRCM_INVALID: // GCOVR_EXCL_START
158
        default:
159
            return false;
160
    } // GCOVR_EXCL_STOP
161
}
162

163
bool _sir_validtextstyle(sir_colormode mode, const sir_textstyle* style) {
168,542✔
164
    if (!_sir_validptr(style) || !_sir_validcolormode(mode))
168,542✔
165
        return false;
×
166

167
    sir_textcolor fg = SIRCM_16 == mode ? _sir_mkansifgcolor(style->fg) : style->fg;
168,542✔
168
    sir_textcolor bg = SIRCM_16 == mode ? _sir_mkansibgcolor(style->bg) : style->bg;
168,542✔
169

170
    if (!_sir_validtextattr(style->attr) || !_sir_validtextcolor(mode, fg) ||
195,911✔
171
        !_sir_validtextcolor(mode, bg))
168,498✔
172
        return false;
44✔
173

174
    if (SIRTC_DEFAULT != style->fg && SIRTC_DEFAULT != style->bg &&
168,498✔
175
        style->fg == style->bg) {
132,659✔
176
        _sir_selflog("error: fg color %08"PRIx32" and bg color %08"PRIx32
21✔
177
                     " are identical; text would be invisible", style->fg,
178
                     style->bg);
179
        SIR_ASSERT(SIRTC_DEFAULT != style->fg && SIRTC_DEFAULT != style->bg &&
21✔
180
                style->fg == style->bg);
181
        return _sir_seterror(_SIR_E_TEXTSTYLE);
22✔
182
    }
183

184
    return true;
141,110✔
185
}
186

187
bool _sir_setcolormode(sir_colormode mode) {
845✔
188
    if (!_sir_validcolormode(mode))
845✔
189
        return false;
19✔
190

191
    _SIR_LOCK_SECTION(sir_text_style_data, data, SIRMI_TEXTSTYLE, false);
823✔
192
    if (*data->color_mode != mode) {
823✔
193
        sir_colormode old = *data->color_mode;
57✔
194
        *data->color_mode = mode;
66✔
195
        _sir_selflog("color mode changed from %"PRId32" to %"PRId32, old, mode);
63✔
196

197
        /* when the color mode changes, it's necessary to regenerate the text styles
198
         * we're holding. for example in the case of downgrading color modes, the
199
         * styles in memory could be incompatible with the new mode. */
200
        if (!_sir_resettextstyles()) {
66✔
201
            _sir_selflog("error: failed to reset text styles!");
×
202
            _SIR_UNLOCK_SECTION(SIRMI_TEXTSTYLE);
×
203
            return false;
×
204
        }
205
    } else {
206
        _sir_selflog("skipped superfluous update of color mode: %"PRId32, mode);
722✔
207
    }
208
    _SIR_UNLOCK_SECTION(SIRMI_TEXTSTYLE);
823✔
209

210
    return true;
823✔
211
}
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