asar coverage - build #264


src/asar/
File: src/asar/libstr.cpp
Date: 2025-02-28 06:49:25
Lines:
217/272
79.8%
Functions:
15/18
83.3%
Branches:
197/314
62.7%

Line Branch Exec Source
1 #include "asar.h"
2 #include "virtualfile.h"
3 #include "unicode.h"
4
5 #include "platform/file-helpers.h"
6
7 #define typed_malloc(type, count) (type*)malloc(sizeof(type)*(count))
8 #define typed_realloc(type, ptr, count) (type*)realloc(ptr, sizeof(type)*(count))
9
10
11 // This function is intentionally left out of the header file so that it is not visible to the
12 // compiler and less likely to be inlined into resize(). This in turn reduces the size of resize()
13 // so that it is then inlined in more places.
14 4559 void string::reallocate_capacity(unsigned int new_length)
15 {
16 // Allocate 1 extra byte for NUL terminator
17 4559 int new_alloc_capacity = bitround(new_length + 1);
18
19
2/2
✓ Branch 0 taken 4379 times.
✓ Branch 1 taken 180 times.
4559 if (is_inlined()) {
20 4379 data_ptr = copy(data_ptr, min(len, new_length), (char*)malloc(new_alloc_capacity));
21 }
22 else {
23 180 data_ptr = (char*)realloc(data_ptr, new_alloc_capacity);
24 }
25 4559 allocated.capacity = new_alloc_capacity - 1; // capacity field doesn't count NUL terminator
26 4559 }
27
28
29 // Detects if str starts with a UTF-8 byte order mark.
30 // If so, throws a warning, then returns the number of bytes we should skip ahead in the string.
31 323 static size_t check_bom(const char* str)
32 {
33 // RPG Hacker: We could also check for BoMs of incompatible encodings here (like UTF-16)
34 // and throw errors, but not sure if that's worth adding. Asar never supported any wide
35 // encodings to begin with, so it's unreasonable to assume that any UTF-16 patches currently
36 // exist for it. As for future patches, those should be caught by the "must be UTF-8" checks
37 // I have already implemented further below.
38 // I think UTF-8 + BoM is the only case that could lead to confusion if we didn't handle it,
39 // so that's why I have added this.
40
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 321 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
323 if (str[0u] == '\xEF' && str[1u] == '\xBB' && str[2u] == '\xBF')
41 {
42 2 asar_throw_warning(0, warning_id_byte_order_mark_utf8);
43 2 return 3u;
44 }
45
46 321 return 0u;
47 }
48
49
50 329 char * readfile(const char * fname, const char * basepath)
51 {
52 329 virtual_file_handle myfile = filesystem->open_file(fname, basepath);
53
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 323 times.
329 if (myfile == INVALID_VIRTUAL_FILE_HANDLE) return nullptr;
54 323 size_t datalen = filesystem->get_file_size(myfile);
55 323 char * data= typed_malloc(char, datalen+1);
56 323 data[filesystem->read_file(myfile, data, 0u, datalen)] = 0;
57 323 filesystem->close_file(myfile);
58
59
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 321 times.
323 if (!is_valid_utf8(data))
60 {
61 2 free(data);
62 2 asar_throw_error(0, error_type_block, error_id_invalid_utf8);
63 }
64
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 319 times.
321 if(check_bom(data)){
65 2 data[0] = ' ';
66 2 data[1] = ' ';
67 2 data[2] = ' ';
68 }
69 321 return data;
70 }
71
72 // RPG Hacker: like readfile(), but doesn't use virtual file system
73 // and instead read our file directly.
74 8 char * readfilenative(const char * fname)
75 {
76 8 FileHandleType myfile = open_file(fname, FileOpenMode_Read);
77
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
8 if (myfile == InvalidFileHandle) return nullptr;
78 2 size_t datalen = (size_t)get_file_size(myfile);
79 2 char * data = typed_malloc(char, datalen + 1);
80 2 data[read_file(myfile, data, datalen)] = 0;
81 2 close_file(myfile);
82
83
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!is_valid_utf8(data)) asar_throw_error(0, error_type_block, error_id_invalid_utf8);
84
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(check_bom(data)){
85 data[0] = ' ';
86 data[1] = ' ';
87 data[2] = ' ';
88 }
89 2 return data;
90 }
91
92 264 bool readfile(const char * fname, const char * basepath, char ** data, int * len)
93 {
94 264 virtual_file_handle myfile = filesystem->open_file(fname, basepath);
95
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 252 times.
264 if (!myfile) return false;
96 252 size_t datalen = filesystem->get_file_size(myfile);
97 252 *data= typed_malloc(char, datalen);
98 252 *len = (int)filesystem->read_file(myfile, *data, 0, datalen);
99 252 filesystem->close_file(myfile);
100 252 return true;
101 }
102
103 #define isq(n) (((0x2227 ^ (0x0101 * (n))) - 0x0101UL) & ~(0x2227 ^ (0x0101 * (n))) & 0x8080UL)
104 #define isqp(n) (((0x22272829 ^ (0x01010101 * (n))) - 0x01010101UL) & ~(0x22272829 ^ (0x01010101 * (n))) & 0x80808080UL)
105
106 // RPG Hacker: Only index this with ASCII characters.
107 // Anything else doesn't make sense, anyways.
108 const bool qparlut[128] = {
109 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0,
112 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 };
118
119 //this will leave the last char found as the one pointed at
120 77651 inline bool skip_quote(char *&str)
121 {
122
123
3/4
✓ Branch 0 taken 7262 times.
✓ Branch 1 taken 70389 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2814 times.
77651 if(*str == '"') str = strchr(str + 1, '"');
124
2/2
✓ Branch 0 taken 840 times.
✓ Branch 1 taken 69549 times.
70389 else if(*str == '\'')
125 {
126 420 int codepoint;
127
1/2
✓ Branch 0 taken 840 times.
✗ Branch 1 not taken.
840 str += utf8_val(&codepoint, str + 1) + 1;
128
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 840 times.
840 if(*str != '\'') return false;
129 }
130 77651 return str;
131 }
132
133 //eat 1 char or quote/par
134 12670 inline bool skip_par(char *&str)
135 {
136 12670 int par = 0;
137
7/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 12664 times.
✓ Branch 2 taken 90 times.
✓ Branch 3 taken 12574 times.
✓ Branch 4 taken 2161 times.
✓ Branch 5 taken 10413 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 10413 times.
12670 if(*str != '\'' && *str != '"' && *str != '(' && *str != ')')
138 {
139 10413 str++;
140 10413 return true;
141 }
142 while(true)
143 {
144 13729 char *t = str;
145
3/4
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 13441 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 148 times.
13729 if(*str == '"') t = strchr(t + 1, '"');
146
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 13435 times.
13441 else if(*str == '\'')
147 {
148 3 int codepoint;
149
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 t += utf8_val(&codepoint, t + 1) + 1;
150
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(*t != '\'') return false;
151 }
152
2/2
✓ Branch 0 taken 2177 times.
✓ Branch 1 taken 11258 times.
13435 else if(*t == '(')
153 {
154 2177 par++;
155 }
156
2/2
✓ Branch 0 taken 2177 times.
✓ Branch 1 taken 9081 times.
11258 else if(*t == ')')
157 {
158 2177 par--;
159
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2177 times.
2177 if(par < 0) return false;
160 }
161
162 13729 str = t + 1;
163
4/4
✓ Branch 0 taken 12115 times.
✓ Branch 1 taken 1614 times.
✓ Branch 2 taken 643 times.
✓ Branch 3 taken 11472 times.
13729 if(!*str || !par) return par == 0 ? true : false;
164 11472 }
165 }
166
167 //instr should not be duplicate chars. Instr should also not be 1 char
168 string& string::qreplace(const char * instr, const char * outstr)
169 {
170 string& thisstring =*this;
171 if (!strstr(thisstring, instr)) return thisstring;
172 int inlen = strlen(instr);
173 string out;
174 for (int i=0;thisstring[i];)
175 {
176 if (!strncmp((const char*)thisstring +i, instr, inlen))
177 {
178 out+=outstr;
179 i+=inlen;
180 }
181 // randomdude999: prevent appending the null terminator to the output
182 else if(!isq(thisstring[i])) out+= thisstring[i++];
183 else
184 {
185 char *start = raw() + i;
186 char *end = start;
187 if(!skip_quote(end)) return thisstring;
188 out.append(raw(), i, end - start + i + 1);
189 i += end - start + 1;
190
191 }
192 }
193 thisstring =out;
194 return thisstring;
195 }
196
197 50951 string& string::qnormalize()
198 {
199 50951 string& thisstring =*this;
200 50951 string out;
201 50951 char *startstr = thisstring.raw();
202 50951 char *str = startstr;
203
4/4
✓ Branch 0 taken 31522 times.
✓ Branch 1 taken 79599 times.
✓ Branch 2 taken 28678 times.
✓ Branch 3 taken 24788 times.
111121 while((str = strpbrk(str, "'\" \t,\r")))
204 {
205
2/2
✓ Branch 0 taken 45789 times.
✓ Branch 1 taken 14411 times.
60200 if(is_space(*str))
206 {
207
6/6
✓ Branch 0 taken 45777 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 45729 times.
✓ Branch 3 taken 48 times.
✓ Branch 4 taken 45729 times.
✓ Branch 5 taken 60 times.
45789 if(str[0] == ' ' && !is_space(str[1]))
208 {
209 45729 str++;
210 45729 continue;
211 }
212
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 out.append(startstr, 0, str - startstr);
213
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 out += ' ';
214
2/2
✓ Branch 0 taken 192 times.
✓ Branch 1 taken 60 times.
252 while(is_space(*str)) str++;
215 60 startstr = str;
216
2/2
✓ Branch 0 taken 6262 times.
✓ Branch 1 taken 8149 times.
14411 }else if(*str == ',')
217 {
218 6262 str++;
219
2/2
✓ Branch 0 taken 1828 times.
✓ Branch 1 taken 4434 times.
6262 if(is_space(*str))
220 {
221
1/2
✓ Branch 0 taken 1828 times.
✗ Branch 1 not taken.
1828 out.append(startstr, 0, str - startstr);
222
2/2
✓ Branch 0 taken 1870 times.
✓ Branch 1 taken 1828 times.
3698 while(is_space(*str)) str++;
223 1828 startstr = str;
224 }
225 }
226 else
227 {
228
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3254 times.
8149 str = strchr(str + 1, *str); //confirm quotes has already been run, so this should be okay
229
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 8119 times.
8149 if(!str) return thisstring;
230 8119 str++;
231 }
232 }
233
2/2
✓ Branch 0 taken 1496 times.
✓ Branch 1 taken 49425 times.
50921 if(startstr != thisstring.raw())
234 {
235
3/4
✓ Branch 0 taken 745 times.
✓ Branch 1 taken 751 times.
✓ Branch 2 taken 751 times.
✗ Branch 3 not taken.
1496 out.append(startstr, 0, strlen(startstr)); //the remaining
236
237
1/2
✓ Branch 0 taken 1496 times.
✗ Branch 1 not taken.
1496 thisstring = out;
238 }
239 50921 return thisstring;
240 50951 }
241
242 72382 bool confirmquotes(const char * str)
243 {
244
2/2
✓ Branch 0 taken 50726 times.
✓ Branch 1 taken 30212 times.
80938 while(*str)
245 {
246
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24722 times.
50726 char *dquote = strchr((char *)str, '"');
247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24722 times.
50726 char *squote = strchr((char *)str, '\'');
248
4/4
✓ Branch 0 taken 43088 times.
✓ Branch 1 taken 7638 times.
✓ Branch 2 taken 928 times.
✓ Branch 3 taken 42160 times.
50726 if(dquote || squote)
249 {
250
6/6
✓ Branch 0 taken 7638 times.
✓ Branch 1 taken 928 times.
✓ Branch 2 taken 7552 times.
✓ Branch 3 taken 86 times.
✓ Branch 4 taken 7544 times.
✓ Branch 5 taken 8 times.
8566 if(dquote && (dquote < squote || !squote))
251 {
252
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3008 times.
7630 dquote = strchr(dquote+1, '"');
253
2/2
✓ Branch 0 taken 7622 times.
✓ Branch 1 taken 8 times.
7630 if(dquote) str = dquote+1;
254 8 else return false;
255 }
256 else
257 {
258 468 int codepoint;
259
1/2
✓ Branch 0 taken 936 times.
✗ Branch 1 not taken.
936 squote += utf8_val(&codepoint, squote + 1) + 1;
260
2/2
✓ Branch 0 taken 934 times.
✓ Branch 1 taken 2 times.
936 if(*squote == '\'') str = squote+1;
261 2 else return false;
262 }
263 8556 }
264 else
265 {
266 42160 return true;
267 }
268 }
269 30212 return true;
270 }
271
272 712 bool confirmqpar(const char * str)
273 {
274 //todo fully optimize
275 712 int par = 0;
276
5/6
✗ Branch 0 not taken.
✓ Branch 1 taken 9594 times.
✓ Branch 2 taken 4434 times.
✓ Branch 3 taken 5160 times.
✓ Branch 4 taken 4448 times.
✓ Branch 5 taken 363 times.
9594 while((unsigned char)*str >= 128 || !qparlut[(unsigned char)*str]) str++;
277
2/2
✓ Branch 0 taken 1814 times.
✓ Branch 1 taken 712 times.
2526 while(*str)
278 {
279
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1448 times.
1814 if(*str == '"')
280 {
281
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 183 times.
366 str = strchr(str + 1, '"');
282
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 366 times.
366 if(!str++) return false;
283 }
284
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 1424 times.
1448 else if(*str == '\'')
285 {
286 12 int codepoint;
287
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 str += utf8_val(&codepoint, str + 1) + 1;
288
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 if(*str == '\'') str++;
289 else return false;
290 }
291 else
292 {
293
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 726 times.
1424 par += 1 - ((*str++ - '(') << 1);
294
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1424 times.
1424 if(par < 0) return false;
295 }
296
5/6
✗ Branch 0 not taken.
✓ Branch 1 taken 4500 times.
✓ Branch 2 taken 1336 times.
✓ Branch 3 taken 3164 times.
✓ Branch 4 taken 1350 times.
✓ Branch 5 taken 921 times.
4500 while((unsigned char)*str >= 128 || !qparlut[(unsigned char)*str]) str++;
297 }
298 712 return !par;
299 }
300
301 55785 char ** split(char * str, char key, int * len)
302 {
303
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28132 times.
55785 char *thisentry=strchr(str, key);
304
2/2
✓ Branch 0 taken 31667 times.
✓ Branch 1 taken 24118 times.
55785 if (!thisentry)
305 {
306 31667 char ** out= typed_malloc(char*, 2);
307 31667 out[0]=str;
308 31667 out[1]=nullptr;
309
2/2
✓ Branch 0 taken 27025 times.
✓ Branch 1 taken 4642 times.
31667 if (len) *len=1;
310 31667 return out;
311 }
312 24118 int count=15; //makes the default alloc 8 elements, sounds fair.
313 24118 char ** outdata= typed_malloc(char*, (size_t)count+1);
314
315 24118 int newcount=0;
316 24118 outdata[newcount++]=str;
317 do{
318 42965 *thisentry = 0;
319 42965 thisentry++;
320 42965 outdata[newcount++]=thisentry;
321
2/2
✓ Branch 0 taken 307 times.
✓ Branch 1 taken 42658 times.
42965 if(newcount >= count)
322 {
323 307 count *= 2;
324 307 outdata = typed_realloc(char *, outdata, count);
325 }
326
4/4
✓ Branch 0 taken 9382 times.
✓ Branch 1 taken 33583 times.
✓ Branch 2 taken 9465 times.
✓ Branch 3 taken 12182 times.
42965 }while((thisentry = strchr(thisentry, key)));
327
328 24118 outdata[newcount]= nullptr;
329
2/2
✓ Branch 0 taken 23356 times.
✓ Branch 1 taken 762 times.
24118 if (len) *len=newcount;
330 24118 return outdata;
331 }
332
333 61234 char ** qsplit(char * str, char key, int * len)
334 {
335
8/10
✓ Branch 0 taken 27060 times.
✓ Branch 1 taken 34174 times.
✓ Branch 2 taken 54246 times.
✓ Branch 3 taken 2830 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 27498 times.
✓ Branch 6 taken 27186 times.
✓ Branch 7 taken 312 times.
✓ Branch 8 taken 27153 times.
✗ Branch 9 not taken.
61234 if (!strchr(str, '"') && !strchr(str, '\'')) return split(str, key, len);
336
337 7300 int count=15;
338 7300 char ** outdata= typed_malloc(char*, (size_t)count+1);
339 7300 int newcount=0;
340 7300 char * thisentry=str;
341 7300 outdata[newcount++]=thisentry;
342
2/2
✓ Branch 0 taken 64391 times.
✓ Branch 1 taken 7300 times.
71691 while (*thisentry) /*todo fix*/
343 {
344
2/2
✓ Branch 0 taken 7725 times.
✓ Branch 1 taken 56666 times.
64391 if (*thisentry == key)
345 {
346 7725 *thisentry=0;
347 7725 thisentry++;
348 7725 outdata[newcount++]=thisentry;
349
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7725 times.
7725 if(newcount >= count)
350 {
351 count *= 2;
352 outdata = typed_realloc(char *, outdata, count);
353 }
354 }
355
2/4
✓ Branch 0 taken 56666 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56666 times.
✗ Branch 3 not taken.
56666 else if(skip_quote(thisentry)) thisentry++;
356 else return nullptr;
357 }
358 7300 outdata[newcount]= nullptr;
359
2/2
✓ Branch 0 taken 6935 times.
✓ Branch 1 taken 365 times.
7300 if (len) *len=newcount;
360 7300 return outdata;
361 }
362
363 49991 char ** qsplitstr(char * str, const char * key, int * len)
364 {
365 //check if the str is found first
366
5/6
✓ Branch 0 taken 25465 times.
✓ Branch 1 taken 24526 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 24307 times.
✓ Branch 4 taken 24028 times.
✓ Branch 5 taken 279 times.
49991 if (!strstr(str, key))
367 {
368 49493 char ** out= typed_malloc(char*, 2);
369 49493 out[0]=str;
370 49493 out[1]=nullptr;
371
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 49493 times.
49493 if (len) *len=1;
372 49493 return out;
373 }
374
375
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 279 times.
498 int keylen=(int)strlen(key);
376 498 int count=15;
377 498 char ** outdata= typed_malloc(char*, (size_t)count+1);
378 498 int newcount=0;
379 498 char * thisentry=str;
380 498 outdata[newcount++]=thisentry;
381
2/2
✓ Branch 0 taken 22854 times.
✓ Branch 1 taken 498 times.
23352 while (*thisentry) /*todo fix*/
382 {
383
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))
384 {
385 1869 *thisentry=0;
386 1869 thisentry+=keylen;
387 1869 outdata[newcount++]=thisentry;
388
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1869 times.
1869 if(newcount >= count)
389 {
390 count *= 2;
391 outdata = typed_realloc(char *, outdata, count);
392 }
393 }
394
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++;
395 else return nullptr;
396 }
397 498 outdata[newcount]= nullptr;
398
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 498 times.
498 if (len) *len=newcount;
399 498 return outdata;
400 }
401
402 //this function is most commonly called in cases where additional chars are very likely
403 11444 char ** qpsplit(char * str, char key, int * len)
404 {
405
8/10
✓ Branch 0 taken 4634 times.
✓ Branch 1 taken 6810 times.
✓ Branch 2 taken 9374 times.
✓ Branch 3 taken 1039 times.
✓ Branch 4 taken 4634 times.
✓ Branch 5 taken 4740 times.
✓ Branch 6 taken 4740 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4740 times.
✗ Branch 9 not taken.
11444 if (!strchr(str, '(') && !strchr(str, ')')) return qsplit(str, key, len);
406 2070 int count=7;
407 2070 char ** outdata= typed_malloc(char*, (size_t)count+1);
408
409 2070 int newcount=0;
410 2070 char * thisentry=str;
411 2070 outdata[newcount++]=thisentry;
412
2/2
✓ Branch 0 taken 12969 times.
✓ Branch 1 taken 2070 times.
15039 while (*thisentry)
413 {
414 //skippar(*thisentry, thisentry++, return nullptr;)
415
2/2
✓ Branch 0 taken 779 times.
✓ Branch 1 taken 12190 times.
12969 if (*thisentry == key)
416 {
417 779 *thisentry=0;
418 779 thisentry++;
419 779 outdata[newcount++]=thisentry;
420
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 771 times.
779 if(newcount >= count)
421 {
422 8 count *= 2;
423 8 outdata = typed_realloc(char *, outdata, count);
424 }
425 }
426
2/4
✓ Branch 0 taken 12190 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12190 times.
12190 else if(!skip_par(thisentry)) return nullptr;
427 }
428 2070 outdata[newcount]= nullptr;
429
2/2
✓ Branch 0 taken 910 times.
✓ Branch 1 taken 1160 times.
2070 if (len) *len=newcount;
430 2070 return outdata;
431 }
432
433 string &itrim(string &input, const char * left, const char * right)
434 {
435 bool nukeright=true;
436 int totallen=input.length();
437 int rightlen=(int)strlen(right);
438 if (rightlen && rightlen<=totallen)
439 {
440 const char * rightend=right+rightlen;
441 const char * strend=input.data()+totallen;
442 while (right!=rightend)
443 {
444 rightend--;
445 strend--;
446 if (to_lower(*strend)!=to_lower(*rightend)) nukeright=false;
447 }
448 if (nukeright)
449 {
450 totallen-=rightlen;
451 input.truncate(totallen);
452 }
453 }
454 bool nukeleft=true;
455 int leftlen = strlen(left);
456 if(leftlen == 1 && input.data()[0] == left[0])
457 {
458 return input = string(input.data()+1, (input.length()-1));
459 }
460 else
461 {
462 for (int i = 0; i < leftlen; i++)
463 {
464 if (to_lower(input.data()[i])!=to_lower(left[i])) nukeleft=false;
465 }
466 if (nukeleft) input = string(input.data()+leftlen, (input.length()-leftlen));
467 }
468 return input;
469 }
470
471 char* strqpchr(char* str, char key)
472 {
473 while (*str)
474 {
475 if (*str == key) return str;
476 else if(!skip_par(str)) return nullptr;
477 }
478 return nullptr;
479 }
480
481 126 char* strqpstr(char* str, const char* key)
482 {
483
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
126 size_t keylen = strlen(key);
484
2/2
✓ Branch 0 taken 600 times.
✓ Branch 1 taken 6 times.
606 while (*str)
485 {
486
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;
487
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 480 times.
480 else if(!skip_par(str)) return nullptr;
488 }
489 6 return nullptr;
490 }
491
492 extern const uint8_t char_props[256] = {
493 //x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF
494 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x00,0x00, // 0x
495 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 1x
496 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 2x !"#$%&'()*+,-./
497 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x00,0x00,0x00,0x00,0x00,0x00, // 3x 0123456789:;<=>?
498 0x00,0x23,0x23,0x23,0x23,0x23,0x23,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, // 4x @ABCDEFGHIJKLMNO
499 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x00,0x00,0x00,0x00,0x08, // 5x PQRSTUVWXYZ[\]^_
500 0x00,0x25,0x25,0x25,0x25,0x25,0x25,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24, // 6x `abcdefghijklmno
501 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x00,0x00,0x00,0x00,0x00, // 7x pqrstuvwxyz{|}~
502 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 8x
503 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 9x
504 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Ax
505 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Bx
506 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Cx
507 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Dx
508 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Ex
509 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Fx
510 };
511