asar coverage - build #300


src/asar/
File: src/asar/libstr.cpp
Date: 2025-03-17 16:09:08
Lines:
222/272
81.6%
Functions:
16/18
88.9%
Branches:
254/393
64.6%

Line Branch Exec Source
1 #include "asar.h"
2 #include "virtualfile.h"
3 #include "unicode.h"
4 #include "libmisc.h"
5
6 #include "platform/file-helpers.h"
7
8 #define typed_malloc(type, count) (type*)malloc(sizeof(type)*(count))
9 #define typed_realloc(type, ptr, count) (type*)realloc(ptr, sizeof(type)*(count))
10
11
12 // This function is intentionally left out of the header file so that it is not visible to the
13 // compiler and less likely to be inlined into resize(). This in turn reduces the size of resize()
14 // so that it is then inlined in more places.
15 3303 void string::reallocate_capacity(unsigned int new_length)
16 {
17 // Allocate 1 extra byte for NUL terminator
18 3303 int new_alloc_capacity = bitround(new_length + 1);
19
20
3/3
✓ Branch 0 taken 1431 times.
✓ Branch 1 taken 1762 times.
✓ Branch 2 taken 110 times.
3303 if (is_inlined()) {
21 3119 data_ptr = copy(data_ptr, min(len, new_length), (char*)malloc(new_alloc_capacity));
22 }
23 else {
24 184 data_ptr = (char*)realloc(data_ptr, new_alloc_capacity);
25 }
26 3303 allocated.capacity = new_alloc_capacity - 1; // capacity field doesn't count NUL terminator
27 3303 }
28
29
30 // Detects if str starts with a UTF-8 byte order mark.
31 // If so, throws a warning, then returns the number of bytes we should skip ahead in the string.
32 329 static size_t check_bom(const char* str)
33 {
34 // RPG Hacker: We could also check for BoMs of incompatible encodings here (like UTF-16)
35 // and throw errors, but not sure if that's worth adding. Asar never supported any wide
36 // encodings to begin with, so it's unreasonable to assume that any UTF-16 patches currently
37 // exist for it. As for future patches, those should be caught by the "must be UTF-8" checks
38 // I have already implemented further below.
39 // I think UTF-8 + BoM is the only case that could lead to confusion if we didn't handle it,
40 // so that's why I have added this.
41
6/9
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 144 times.
✓ Branch 2 taken 185 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
329 if (str[0u] == '\xEF' && str[1u] == '\xBB' && str[2u] == '\xBF')
42 {
43 2 throw_warning(0, warn_byte_order_mark_utf8);
44 2 return 3u;
45 }
46
47 327 return 0u;
48 }
49
50
51 335 char * readfile(const char * fname, const char * basepath)
52 {
53 335 virtual_file_handle myfile = filesystem->open_file(fname, basepath);
54
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 329 times.
335 if (myfile == INVALID_VIRTUAL_FILE_HANDLE) return nullptr;
55 329 size_t datalen = filesystem->get_file_size(myfile);
56 329 char * data= typed_malloc(char, datalen+1);
57 329 data[filesystem->read_file(myfile, data, 0u, datalen)] = 0;
58 329 filesystem->close_file(myfile);
59
60
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 327 times.
329 if (!is_valid_utf8(data, datalen))
61 {
62 2 free(data);
63 2 throw_err_block(0, err_invalid_utf8);
64 }
65
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 325 times.
327 if(check_bom(data)){
66 2 data[0] = ' ';
67 2 data[1] = ' ';
68 2 data[2] = ' ';
69 }
70 327 return data;
71 }
72
73 // RPG Hacker: like readfile(), but doesn't use virtual file system
74 // and instead read our file directly.
75 8 char * readfilenative(const char * fname)
76 {
77 8 FileHandleType myfile = open_file(fname, FileOpenMode_Read);
78
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
8 if (myfile == InvalidFileHandle) return nullptr;
79 2 size_t datalen = (size_t)get_file_size(myfile);
80 2 char * data = typed_malloc(char, datalen + 1);
81 2 data[read_file(myfile, data, datalen)] = 0;
82 2 close_file(myfile);
83
84
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!is_valid_utf8(data, datalen)) throw_err_block(0, err_invalid_utf8);
85
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(check_bom(data)){
86 data[0] = ' ';
87 data[1] = ' ';
88 data[2] = ' ';
89 }
90 2 return data;
91 }
92
93 266 bool readfile(const char * fname, const char * basepath, char ** data, int * len)
94 {
95 266 virtual_file_handle myfile = filesystem->open_file(fname, basepath);
96
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 254 times.
266 if (!myfile) return false;
97 254 size_t datalen = filesystem->get_file_size(myfile);
98 254 *data= typed_malloc(char, datalen);
99 254 *len = (int)filesystem->read_file(myfile, *data, 0, datalen);
100 254 filesystem->close_file(myfile);
101 254 return true;
102 }
103
104 #define isq(n) (((0x2227 ^ (0x0101 * (n))) - 0x0101UL) & ~(0x2227 ^ (0x0101 * (n))) & 0x8080UL)
105 #define isqp(n) (((0x22272829 ^ (0x01010101 * (n))) - 0x01010101UL) & ~(0x22272829 ^ (0x01010101 * (n))) & 0x80808080UL)
106
107 // RPG Hacker: Only index this with ASCII characters.
108 // Anything else doesn't make sense, anyways.
109 const bool qparlut[128] = {
110 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
112 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0,
113 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
114 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
115 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
116 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
117 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
118 };
119
120 //this will leave the last char found as the one pointed at
121 22208 inline bool skip_quote(char *&str)
122 {
123
124
5/6
✓ Branch 0 taken 344 times.
✓ Branch 1 taken 10206 times.
✓ Branch 2 taken 357 times.
✓ Branch 3 taken 11301 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 357 times.
22208 if(*str == '"') str = strchr(str + 1, '"');
125
4/4
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 10152 times.
✓ Branch 2 taken 54 times.
✓ Branch 3 taken 11247 times.
21507 else if(*str == '\'')
126 {
127 54 int codepoint;
128
2/4
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 54 times.
✗ Branch 3 not taken.
108 str += utf8_val(&codepoint, str + 1) + 1;
129
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 54 times.
108 if(*str != '\'') return false;
130 }
131 22208 return str;
132 }
133
134 //eat 1 char or quote/par
135 16888 inline bool skip_par(char *&str)
136 {
137 16888 int par = 0;
138
11/12
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 8407 times.
✓ Branch 2 taken 95 times.
✓ Branch 3 taken 16787 times.
✓ Branch 4 taken 1071 times.
✓ Branch 5 taken 7247 times.
✓ Branch 6 taken 91 times.
✓ Branch 7 taken 15625 times.
✓ Branch 8 taken 1080 times.
✓ Branch 9 taken 7298 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 7298 times.
16888 if(*str != '\'' && *str != '"' && *str != '(' && *str != ')')
139 {
140 14545 str++;
141 14545 return true;
142 }
143 while(true)
144 {
145 13685 char *t = str;
146
5/6
✓ Branch 0 taken 191 times.
✓ Branch 1 taken 6632 times.
✓ Branch 2 taken 199 times.
✓ Branch 3 taken 6663 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 199 times.
13685 if(*str == '"') t = strchr(t + 1, '"');
147
4/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6626 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6657 times.
13295 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 1079 times.
✓ Branch 1 taken 6635 times.
✓ Branch 2 taken 5569 times.
13283 else if(*t == '(')
154 {
155 2167 par++;
156 }
157
3/3
✓ Branch 0 taken 1079 times.
✓ Branch 1 taken 5556 times.
✓ Branch 2 taken 4481 times.
11116 else if(*t == ')')
158 {
159 2167 par--;
160
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2167 times.
2167 if(par < 0) return false;
161 }
162
163 13685 str = t + 1;
164
6/6
✓ Branch 0 taken 6001 times.
✓ Branch 1 taken 822 times.
✓ Branch 2 taken 6376 times.
✓ Branch 3 taken 6487 times.
✓ Branch 4 taken 347 times.
✓ Branch 5 taken 5685 times.
13685 if(!*str || !par) return par == 0 ? true : false;
165 11342 }
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 // * convert tabs to spaces
199 // * collapse multiple consecutive spaces into one
200 // * delete spaces after comma
201 // in total, this means that after qnormalize, splitting by spaces will split the input into "words".
202 57961 string& string::qnormalize()
203 {
204 57961 string& thisstring =*this;
205 57961 string out;
206 57961 const char *startstr = thisstring.data();
207 57961 const char *str = startstr;
208
4/4
✓ Branch 0 taken 35364 times.
✓ Branch 1 taken 93799 times.
✓ Branch 2 taken 35868 times.
✓ Branch 3 taken 29130 times.
129163 while((str = strpbrk(str, "'\" \t,\r")))
209 {
210
3/3
✓ Branch 0 taken 25528 times.
✓ Branch 1 taken 35781 times.
✓ Branch 2 taken 9923 times.
71232 if(is_space(*str))
211 {
212
10/10
✓ Branch 0 taken 25522 times.
✓ Branch 1 taken 25945 times.
✓ Branch 2 taken 25504 times.
✓ Branch 3 taken 24 times.
✓ Branch 4 taken 25498 times.
✓ Branch 5 taken 30 times.
✓ Branch 6 taken 25915 times.
✓ Branch 7 taken 24 times.
✓ Branch 8 taken 25915 times.
✓ Branch 9 taken 30 times.
51473 if(str[0] == ' ' && !is_space(str[1]))
213 {
214 51413 str++;
215 51413 continue;
216 }
217
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 out.append(startstr, 0, str - startstr);
218
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 out += ' ';
219
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++;
220 60 startstr = str;
221
3/3
✓ Branch 0 taken 3116 times.
✓ Branch 1 taken 9890 times.
✓ Branch 2 taken 6753 times.
19759 }else if(*str == ',')
222 {
223 6286 str++;
224
3/3
✓ Branch 0 taken 914 times.
✓ Branch 1 taken 3122 times.
✓ Branch 2 taken 2250 times.
6286 if(is_space(*str))
225 {
226
1/2
✓ Branch 0 taken 1834 times.
✗ Branch 1 not taken.
1834 out.append(startstr, 0, str - startstr);
227
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++;
228 1834 startstr = str;
229 }
230 }
231 else
232 {
233
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6753 times.
13473 str = strchr(str + 1, *str); //confirm quotes has already been run, so this should be okay
234
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 13443 times.
13473 if(!str) return thisstring;
235 13443 str++;
236 }
237 }
238
3/3
✓ Branch 0 taken 748 times.
✓ Branch 1 taken 28807 times.
✓ Branch 2 taken 28376 times.
57931 if(startstr != thisstring.data())
239 {
240
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
241
242 1502 thisstring = std::move(out);
243 }
244 57931 return thisstring;
245 57961 }
246
247 79988 bool confirmquotes(const char * str)
248 {
249
3/3
✓ Branch 0 taken 27955 times.
✓ Branch 1 taken 47100 times.
✓ Branch 2 taken 18887 times.
93942 while(*str)
250 {
251
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28347 times.
56302 char *dquote = strchr((char *)str, '"');
252
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28347 times.
56302 char *squote = strchr((char *)str, '\'');
253
4/4
✓ Branch 0 taken 43266 times.
✓ Branch 1 taken 13036 times.
✓ Branch 2 taken 928 times.
✓ Branch 3 taken 42338 times.
56302 if(dquote || squote)
254 {
255
6/6
✓ Branch 0 taken 13036 times.
✓ Branch 1 taken 928 times.
✓ Branch 2 taken 12934 times.
✓ Branch 3 taken 102 times.
✓ Branch 4 taken 12918 times.
✓ Branch 5 taken 16 times.
13964 if(dquote && (dquote < squote || !squote))
256 {
257
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6540 times.
13020 dquote = strchr(dquote+1, '"');
258
2/2
✓ Branch 0 taken 13012 times.
✓ Branch 1 taken 8 times.
13020 if(dquote) str = dquote+1;
259 8 else return false;
260 }
261 else
262 {
263 472 int codepoint;
264
2/3
✓ Branch 0 taken 472 times.
✓ Branch 1 taken 472 times.
✗ Branch 2 not taken.
944 squote += utf8_val(&codepoint, squote + 1) + 1;
265
3/3
✓ Branch 0 taken 471 times.
✓ Branch 1 taken 472 times.
✓ Branch 2 taken 1 times.
944 if(*squote == '\'') str = squote+1;
266 2 else return false;
267 }
268 13954 }
269 else
270 {
271 42338 return true;
272 }
273 }
274 37640 return true;
275 }
276
277 724 bool confirmqpar(const char * str)
278 {
279 //todo fully optimize
280 724 int par = 0;
281
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++;
282
3/3
✓ Branch 0 taken 905 times.
✓ Branch 1 taken 1288 times.
✓ Branch 2 taken 369 times.
2562 while(*str)
283 {
284
3/3
✓ Branch 0 taken 183 times.
✓ Branch 1 taken 905 times.
✓ Branch 2 taken 750 times.
1838 if(*str == '"')
285 {
286
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 183 times.
366 str = strchr(str + 1, '"');
287
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 183 times.
✓ Branch 2 taken 183 times.
366 if(!str++) return false;
288 }
289
3/3
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 722 times.
✓ Branch 2 taken 738 times.
1472 else if(*str == '\'')
290 {
291 12 int codepoint;
292
2/3
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
24 str += utf8_val(&codepoint, str + 1) + 1;
293
2/3
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
24 if(*str == '\'') str++;
294 else return false;
295 }
296 else
297 {
298
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 738 times.
1448 par += 1 - ((*str++ - '(') << 1);
299
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1448 times.
1448 if(par < 0) return false;
300 }
301
6/8
✗ Branch 0 not taken.
✓ Branch 1 taken 2265 times.
✓ Branch 2 taken 1360 times.
✓ Branch 3 taken 3212 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2307 times.
✓ Branch 6 taken 1374 times.
✓ Branch 7 taken 933 times.
4572 while((unsigned char)*str >= 128 || !qparlut[(unsigned char)*str]) str++;
302 }
303 724 return !par;
304 }
305
306 12029 char ** split(char * str, char key, int * len)
307 {
308
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6083 times.
12029 char *thisentry=strchr(str, key);
309
2/2
✓ Branch 0 taken 9087 times.
✓ Branch 1 taken 2942 times.
12029 if (!thisentry)
310 {
311 9087 char ** out= typed_malloc(char*, 2);
312 9087 out[0]=str;
313 9087 out[1]=nullptr;
314
2/2
✓ Branch 0 taken 4493 times.
✓ Branch 1 taken 4594 times.
9087 if (len) *len=1;
315 9087 return out;
316 }
317 2942 int count=15; //makes the default alloc 8 elements, sounds fair.
318 2942 char ** outdata= typed_malloc(char*, (size_t)count+1);
319
320 2942 int newcount=0;
321 2942 outdata[newcount++]=str;
322 do{
323 15178 *thisentry = 0;
324 15178 thisentry++;
325 15178 outdata[newcount++]=thisentry;
326
2/2
✓ Branch 0 taken 309 times.
✓ Branch 1 taken 14869 times.
15178 if(newcount >= count)
327 {
328 309 count *= 2;
329 309 outdata = typed_realloc(char *, outdata, count);
330 }
331
4/4
✓ Branch 0 taken 6084 times.
✓ Branch 1 taken 9094 times.
✓ Branch 2 taken 6152 times.
✓ Branch 3 taken 1489 times.
15178 }while((thisentry = strchr(thisentry, key)));
332
333 2942 outdata[newcount]= nullptr;
334
2/2
✓ Branch 0 taken 2174 times.
✓ Branch 1 taken 768 times.
2942 if (len) *len=newcount;
335 2942 return outdata;
336 }
337
338 12027 char ** qsplit(char * str, char key, int * len)
339 {
340
8/10
✓ Branch 0 taken 5740 times.
✓ Branch 1 taken 6287 times.
✓ Branch 2 taken 11549 times.
✓ Branch 3 taken 256 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 5836 times.
✓ Branch 6 taken 5809 times.
✓ Branch 7 taken 27 times.
✓ Branch 8 taken 5800 times.
✗ Branch 9 not taken.
12027 if (!strchr(str, '"') && !strchr(str, '\'')) return split(str, key, len);
341
342 505 int count=15;
343 505 char ** outdata= typed_malloc(char*, (size_t)count+1);
344 505 int newcount=0;
345 505 char * thisentry=str;
346 505 outdata[newcount++]=thisentry;
347
3/3
✓ Branch 0 taken 739 times.
✓ Branch 1 taken 995 times.
✓ Branch 2 taken 256 times.
1990 while (*thisentry) /*todo fix*/
348 {
349
3/3
✓ Branch 0 taken 131 times.
✓ Branch 1 taken 739 times.
✓ Branch 2 taken 615 times.
1485 if (*thisentry == key)
350 {
351 262 *thisentry=0;
352 262 thisentry++;
353 262 outdata[newcount++]=thisentry;
354
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 262 times.
262 if(newcount >= count)
355 {
356 count *= 2;
357 outdata = typed_realloc(char *, outdata, count);
358 }
359 }
360
2/4
✓ Branch 0 taken 1223 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1223 times.
✗ Branch 3 not taken.
1223 else if(skip_quote(thisentry)) thisentry++;
361 else return nullptr;
362 }
363 505 outdata[newcount]= nullptr;
364
2/2
✓ Branch 0 taken 150 times.
✓ Branch 1 taken 355 times.
505 if (len) *len=newcount;
365 505 return outdata;
366 }
367
368 56887 char ** qsplitstr(char * str, const char * key, int * len)
369 {
370 //check if the str is found first
371
5/6
✓ Branch 0 taken 28076 times.
✓ Branch 1 taken 28811 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 28592 times.
✓ Branch 4 taken 28313 times.
✓ Branch 5 taken 279 times.
56887 if (!strstr(str, key))
372 {
373 56389 char ** out= typed_malloc(char*, 2);
374 56389 out[0]=str;
375 56389 out[1]=nullptr;
376
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56389 times.
56389 if (len) *len=1;
377 56389 return out;
378 }
379
380
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 279 times.
498 int keylen=(int)strlen(key);
381 498 int count=15;
382 498 char ** outdata= typed_malloc(char*, (size_t)count+1);
383 498 int newcount=0;
384 498 char * thisentry=str;
385 498 outdata[newcount++]=thisentry;
386
3/3
✓ Branch 0 taken 10842 times.
✓ Branch 1 taken 12231 times.
✓ Branch 2 taken 279 times.
23352 while (*thisentry) /*todo fix*/
387 {
388
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))
389 {
390 1869 *thisentry=0;
391 1869 thisentry+=keylen;
392 1869 outdata[newcount++]=thisentry;
393
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1869 times.
1869 if(newcount >= count)
394 {
395 count *= 2;
396 outdata = typed_realloc(char *, outdata, count);
397 }
398 }
399
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++;
400 else return nullptr;
401 }
402 498 outdata[newcount]= nullptr;
403
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 498 times.
498 if (len) *len=newcount;
404 498 return outdata;
405 }
406
407 //this function is most commonly called in cases where additional chars are very likely
408 12496 char ** qpsplit(char * str, char key, int * len)
409 {
410
8/10
✓ Branch 0 taken 5258 times.
✓ Branch 1 taken 7238 times.
✓ Branch 2 taken 10616 times.
✓ Branch 3 taken 941 times.
✓ Branch 4 taken 5258 times.
✓ Branch 5 taken 5358 times.
✓ Branch 6 taken 5358 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5358 times.
✗ Branch 9 not taken.
12496 if (!strchr(str, '(') && !strchr(str, ')')) return qsplit(str, key, len);
411 1880 int count=7;
412 1880 char ** outdata= typed_malloc(char*, (size_t)count+1);
413
414 1880 int newcount=0;
415 1880 char * thisentry=str;
416 1880 outdata[newcount++]=thisentry;
417
3/3
✓ Branch 0 taken 5462 times.
✓ Branch 1 taken 6418 times.
✓ Branch 2 taken 941 times.
12821 while (*thisentry)
418 {
419 //skippar(*thisentry, thisentry++, return nullptr;)
420
3/3
✓ Branch 0 taken 364 times.
✓ Branch 1 taken 5465 times.
✓ Branch 2 taken 5112 times.
10941 if (*thisentry == key)
421 {
422 731 *thisentry=0;
423 731 thisentry++;
424 731 outdata[newcount++]=thisentry;
425
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 729 times.
731 if(newcount >= count)
426 {
427 2 count *= 2;
428 2 outdata = typed_realloc(char *, outdata, count);
429 }
430 }
431
2/4
✓ Branch 0 taken 10210 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10210 times.
10210 else if(!skip_par(thisentry)) return nullptr;
432 }
433 1880 outdata[newcount]= nullptr;
434
2/2
✓ Branch 0 taken 906 times.
✓ Branch 1 taken 974 times.
1880 if (len) *len=newcount;
435 1880 return outdata;
436 }
437
438 string &itrim(string &input, const char * left, const char * right)
439 {
440 bool nukeright=true;
441 int totallen=input.length();
442 int rightlen=(int)strlen(right);
443 if (rightlen && rightlen<=totallen)
444 {
445 const char * rightend=right+rightlen;
446 const char * strend=input.data()+totallen;
447 while (right!=rightend)
448 {
449 rightend--;
450 strend--;
451 if (to_lower(*strend)!=to_lower(*rightend)) nukeright=false;
452 }
453 if (nukeright)
454 {
455 totallen-=rightlen;
456 input.truncate(totallen);
457 }
458 }
459 bool nukeleft=true;
460 int leftlen = strlen(left);
461 if(leftlen == 1 && input.data()[0] == left[0])
462 {
463 return input = string(input.data()+1, (input.length()-1));
464 }
465 else
466 {
467 for (int i = 0; i < leftlen; i++)
468 {
469 if (to_lower(input.data()[i])!=to_lower(left[i])) nukeleft=false;
470 }
471 if (nukeleft) input = string(input.data()+leftlen, (input.length()-leftlen));
472 }
473 return input;
474 }
475
476 1026 char* strqpchr(char* str, char key)
477 {
478
3/3
✓ Branch 0 taken 3492 times.
✓ Branch 1 taken 3693 times.
✓ Branch 2 taken 159 times.
7344 while (*str)
479 {
480
3/3
✓ Branch 0 taken 357 times.
✓ Branch 1 taken 3492 times.
✓ Branch 2 taken 3183 times.
7032 if (*str == key) return str;
481
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6318 times.
6318 else if(!skip_par(str)) return nullptr;
482 }
483 312 return nullptr;
484 }
485
486 114 char* strqpstr(char* str, const char* key)
487 {
488
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
114 size_t keylen = strlen(key);
489
3/3
✓ Branch 0 taken 234 times.
✓ Branch 1 taken 237 times.
✓ Branch 2 taken 3 times.
474 while (*str)
490 {
491
5/6
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 414 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 234 times.
✓ Branch 4 taken 54 times.
✓ Branch 5 taken 180 times.
468 if (!strncmp(str, key, keylen)) return str;
492
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 360 times.
360 else if(!skip_par(str)) return nullptr;
493 }
494 6 return nullptr;
495 }
496
497 extern const uint8_t char_props[256] = {
498 //x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF
499 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x00,0x00, // 0x
500 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 1x
501 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 2x !"#$%&'()*+,-./
502 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x00,0x00,0x00,0x00,0x00,0x00, // 3x 0123456789:;<=>?
503 0x00,0x23,0x23,0x23,0x23,0x23,0x23,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, // 4x @ABCDEFGHIJKLMNO
504 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x00,0x00,0x00,0x00,0x08, // 5x PQRSTUVWXYZ[\]^_
505 0x00,0x25,0x25,0x25,0x25,0x25,0x25,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24, // 6x `abcdefghijklmno
506 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x00,0x00,0x00,0x00,0x00, // 7x pqrstuvwxyz{|}~
507 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 8x
508 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 9x
509 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Ax
510 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Bx
511 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Cx
512 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Dx
513 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Ex
514 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Fx
515 };
516