dte test coverage


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 50.0% high: ≥ 85.0%
Coverage Exec / Excl / Total
Lines: 100.0% 80 / 0 / 80
Functions: 100.0% 16 / 0 / 16
Branches: 100.0% 10 / 12 / 22

src/util/string.c
Line Branch Exec Source
1 #include <stdarg.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include "string.h"
5 #include "debug.h"
6 #include "utf8.h"
7 #include "xmalloc.h"
8
9 // Reserve `more` bytes of additional space and return a pointer to the
10 // start of it, to allow writing directly to the buffer. Updating `s->len`
11 // to reflect the new length is left up to the caller.
12 245656 char *string_reserve_space(String *s, size_t more)
13 {
14 245656 BUG_ON(more == 0);
15 245656 size_t min_alloc = xadd(s->len, more);
16
2/2
✓ Branch 5 → 6 taken 96 times.
✓ Branch 5 → 9 taken 245560 times.
245656 if (unlikely(s->alloc < min_alloc)) {
17 96 s->alloc = string_next_alloc_size(s->alloc, min_alloc);
18 96 s->buffer = xrealloc(s->buffer, s->alloc);
19 }
20 245656 return s->buffer + s->len;
21 }
22
23 763 void string_free(String *s)
24 {
25 763 free(s->buffer);
26 763 *s = (String) STRING_INIT;
27 763 }
28
29 188775 void string_append_byte(String *s, unsigned char byte)
30 {
31 188775 string_reserve_space(s, 1);
32 188775 s->buffer[s->len++] = byte;
33 188775 }
34
35 11 size_t string_append_codepoint(String *s, CodePoint u)
36 {
37 11 string_reserve_space(s, UTF8_MAX_SEQ_LEN);
38 11 size_t n = u_set_char_raw(s->buffer + s->len, u);
39 11 s->len += n;
40 11 return n;
41 }
42
43 25 static char *string_make_space(String *s, size_t pos, size_t len)
44 {
45 25 BUG_ON(pos > s->len);
46 25 BUG_ON(len == 0);
47 25 string_reserve_space(s, len);
48 25 char *start = s->buffer + pos;
49 25 memmove(start + len, start, s->len - pos);
50 25 s->len += len;
51 25 return start;
52 }
53
54 6 size_t string_insert_codepoint(String *s, size_t pos, CodePoint u)
55 {
56 6 size_t len = u_char_size(u);
57 6 return u_set_char_raw(string_make_space(s, pos, len), u);
58 }
59
60 20 size_t string_insert_buf(String *s, size_t pos, const char *buf, size_t len)
61 {
62
2/2
✓ Branch 2 → 3 taken 19 times.
✓ Branch 2 → 5 taken 1 time.
20 if (len) {
63 19 memcpy(string_make_space(s, pos, len), buf, len);
64 }
65 20 return len;
66 }
67
68 13971 size_t string_append_buf(String *s, const char *ptr, size_t len)
69 {
70
2/2
✓ Branch 2 → 3 taken 12163 times.
✓ Branch 2 → 5 taken 1808 times.
13971 if (len) {
71 12163 memcpy(string_reserve_space(s, len), ptr, len);
72 12163 s->len += len;
73 }
74 13971 return len;
75 }
76
77 13 size_t string_append_memset(String *s, unsigned char byte, size_t len)
78 {
79
2/2
✓ Branch 2 → 3 taken 11 times.
✓ Branch 2 → 5 taken 2 times.
13 if (len) {
80 11 memset(string_reserve_space(s, len), byte, len);
81 11 s->len += len;
82 }
83 13 return len;
84 }
85
86 VPRINTF(2)
87 7 static void string_vsprintf(String *s, const char *fmt, va_list ap)
88 {
89 7 va_list ap2;
90 7 va_copy(ap2, ap);
91 // Calculate the required size
92 7 int n = vsnprintf(NULL, 0, fmt, ap2);
93 7 va_end(ap2);
94 7 BUG_ON(n < 0);
95 7 string_reserve_space(s, n + 1);
96 7 int wrote = vsnprintf(s->buffer + s->len, n + 1, fmt, ap);
97 7 BUG_ON(wrote != n);
98 7 s->len += wrote;
99 7 }
100
101 7 void string_sprintf(String *s, const char *fmt, ...)
102 {
103 7 va_list ap;
104 7 va_start(ap, fmt);
105 7 string_vsprintf(s, fmt, ap);
106 7 va_end(ap);
107 7 }
108
109 42937 static char *null_terminate(String *s)
110 {
111 42937 string_reserve_space(s, 1);
112 42937 s->buffer[s->len] = '\0';
113 42937 return s->buffer;
114 }
115
116 33514 char *string_steal_cstring(String *s)
117 {
118 33514 char *buf = null_terminate(s);
119 33514 *s = (String) STRING_INIT;
120 33514 return buf;
121 }
122
123 93 char *string_clone_cstring(const String *s)
124 {
125 93 return xmemjoin(s->buffer, s->len, "", 1);
126 }
127
128 /*
129 * This method first ensures that the String buffer is null-terminated
130 * and then returns a const pointer to it, without doing any copying.
131 *
132 * NOTE: the returned pointer only remains valid so long as no other
133 * methods are called on the String. There are no exceptions to this
134 * rule. If the buffer is realloc'd, the pointer will be dangling and
135 * using it will invoke undefined behaviour. If unsure, just use
136 * string_clone_cstring() instead.
137 *
138 * This function itself may also invalidate other pointers into the
139 * buffer, since a realloc() may be needed before appending the null
140 * terminator.
141 */
142 9423 const char *string_borrow_cstring(String *s)
143 {
144 9423 return null_terminate(s);
145 }
146
147 9 void string_remove(String *s, size_t pos, size_t len)
148 {
149
2/2
✓ Branch 2 → 3 taken 8 times.
✓ Branch 2 → 6 taken 1 time.
9 if (len == 0) {
150 return;
151 }
152 8 size_t oldlen = s->len;
153 8 BUG_ON(pos + len > oldlen);
154 8 s->len -= len;
155 8 memmove(s->buffer + pos, s->buffer + pos + len, oldlen - pos - len);
156 }
157