asar coverage - build #289


src/asar/
File: src/asar/libstr.cpp
Date: 2025-03-10 00:43:19
Lines:
222/272
81.6%
Functions:
16/18
88.9%
Branches:
254/393
64.6%

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 3303 void string::reallocate_capacity(unsigned int new_length)
16 {
17 // Allocate 1 extra byte for NUL terminator
18 3303 int new_alloc_capacity = bitround(new_length + 1);
19
20
3/3
✓ Branch 0 taken 1431 times.
✓ Branch 1 taken 1762 times.
✓ Branch 2 taken 110 times.
3303 if (is_inlined()) {
21 3119 data_ptr = copy(data_ptr, min(len, new_length), (char*)malloc(new_alloc_capacity));
22 }
23 else {
24 184 data_ptr = (char*)realloc(data_ptr, new_alloc_capacity);
25 }
26 3303 allocated.capacity = new_alloc_capacity - 1; // capacity field doesn't count NUL terminator
27 3303 }
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 329 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
6/9
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 144 times.
✓ Branch 2 taken 185 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
329 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 327 return 0u;
48 }
49
50
51 335 char * readfile(const char * fname, const char * basepath)
52 {
53 335 virtual_file_handle myfile = filesystem->open_file(fname, basepath);
54
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 329 times.
335 if (myfile == INVALID_VIRTUAL_FILE_HANDLE) return nullptr;
55 329 size_t datalen = filesystem->get_file_size(myfile);
56 329 char * data= typed_malloc(char, datalen+1);
57 329 data[filesystem->read_file(myfile, data, 0u, datalen)] = 0;
58 329 filesystem->close_file(myfile);
59
60
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 327 times.
329 if (!is_valid_utf8(data, datalen))
61 {
62 2 free(data);
63 2 throw_err_block(0, err_invalid_utf8);
64 }
65
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 325 times.
327 if(check_bom(data)){
66 2 data[0] = ' ';
67 2 data[1] = ' ';
68 2 data[2] = ' ';
69 }
70 327 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 0 taken 6 times.
✓ Branch 1 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/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!is_valid_utf8(data, datalen)) throw_err_block(0, err_invalid_utf8);
85
1/2
✗ Branch 0 not taken.
✓ Branch 1 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 266 bool readfile(const char * fname, const char * basepath, char ** data, int * len)
94 {
95 266 virtual_file_handle myfile = filesystem->open_file(fname, basepath);
96
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 254 times.
266 if (!myfile) return false;
97 254 size_t datalen = filesystem->get_file_size(myfile);
98 254 *data= typed_malloc(char, datalen);
99 254 *len = (int)filesystem->read_file(myfile, *data, 0, datalen);
100 254 filesystem->close_file(myfile);
101 254 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 22208 inline bool skip_quote(char *&str)
122 {
123
124
5/6
✓ Branch 0 taken 344 times.
✓ Branch 1 taken 10206 times.
✓ Branch 2 taken 357 times.
✓ Branch 3 taken 11301 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 357 times.
22208 if(*str == '"') str = strchr(str + 1, '"');
125
4/4
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 10152 times.
✓ Branch 2 taken 54 times.
✓ Branch 3 taken 11247 times.
21507 else if(*str == '\'')
126 {
127 54 int codepoint;
128
2/4
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 54 times.
✗ Branch 3 not taken.
108 str += utf8_val(&codepoint, str + 1) + 1;
129
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 54 times.
108 if(*str != '\'') return false;
130 }
131 22208 return str;
132 }
133
134 //eat 1 char or quote/par
135 13420 inline bool skip_par(char *&str)
136 {
137 13420 int par = 0;
138
11/12
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6673 times.
✓ Branch 2 taken 95 times.
✓ Branch 3 taken 13319 times.
✓ Branch 4 taken 1068 times.
✓ Branch 5 taken 5516 times.
✓ Branch 6 taken 91 times.
✓ Branch 7 taken 12160 times.
✓ Branch 8 taken 1077 times.
✓ Branch 9 taken 5567 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 5567 times.
13420 if(*str != '\'' && *str != '"' && *str != '(' && *str != ')')
139 {
140 11083 str++;
141 11083 return true;
142 }
143 while(true)
144 {
145 13655 char *t = str;
146
5/6
✓ Branch 0 taken 191 times.
✓ Branch 1 taken 6617 times.
✓ Branch 2 taken 199 times.
✓ Branch 3 taken 6648 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 199 times.
13655 if(*str == '"') t = strchr(t + 1, '"');
147
4/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6611 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6642 times.
13265 else if(*str == '\'')
148 {
149 6 int codepoint;
150
2/3
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
12 t += utf8_val(&codepoint, t + 1) + 1;
151
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
12 if(*t != '\'') return false;
152 }
153
3/3
✓ Branch 0 taken 1076 times.
✓ Branch 1 taken 6620 times.
✓ Branch 2 taken 5557 times.
13253 else if(*t == '(')
154 {
155 2161 par++;
156 }
157
3/3
✓ Branch 0 taken 1076 times.
✓ Branch 1 taken 5544 times.
✓ Branch 2 taken 4472 times.
11092 else if(*t == ')')
158 {
159 2161 par--;
160
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2161 times.
2161 if(par < 0) return false;
161 }
162
163 13655 str = t + 1;
164
6/6
✓ Branch 0 taken 5986 times.
✓ Branch 1 taken 822 times.
✓ Branch 2 taken 6358 times.
✓ Branch 3 taken 6475 times.
✓ Branch 4 taken 344 times.
✓ Branch 5 taken 5673 times.
13655 if(!*str || !par) return par == 0 ? true : false;
165 11318 }
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 56437 string& string::qnormalize()
199 {
200 56437 string& thisstring =*this;
201 56437 string out;
202 56437 const char *startstr = thisstring.data();
203 56437 const char *str = startstr;
204
4/4
✓ Branch 0 taken 35352 times.
✓ Branch 1 taken 92263 times.
✓ Branch 2 taken 35856 times.
✓ Branch 3 taken 28368 times.
127615 while((str = strpbrk(str, "'\" \t,\r")))
205 {
206
3/3
✓ Branch 0 taken 25522 times.
✓ Branch 1 taken 35769 times.
✓ Branch 2 taken 9917 times.
71208 if(is_space(*str))
207 {
208
10/10
✓ Branch 0 taken 25516 times.
✓ Branch 1 taken 25939 times.
✓ Branch 2 taken 25498 times.
✓ Branch 3 taken 24 times.
✓ Branch 4 taken 25492 times.
✓ Branch 5 taken 30 times.
✓ Branch 6 taken 25909 times.
✓ Branch 7 taken 24 times.
✓ Branch 8 taken 25909 times.
✓ Branch 9 taken 30 times.
51461 if(str[0] == ' ' && !is_space(str[1]))
209 {
210 51401 str++;
211 51401 continue;
212 }
213
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 out.append(startstr, 0, str - startstr);
214
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 out += ' ';
215
4/4
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 96 times.
✓ Branch 3 taken 30 times.
252 while(is_space(*str)) str++;
216 60 startstr = str;
217
3/3
✓ Branch 0 taken 3110 times.
✓ Branch 1 taken 9884 times.
✓ Branch 2 taken 6753 times.
19747 }else if(*str == ',')
218 {
219 6274 str++;
220
3/3
✓ Branch 0 taken 914 times.
✓ Branch 1 taken 3116 times.
✓ Branch 2 taken 2244 times.
6274 if(is_space(*str))
221 {
222
1/2
✓ Branch 0 taken 1834 times.
✗ Branch 1 not taken.
1834 out.append(startstr, 0, str - startstr);
223
4/4
✓ Branch 0 taken 935 times.
✓ Branch 1 taken 914 times.
✓ Branch 2 taken 941 times.
✓ Branch 3 taken 920 times.
3710 while(is_space(*str)) str++;
224 1834 startstr = str;
225 }
226 }
227 else
228 {
229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6753 times.
13473 str = strchr(str + 1, *str); //confirm quotes has already been run, so this should be okay
230
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 13443 times.
13473 if(!str) return thisstring;
231 13443 str++;
232 }
233 }
234
3/3
✓ Branch 0 taken 748 times.
✓ Branch 1 taken 28045 times.
✓ Branch 2 taken 27614 times.
56407 if(startstr != thisstring.data())
235 {
236
2/4
✓ Branch 0 taken 748 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 754 times.
✗ Branch 3 not taken.
1502 out.append(startstr, 0, (thisstring.data() + thisstring.length()) - startstr); //the remaining
237
238 1502 thisstring = std::move(out);
239 }
240 56407 return thisstring;
241 56437 }
242
243 77970 bool confirmquotes(const char * str)
244 {
245
3/3
✓ Branch 0 taken 27946 times.
✓ Branch 1 taken 46091 times.
✓ Branch 2 taken 17887 times.
91924 while(*str)
246 {
247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28338 times.
56284 char *dquote = strchr((char *)str, '"');
248
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28338 times.
56284 char *squote = strchr((char *)str, '\'');
249
4/4
✓ Branch 0 taken 43248 times.
✓ Branch 1 taken 13036 times.
✓ Branch 2 taken 928 times.
✓ Branch 3 taken 42320 times.
56284 if(dquote || squote)
250 {
251
6/6
✓ Branch 0 taken 13036 times.
✓ Branch 1 taken 928 times.
✓ Branch 2 taken 12934 times.
✓ Branch 3 taken 102 times.
✓ Branch 4 taken 12918 times.
✓ Branch 5 taken 16 times.
13964 if(dquote && (dquote < squote || !squote))
252 {
253
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6540 times.
13020 dquote = strchr(dquote+1, '"');
254
2/2
✓ Branch 0 taken 13012 times.
✓ Branch 1 taken 8 times.
13020 if(dquote) str = dquote+1;
255 8 else return false;
256 }
257 else
258 {
259 472 int codepoint;
260
2/3
✓ Branch 0 taken 472 times.
✓ Branch 1 taken 472 times.
✗ Branch 2 not taken.
944 squote += utf8_val(&codepoint, squote + 1) + 1;
261
3/3
✓ Branch 0 taken 471 times.
✓ Branch 1 taken 472 times.
✓ Branch 2 taken 1 times.
944 if(*squote == '\'') str = squote+1;
262 2 else return false;
263 }
264 13954 }
265 else
266 {
267 42320 return true;
268 }
269 }
270 35640 return true;
271 }
272
273 724 bool confirmqpar(const char * str)
274 {
275 //todo fully optimize
276 724 int par = 0;
277
6/8
✗ Branch 0 not taken.
✓ Branch 1 taken 4810 times.
✓ Branch 2 taken 4455 times.
✓ Branch 3 taken 5193 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 4838 times.
✓ Branch 6 taken 4469 times.
✓ Branch 7 taken 369 times.
9648 while((unsigned char)*str >= 128 || !qparlut[(unsigned char)*str]) str++;
278
3/3
✓ Branch 0 taken 905 times.
✓ Branch 1 taken 1288 times.
✓ Branch 2 taken 369 times.
2562 while(*str)
279 {
280
3/3
✓ Branch 0 taken 183 times.
✓ Branch 1 taken 905 times.
✓ Branch 2 taken 750 times.
1838 if(*str == '"')
281 {
282
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 183 times.
366 str = strchr(str + 1, '"');
283
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 183 times.
✓ Branch 2 taken 183 times.
366 if(!str++) return false;
284 }
285
3/3
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 722 times.
✓ Branch 2 taken 738 times.
1472 else if(*str == '\'')
286 {
287 12 int codepoint;
288
2/3
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
24 str += utf8_val(&codepoint, str + 1) + 1;
289
2/3
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
24 if(*str == '\'') str++;
290 else return false;
291 }
292 else
293 {
294
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 738 times.
1448 par += 1 - ((*str++ - '(') << 1);
295
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1448 times.
1448 if(par < 0) return false;
296 }
297
6/8
✗ Branch 0 not taken.
✓ Branch 1 taken 2265 times.
✓ Branch 2 taken 1360 times.
✓ Branch 3 taken 3212 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2307 times.
✓ Branch 6 taken 1374 times.
✓ Branch 7 taken 933 times.
4572 while((unsigned char)*str >= 128 || !qparlut[(unsigned char)*str]) str++;
298 }
299 724 return !par;
300 }
301
302 12023 char ** split(char * str, char key, int * len)
303 {
304
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6080 times.
12023 char *thisentry=strchr(str, key);
305
2/2
✓ Branch 0 taken 9081 times.
✓ Branch 1 taken 2942 times.
12023 if (!thisentry)
306 {
307 9081 char ** out= typed_malloc(char*, 2);
308 9081 out[0]=str;
309 9081 out[1]=nullptr;
310
2/2
✓ Branch 0 taken 4493 times.
✓ Branch 1 taken 4588 times.
9081 if (len) *len=1;
311 9081 return out;
312 }
313 2942 int count=15; //makes the default alloc 8 elements, sounds fair.
314 2942 char ** outdata= typed_malloc(char*, (size_t)count+1);
315
316 2942 int newcount=0;
317 2942 outdata[newcount++]=str;
318 do{
319 14690 *thisentry = 0;
320 14690 thisentry++;
321 14690 outdata[newcount++]=thisentry;
322
2/2
✓ Branch 0 taken 307 times.
✓ Branch 1 taken 14383 times.
14690 if(newcount >= count)
323 {
324 307 count *= 2;
325 307 outdata = typed_realloc(char *, outdata, count);
326 }
327
4/4
✓ Branch 0 taken 5840 times.
✓ Branch 1 taken 8850 times.
✓ Branch 2 taken 5908 times.
✓ Branch 3 taken 1489 times.
14690 }while((thisentry = strchr(thisentry, key)));
328
329 2942 outdata[newcount]= nullptr;
330
2/2
✓ Branch 0 taken 2174 times.
✓ Branch 1 taken 768 times.
2942 if (len) *len=newcount;
331 2942 return outdata;
332 }
333
334 12021 char ** qsplit(char * str, char key, int * len)
335 {
336
8/10
✓ Branch 0 taken 5737 times.
✓ Branch 1 taken 6284 times.
✓ Branch 2 taken 11543 times.
✓ Branch 3 taken 256 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 5833 times.
✓ Branch 6 taken 5806 times.
✓ Branch 7 taken 27 times.
✓ Branch 8 taken 5797 times.
✗ Branch 9 not taken.
12021 if (!strchr(str, '"') && !strchr(str, '\'')) return split(str, key, len);
337
338 505 int count=15;
339 505 char ** outdata= typed_malloc(char*, (size_t)count+1);
340 505 int newcount=0;
341 505 char * thisentry=str;
342 505 outdata[newcount++]=thisentry;
343
3/3
✓ Branch 0 taken 739 times.
✓ Branch 1 taken 995 times.
✓ Branch 2 taken 256 times.
1990 while (*thisentry) /*todo fix*/
344 {
345
3/3
✓ Branch 0 taken 131 times.
✓ Branch 1 taken 739 times.
✓ Branch 2 taken 615 times.
1485 if (*thisentry == key)
346 {
347 262 *thisentry=0;
348 262 thisentry++;
349 262 outdata[newcount++]=thisentry;
350
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 262 times.
262 if(newcount >= count)
351 {
352 count *= 2;
353 outdata = typed_realloc(char *, outdata, count);
354 }
355 }
356
2/4
✓ Branch 0 taken 1223 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1223 times.
✗ Branch 3 not taken.
1223 else if(skip_quote(thisentry)) thisentry++;
357 else return nullptr;
358 }
359 505 outdata[newcount]= nullptr;
360
2/2
✓ Branch 0 taken 150 times.
✓ Branch 1 taken 355 times.
505 if (len) *len=newcount;
361 505 return outdata;
362 }
363
364 55471 char ** qsplitstr(char * str, const char * key, int * len)
365 {
366 //check if the str is found first
367
5/6
✓ Branch 0 taken 27368 times.
✓ Branch 1 taken 28103 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 27884 times.
✓ Branch 4 taken 27605 times.
✓ Branch 5 taken 279 times.
55471 if (!strstr(str, key))
368 {
369 54973 char ** out= typed_malloc(char*, 2);
370 54973 out[0]=str;
371 54973 out[1]=nullptr;
372
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54973 times.
54973 if (len) *len=1;
373 54973 return out;
374 }
375
376
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 279 times.
498 int keylen=(int)strlen(key);
377 498 int count=15;
378 498 char ** outdata= typed_malloc(char*, (size_t)count+1);
379 498 int newcount=0;
380 498 char * thisentry=str;
381 498 outdata[newcount++]=thisentry;
382
3/3
✓ Branch 0 taken 10842 times.
✓ Branch 1 taken 12231 times.
✓ Branch 2 taken 279 times.
23352 while (*thisentry) /*todo fix*/
383 {
384
5/6
✓ Branch 0 taken 900 times.
✓ Branch 1 taken 21954 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12012 times.
✓ Branch 4 taken 969 times.
✓ Branch 5 taken 11043 times.
22854 if (!strncmp(thisentry, key, (size_t)keylen))
385 {
386 1869 *thisentry=0;
387 1869 thisentry+=keylen;
388 1869 outdata[newcount++]=thisentry;
389
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1869 times.
1869 if(newcount >= count)
390 {
391 count *= 2;
392 outdata = typed_realloc(char *, outdata, count);
393 }
394 }
395
2/4
✓ Branch 0 taken 20985 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20985 times.
✗ Branch 3 not taken.
20985 else if(skip_quote(thisentry)) thisentry++;
396 else return nullptr;
397 }
398 498 outdata[newcount]= nullptr;
399
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 498 times.
498 if (len) *len=newcount;
400 498 return outdata;
401 }
402
403 //this function is most commonly called in cases where additional chars are very likely
404 12484 char ** qpsplit(char * str, char key, int * len)
405 {
406
8/10
✓ Branch 0 taken 5255 times.
✓ Branch 1 taken 7229 times.
✓ Branch 2 taken 10610 times.
✓ Branch 3 taken 938 times.
✓ Branch 4 taken 5255 times.
✓ Branch 5 taken 5355 times.
✓ Branch 6 taken 5355 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5355 times.
✗ Branch 9 not taken.
12484 if (!strchr(str, '(') && !strchr(str, ')')) return qsplit(str, key, len);
407 1874 int count=7;
408 1874 char ** outdata= typed_malloc(char*, (size_t)count+1);
409
410 1874 int newcount=0;
411 1874 char * thisentry=str;
412 1874 outdata[newcount++]=thisentry;
413
3/3
✓ Branch 0 taken 5417 times.
✓ Branch 1 taken 6370 times.
✓ Branch 2 taken 938 times.
12725 while (*thisentry)
414 {
415 //skippar(*thisentry, thisentry++, return nullptr;)
416
3/3
✓ Branch 0 taken 358 times.
✓ Branch 1 taken 5420 times.
✓ Branch 2 taken 5073 times.
10851 if (*thisentry == key)
417 {
418 719 *thisentry=0;
419 719 thisentry++;
420 719 outdata[newcount++]=thisentry;
421
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 717 times.
719 if(newcount >= count)
422 {
423 2 count *= 2;
424 2 outdata = typed_realloc(char *, outdata, count);
425 }
426 }
427
2/4
✓ Branch 0 taken 10132 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10132 times.
10132 else if(!skip_par(thisentry)) return nullptr;
428 }
429 1874 outdata[newcount]= nullptr;
430
2/2
✓ Branch 0 taken 906 times.
✓ Branch 1 taken 968 times.
1874 if (len) *len=newcount;
431 1874 return outdata;
432 }
433
434 string &itrim(string &input, const char * left, const char * right)
435 {
436 bool nukeright=true;
437 int totallen=input.length();
438 int rightlen=(int)strlen(right);
439 if (rightlen && rightlen<=totallen)
440 {
441 const char * rightend=right+rightlen;
442 const char * strend=input.data()+totallen;
443 while (right!=rightend)
444 {
445 rightend--;
446 strend--;
447 if (to_lower(*strend)!=to_lower(*rightend)) nukeright=false;
448 }
449 if (nukeright)
450 {
451 totallen-=rightlen;
452 input.truncate(totallen);
453 }
454 }
455 bool nukeleft=true;
456 int leftlen = strlen(left);
457 if(leftlen == 1 && input.data()[0] == left[0])
458 {
459 return input = string(input.data()+1, (input.length()-1));
460 }
461 else
462 {
463 for (int i = 0; i < leftlen; i++)
464 {
465 if (to_lower(input.data()[i])!=to_lower(left[i])) nukeleft=false;
466 }
467 if (nukeleft) input = string(input.data()+leftlen, (input.length()-leftlen));
468 }
469 return input;
470 }
471
472 336 char* strqpchr(char* str, char key)
473 {
474
3/3
✓ Branch 0 taken 1455 times.
✓ Branch 1 taken 1653 times.
✓ Branch 2 taken 156 times.
3264 while (*str)
475 {
476
3/3
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 1455 times.
✓ Branch 2 taken 1488 times.
2958 if (*str == key) return str;
477
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2928 times.
2928 else if(!skip_par(str)) return nullptr;
478 }
479 306 return nullptr;
480 }
481
482 114 char* strqpstr(char* str, const char* key)
483 {
484
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
114 size_t keylen = strlen(key);
485
3/3
✓ Branch 0 taken 234 times.
✓ Branch 1 taken 237 times.
✓ Branch 2 taken 3 times.
474 while (*str)
486 {
487
5/6
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 414 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 234 times.
✓ Branch 4 taken 54 times.
✓ Branch 5 taken 180 times.
468 if (!strncmp(str, key, keylen)) return str;
488
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 360 times.
360 else if(!skip_par(str)) return nullptr;
489 }
490 6 return nullptr;
491 }
492
493 extern const uint8_t char_props[256] = {
494 //x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF
495 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x00,0x00, // 0x
496 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 1x
497 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 2x !"#$%&'()*+,-./
498 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x00,0x00,0x00,0x00,0x00,0x00, // 3x 0123456789:;<=>?
499 0x00,0x23,0x23,0x23,0x23,0x23,0x23,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, // 4x @ABCDEFGHIJKLMNO
500 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x00,0x00,0x00,0x00,0x08, // 5x PQRSTUVWXYZ[\]^_
501 0x00,0x25,0x25,0x25,0x25,0x25,0x25,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24, // 6x `abcdefghijklmno
502 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x00,0x00,0x00,0x00,0x00, // 7x pqrstuvwxyz{|}~
503 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 8x
504 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 9x
505 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Ax
506 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Bx
507 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Cx
508 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Dx
509 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Ex
510 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Fx
511 };
512