asar coverage - build #324


src/asar/
File: src/asar/libstr.cpp
Date: 2025-11-02 06:43:51
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 2714 void string::reallocate_capacity(unsigned int new_length)
16 {
17 // Allocate 1 extra byte for NUL terminator
18 2714 int new_alloc_capacity = bitround(new_length + 1);
19
20
3/3
✓ Branch 0 taken 1182 times.
✓ Branch 1 taken 1425 times.
✓ Branch 2 taken 107 times.
2714 if (is_inlined()) {
21 2533 data_ptr = copy(data_ptr, min(len, new_length), (char*)malloc(new_alloc_capacity));
22 }
23 else {
24 181 data_ptr = (char*)realloc(data_ptr, new_alloc_capacity);
25 }
26 2714 allocated.capacity = new_alloc_capacity - 1; // capacity field doesn't count NUL terminator
27 2714 }
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 332 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 146 times.
✓ Branch 2 taken 186 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.
332 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 330 return 0u;
48 }
49
50
51 338 char * readfile(const char * fname, const char * basepath)
52 {
53 338 virtual_file_handle myfile = filesystem->open_file(fname, basepath);
54
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 332 times.
338 if (myfile == INVALID_VIRTUAL_FILE_HANDLE) return nullptr;
55 332 size_t datalen = filesystem->get_file_size(myfile);
56 332 char * data= typed_malloc(char, datalen+1);
57 332 data[filesystem->read_file(myfile, data, 0u, datalen)] = 0;
58 332 filesystem->close_file(myfile);
59
60
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 330 times.
332 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 328 times.
330 if(check_bom(data)){
66 2 data[0] = ' ';
67 2 data[1] = ' ';
68 2 data[2] = ' ';
69 }
70 330 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 267 bool readfile(const char * fname, const char * basepath, char ** data, int * len)
94 {
95 267 virtual_file_handle myfile = filesystem->open_file(fname, basepath);
96
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 255 times.
267 if (!myfile) return false;
97 255 size_t datalen = filesystem->get_file_size(myfile);
98 255 *data= typed_malloc(char, datalen);
99 255 *len = (int)filesystem->read_file(myfile, *data, 0, datalen);
100 255 filesystem->close_file(myfile);
101 255 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 22206 inline bool skip_quote(char *&str)
122 {
123
124
5/6
✓ Branch 0 taken 344 times.
✓ Branch 1 taken 10206 times.
✓ Branch 2 taken 355 times.
✓ Branch 3 taken 11301 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 355 times.
22206 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 22206 return str;
132 }
133
134 //eat 1 char or quote/par
135 17104 inline bool skip_par(char *&str)
136 {
137 17104 int par = 0;
138
11/12
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 8515 times.
✓ Branch 2 taken 104 times.
✓ Branch 3 taken 16994 times.
✓ Branch 4 taken 1083 times.
✓ Branch 5 taken 7334 times.
✓ Branch 6 taken 100 times.
✓ Branch 7 taken 15811 times.
✓ Branch 8 taken 1092 times.
✓ Branch 9 taken 7385 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 7385 times.
17104 if(*str != '\'' && *str != '"' && *str != '(' && *str != ')')
139 {
140 14719 str++;
141 14719 return true;
142 }
143 while(true)
144 {
145 13883 char *t = str;
146
5/6
✓ Branch 0 taken 215 times.
✓ Branch 1 taken 6707 times.
✓ Branch 2 taken 223 times.
✓ Branch 3 taken 6738 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 223 times.
13883 if(*str == '"') t = strchr(t + 1, '"');
147
4/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6701 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6732 times.
13445 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 6710 times.
✓ Branch 2 taken 5632 times.
13433 else if(*t == '(')
154 {
155 2191 par++;
156 }
157
3/3
✓ Branch 0 taken 1091 times.
✓ Branch 1 taken 5619 times.
✓ Branch 2 taken 4532 times.
11242 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 13883 str = t + 1;
164
6/6
✓ Branch 0 taken 6091 times.
✓ Branch 1 taken 831 times.
✓ Branch 2 taken 6478 times.
✓ Branch 3 taken 6574 times.
✓ Branch 4 taken 359 times.
✓ Branch 5 taken 5763 times.
13883 if(!*str || !par) return par == 0 ? true : false;
165 11498 }
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 58181 string& string::qnormalize()
203 {
204 58181 string& thisstring =*this;
205 58181 string out;
206 58181 const char *startstr = thisstring.data();
207 58181 const char *str = startstr;
208
4/4
✓ Branch 0 taken 35520 times.
✓ Branch 1 taken 94118 times.
✓ Branch 2 taken 35967 times.
✓ Branch 3 taken 29197 times.
129638 while((str = strpbrk(str, "'\" \t,\r")))
209 {
210
3/3
✓ Branch 0 taken 25636 times.
✓ Branch 1 taken 35892 times.
✓ Branch 2 taken 9959 times.
71487 if(is_space(*str))
211 {
212
10/10
✓ Branch 0 taken 25630 times.
✓ Branch 1 taken 26008 times.
✓ Branch 2 taken 25612 times.
✓ Branch 3 taken 24 times.
✓ Branch 4 taken 25606 times.
✓ Branch 5 taken 30 times.
✓ Branch 6 taken 25978 times.
✓ Branch 7 taken 24 times.
✓ Branch 8 taken 25978 times.
✓ Branch 9 taken 30 times.
51644 if(str[0] == ' ' && !is_space(str[1]))
213 {
214 51584 str++;
215 51584 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 3140 times.
✓ Branch 1 taken 9935 times.
✓ Branch 2 taken 6768 times.
19843 }else if(*str == ',')
222 {
223 6331 str++;
224
3/3
✓ Branch 0 taken 938 times.
✓ Branch 1 taken 3146 times.
✓ Branch 2 taken 2247 times.
6331 if(is_space(*str))
225 {
226
1/2
✓ Branch 0 taken 1882 times.
✗ Branch 1 not taken.
1882 out.append(startstr, 0, str - startstr);
227
4/4
✓ Branch 0 taken 959 times.
✓ Branch 1 taken 938 times.
✓ Branch 2 taken 965 times.
✓ Branch 3 taken 944 times.
3806 while(is_space(*str)) str++;
228 1882 startstr = str;
229 }
230 }
231 else
232 {
233
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6768 times.
13512 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 13482 times.
13512 if(!str) return thisstring;
235 13482 str++;
236 }
237 }
238
3/3
✓ Branch 0 taken 760 times.
✓ Branch 1 taken 28960 times.
✓ Branch 2 taken 28431 times.
58151 if(startstr != thisstring.data())
239 {
240
2/4
✓ Branch 0 taken 760 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 766 times.
✗ Branch 3 not taken.
1526 out.append(startstr, 0, (thisstring.data() + thisstring.length()) - startstr); //the remaining
241
242 1526 thisstring = std::move(out);
243 }
244 58151 return thisstring;
245 58181 }
246
247 69850 bool confirmquotes(const char * str)
248 {
249
3/3
✓ Branch 0 taken 24207 times.
✓ Branch 1 taken 41853 times.
✓ Branch 2 taken 17447 times.
83507 while(*str)
250 {
251
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24483 times.
48690 char *dquote = strchr((char *)str, '"');
252
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24483 times.
48690 char *squote = strchr((char *)str, '\'');
253
4/4
✓ Branch 0 taken 35927 times.
✓ Branch 1 taken 12763 times.
✓ Branch 2 taken 904 times.
✓ Branch 3 taken 35023 times.
48690 if(dquote || squote)
254 {
255
6/6
✓ Branch 0 taken 12763 times.
✓ Branch 1 taken 904 times.
✓ Branch 2 taken 12667 times.
✓ Branch 3 taken 96 times.
✓ Branch 4 taken 12651 times.
✓ Branch 5 taken 16 times.
13667 if(dquote && (dquote < squote || !squote))
256 {
257
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6388 times.
12747 dquote = strchr(dquote+1, '"');
258
2/2
✓ Branch 0 taken 12739 times.
✓ Branch 1 taken 8 times.
12747 if(dquote) str = dquote+1;
259 8 else return false;
260 }
261 else
262 {
263 460 int codepoint;
264
2/3
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 460 times.
✗ Branch 2 not taken.
920 squote += utf8_val(&codepoint, squote + 1) + 1;
265
3/3
✓ Branch 0 taken 459 times.
✓ Branch 1 taken 460 times.
✓ Branch 2 taken 1 times.
920 if(*squote == '\'') str = squote+1;
266 2 else return false;
267 }
268 13657 }
269 else
270 {
271 35023 return true;
272 }
273 }
274 34817 return true;
275 }
276
277 710 bool confirmqpar(const char * str)
278 {
279 //todo fully optimize
280 710 int par = 0;
281
6/8
✗ Branch 0 not taken.
✓ Branch 1 taken 4810 times.
✓ Branch 2 taken 4455 times.
✓ Branch 3 taken 5165 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 4810 times.
✓ Branch 6 taken 4455 times.
✓ Branch 7 taken 355 times.
9620 while((unsigned char)*str >= 128 || !qparlut[(unsigned char)*str]) str++;
282
3/3
✓ Branch 0 taken 905 times.
✓ Branch 1 taken 1260 times.
✓ Branch 2 taken 355 times.
2520 while(*str)
283 {
284
3/3
✓ Branch 0 taken 183 times.
✓ Branch 1 taken 905 times.
✓ Branch 2 taken 722 times.
1810 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 710 times.
1444 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 710 times.
1420 par += 1 - ((*str++ - '(') << 1);
299
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1420 times.
1420 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 3170 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2265 times.
✓ Branch 6 taken 1360 times.
✓ Branch 7 taken 905 times.
4530 while((unsigned char)*str >= 128 || !qparlut[(unsigned char)*str]) str++;
302 }
303 710 return !par;
304 }
305
306 12039 char ** split(char * str, char key, int * len)
307 {
308
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6076 times.
12039 char *thisentry=strchr(str, key);
309
2/2
✓ Branch 0 taken 9091 times.
✓ Branch 1 taken 2948 times.
12039 if (!thisentry)
310 {
311 9091 char ** out= typed_malloc(char*, 2);
312 9091 out[0]=str;
313 9091 out[1]=nullptr;
314
2/2
✓ Branch 0 taken 4479 times.
✓ Branch 1 taken 4612 times.
9091 if (len) *len=1;
315 9091 return out;
316 }
317 2948 int count=15; //makes the default alloc 8 elements, sounds fair.
318 2948 char ** outdata= typed_malloc(char*, (size_t)count+1);
319
320 2948 int newcount=0;
321 2948 outdata[newcount++]=str;
322 do{
323 15260 *thisentry = 0;
324 15260 thisentry++;
325 15260 outdata[newcount++]=thisentry;
326
2/2
✓ Branch 0 taken 308 times.
✓ Branch 1 taken 14952 times.
15260 if(newcount >= count)
327 {
328 308 count *= 2;
329 308 outdata = typed_realloc(char *, outdata, count);
330 }
331
4/4
✓ Branch 0 taken 6131 times.
✓ Branch 1 taken 9129 times.
✓ Branch 2 taken 6181 times.
✓ Branch 3 taken 1490 times.
15260 }while((thisentry = strchr(thisentry, key)));
332
333 2948 outdata[newcount]= nullptr;
334
2/2
✓ Branch 0 taken 2180 times.
✓ Branch 1 taken 768 times.
2948 if (len) *len=newcount;
335 2948 return outdata;
336 }
337
338 12034 char ** qsplit(char * str, char key, int * len)
339 {
340
8/10
✓ Branch 0 taken 5755 times.
✓ Branch 1 taken 6279 times.
✓ Branch 2 taken 11558 times.
✓ Branch 3 taken 254 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 5830 times.
✓ Branch 6 taken 5803 times.
✓ Branch 7 taken 27 times.
✓ Branch 8 taken 5794 times.
✗ Branch 9 not taken.
12034 if (!strchr(str, '"') && !strchr(str, '\'')) return split(str, key, len);
341
342 503 int count=15;
343 503 char ** outdata= typed_malloc(char*, (size_t)count+1);
344 503 int newcount=0;
345 503 char * thisentry=str;
346 503 outdata[newcount++]=thisentry;
347
3/3
✓ Branch 0 taken 739 times.
✓ Branch 1 taken 993 times.
✓ Branch 2 taken 254 times.
1986 while (*thisentry) /*todo fix*/
348 {
349
3/3
✓ Branch 0 taken 131 times.
✓ Branch 1 taken 739 times.
✓ Branch 2 taken 613 times.
1483 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 1221 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1221 times.
✗ Branch 3 not taken.
1221 else if(skip_quote(thisentry)) thisentry++;
361 else return nullptr;
362 }
363 503 outdata[newcount]= nullptr;
364
2/2
✓ Branch 0 taken 150 times.
✓ Branch 1 taken 353 times.
503 if (len) *len=newcount;
365 503 return outdata;
366 }
367
368 57133 char ** qsplitstr(char * str, const char * key, int * len)
369 {
370 //check if the str is found first
371
5/6
✓ Branch 0 taken 28226 times.
✓ Branch 1 taken 28907 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 28688 times.
✓ Branch 4 taken 28409 times.
✓ Branch 5 taken 279 times.
57133 if (!strstr(str, key))
372 {
373 56635 char ** out= typed_malloc(char*, 2);
374 56635 out[0]=str;
375 56635 out[1]=nullptr;
376
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56635 times.
56635 if (len) *len=1;
377 56635 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 12497 char ** qpsplit(char * str, char key, int * len)
409 {
410
8/10
✓ Branch 0 taken 5270 times.
✓ Branch 1 taken 7227 times.
✓ Branch 2 taken 10617 times.
✓ Branch 3 taken 941 times.
✓ Branch 4 taken 5270 times.
✓ Branch 5 taken 5347 times.
✓ Branch 6 taken 5347 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5347 times.
✗ Branch 9 not taken.
12497 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 1056 char* strqpchr(char* str, char key)
477 {
478
3/3
✓ Branch 0 taken 3600 times.
✓ Branch 1 taken 3816 times.
✓ Branch 2 taken 174 times.
7590 while (*str)
479 {
480
3/3
✓ Branch 0 taken 357 times.
✓ Branch 1 taken 3600 times.
✓ Branch 2 taken 3291 times.
7248 if (*str == key) return str;
481
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6534 times.
6534 else if(!skip_par(str)) return nullptr;
482 }
483 342 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