asar coverage - build #273


src/asar/
File: src/asar/libstr.cpp
Date: 2025-03-03 20:49:12
Lines:
217/272
79.8%
Functions:
15/18
83.3%
Branches:
250/397
63.0%

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 3399 void string::reallocate_capacity(unsigned int new_length)
16 {
17 // Allocate 1 extra byte for NUL terminator
18 3399 int new_alloc_capacity = bitround(new_length + 1);
19
20
3/3
✓ Branch 0 taken 1477 times.
✓ Branch 1 taken 1809 times.
✓ Branch 2 taken 113 times.
3399 if (is_inlined()) {
21 3209 data_ptr = copy(data_ptr, min(len, new_length), (char*)malloc(new_alloc_capacity));
22 }
23 else {
24 190 data_ptr = (char*)realloc(data_ptr, new_alloc_capacity);
25 }
26 3399 allocated.capacity = new_alloc_capacity - 1; // capacity field doesn't count NUL terminator
27 3399 }
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))
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)) 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 69753 inline bool skip_quote(char *&str)
122 {
123
124
5/6
✓ Branch 0 taken 3639 times.
✓ Branch 1 taken 34329 times.
✓ Branch 2 taken 2595 times.
✓ Branch 3 taken 29190 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2595 times.
69753 if(*str == '"') str = strchr(str + 1, '"');
125
4/4
✓ Branch 0 taken 423 times.
✓ Branch 1 taken 33906 times.
✓ Branch 2 taken 423 times.
✓ Branch 3 taken 28767 times.
63519 else if(*str == '\'')
126 {
127 423 int codepoint;
128
2/4
✓ Branch 0 taken 423 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 423 times.
✗ Branch 3 not taken.
846 str += utf8_val(&codepoint, str + 1) + 1;
129
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 423 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 423 times.
846 if(*str != '\'') return false;
130 }
131 69753 return str;
132 }
133
134 //eat 1 char or quote/par
135 12850 inline bool skip_par(char *&str)
136 {
137 12850 int par = 0;
138
11/12
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6388 times.
✓ Branch 2 taken 50 times.
✓ Branch 3 taken 12794 times.
✓ Branch 4 taken 1085 times.
✓ Branch 5 taken 5259 times.
✓ Branch 6 taken 46 times.
✓ Branch 7 taken 11663 times.
✓ Branch 8 taken 1094 times.
✓ Branch 9 taken 5310 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 5310 times.
12850 if(*str != '\'' && *str != '"' && *str != '(' && *str != ')')
139 {
140 10569 str++;
141 10569 return true;
142 }
143 while(true)
144 {
145 13819 char *t = str;
146
5/6
✓ Branch 0 taken 146 times.
✓ Branch 1 taken 6744 times.
✓ Branch 2 taken 154 times.
✓ Branch 3 taken 6775 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 154 times.
13819 if(*str == '"') t = strchr(t + 1, '"');
147
4/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6738 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6769 times.
13519 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 1093 times.
✓ Branch 1 taken 6747 times.
✓ Branch 2 taken 5667 times.
13507 else if(*t == '(')
154 {
155 2195 par++;
156 }
157
3/3
✓ Branch 0 taken 1093 times.
✓ Branch 1 taken 5654 times.
✓ Branch 2 taken 4565 times.
11312 else if(*t == ')')
158 {
159 2195 par--;
160
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2195 times.
2195 if(par < 0) return false;
161 }
162
163 13819 str = t + 1;
164
6/6
✓ Branch 0 taken 6081 times.
✓ Branch 1 taken 809 times.
✓ Branch 2 taken 6438 times.
✓ Branch 3 taken 6572 times.
✓ Branch 4 taken 329 times.
✓ Branch 5 taken 5783 times.
13819 if(!*str || !par) return par == 0 ? true : false;
165 11538 }
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 50079 string& string::qnormalize()
199 {
200 50079 string& thisstring =*this;
201 50079 string out;
202 50079 char *startstr = thisstring.raw();
203 50079 char *str = startstr;
204
4/4
✓ Branch 0 taken 29934 times.
✓ Branch 1 taken 78319 times.
✓ Branch 2 taken 28270 times.
✓ Branch 3 taken 24647 times.
108253 while((str = strpbrk(str, "'\" \t,\r")))
205 {
206
3/3
✓ Branch 0 taken 22798 times.
✓ Branch 1 taken 29267 times.
✓ Branch 2 taken 6139 times.
58204 if(is_space(*str))
207 {
208
10/10
✓ Branch 0 taken 22792 times.
✓ Branch 1 taken 22131 times.
✓ Branch 2 taken 22774 times.
✓ Branch 3 taken 24 times.
✓ Branch 4 taken 22768 times.
✓ Branch 5 taken 30 times.
✓ Branch 6 taken 22101 times.
✓ Branch 7 taken 24 times.
✓ Branch 8 taken 22101 times.
✓ Branch 9 taken 30 times.
44929 if(str[0] == ' ' && !is_space(str[1]))
209 {
210 44869 str++;
211 44869 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 3107 times.
✓ Branch 1 taken 7190 times.
✓ Branch 2 taken 2978 times.
13275 }else if(*str == ',')
218 {
219 6268 str++;
220
3/3
✓ Branch 0 taken 914 times.
✓ Branch 1 taken 3113 times.
✓ Branch 2 taken 2241 times.
6268 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 2978 times.
7007 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 6977 times.
7007 if(!str) return thisstring;
231 6977 str++;
232 }
233 }
234
3/3
✓ Branch 0 taken 748 times.
✓ Branch 1 taken 25408 times.
✓ Branch 2 taken 23893 times.
50049 if(startstr != thisstring.raw())
235 {
236
3/5
✓ Branch 0 taken 748 times.
✓ Branch 1 taken 754 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 754 times.
✗ Branch 4 not taken.
1502 out.append(startstr, 0, strlen(startstr)); //the remaining
237
238
2/3
✓ Branch 0 taken 748 times.
✓ Branch 1 taken 754 times.
✗ Branch 2 not taken.
1502 thisstring = out;
239 }
240 50049 return thisstring;
241 50079 }
242
243 71644 bool confirmquotes(const char * str)
244 {
245
3/3
✓ Branch 0 taken 25281 times.
✓ Branch 1 taken 39693 times.
✓ Branch 2 taken 14154 times.
79128 while(*str)
246 {
247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24589 times.
49870 char *dquote = strchr((char *)str, '"');
248
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24589 times.
49870 char *squote = strchr((char *)str, '\'');
249
4/4
✓ Branch 0 taken 43304 times.
✓ Branch 1 taken 6566 times.
✓ Branch 2 taken 928 times.
✓ Branch 3 taken 42376 times.
49870 if(dquote || squote)
250 {
251
6/6
✓ Branch 0 taken 6566 times.
✓ Branch 1 taken 928 times.
✓ Branch 2 taken 6464 times.
✓ Branch 3 taken 102 times.
✓ Branch 4 taken 6448 times.
✓ Branch 5 taken 16 times.
7494 if(dquote && (dquote < squote || !squote))
252 {
253
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2763 times.
6550 dquote = strchr(dquote+1, '"');
254
2/2
✓ Branch 0 taken 6542 times.
✓ Branch 1 taken 8 times.
6550 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 7484 }
265 else
266 {
267 42376 return true;
268 }
269 }
270 29258 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 2241 times.
✓ Branch 2 taken 1336 times.
✓ Branch 3 taken 3188 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2283 times.
✓ Branch 6 taken 1350 times.
✓ Branch 7 taken 933 times.
4524 while((unsigned char)*str >= 128 || !qparlut[(unsigned char)*str]) str++;
298 }
299 724 return !par;
300 }
301
302 56139 char ** split(char * str, char key, int * len)
303 {
304
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28309 times.
56139 char *thisentry=strchr(str, key);
305
2/2
✓ Branch 0 taken 31907 times.
✓ Branch 1 taken 24232 times.
56139 if (!thisentry)
306 {
307 31907 char ** out= typed_malloc(char*, 2);
308 31907 out[0]=str;
309 31907 out[1]=nullptr;
310
2/2
✓ Branch 0 taken 27265 times.
✓ Branch 1 taken 4642 times.
31907 if (len) *len=1;
311 31907 return out;
312 }
313 24232 int count=15; //makes the default alloc 8 elements, sounds fair.
314 24232 char ** outdata= typed_malloc(char*, (size_t)count+1);
315
316 24232 int newcount=0;
317 24232 outdata[newcount++]=str;
318 do{
319 43285 *thisentry = 0;
320 43285 thisentry++;
321 43285 outdata[newcount++]=thisentry;
322
2/2
✓ Branch 0 taken 309 times.
✓ Branch 1 taken 42976 times.
43285 if(newcount >= count)
323 {
324 309 count *= 2;
325 309 outdata = typed_realloc(char *, outdata, count);
326 }
327
4/4
✓ Branch 0 taken 9485 times.
✓ Branch 1 taken 33800 times.
✓ Branch 2 taken 9568 times.
✓ Branch 3 taken 12239 times.
43285 }while((thisentry = strchr(thisentry, key)));
328
329 24232 outdata[newcount]= nullptr;
330
2/2
✓ Branch 0 taken 23464 times.
✓ Branch 1 taken 768 times.
24232 if (len) *len=newcount;
331 24232 return outdata;
332 }
333
334 60416 char ** qsplit(char * str, char key, int * len)
335 {
336
8/10
✓ Branch 0 taken 27228 times.
✓ Branch 1 taken 33188 times.
✓ Branch 2 taken 54582 times.
✓ Branch 3 taken 2548 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 27666 times.
✓ Branch 6 taken 27354 times.
✓ Branch 7 taken 312 times.
✓ Branch 8 taken 27321 times.
✗ Branch 9 not taken.
60416 if (!strchr(str, '"') && !strchr(str, '\'')) return split(str, key, len);
337
338 6146 int count=15;
339 6146 char ** outdata= typed_malloc(char*, (size_t)count+1);
340 6146 int newcount=0;
341 6146 char * thisentry=str;
342 6146 outdata[newcount++]=thisentry;
343
3/3
✓ Branch 0 taken 31891 times.
✓ Branch 1 taken 27148 times.
✓ Branch 2 taken 2548 times.
61587 while (*thisentry) /*todo fix*/
344 {
345
3/3
✓ Branch 0 taken 3865 times.
✓ Branch 1 taken 30834 times.
✓ Branch 2 taken 20742 times.
55441 if (*thisentry == key)
346 {
347 6673 *thisentry=0;
348 6673 thisentry++;
349 6673 outdata[newcount++]=thisentry;
350
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6673 times.
6673 if(newcount >= count)
351 {
352 count *= 2;
353 outdata = typed_realloc(char *, outdata, count);
354 }
355 }
356
2/4
✓ Branch 0 taken 48768 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 48768 times.
✗ Branch 3 not taken.
48768 else if(skip_quote(thisentry)) thisentry++;
357 else return nullptr;
358 }
359 6146 outdata[newcount]= nullptr;
360
2/2
✓ Branch 0 taken 5721 times.
✓ Branch 1 taken 425 times.
6146 if (len) *len=newcount;
361 6146 return outdata;
362 }
363
364 49113 char ** qsplitstr(char * str, const char * key, int * len)
365 {
366 //check if the str is found first
367
5/6
✓ Branch 0 taken 24731 times.
✓ Branch 1 taken 24382 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 24163 times.
✓ Branch 4 taken 23884 times.
✓ Branch 5 taken 279 times.
49113 if (!strstr(str, key))
368 {
369 48615 char ** out= typed_malloc(char*, 2);
370 48615 out[0]=str;
371 48615 out[1]=nullptr;
372
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48615 times.
48615 if (len) *len=1;
373 48615 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 11522 char ** qpsplit(char * str, char key, int * len)
405 {
406
8/10
✓ Branch 0 taken 4664 times.
✓ Branch 1 taken 6858 times.
✓ Branch 2 taken 9434 times.
✓ Branch 3 taken 1048 times.
✓ Branch 4 taken 4664 times.
✓ Branch 5 taken 4770 times.
✓ Branch 6 taken 4770 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4770 times.
✗ Branch 9 not taken.
11522 if (!strchr(str, '(') && !strchr(str, ')')) return qsplit(str, key, len);
407 2088 int count=7;
408 2088 char ** outdata= typed_malloc(char*, (size_t)count+1);
409
410 2088 int newcount=0;
411 2088 char * thisentry=str;
412 2088 outdata[newcount++]=thisentry;
413
3/3
✓ Branch 0 taken 6542 times.
✓ Branch 1 taken 7647 times.
✓ Branch 2 taken 1048 times.
15237 while (*thisentry)
414 {
415 //skippar(*thisentry, thisentry++, return nullptr;)
416
3/3
✓ Branch 0 taken 388 times.
✓ Branch 1 taken 6545 times.
✓ Branch 2 taken 6216 times.
13149 if (*thisentry == key)
417 {
418 779 *thisentry=0;
419 779 thisentry++;
420 779 outdata[newcount++]=thisentry;
421
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 771 times.
779 if(newcount >= count)
422 {
423 8 count *= 2;
424 8 outdata = typed_realloc(char *, outdata, count);
425 }
426 }
427
2/4
✓ Branch 0 taken 12370 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12370 times.
12370 else if(!skip_par(thisentry)) return nullptr;
428 }
429 2088 outdata[newcount]= nullptr;
430
2/2
✓ Branch 0 taken 910 times.
✓ Branch 1 taken 1178 times.
2088 if (len) *len=newcount;
431 2088 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 char* strqpchr(char* str, char key)
473 {
474 while (*str)
475 {
476 if (*str == key) return str;
477 else if(!skip_par(str)) return nullptr;
478 }
479 return nullptr;
480 }
481
482 126 char* strqpstr(char* str, const char* key)
483 {
484
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
126 size_t keylen = strlen(key);
485
3/3
✓ Branch 0 taken 300 times.
✓ Branch 1 taken 303 times.
✓ Branch 2 taken 3 times.
606 while (*str)
486 {
487
5/6
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 540 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 300 times.
✓ Branch 4 taken 60 times.
✓ Branch 5 taken 240 times.
600 if (!strncmp(str, key, keylen)) return str;
488
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 480 times.
480 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