Line |
Branch |
Exec |
Source |
1 |
|
|
#pragma once |
2 |
|
|
|
3 |
|
|
#include "std-includes.h" |
4 |
|
|
#include <cstdint> |
5 |
|
|
#include <cstring> |
6 |
|
|
#include <utility> |
7 |
|
|
#include <string_view> |
8 |
|
|
#include <cinttypes> |
9 |
|
|
|
10 |
|
|
//ty alcaro |
11 |
|
|
extern const unsigned char char_props[256]; |
12 |
|
1450708 |
static inline int to_lower(unsigned char c) { return c|(char_props[c]&0x20); } |
13 |
|
|
static inline int to_upper(unsigned char c) { return c&~(char_props[c]&0x20); } |
14 |
|
|
|
15 |
|
238217 |
inline bool is_space(unsigned char c) { return char_props[c] & 0x80; } // C standard says \f \v are space, but this one disagrees |
16 |
|
|
// TODO is this opaque table lookup really faster than c >= '0' && c <= '9'? |
17 |
|
49749 |
inline bool is_digit(unsigned char c) { return char_props[c] & 0x40; } |
18 |
|
|
inline bool is_alpha(unsigned char c) { return char_props[c] & 0x20; } |
19 |
|
✗ |
inline bool is_lower(unsigned char c) { return char_props[c] & 0x04; } |
20 |
|
106 |
inline bool is_upper(unsigned char c) { return char_props[c] & 0x02; } |
21 |
|
|
inline bool is_alnum(unsigned char c) { return char_props[c] & 0x60; } |
22 |
|
14715 |
inline bool is_ualpha(unsigned char c) { return char_props[c] & 0x28; } |
23 |
|
120831 |
inline bool is_ualnum(unsigned char c) { return char_props[c] & 0x68; } |
24 |
|
7334 |
inline bool is_xdigit(unsigned char c) { return char_props[c] & 0x01; } |
25 |
|
|
|
26 |
|
791786 |
inline char *copy(const char *source, int copy_length, char *dest) |
27 |
|
|
{ |
28 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 373149 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 373149 times.
|
791786 |
memcpy(dest, source, copy_length*sizeof(char)); |
29 |
|
791786 |
return dest; |
30 |
|
|
} |
31 |
|
|
|
32 |
|
|
class string { |
33 |
|
|
public: |
34 |
|
2569072 |
const char *data() const |
35 |
|
|
{ |
36 |
|
2569072 |
return data_ptr; |
37 |
|
|
} |
38 |
|
|
|
39 |
|
115793 |
char *temp_raw() const //things to cleanup and take a look at |
40 |
|
|
{ |
41 |
|
115793 |
return data_ptr; |
42 |
|
|
} |
43 |
|
|
|
44 |
|
264907 |
char *raw() const |
45 |
|
|
{ |
46 |
|
264907 |
return data_ptr; |
47 |
|
|
} |
48 |
|
|
|
49 |
|
2530279 |
int length() const |
50 |
|
|
{ |
51 |
|
2530279 |
return len; |
52 |
|
|
} |
53 |
|
|
|
54 |
|
1303693 |
void resize(unsigned int new_length) |
55 |
|
|
{ |
56 |
3/3
✓ Branch 0 taken 1572 times.
✓ Branch 1 taken 698706 times.
✓ Branch 2 taken 603415 times.
|
1303693 |
if (new_length > capacity()) { |
57 |
|
3437 |
reallocate_capacity(new_length); |
58 |
|
|
} |
59 |
|
|
|
60 |
|
1303693 |
len = new_length; |
61 |
|
1303693 |
data_ptr[new_length] = 0; //always ensure null terminator |
62 |
|
1303693 |
} |
63 |
|
|
|
64 |
|
792 |
void truncate(int newlen) |
65 |
|
|
{ |
66 |
|
792 |
resize(newlen); |
67 |
|
792 |
} |
68 |
|
|
|
69 |
|
463160 |
void assign(const char * newstr) |
70 |
|
|
{ |
71 |
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 463157 times.
|
463160 |
if (!newstr) newstr = ""; |
72 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 223643 times.
|
463160 |
assign(newstr, strlen(newstr)); |
73 |
|
463160 |
} |
74 |
|
|
|
75 |
|
112877 |
void assign(const string &newstr) |
76 |
|
|
{ |
77 |
|
112877 |
assign(newstr.data(), newstr.length()); |
78 |
|
112877 |
} |
79 |
|
|
|
80 |
|
651626 |
void assign(const char * newstr, int end) |
81 |
|
|
{ |
82 |
|
651626 |
resize(end); |
83 |
|
651626 |
copy(newstr, end, data_ptr); |
84 |
|
651626 |
} |
85 |
|
|
|
86 |
|
|
|
87 |
|
14177 |
string& operator=(const char * newstr) |
88 |
|
|
{ |
89 |
|
14177 |
assign(newstr); |
90 |
|
14177 |
return *this; |
91 |
|
|
} |
92 |
|
|
|
93 |
|
112877 |
string& operator=(const string &newstr) |
94 |
|
|
{ |
95 |
|
112877 |
assign(newstr); |
96 |
|
112877 |
return *this; |
97 |
|
|
} |
98 |
|
|
|
99 |
|
|
string& append(const string& other, int start, int end) |
100 |
|
|
{ |
101 |
|
|
int current_end = length(); |
102 |
|
|
resize(length() + end - start); |
103 |
|
|
copy(other.data() + start, end - start, data_ptr + current_end); |
104 |
|
|
return *this; |
105 |
|
|
} |
106 |
|
|
|
107 |
|
3408 |
string& append(const char *other, int start, int end) |
108 |
|
|
{ |
109 |
|
3408 |
int current_end = length(); |
110 |
|
3408 |
resize(length() + end - start); |
111 |
|
3408 |
copy(other + start, end - start, data_ptr + current_end); |
112 |
|
3408 |
return *this; |
113 |
|
|
} |
114 |
|
|
|
115 |
|
50090 |
string& operator+=(const string& other) |
116 |
|
|
{ |
117 |
|
50090 |
int current_end = length(); |
118 |
|
50090 |
resize(length() + other.length()); |
119 |
|
50090 |
copy(other.data(), other.length(), data_ptr + current_end); |
120 |
|
50090 |
return *this; |
121 |
|
|
} |
122 |
|
|
|
123 |
|
83415 |
string& operator+=(const char *other) |
124 |
|
|
{ |
125 |
|
83415 |
int current_end = length(); |
126 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39104 times.
|
83415 |
int otherlen=(int)strlen(other); |
127 |
|
83415 |
resize(length() + otherlen); |
128 |
|
83415 |
copy(other, otherlen, data_ptr + current_end); |
129 |
|
83415 |
return *this; |
130 |
|
|
} |
131 |
|
|
|
132 |
|
514358 |
string& operator+=(char c) |
133 |
|
|
{ |
134 |
|
514358 |
resize(length() + 1); |
135 |
|
514358 |
data_ptr[length() - 1] = c; |
136 |
|
514358 |
return *this; |
137 |
|
|
} |
138 |
|
|
|
139 |
|
|
string operator+(char right) const |
140 |
|
|
{ |
141 |
|
|
string ret=*this; |
142 |
|
|
ret+=right; |
143 |
|
|
return ret; |
144 |
|
|
} |
145 |
|
|
|
146 |
|
19097 |
string operator+(const char * right) const |
147 |
|
|
{ |
148 |
|
19097 |
string ret=*this; |
149 |
1/2
✓ Branch 0 taken 19097 times.
✗ Branch 1 not taken.
|
19097 |
ret+=right; |
150 |
|
19097 |
return ret; |
151 |
|
✗ |
} |
152 |
|
|
|
153 |
|
1772471 |
operator const char*() const |
154 |
|
|
{ |
155 |
|
1772471 |
return data(); |
156 |
|
|
} |
157 |
|
|
|
158 |
|
10280 |
explicit operator bool() const |
159 |
|
|
{ |
160 |
|
10280 |
return length(); |
161 |
|
|
} |
162 |
|
|
|
163 |
|
894236 |
string() |
164 |
|
894236 |
{ |
165 |
|
894236 |
data_ptr = inlined.data; |
166 |
|
894236 |
len = 0; |
167 |
|
894236 |
inlined.data[0] = '\0'; |
168 |
|
894236 |
} |
169 |
|
267407 |
string(const char * newstr) : string() |
170 |
|
|
{ |
171 |
2/3
✓ Branch 0 taken 138021 times.
✓ Branch 1 taken 129386 times.
✗ Branch 2 not taken.
|
267407 |
assign(newstr); |
172 |
|
267407 |
} |
173 |
|
63282 |
string(const char * newstr, int newlen) : string() |
174 |
|
|
{ |
175 |
2/3
✓ Branch 0 taken 32957 times.
✓ Branch 1 taken 30325 times.
✗ Branch 2 not taken.
|
63282 |
assign(newstr, newlen); |
176 |
|
63282 |
} |
177 |
|
181576 |
string(const string& old) : string() |
178 |
|
|
{ |
179 |
2/4
✓ Branch 0 taken 92997 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88579 times.
✗ Branch 3 not taken.
|
181576 |
assign(old.data()); |
180 |
|
181576 |
} |
181 |
|
|
|
182 |
|
20184 |
string(string &&move) noexcept : string() |
183 |
|
|
{ |
184 |
|
20184 |
*this = move; |
185 |
|
20184 |
} |
186 |
|
|
|
187 |
|
45660 |
string& operator=(string&& other) noexcept |
188 |
|
|
{ |
189 |
3/3
✓ Branch 0 taken 27666 times.
✓ Branch 1 taken 17953 times.
✓ Branch 2 taken 41 times.
|
45660 |
if (other.is_inlined()) { |
190 |
|
|
// No resources to steal so just do a normal assignment |
191 |
|
45580 |
*this = other; |
192 |
|
|
} else { |
193 |
3/3
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 41 times.
✓ Branch 2 taken 21 times.
|
80 |
if (is_inlined()) { |
194 |
|
38 |
data_ptr = other.data_ptr; |
195 |
|
38 |
other.data_ptr = 0; |
196 |
|
|
} else { |
197 |
|
|
// Give our old allocation back so other can free it for us |
198 |
|
42 |
std::swap(data_ptr, other.data_ptr); |
199 |
|
|
} |
200 |
|
80 |
len = other.len; |
201 |
|
80 |
allocated = other.allocated; |
202 |
|
|
} |
203 |
|
45660 |
return *this; |
204 |
|
|
} |
205 |
|
|
|
206 |
|
875403 |
~string() |
207 |
|
|
{ |
208 |
3/3
✓ Branch 0 taken 1513 times.
✓ Branch 1 taken 451992 times.
✓ Branch 2 taken 421898 times.
|
875403 |
if(!is_inlined()){ |
209 |
|
3285 |
free(data_ptr); |
210 |
|
|
} |
211 |
|
875403 |
} |
212 |
|
|
|
213 |
|
|
//maybe these should return refs to chain. but also good not to encourage chaining |
214 |
|
11 |
void strip_prefix(char c) |
215 |
|
|
{ |
216 |
2/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 7 times.
|
11 |
if(data()[0] == c){ |
217 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
|
4 |
std::memmove(data_ptr, data_ptr + 1, length() - 1); |
218 |
|
4 |
resize(length() - 1); |
219 |
|
|
} |
220 |
|
11 |
} |
221 |
|
|
|
222 |
|
|
void strip_suffix(char c) |
223 |
|
|
{ |
224 |
|
|
if (data()[length() - 1] == c) { |
225 |
|
|
truncate(length() - 1); |
226 |
|
|
} |
227 |
|
|
} |
228 |
|
|
|
229 |
|
|
string& qreplace(const char * instr, const char * outstr); |
230 |
|
|
string& qnormalize(); |
231 |
|
|
|
232 |
|
|
// RPG Hacker: My hack shmeck to get around no longer supporting text mode. |
233 |
|
|
// Symbol files are currently the only thing that use text mode, anyways, and I don't even know |
234 |
|
|
// if the emulators that read them care about line endings. |
235 |
|
✗ |
string& convert_line_endings_to_native() |
236 |
|
|
{ |
237 |
|
|
#if defined(windows) |
238 |
|
|
// RPG Hacker: This is quite stinky, but doing the replacement directly will lead to a dead-lock. |
239 |
|
|
// \x08 = backspace should never appear inside a string, so I'm abusing it here. |
240 |
|
✗ |
return qreplace("\n", "\x08").qreplace("\x08", "\r\n"); |
241 |
|
|
#else |
242 |
|
✗ |
return *this; |
243 |
|
|
#endif |
244 |
|
|
} |
245 |
|
|
|
246 |
|
|
private: |
247 |
|
|
static const int scale_factor = 4; //scale sso |
248 |
|
|
static const int inline_capacity = ((sizeof(char *) + sizeof(int) * 2) * scale_factor) - 2; |
249 |
|
|
|
250 |
|
|
// Points to a malloc'd data block or to inlined.data |
251 |
|
|
char *data_ptr; |
252 |
|
|
unsigned int len; |
253 |
|
|
union { |
254 |
|
|
struct { |
255 |
|
|
// Actual allocated capacity is +1 this value, to cover for the terminating NUL |
256 |
|
|
unsigned int capacity; |
257 |
|
|
} allocated; |
258 |
|
|
struct { |
259 |
|
|
char data[inline_capacity + 1]; |
260 |
|
|
} inlined; |
261 |
|
|
}; |
262 |
|
|
|
263 |
|
|
void reallocate_capacity(unsigned int new_length); |
264 |
|
|
|
265 |
|
1303693 |
unsigned capacity() const |
266 |
|
|
{ |
267 |
3/3
✓ Branch 0 taken 697733 times.
✓ Branch 1 taken 605064 times.
✓ Branch 2 taken 896 times.
|
1303693 |
return is_inlined() ? inline_capacity : allocated.capacity; |
268 |
|
|
} |
269 |
|
|
|
270 |
|
2228273 |
bool is_inlined() const |
271 |
|
|
{ |
272 |
|
2228273 |
return data_ptr == inlined.data; |
273 |
|
|
} |
274 |
|
|
}; |
275 |
|
|
#define STR (string) |
276 |
|
|
|
277 |
|
|
#define ASAR_STRCMP_OPERATORS(op) \ |
278 |
|
|
inline bool operator op(const string& left, const string& right) { \ |
279 |
|
|
return strcmp(left, right) op 0; \ |
280 |
|
|
} \ |
281 |
|
|
inline bool operator op(const string& left, const char* right) { \ |
282 |
|
|
return strcmp(left, right) op 0; \ |
283 |
|
|
} \ |
284 |
|
|
inline bool operator op(const char* left, const string& right) { \ |
285 |
|
|
return strcmp(left, right) op 0; \ |
286 |
|
|
} |
287 |
|
|
|
288 |
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 3566 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 26021 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 22455 times.
|
60197 |
ASAR_STRCMP_OPERATORS(==) |
289 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1632 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1632 times.
|
4237 |
ASAR_STRCMP_OPERATORS(!=) |
290 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
|
12 |
ASAR_STRCMP_OPERATORS(<) |
291 |
|
✗ |
ASAR_STRCMP_OPERATORS(<=) |
292 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
|
6 |
ASAR_STRCMP_OPERATORS(>) |
293 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
|
6 |
ASAR_STRCMP_OPERATORS(>=) |
294 |
|
|
#undef ASAR_STRCMP_OPERATORS |
295 |
|
|
|
296 |
|
|
template<> |
297 |
|
|
struct std::hash<string> { |
298 |
|
72839 |
size_t operator()(const ::string& s) const { |
299 |
|
72839 |
return std::hash<std::string_view>()(std::string_view(s.data(), s.length())); |
300 |
|
|
} |
301 |
|
|
}; |
302 |
|
|
|
303 |
|
|
char * readfile(const char * fname, const char * basepath); |
304 |
|
|
char * readfilenative(const char * fname); |
305 |
|
|
bool readfile(const char * fname, const char * basepath, char ** data, int * len);//if you want an uchar*, cast it |
306 |
|
|
char ** split(char * str, char key, int * len= nullptr); |
307 |
|
|
char ** qsplit(char * str, char key, int * len= nullptr); |
308 |
|
|
char ** qpsplit(char * str, char key, int * len= nullptr); |
309 |
|
|
char ** qsplitstr(char * str, const char * key, int * len= nullptr); |
310 |
|
|
bool confirmquotes(const char * str); |
311 |
|
|
bool confirmqpar(const char * str); |
312 |
|
|
char* strqpchr(char* str, char key); |
313 |
|
|
char* strqpstr(char* str, const char* key); |
314 |
|
|
|
315 |
|
✗ |
inline string hex(unsigned int value) |
316 |
|
|
{ |
317 |
|
✗ |
char buffer[64]; |
318 |
|
|
if(0); |
319 |
|
✗ |
else if (value<=0x000000FF) snprintf(buffer, sizeof(buffer), "%.2X", value); |
320 |
|
✗ |
else if (value<=0x0000FFFF) snprintf(buffer, sizeof(buffer), "%.4X", value); |
321 |
|
✗ |
else if (value<=0x00FFFFFF) snprintf(buffer, sizeof(buffer), "%.6X", value); |
322 |
|
✗ |
else snprintf(buffer, sizeof(buffer), "%.8X", value); |
323 |
|
✗ |
return buffer; |
324 |
|
|
} |
325 |
|
|
|
326 |
|
2 |
inline string hex(unsigned int value, int width) |
327 |
|
|
{ |
328 |
|
1 |
char buffer[64]; |
329 |
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
2 |
snprintf(buffer, sizeof(buffer), "%.*X", width, value); |
330 |
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
4 |
return buffer; |
331 |
|
|
} |
332 |
|
|
|
333 |
|
3310 |
inline string dec(int64_t value) |
334 |
|
|
{ |
335 |
|
1710 |
char buffer[64]; |
336 |
2/2
✓ Branch 0 taken 1600 times.
✓ Branch 1 taken 1710 times.
|
3310 |
snprintf(buffer, sizeof(buffer), "%" PRId64, value); |
337 |
1/2
✓ Branch 0 taken 3310 times.
✗ Branch 1 not taken.
|
6620 |
return buffer; |
338 |
|
|
} |
339 |
|
|
|
340 |
|
|
// todo this function sucks, replace with std::to_chars |
341 |
|
258 |
inline string ftostr(double value) |
342 |
|
|
{ |
343 |
|
|
// randomdude999: With 100 digits of precision, the buffer needs to be approx. 311+100, |
344 |
|
|
// but let's be safe here https://stackoverflow.com/questions/7235456 |
345 |
|
129 |
char rval[512]; |
346 |
|
|
// RPG Hacker: Ridiculously high precision, I know, but we're working with doubles |
347 |
|
|
// here and can afford it, so no need to waste any precision |
348 |
1/2
✓ Branch 0 taken 129 times.
✗ Branch 1 not taken.
|
258 |
snprintf(rval, sizeof(rval), "%.100f", value); |
349 |
1/2
✓ Branch 0 taken 258 times.
✗ Branch 1 not taken.
|
258 |
if (strchr(rval, '.'))//nuke useless zeroes |
350 |
|
|
{ |
351 |
|
258 |
char * end=strrchr(rval, '\0')-1; |
352 |
3/3
✓ Branch 0 taken 12726 times.
✓ Branch 1 taken 12855 times.
✓ Branch 2 taken 129 times.
|
25710 |
while (*end=='0') |
353 |
|
|
{ |
354 |
|
25452 |
*end='\0'; |
355 |
|
25452 |
end--; |
356 |
|
|
} |
357 |
3/3
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 129 times.
✓ Branch 2 taken 3 times.
|
258 |
if (*end=='.') *end='\0'; |
358 |
|
|
} |
359 |
1/2
✓ Branch 0 taken 258 times.
✗ Branch 1 not taken.
|
516 |
return rval; |
360 |
|
|
} |
361 |
|
|
|
362 |
|
|
// Same as above, but with variable precision |
363 |
|
24 |
inline string ftostrvar(double value, int precision) |
364 |
|
|
{ |
365 |
|
24 |
int clampedprecision = precision; |
366 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
|
24 |
if (clampedprecision < 0) clampedprecision = 0; |
367 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
|
24 |
if (clampedprecision > 100) clampedprecision = 100; |
368 |
|
|
|
369 |
|
|
// see above |
370 |
|
12 |
char rval[512]; |
371 |
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
|
24 |
snprintf(rval, sizeof(rval), "%.*f", clampedprecision, (double)value); |
372 |
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 2 times.
|
24 |
if (strchr(rval, '.'))//nuke useless zeroes |
373 |
|
|
{ |
374 |
|
22 |
char * end = strrchr(rval, '\0') - 1; |
375 |
3/3
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 34 times.
✓ Branch 2 taken 11 times.
|
68 |
while (*end == '0') |
376 |
|
|
{ |
377 |
|
46 |
*end = '\0'; |
378 |
|
46 |
end--; |
379 |
|
|
} |
380 |
3/3
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 8 times.
|
22 |
if (*end == '.') *end = '\0'; |
381 |
|
|
} |
382 |
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
|
48 |
return rval; |
383 |
|
|
} |
384 |
|
|
|
385 |
|
80843 |
inline bool stribegin(const char * str, const char * key) |
386 |
|
|
{ |
387 |
4/4
✓ Branch 0 taken 112589 times.
✓ Branch 1 taken 4061 times.
✓ Branch 2 taken 77478 times.
✓ Branch 3 taken 1908 times.
|
196036 |
for (int i=0;key[i];i++) |
388 |
|
|
{ |
389 |
4/4
✓ Branch 0 taken 37178 times.
✓ Branch 1 taken 75411 times.
✓ Branch 2 taken 37696 times.
✓ Branch 3 taken 39782 times.
|
190067 |
if (to_lower(str[i])!=to_lower(key[i])) return false; |
390 |
|
|
} |
391 |
|
5969 |
return true; |
392 |
|
|
} |
393 |
|
|
|
394 |
|
|
inline bool striend(const char * str, const char * key) |
395 |
|
|
{ |
396 |
|
|
const char * keyend=strrchr(key, '\0'); |
397 |
|
|
const char * strend=strrchr(str, '\0'); |
398 |
|
|
if(keyend-key > strend-str) return false; |
399 |
|
|
|
400 |
|
|
while (key!=keyend) |
401 |
|
|
{ |
402 |
|
|
keyend--; |
403 |
|
|
strend--; |
404 |
|
|
if (to_lower(*strend)!=to_lower(*keyend)) return false; |
405 |
|
|
} |
406 |
|
|
return true; |
407 |
|
|
} |
408 |
|
|
|
409 |
|
|
inline bool stricmpwithupper(const char *word1, const char *word2) |
410 |
|
|
{ |
411 |
|
|
while(*word2) |
412 |
|
|
{ |
413 |
|
|
if(to_upper(*word1++) != *word2++) return true; |
414 |
|
|
} |
415 |
|
|
return *word1; |
416 |
|
|
} |
417 |
|
|
|
418 |
|
568674 |
inline bool stricmpwithlower(const char *word1, const char *word2) |
419 |
|
|
{ |
420 |
3/3
✓ Branch 0 taken 408928 times.
✓ Branch 1 taken 382988 times.
✓ Branch 2 taken 16917 times.
|
808833 |
while(*word2) |
421 |
|
|
{ |
422 |
4/4
✓ Branch 0 taken 283881 times.
✓ Branch 1 taken 125047 times.
✓ Branch 2 taken 250200 times.
✓ Branch 3 taken 115112 times.
|
774240 |
if(to_lower(*word1++) != *word2++) return true; |
423 |
|
|
} |
424 |
|
34593 |
return *word1; |
425 |
|
|
} |
426 |
|
|
|
427 |
|
|
//function: return the string without quotes around it, if any exists |
428 |
|
|
//if they don't exist, return it unaltered |
429 |
|
|
//it is not guaranteed to return str |
430 |
|
|
//it is not guaranteed to not edit str |
431 |
|
|
//the input must be freed even though it's garbage, the output must not |
432 |
|
4902 |
inline const char * dequote(char * str) |
433 |
|
|
{ |
434 |
3/3
✓ Branch 0 taken 372 times.
✓ Branch 1 taken 2971 times.
✓ Branch 2 taken 1559 times.
|
4902 |
if (*str!='"') return str; |
435 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1559 times.
|
4122 |
char *end = strrchr(str, '"'); |
436 |
1/2
✓ Branch 0 taken 4122 times.
✗ Branch 1 not taken.
|
4122 |
if (end) |
437 |
|
|
{ |
438 |
|
4122 |
*end = 0; |
439 |
|
4122 |
char *quote = str+1; |
440 |
4/4
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 4194 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 1559 times.
|
4266 |
while((quote = strstr(quote, "\"\""))) { |
441 |
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 72 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 72 times.
|
144 |
memmove(quote, quote+1, strlen(quote)); |
442 |
|
144 |
quote++; |
443 |
|
|
} |
444 |
|
4122 |
return str + 1; |
445 |
|
|
} |
446 |
|
✗ |
return nullptr; |
447 |
|
|
} |
448 |
|
|
|
449 |
|
15749 |
inline char * strqchr(const char * str, char key) |
450 |
|
|
{ |
451 |
3/3
✓ Branch 0 taken 68973 times.
✓ Branch 1 taken 76315 times.
✓ Branch 2 taken 5999 times.
|
151287 |
while (*str != '\0') |
452 |
|
|
{ |
453 |
3/3
✓ Branch 0 taken 1922 times.
✓ Branch 1 taken 68979 times.
✓ Branch 2 taken 68489 times.
|
139390 |
if (*str == key) { return const_cast<char*>(str); } |
454 |
6/6
✓ Branch 0 taken 66704 times.
✓ Branch 1 taken 68480 times.
✓ Branch 2 taken 449 times.
✓ Branch 3 taken 66611 times.
✓ Branch 4 taken 93 times.
✓ Branch 5 taken 68040 times.
|
135540 |
else if (*str == '"' || *str == '\'') |
455 |
|
|
{ |
456 |
|
|
// Special case hack for ''', which is currently our official way of handling the ' character. |
457 |
|
|
// Even though it really stinks. |
458 |
8/9
✓ Branch 0 taken 93 times.
✓ Branch 1 taken 440 times.
✓ Branch 2 taken 362 times.
✓ Branch 3 taken 87 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 87 times.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
|
889 |
if (str[0] == '\'' && str[1] == '\'' && str[2] == '\'') { str += 2; } |
459 |
|
|
else |
460 |
|
|
{ |
461 |
|
877 |
char delimiter = *str; |
462 |
|
|
|
463 |
|
|
do |
464 |
|
|
{ |
465 |
|
9091 |
str++; |
466 |
|
|
|
467 |
|
|
// If we want to support backslash escapes, we'll have to add that right here. |
468 |
6/6
✓ Branch 0 taken 4070 times.
✓ Branch 1 taken 4579 times.
✓ Branch 2 taken 4511 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 4145 times.
✓ Branch 5 taken 1 times.
|
9091 |
} while (*str != delimiter && *str != '\0'); |
469 |
|
|
|
470 |
|
|
// This feels like a superfluous check, but I can't really find a clean way to avoid it. |
471 |
3/3
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 434 times.
✓ Branch 2 taken 442 times.
|
877 |
if (*str == '\0') { return nullptr; } |
472 |
|
|
} |
473 |
|
|
} |
474 |
|
|
|
475 |
|
135538 |
str++; |
476 |
|
|
} |
477 |
|
|
|
478 |
|
11897 |
return nullptr; |
479 |
|
|
} |
480 |
|
|
|
481 |
|
2580 |
inline string substr(const char * str, int len) |
482 |
|
|
{ |
483 |
|
2580 |
return string(str, len); |
484 |
|
|
} |
485 |
|
|
|
486 |
|
|
|
487 |
|
63967 |
inline char *strip_whitespace(char *str) |
488 |
|
|
{ |
489 |
4/4
✓ Branch 0 taken 1532 times.
✓ Branch 1 taken 32239 times.
✓ Branch 2 taken 1971 times.
✓ Branch 3 taken 31728 times.
|
67470 |
while(is_space(*str)) str++; |
490 |
4/4
✓ Branch 0 taken 29248 times.
✓ Branch 1 taken 42287 times.
✓ Branch 2 taken 28661 times.
✓ Branch 3 taken 10643 times.
|
79111 |
for(int i = strlen(str) - 1; i >= 0; i--) |
491 |
|
|
{ |
492 |
4/4
✓ Branch 0 taken 21680 times.
✓ Branch 1 taken 7568 times.
✓ Branch 2 taken 21085 times.
✓ Branch 3 taken 7576 times.
|
57909 |
if(!is_space(str[i])) |
493 |
|
|
{ |
494 |
|
42765 |
str[i + 1] = 0; |
495 |
|
42765 |
return str; |
496 |
|
|
} |
497 |
|
|
} |
498 |
|
21202 |
return str; |
499 |
|
|
} |
500 |
|
267 |
inline void strip_whitespace(string &str) |
501 |
|
|
{ |
502 |
2/4
✓ Branch 0 taken 126 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 141 times.
✗ Branch 3 not taken.
|
267 |
str = string(strip_whitespace(str.temp_raw())); |
503 |
|
267 |
} |
504 |
|
|
|
505 |
|
|
string &itrim(string &str, const char * left, const char * right); |
506 |
|
|
|
507 |
|
5635 |
inline string &lower(string &old) |
508 |
|
|
{ |
509 |
|
5635 |
int length = old.length(); |
510 |
4/4
✓ Branch 0 taken 168255 times.
✓ Branch 1 taken 5633 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 2 times.
|
173896 |
for (int i=0;i<length;i++) old.raw()[i]=(char)to_lower(old.data()[i]); |
511 |
|
5635 |
return old; |
512 |
|
|
} |
513 |
|
|
|
514 |
|
|
|
515 |
|
|
// Returns number of connected lines - 1 |
516 |
|
|
template<typename stringarraytype> |
517 |
|
45338 |
inline int getconnectedlines(stringarraytype& lines, int startline, string& out) |
518 |
|
|
{ |
519 |
|
45338 |
int count = 0; |
520 |
|
|
|
521 |
2/4
✓ Branch 0 taken 23030 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 22326 times.
✗ Branch 3 not taken.
|
45356 |
for (int i = startline; lines[i]; i++) |
522 |
|
|
{ |
523 |
|
|
// The line should already be stripped of any comments at this point |
524 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22326 times.
|
45356 |
int linestartpos = (int)strlen(lines[i]); |
525 |
|
|
|
526 |
6/6
✓ Branch 0 taken 31776 times.
✓ Branch 1 taken 13580 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 16255 times.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 15503 times.
|
45356 |
if(linestartpos && lines[i][linestartpos - 1] == '\\') |
527 |
|
|
{ |
528 |
|
18 |
count++; |
529 |
4/7
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 9 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
|
18 |
out += string(lines[i], linestartpos - 1); |
530 |
|
18 |
continue; |
531 |
|
|
} |
532 |
|
|
else |
533 |
|
|
{ |
534 |
4/7
✓ Branch 0 taken 23021 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 23021 times.
✓ Branch 3 taken 22317 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 22317 times.
✗ Branch 6 not taken.
|
45338 |
out += string(lines[i], linestartpos); |
535 |
|
45338 |
return count; |
536 |
|
|
} |
537 |
|
|
} |
538 |
|
|
|
539 |
|
✗ |
return count; |
540 |
|
|
} |
541 |
|
|
|