asar coverage - build #278


src/asar/
File: src/asar/libstr.cpp
Date: 2025-03-05 17:13:33
Lines:
217/272
79.8%
Functions:
15/18
83.3%
Branches:
247/393
62.8%

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 3437 void string::reallocate_capacity(unsigned int new_length)
16 {
17 // Allocate 1 extra byte for NUL terminator
18 3437 int new_alloc_capacity = bitround(new_length + 1);
19
20
3/3
✓ Branch 0 taken 1495 times.
✓ Branch 1 taken 1829 times.
✓ Branch 2 taken 113 times.
3437 if (is_inlined()) {
21 3247 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 3437 allocated.capacity = new_alloc_capacity - 1; // capacity field doesn't count NUL terminator
27 3437 }
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 68534 inline bool skip_quote(char *&str)
122 {
123
124
5/6
✓ Branch 0 taken 3525 times.
✓ Branch 1 taken 33564 times.
✓ Branch 2 taken 2558 times.
✓ Branch 3 taken 28887 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2558 times.
68534 if(*str == '"') str = strchr(str + 1, '"');
125
4/4
✓ Branch 0 taken 423 times.
✓ Branch 1 taken 33141 times.
✓ Branch 2 taken 423 times.
✓ Branch 3 taken 28464 times.
62451 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 68534 return str;
132 }
133
134 //eat 1 char or quote/par
135 12832 inline bool skip_par(char *&str)
136 {
137 12832 int par = 0;
138
11/12
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6379 times.
✓ Branch 2 taken 50 times.
✓ Branch 3 taken 12776 times.
✓ Branch 4 taken 1083 times.
✓ Branch 5 taken 5252 times.
✓ Branch 6 taken 46 times.
✓ Branch 7 taken 11647 times.
✓ Branch 8 taken 1092 times.
✓ Branch 9 taken 5303 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 5303 times.
12832 if(*str != '\'' && *str != '"' && *str != '(' && *str != ')')
139 {
140 10555 str++;
141 10555 return true;
142 }
143 while(true)
144 {
145 13799 char *t = str;
146
5/6
✓ Branch 0 taken 146 times.
✓ Branch 1 taken 6734 times.
✓ Branch 2 taken 154 times.
✓ Branch 3 taken 6765 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 154 times.
13799 if(*str == '"') t = strchr(t + 1, '"');
147
4/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6728 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6759 times.
13499 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 1091 times.
✓ Branch 1 taken 6737 times.
✓ Branch 2 taken 5659 times.
13487 else if(*t == '(')
154 {
155 2191 par++;
156 }
157
3/3
✓ Branch 0 taken 1091 times.
✓ Branch 1 taken 5646 times.
✓ Branch 2 taken 4559 times.
11296 else if(*t == ')')
158 {
159 2191 par--;
160
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2191 times.
2191 if(par < 0) return false;
161 }
162
163 13799 str = t + 1;
164
6/6
✓ Branch 0 taken 6073 times.
✓ Branch 1 taken 807 times.
✓ Branch 2 taken 6430 times.
✓ Branch 3 taken 6562 times.
✓ Branch 4 taken 329 times.
✓ Branch 5 taken 5775 times.
13799 if(!*str || !par) return par == 0 ? true : false;
165 11522 }
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 49890 string& string::qnormalize()
199 {
200 49890 string& thisstring =*this;
201 49890 string out;
202 49890 const char *startstr = thisstring.data();
203 49890 const char *str = startstr;
204
4/4
✓ Branch 0 taken 29689 times.
✓ Branch 1 taken 78039 times.
✓ Branch 2 taken 28179 times.
✓ Branch 3 taken 24591 times.
107728 while((str = strpbrk(str, "'\" \t,\r")))
205 {
206
3/3
✓ Branch 0 taken 22671 times.
✓ Branch 1 taken 29099 times.
✓ Branch 2 taken 6098 times.
57868 if(is_space(*str))
207 {
208
10/10
✓ Branch 0 taken 22665 times.
✓ Branch 1 taken 22081 times.
✓ Branch 2 taken 22647 times.
✓ Branch 3 taken 24 times.
✓ Branch 4 taken 22641 times.
✓ Branch 5 taken 30 times.
✓ Branch 6 taken 22051 times.
✓ Branch 7 taken 24 times.
✓ Branch 8 taken 22051 times.
✓ Branch 9 taken 30 times.
44752 if(str[0] == ' ' && !is_space(str[1]))
209 {
210 44692 str++;
211 44692 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 7072 times.
✓ Branch 2 taken 2937 times.
13116 }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 2937 times.
6848 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 6818 times.
6848 if(!str) return thisstring;
231 6818 str++;
232 }
233 }
234
3/3
✓ Branch 0 taken 748 times.
✓ Branch 1 taken 25275 times.
✓ Branch 2 taken 23837 times.
49860 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 49860 return thisstring;
241 49890 }
242
243 71453 bool confirmquotes(const char * str)
244 {
245
3/3
✓ Branch 0 taken 25167 times.
✓ Branch 1 taken 39522 times.
✓ Branch 2 taken 14097 times.
78786 while(*str)
246 {
247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24552 times.
49719 char *dquote = strchr((char *)str, '"');
248
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24552 times.
49719 char *squote = strchr((char *)str, '\'');
249
4/4
✓ Branch 0 taken 43304 times.
✓ Branch 1 taken 6415 times.
✓ Branch 2 taken 928 times.
✓ Branch 3 taken 42376 times.
49719 if(dquote || squote)
250 {
251
6/6
✓ Branch 0 taken 6415 times.
✓ Branch 1 taken 928 times.
✓ Branch 2 taken 6313 times.
✓ Branch 3 taken 102 times.
✓ Branch 4 taken 6297 times.
✓ Branch 5 taken 16 times.
7343 if(dquote && (dquote < squote || !squote))
252 {
253
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2726 times.
6399 dquote = strchr(dquote+1, '"');
254
2/2
✓ Branch 0 taken 6391 times.
✓ Branch 1 taken 8 times.
6399 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 7333 }
265 else
266 {
267 42376 return true;
268 }
269 }
270 29067 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 56080 char ** split(char * str, char key, int * len)
303 {
304
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28278 times.
56080 char *thisentry=strchr(str, key);
305
2/2
✓ Branch 0 taken 31874 times.
✓ Branch 1 taken 24206 times.
56080 if (!thisentry)
306 {
307 31874 char ** out= typed_malloc(char*, 2);
308 31874 out[0]=str;
309 31874 out[1]=nullptr;
310
2/2
✓ Branch 0 taken 27232 times.
✓ Branch 1 taken 4642 times.
31874 if (len) *len=1;
311 31874 return out;
312 }
313 24206 int count=15; //makes the default alloc 8 elements, sounds fair.
314 24206 char ** outdata= typed_malloc(char*, (size_t)count+1);
315
316 24206 int newcount=0;
317 24206 outdata[newcount++]=str;
318 do{
319 43257 *thisentry = 0;
320 43257 thisentry++;
321 43257 outdata[newcount++]=thisentry;
322
2/2
✓ Branch 0 taken 309 times.
✓ Branch 1 taken 42948 times.
43257 if(newcount >= count)
323 {
324 309 count *= 2;
325 309 outdata = typed_realloc(char *, outdata, count);
326 }
327
4/4
✓ Branch 0 taken 9484 times.
✓ Branch 1 taken 33773 times.
✓ Branch 2 taken 9567 times.
✓ Branch 3 taken 12226 times.
43257 }while((thisentry = strchr(thisentry, key)));
328
329 24206 outdata[newcount]= nullptr;
330
2/2
✓ Branch 0 taken 23438 times.
✓ Branch 1 taken 768 times.
24206 if (len) *len=newcount;
331 24206 return outdata;
332 }
333
334 60182 char ** qsplit(char * str, char key, int * len)
335 {
336
8/10
✓ Branch 0 taken 27200 times.
✓ Branch 1 taken 32982 times.
✓ Branch 2 taken 54523 times.
✓ Branch 3 taken 2499 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 27635 times.
✓ Branch 6 taken 27323 times.
✓ Branch 7 taken 312 times.
✓ Branch 8 taken 27290 times.
✗ Branch 9 not taken.
60182 if (!strchr(str, '"') && !strchr(str, '\'')) return split(str, key, len);
337
338 5971 int count=15;
339 5971 char ** outdata= typed_malloc(char*, (size_t)count+1);
340 5971 int newcount=0;
341 5971 char * thisentry=str;
342 5971 outdata[newcount++]=thisentry;
343
3/3
✓ Branch 0 taken 30885 times.
✓ Branch 1 taken 26632 times.
✓ Branch 2 taken 2499 times.
60016 while (*thisentry) /*todo fix*/
344 {
345
3/3
✓ Branch 0 taken 3738 times.
✓ Branch 1 taken 29905 times.
✓ Branch 2 taken 20402 times.
54045 if (*thisentry == key)
346 {
347 6496 *thisentry=0;
348 6496 thisentry++;
349 6496 outdata[newcount++]=thisentry;
350
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6496 times.
6496 if(newcount >= count)
351 {
352 count *= 2;
353 outdata = typed_realloc(char *, outdata, count);
354 }
355 }
356
2/4
✓ Branch 0 taken 47549 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47549 times.
✗ Branch 3 not taken.
47549 else if(skip_quote(thisentry)) thisentry++;
357 else return nullptr;
358 }
359 5971 outdata[newcount]= nullptr;
360
2/2
✓ Branch 0 taken 5544 times.
✓ Branch 1 taken 427 times.
5971 if (len) *len=newcount;
361 5971 return outdata;
362 }
363
364 48924 char ** qsplitstr(char * str, const char * key, int * len)
365 {
366 //check if the str is found first
367
5/6
✓ Branch 0 taken 24598 times.
✓ Branch 1 taken 24326 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 24107 times.
✓ Branch 4 taken 23828 times.
✓ Branch 5 taken 279 times.
48924 if (!strstr(str, key))
368 {
369 48426 char ** out= typed_malloc(char*, 2);
370 48426 out[0]=str;
371 48426 out[1]=nullptr;
372
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48426 times.
48426 if (len) *len=1;
373 48426 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 11473 char ** qpsplit(char * str, char key, int * len)
405 {
406
8/10
✓ Branch 0 taken 4643 times.
✓ Branch 1 taken 6830 times.
✓ Branch 2 taken 9389 times.
✓ Branch 3 taken 1046 times.
✓ Branch 4 taken 4643 times.
✓ Branch 5 taken 4746 times.
✓ Branch 6 taken 4746 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4746 times.
✗ Branch 9 not taken.
11473 if (!strchr(str, '(') && !strchr(str, ')')) return qsplit(str, key, len);
407 2084 int count=7;
408 2084 char ** outdata= typed_malloc(char*, (size_t)count+1);
409
410 2084 int newcount=0;
411 2084 char * thisentry=str;
412 2084 outdata[newcount++]=thisentry;
413
3/3
✓ Branch 0 taken 6533 times.
✓ Branch 1 taken 7636 times.
✓ Branch 2 taken 1046 times.
15215 while (*thisentry)
414 {
415 //skippar(*thisentry, thisentry++, return nullptr;)
416
3/3
✓ Branch 0 taken 388 times.
✓ Branch 1 taken 6536 times.
✓ Branch 2 taken 6207 times.
13131 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 12352 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12352 times.
12352 else if(!skip_par(thisentry)) return nullptr;
428 }
429 2084 outdata[newcount]= nullptr;
430
2/2
✓ Branch 0 taken 906 times.
✓ Branch 1 taken 1178 times.
2084 if (len) *len=newcount;
431 2084 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