dte test coverage


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 50.0% high: ≥ 85.0%
Coverage Exec / Excl / Total
Lines: 100.0% 79 / 0 / 79
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 244615 char *string_reserve_space(String *s, size_t more)
13 {
14 244615 BUG_ON(more == 0);
15 244615 size_t min_alloc = xadd(s->len, more);
16
2/2
✓ Branch 5 → 6 taken 72 times.
✓ Branch 5 → 9 taken 244543 times.
244615 if (unlikely(s->alloc < min_alloc)) {
17 72 s->alloc = string_next_alloc_size(s->alloc, min_alloc);
18 72 s->buffer = xrealloc(s->buffer, s->alloc);
19 }
20 244615 return s->buffer + s->len;
21 }
22
23 544 void string_free(String *s)
24 {
25 544 free(s->buffer);
26 544 *s = (String) STRING_INIT;
27 544 }
28
29 187899 void string_append_byte(String *s, unsigned char byte)
30 {
31 187899 string_reserve_space(s, 1);
32 187899 s->buffer[s->len++] = byte;
33 187899 }
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 void 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 == 0) {
63 return;
64 }
65 19 memcpy(string_make_space(s, pos, len), buf, len);
66 }
67
68 13874 void string_append_buf(String *s, const char *ptr, size_t len)
69 {
70
2/2
✓ Branch 2 → 3 taken 12081 times.
✓ Branch 2 → 5 taken 1793 times.
13874 if (len == 0) {
71 return;
72 }
73 12081 char *reserved = string_reserve_space(s, len);
74 12081 s->len += len;
75 12081 memcpy(reserved, ptr, len);
76 }
77
78 3 void string_append_memset(String *s, unsigned char byte, size_t len)
79 {
80
2/2
✓ Branch 2 → 3 taken 1 time.
✓ Branch 2 → 5 taken 2 times.
3 if (len == 0) {
81 return;
82 }
83 1 char *reserved = string_reserve_space(s, len);
84 1 s->len += len;
85 1 memset(reserved, byte, len);
86 }
87
88 VPRINTF(2)
89 7 static void string_vsprintf(String *s, const char *fmt, va_list ap)
90 {
91 7 va_list ap2;
92 7 va_copy(ap2, ap);
93 // Calculate the required size
94 7 int n = vsnprintf(NULL, 0, fmt, ap2);
95 7 va_end(ap2);
96 7 BUG_ON(n < 0);
97 7 string_reserve_space(s, n + 1);
98 7 int wrote = vsnprintf(s->buffer + s->len, n + 1, fmt, ap);
99 7 BUG_ON(wrote != n);
100 7 s->len += wrote;
101 7 }
102
103 7 void string_sprintf(String *s, const char *fmt, ...)
104 {
105 7 va_list ap;
106 7 va_start(ap, fmt);
107 7 string_vsprintf(s, fmt, ap);
108 7 va_end(ap);
109 7 }
110
111 42873 static char *null_terminate(String *s)
112 {
113 42873 string_reserve_space(s, 1);
114 42873 s->buffer[s->len] = '\0';
115 42873 return s->buffer;
116 }
117
118 33505 char *string_steal_cstring(String *s)
119 {
120 33505 char *buf = null_terminate(s);
121 33505 *s = (String) STRING_INIT;
122 33505 return buf;
123 }
124
125 91 char *string_clone_cstring(const String *s)
126 {
127 91 return xmemjoin(s->buffer, s->len, "", 1);
128 }
129
130 /*
131 * This method first ensures that the String buffer is null-terminated
132 * and then returns a const pointer to it, without doing any copying.
133 *
134 * NOTE: the returned pointer only remains valid so long as no other
135 * methods are called on the String. There are no exceptions to this
136 * rule. If the buffer is realloc'd, the pointer will be dangling and
137 * using it will invoke undefined behaviour. If unsure, just use
138 * string_clone_cstring() instead.
139 */
140 9368 const char *string_borrow_cstring(String *s)
141 {
142 9368 return null_terminate(s);
143 }
144
145 9 void string_remove(String *s, size_t pos, size_t len)
146 {
147
2/2
✓ Branch 2 → 3 taken 8 times.
✓ Branch 2 → 6 taken 1 time.
9 if (len == 0) {
148 return;
149 }
150 8 size_t oldlen = s->len;
151 8 BUG_ON(pos + len > oldlen);
152 8 s->len -= len;
153 8 memmove(s->buffer + pos, s->buffer + pos + len, oldlen - pos - len);
154 }
155