asar coverage - build #


src/asar/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
219 of 272, 0 excluded
80.5%
Functions:
16 of 18, 0 excluded
88.9%
Branches:
340 of 558, 0 excluded
60.9%

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 3626 void string::reallocate_capacity(unsigned int new_length)
16 {
17 // Allocate 1 extra byte for NUL terminator
18 3626 int new_alloc_capacity = bitround(new_length + 1);
19
20
4/4
✓ Branch 4 → 5 taken 1382 times.
✓ Branch 4 → 8 taken 138 times.
✓ Branch 5 → 6 taken 1960 times.
✓ Branch 5 → 13 taken 146 times.
3626 if (is_inlined()) {
21 3342 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 3626 allocated.capacity = new_alloc_capacity - 1; // capacity field doesn't count NUL terminator
27 3626 }
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 336 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 147 times.
✓ Branch 3 → 4 taken 2 times.
✗ Branch 3 → 7 not taken.
✓ Branch 3 → 12 taken 187 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.
336 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 334 return 0u;
48 }
49
50
51 342 char * readfile(const char * fname, const char * basepath)
52 {
53 342 virtual_file_handle myfile = filesystem->open_file(fname, basepath);
54
4/4
✓ Branch 3 → 4 taken 3 times.
✓ Branch 3 → 5 taken 149 times.
✓ Branch 4 → 5 taken 3 times.
✓ Branch 4 → 6 taken 187 times.
342 if (myfile == INVALID_VIRTUAL_FILE_HANDLE) return nullptr;
55 336 size_t datalen = filesystem->get_file_size(myfile);
56 336 char * data= typed_malloc(char, datalen+1);
57 336 data[filesystem->read_file(myfile, data, 0u, datalen)] = 0;
58 336 filesystem->close_file(myfile);
59
60
4/4
✓ Branch 9 → 10 taken 1 time.
✓ Branch 9 → 13 taken 148 times.
✓ Branch 15 → 16 taken 1 time.
✓ Branch 15 → 19 taken 186 times.
336 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 147 times.
✓ Branch 20 → 21 taken 1 time.
✓ Branch 20 → 27 taken 185 times.
334 if(check_bom(data)){
66 2 data[0] = ' ';
67 2 data[1] = ' ';
68 2 data[2] = ' ';
69 }
70 334 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 271 bool readfile(const char * fname, const char * basepath, char ** data, int * len)
94 {
95 271 virtual_file_handle myfile = filesystem->open_file(fname, basepath);
96
4/4
✓ Branch 3 → 4 taken 6 times.
✓ Branch 3 → 5 taken 119 times.
✓ Branch 4 → 5 taken 6 times.
✓ Branch 4 → 6 taken 140 times.
271 if (!myfile) return false;
97 259 size_t datalen = filesystem->get_file_size(myfile);
98 259 *data= typed_malloc(char, datalen);
99 259 *len = (int)filesystem->read_file(myfile, *data, 0, datalen);
100 259 filesystem->close_file(myfile);
101 259 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 17140 inline bool skip_par(char *&str)
136 {
137 17140 int par = 0;
138
13/15
✓ Branch 2 → 3 taken 6 times.
✓ Branch 2 → 4 taken 8533 times.
✓ Branch 4 → 3 taken 98 times.
✓ Branch 4 → 5 taken 8441 times.
✓ Branch 4 → 6 taken 8595 times.
✓ Branch 5 → 3 taken 1086 times.
✓ Branch 5 → 6 taken 7349 times.
✗ Branch 6 → 3 not taken.
✓ Branch 6 → 7 taken 7349 times.
✓ Branch 8 → 5 taken 100 times.
✓ Branch 8 → 9 taken 8495 times.
✓ Branch 11 → 5 taken 1095 times.
✓ Branch 11 → 12 taken 7400 times.
✗ Branch 14 → 5 not taken.
✓ Branch 14 → 15 taken 7400 times.
17140 if(*str != '\'' && *str != '"' && *str != '(' && *str != ')')
139 {
140 14749 str++;
141 14749 return true;
142 }
143 while(true)
144 {
145 13973 char *t = str;
146
5/6
✓ Branch 8 → 9 taken 218 times.
✓ Branch 8 → 10 taken 6749 times.
✓ Branch 22 → 23 taken 226 times.
✓ Branch 22 → 27 taken 6780 times.
✗ Branch 24 → 25 not taken.
✓ Branch 24 → 26 taken 226 times.
13973 if(*str == '"') t = strchr(t + 1, '"');
147
4/4
✓ Branch 10 → 11 taken 6 times.
✓ Branch 10 → 16 taken 6743 times.
✓ Branch 29 → 30 taken 6 times.
✓ Branch 29 → 40 taken 6774 times.
13529 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 1097 times.
✓ Branch 16 → 18 taken 5646 times.
✓ Branch 41 → 42 taken 1106 times.
✓ Branch 41 → 43 taken 5668 times.
13517 else if(*t == '(')
154 {
155 2203 par++;
156 }
157
4/4
✓ Branch 18 → 19 taken 1097 times.
✓ Branch 18 → 21 taken 4549 times.
✓ Branch 44 → 45 taken 1106 times.
✓ Branch 44 → 47 taken 4562 times.
11314 else if(*t == ')')
158 {
159 2203 par--;
160
2/4
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 21 taken 1097 times.
✗ Branch 45 → 46 not taken.
✓ Branch 45 → 47 taken 1106 times.
2203 if(par < 0) return false;
161 }
162
163 13973 str = t + 1;
164
8/8
✓ Branch 21 → 22 taken 6133 times.
✓ Branch 21 → 23 taken 834 times.
✓ Branch 22 → 23 taken 356 times.
✓ Branch 22 → 24 taken 5777 times.
✓ Branch 51 → 52 taken 6164 times.
✓ Branch 51 → 53 taken 842 times.
✓ Branch 52 → 53 taken 359 times.
✓ Branch 52 → 54 taken 5805 times.
13973 if(!*str || !par) return par == 0 ? true : false;
165 11582 }
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 42657 string& string::qnormalize()
203 {
204 42657 string& thisstring =*this;
205 42657 string out;
206 42657 const char *startstr = thisstring.data();
207 42657 const char *str = startstr;
208
5/6
✓ Branch 34 → 5 taken 35778 times.
✓ Branch 34 → 35 taken 21213 times.
✗ Branch 54 → 55 not taken.
✓ Branch 54 → 56 taken 57639 times.
✓ Branch 56 → 8 taken 36225 times.
✓ Branch 56 → 57 taken 21414 times.
114630 while((str = strpbrk(str, "'\" \t,\r")))
209 {
210
4/4
✓ Branch 6 → 7 taken 25774 times.
✓ Branch 6 → 21 taken 10004 times.
✓ Branch 10 → 11 taken 26146 times.
✓ Branch 10 → 31 taken 10079 times.
72003 if(is_space(*str))
211 {
212
11/11
✓ Branch 7 → 8 taken 25768 times.
✓ Branch 7 → 11 taken 6 times.
✓ Branch 9 → 10 taken 25738 times.
✓ Branch 9 → 11 taken 30 times.
✓ Branch 12 → 13 taken 51878 times.
✓ Branch 12 → 14 taken 36 times.
✓ Branch 12 → 18 taken 6 times.
✓ Branch 16 → 17 taken 26110 times.
✓ Branch 16 → 18 taken 30 times.
✓ Branch 19 → 20 taken 26110 times.
✓ Branch 19 → 22 taken 36 times.
51920 if(str[0] == ' ' && !is_space(str[1]))
213 {
214 51848 str++;
215 51848 continue;
216 }
217
2/4
✓ Branch 14 → 15 taken 36 times.
✗ Branch 14 → 46 not taken.
✓ Branch 22 → 23 taken 36 times.
✗ Branch 22 → 74 not taken.
72 out.append(startstr, 0, str - startstr);
218
2/4
✓ Branch 15 → 16 taken 36 times.
✗ Branch 15 → 46 not taken.
✓ Branch 23 → 24 taken 36 times.
✗ Branch 23 → 74 not taken.
72 out += ' ';
219
4/4
✓ Branch 19 → 17 taken 195 times.
✓ Branch 19 → 20 taken 36 times.
✓ Branch 29 → 25 taken 195 times.
✓ Branch 29 → 30 taken 36 times.
462 while(is_space(*str)) str++;
220 72 startstr = str;
221
4/4
✓ Branch 21 → 22 taken 3227 times.
✓ Branch 21 → 30 taken 6777 times.
✓ Branch 32 → 33 taken 3278 times.
✓ Branch 32 → 45 taken 6801 times.
20083 }else if(*str == ',')
222 {
223 6505 str++;
224
4/4
✓ Branch 23 → 24 taken 968 times.
✓ Branch 23 → 33 taken 2259 times.
✓ Branch 36 → 37 taken 974 times.
✓ Branch 36 → 53 taken 2304 times.
6505 if(is_space(*str))
225 {
226
2/4
✓ Branch 24 → 25 taken 968 times.
✗ Branch 24 → 46 not taken.
✓ Branch 37 → 38 taken 974 times.
✗ Branch 37 → 74 not taken.
1942 out.append(startstr, 0, str - startstr);
227
4/4
✓ Branch 28 → 26 taken 1004 times.
✓ Branch 28 → 29 taken 968 times.
✓ Branch 43 → 39 taken 1010 times.
✓ Branch 43 → 44 taken 974 times.
3956 while(is_space(*str)) str++;
228 1942 startstr = str;
229 }
230 }
231 else
232 {
233
1/2
✗ Branch 47 → 48 not taken.
✓ Branch 47 → 49 taken 6801 times.
13578 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 6762 times.
✓ Branch 49 → 50 taken 15 times.
✓ Branch 49 → 51 taken 6786 times.
13578 if(!str) return thisstring;
235 13548 str++;
236 }
237 }
238
4/4
✓ Branch 36 → 37 taken 784 times.
✓ Branch 36 → 42 taken 20429 times.
✓ Branch 59 → 60 taken 790 times.
✓ Branch 59 → 70 taken 20624 times.
42627 if(startstr != thisstring.data())
239 {
240
2/4
✓ Branch 39 → 40 taken 784 times.
✗ Branch 39 → 46 not taken.
✓ Branch 65 → 66 taken 790 times.
✗ Branch 65 → 74 not taken.
1574 out.append(startstr, 0, (thisstring.data() + thisstring.length()) - startstr); //the remaining
241
242 1574 thisstring = std::move(out);
243 }
244 42627 return thisstring;
245 42657 }
246
247 41897 bool confirmquotes(const char * str)
248 {
249
4/4
✓ Branch 18 → 3 taken 20350 times.
✓ Branch 18 → 19 taken 6956 times.
✓ Branch 34 → 3 taken 20551 times.
✓ Branch 34 → 35 taken 6977 times.
54834 while(*str)
250 {
251
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 20551 times.
40901 char *dquote = strchr((char *)str, '"');
252
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 20551 times.
40901 char *squote = strchr((char *)str, '\'');
253
8/8
✓ Branch 3 → 4 taken 14264 times.
✓ Branch 3 → 5 taken 6086 times.
✓ Branch 4 → 5 taken 375 times.
✓ Branch 4 → 17 taken 13889 times.
✓ Branch 7 → 8 taken 14444 times.
✓ Branch 7 → 9 taken 6107 times.
✓ Branch 8 → 9 taken 375 times.
✓ Branch 8 → 32 taken 14069 times.
40901 if(dquote || squote)
254 {
255
12/12
✓ Branch 5 → 6 taken 6086 times.
✓ Branch 5 → 12 taken 375 times.
✓ Branch 6 → 7 taken 6050 times.
✓ Branch 6 → 8 taken 36 times.
✓ Branch 7 → 8 taken 6044 times.
✓ Branch 7 → 12 taken 6 times.
✓ Branch 9 → 10 taken 6107 times.
✓ Branch 9 → 20 taken 375 times.
✓ Branch 10 → 11 taken 6071 times.
✓ Branch 10 → 12 taken 36 times.
✓ Branch 11 → 12 taken 6065 times.
✓ Branch 11 → 20 taken 6 times.
12943 if(dquote && (dquote < squote || !squote))
256 {
257
1/2
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 15 taken 6101 times.
12181 dquote = strchr(dquote+1, '"');
258
4/4
✓ Branch 8 → 9 taken 6077 times.
✓ Branch 8 → 10 taken 3 times.
✓ Branch 15 → 16 taken 6098 times.
✓ Branch 15 → 18 taken 3 times.
12181 if(dquote) str = dquote+1;
259 6 else return false;
260 }
261 else
262 {
263 381 int codepoint;
264
2/4
✓ Branch 12 → 13 taken 381 times.
✗ Branch 12 → 21 not taken.
✓ Branch 22 → 23 taken 381 times.
✗ Branch 22 → 37 not taken.
762 squote += utf8_val(&codepoint, squote + 1) + 1;
265
2/4
✓ Branch 13 → 14 taken 381 times.
✗ Branch 13 → 15 not taken.
✓ Branch 25 → 26 taken 381 times.
✗ Branch 25 → 28 not taken.
762 if(*squote == '\'') str = squote+1;
266 else return false;
267 }
268 12937 }
269 else
270 {
271 27958 return true;
272 }
273 }
274 13933 return true;
275 }
276
277 728 bool confirmqpar(const char * str)
278 {
279 //todo fully optimize
280 728 int par = 0;
281
7/10
✗ Branch 4 → 3 not taken.
✓ Branch 4 → 5 taken 4888 times.
✓ Branch 5 → 3 taken 4524 times.
✓ Branch 5 → 6 taken 364 times.
✗ Branch 6 → 3 not taken.
✓ Branch 6 → 7 taken 4888 times.
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 4888 times.
✓ Branch 12 → 3 taken 4524 times.
✓ Branch 12 → 13 taken 364 times.
9776 while((unsigned char)*str >= 128 || !qparlut[(unsigned char)*str]) str++;
282
4/4
✓ Branch 21 → 7 taken 923 times.
✓ Branch 21 → 22 taken 364 times.
✓ Branch 53 → 14 taken 923 times.
✓ Branch 53 → 54 taken 364 times.
2574 while(*str)
283 {
284
4/4
✓ Branch 7 → 8 taken 183 times.
✓ Branch 7 → 10 taken 740 times.
✓ Branch 15 → 16 taken 183 times.
✓ Branch 15 → 22 taken 740 times.
1846 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 728 times.
✓ Branch 23 → 24 taken 12 times.
✓ Branch 23 → 35 taken 728 times.
1480 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 728 times.
1456 par += 1 - ((*str++ - '(') << 1);
299
2/4
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 728 times.
✗ Branch 39 → 40 not taken.
✓ Branch 39 → 41 taken 728 times.
1456 if(par < 0) return false;
300 }
301
7/10
✗ Branch 19 → 18 not taken.
✓ Branch 19 → 20 taken 2307 times.
✓ Branch 20 → 18 taken 1384 times.
✓ Branch 20 → 21 taken 923 times.
✗ Branch 45 → 42 not taken.
✓ Branch 45 → 46 taken 2307 times.
✗ Branch 49 → 50 not taken.
✓ Branch 49 → 51 taken 2307 times.
✓ Branch 51 → 42 taken 1384 times.
✓ Branch 51 → 52 taken 923 times.
4614 while((unsigned char)*str >= 128 || !qparlut[(unsigned char)*str]) str++;
302 }
303 728 return !par;
304 }
305
306 11781 char ** split(char * str, char key, int * len)
307 {
308
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 5928 times.
11781 char *thisentry=strchr(str, key);
309
4/4
✓ Branch 2 → 3 taken 4532 times.
✓ Branch 2 → 6 taken 1321 times.
✓ Branch 4 → 5 taken 4589 times.
✓ Branch 4 → 12 taken 1339 times.
11781 if (!thisentry)
310 {
311 9121 char ** out= typed_malloc(char*, 2);
312 9121 out[0]=str;
313 9121 out[1]=nullptr;
314
4/4
✓ Branch 3 → 4 taken 2253 times.
✓ Branch 3 → 5 taken 2279 times.
✓ Branch 8 → 9 taken 2256 times.
✓ Branch 8 → 11 taken 2333 times.
9121 if (len) *len=1;
315 9121 return out;
316 }
317 2660 int count=15; //makes the default alloc 8 elements, sounds fair.
318 2660 char ** outdata= typed_malloc(char*, (size_t)count+1);
319
320 2660 int newcount=0;
321 2660 outdata[newcount++]=str;
322 do{
323 3197 *thisentry = 0;
324 3197 thisentry++;
325 3197 outdata[newcount++]=thisentry;
326
2/4
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 1579 times.
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 21 taken 1618 times.
3197 if(newcount >= count)
327 {
328 count *= 2;
329 outdata = typed_realloc(char *, outdata, count);
330 }
331
5/6
✓ Branch 9 → 7 taken 258 times.
✓ Branch 9 → 10 taken 1321 times.
✗ Branch 21 → 22 not taken.
✓ Branch 21 → 23 taken 1618 times.
✓ Branch 23 → 15 taken 279 times.
✓ Branch 23 → 24 taken 1339 times.
3197 }while((thisentry = strchr(thisentry, key)));
332
333 2660 outdata[newcount]= nullptr;
334
4/4
✓ Branch 10 → 11 taken 1096 times.
✓ Branch 10 → 12 taken 225 times.
✓ Branch 26 → 27 taken 1096 times.
✓ Branch 26 → 29 taken 243 times.
2660 if (len) *len=newcount;
335 2660 return outdata;
336 }
337
338 12088 char ** qsplit(char * str, char key, int * len)
339 {
340
11/15
✓ Branch 2 → 3 taken 5782 times.
✓ Branch 2 → 4 taken 6084 times.
✓ Branch 2 → 5 taken 222 times.
✓ Branch 3 → 4 taken 5755 times.
✓ Branch 3 → 5 taken 27 times.
✓ Branch 4 → 5 taken 5857 times.
✗ Branch 4 → 9 not taken.
✓ Branch 4 → 10 taken 227 times.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 5857 times.
✓ Branch 7 → 8 taken 5830 times.
✗ Branch 7 → 9 not taken.
✓ Branch 7 → 10 taken 27 times.
✓ Branch 8 → 9 taken 5821 times.
✗ Branch 8 → 38 not taken.
12088 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 41735 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 20545 times.
✓ Branch 2 → 4 taken 20968 times.
✓ Branch 2 → 6 taken 222 times.
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 20968 times.
✓ Branch 6 → 7 taken 20686 times.
✓ Branch 6 → 14 taken 282 times.
41735 if (!strstr(str, key))
372 {
373 41231 char ** out= typed_malloc(char*, 2);
374 41231 out[0]=str;
375 41231 out[1]=nullptr;
376
2/4
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 20545 times.
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 13 taken 20686 times.
41231 if (len) *len=1;
377 41231 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 1062 char* strqpchr(char* str, char key)
477 {
478
4/4
✓ Branch 9 → 3 taken 3618 times.
✓ Branch 9 → 10 taken 171 times.
✓ Branch 11 → 3 taken 3666 times.
✓ Branch 11 → 12 taken 177 times.
7632 while (*str)
479 {
480
4/4
✓ Branch 3 → 4 taken 357 times.
✓ Branch 3 → 5 taken 3261 times.
✓ Branch 4 → 5 taken 357 times.
✓ Branch 4 → 6 taken 3309 times.
7284 if (*str == key) return str;
481
2/4
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 3261 times.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 3309 times.
6570 else if(!skip_par(str)) return nullptr;
482 }
483 348 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