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

tstack / lnav / 19561959745-2698

21 Nov 2025 06:05AM UTC coverage: 68.864%. Remained the same
19561959745-2698

push

github

tstack
[perf] improve stuff related to archive extraction

19 of 27 new or added lines in 4 files covered. (70.37%)

3 existing lines in 2 files now uncovered.

51106 of 74213 relevant lines covered (68.86%)

431629.27 hits per line

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

81.48
/src/base/strnatcmp.c
1
/* -*- mode: c; c-file-style: "k&r" -*-
2

3
  strnatcmp.c -- Perform 'natural order' comparisons of strings in C.
4
  Copyright (C) 2000, 2004 by Martin Pool <mbp sourcefrog net>
5

6
  This software is provided 'as-is', without any express or implied
7
  warranty.  In no event will the authors be held liable for any damages
8
  arising from the use of this software.
9

10
  Permission is granted to anyone to use this software for any purpose,
11
  including commercial applications, and to alter it and redistribute it
12
  freely, subject to the following restrictions:
13

14
  1. The origin of this software must not be misrepresented; you must not
15
     claim that you wrote the original software. If you use this software
16
     in a product, an acknowledgment in the product documentation would be
17
     appreciated but is not required.
18
  2. Altered source versions must be plainly marked as such, and must not be
19
     misrepresented as being the original software.
20
  3. This notice may not be removed or altered from any source distribution.
21
*/
22

23

24
/* partial change history:
25
 *
26
 * 2004-10-10 mbp: Lift out character type dependencies into macros.
27
 *
28
 * Eric Sosman pointed out that ctype functions take a parameter whose
29
 * value must be that of an unsigned int, even on platforms that have
30
 * negative chars in their default char type.
31
 */
32

33
#include <assert.h>
34
#include <ctype.h>
35

36
#include "strnatcmp.h"
37

38

39
/* These are defined as macros to make it easier to adapt this code to
40
 * different characters types or comparison functions. */
41
static inline int
42
nat_isdigit(nat_char a)
3,479,124✔
43
{
44
        return isdigit((unsigned char) a);
3,479,124✔
45
}
46

47

48
static inline int
49
nat_isspace(nat_char a)
5,071,364✔
50
{
51
        return isspace((unsigned char) a);
5,071,364✔
52
}
53

54

55
static inline nat_char
56
nat_toupper(nat_char a)
4,375,944✔
57
{
58
        return toupper((unsigned char) a);
4,375,944✔
59
}
60

61

62

63
static int
64
compare_right(int a_len, nat_char const *a, int b_len, nat_char const *b, int *len_out)
140,027✔
65
{
66
        int bias = 0;
140,027✔
67

68
        /* The longest run of digits wins.  That aside, the greatest
69
        value wins, but we can't know that it will until we've scanned
70
        both numbers to know that they have the same magnitude, so we
71
        remember it in BIAS. */
72
        for (;; a++, b++, a_len--, b_len--, (*len_out)++) {
267,608✔
73
                if (a_len == 0 && b_len == 0)
407,635✔
74
                        return bias;
139,957✔
75
                if (a_len == 0)
267,678✔
76
                        return -1;
3✔
77
                if (b_len == 0)
267,675✔
78
                        return 1;
1✔
79
                if (!nat_isdigit(*a) && !nat_isdigit(*b))
267,674✔
80
                        return bias;
63✔
81
                else if (!nat_isdigit(*a))
267,611✔
82
                        return -1;
2✔
83
                else if (!nat_isdigit(*b))
267,609✔
84
                        return +1;
1✔
85
                else if (*a < *b) {
267,608✔
86
                        if (!bias)
98,240✔
87
                                bias = -1;
65,726✔
88
                } else if (*a > *b) {
169,368✔
89
                        if (!bias)
109,078✔
90
                                bias = +1;
51,658✔
91
                } else if (!*a && !*b)
60,290✔
92
                        return bias;
×
93
        }
94

95
        return 0;
96
}
97

98
static int
99
compare_left(int a_len, nat_char const *a, int b_len, nat_char const *b, int *len_out)
110✔
100
{
101
     /* Compare two left-aligned numbers: the first to have a
102
        different value wins. */
103
     for (;; a++, b++, a_len--, b_len--, (*len_out)++) {
88✔
104
               if (a_len == 0 && b_len == 0)
198✔
105
                       return 0;
84✔
106
               if (a_len == 0)
114✔
107
                       return -1;
×
108
               if (b_len == 0)
114✔
109
                       return 1;
×
110
          if (!nat_isdigit(*a)  &&  !nat_isdigit(*b))
114✔
111
               return 0;
3✔
112
          else if (!nat_isdigit(*a))
111✔
113
               return -1;
×
114
          else if (!nat_isdigit(*b))
111✔
115
               return +1;
×
116
          else if (*a < *b)
111✔
117
               return -1;
23✔
118
          else if (*a > *b)
88✔
UNCOV
119
               return +1;
×
120
     }
121
          
122
     return 0;
123
}
124

125
static int strnatcmp0(int a_len, nat_char const *a,
799,099✔
126
                      int b_len, nat_char const *b,
127
                      int fold_case)
