asar coverage - build #234


src/asar/
File: src/asar/libstr.cpp
Date: 2025-02-20 01:21:10
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 23642 void string::reallocate_capacity(unsigned int new_length)
15 {
16 // Allocate 1 extra byte for NUL terminator
17
2/2
✓ Branch 0 taken 11497 times.
✓ Branch 1 taken 381 times.
23642 int new_alloc_capacity = bitround(new_length + 1);
18
19
2/2
✓ Branch 0 taken 22790 times.
✓ Branch 1 taken 852 times.
23642 if (is_inlined()) {
20 22790 data_ptr = copy(data_ptr, min(len, new_length), (char*)malloc(new_alloc_capacity));
21 }
22 else {
23 852 data_ptr = (char*)realloc(data_ptr, new_alloc_capacity);
24 }
25 23642 allocated.capacity = new_alloc_capacity - 1; // capacity field doesn't count NUL terminator
26 23642 }
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 300646 inline bool skip_quote(char *&str)
121 {
122
123
2/2
✓ Branch 0 taken 32005 times.
✓ Branch 1 taken 268641 times.
300646 if(*str == '"') str = strchr(str + 1, '"');
124
2/2
✓ Branch 0 taken 2502 times.
✓ Branch 1 taken 266139 times.
268641 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 300646 return str;
131 }
132
133 //eat 1 char or quote/par
134 32102 inline bool skip_par(char *&str)
135 {
136 16058 int par = 0;
137
7/8
✓ Branch 0 taken 15933 times.
✓ Branch 1 taken 16169 times.
✓ Branch 2 taken 13106 times.
✓ Branch 3 taken 18885 times.
✓ Branch 4 taken 15936 times.
✓ Branch 5 taken 13002 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 13002 times.
32102 if(*str != '\'' && *str != '"' && *str != '(' && *str != ')')
138 {
139 25995 str++;
140 25995 return true;
141 }
142 while(true)
143 {
144 37323 char *t = str;
145
2/2
✓ Branch 0 taken 692 times.
✓ Branch 1 taken 36631 times.
37323 if(*str == '"') t = strchr(t + 1, '"');
146
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36631 times.
36631 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 5883 times.
✓ Branch 1 taken 30748 times.
36631 else if(*t == '(')
153 {
154 5883 par++;
155 }
156
2/2
✓ Branch 0 taken 5883 times.
✓ Branch 1 taken 24865 times.
30748 else if(*t == ')')
157 {
158 5883 par--;
159
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5883 times.
5883 if(par < 0) return false;
160 }
161
162 37323 str = t + 1;
163
4/4
✓ Branch 0 taken 32737 times.
✓ Branch 1 taken 4586 times.
✓ Branch 2 taken 16362 times.
✓ Branch 3 taken 16375 times.
37323 if(!*str || !par) return par == 0 ? true : false;
164 15616 }
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 161324 string& string::qnormalize()
198 {
199 78161 string& thisstring =*this;
200 78161 string out;
201 78161 char *startstr = thisstring.raw();
202 78161 char *str = startstr;
203
2/2
✓ Branch 0 taken 197505 times.
✓ Branch 1 taken 161234 times.
358739 while((str = strpbrk(str, "'\" \t,\r")))
204 {
205
2/2
✓ Branch 0 taken 144681 times.
✓ Branch 1 taken 52824 times.
197505 if(is_space(*str))
206 {
207
6/6
✓ Branch 0 taken 144645 times.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 144501 times.
✓ Branch 3 taken 144 times.
✓ Branch 4 taken 69798 times.
✓ Branch 5 taken 90 times.
144681 if(str[0] == ' ' && !is_space(str[1]))
208 {
209 144501 str++;
210 144501 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 18264 times.
✓ Branch 1 taken 34560 times.
52824 }else if(*str == ',')
217 {
218 18264 str++;
219
2/2
✓ Branch 0 taken 5166 times.
✓ Branch 1 taken 13098 times.
18264 if(is_space(*str))
220 {
221
1/2
✓ Branch 0 taken 2586 times.
✗ Branch 1 not taken.
5166 out.append(startstr, 0, str - startstr);
222
2/2
✓ Branch 0 taken 5292 times.
✓ Branch 1 taken 5166 times.
10458 while(is_space(*str)) str++;
223 2586 startstr = str;
224 }
225 }
226 else
227 {
228 34560 str = strchr(str + 1, *str); //confirm quotes has already been run, so this should be okay
229
2/2
✓ Branch 0 taken 19923 times.
✓ Branch 1 taken 14637 times.
34560 if(!str) return thisstring;
230 34470 str++;
231 }
232 }
233
2/2
✓ Branch 0 taken 4206 times.
✓ Branch 1 taken 157028 times.
161234 if(startstr != thisstring.raw())
234 {
235
1/2
✓ Branch 0 taken 2106 times.
✗ Branch 1 not taken.
4206 out.append(startstr, 0, strlen(startstr)); //the remaining
236
237
1/2
✓ Branch 0 taken 2106 times.
✗ Branch 1 not taken.
2106 thisstring = out;
238 }
239 78116 return thisstring;
240 161324 }
241
242 225092 bool confirmquotes(const char * str)
243 {
244
2/2
✓ Branch 0 taken 160834 times.
✓ Branch 1 taken 100015 times.
260849 while(*str)
245 {
246 160834 char *dquote = strchr((char *)str, '"');
247 160834 char *squote = strchr((char *)str, '\'');
248
4/4
✓ Branch 0 taken 84584 times.
✓ Branch 1 taken 76250 times.
✓ Branch 2 taken 1380 times.
✓ Branch 3 taken 62680 times.
160834 if(dquote || squote)
249 {
250
6/6
✓ Branch 0 taken 33027 times.
✓ Branch 1 taken 2760 times.
✓ Branch 2 taken 32880 times.
✓ Branch 3 taken 147 times.
✓ Branch 4 taken 13736 times.
✓ Branch 5 taken 12 times.
35787 if(dquote && (dquote < squote || !squote))
251 {
252 33003 dquote = strchr(dquote+1, '"');
253
2/2
✓ Branch 0 taken 32979 times.
✓ Branch 1 taken 24 times.
33003 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 15248 }
264 else
265 {
266 62680 return true;
267 }
268 }
269 47414 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 165561 char ** split(char * str, char key, int * len)
302 {
303 165561 char *thisentry=strchr(str, key);
304
2/2
✓ Branch 0 taken 94389 times.
✓ Branch 1 taken 71172 times.
165561 if (!thisentry)
305 {
306 94389 char ** out= typed_malloc(char*, 2);
307 94389 out[0]=str;
308 94389 out[1]=nullptr;
309
2/2
✓ Branch 0 taken 80573 times.
✓ Branch 1 taken 13816 times.
94389 if (len) *len=1;
310 94389 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 126108 *thisentry = 0;
319 126108 thisentry++;
320 126108 outdata[newcount++]=thisentry;
321
2/2
✓ Branch 0 taken 895 times.
✓ Branch 1 taken 125213 times.
126108 if(newcount >= count)
322 {
323 895 count *= 2;
324 895 outdata = typed_realloc(char *, outdata, count);
325 }
326
2/2
✓ Branch 0 taken 54936 times.
✓ Branch 1 taken 71172 times.
126108 }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 192220 char ** qsplit(char * str, char key, int * len)
334 {
335
5/6
✓ Branch 0 taken 161961 times.
✓ Branch 1 taken 30259 times.
✓ Branch 2 taken 160089 times.
✓ Branch 3 taken 1872 times.
✓ Branch 4 taken 53555 times.
✗ Branch 5 not taken.
192220 if (!strchr(str, '"') && !strchr(str, '\'')) return split(str, key, len);
336
337 13423 int count=15;
338 32131 char ** outdata= typed_malloc(char*, (size_t)count+1);
339 13423 int newcount=0;
340 32131 char * thisentry=str;
341 32131 outdata[newcount++]=thisentry;
342
2/2
✓ Branch 0 taken 273169 times.
✓ Branch 1 taken 32131 times.
305300 while (*thisentry) /*todo fix*/
343 {
344
2/2
✓ Branch 0 taken 33276 times.
✓ Branch 1 taken 239893 times.
273169 if (*thisentry == key)
345 {
346 33276 *thisentry=0;
347 33276 thisentry++;
348 33276 outdata[newcount++]=thisentry;
349
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33276 times.
33276 if(newcount >= count)
350 {
351 count *= 2;
352 outdata = typed_realloc(char *, outdata, count);
353 }
354 }
355
2/4
✓ Branch 0 taken 239893 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 101455 times.
✗ Branch 3 not taken.
239893 else if(skip_quote(thisentry)) thisentry++;
356 else return nullptr;
357 }
358 32131 outdata[newcount]= nullptr;
359
2/2
✓ Branch 0 taken 31068 times.
✓ Branch 1 taken 1063 times.
32131 if (len) *len=newcount;
360 13423 return outdata;
361 }
362
363 158796 char ** qsplitstr(char * str, const char * key, int * len)
364 {
365 //check if the str is found first
366
2/2
✓ Branch 0 taken 157422 times.
✓ Branch 1 taken 1374 times.
158796 if (!strstr(str, key))
367 {
368 157422 char ** out= typed_malloc(char*, 2);
369 157422 out[0]=str;
370 157422 out[1]=nullptr;
371
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 157422 times.
157422 if (len) *len=1;
372 157422 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 33567 char ** qpsplit(char * str, char key, int * len)
404 {
405
4/6
✓ Branch 0 taken 27955 times.
✓ Branch 1 taken 5612 times.
✓ Branch 2 taken 27955 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14029 times.
✗ Branch 5 not taken.
33567 if (!strchr(str, '(') && !strchr(str, ')')) return qsplit(str, key, len);
406 2807 int count=7;
407 5612 char ** outdata= typed_malloc(char*, (size_t)count+1);
408
409 2807 int newcount=0;
410 5612 char * thisentry=str;
411 5612 outdata[newcount++]=thisentry;
412
2/2
✓ Branch 0 taken 32915 times.
✓ Branch 1 taken 5612 times.
38527 while (*thisentry)
413 {
414 //skippar(*thisentry, thisentry++, return nullptr;)
415
2/2
✓ Branch 0 taken 2253 times.
✓ Branch 1 taken 30662 times.
32915 if (*thisentry == key)
416 {
417 2253 *thisentry=0;
418 2253 thisentry++;
419 2253 outdata[newcount++]=thisentry;
420
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 2229 times.
2253 if(newcount >= count)
421 {
422 24 count *= 2;
423 24 outdata = typed_realloc(char *, outdata, count);
424 }
425 }
426
2/4
✓ Branch 0 taken 30662 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 15338 times.
30662 else if(!skip_par(thisentry)) return nullptr;
427 }
428 5612 outdata[newcount]= nullptr;
429
2/2
✓ Branch 0 taken 2718 times.
✓ Branch 1 taken 2894 times.
5612 if (len) *len=newcount;
430 2807 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