asar coverage - build #266


src/asar/
File: src/asar/libstr.cpp
Date: 2025-03-01 20:27:29
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 4571 void string::reallocate_capacity(unsigned int new_length)
16 {
17 // Allocate 1 extra byte for NUL terminator
18 4571 int new_alloc_capacity = bitround(new_length + 1);
19
20
3/3
✓ Branch 0 taken 2044 times.
✓ Branch 1 taken 2419 times.
✓ Branch 2 taken 108 times.
4571 if (is_inlined()) {
21 4391 data_ptr = copy(data_ptr, min(len, new_length), (char*)malloc(new_alloc_capacity));
22 }
23 else {
24 180 data_ptr = (char*)realloc(data_ptr, new_alloc_capacity);
25 }
26 4571 allocated.capacity = new_alloc_capacity - 1; // capacity field doesn't count NUL terminator
27 4571 }
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 325 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 142 times.
✓ Branch 2 taken 183 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.
325 if (str[0u] == '\xEF' && str[1u] == '\xBB' && str[2u] == '\xBF')
42 {
43 2 asar_throw_warning(0, warning_id_byte_order_mark_utf8);
44 2 return 3u;
45 }
46
47 323 return 0u;
48 }
49
50
51 331 char * readfile(const char * fname, const char * basepath)
52 {
53 331 virtual_file_handle myfile = filesystem->open_file(fname, basepath);
54
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 325 times.
331 if (myfile == INVALID_VIRTUAL_FILE_HANDLE) return nullptr;
55 325 size_t datalen = filesystem->get_file_size(myfile);
56 325 char * data= typed_malloc(char, datalen+1);
57 325 data[filesystem->read_file(myfile, data, 0u, datalen)] = 0;
58 325 filesystem->close_file(myfile);
59
60
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 323 times.
325 if (!is_valid_utf8(data))
61 {
62 2 free(data);
63 2 asar_throw_error(0, error_type_block, error_id_invalid_utf8);
64 }
65
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 321 times.
323 if(check_bom(data)){
66 2 data[0] = ' ';
67 2 data[1] = ' ';
68 2 data[2] = ' ';
69 }
70 323 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)) asar_throw_error(0, error_type_block, error_id_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 68544 inline bool skip_quote(char *&str)
122 {
123
124
5/6
✓ Branch 0 taken 3498 times.
✓ Branch 1 taken 33834 times.
✓ Branch 2 taken 2463 times.
✓ Branch 3 taken 28749 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2463 times.
68544 if(*str == '"') str = strchr(str + 1, '"');
125
4/4
✓ Branch 0 taken 420 times.
✓ Branch 1 taken 33414 times.
✓ Branch 2 taken 420 times.
✓ Branch 3 taken 28329 times.
62583 else if(*str == '\'')
126 {
127 420 int codepoint;
128
2/4
✓ Branch 0 taken 420 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 420 times.
✗ Branch 3 not taken.
840 str += utf8_val(&codepoint, str + 1) + 1;
129
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 420 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 420 times.
840 if(*str != '\'') return false;
130 }
131 68544 return str;
132 }
133
134 //eat 1 char or quote/par
135 12736 inline bool skip_par(char *&str)
136 {
137 12736 int par = 0;
138
11/12
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 6334 times.
✓ Branch 2 taken 47 times.
✓ Branch 3 taken 12686 times.
✓ Branch 4 taken 1079 times.
✓ Branch 5 taken 5211 times.
✓ Branch 6 taken 46 times.
✓ Branch 7 taken 11561 times.
✓ Branch 8 taken 1088 times.
✓ Branch 9 taken 5262 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 5262 times.
12736 if(*str != '\'' && *str != '"' && *str != '(' && *str != ')')
139 {
140 10473 str++;
141 10473 return true;
142 }
143 while(true)
144 {
145 13741 char *t = str;
146
5/6
✓ Branch 0 taken 140 times.
✓ Branch 1 taken 6711 times.
✓ Branch 2 taken 148 times.
✓ Branch 3 taken 6742 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 148 times.
13741 if(*str == '"') t = strchr(t + 1, '"');
147
4/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 6708 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 6739 times.
13453 else if(*str == '\'')
148 {
149 3 int codepoint;
150
2/3
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
6 t += utf8_val(&codepoint, t + 1) + 1;
151
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
6 if(*t != '\'') return false;
152 }
153
3/3
✓ Branch 0 taken 1087 times.
✓ Branch 1 taken 6717 times.
✓ Branch 2 taken 5643 times.
13447 else if(*t == '(')
154 {
155 2183 par++;
156 }
157
3/3
✓ Branch 0 taken 1087 times.
✓ Branch 1 taken 5630 times.
✓ Branch 2 taken 4547 times.
11264 else if(*t == ')')
158 {
159 2183 par--;
160
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2183 times.
2183 if(par < 0) return false;
161 }
162
163 13741 str = t + 1;
164
6/6
✓ Branch 0 taken 6048 times.
✓ Branch 1 taken 803 times.
✓ Branch 2 taken 6402 times.
✓ Branch 3 taken 6536 times.
✓ Branch 4 taken 326 times.
✓ Branch 5 taken 5753 times.
13741 if(!*str || !par) return par == 0 ? true : false;
165 11478 }
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 49824 string& string::qnormalize()
199 {
200 49824 string& thisstring =*this;
201 49824 string out;
202 49824 char *startstr = thisstring.raw();
203 49824 char *str = startstr;
204
4/4
✓ Branch 0 taken 29676 times.
✓ Branch 1 taken 77824 times.
✓ Branch 2 taken 28030 times.
✓ Branch 3 taken 24524 times.
107500 while((str = strpbrk(str, "'\" \t,\r")))
205 {
206
3/3
✓ Branch 0 taken 22627 times.
✓ Branch 1 taken 29018 times.
✓ Branch 2 taken 6061 times.
57706 if(is_space(*str))
207 {
208
10/10
✓ Branch 0 taken 22621 times.
✓ Branch 1 taken 21969 times.
✓ Branch 2 taken 22603 times.
✓ Branch 3 taken 24 times.
✓ Branch 4 taken 22597 times.
✓ Branch 5 taken 30 times.
✓ Branch 6 taken 21939 times.
✓ Branch 7 taken 24 times.
✓ Branch 8 taken 21939 times.
✓ Branch 9 taken 30 times.
44596 if(str[0] == ' ' && !is_space(str[1]))
209 {
210 44536 str++;
211 44536 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 3104 times.
✓ Branch 1 taken 7103 times.
✓ Branch 2 taken 2903 times.
13110 }else if(*str == ',')
218 {
219 6262 str++;
220
3/3
✓ Branch 0 taken 911 times.
✓ Branch 1 taken 3110 times.
✓ Branch 2 taken 2241 times.
6262 if(is_space(*str))
221 {
222
1/2
✓ Branch 0 taken 1828 times.
✗ Branch 1 not taken.
1828 out.append(startstr, 0, str - startstr);
223
4/4
✓ Branch 0 taken 932 times.
✓ Branch 1 taken 911 times.
✓ Branch 2 taken 938 times.
✓ Branch 3 taken 917 times.
3698 while(is_space(*str)) str++;
224 1828 startstr = str;
225 }
226 }
227 else
228 {
229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2903 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 745 times.
✓ Branch 1 taken 25276 times.
✓ Branch 2 taken 23773 times.
49794 if(startstr != thisstring.raw())
235 {
236
3/5
✓ Branch 0 taken 745 times.
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 751 times.
✗ Branch 4 not taken.
1496 out.append(startstr, 0, strlen(startstr)); //the remaining
237
238
2/3
✓ Branch 0 taken 745 times.
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
1496 thisstring = out;
239 }
240 49794 return thisstring;
241 49824 }
242
243 71299 bool confirmquotes(const char * str)
244 {
245
3/3
✓ Branch 0 taken 25103 times.
✓ Branch 1 taken 39406 times.
✓ Branch 2 taken 14045 times.
78554 while(*str)
246 {
247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24420 times.
49523 char *dquote = strchr((char *)str, '"');
248
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24420 times.
49523 char *squote = strchr((char *)str, '\'');
249
4/4
✓ Branch 0 taken 43186 times.
✓ Branch 1 taken 6337 times.
✓ Branch 2 taken 928 times.
✓ Branch 3 taken 42258 times.
49523 if(dquote || squote)
250 {
251
6/6
✓ Branch 0 taken 6337 times.
✓ Branch 1 taken 928 times.
✓ Branch 2 taken 6251 times.
✓ Branch 3 taken 86 times.
✓ Branch 4 taken 6243 times.
✓ Branch 5 taken 8 times.
7265 if(dquote && (dquote < squote || !squote))
252 {
253
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2657 times.
6329 dquote = strchr(dquote+1, '"');
254
2/2
✓ Branch 0 taken 6321 times.
✓ Branch 1 taken 8 times.
6329 if(dquote) str = dquote+1;
255 8 else return false;
256 }
257 else
258 {
259 468 int codepoint;
260
2/3
✓ Branch 0 taken 468 times.
✓ Branch 1 taken 468 times.
✗ Branch 2 not taken.
936 squote += utf8_val(&codepoint, squote + 1) + 1;
261
3/3
✓ Branch 0 taken 467 times.
✓ Branch 1 taken 468 times.
✓ Branch 2 taken 1 times.
936 if(*squote == '\'') str = squote+1;
262 2 else return false;
263 }
264 7255 }
265 else
266 {
267 42258 return true;
268 }
269 }
270 29031 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 55967 char ** split(char * str, char key, int * len)
303 {
304
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28223 times.
55967 char *thisentry=strchr(str, key);
305
2/2
✓ Branch 0 taken 31787 times.
✓ Branch 1 taken 24180 times.
55967 if (!thisentry)
306 {
307 31787 char ** out= typed_malloc(char*, 2);
308 31787 out[0]=str;
309 31787 out[1]=nullptr;
310
2/2
✓ Branch 0 taken 27145 times.
✓ Branch 1 taken 4642 times.
31787 if (len) *len=1;
311 31787 return out;
312 }
313 24180 int count=15; //makes the default alloc 8 elements, sounds fair.
314 24180 char ** outdata= typed_malloc(char*, (size_t)count+1);
315
316 24180 int newcount=0;
317 24180 outdata[newcount++]=str;
318 do{
319 43127 *thisentry = 0;
320 43127 thisentry++;
321 43127 outdata[newcount++]=thisentry;
322
2/2
✓ Branch 0 taken 307 times.
✓ Branch 1 taken 42820 times.
43127 if(newcount >= count)
323 {
324 307 count *= 2;
325 307 outdata = typed_realloc(char *, outdata, count);
326 }
327
4/4
✓ Branch 0 taken 9432 times.
✓ Branch 1 taken 33695 times.
✓ Branch 2 taken 9515 times.
✓ Branch 3 taken 12213 times.
43127 }while((thisentry = strchr(thisentry, key)));
328
329 24180 outdata[newcount]= nullptr;
330
2/2
✓ Branch 0 taken 23416 times.
✓ Branch 1 taken 764 times.
24180 if (len) *len=newcount;
331 24180 return outdata;
332 }
333
334 60101 char ** qsplit(char * str, char key, int * len)
335 {
336
8/10
✓ Branch 0 taken 27144 times.
✓ Branch 1 taken 32957 times.
✓ Branch 2 taken 54414 times.
✓ Branch 3 taken 2479 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 27582 times.
✓ Branch 6 taken 27270 times.
✓ Branch 7 taken 312 times.
✓ Branch 8 taken 27237 times.
✗ Branch 9 not taken.
60101 if (!strchr(str, '"') && !strchr(str, '\'')) return split(str, key, len);
337
338 5999 int count=15;
339 5999 char ** outdata= typed_malloc(char*, (size_t)count+1);
340 5999 int newcount=0;
341 5999 char * thisentry=str;
342 5999 outdata[newcount++]=thisentry;
343
3/3
✓ Branch 0 taken 31126 times.
✓ Branch 1 taken 26377 times.
✓ Branch 2 taken 2479 times.
59982 while (*thisentry) /*todo fix*/
344 {
345
3/3
✓ Branch 0 taken 3736 times.
✓ Branch 1 taken 30078 times.
✓ Branch 2 taken 20169 times.
53983 if (*thisentry == key)
346 {
347 6424 *thisentry=0;
348 6424 thisentry++;
349 6424 outdata[newcount++]=thisentry;
350
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6424 times.
6424 if(newcount >= count)
351 {
352 count *= 2;
353 outdata = typed_realloc(char *, outdata, count);
354 }
355 }
356
2/4
✓ Branch 0 taken 47559 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47559 times.
✗ Branch 3 not taken.
47559 else if(skip_quote(thisentry)) thisentry++;
357 else return nullptr;
358 }
359 5999 outdata[newcount]= nullptr;
360
2/2
✓ Branch 0 taken 5634 times.
✓ Branch 1 taken 365 times.
5999 if (len) *len=newcount;
361 5999 return outdata;
362 }
363
364 48858 char ** qsplitstr(char * str, const char * key, int * len)
365 {
366 //check if the str is found first
367
5/6
✓ Branch 0 taken 24599 times.
✓ Branch 1 taken 24259 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 24040 times.
✓ Branch 4 taken 23761 times.
✓ Branch 5 taken 279 times.
48858 if (!strstr(str, key))
368 {
369 48360 char ** out= typed_malloc(char*, 2);
370 48360 out[0]=str;
371 48360 out[1]=nullptr;
372
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48360 times.
48360 if (len) *len=1;
373 48360 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 11450 char ** qpsplit(char * str, char key, int * len)
405 {
406
8/10
✓ Branch 0 taken 4634 times.
✓ Branch 1 taken 6816 times.
✓ Branch 2 taken 9374 times.
✓ Branch 3 taken 1042 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.
11450 if (!strchr(str, '(') && !strchr(str, ')')) return qsplit(str, key, len);
407 2076 int count=7;
408 2076 char ** outdata= typed_malloc(char*, (size_t)count+1);
409
410 2076 int newcount=0;
411 2076 char * thisentry=str;
412 2076 outdata[newcount++]=thisentry;
413
3/3
✓ Branch 0 taken 6485 times.
✓ Branch 1 taken 7584 times.
✓ Branch 2 taken 1042 times.
15111 while (*thisentry)
414 {
415 //skippar(*thisentry, thisentry++, return nullptr;)
416
3/3
✓ Branch 0 taken 388 times.
✓ Branch 1 taken 6488 times.
✓ Branch 2 taken 6159 times.
13035 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 12256 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12256 times.
12256 else if(!skip_par(thisentry)) return nullptr;
428 }
429 2076 outdata[newcount]= nullptr;
430
2/2
✓ Branch 0 taken 910 times.
✓ Branch 1 taken 1166 times.
2076 if (len) *len=newcount;
431 2076 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