asar coverage - build #246


src/asar/
File: src/asar/libstr.cpp
Date: 2025-02-21 15:35:06
Lines:
211/268
78.7%
Functions:
15/18
83.3%
Branches:
159/254
62.6%

Line Branch Exec Source
1 #include "asar.h"
2 #include "virtualfile.h"
3 #include "unicode.h"
4
5 #include "platform/file-helpers.h"
6
7 #define typed_malloc(type, count) (type*)malloc(sizeof(type)*(count))
8 #define typed_realloc(type, ptr, count) (type*)realloc(ptr, sizeof(type)*(count))
9
10
11 // This function is intentionally left out of the header file so that it is not visible to the
12 // compiler and less likely to be inlined into resize(). This in turn reduces the size of resize()
13 // so that it is then inlined in more places.
14 23731 void string::reallocate_capacity(unsigned int new_length)
15 {
16 // Allocate 1 extra byte for NUL terminator
17
2/2
✓ Branch 0 taken 11513 times.
✓ Branch 1 taken 384 times.
23731 int new_alloc_capacity = bitround(new_length + 1);
18
19
2/2
✓ Branch 0 taken 22873 times.
✓ Branch 1 taken 858 times.
23731 if (is_inlined()) {
20 22873 data_ptr = copy(data_ptr, min(len, new_length), (char*)malloc(new_alloc_capacity));
21 }
22 else {
23 858 data_ptr = (char*)realloc(data_ptr, new_alloc_capacity);
24 }
25 23731 allocated.capacity = new_alloc_capacity - 1; // capacity field doesn't count NUL terminator
26 23731 }
27
28
29 // Detects if str starts with a UTF-8 byte order mark.
30 // If so, throws a warning, then returns the number of bytes we should skip ahead in the string.
31 1884 size_t check_bom(const char* str)
32 {
33 // RPG Hacker: We could also check for BoMs of incompatible encodings here (like UTF-16)
34 // and throw errors, but not sure if that's worth adding. Asar never supported any wide
35 // encodings to begin with, so it's unreasonable to assume that any UTF-16 patches currently
36 // exist for it. As for future patches, those should be caught by the "must be UTF-8" checks
37 // I have already implemented further below.
38 // I think UTF-8 + BoM is the only case that could lead to confusion if we didn't handle it,
39 // so that's why I have added this.
40
4/6
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1878 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
1884 if (str[0u] == '\xEF' && str[1u] == '\xBB' && str[2u] == '\xBF')
41 {
42 6 asar_throw_warning(0, warning_id_byte_order_mark_utf8);
43 6 return 3u;
44 }
45
46 961 return 0u;
47 }
48
49
50 910 char * readfile(const char * fname, const char * basepath)
51 {
52 910 virtual_file_handle myfile = filesystem->open_file(fname, basepath);
53
2/2
✓ Branch 0 taken 436 times.
✓ Branch 1 taken 474 times.
910 if (myfile == INVALID_VIRTUAL_FILE_HANDLE) return nullptr;
54 892 size_t datalen = filesystem->get_file_size(myfile);
55 892 char * data= typed_malloc(char, datalen+1);
56 892 data[filesystem->read_file(myfile, data, 0u, datalen)] = 0;
57 892 filesystem->close_file(myfile);
58
59
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 886 times.
892 if (!is_valid_utf8(data))
60 {
61 6 free(data);
62 6 asar_throw_error(0, error_type_block, error_id_invalid_utf8);
63 }
64
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 880 times.
886 if(check_bom(data)){
65 6 data[0] = ' ';
66 6 data[1] = ' ';
67 6 data[2] = ' ';
68 }
69 462 return data;
70 }
71
72 // RPG Hacker: like readfile(), but doesn't use virtual file system
73 // and instead read our file directly.
74 998 char * readfilenative(const char * fname)
75 {
76 998 FileHandleType myfile = open_file(fname, FileOpenMode_Read);
77
2/2
✓ Branch 0 taken 496 times.
✓ Branch 1 taken 502 times.
998 if (myfile == InvalidFileHandle) return nullptr;
78 998 size_t datalen = (size_t)get_file_size(myfile);
79 998 char * data = typed_malloc(char, datalen + 1);
80 998 data[read_file(myfile, data, datalen)] = 0;
81 998 close_file(myfile);
82
83
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 998 times.
998 if (!is_valid_utf8(data)) asar_throw_error(0, error_type_block, error_id_invalid_utf8);
84
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 998 times.
998 if(check_bom(data)){
85 data[0] = ' ';
86 data[1] = ' ';
87 data[2] = ' ';
88 }
89 502 return data;
90 }
91
92 753 bool readfile(const char * fname, const char * basepath, char ** data, int * len)
93 {
94 753 virtual_file_handle myfile = filesystem->open_file(fname, basepath);
95
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 387 times.
753 if (!myfile) return false;
96 717 size_t datalen = filesystem->get_file_size(myfile);
97 717 *data= typed_malloc(char, datalen);
98 717 *len = (int)filesystem->read_file(myfile, *data, 0, datalen);
99 717 filesystem->close_file(myfile);
100 717 return true;
101 }
102
103 #define isq(n) (((0x2227 ^ (0x0101 * (n))) - 0x0101UL) & ~(0x2227 ^ (0x0101 * (n))) & 0x8080UL)
104 #define isqp(n) (((0x22272829 ^ (0x01010101 * (n))) - 0x01010101UL) & ~(0x22272829 ^ (0x01010101 * (n))) & 0x80808080UL)
105
106 // RPG Hacker: Only index this with ASCII characters.
107 // Anything else doesn't make sense, anyways.
108 const bool qparlut[128] = {
109 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0,
112 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
113 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
114 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
115 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
116 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
117 };
118
119 //this will leave the last char found as the one pointed at
120 302641 inline bool skip_quote(char *&str)
121 {
122
123
2/2
✓ Branch 0 taken 32218 times.
✓ Branch 1 taken 270423 times.
302641 if(*str == '"') str = strchr(str + 1, '"');
124
2/2
✓ Branch 0 taken 2502 times.
✓ Branch 1 taken 267921 times.
270423 else if(*str == '\'')
125 {
126 int codepoint;
127
1/2
✓ Branch 0 taken 1251 times.
✗ Branch 1 not taken.
2502 str += utf8_val(&codepoint, str + 1) + 1;
128
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2502 times.
2502 if(*str != '\'') return false;
129 }
130 302641 return str;
131 }
132
133 //eat 1 char or quote/par
134 32978 inline bool skip_par(char *&str)
135 {
136 16496 int par = 0;
137
7/8
✓ Branch 0 taken 16359 times.
✓ Branch 1 taken 16619 times.
✓ Branch 2 taken 13505 times.
✓ Branch 3 taken 19350 times.
✓ Branch 4 taken 16362 times.
✓ Branch 5 taken 13389 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 13389 times.
32978 if(*str != '\'' && *str != '"' && *str != '(' && *str != ')')
138 {
139 26769 str++;
140 26769 return true;
141 }
142 while(true)
143 {
144 37599 char *t = str;
145
2/2
✓ Branch 0 taken 716 times.
✓ Branch 1 taken 36883 times.
37599 if(*str == '"') t = strchr(t + 1, '"');
146
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36883 times.
36883 else if(*str == '\'')
147 {
148 int codepoint;
149 t += utf8_val(&codepoint, t + 1) + 1;
150 if(*t != '\'') return false;
151 }
152
2/2
✓ Branch 0 taken 5961 times.
✓ Branch 1 taken 30922 times.
36883 else if(*t == '(')
153 {
154 5961 par++;
155 }
156
2/2
✓ Branch 0 taken 5961 times.
✓ Branch 1 taken 24961 times.
30922 else if(*t == ')')
157 {
158 5961 par--;
159
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5961 times.
5961 if(par < 0) return false;
160 }
161
162 37599 str = t + 1;
163
4/4
✓ Branch 0 taken 32989 times.
✓ Branch 1 taken 4610 times.
✓ Branch 2 taken 16488 times.
✓ Branch 3 taken 16501 times.
37599 if(!*str || !par) return par == 0 ? true : false;
164 15703 }
165 }
166
167 //instr should not be duplicate chars. Instr should also not be 1 char
168 string& string::qreplace(const char * instr, const char * outstr)
169 {
170 string& thisstring =*this;
171 if (!strstr(thisstring, instr)) return thisstring;
172 int inlen = strlen(instr);
173 string out;
174 for (int i=0;thisstring[i];)
175 {
176 if (!strncmp((const char*)thisstring +i, instr, inlen))
177 {
178 out+=outstr;
179 i+=inlen;
180 }
181 // randomdude999: prevent appending the null terminator to the output
182 else if(!isq(thisstring[i])) out+= thisstring[i++];
183 else
184 {
185 char *start = raw() + i;
186 char *end = start;
187 if(!skip_quote(end)) return thisstring;
188 out.append(raw(), i, end - start + i + 1);
189 i += end - start + 1;
190
191 }
192 }
193 thisstring =out;
194 return thisstring;
195 }
196
197 161549 string& string::qnormalize()
198 {
199 78350 string& thisstring =*this;
200 78350 string out;
201 78350 char *startstr = thisstring.raw();
202 78350 char *str = startstr;
203
2/2
✓ Branch 0 taken 198009 times.
✓ Branch 1 taken 161459 times.
359468 while((str = strpbrk(str, "'\" \t,\r")))
204 {
205
2/2
✓ Branch 0 taken 144942 times.
✓ Branch 1 taken 53067 times.
198009 if(is_space(*str))
206 {
207
6/6
✓ Branch 0 taken 144906 times.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 144762 times.
✓ Branch 3 taken 144 times.
✓ Branch 4 taken 70005 times.
✓ Branch 5 taken 90 times.
144942 if(str[0] == ' ' && !is_space(str[1]))
208 {
209 144762 str++;
210 144762 continue;
211 }
212
1/2
✓ Branch 0 taken 90 times.
✗ Branch 1 not taken.
180 out.append(startstr, 0, str - startstr);
213
1/2
✓ Branch 0 taken 90 times.
✗ Branch 1 not taken.
180 out += ' ';
214
2/2
✓ Branch 0 taken 576 times.
✓ Branch 1 taken 180 times.
756 while(is_space(*str)) str++;
215 90 startstr = str;
216
2/2
✓ Branch 0 taken 18318 times.
✓ Branch 1 taken 34749 times.
53067 }else if(*str == ',')
217 {
218 18318 str++;
219
2/2
✓ Branch 0 taken 5202 times.
✓ Branch 1 taken 13116 times.
18318 if(is_space(*str))
220 {
221
1/2
✓ Branch 0 taken 2604 times.
✗ Branch 1 not taken.
5202 out.append(startstr, 0, str - startstr);
222
2/2
✓ Branch 0 taken 5328 times.
✓ Branch 1 taken 5202 times.
10530 while(is_space(*str)) str++;
223 2604 startstr = str;
224 }
225 }
226 else
227 {
228 34749 str = strchr(str + 1, *str); //confirm quotes has already been run, so this should be okay
229
2/2
✓ Branch 0 taken 19941 times.
✓ Branch 1 taken 14808 times.
34749 if(!str) return thisstring;
230 34659 str++;
231 }
232 }
233
2/2
✓ Branch 0 taken 4242 times.
✓ Branch 1 taken 157217 times.
161459 if(startstr != thisstring.raw())
234 {
235
1/2
✓ Branch 0 taken 2124 times.
✗ Branch 1 not taken.
4242 out.append(startstr, 0, strlen(startstr)); //the remaining
236
237
1/2
✓ Branch 0 taken 2124 times.
✗ Branch 1 not taken.
2124 thisstring = out;
238 }
239 78305 return thisstring;
240 161549 }
241
242 225341 bool confirmquotes(const char * str)
243 {
244
2/2
✓ Branch 0 taken 161059 times.
✓ Branch 1 taken 100240 times.
261299 while(*str)
245 {
246 161059 char *dquote = strchr((char *)str, '"');
247 161059 char *squote = strchr((char *)str, '\'');
248
4/4
✓ Branch 0 taken 84620 times.
✓ Branch 1 taken 76439 times.
✓ Branch 2 taken 1380 times.
✓ Branch 3 taken 62692 times.
161059 if(dquote || squote)
249 {
250
6/6
✓ Branch 0 taken 33228 times.
✓ Branch 1 taken 2760 times.
✓ Branch 2 taken 33081 times.
✓ Branch 3 taken 147 times.
✓ Branch 4 taken 13913 times.
✓ Branch 5 taken 12 times.
35988 if(dquote && (dquote < squote || !squote))
251 {
252 33204 dquote = strchr(dquote+1, '"');
253
2/2
✓ Branch 0 taken 33180 times.
✓ Branch 1 taken 24 times.
33204 if(dquote) str = dquote+1;
254 12 else return false;
255 }
256 else
257 {
258 int codepoint;
259
1/2
✓ Branch 0 taken 1392 times.
✗ Branch 1 not taken.
2784 squote += utf8_val(&codepoint, squote + 1) + 1;
260
2/2
✓ Branch 0 taken 2778 times.
✓ Branch 1 taken 6 times.
2784 if(*squote == '\'') str = squote+1;
261 6 else return false;
262 }
263 15425 }
264 else
265 {
266 62692 return true;
267 }
268 }
269 47603 return true;
270 }
271
272 2216 bool confirmqpar(const char * str)
273 {
274 //todo fully optimize
275 1115 int par = 0;
276
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 29446 times.
✓ Branch 2 taken 27230 times.
✓ Branch 3 taken 2216 times.
29446 while((unsigned char)*str >= 128 || !qparlut[(unsigned char)*str]) str++;
277
2/2
✓ Branch 0 taken 5422 times.
✓ Branch 1 taken 2216 times.
7638 while(*str)
278 {
279
2/2
✓ Branch 0 taken 1098 times.
✓ Branch 1 taken 4324 times.
5422 if(*str == '"')
280 {
281 1098 str = strchr(str + 1, '"');
282
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1098 times.
1098 if(!str++) return false;
283 }
284
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 4252 times.
4324 else if(*str == '\'')
285 {
286 int codepoint;
287
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
72 str += utf8_val(&codepoint, str + 1) + 1;
288
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 if(*str == '\'') str++;
289 else return false;
290 }
291 else
292 {
293 4252 par += 1 - ((*str++ - '(') << 1);
294
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4252 times.
4252 if(par < 0) return false;
295 }
296
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 13704 times.
✓ Branch 2 taken 8282 times.
✓ Branch 3 taken 5422 times.
13704 while((unsigned char)*str >= 128 || !qparlut[(unsigned char)*str]) str++;
297 }
298 2216 return !par;
299 }
300
301 165549 char ** split(char * str, char key, int * len)
302 {
303 165549 char *thisentry=strchr(str, key);
304
2/2
✓ Branch 0 taken 94377 times.
✓ Branch 1 taken 71172 times.
165549 if (!thisentry)
305 {
306 94377 char ** out= typed_malloc(char*, 2);
307 94377 out[0]=str;
308 94377 out[1]=nullptr;
309
2/2
✓ Branch 0 taken 80615 times.
✓ Branch 1 taken 13762 times.
94377 if (len) *len=1;
310 94377 return out;
311 }
312 35704 int count=15; //makes the default alloc 8 elements, sounds fair.
313 71172 char ** outdata= typed_malloc(char*, (size_t)count+1);
314
315 35704 int newcount=0;
316 71172 outdata[newcount++]=str;
317 do{
318 126132 *thisentry = 0;
319 126132 thisentry++;
320 126132 outdata[newcount++]=thisentry;
321
2/2
✓ Branch 0 taken 895 times.
✓ Branch 1 taken 125237 times.
126132 if(newcount >= count)
322 {
323 895 count *= 2;
324 895 outdata = typed_realloc(char *, outdata, count);
325 }
326
2/2
✓ Branch 0 taken 54960 times.
✓ Branch 1 taken 71172 times.
126132 }while((thisentry = strchr(thisentry, key)));
327
328 71172 outdata[newcount]= nullptr;
329
2/2
✓ Branch 0 taken 68940 times.
✓ Branch 1 taken 2232 times.
71172 if (len) *len=newcount;
330 35704 return outdata;
331 }
332
333 192421 char ** qsplit(char * str, char key, int * len)
334 {
335
5/6
✓ Branch 0 taken 161949 times.
✓ Branch 1 taken 30472 times.
✓ Branch 2 taken 160077 times.
✓ Branch 3 taken 1872 times.
✓ Branch 4 taken 53551 times.
✗ Branch 5 not taken.
192421 if (!strchr(str, '"') && !strchr(str, '\'')) return split(str, key, len);
336
337 13606 int count=15;
338 32344 char ** outdata= typed_malloc(char*, (size_t)count+1);
339 13606 int newcount=0;
340 32344 char * thisentry=str;
341 32344 outdata[newcount++]=thisentry;
342
2/2
✓ Branch 0 taken 275443 times.
✓ Branch 1 taken 32344 times.
307787 while (*thisentry) /*todo fix*/
343 {
344
2/2
✓ Branch 0 taken 33555 times.
✓ Branch 1 taken 241888 times.
275443 if (*thisentry == key)
345 {
346 33555 *thisentry=0;
347 33555 thisentry++;
348 33555 outdata[newcount++]=thisentry;
349
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33555 times.
33555 if(newcount >= count)
350 {
351 count *= 2;
352 outdata = typed_realloc(char *, outdata, count);
353 }
354 }
355
2/4
✓ Branch 0 taken 241888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 102988 times.
✗ Branch 3 not taken.
241888 else if(skip_quote(thisentry)) thisentry++;
356 else return nullptr;
357 }
358 32344 outdata[newcount]= nullptr;
359
2/2
✓ Branch 0 taken 31257 times.
✓ Branch 1 taken 1087 times.
32344 if (len) *len=newcount;
360 13606 return outdata;
361 }
362
363 159021 char ** qsplitstr(char * str, const char * key, int * len)
364 {
365 //check if the str is found first
366
2/2
✓ Branch 0 taken 157647 times.
✓ Branch 1 taken 1374 times.
159021 if (!strstr(str, key))
367 {
368 157647 char ** out= typed_malloc(char*, 2);
369 157647 out[0]=str;
370 157647 out[1]=nullptr;
371
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 157647 times.
157647 if (len) *len=1;
372 157647 return out;
373 }
374
375 1374 int keylen=(int)strlen(key);
376 717 int count=15;
377 1374 char ** outdata= typed_malloc(char*, (size_t)count+1);
378 717 int newcount=0;
379 1374 char * thisentry=str;
380 1374 outdata[newcount++]=thisentry;
381
2/2
✓ Branch 0 taken 66222 times.
✓ Branch 1 taken 1374 times.
67596 while (*thisentry) /*todo fix*/
382 {
383
2/2
✓ Branch 0 taken 5469 times.
✓ Branch 1 taken 60753 times.
66222 if (!strncmp(thisentry, key, (size_t)keylen))
384 {
385 5469 *thisentry=0;
386 5469 thisentry+=keylen;
387 5469 outdata[newcount++]=thisentry;
388
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5469 times.
5469 if(newcount >= count)
389 {
390 count *= 2;
391 outdata = typed_realloc(char *, outdata, count);
392 }
393 }
394
2/4
✓ Branch 0 taken 60753 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30927 times.
✗ Branch 3 not taken.
60753 else if(skip_quote(thisentry)) thisentry++;
395 else return nullptr;
396 }
397 1374 outdata[newcount]= nullptr;
398
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1374 times.
1374 if (len) *len=newcount;
399 717 return outdata;
400 }
401
402 //this function is most commonly called in cases where additional chars are very likely
403 33621 char ** qpsplit(char * str, char key, int * len)
404 {
405
4/6
✓ Branch 0 taken 27931 times.
✓ Branch 1 taken 5690 times.
✓ Branch 2 taken 27931 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14017 times.
✗ Branch 5 not taken.
33621 if (!strchr(str, '(') && !strchr(str, ')')) return qsplit(str, key, len);
406 2846 int count=7;
407 5690 char ** outdata= typed_malloc(char*, (size_t)count+1);
408
409 2846 int newcount=0;
410 5690 char * thisentry=str;
411 5690 outdata[newcount++]=thisentry;
412
2/2
✓ Branch 0 taken 33833 times.
✓ Branch 1 taken 5690 times.
39523 while (*thisentry)
413 {
414 //skippar(*thisentry, thisentry++, return nullptr;)
415
2/2
✓ Branch 0 taken 2295 times.
✓ Branch 1 taken 31538 times.
33833 if (*thisentry == key)
416 {
417 2295 *thisentry=0;
418 2295 thisentry++;
419 2295 outdata[newcount++]=thisentry;
420
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 2271 times.
2295 if(newcount >= count)
421 {
422 24 count *= 2;
423 24 outdata = typed_realloc(char *, outdata, count);
424 }
425 }
426
2/4
✓ Branch 0 taken 31538 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 15776 times.
31538 else if(!skip_par(thisentry)) return nullptr;
427 }
428 5690 outdata[newcount]= nullptr;
429
2/2
✓ Branch 0 taken 2718 times.
✓ Branch 1 taken 2972 times.
5690 if (len) *len=newcount;
430 2846 return outdata;
431 }
432
433 string &itrim(string &input, const char * left, const char * right)
434 {
435 bool nukeright=true;
436 int totallen=input.length();
437 int rightlen=(int)strlen(right);
438 if (rightlen && rightlen<=totallen)
439 {
440 const char * rightend=right+rightlen;
441 const char * strend=input.data()+totallen;
442 while (right!=rightend)
443 {
444 rightend--;
445 strend--;
446 if (to_lower(*strend)!=to_lower(*rightend)) nukeright=false;
447 }
448 if (nukeright)
449 {
450 totallen-=rightlen;
451 input.truncate(totallen);
452 }
453 }
454 bool nukeleft=true;
455 int leftlen = strlen(left);
456 if(leftlen == 1 && input.data()[0] == left[0])
457 {
458 return input = string(input.data()+1, (input.length()-1));
459 }
460 else
461 {
462 for (int i = 0; i < leftlen; i++)
463 {
464 if (to_lower(input.data()[i])!=to_lower(left[i])) nukeleft=false;
465 }
466 if (nukeleft) input = string(input.data()+leftlen, (input.length()-leftlen));
467 }
468 return input;
469 }
470
471 char* strqpchr(char* str, char key)
472 {
473 while (*str)
474 {
475 if (*str == key) return str;
476 else if(!skip_par(str)) return nullptr;
477 }
478 return nullptr;
479 }
480
481 378 char* strqpstr(char* str, const char* key)
482 {
483 378 size_t keylen = strlen(key);
484
2/2
✓ Branch 0 taken 1800 times.
✓ Branch 1 taken 18 times.
1818 while (*str)
485 {
486
2/2
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 1440 times.
1800 if (!strncmp(str, key, keylen)) return str;
487
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1440 times.
1440 else if(!skip_par(str)) return nullptr;
488 }
489 9 return nullptr;
490 }
491
492 extern const uint8_t char_props[256] = {
493 //x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF
494 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x00,0x00, // 0x
495 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 1x
496 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 2x !"#$%&'()*+,-./
497 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x00,0x00,0x00,0x00,0x00,0x00, // 3x 0123456789:;<=>?
498 0x00,0x23,0x23,0x23,0x23,0x23,0x23,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, // 4x @ABCDEFGHIJKLMNO
499 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x00,0x00,0x00,0x00,0x08, // 5x PQRSTUVWXYZ[\]^_
500 0x00,0x25,0x25,0x25,0x25,0x25,0x25,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24, // 6x `abcdefghijklmno
501 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x00,0x00,0x00,0x00,0x00, // 7x pqrstuvwxyz{|}~
502 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 8x
503 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 9x
504 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Ax
505 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Bx
506 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Cx
507 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Dx
508 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Ex
509 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Fx
510 };
511