asar coverage - build #243


src/asar/
File: src/asar/libstr.cpp
Date: 2025-02-21 04:16:25
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 23727 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 382 times.
23727 int new_alloc_capacity = bitround(new_length + 1);
18
19
2/2
✓ Branch 0 taken 22873 times.
✓ Branch 1 taken 854 times.
23727 if (is_inlined()) {
20 22873 data_ptr = copy(data_ptr, min(len, new_length), (char*)malloc(new_alloc_capacity));
21 }
22 else {
23 854 data_ptr = (char*)realloc(data_ptr, new_alloc_capacity);
24 }
25 23727 allocated.capacity = new_alloc_capacity - 1; // capacity field doesn't count NUL terminator
26 23727 }
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 302323 inline bool skip_quote(char *&str)
121 {
122
123
2/2
✓ Branch 0 taken 32242 times.
✓ Branch 1 taken 270081 times.
302323 if(*str == '"') str = strchr(str + 1, '"');
124
2/2
✓ Branch 0 taken 2502 times.
✓ Branch 1 taken 267579 times.
270081 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 302323 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 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 197991 times.
✓ Branch 1 taken 161459 times.
359450 while((str = strpbrk(str, "'\" \t,\r")))
204 {
205
2/2
✓ Branch 0 taken 144942 times.
✓ Branch 1 taken 53049 times.
197991 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 18300 times.
✓ Branch 1 taken 34749 times.
53049 }else if(*str == ',')
217 {
218 18300 str++;
219
2/2
✓ Branch 0 taken 5202 times.
✓ Branch 1 taken 13098 times.
18300 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 161035 times.
✓ Branch 1 taken 100264 times.
261299 while(*str)
245 {
246 161035 char *dquote = strchr((char *)str, '"');
247 161035 char *squote = strchr((char *)str, '\'');
248
4/4
✓ Branch 0 taken 84608 times.
✓ Branch 1 taken 76427 times.
✓ Branch 2 taken 1380 times.
✓ Branch 3 taken 62680 times.
161035 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 62680 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 165597 char ** split(char * str, char key, int * len)
302 {
303 165597 char *thisentry=strchr(str, key);
304
2/2
✓ Branch 0 taken 94425 times.
✓ Branch 1 taken 71172 times.
165597 if (!thisentry)
305 {
306 94425 char ** out= typed_malloc(char*, 2);
307 94425 out[0]=str;
308 94425 out[1]=nullptr;
309
2/2
✓ Branch 0 taken 80609 times.
✓ Branch 1 taken 13816 times.
94425 if (len) *len=1;
310 94425 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 192493 char ** qsplit(char * str, char key, int * len)
334 {
335
5/6
✓ Branch 0 taken 161997 times.
✓ Branch 1 taken 30496 times.
✓ Branch 2 taken 160125 times.
✓ Branch 3 taken 1872 times.
✓ Branch 4 taken 53567 times.
✗ Branch 5 not taken.
192493 if (!strchr(str, '"') && !strchr(str, '\'')) return split(str, key, len);
336
337 13618 int count=15;
338 32368 char ** outdata= typed_malloc(char*, (size_t)count+1);
339 13618 int newcount=0;
340 32368 char * thisentry=str;
341 32368 outdata[newcount++]=thisentry;
342
2/2
✓ Branch 0 taken 275143 times.
✓ Branch 1 taken 32368 times.
307511 while (*thisentry) /*todo fix*/
343 {
344
2/2
✓ Branch 0 taken 33573 times.
✓ Branch 1 taken 241570 times.
275143 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 241570 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 102829 times.
✗ Branch 3 not taken.
241570 else if(skip_quote(thisentry)) thisentry++;
356 else return nullptr;
357 }
358 32368 outdata[newcount]= nullptr;
359
2/2
✓ Branch 0 taken 31257 times.
✓ Branch 1 taken 1111 times.
32368 if (len) *len=newcount;
360 13618 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 33615 char ** qpsplit(char * str, char key, int * len)
404 {
405
4/6
✓ Branch 0 taken 28003 times.
✓ Branch 1 taken 5612 times.
✓ Branch 2 taken 28003 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14053 times.
✗ Branch 5 not taken.
33615 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