Line |
Branch |
Exec |
Source |
1 |
|
|
#pragma once |
2 |
|
|
|
3 |
|
|
#include "std-includes.h" |
4 |
|
|
#include "libmisc.h" |
5 |
|
|
#include <cstdint> |
6 |
|
|
//ty alcaro |
7 |
|
|
extern const unsigned char char_props[256]; |
8 |
|
4510143 |
static inline int to_lower(unsigned char c) { return c|(char_props[c]&0x20); } |
9 |
|
345966 |
static inline int to_upper(unsigned char c) { return c&~(char_props[c]&0x20); } |
10 |
|
|
|
11 |
|
726295 |
inline bool is_space(unsigned char c) { return char_props[c] & 0x80; } // C standard says \f \v are space, but this one disagrees |
12 |
|
149687 |
inline bool is_digit(unsigned char c) { return char_props[c] & 0x40; } |
13 |
|
|
inline bool is_alpha(unsigned char c) { return char_props[c] & 0x20; } |
14 |
|
3570 |
inline bool is_lower(unsigned char c) { return char_props[c] & 0x04; } |
15 |
|
4974 |
inline bool is_upper(unsigned char c) { return char_props[c] & 0x02; } |
16 |
|
|
inline bool is_alnum(unsigned char c) { return char_props[c] & 0x60; } |
17 |
|
40849 |
inline bool is_ualpha(unsigned char c) { return char_props[c] & 0x28; } |
18 |
|
387044 |
inline bool is_ualnum(unsigned char c) { return char_props[c] & 0x68; } |
19 |
|
86925 |
inline bool is_xdigit(unsigned char c) { return char_props[c] & 0x01; } |
20 |
|
|
|
21 |
|
3843693 |
inline char *copy(const char *source, int copy_length, char *dest) |
22 |
|
|
{ |
23 |
|
3843693 |
memcpy(dest, source, copy_length*sizeof(char)); |
24 |
|
3843693 |
return dest; |
25 |
|
|
} |
26 |
|
|
|
27 |
|
|
class string { |
28 |
|
|
public: |
29 |
|
13574968 |
const char *data() const |
30 |
|
|
{ |
31 |
|
13574968 |
return cached_data; |
32 |
|
|
} |
33 |
|
|
|
34 |
|
367699 |
char *temp_raw() const //things to cleanup and take a look at |
35 |
|
|
{ |
36 |
|
367699 |
return cached_data; |
37 |
|
|
} |
38 |
|
|
|
39 |
|
6757335 |
char *raw() const |
40 |
|
|
{ |
41 |
|
6757335 |
return cached_data; |
42 |
|
|
} |
43 |
|
|
|
44 |
|
12778131 |
int length() const |
45 |
|
|
{ |
46 |
2/2
✓ Branch 0 taken 12715663 times.
✓ Branch 1 taken 62468 times.
|
12778131 |
return is_inlined() ? inlined.len : allocated.len; |
47 |
|
|
} |
48 |
|
|
|
49 |
|
5788304 |
void set_length(int length) |
50 |
|
|
{ |
51 |
2/2
✓ Branch 0 taken 32351 times.
✓ Branch 1 taken 5755953 times.
|
5788304 |
if(length > max_inline_length_){ |
52 |
|
32351 |
inlined.len = (unsigned char)-1; |
53 |
|
32351 |
allocated.len = length; |
54 |
|
|
}else{ |
55 |
|
5755953 |
inlined.len = length; |
56 |
|
|
} |
57 |
|
5788304 |
} |
58 |
|
|
|
59 |
|
2898 |
void truncate(int newlen) |
60 |
|
|
{ |
61 |
|
2898 |
resize(newlen); |
62 |
|
2898 |
} |
63 |
|
|
|
64 |
|
1704113 |
void assign(const char * newstr) |
65 |
|
|
{ |
66 |
2/2
✓ Branch 0 taken 236 times.
✓ Branch 1 taken 1703877 times.
|
1704113 |
if (!newstr) newstr = ""; |
67 |
|
1704113 |
assign(newstr, strlen(newstr)); |
68 |
|
1704113 |
} |
69 |
|
|
|
70 |
|
1117284 |
void assign(const string &newstr) |
71 |
|
|
{ |
72 |
|
1117284 |
assign(newstr, newstr.length()); |
73 |
|
1117284 |
} |
74 |
|
|
|
75 |
|
3049839 |
void assign(const char * newstr, int end) |
76 |
|
|
{ |
77 |
|
3049839 |
resize(end); |
78 |
|
3049839 |
copy(newstr, length(), cached_data); |
79 |
|
3049839 |
} |
80 |
|
|
|
81 |
|
|
|
82 |
|
736296 |
string& operator=(const char * newstr) |
83 |
|
|
{ |
84 |
|
736296 |
assign(newstr); |
85 |
|
736296 |
return *this; |
86 |
|
|
} |
87 |
|
|
|
88 |
|
839242 |
string& operator=(const string &newstr) |
89 |
|
|
{ |
90 |
|
839242 |
assign(newstr); |
91 |
|
839242 |
return *this; |
92 |
|
|
} |
93 |
|
|
|
94 |
|
|
string& append(const string& other, int start, int end) |
95 |
|
|
{ |
96 |
|
|
int current_end = length(); |
97 |
|
|
resize(length() + end - start); |
98 |
|
|
copy(other.cached_data + start, end - start, cached_data + current_end); |
99 |
|
|
return *this; |
100 |
|
|
} |
101 |
|
|
|
102 |
|
9564 |
string& append(const char *other, int start, int end) |
103 |
|
|
{ |
104 |
|
9564 |
int current_end = length(); |
105 |
|
9564 |
resize(length() + end - start); |
106 |
|
9564 |
copy(other + start, end - start, cached_data + current_end); |
107 |
|
9564 |
return *this; |
108 |
|
|
} |
109 |
|
|
|
110 |
|
196586 |
string& operator+=(const string& other) |
111 |
|
|
{ |
112 |
|
196586 |
int current_end = length(); |
113 |
|
196586 |
resize(length() + other.length()); |
114 |
|
196586 |
copy(other.cached_data, other.length(), cached_data + current_end); |
115 |
|
196586 |
return *this; |
116 |
|
|
} |
117 |
|
|
|
118 |
|
570806 |
string& operator+=(const char *other) |
119 |
|
|
{ |
120 |
|
570806 |
int current_end = length(); |
121 |
|
570806 |
int otherlen=(int)strlen(other); |
122 |
|
570806 |
resize(length() + otherlen); |
123 |
|
570806 |
copy(other, otherlen, cached_data + current_end); |
124 |
|
570806 |
return *this; |
125 |
|
|
} |
126 |
|
|
|
127 |
|
1958383 |
string& operator+=(char c) |
128 |
|
|
{ |
129 |
|
1958383 |
resize(length() + 1); |
130 |
|
1958383 |
cached_data[length() - 1] = c; |
131 |
|
1958383 |
return *this; |
132 |
|
|
} |
133 |
|
|
|
134 |
|
|
string operator+(char right) const |
135 |
|
|
{ |
136 |
|
|
string ret=*this; |
137 |
|
|
ret+=right; |
138 |
|
|
return ret; |
139 |
|
|
} |
140 |
|
|
|
141 |
|
112781 |
string operator+(const char * right) const |
142 |
|
|
{ |
143 |
|
112781 |
string ret=*this; |
144 |
1/2
✓ Branch 0 taken 112781 times.
✗ Branch 1 not taken.
|
112781 |
ret+=right; |
145 |
|
112781 |
return ret; |
146 |
|
✗ |
} |
147 |
|
|
|
148 |
|
13056 |
bool operator==(const char * right) const |
149 |
|
|
{ |
150 |
|
13056 |
return !strcmp(data(), right); |
151 |
|
|
} |
152 |
|
|
|
153 |
|
222 |
bool operator==(const string& right) const |
154 |
|
|
{ |
155 |
|
222 |
return !strcmp(data(), right.data()); |
156 |
|
|
} |
157 |
|
|
|
158 |
|
20263 |
bool operator!=(const char * right) const |
159 |
|
|
{ |
160 |
|
20263 |
return (strcmp(data(), right) != 0); |
161 |
|
|
} |
162 |
|
|
|
163 |
|
|
bool operator!=(const string& right) const |
164 |
|
|
{ |
165 |
|
|
return (strcmp(data(), right.data()) != 0); |
166 |
|
|
} |
167 |
|
|
|
168 |
|
6991186 |
operator const char*() const |
169 |
|
|
{ |
170 |
|
6991186 |
return data(); |
171 |
|
|
} |
172 |
|
|
|
173 |
|
34466 |
explicit operator bool() const |
174 |
|
|
{ |
175 |
|
34466 |
return length(); |
176 |
|
|
} |
177 |
|
|
|
178 |
|
3890477 |
string() |
179 |
|
3890477 |
{ |
180 |
|
|
//todo reduce I know this isn't all needed |
181 |
|
3890477 |
allocated.bufferlen = 0; |
182 |
|
3890477 |
allocated.str = 0; |
183 |
|
3890477 |
allocated.len = 0; |
184 |
|
3890477 |
inlined.len = 0; |
185 |
|
3890477 |
cached_data = inlined.str; |
186 |
|
3890477 |
next_resize = max_inline_length_+1; |
187 |
|
|
|
188 |
|
3890477 |
} |
189 |
|
829407 |
string(const char * newstr) : string() |
190 |
|
|
{ |
191 |
1/2
✓ Branch 0 taken 829407 times.
✗ Branch 1 not taken.
|
829407 |
assign(newstr); |
192 |
|
829407 |
} |
193 |
|
195753 |
string(const char * newstr, int newlen) : string() |
194 |
|
|
{ |
195 |
1/2
✓ Branch 0 taken 195753 times.
✗ Branch 1 not taken.
|
195753 |
assign(newstr, newlen); |
196 |
|
195753 |
} |
197 |
|
138410 |
string(const string& old) : string() |
198 |
|
|
{ |
199 |
1/2
✓ Branch 0 taken 138410 times.
✗ Branch 1 not taken.
|
138410 |
assign(old.data()); |
200 |
|
138410 |
} |
201 |
|
|
|
202 |
|
18348 |
string(string &&move) : string() |
203 |
|
|
{ |
204 |
1/2
✓ Branch 0 taken 18348 times.
✗ Branch 1 not taken.
|
18348 |
*this = move; |
205 |
|
18348 |
} |
206 |
|
|
|
207 |
|
278270 |
string& operator=(string&& move) |
208 |
|
|
{ |
209 |
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 278106 times.
|
278270 |
if(!is_inlined()) free(allocated.str); |
210 |
2/2
✓ Branch 0 taken 228 times.
✓ Branch 1 taken 278042 times.
|
278270 |
if(!move.is_inlined()){ |
211 |
|
228 |
allocated.str = move.allocated.str; |
212 |
|
228 |
allocated.bufferlen = move.allocated.bufferlen; |
213 |
|
228 |
set_length(move.allocated.len); |
214 |
|
|
|
215 |
|
228 |
move.inlined.len = 0; |
216 |
|
228 |
move.inlined.str[0] = 0; |
217 |
|
228 |
cached_data = allocated.str; |
218 |
|
228 |
next_resize = move.next_resize; |
219 |
|
|
|
220 |
|
|
}else{ |
221 |
|
278042 |
inlined.len = 0; |
222 |
|
278042 |
cached_data = inlined.str; |
223 |
|
278042 |
next_resize = max_inline_length_+1; |
224 |
|
278042 |
assign(move); |
225 |
|
|
} |
226 |
|
278270 |
return *this; |
227 |
|
|
} |
228 |
|
|
|
229 |
|
3711388 |
~string() |
230 |
|
|
{ |
231 |
2/2
✓ Branch 0 taken 16296 times.
✓ Branch 1 taken 3695092 times.
|
3711388 |
if(!is_inlined()){ |
232 |
|
16296 |
free(allocated.str); |
233 |
|
|
} |
234 |
|
3711388 |
} |
235 |
|
|
|
236 |
|
|
//maybe these should return refs to chain. but also good not to encourage chaining |
237 |
|
6730 |
void strip_prefix(char c) |
238 |
|
|
{ |
239 |
2/2
✓ Branch 0 taken 3185 times.
✓ Branch 1 taken 3545 times.
|
6730 |
if(cached_data[0] == c){ |
240 |
3/6
✓ Branch 0 taken 3185 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3185 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3185 times.
✗ Branch 5 not taken.
|
3185 |
*this = string(cached_data + 1, length() - 1); |
241 |
|
|
} |
242 |
|
6730 |
} |
243 |
|
|
|
244 |
|
378 |
void strip_suffix(char c) |
245 |
|
|
{ |
246 |
1/2
✓ Branch 0 taken 378 times.
✗ Branch 1 not taken.
|
378 |
if(cached_data[length() - 1] == c){ |
247 |
|
378 |
truncate(length() - 1); |
248 |
|
|
} |
249 |
|
378 |
} |
250 |
|
|
|
251 |
|
|
string& qreplace(const char * instr, const char * outstr); |
252 |
|
|
string& qnormalize(); |
253 |
|
|
|
254 |
|
|
// RPG Hacker: My hack shmeck to get around no longer supporting text mode. |
255 |
|
|
// Symbol files are currently the only thing that use text mode, anyways, and I don't even know |
256 |
|
|
// if the emulators that read them care about line endings. |
257 |
|
✗ |
string& convert_line_endings_to_native() |
258 |
|
|
{ |
259 |
|
|
#if defined(windows) |
260 |
|
|
// RPG Hacker: This is quite stinky, but doing the replacement directly will lead to a dead-lock. |
261 |
|
|
// \x08 = backspace should never appear inside a string, so I'm abusing it here. |
262 |
|
✗ |
return qreplace("\n", "\x08").qreplace("\x08", "\r\n"); |
263 |
|
|
#else |
264 |
|
✗ |
return *this; |
265 |
|
|
#endif |
266 |
|
|
} |
267 |
|
|
|
268 |
|
|
#ifdef SERIALIZER |
269 |
|
|
void serialize(serializer & s) |
270 |
|
|
{ |
271 |
|
|
s(str, allocated.bufferlen); |
272 |
|
|
set_length(strlen(str)); |
273 |
|
|
} |
274 |
|
|
#endif |
275 |
|
|
#define SERIALIZER_BANNED |
276 |
|
|
|
277 |
|
|
private: |
278 |
|
|
static const int scale_factor = 4; //scale sso |
279 |
|
|
static const int max_inline_length_ = ((sizeof(char *) + sizeof(int) * 2) * scale_factor) - 2; |
280 |
|
|
char *cached_data; |
281 |
|
|
int next_resize; |
282 |
|
|
struct si{ |
283 |
|
|
char str[max_inline_length_ + 1]; |
284 |
|
|
unsigned char len; |
285 |
|
|
}; |
286 |
|
|
|
287 |
|
|
struct sa{ |
288 |
|
|
char *str; |
289 |
|
|
int len; |
290 |
|
|
int bufferlen ; |
291 |
|
|
}; |
292 |
|
|
union{ |
293 |
|
|
si inlined; |
294 |
|
|
sa allocated; |
295 |
|
|
}; |
296 |
|
|
|
297 |
|
|
|
298 |
|
5788076 |
void resize(int new_length) |
299 |
|
|
{ |
300 |
|
5788076 |
const char *old_data = data(); |
301 |
8/8
✓ Branch 0 taken 5770657 times.
✓ Branch 1 taken 17419 times.
✓ Branch 2 taken 14922 times.
✓ Branch 3 taken 5755735 times.
✓ Branch 4 taken 218 times.
✓ Branch 5 taken 14704 times.
✓ Branch 6 taken 17637 times.
✓ Branch 7 taken 5770439 times.
|
5788076 |
if(new_length >= next_resize || (!is_inlined() && new_length <= max_inline_length_)) { |
302 |
7/8
✓ Branch 0 taken 17419 times.
✓ Branch 1 taken 218 times.
✓ Branch 2 taken 739 times.
✓ Branch 3 taken 16680 times.
✓ Branch 4 taken 739 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 17419 times.
✓ Branch 7 taken 218 times.
|
17637 |
if(new_length > max_inline_length_ && (is_inlined() || allocated.bufferlen <= new_length)){ //SSO or big to big |
303 |
|
17419 |
int new_size = bitround(new_length + 1); |
304 |
2/2
✓ Branch 0 taken 16680 times.
✓ Branch 1 taken 739 times.
|
17419 |
if(old_data == inlined.str){ |
305 |
|
16680 |
allocated.str = copy(old_data, min(length(), new_length), (char *)malloc(new_size)); |
306 |
|
|
}else{ |
307 |
|
739 |
allocated.str = (char *)realloc(allocated.str, new_size); |
308 |
|
739 |
old_data = inlined.str; //this will prevent freeing a dead realloc ptr |
309 |
|
|
} |
310 |
|
17419 |
allocated.bufferlen = new_size; |
311 |
|
17419 |
cached_data = allocated.str; |
312 |
|
17419 |
next_resize = allocated.bufferlen; |
313 |
3/6
✓ Branch 0 taken 218 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 218 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 218 times.
✗ Branch 5 not taken.
|
218 |
}else if(length() > max_inline_length_ && new_length <= max_inline_length_){ //big to SSO |
314 |
|
218 |
copy(old_data, new_length, inlined.str); |
315 |
|
218 |
cached_data = inlined.str; |
316 |
|
218 |
next_resize = max_inline_length_+1; |
317 |
|
|
} |
318 |
5/6
✓ Branch 0 taken 218 times.
✓ Branch 1 taken 17419 times.
✓ Branch 2 taken 218 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 218 times.
✓ Branch 5 taken 17419 times.
|
17637 |
if(old_data != inlined.str && old_data != data()){ |
319 |
|
218 |
free((char *)old_data); |
320 |
|
|
} |
321 |
|
|
} |
322 |
|
5788076 |
set_length(new_length); |
323 |
|
|
|
324 |
|
5788076 |
raw()[new_length] = 0; //always ensure null terminator |
325 |
|
5788076 |
} |
326 |
|
|
|
327 |
|
22834135 |
bool is_inlined() const |
328 |
|
|
{ |
329 |
|
22834135 |
return inlined.len != (unsigned char)-1; |
330 |
|
|
} |
331 |
|
|
}; |
332 |
|
|
#define STR (string) |
333 |
|
|
|
334 |
|
|
char * readfile(const char * fname, const char * basepath); |
335 |
|
|
char * readfilenative(const char * fname); |
336 |
|
|
bool readfile(const char * fname, const char * basepath, char ** data, int * len);//if you want an uchar*, cast it |
337 |
|
|
char ** split(char * str, char key, int * len= nullptr); |
338 |
|
|
char ** qsplit(char * str, char key, int * len= nullptr); |
339 |
|
|
char ** qpsplit(char * str, char key, int * len= nullptr); |
340 |
|
|
char ** qsplitstr(char * str, const char * key, int * len= nullptr); |
341 |
|
|
bool confirmquotes(const char * str); |
342 |
|
|
bool confirmqpar(const char * str); |
343 |
|
|
char* strqpchr(char* str, char key); |
344 |
|
|
char* strqpstr(char* str, const char* key); |
345 |
|
|
|
346 |
|
18 |
inline string hex(unsigned int value) |
347 |
|
|
{ |
348 |
|
|
char buffer[64]; |
349 |
|
|
if(0); |
350 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
|
18 |
else if (value<=0x000000FF) sprintf(buffer, "%.2X", value); |
351 |
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
|
18 |
else if (value<=0x0000FFFF) sprintf(buffer, "%.4X", value); |
352 |
|
✗ |
else if (value<=0x00FFFFFF) sprintf(buffer, "%.6X", value); |
353 |
|
✗ |
else sprintf(buffer, "%.8X", value); |
354 |
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
|
36 |
return buffer; |
355 |
|
|
} |
356 |
|
|
|
357 |
|
660 |
inline string hex(unsigned int value, int width) |
358 |
|
|
{ |
359 |
|
|
char buffer[64]; |
360 |
|
660 |
sprintf(buffer, "%.*X", width, value); |
361 |
1/2
✓ Branch 0 taken 660 times.
✗ Branch 1 not taken.
|
1320 |
return buffer; |
362 |
|
|
} |
363 |
|
|
|
364 |
|
16009 |
inline string dec(int value) |
365 |
|
|
{ |
366 |
|
|
char buffer[64]; |
367 |
|
16009 |
sprintf(buffer, "%i", value); |
368 |
1/2
✓ Branch 0 taken 16009 times.
✗ Branch 1 not taken.
|
32018 |
return buffer; |
369 |
|
|
} |
370 |
|
|
|
371 |
|
6498 |
inline string ftostr(double value) |
372 |
|
|
{ |
373 |
|
|
// randomdude999: With 100 digits of precision, the buffer needs to be approx. 311+100, |
374 |
|
|
// but let's be safe here https://stackoverflow.com/questions/7235456 |
375 |
|
|
char rval[512]; |
376 |
|
|
// RPG Hacker: Ridiculously high precision, I know, but we're working with doubles |
377 |
|
|
// here and can afford it, so no need to waste any precision |
378 |
|
6498 |
sprintf(rval, "%.100f", value); |
379 |
1/2
✓ Branch 0 taken 6498 times.
✗ Branch 1 not taken.
|
6498 |
if (strchr(rval, '.'))//nuke useless zeroes |
380 |
|
|
{ |
381 |
|
6498 |
char * end=strrchr(rval, '\0')-1; |
382 |
2/2
✓ Branch 0 taken 648756 times.
✓ Branch 1 taken 6498 times.
|
655254 |
while (*end=='0') |
383 |
|
|
{ |
384 |
|
648756 |
*end='\0'; |
385 |
|
648756 |
end--; |
386 |
|
|
} |
387 |
2/2
✓ Branch 0 taken 6480 times.
✓ Branch 1 taken 18 times.
|
6498 |
if (*end=='.') *end='\0'; |
388 |
|
|
} |
389 |
1/2
✓ Branch 0 taken 6498 times.
✗ Branch 1 not taken.
|
12996 |
return rval; |
390 |
|
|
} |
391 |
|
|
|
392 |
|
|
// Same as above, but with variable precision |
393 |
|
138 |
inline string ftostrvar(double value, int precision) |
394 |
|
|
{ |
395 |
|
138 |
int clampedprecision = precision; |
396 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 138 times.
|
138 |
if (clampedprecision < 0) clampedprecision = 0; |
397 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 138 times.
|
138 |
if (clampedprecision > 100) clampedprecision = 100; |
398 |
|
|
|
399 |
|
|
// see above |
400 |
|
|
char rval[512]; |
401 |
|
138 |
sprintf(rval, "%.*f", clampedprecision, (double)value); |
402 |
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 6 times.
|
138 |
if (strchr(rval, '.'))//nuke useless zeroes |
403 |
|
|
{ |
404 |
|
132 |
char * end = strrchr(rval, '\0') - 1; |
405 |
2/2
✓ Branch 0 taken 414 times.
✓ Branch 1 taken 132 times.
|
546 |
while (*end == '0') |
406 |
|
|
{ |
407 |
|
414 |
*end = '\0'; |
408 |
|
414 |
end--; |
409 |
|
|
} |
410 |
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 78 times.
|
132 |
if (*end == '.') *end = '\0'; |
411 |
|
|
} |
412 |
1/2
✓ Branch 0 taken 138 times.
✗ Branch 1 not taken.
|
276 |
return rval; |
413 |
|
|
} |
414 |
|
|
|
415 |
|
313864 |
inline bool stribegin(const char * str, const char * key) |
416 |
|
|
{ |
417 |
2/2
✓ Branch 0 taken 809259 times.
✓ Branch 1 taken 39618 times.
|
848877 |
for (int i=0;key[i];i++) |
418 |
|
|
{ |
419 |
2/2
✓ Branch 0 taken 274246 times.
✓ Branch 1 taken 535013 times.
|
809259 |
if (to_lower(str[i])!=to_lower(key[i])) return false; |
420 |
|
|
} |
421 |
|
39618 |
return true; |
422 |
|
|
} |
423 |
|
|
|
424 |
|
23256 |
inline bool striend(const char * str, const char * key) |
425 |
|
|
{ |
426 |
|
23256 |
const char * keyend=strrchr(key, '\0'); |
427 |
|
23256 |
const char * strend=strrchr(str, '\0'); |
428 |
2/2
✓ Branch 0 taken 675 times.
✓ Branch 1 taken 22581 times.
|
23256 |
if(keyend-key > strend-str) return false; |
429 |
|
|
|
430 |
2/2
✓ Branch 0 taken 26613 times.
✓ Branch 1 taken 2898 times.
|
29511 |
while (key!=keyend) |
431 |
|
|
{ |
432 |
|
26613 |
keyend--; |
433 |
|
26613 |
strend--; |
434 |
2/2
✓ Branch 0 taken 19683 times.
✓ Branch 1 taken 6930 times.
|
26613 |
if (to_lower(*strend)!=to_lower(*keyend)) return false; |
435 |
|
|
} |
436 |
|
2898 |
return true; |
437 |
|
|
} |
438 |
|
|
|
439 |
|
306378 |
inline bool stricmpwithupper(const char *word1, const char *word2) |
440 |
|
|
{ |
441 |
2/2
✓ Branch 0 taken 345966 times.
✓ Branch 1 taken 11343 times.
|
357309 |
while(*word2) |
442 |
|
|
{ |
443 |
2/2
✓ Branch 0 taken 295035 times.
✓ Branch 1 taken 50931 times.
|
345966 |
if(to_upper(*word1++) != *word2++) return true; |
444 |
|
|
} |
445 |
|
11343 |
return *word1; |
446 |
|
|
} |
447 |
|
|
|
448 |
|
1535752 |
inline bool stricmpwithlower(const char *word1, const char *word2) |
449 |
|
|
{ |
450 |
2/2
✓ Branch 0 taken 2171815 times.
✓ Branch 1 taken 107354 times.
|
2279169 |
while(*word2) |
451 |
|
|
{ |
452 |
2/2
✓ Branch 0 taken 1428398 times.
✓ Branch 1 taken 743417 times.
|
2171815 |
if(to_lower(*word1++) != *word2++) return true; |
453 |
|
|
} |
454 |
|
107354 |
return *word1; |
455 |
|
|
} |
456 |
|
|
|
457 |
|
|
//function: return the string without quotes around it, if any exists |
458 |
|
|
//if they don't exist, return it unaltered |
459 |
|
|
//it is not guaranteed to return str |
460 |
|
|
//it is not guaranteed to not edit str |
461 |
|
|
//the input must be freed even though it's garbage, the output must not |
462 |
|
22644 |
inline const char * dequote(char * str) |
463 |
|
|
{ |
464 |
2/2
✓ Branch 0 taken 2253 times.
✓ Branch 1 taken 20391 times.
|
22644 |
if (*str!='"') return str; |
465 |
|
20391 |
char *end = strrchr(str, '"'); |
466 |
1/2
✓ Branch 0 taken 20391 times.
✗ Branch 1 not taken.
|
20391 |
if (end) |
467 |
|
|
{ |
468 |
|
20391 |
*end = 0; |
469 |
|
20391 |
char *quote = str+1; |
470 |
2/2
✓ Branch 0 taken 432 times.
✓ Branch 1 taken 20391 times.
|
20823 |
while((quote = strstr(quote, "\"\""))) memmove(quote, quote+1, strlen(quote)); |
471 |
|
20391 |
return str + 1; |
472 |
|
|
} |
473 |
|
✗ |
return nullptr; |
474 |
|
|
} |
475 |
|
|
|
476 |
|
34867 |
inline char * strqchr(const char * str, char key) |
477 |
|
|
{ |
478 |
2/2
✓ Branch 0 taken 332147 times.
✓ Branch 1 taken 24211 times.
|
356358 |
while (*str != '\0') |
479 |
|
|
{ |
480 |
2/2
✓ Branch 0 taken 10650 times.
✓ Branch 1 taken 321497 times.
|
332147 |
if (*str == key) { return const_cast<char*>(str); } |
481 |
4/4
✓ Branch 0 taken 319611 times.
✓ Branch 1 taken 1886 times.
✓ Branch 2 taken 534 times.
✓ Branch 3 taken 319077 times.
|
321497 |
else if (*str == '"' || *str == '\'') |
482 |
|
|
{ |
483 |
|
|
// Special case hack for ''', which is currently our official way of handling the ' character. |
484 |
|
|
// Even though it really stinks. |
485 |
5/6
✓ Branch 0 taken 534 times.
✓ Branch 1 taken 1886 times.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 504 times.
✓ Branch 4 taken 30 times.
✗ Branch 5 not taken.
|
2420 |
if (str[0] == '\'' && str[1] == '\'' && str[2] == '\'') { str += 2; } |
486 |
|
|
else |
487 |
|
|
{ |
488 |
|
2390 |
char delimiter = *str; |
489 |
|
|
|
490 |
|
|
do |
491 |
|
|
{ |
492 |
|
27895 |
str++; |
493 |
|
|
|
494 |
|
|
// If we want to support backslash escapes, we'll have to add that right here. |
495 |
4/4
✓ Branch 0 taken 25511 times.
✓ Branch 1 taken 2384 times.
✓ Branch 2 taken 25505 times.
✓ Branch 3 taken 6 times.
|
27895 |
} while (*str != delimiter && *str != '\0'); |
496 |
|
|
|
497 |
|
|
// This feels like a superfluous check, but I can't really find a clean way to avoid it. |
498 |
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2384 times.
|
2390 |
if (*str == '\0') { return nullptr; } |
499 |
|
|
} |
500 |
|
|
} |
501 |
|
|
|
502 |
|
321491 |
str++; |
503 |
|
|
} |
504 |
|
|
|
505 |
|
24211 |
return nullptr; |
506 |
|
|
} |
507 |
|
|
|
508 |
|
7656 |
inline string substr(const char * str, int len) |
509 |
|
|
{ |
510 |
|
7656 |
return string(str, len); |
511 |
|
|
} |
512 |
|
|
|
513 |
|
|
//todo make these members |
514 |
|
|
string &strip_prefix(string &str, char c); |
515 |
|
|
string &strip_suffix(string &str, char c); |
516 |
|
|
|
517 |
|
|
|
518 |
|
192800 |
inline char *strip_whitespace(char *str) |
519 |
|
|
{ |
520 |
2/2
✓ Branch 0 taken 11050 times.
✓ Branch 1 taken 192800 times.
|
203850 |
while(is_space(*str)) str++; |
521 |
2/2
✓ Branch 0 taken 181291 times.
✓ Branch 1 taken 58911 times.
|
240202 |
for(int i = strlen(str) - 1; i >= 0; i--) |
522 |
|
|
{ |
523 |
2/2
✓ Branch 0 taken 133889 times.
✓ Branch 1 taken 47402 times.
|
181291 |
if(!is_space(str[i])) |
524 |
|
|
{ |
525 |
|
133889 |
str[i + 1] = 0; |
526 |
|
133889 |
return str; |
527 |
|
|
} |
528 |
|
|
} |
529 |
|
58911 |
return str; |
530 |
|
|
} |
531 |
|
6667 |
inline void strip_whitespace(string &str) |
532 |
|
|
{ |
533 |
2/4
✓ Branch 0 taken 6667 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6667 times.
✗ Branch 3 not taken.
|
6667 |
str = string(strip_whitespace(str.temp_raw())); |
534 |
|
6667 |
} |
535 |
|
|
|
536 |
|
|
string &itrim(string &str, const char * left, const char * right); |
537 |
|
|
|
538 |
|
20959 |
inline string &lower(string &old) |
539 |
|
|
{ |
540 |
|
20959 |
int length = old.length(); |
541 |
2/2
✓ Branch 0 taken 605066 times.
✓ Branch 1 taken 20959 times.
|
626025 |
for (int i=0;i<length;i++) old.raw()[i]=(char)to_lower(old.data()[i]); |
542 |
|
20959 |
return old; |
543 |
|
|
} |
544 |
|
|
|
545 |
|
|
|
546 |
|
|
// Returns number of connected lines - 1 |
547 |
|
|
template<typename stringarraytype> |
548 |
|
134319 |
inline int getconnectedlines(stringarraytype& lines, int startline, string& out) |
549 |
|
|
{ |
550 |
|
134319 |
int count = 0; |
551 |
|
|
|
552 |
1/2
✓ Branch 0 taken 134373 times.
✗ Branch 1 not taken.
|
134373 |
for (int i = startline; lines[i]; i++) |
553 |
|
|
{ |
554 |
|
|
// The line should already be stripped of any comments at this point |
555 |
|
134373 |
int linestartpos = (int)strlen(lines[i]); |
556 |
|
|
|
557 |
4/4
✓ Branch 0 taken 97749 times.
✓ Branch 1 taken 36624 times.
✓ Branch 2 taken 54 times.
✓ Branch 3 taken 97695 times.
|
134373 |
if(linestartpos && lines[i][linestartpos - 1] == '\\') |
558 |
|
|
{ |
559 |
|
54 |
count++; |
560 |
2/4
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 54 times.
✗ Branch 3 not taken.
|
54 |
out += string(lines[i], linestartpos - 1); |
561 |
|
54 |
continue; |
562 |
|
|
} |
563 |
|
|
else |
564 |
|
|
{ |
565 |
2/4
✓ Branch 0 taken 134319 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 134319 times.
✗ Branch 3 not taken.
|
134319 |
out += string(lines[i], linestartpos); |
566 |
|
134319 |
return count; |
567 |
|
|
} |
568 |
|
|
} |
569 |
|
|
|
570 |
|
✗ |
return count; |
571 |
|
|
} |
572 |
|
|
|