128
{
129
        int ai, bi;
130
        nat_char ca, cb;
131
        int fractional, result;
132

133
        assert(a && b);
134
        ai = bi = 0;
799,099✔
135
        while (1) {
136
                if (ai >= a_len)
2,535,629✔
137
                        ca = 0;
200,097✔
138
                else
139
                        ca = a[ai];
2,335,532✔
140
                if (bi >= b_len)
2,535,629✔
141
                        cb = 0;
200,095✔
142
                else
143
                        cb = b[bi];
2,335,534✔
144

145
                /* skip over leading spaces or zeros */
146
                while (nat_isspace(ca)) {
2,535,629✔
147
                        ai += 1;
×
148
                        if (ai >= a_len)
×
149
                                ca = 0;
×
150
                        else
151
                                ca = a[ai];
×
152
                }
153

154
                while (nat_isspace(cb)) {
2,535,629✔
155
                        bi += 1;
×
156
                        if (bi >= b_len)
×
157
                                cb = 0;
×
158
                        else
159
                                cb = b[bi];
×
160
                }
161

162
                /* process run of digits */
163
                if (nat_isdigit(ca) && nat_isdigit(cb)) {
2,535,629✔
164
            int num_len = 0;
140,112✔
165

166
                        fractional = (ca == '0' || cb == '0');
140,112✔
167

168
                        if (fractional) {
140,112✔
169
                                if ((result = compare_left(a_len - ai, a + ai, b_len - bi,
110✔
170
                                                                                   b + bi, &num_len)) != 0) {
171
                    return result;
117,404✔
172
                }
173
                        } else {
174
                                if ((result = compare_right(a_len - ai, a + ai, b_len - bi,
140,002✔
175
                                                                                        b + bi, &num_len)) != 0) {
176
                    return result;
117,381✔
177
                }
178
                        }
179

180
            ai += num_len;
22,708✔
181
            bi += num_len;
22,708✔
182
            continue;
22,708✔
183
                }
184

185
                if (!ca && !cb) {
2,395,517✔
186
                        /* The strings compare the same.  Perhaps the caller
187
                   will want to call strcmp to break the tie. */
188
                        return 0;
200,095✔
189
                }
190

191
                if (fold_case) {
2,195,422✔
192
                        ca = nat_toupper(ca);
2,187,972✔
193
                        cb = nat_toupper(cb);
2,187,972✔
194
                }
195

196
                if (ca < cb)
2,195,422✔
197
                        return -1;
214,949✔
198
                else if (ca > cb)
1,980,473✔
199
                        return +1;
266,651✔
200

201
                ++ai;
1,713,822✔
202
                ++bi;
1,713,822✔
203
        }
204
}
205

206
int ipv4cmp(int a_len, nat_char const *a,
13✔
207
            int b_len, nat_char const *b,
208
            int *res_out)
209
{
210
    int ai, bi;
211
    nat_char ca, cb;
212
    int fractional, result = 0;
13✔
213

214
    assert(a && b);
215
    ai = bi = 0;
13✔
216
    while (result == 0) {
56✔
217
        if (ai >= a_len)
53✔
218
            ca = 0;
5✔
219
        else
220
            ca = a[ai];
48✔
221
        if (bi >= b_len)
53✔
222
            cb = 0;
5✔
223
        else
224
            cb = b[bi];
48✔
225

226
        /* skip over leading spaces or zeros */
227
        while (nat_isspace(ca)) {
53✔
228
            ai += 1;
×
229
            if (ai >= a_len)
×
230
                ca = 0;
×
231
            else
232
                ca = a[ai];
×
233
        }
234

235
        while (nat_isspace(cb)) {
53✔
236
            bi += 1;
×
237
            if (bi >= b_len)
×
238
                cb = 0;
×
239
            else
240
                cb = b[bi];
×
241
        }
242

243
        /* process run of digits */
244
        if (nat_isdigit(ca) && nat_isdigit(cb)) {
53✔
245
            int num_len = 0;
25✔
246

247
            fractional = (ca == '0' || cb == '0');
25✔
248

249
            if (fractional) {
25✔
250
                result = compare_left(a_len - ai, a + ai, b_len - bi,
×
251
                                      b + bi, &num_len);
252
            } else {
253
                result = compare_right(a_len - ai, a + ai, b_len - bi,
25✔
254
                                       b + bi, &num_len);
255
            }
256

257
            ai += num_len;
25✔
258
            bi += num_len;
25✔
259
            continue;
25✔
260
        }
261

262
        if (!ca && !cb) {
28✔
263
            /* The strings compare the same.  Perhaps the caller
264
                   will want to call strcmp to break the tie. */
265
            *res_out = result;
4✔
266
            return 1;
4✔
267
        }
268

269
        if (ca != '.' || cb != '.') {
24✔
270
            return 0;
6✔
271
        }
272

273
        ++ai;
18✔
274
        ++bi;
18✔
275
    }
276

277
    for (; ai < a_len; ai++) {
14✔
278
        if (!isdigit((unsigned char)a[ai]) && a[ai] != '.') {
11✔
279
            return 0;
×
280
        }
281
    }
282

283
    for (; bi < b_len; bi++) {
16✔
284
        if (!isdigit((unsigned char)b[bi]) && b[bi] != '.') {
13✔
285
            return 0;
×
286
        }
287
    }
288

289
    *res_out = result;
3✔
290
    return 1;
3✔
291
}
292

293
int strnatcmp(int a_len, nat_char const *a, int b_len, nat_char const *b)
150✔
294
{
295
        return strnatcmp0(a_len, a, b_len, b, 0);
150✔
296
}
297

298
/* Compare, recognizing numeric string and ignoring case. */
299
int strnatcasecmp(int a_len, nat_char const *a, int b_len, nat_char const *b)
798,949✔
300
{
301
        return strnatcmp0(a_len, a, b_len, b, 1);
798,949✔
302
}
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

© 2026 Coveralls, Inc