asar coverage - build #


src/asar/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
222 of 272, 0 excluded
81.6%
Functions:
16 of 18, 0 excluded
88.9%
Branches:
344 of 558, 0 excluded
61.6%

libstr.cpp
Line Branch Exec Source
1 #include "asar.h"
2 #include "virtualfile.h"
3 #include "unicode.h"
4 #include "libmisc.h"
5
6 #include "platform/file-helpers.h"
7
8 #define typed_malloc(type, count) (type*)malloc(sizeof(type)*(count))
9 #define typed_realloc(type, ptr, count) (type*)realloc(ptr, sizeof(type)*(count))
10
11
12 // This function is intentionally left out of the header file so that it is not visible to the
13 // compiler and less likely to be inlined into resize(). This in turn reduces the size of resize()
14 // so that it is then inlined in more places.
15 3709 void string::reallocate_capacity(unsigned int new_length)
16 {
17 // Allocate 1 extra byte for NUL terminator
18 3709 int new_alloc_capacity = bitround(new_length + 1);
19
20
4/4
✓ Branch 4 → 5 taken 1429 times.
✓ Branch 4 → 8 taken 138 times.
✓ Branch 5 → 6 taken 1996 times.
✓ Branch 5 → 13 taken 146 times.
3709 if (is_inlined()) {
21 3425 data_ptr = copy(data_ptr, min(len, new_length), (char*)malloc(new_alloc_capacity));
22 }
23 else {
24 284 data_ptr = (char*)realloc(data_ptr, new_alloc_capacity);
25 }
26 3709 allocated.capacity = new_alloc_capacity - 1; // capacity field doesn't count NUL terminator
27 3709 }
28
29
30 // Detects if str starts with a UTF-8 byte order mark.
31 // If so, throws a warning, then returns the number of bytes we should skip ahead in the string.
32 334 static size_t check_bom(const char* str)
33 {
34 // RPG Hacker: We could also check for BoMs of incompatible encodings here (like UTF-16)
35 // and throw errors, but not sure if that's worth adding. Asar never supported any wide
36 // encodings to begin with, so it's unreasonable to assume that any UTF-16 patches currently
37 // exist for it. As for future patches, those should be caught by the "must be UTF-8" checks
38 // I have already implemented further below.
39 // I think UTF-8 + BoM is the only case that could lead to confusion if we didn't handle it,
40 // so that's why I have added this.
41
7/11
✓ Branch 2 → 3 taken 1 time.
✓ Branch 2 → 7 taken 146 times.
✓ Branch 3 → 4 taken 2 times.
✗ Branch 3 → 7 not taken.
✓ Branch 3 → 12 taken 186 times.
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 7 not taken.
✓ Branch 6 → 7 taken 1 time.
✗ Branch 6 → 12 not taken.
✓ Branch 9 → 10 taken 1 time.
✗ Branch 9 → 12 not taken.
334 if (str[0u] == '\xEF' && str[1u] == '\xBB' && str[2u] == '\xBF')
42 {
43 2 throw_warning(0, warn_byte_order_mark_utf8);
44 2 return 3u;
45 }
46
47 332 return 0u;
48 }
49
50
51 340 char * readfile(const char * fname, const char * basepath)
52 {
53 340 virtual_file_handle myfile = filesystem->open_file(fname, basepath);
54
4/4
✓ Branch 3 → 4 taken 3 times.
✓ Branch 3 → 5 taken 148 times.
✓ Branch 4 → 5 taken 3 times.
✓ Branch 4 → 6 taken 186 times.
340 if (myfile == INVALID_VIRTUAL_FILE_HANDLE) return nullptr;
55 334 size_t datalen = filesystem->get_file_size(myfile);
56 334 char * data= typed_malloc(char, datalen+1);
57 334 data[filesystem->read_file(myfile, data, 0u, datalen)] = 0;
58 334 filesystem->close_file(myfile);
59
60
4/4
✓ Branch 9 → 10 taken 1 time.
✓ Branch 9 → 13 taken 147 times.
✓ Branch 15 → 16 taken 1 time.
✓ Branch 15 → 19 taken 185 times.
334 if (!is_valid_utf8(data, datalen))
61 {
62 2 free(data);
63 2 throw_err_block(0, err_invalid_utf8);
64 }
65
4/4
✓ Branch 14 → 15 taken 1 time.
✓ Branch 14 → 16 taken 146 times.
✓ Branch 20 → 21 taken 1 time.
✓ Branch 20 → 27 taken 184 times.
332 if(check_bom(data)){
66 2 data[0] = ' ';
67 2 data[1] = ' ';
68 2 data[2] = ' ';
69 }
70 332 return data;
71 }
72
73 // RPG Hacker: like readfile(), but doesn't use virtual file system
74 // and instead read our file directly.
75 8 char * readfilenative(const char * fname)
76 {
77 8 FileHandleType myfile = open_file(fname, FileOpenMode_Read);
78
2/2
✓ Branch 3 → 4 taken 6 times.
✓ Branch 3 → 5 taken 2 times.
8 if (myfile == InvalidFileHandle) return nullptr;
79 2 size_t datalen = (size_t)get_file_size(myfile);
80 2 char * data = typed_malloc(char, datalen + 1);
81 2 data[read_file(myfile, data, datalen)] = 0;
82 2 close_file(myfile);
83
84
1/4
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 13 not taken.
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 15 taken 2 times.
2 if (!is_valid_utf8(data, datalen)) throw_err_block(0, err_invalid_utf8);
85
1/4
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 16 not taken.
✗ Branch 16 → 17 not taken.
✓ Branch 16 → 23 taken 2 times.
2 if(check_bom(data)){
86 data[0] = ' ';
87 data[1] = ' ';
88 data[2] = ' ';
89 }
90 2 return data;
91 }
92
93 269 bool readfile(const char * fname, const char * basepath, char ** data, int * len)
94 {
95 269 virtual_file_handle myfile = filesystem->open_file(fname, basepath);
96
4/4
✓ Branch 3 → 4 taken 6 times.
✓ Branch 3 → 5 taken 118 times.
✓ Branch 4 → 5 taken 6 times.
✓ Branch 4 → 6 taken 139 times.
269 if (!myfile) return false;
97 257 size_t datalen = filesystem->get_file_size(myfile);
98 257 *data= typed_malloc(char, datalen);
99 257 *len = (int)filesystem->read_file(myfile, *data, 0, datalen);
100 257 filesystem->close_file(myfile);
101 257 return true;
102 }
103
104 #define isq(n) (((0x2227 ^ (0x0101 * (n))) - 0x0101UL) & ~(0x2227 ^ (0x0101 * (n))) & 0x8080UL)
105 #define isqp(n) (((0x22272829 ^ (0x01010101 * (n))) - 0x01010101UL) & ~(0x22272829 ^ (0x01010101 * (n))) & 0x80808080UL)
106
107 // RPG Hacker: Only index this with ASCII characters.
108 // Anything else doesn't make sense, anyways.
109 const bool qparlut[128] = {
110 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
112 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0,
113 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
114 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
115 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
116 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
117 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
118 };
119
120 //this will leave the last char found as the one pointed at
121 22284 inline bool skip_quote(char *&str)
122 {
123
124
5/6
✓ Branch 2 → 3 taken 344 times.
✓ Branch 2 → 4 taken 10245 times.
✓ Branch 4 → 5 taken 355 times.
✓ Branch 4 → 11 taken 11340 times.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 355 times.
22284 if(*str == '"') str = strchr(str + 1, '"');
125
4/4
✓ Branch 4 → 5 taken 54 times.
✓ Branch 4 → 10 taken 10191 times.
✓ Branch 13 → 14 taken 54 times.
✓ Branch 13 → 28 taken 11286 times.
21585 else if(*str == '\'')
126 {
127 54 int codepoint;
128
2/4
✓ Branch 5 → 6 taken 54 times.
✗ Branch 5 → 12 not taken.
✓ Branch 17 → 18 taken 54 times.
✗ Branch 17 → 31 not taken.
108 str += utf8_val(&codepoint, str + 1) + 1;
129
2/4
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 54 times.
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 25 taken 54 times.
108 if(*str != '\'') return false;
130 }
131 22284 return str;
132 }
133
134 //eat 1 char or quote/par
135 17104 inline bool skip_par(char *&str)
136 {
137 17104 int par = 0;
138
13/15
✓ Branch 2 → 3 taken 6 times.
✓ Branch 2 → 4 taken 8515 times.
✓ Branch 4 → 3 taken 98 times.
✓ Branch 4 → 5 taken 8423 times.
✓ Branch 4 → 6 taken 8577 times.
✓ Branch 5 → 3 taken 1083 times.
✓ Branch 5 → 6 taken 7334 times.
✗ Branch 6 → 3 not taken.
✓ Branch 6 → 7 taken 7334 times.
✓ Branch 8 → 5 taken 100 times.
✓ Branch 8 → 9 taken 8477 times.
✓ Branch 11 → 5 taken 1092 times.
✓ Branch 11 → 12 taken 7385 times.
✗ Branch 14 → 5 not taken.
✓ Branch 14 → 15 taken 7385 times.
17104 if(*str != '\'' && *str != '"' && *str != '(' && *str != ')')
139 {
140 14719 str++;
141 14719 return true;
142 }
143 while(true)
144 {
145 13883 char *t = str;
146
5/6
✓ Branch 8 → 9 taken 215 times.
✓ Branch 8 → 10 taken 6707 times.
✓ Branch 22 → 23 taken 223 times.
✓ Branch 22 → 27 taken 6738 times.
✗ Branch 24 → 25 not taken.
✓ Branch 24 → 26 taken 223 times.
13883 if(*str == '"') t = strchr(t + 1, '"');
147
4/4
✓ Branch 10 → 11 taken 6 times.
✓ Branch 10 → 16 taken 6701 times.
✓ Branch 29 → 30 taken 6 times.
✓ Branch 29 → 40 taken 6732 times.
13445 else if(*str == '\'')
148 {
149 6 int codepoint;
150
2/4
✓ Branch 11 → 12 taken 6 times.
✗ Branch 11 → 26 not taken.
✓ Branch 32 → 33 taken 6 times.
✗ Branch 32 → 56 not taken.
12 t += utf8_val(&codepoint, t + 1) + 1;
151
2/4
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 6 times.
✗ Branch 35 → 36 not taken.
✓ Branch 35 → 37 taken 6 times.
12 if(*t != '\'') return false;
152 }
153
4/4
✓ Branch 16 → 17 taken 1091 times.
✓ Branch 16 → 18 taken 5610 times.
✓ Branch 41 → 42 taken 1100 times.
✓ Branch 41 → 43 taken 5632 times.
13433 else if(*t == '(')
154 {
155 2191 par++;
156 }
157
4/4
✓ Branch 18 → 19 taken 1091 times.
✓ Branch 18 → 21 taken 4519 times.
✓ Branch 44 → 45 taken 1100 times.
✓ Branch 44 → 47 taken 4532 times.
11242 else if(*t == ')')
158 {
159 2191 par--;
160
2/4
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 21 taken 1091 times.
✗ Branch 45 → 46 not taken.
✓ Branch 45 → 47 taken 1100 times.
2191 if(par < 0) return false;
161 }
162
163 13883 str = t + 1;
164
8/8
✓ Branch 21 → 22 taken 6091 times.
✓ Branch 21 → 23 taken 831 times.
✓ Branch 22 → 23 taken 356 times.
✓ Branch 22 → 24 taken 5735 times.
✓ Branch 51 → 52 taken 6122 times.
✓ Branch 51 → 53 taken 839 times.
✓ Branch 52 → 53 taken 359 times.
✓ Branch 52 → 54 taken 5763 times.
13883 if(!*str || !par) return par == 0 ? true : false;
165 11498 }
166 }
167
168 //instr should not be duplicate chars. Instr should also not be 1 char
169 string& string::qreplace(const char * instr, const char * outstr)
170 {
171 string& thisstring =*this;
172 if (!strstr(thisstring, instr)) return thisstring;
173 int inlen = strlen(instr);
174 string out;
175 for (int i=0;thisstring[i];)
176 {
177 if (!strncmp((const char*)thisstring +i, instr, inlen))
178 {
179 out+=outstr;
180 i+=inlen;
181 }
182 // randomdude999: prevent appending the null terminator to the output
183 else if(!isq(thisstring[i])) out+= thisstring[i++];
184 else
185 {
186 char *start = raw() + i;
187 char *end = start;
188 if(!skip_quote(end)) return thisstring;
189 out.append(raw(), i, end - start + i + 1);
190 i += end - start + 1;
191
192 }
193 }
194 thisstring =out;
195 return thisstring;
196 }
197
198 // * convert tabs to spaces
199 // * collapse multiple consecutive spaces into one
200 // * delete spaces after comma
201 // in total, this means that after qnormalize, splitting by spaces will split the input into "words".
202 58283 string& string::qnormalize()
203 {
204 58283 string& thisstring =*this;
205 58283 string out;
206 58283 const char *startstr = thisstring.data();
207 58283 const char *str = startstr;
208
5/6
✓ Branch 34 → 5 taken 35562 times.
✓ Branch 34 → 35 taken 29005 times.
✗ Branch 54 → 55 not taken.
✓ Branch 54 → 56 taken 65257 times.
✓ Branch 56 → 8 taken 36009 times.
✓ Branch 56 → 57 taken 29248 times.
129824 while((str = strpbrk(str, "'\" \t,\r")))
209 {
210
4/4
✓ Branch 6 → 7 taken 25675 times.
✓ Branch 6 → 21 taken 9887 times.
✓ Branch 10 → 11 taken 26047 times.
✓ Branch 10 → 31 taken 9962 times.
71571 if(is_space(*str))
211 {
212
11/11
✓ Branch 7 → 8 taken 25669 times.
✓ Branch 7 → 11 taken 6 times.
✓ Branch 9 → 10 taken 25645 times.
✓ Branch 9 → 11 taken 24 times.
✓ Branch 12 → 13 taken 51686 times.
✓ Branch 12 → 14 taken 30 times.
✓ Branch 12 → 18 taken 6 times.
✓ Branch 16 → 17 taken 26017 times.
✓ Branch 16 → 18 taken 24 times.
✓ Branch 19 → 20 taken 26017 times.
✓ Branch 19 → 22 taken 30 times.
51722 if(str[0] == ' ' && !is_space(str[1]))
213 {
214 51662 str++;
215 51662 continue;
216 }
217
2/4
✓ Branch 14 → 15 taken 30 times.
✗ Branch 14 → 46 not taken.
✓ Branch 22 → 23 taken 30 times.
✗ Branch 22 → 74 not taken.
60 out.append(startstr, 0, str - startstr);
218
2/4
✓ Branch 15 → 16 taken 30 times.
✗ Branch 15 → 46 not taken.
✓ Branch 23 → 24 taken 30 times.
✗ Branch 23 → 74 not taken.
60 out += ' ';
219
4/4
✓ Branch 19 → 17 taken 96 times.
✓ Branch 19 → 20 taken 30 times.
✓ Branch 29 → 25 taken 96 times.
✓ Branch 29 → 30 taken 30 times.
252 while(is_space(*str)) str++;
220 60 startstr = str;
221
4/4
✓ Branch 21 → 22 taken 3143 times.
✓ Branch 21 → 30 taken 6744 times.
✓ Branch 32 → 33 taken 3194 times.
✓ Branch 32 → 45 taken 6768 times.
19849 }else if(*str == ',')
222 {
223 6337 str++;
224
4/4
✓ Branch 23 → 24 taken 941 times.
✓ Branch 23 → 33 taken 2202 times.
✓ Branch 36 → 37 taken 947 times.
✓ Branch 36 → 53 taken 2247 times.
6337 if(is_space(*str))
225 {
226
2/4
✓ Branch 24 → 25 taken 941 times.
✗ Branch 24 → 46 not taken.
✓ Branch 37 → 38 taken 947 times.
✗ Branch 37 → 74 not taken.
1888 out.append(startstr, 0, str - startstr);
227
4/4
✓ Branch 28 → 26 taken 962 times.
✓ Branch 28 → 29 taken 941 times.
✓ Branch 43 → 39 taken 968 times.
✓ Branch 43 → 44 taken 947 times.
3818 while(is_space(*str)) str++;
228 1888 startstr = str;
229 }
230 }
231 else
232 {
233
1/2
✗ Branch 47 → 48 not taken.
✓ Branch 47 → 49 taken 6768 times.
13512 str = strchr(str + 1, *str); //confirm quotes has already been run, so this should be okay
234
4/4
✓ Branch 30 → 31 taken 15 times.
✓ Branch 30 → 32 taken 6729 times.
✓ Branch 49 → 50 taken 15 times.
✓ Branch 49 → 51 taken 6753 times.
13512 if(!str) return thisstring;
235 13482 str++;
236 }
237 }
238
4/4
✓ Branch 36 → 37 taken 763 times.
✓ Branch 36 → 42 taken 28242 times.
✓ Branch 59 → 60 taken 769 times.
✓ Branch 59 → 70 taken 28479 times.
58253 if(startstr != thisstring.data())
239 {
240
2/4
✓ Branch 39 → 40 taken 763 times.
✗ Branch 39 → 46 not taken.
✓ Branch 65 → 66 taken 769 times.
✗ Branch 65 → 74 not taken.
1532 out.append(startstr, 0, (thisstring.data() + thisstring.length()) - startstr); //the remaining
241
242 1532 thisstring = std::move(out);
243 }
244 58253 return thisstring;
245 58283 }
246
247 69986 bool confirmquotes(const char * str)
248 {
249
4/4
✓ Branch 18 → 3 taken 24247 times.
✓ Branch 18 → 19 taken 17398 times.
✓ Branch 34 → 3 taken 24523 times.
✓ Branch 34 → 35 taken 17475 times.
83643 while(*str)
250 {
251
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 24523 times.
48770 char *dquote = strchr((char *)str, '"');
252
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 24523 times.
48770 char *squote = strchr((char *)str, '\'');
253
8/8
✓ Branch 3 → 4 taken 17880 times.
✓ Branch 3 → 5 taken 6367 times.
✓ Branch 4 → 5 taken 452 times.
✓ Branch 4 → 17 taken 17428 times.
✓ Branch 7 → 8 taken 18127 times.
✓ Branch 7 → 9 taken 6396 times.
✓ Branch 8 → 9 taken 452 times.
✓ Branch 8 → 32 taken 17675 times.
48770 if(dquote || squote)
254 {
255
12/12
✓ Branch 5 → 6 taken 6367 times.
✓ Branch 5 → 12 taken 452 times.
✓ Branch 6 → 7 taken 6319 times.
✓ Branch 6 → 8 taken 48 times.
✓ Branch 7 → 8 taken 6311 times.
✓ Branch 7 → 12 taken 8 times.
✓ Branch 9 → 10 taken 6396 times.
✓ Branch 9 → 20 taken 452 times.
✓ Branch 10 → 11 taken 6348 times.
✓ Branch 10 → 12 taken 48 times.
✓ Branch 11 → 12 taken 6340 times.
✓ Branch 11 → 20 taken 8 times.
13667 if(dquote && (dquote < squote || !squote))
256 {
257
1/2
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 15 taken 6388 times.
12747 dquote = strchr(dquote+1, '"');
258
4/4
✓ Branch 8 → 9 taken 6355 times.
✓ Branch 8 → 10 taken 4 times.
✓ Branch 15 → 16 taken 6384 times.
✓ Branch 15 → 18 taken 4 times.
12747 if(dquote) str = dquote+1;
259 8 else return false;
260 }
261 else
262 {
263 460 int codepoint;
264
2/4
✓ Branch 12 → 13 taken 460 times.
✗ Branch 12 → 21 not taken.
✓ Branch 22 → 23 taken 460 times.
✗ Branch 22 → 37 not taken.
920 squote += utf8_val(&codepoint, squote + 1) + 1;
265
4/4
✓ Branch 13 → 14 taken 459 times.
✓ Branch 13 → 15 taken 1 time.
✓ Branch 25 → 26 taken 459 times.
✓ Branch 25 → 28 taken 1 time.
920 if(*squote == '\'') str = squote+1;
266 2 else return false;
267 }
268 13657 }
269 else
270 {
271 35103 return true;
272 }
273 }
274 34873 return true;
275 }
276
277 710 bool confirmqpar(const char * str)
278 {
279 //todo fully optimize
280 710 int par = 0;
281
7/10
✗ Branch 4 → 3 not taken.
✓ Branch 4 → 5 taken 4810 times.
✓ Branch 5 → 3 taken 4455 times.
✓ Branch 5 → 6 taken 355 times.
✗ Branch 6 → 3 not taken.
✓ Branch 6 → 7 taken 4810 times.
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 4810 times.
✓ Branch 12 → 3 taken 4455 times.
✓ Branch 12 → 13 taken 355 times.
9620 while((unsigned char)*str >= 128 || !qparlut[(unsigned char)*str]) str++;
282
4/4
✓ Branch 21 → 7 taken 905 times.
✓ Branch 21 → 22 taken 355 times.
✓ Branch 53 → 14 taken 905 times.
✓ Branch 53 → 54 taken 355 times.
2520 while(*str)
283 {
284
4/4
✓ Branch 7 → 8 taken 183 times.
✓ Branch 7 → 10 taken 722 times.
✓ Branch 15 → 16 taken 183 times.
✓ Branch 15 → 22 taken 722 times.
1810 if(*str == '"')
285 {
286
1/2
✗ Branch 17 → 18 not taken.
✓ Branch 17 → 19 taken 183 times.
366 str = strchr(str + 1, '"');
287
2/4
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 17 taken 183 times.
✗ Branch 20 → 21 not taken.
✓ Branch 20 → 41 taken 183 times.
366 if(!str++) return false;
288 }
289
4/4
✓ Branch 10 → 11 taken 12 times.
✓ Branch 10 → 15 taken 710 times.
✓ Branch 23 → 24 taken 12 times.
✓ Branch 23 → 35 taken 710 times.
1444 else if(*str == '\'')
290 {
291 12 int codepoint;
292
2/4
✓ Branch 11 → 12 taken 12 times.
✗ Branch 11 → 24 not taken.
✓ Branch 26 → 27 taken 12 times.
✗ Branch 26 → 56 not taken.
24 str += utf8_val(&codepoint, str + 1) + 1;
293
2/4
✓ Branch 12 → 13 taken 12 times.
✗ Branch 12 → 14 not taken.
✓ Branch 29 → 30 taken 12 times.
✗ Branch 29 → 32 not taken.
24 if(*str == '\'') str++;
294 else return false;
295 }
296 else
297 {
298
1/2
✗ Branch 37 → 38 not taken.
✓ Branch 37 → 39 taken 710 times.
1420 par += 1 - ((*str++ - '(') << 1);
299
2/4
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 710 times.
✗ Branch 39 → 40 not taken.
✓ Branch 39 → 41 taken 710 times.
1420 if(par < 0) return false;
300 }
301
7/10
✗ Branch 19 → 18 not taken.
✓ Branch 19 → 20 taken 2265 times.
✓ Branch 20 → 18 taken 1360 times.
✓ Branch 20 → 21 taken 905 times.
✗ Branch 45 → 42 not taken.
✓ Branch 45 → 46 taken 2265 times.
✗ Branch 49 → 50 not taken.
✓ Branch 49 → 51 taken 2265 times.
✓ Branch 51 → 42 taken 1360 times.
✓ Branch 51 → 52 taken 905 times.
4530 while((unsigned char)*str >= 128 || !qparlut[(unsigned char)*str]) str++;
302 }
303 710 return !par;
304 }
305
306 12071 char ** split(char * str, char key, int * len)
307 {
308
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 6092 times.
12071 char *thisentry=strchr(str, key);
309
4/4
✓ Branch 2 → 3 taken 4517 times.
✓ Branch 2 → 6 taken 1462 times.
✓ Branch 4 → 5 taken 4598 times.
✓ Branch 4 → 12 taken 1494 times.
12071 if (!thisentry)
310 {
311 9115 char ** out= typed_malloc(char*, 2);
312 9115 out[0]=str;
313 9115 out[1]=nullptr;
314
4/4
✓ Branch 3 → 4 taken 2238 times.
✓ Branch 3 → 5 taken 2279 times.
✓ Branch 8 → 9 taken 2241 times.
✓ Branch 8 → 11 taken 2357 times.
9115 if (len) *len=1;
315 9115 return out;
316 }
317 2956 int count=15; //makes the default alloc 8 elements, sounds fair.
318 2956 char ** outdata= typed_malloc(char*, (size_t)count+1);
319
320 2956 int newcount=0;
321 2956 outdata[newcount++]=str;
322 do{
323 15298 *thisentry = 0;
324 15298 thisentry++;
325 15298 outdata[newcount++]=thisentry;
326
4/4
✓ Branch 7 → 8 taken 155 times.
✓ Branch 7 → 9 taken 7453 times.
✓ Branch 19 → 20 taken 155 times.
✓ Branch 19 → 21 taken 7535 times.
15298 if(newcount >= count)
327 {
328 310 count *= 2;
329 310 outdata = typed_realloc(char *, outdata, count);
330 }
331
5/6
✓ Branch 9 → 7 taken 6146 times.
✓ Branch 9 → 10 taken 1462 times.
✗ Branch 21 → 22 not taken.
✓ Branch 21 → 23 taken 7690 times.
✓ Branch 23 → 15 taken 6196 times.
✓ Branch 23 → 24 taken 1494 times.
15298 }while((thisentry = strchr(thisentry, key)));
332
333 2956 outdata[newcount]= nullptr;
334
4/4
✓ Branch 10 → 11 taken 1090 times.
✓ Branch 10 → 12 taken 372 times.
✓ Branch 26 → 27 taken 1090 times.
✓ Branch 26 → 29 taken 404 times.
2956 if (len) *len=newcount;
335 2956 return outdata;
336 }
337
338 12064 char ** qsplit(char * str, char key, int * len)
339 {
340
11/15
✓ Branch 2 → 3 taken 5770 times.
✓ Branch 2 → 4 taken 6072 times.
✓ Branch 2 → 5 taken 222 times.
✓ Branch 3 → 4 taken 5743 times.
✓ Branch 3 → 5 taken 27 times.
✓ Branch 4 → 5 taken 5845 times.
✗ Branch 4 → 9 not taken.
✓ Branch 4 → 10 taken 227 times.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 5845 times.
✓ Branch 7 → 8 taken 5818 times.
✗ Branch 7 → 9 not taken.
✓ Branch 7 → 10 taken 27 times.
✓ Branch 8 → 9 taken 5809 times.
✗ Branch 8 → 38 not taken.
12064 if (!strchr(str, '"') && !strchr(str, '\'')) return split(str, key, len);
341
342 503 int count=15;
343 503 char ** outdata= typed_malloc(char*, (size_t)count+1);
344 503 int newcount=0;
345 503 char * thisentry=str;
346 503 outdata[newcount++]=thisentry;
347
4/6
✓ Branch 14 → 6 taken 739 times.
✓ Branch 14 → 15 taken 249 times.
✗ Branch 28 → 13 not taken.
✗ Branch 28 → 29 not taken.
✓ Branch 29 → 14 taken 744 times.
✓ Branch 29 → 30 taken 254 times.
1986 while (*thisentry) /*todo fix*/
348 {
349
4/6
✓ Branch 6 → 7 taken 131 times.
✓ Branch 6 → 9 taken 608 times.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 21 not taken.
✓ Branch 15 → 16 taken 131 times.
✓ Branch 15 → 22 taken 613 times.
1483 if (*thisentry == key)
350 {
351 262 *thisentry=0;
352 262 thisentry++;
353 262 outdata[newcount++]=thisentry;
354
2/6
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 13 taken 131 times.
✗ Branch 19 → 20 not taken.
✗ Branch 19 → 26 not taken.
✗ Branch 20 → 21 not taken.
✓ Branch 20 → 27 taken 131 times.
262 if(newcount >= count)
355 {
356 count *= 2;
357 outdata = typed_realloc(char *, outdata, count);
358 }
359 }
360
4/11
✓ Branch 9 → 10 taken 608 times.
✗ Branch 9 → 20 not taken.
✓ Branch 10 → 11 taken 608 times.
✗ Branch 10 → 12 not taken.
✗ Branch 21 → 22 not taken.
✗ Branch 21 → 37 not taken.
✓ Branch 22 → 23 taken 613 times.
✗ Branch 22 → 25 not taken.
✗ Branch 22 → 38 not taken.
✓ Branch 23 → 24 taken 613 times.
✗ Branch 23 → 26 not taken.
1221 else if(skip_quote(thisentry)) thisentry++;
361 else return nullptr;
362 }
363 503 outdata[newcount]= nullptr;
364
4/6
✓ Branch 15 → 16 taken 75 times.
✓ Branch 15 → 17 taken 174 times.
✗ Branch 31 → 32 not taken.
✗ Branch 31 → 34 not taken.
✓ Branch 32 → 33 taken 75 times.
✓ Branch 32 → 35 taken 179 times.
503 if (len) *len=newcount;
365 503 return outdata;
366 }
367
368 57235 char ** qsplitstr(char * str, const char * key, int * len)
369 {
370 //check if the str is found first
371
6/7
✓ Branch 2 → 3 taken 28274 times.
✓ Branch 2 → 4 taken 28739 times.
✓ Branch 2 → 6 taken 222 times.
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 28739 times.
✓ Branch 6 → 7 taken 28457 times.
✓ Branch 6 → 14 taken 282 times.
57235 if (!strstr(str, key))
372 {
373 56731 char ** out= typed_malloc(char*, 2);
374 56731 out[0]=str;
375 56731 out[1]=nullptr;
376
2/4
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 28274 times.
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 13 taken 28457 times.
56731 if (len) *len=1;
377 56731 return out;
378 }
379
380
1/2
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 16 taken 282 times.
504 int keylen=(int)strlen(key);
381 504 int count=15;
382 504 char ** outdata= typed_malloc(char*, (size_t)count+1);
383 504 int newcount=0;
384 504 char * thisentry=str;
385 504 outdata[newcount++]=thisentry;
386
4/4
✓ Branch 15 → 7 taken 10884 times.
✓ Branch 15 → 16 taken 222 times.
✓ Branch 38 → 20 taken 12054 times.
✓ Branch 38 → 39 taken 282 times.
23442 while (*thisentry) /*todo fix*/
387 {
388
6/8
✓ Branch 7 → 8 taken 903 times.
✓ Branch 7 → 10 taken 9981 times.
✗ Branch 20 → 21 not taken.
✓ Branch 20 → 22 taken 12054 times.
✗ Branch 22 → 23 not taken.
✓ Branch 22 → 24 taken 12054 times.
✓ Branch 24 → 25 taken 972 times.
✓ Branch 24 → 31 taken 11082 times.
22938 if (!strncmp(thisentry, key, (size_t)keylen))
389 {
390 1875 *thisentry=0;
391 1875 thisentry+=keylen;
392 1875 outdata[newcount++]=thisentry;
393
2/4
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 14 taken 903 times.
✗ Branch 29 → 30 not taken.
✓ Branch 29 → 36 taken 972 times.
1875 if(newcount >= count)
394 {
395 count *= 2;
396 outdata = typed_realloc(char *, outdata, count);
397 }
398 }
399
4/8
✓ Branch 10 → 11 taken 9981 times.
✗ Branch 10 → 21 not taken.
✓ Branch 11 → 12 taken 9981 times.
✗ Branch 11 → 13 not taken.
✓ Branch 31 → 32 taken 11082 times.
✗ Branch 31 → 47 not taken.
✓ Branch 32 → 33 taken 11082 times.
✗ Branch 32 → 35 not taken.
21063 else if(skip_quote(thisentry)) thisentry++;
400 else return nullptr;
401 }
402 504 outdata[newcount]= nullptr;
403
2/4
✗ Branch 16 → 17 not taken.
✓ Branch 16 → 18 taken 222 times.
✗ Branch 41 → 42 not taken.
✓ Branch 41 → 44 taken 282 times.
504 if (len) *len=newcount;
404 504 return outdata;
405 }
406
407 //this function is most commonly called in cases where additional chars are very likely
408 12527 char ** qpsplit(char * str, char key, int * len)
409 {
410
9/14
✓ Branch 2 → 3 taken 5285 times.
✓ Branch 2 → 4 taken 6303 times.
✓ Branch 2 → 6 taken 939 times.
✓ Branch 3 → 4 taken 5285 times.
✗ Branch 3 → 6 not taken.
✓ Branch 4 → 5 taken 10647 times.
✓ Branch 4 → 10 taken 941 times.
✗ Branch 4 → 20 not taken.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 5362 times.
✓ Branch 7 → 8 taken 5362 times.
✗ Branch 7 → 10 not taken.
✓ Branch 8 → 9 taken 5362 times.
✗ Branch 8 → 36 not taken.
12527 if (!strchr(str, '(') && !strchr(str, ')')) return qsplit(str, key, len);
411 1880 int count=7;
412 1880 char ** outdata= typed_malloc(char*, (size_t)count+1);
413
414 1880 int newcount=0;
415 1880 char * thisentry=str;
416 1880 outdata[newcount++]=thisentry;
417
4/4
✓ Branch 14 → 7 taken 5462 times.
✓ Branch 14 → 15 taken 939 times.
✓ Branch 27 → 14 taken 5479 times.
✓ Branch 27 → 28 taken 941 times.
12821 while (*thisentry)
418 {
419 //skippar(*thisentry, thisentry++, return nullptr;)
420
4/4
✓ Branch 7 → 8 taken 364 times.
✓ Branch 7 → 10 taken 5098 times.
✓ Branch 15 → 16 taken 367 times.
✓ Branch 15 → 22 taken 5112 times.
10941 if (*thisentry == key)
421 {
422 731 *thisentry=0;
423 731 thisentry++;
424 731 outdata[newcount++]=thisentry;
425
4/4
✓ Branch 8 → 9 taken 1 time.
✓ Branch 8 → 13 taken 363 times.
✓ Branch 20 → 21 taken 1 time.
✓ Branch 20 → 25 taken 366 times.
731 if(newcount >= count)
426 {
427 2 count *= 2;
428 2 outdata = typed_realloc(char *, outdata, count);
429 }
430 }
431
4/8
✓ Branch 10 → 11 taken 5098 times.
✗ Branch 10 → 20 not taken.
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 13 taken 5098 times.
✓ Branch 22 → 23 taken 5112 times.
✗ Branch 22 → 36 not taken.
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 25 taken 5112 times.
10210 else if(!skip_par(thisentry)) return nullptr;
432 }
433 1880 outdata[newcount]= nullptr;
434
4/4
✓ Branch 15 → 16 taken 453 times.
✓ Branch 15 → 17 taken 486 times.
✓ Branch 30 → 31 taken 453 times.
✓ Branch 30 → 33 taken 488 times.
1880 if (len) *len=newcount;
435 1880 return outdata;
436 }
437
438 string &itrim(string &input, const char * left, const char * right)
439 {
440 bool nukeright=true;
441 int totallen=input.length();
442 int rightlen=(int)strlen(right);
443 if (rightlen && rightlen<=totallen)
444 {
445 const char * rightend=right+rightlen;
446 const char * strend=input.data()+totallen;
447 while (right!=rightend)
448 {
449 rightend--;
450 strend--;
451 if (to_lower(*strend)!=to_lower(*rightend)) nukeright=false;
452 }
453 if (nukeright)
454 {
455 totallen-=rightlen;
456 input.truncate(totallen);
457 }
458 }
459 bool nukeleft=true;
460 int leftlen = strlen(left);
461 if(leftlen == 1 && input.data()[0] == left[0])
462 {
463 return input = string(input.data()+1, (input.length()-1));
464 }
465 else
466 {
467 for (int i = 0; i < leftlen; i++)
468 {
469 if (to_lower(input.data()[i])!=to_lower(left[i])) nukeleft=false;
470 }
471 if (nukeleft) input = string(input.data()+leftlen, (input.length()-leftlen));
472 }
473 return input;
474 }
475
476 1056 char* strqpchr(char* str, char key)
477 {
478
4/4
✓ Branch 9 → 3 taken 3600 times.
✓ Branch 9 → 10 taken 168 times.
✓ Branch 11 → 3 taken 3648 times.
✓ Branch 11 → 12 taken 174 times.
7590 while (*str)
479 {
480
4/4
✓ Branch 3 → 4 taken 357 times.
✓ Branch 3 → 5 taken 3243 times.
✓ Branch 4 → 5 taken 357 times.
✓ Branch 4 → 6 taken 3291 times.
7248 if (*str == key) return str;
481
2/4
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 3243 times.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 3291 times.
6534 else if(!skip_par(str)) return nullptr;
482 }
483 342 return nullptr;
484 }
485
486 114 char* strqpstr(char* str, const char* key)
487 {
488
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 57 times.
114 size_t keylen = strlen(key);
489
4/4
✓ Branch 8 → 3 taken 234 times.
✓ Branch 8 → 9 taken 3 times.
✓ Branch 15 → 5 taken 234 times.
✓ Branch 15 → 16 taken 3 times.
474 while (*str)
490 {
491
6/8
✓ Branch 3 → 4 taken 54 times.
✓ Branch 3 → 5 taken 180 times.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 234 times.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 234 times.
✓ Branch 9 → 10 taken 54 times.
✓ Branch 9 → 11 taken 180 times.
468 if (!strncmp(str, key, keylen)) return str;
492
2/4
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 180 times.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 180 times.
360 else if(!skip_par(str)) return nullptr;
493 }
494 6 return nullptr;
495 }
496
497 extern const uint8_t char_props[256] = {
498 //x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF
499 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x00,0x00, // 0x
500 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 1x
501 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 2x !"#$%&'()*+,-./
502 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x00,0x00,0x00,0x00,0x00,0x00, // 3x 0123456789:;<=>?
503 0x00,0x23,0x23,0x23,0x23,0x23,0x23,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, // 4x @ABCDEFGHIJKLMNO
504 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x00,0x00,0x00,0x00,0x08, // 5x PQRSTUVWXYZ[\]^_
505 0x00,0x25,0x25,0x25,0x25,0x25,0x25,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24, // 6x `abcdefghijklmno
506 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x00,0x00,0x00,0x00,0x00, // 7x pqrstuvwxyz{|}~
507 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 8x
508 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 9x
509 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Ax
510 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Bx
511 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Cx
512 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Dx
513 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Ex
514 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Fx
515 };
516