asar coverage - build #252


src/asar/
File: src/asar/libstr.cpp
Date: 2025-02-21 20:14:43
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 302959 inline bool skip_quote(char *&str)
121 {
122
123
2/2
✓ Branch 0 taken 32230 times.
✓ Branch 1 taken 270729 times.
302959 if(*str == '"') str = strchr(str + 1, '"');
124
2/2
✓ Branch 0 taken 2502 times.
✓ Branch 1 taken 268227 times.
270729 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 302959 return str;
131 }
132
133 //eat 1 char or quote/par
134 33086 inline bool skip_par(char *&str)
135 {
136 16550 int par = 0;
137
7/8
✓ Branch 0 taken 16404 times.
✓ Branch 1 taken 16682 times.
✓ Branch 2 taken 13550 times.
✓ Branch 3 taken 19404 times.
✓ Branch 4 taken 16407 times.
✓ Branch 5 taken 13425 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 13425 times.
33086 if(*str != '\'' && *str != '"' && *str != '(' && *str != ')')
138 {
139 26841 str++;
140 26841 return true;
141 }
142 while(true)
143 {
144 37707 char *t = str;
145
2/2
✓ Branch 0 taken 734 times.
✓ Branch 1 taken 36973 times.
37707 if(*str == '"') t = strchr(t + 1, '"');
146
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36973 times.
36973 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 5979 times.
✓ Branch 1 taken 30994 times.
36973 else if(*t == '(')
153 {
154 5979 par++;
155 }
156
2/2
✓ Branch 0 taken 5979 times.
✓ Branch 1 taken 25015 times.
30994 else if(*t == ')')
157 {
158 5979 par--;
159
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5979 times.
5979 if(par < 0) return false;
160 }
161
162 37707 str = t + 1;
163
4/4
✓ Branch 0 taken 33079 times.
✓ Branch 1 taken 4628 times.
✓ Branch 2 taken 16533 times.
✓ Branch 3 taken 16546 times.
37707 if(!*str || !par) return par == 0 ? true : false;
164 15739 }
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 161585 string& string::qnormalize()
198 {
199 78368 string& thisstring =*this;
200 78368 string out;
201 78368 char *startstr = thisstring.raw();
202 78368 char *str = startstr;
203
2/2
✓ Branch 0 taken 198081 times.
✓ Branch 1 taken 161495 times.
359576 while((str = strpbrk(str, "'\" \t,\r")))
204 {
205
2/2
✓ Branch 0 taken 144960 times.
✓ Branch 1 taken 53121 times.
198081 if(is_space(*str))
206 {
207
6/6
✓ Branch 0 taken 144924 times.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 144780 times.
✓ Branch 3 taken 144 times.
✓ Branch 4 taken 70014 times.
✓ Branch 5 taken 90 times.
144960 if(str[0] == ' ' && !is_space(str[1]))
208 {
209 144780 str++;
210 144780 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 18354 times.
✓ Branch 1 taken 34767 times.
53121 }else if(*str == ',')
217 {
218 18354 str++;
219
2/2
✓ Branch 0 taken 5238 times.
✓ Branch 1 taken 13116 times.
18354 if(is_space(*str))
220 {
221
1/2
✓ Branch 0 taken 2622 times.
✗ Branch 1 not taken.
5238 out.append(startstr, 0, str - startstr);
222
2/2
✓ Branch 0 taken 5364 times.
✓ Branch 1 taken 5238 times.
10602 while(is_space(*str)) str++;
223 2622 startstr = str;
224 }
225 }
226 else
227 {
228 34767 str = strchr(str + 1, *str); //confirm quotes has already been run, so this should be okay
229
2/2
✓ Branch 0 taken 19950 times.
✓ Branch 1 taken 14817 times.
34767 if(!str) return thisstring;
230 34677 str++;
231 }
232 }
233
2/2
✓ Branch 0 taken 4260 times.
✓ Branch 1 taken 157235 times.
161495 if(startstr != thisstring.raw())
234 {
235
1/2
✓ Branch 0 taken 2133 times.
✗ Branch 1 not taken.
4260 out.append(startstr, 0, strlen(startstr)); //the remaining
236
237
1/2
✓ Branch 0 taken 2133 times.
✗ Branch 1 not taken.
2133 thisstring = out;
238 }
239 78323 return thisstring;
240 161585 }
241
242 225389 bool confirmquotes(const char * str)
243 {
244
2/2
✓ Branch 0 taken 161107 times.
✓ Branch 1 taken 100264 times.
261371 while(*str)
245 {
246 161107 char *dquote = strchr((char *)str, '"');
247 161107 char *squote = strchr((char *)str, '\'');
248
4/4
✓ Branch 0 taken 84644 times.
✓ Branch 1 taken 76463 times.
✓ Branch 2 taken 1380 times.
✓ Branch 3 taken 62704 times.
161107 if(dquote || squote)
249 {
250
6/6
✓ Branch 0 taken 33252 times.
✓ Branch 1 taken 2760 times.
✓ Branch 2 taken 33105 times.
✓ Branch 3 taken 147 times.
✓ Branch 4 taken 13925 times.
✓ Branch 5 taken 12 times.
36012 if(dquote && (dquote < squote || !squote))
251 {
252 33228 dquote = strchr(dquote+1, '"');
253
2/2
✓ Branch 0 taken 33204 times.
✓ Branch 1 taken 24 times.
33228 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 15437 }
264 else
265 {
266 62704 return true;
267 }
268 }
269 47615 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 165567 char ** split(char * str, char key, int * len)
302 {
303 165567 char *thisentry=strchr(str, key);
304
2/2
✓ Branch 0 taken 94395 times.
✓ Branch 1 taken 71172 times.
165567 if (!thisentry)
305 {
306 94395 char ** out= typed_malloc(char*, 2);
307 94395 out[0]=str;
308 94395 out[1]=nullptr;
309
2/2
✓ Branch 0 taken 80633 times.
✓ Branch 1 taken 13762 times.
94395 if (len) *len=1;
310 94395 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 126144 *thisentry = 0;
319 126144 thisentry++;
320 126144 outdata[newcount++]=thisentry;
321
2/2
✓ Branch 0 taken 895 times.
✓ Branch 1 taken 125249 times.
126144 if(newcount >= count)
322 {
323 895 count *= 2;
324 895 outdata = typed_realloc(char *, outdata, count);
325 }
326
2/2
✓ Branch 0 taken 54972 times.
✓ Branch 1 taken 71172 times.
126144 }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 192451 char ** qsplit(char * str, char key, int * len)
334 {
335
5/6
✓ Branch 0 taken 161967 times.
✓ Branch 1 taken 30484 times.
✓ Branch 2 taken 160095 times.
✓ Branch 3 taken 1872 times.
✓ Branch 4 taken 53557 times.
✗ Branch 5 not taken.
192451 if (!strchr(str, '"') && !strchr(str, '\'')) return split(str, key, len);
336
337 13612 int count=15;
338 32356 char ** outdata= typed_malloc(char*, (size_t)count+1);
339 13612 int newcount=0;
340 32356 char * thisentry=str;
341 32356 outdata[newcount++]=thisentry;
342
2/2
✓ Branch 0 taken 275779 times.
✓ Branch 1 taken 32356 times.
308135 while (*thisentry) /*todo fix*/
343 {
344
2/2
✓ Branch 0 taken 33573 times.
✓ Branch 1 taken 242206 times.
275779 if (*thisentry == key)
345 {
346 33573 *thisentry=0;
347 33573 thisentry++;
348 33573 outdata[newcount++]=thisentry;
349
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33573 times.
33573 if(newcount >= count)
350 {
351 count *= 2;
352 outdata = typed_realloc(char *, outdata, count);
353 }
354 }
355
2/4
✓ Branch 0 taken 242206 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103147 times.
✗ Branch 3 not taken.
242206 else if(skip_quote(thisentry)) thisentry++;
356 else return nullptr;
357 }
358 32356 outdata[newcount]= nullptr;
359
2/2
✓ Branch 0 taken 31275 times.
✓ Branch 1 taken 1081 times.
32356 if (len) *len=newcount;
360 13612 return outdata;
361 }
362
363 159057 char ** qsplitstr(char * str, const char * key, int * len)
364 {
365 //check if the str is found first
366
2/2
✓ Branch 0 taken 157683 times.
✓ Branch 1 taken 1374 times.
159057 if (!strstr(str, key))
367 {
368 157683 char ** out= typed_malloc(char*, 2);
369 157683 out[0]=str;
370 157683 out[1]=nullptr;
371
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 157683 times.
157683 if (len) *len=1;
372 157683 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 33633 char ** qpsplit(char * str, char key, int * len)
404 {
405
4/6
✓ Branch 0 taken 27925 times.
✓ Branch 1 taken 5708 times.
✓ Branch 2 taken 27925 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14014 times.
✗ Branch 5 not taken.
33633 if (!strchr(str, '(') && !strchr(str, ')')) return qsplit(str, key, len);
406 2855 int count=7;
407 5708 char ** outdata= typed_malloc(char*, (size_t)count+1);
408
409 2855 int newcount=0;
410 5708 char * thisentry=str;
411 5708 outdata[newcount++]=thisentry;
412
2/2
✓ Branch 0 taken 33977 times.
✓ Branch 1 taken 5708 times.
39685 while (*thisentry)
413 {
414 //skippar(*thisentry, thisentry++, return nullptr;)
415
2/2
✓ Branch 0 taken 2331 times.
✓ Branch 1 taken 31646 times.
33977 if (*thisentry == key)
416 {
417 2331 *thisentry=0;
418 2331 thisentry++;
419 2331 outdata[newcount++]=thisentry;
420
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 2307 times.
2331 if(newcount >= count)
421 {
422 24 count *= 2;
423 24 outdata = typed_realloc(char *, outdata, count);
424 }
425 }
426
2/4
✓ Branch 0 taken 31646 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 15830 times.
31646 else if(!skip_par(thisentry)) return nullptr;
427 }
428 5708 outdata[newcount]= nullptr;
429
2/2
✓ Branch 0 taken 2718 times.
✓ Branch 1 taken 2990 times.
5708 if (len) *len=newcount;
430 2855 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