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 |
|
1628320 |
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 |
|
273328 |
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 |
|
48341 |
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 |
|
16965 |
inline bool is_ualpha(unsigned char c) { return char_props[c] & 0x28; } |
23 |
|
121519 |
inline bool is_ualnum(unsigned char c) { return char_props[c] & 0x68; } |
24 |
|
7328 |
inline bool is_xdigit(unsigned char c) { return char_props[c] & 0x01; } |
25 |
|
|
|
26 |
|
1086545 |
inline char *copy(const char *source, int copy_length, char *dest) |
27 |
|
|
{ |
28 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 542447 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 542447 times.
|
1086545 |
memcpy(dest, source, copy_length*sizeof(char)); |
29 |
|
1086545 |
return dest; |
30 |
|
|
} |
31 |
|
|
|
32 |
|
|
class string { |
33 |
|
|
public: |
34 |
|
4561677 |
const char *data() const |
35 |
|
|
{ |
36 |
|
4561677 |
return data_ptr; |
37 |
|
|
} |
38 |
|
|
|
39 |
|
86243 |
char *temp_raw() const //things to cleanup and take a look at |
40 |
|
|
{ |
41 |
|
86243 |
return data_ptr; |
42 |
|
|
} |
43 |
|
|
|
44 |
|
832790 |
char *raw() const |
45 |
|
|
{ |
46 |
|
832790 |
return data_ptr; |
47 |
|
|
} |
48 |
|
|
|
49 |
|
4530120 |
int length() const |
50 |
|
|
{ |
51 |
|
4530120 |
return len; |
52 |
|
|
} |
53 |
|
|
|
54 |
|
1943072 |
void resize(unsigned int new_length) |
55 |
|
|
{ |
56 |
3/3
✓ Branch 0 taken 1256 times.
✓ Branch 1 taken 973492 times.
✓ Branch 2 taken 968324 times.
|
1943072 |
if (new_length > capacity()) { |
57 |
|
2724 |
reallocate_capacity(new_length); |
58 |
|
|
} |
59 |
|
|
|
60 |
|
1943072 |
len = new_length; |
61 |
|
1943072 |
data_ptr[new_length] = 0; //always ensure null terminator |
62 |
|
1943072 |
} |
63 |
|
|
|
64 |
|
804 |
void truncate(int newlen) |
65 |
|
|
{ |
66 |
|
804 |
resize(newlen); |
67 |
|
804 |
} |
68 |
|
|
|
69 |
|
210166 |
void assign(const char * newstr) |
70 |
|
|
{ |
71 |
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 210163 times.
|
210166 |
if (!newstr) newstr = ""; |
72 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 106702 times.
|
210166 |
assign(newstr, strlen(newstr)); |
73 |
|
210166 |
} |
74 |
|
|
|
75 |
|
289092 |
void assign(const string &newstr) |
76 |
|
|
{ |
77 |
|
289092 |
assign(newstr.data(), newstr.length()); |
78 |
|
289092 |
} |
79 |
|
|
|
80 |
|
900214 |
void assign(const char * newstr, int end) |
81 |
|
|
{ |
82 |
|
900214 |
resize(end); |
83 |
|
900214 |
copy(newstr, end, data_ptr); |
84 |
|
900214 |
} |
85 |
|
|
|
86 |
|
|
|
87 |
|
12401 |
string& operator=(const char * newstr) |
88 |
|
|
{ |
89 |
|
12401 |
assign(newstr); |
90 |
|
12401 |
return *this; |
91 |
|
|
} |
92 |
|
|
|
93 |
|
289092 |
string& operator=(const string &newstr) |
94 |
|
|
{ |
95 |
|
289092 |
assign(newstr); |
96 |
|
289092 |
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 |
|
3564 |
string& append(const char *other, int start, int end) |
108 |
|
|
{ |
109 |
|
3564 |
int current_end = length(); |
110 |
|
3564 |
resize(length() + end - start); |
111 |
|
3564 |
copy(other + start, end - start, data_ptr + current_end); |
112 |
|
3564 |
return *this; |
113 |
|
|
} |
114 |
|
|
|
115 |
|
64566 |
string& operator+=(const string& other) |
116 |
|
|
{ |
117 |
|
64566 |
int current_end = length(); |
118 |
|
64566 |
resize(length() + other.length()); |
119 |
|
64566 |
copy(other.data(), other.length(), data_ptr + current_end); |
120 |
|
64566 |
return *this; |
121 |
|
|
} |
122 |
|
|
|
123 |
|
115661 |
string& operator+=(const char *other) |
124 |
|
|
{ |
125 |
|
115661 |
int current_end = length(); |
126 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58192 times.
|
115661 |
int otherlen=(int)strlen(other); |
127 |
|
115661 |
resize(length() + otherlen); |
128 |
|
115661 |
copy(other, otherlen, data_ptr + current_end); |
129 |
|
115661 |
return *this; |
130 |
|
|
} |
131 |
|
|
|
132 |
|
858259 |
string& operator+=(char c) |
133 |
|
|
{ |
134 |
|
858259 |
resize(length() + 1); |
135 |
|
858259 |
data_ptr[length() - 1] = c; |
136 |
|
858259 |
return *this; |
137 |
|
|
} |
138 |
|
|
|
139 |
|
|
string operator+(char right) const |
140 |
|
|
{ |
141 |
|
|
string ret=*this; |
142 |
|
|
ret+=right; |
143 |
|
|
return ret; |
144 |
|
|
} |
145 |
|
|
|
146 |
|
45243 |
string operator+(const char * right) const |
147 |
|
|
{ |
148 |
|
45243 |
string ret=*this; |
149 |
1/2
✓ Branch 0 taken 45243 times.
✗ Branch 1 not taken.
|
45243 |
ret+=right; |
150 |
|
45243 |
return ret; |
151 |
|
✗ |
} |
152 |
|
|
|
153 |
|
2852820 |
operator const char*() const |
154 |
|
|
{ |
155 |
|
2852820 |
return data(); |
156 |
|
|
} |
157 |
|
|
|
158 |
|
10226 |
explicit operator bool() const |
159 |
|
|
{ |
160 |
|
10226 |
return length(); |
161 |
|
|
} |
162 |
|
|
|
163 |
|
1118881 |
string() |
164 |
|
1118881 |
{ |
165 |
|
1118881 |
data_ptr = inlined.data; |
166 |
|
1118881 |
len = 0; |
167 |
|
1118881 |
inlined.data[0] = '\0'; |
168 |
|
1118881 |
} |
169 |
|
190619 |
string(const char * newstr) : string() |
170 |
|
|
{ |
171 |
2/3
✓ Branch 0 taken 93810 times.
✓ Branch 1 taken 96809 times.
✗ Branch 2 not taken.
|
190619 |
assign(newstr); |
172 |
|
190619 |
} |
173 |
|
84361 |
string(const char * newstr, int newlen) : string() |
174 |
|
|
{ |
175 |
2/3
✓ Branch 0 taken 41986 times.
✓ Branch 1 taken 42375 times.
✗ Branch 2 not taken.
|
84361 |
assign(newstr, newlen); |
176 |
|
84361 |
} |
177 |
|
270330 |
string(const string& old) : string() |
178 |
|
|
{ |
179 |
2/4
✓ Branch 0 taken 134206 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 136124 times.
✗ Branch 3 not taken.
|
270330 |
assign(old.data(), old.length()); |
180 |
|
270330 |
} |
181 |
|
|
|
182 |
|
26205 |
string(string &&move) noexcept : string() |
183 |
|
|
{ |
184 |
|
26205 |
*this = move; |
185 |
|
26205 |
} |
186 |
|
|
|
187 |
|
112936 |
string& operator=(string&& other) noexcept |
188 |
|
|
{ |
189 |
3/3
✓ Branch 0 taken 56221 times.
✓ Branch 1 taken 56675 times.
✓ Branch 2 taken 40 times.
|
112936 |
if (other.is_inlined()) { |
190 |
|
|
// No resources to steal so just do a normal assignment |
191 |
|
112858 |
*this = other; |
192 |
|
|
} else { |
193 |
3/3
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 40 times.
✓ Branch 2 taken 21 times.
|
78 |
if (is_inlined()) { |
194 |
|
36 |
data_ptr = other.data_ptr; |
195 |
|
36 |
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 |
|
78 |
len = other.len; |
201 |
|
78 |
allocated = other.allocated; |
202 |
|
|
} |
203 |
|
112936 |
return *this; |
204 |
|
|
} |
205 |
|
|
|
206 |
|
1069456 |
~string() |
207 |
|
|
{ |
208 |
3/3
✓ Branch 0 taken 1199 times.
✓ Branch 1 taken 529938 times.
✓ Branch 2 taken 538319 times.
|
1069456 |
if(!is_inlined()){ |
209 |
|
2576 |
free(data_ptr); |
210 |
|
|
} |
211 |
|
1069456 |
} |
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 |
|
1943072 |
unsigned capacity() const |
266 |
|
|
{ |
267 |
3/3
✓ Branch 0 taken 972636 times.
✓ Branch 1 taken 969576 times.
✓ Branch 2 taken 860 times.
|
1943072 |
return is_inlined() ? inline_capacity : allocated.capacity; |
268 |
|
|
} |
269 |
|
|
|
270 |
|
3128266 |
bool is_inlined() const |
271 |
|
|
{ |
272 |
|
3128266 |
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 3997 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 30965 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 26968 times.
|
61360 |
ASAR_STRCMP_OPERATORS(==) |
289 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5454 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5454 times.
|
10874 |
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 |
|
64964 |
size_t operator()(const ::string& s) const { |
299 |
|
64964 |
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 |
|
1026 |
inline const char* strqpchr(const char* str, char key) { return strqpchr(const_cast<char*>(str), key); }; |
315 |
|
114 |
inline const char* strqpstr(const char* str, const char* key) { return strqpstr(const_cast<char*>(str), key); }; |
316 |
|
|
|
317 |
|
✗ |
inline string hex(unsigned int value) |
318 |
|
|
{ |
319 |
|
✗ |
char buffer[64]; |
320 |
|
|
if(0); |
321 |
|
✗ |
else if (value<=0x000000FF) snprintf(buffer, sizeof(buffer), "%.2X", value); |
322 |
|
✗ |
else if (value<=0x0000FFFF) snprintf(buffer, sizeof(buffer), "%.4X", value); |
323 |
|
✗ |
else if (value<=0x00FFFFFF) snprintf(buffer, sizeof(buffer), "%.6X", value); |
324 |
|
✗ |
else snprintf(buffer, sizeof(buffer), "%.8X", value); |
325 |
|
✗ |
return buffer; |
326 |
|
|
} |
327 |
|
|
|
328 |
|
2 |
inline string hex(unsigned int value, int width) |
329 |
|
|
{ |
330 |
|
1 |
char buffer[64]; |
331 |
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
2 |
snprintf(buffer, sizeof(buffer), "%.*X", width, value); |
332 |
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
4 |
return buffer; |
333 |
|
|
} |
334 |
|
|
|
335 |
|
3302 |
inline string dec(int64_t value) |
336 |
|
|
{ |
337 |
|
1706 |
char buffer[64]; |
338 |
2/2
✓ Branch 0 taken 1596 times.
✓ Branch 1 taken 1706 times.
|
3302 |
snprintf(buffer, sizeof(buffer), "%" PRId64, value); |
339 |
1/2
✓ Branch 0 taken 3302 times.
✗ Branch 1 not taken.
|
6604 |
return buffer; |
340 |
|
|
} |
341 |
|
|
|
342 |
|
|
// todo this function sucks, replace with std::to_chars |
343 |
|
258 |
inline string ftostr(double value) |
344 |
|
|
{ |
345 |
|
|
// randomdude999: With 100 digits of precision, the buffer needs to be approx. 311+100, |
346 |
|
|
// but let's be safe here https://stackoverflow.com/questions/7235456 |
347 |
|
129 |
char rval[512]; |
348 |
|
|
// RPG Hacker: Ridiculously high precision, I know, but we're working with doubles |
349 |
|
|
// here and can afford it, so no need to waste any precision |
350 |
1/2
✓ Branch 0 taken 129 times.
✗ Branch 1 not taken.
|
258 |
snprintf(rval, sizeof(rval), "%.100f", value); |
351 |
1/2
✓ Branch 0 taken 258 times.
✗ Branch 1 not taken.
|
258 |
if (strchr(rval, '.'))//nuke useless zeroes |
352 |
|
|
{ |
353 |
|
258 |
char * end=strrchr(rval, '\0')-1; |
354 |
3/3
✓ Branch 0 taken 12726 times.
✓ Branch 1 taken 12855 times.
✓ Branch 2 taken 129 times.
|
25710 |
while (*end=='0') |
355 |
|
|
{ |
356 |
|
25452 |
*end='\0'; |
357 |
|
25452 |
end--; |
358 |
|
|
} |
359 |
3/3
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 129 times.
✓ Branch 2 taken 3 times.
|
258 |
if (*end=='.') *end='\0'; |
360 |
|
|
} |
361 |
1/2
✓ Branch 0 taken 258 times.
✗ Branch 1 not taken.
|
516 |
return rval; |
362 |
|
|
} |
363 |
|
|
|
364 |
|
|
// Same as above, but with variable precision |
365 |
|
24 |
inline string ftostrvar(double value, int precision) |
366 |
|
|
{ |
367 |
|
24 |
int clampedprecision = precision; |
368 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
|
24 |
if (clampedprecision < 0) clampedprecision = 0; |
369 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
|
24 |
if (clampedprecision > 100) clampedprecision = 100; |
370 |
|
|
|
371 |
|
|
// see above |
372 |
|
12 |
char rval[512]; |
373 |
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
|
24 |
snprintf(rval, sizeof(rval), "%.*f", clampedprecision, (double)value); |
374 |
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 2 times.
|
24 |
if (strchr(rval, '.'))//nuke useless zeroes |
375 |
|
|
{ |
376 |
|
22 |
char * end = strrchr(rval, '\0') - 1; |
377 |
3/3
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 34 times.
✓ Branch 2 taken 11 times.
|
68 |
while (*end == '0') |
378 |
|
|
{ |
379 |
|
46 |
*end = '\0'; |
380 |
|
46 |
end--; |
381 |
|
|
} |
382 |
3/3
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 8 times.
|
22 |
if (*end == '.') *end = '\0'; |
383 |
|
|
} |
384 |
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
|
48 |
return rval; |
385 |
|
|
} |
386 |
|
|
|
387 |
|
123170 |
inline bool stribegin(const char * str, const char * key) |
388 |
|
|
{ |
389 |
4/4
✓ Branch 0 taken 206175 times.
✓ Branch 1 taken 7397 times.
✓ Branch 2 taken 172690 times.
✓ Branch 3 taken 2435 times.
|
388697 |
for (int i=0;key[i];i++) |
390 |
|
|
{ |
391 |
4/4
✓ Branch 0 taken 53892 times.
✓ Branch 1 taken 152283 times.
✓ Branch 2 taken 59446 times.
✓ Branch 3 taken 113244 times.
|
378865 |
if (to_lower(str[i])!=to_lower(key[i])) return false; |
392 |
|
|
} |
393 |
|
9832 |
return true; |
394 |
|
|
} |
395 |
|
|
|
396 |
|
|
inline bool striend(const char * str, const char * key) |
397 |
|
|
{ |
398 |
|
|
const char * keyend=strrchr(key, '\0'); |
399 |
|
|
const char * strend=strrchr(str, '\0'); |
400 |
|
|
if(keyend-key > strend-str) return false; |
401 |
|
|
|
402 |
|
|
while (key!=keyend) |
403 |
|
|
{ |
404 |
|
|
keyend--; |
405 |
|
|
strend--; |
406 |
|
|
if (to_lower(*strend)!=to_lower(*keyend)) return false; |
407 |
|
|
} |
408 |
|
|
return true; |
409 |
|
|
} |
410 |
|
|
|
411 |
|
|
inline bool stricmpwithupper(const char *word1, const char *word2) |
412 |
|
|
{ |
413 |
|
|
while(*word2) |
414 |
|
|
{ |
415 |
|
|
if(to_upper(*word1++) != *word2++) return true; |
416 |
|
|
} |
417 |
|
|
return *word1; |
418 |
|
|
} |
419 |
|
|
|
420 |
|
27484 |
inline bool stricmpwithlower(const char *word1, const char *word2) |
421 |
|
|
{ |
422 |
3/3
✓ Branch 0 taken 15941 times.
✓ Branch 1 taken 16538 times.
✓ Branch 2 taken 261 times.
|
32740 |
while(*word2) |
423 |
|
|
{ |
424 |
4/4
✓ Branch 0 taken 13335 times.
✓ Branch 1 taken 2606 times.
✓ Branch 2 taken 13629 times.
✓ Branch 3 taken 2650 times.
|
32220 |
if(to_lower(*word1++) != *word2++) return true; |
425 |
|
|
} |
426 |
|
520 |
return *word1; |
427 |
|
|
} |
428 |
|
|
|
429 |
|
|
//function: return the string without quotes around it, if any exists |
430 |
|
|
//if they don't exist, return it unaltered |
431 |
|
|
//it is not guaranteed to return str |
432 |
|
|
//it is not guaranteed to not edit str |
433 |
|
|
//the input must be freed even though it's garbage, the output must not |
434 |
|
11539 |
inline const char * dequote(char * str) |
435 |
|
|
{ |
436 |
3/3
✓ Branch 0 taken 372 times.
✓ Branch 1 taken 5786 times.
✓ Branch 2 taken 5381 times.
|
11539 |
if (*str!='"') return str; |
437 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5381 times.
|
10759 |
char *end = strrchr(str, '"'); |
438 |
1/2
✓ Branch 0 taken 10759 times.
✗ Branch 1 not taken.
|
10759 |
if (end) |
439 |
|
|
{ |
440 |
|
|
// make sure the closing quote is at the end of the argument |
441 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5378 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5381 times.
|
10759 |
if(end[1] != 0) return nullptr; |
442 |
|
10759 |
*end = 0; |
443 |
|
10759 |
char *quote = str+1; |
444 |
4/4
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 10831 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 5381 times.
|
10903 |
while((quote = strstr(quote, "\"\""))) { |
445 |
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)); |
446 |
|
144 |
quote++; |
447 |
|
|
} |
448 |
|
10759 |
return str + 1; |
449 |
|
|
} |
450 |
|
✗ |
return nullptr; |
451 |
|
|
} |
452 |
|
|
|
453 |
|
57737 |
inline char * strqchr(char * str, char key) |
454 |
|
|
{ |
455 |
3/3
✓ Branch 0 taken 186358 times.
✓ Branch 1 taken 198825 times.
✓ Branch 2 taken 9834 times.
|
395017 |
while (*str != '\0') |
456 |
|
|
{ |
457 |
3/3
✓ Branch 0 taken 18994 times.
✓ Branch 1 taken 186604 times.
✓ Branch 2 taken 169918 times.
|
375516 |
if (*str == key) { return str; } |
458 |
6/6
✓ Branch 0 taken 166881 times.
✓ Branch 1 taken 169909 times.
✓ Branch 2 taken 798 times.
✓ Branch 3 taken 166575 times.
✓ Branch 4 taken 306 times.
✓ Branch 5 taken 169120 times.
|
337282 |
else if (*str == '"' || *str == '\'') |
459 |
|
|
{ |
460 |
|
|
// Special case hack for ''', which is currently our official way of handling the ' character. |
461 |
|
|
// Even though it really stinks. |
462 |
8/9
✓ Branch 0 taken 306 times.
✓ Branch 1 taken 789 times.
✓ Branch 2 taken 507 times.
✓ Branch 3 taken 291 times.
✓ Branch 4 taken 15 times.
✓ Branch 5 taken 15 times.
✓ Branch 6 taken 291 times.
✓ Branch 7 taken 15 times.
✗ Branch 8 not taken.
|
1587 |
if (str[0] == '\'' && str[1] == '\'' && str[2] == '\'') { str += 2; } |
463 |
|
|
else |
464 |
|
|
{ |
465 |
|
1557 |
char delimiter = *str; |
466 |
|
|
|
467 |
|
|
do |
468 |
|
|
{ |
469 |
|
11213 |
str++; |
470 |
|
|
|
471 |
|
|
// If we want to support backslash escapes, we'll have to add that right here. |
472 |
6/6
✓ Branch 0 taken 4791 times.
✓ Branch 1 taken 5640 times.
✓ Branch 2 taken 5572 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 4866 times.
✓ Branch 5 taken 1 times.
|
11213 |
} while (*str != delimiter && *str != '\0'); |
473 |
|
|
|
474 |
|
|
// This feels like a superfluous check, but I can't really find a clean way to avoid it. |
475 |
3/3
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 774 times.
✓ Branch 2 taken 782 times.
|
1557 |
if (*str == '\0') { return nullptr; } |
476 |
|
|
} |
477 |
|
|
} |
478 |
|
|
|
479 |
|
337280 |
str++; |
480 |
|
|
} |
481 |
|
|
|
482 |
|
19501 |
return nullptr; |
483 |
|
|
} |
484 |
|
|
|
485 |
|
41168 |
inline const char * strqchr(const char * str, char key) { |
486 |
|
41168 |
return strqchr(const_cast<char*>(str), key); |
487 |
|
|
} |
488 |
|
|
|
489 |
|
2580 |
inline string substr(const char * str, int len) |
490 |
|
|
{ |
491 |
|
2580 |
return string(str, len); |
492 |
|
|
} |
493 |
|
|
|
494 |
|
|
|
495 |
|
72382 |
inline char *strip_whitespace(char *str) |
496 |
|
|
{ |
497 |
4/4
✓ Branch 0 taken 1532 times.
✓ Branch 1 taken 35943 times.
✓ Branch 2 taken 1971 times.
✓ Branch 3 taken 36439 times.
|
75885 |
while(is_space(*str)) str++; |
498 |
4/4
✓ Branch 0 taken 32041 times.
✓ Branch 1 taken 47909 times.
✓ Branch 2 taken 32461 times.
✓ Branch 3 taken 11554 times.
|
87526 |
for(int i = strlen(str) - 1; i >= 0; i--) |
499 |
|
|
{ |
500 |
4/4
✓ Branch 0 taken 24473 times.
✓ Branch 1 taken 7568 times.
✓ Branch 2 taken 24885 times.
✓ Branch 3 taken 7576 times.
|
64502 |
if(!is_space(str[i])) |
501 |
|
|
{ |
502 |
|
49358 |
str[i + 1] = 0; |
503 |
|
49358 |
return str; |
504 |
|
|
} |
505 |
|
|
} |
506 |
|
23024 |
return str; |
507 |
|
|
} |
508 |
|
267 |
inline void strip_whitespace(string &str) |
509 |
|
|
{ |
510 |
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())); |
511 |
|
267 |
} |
512 |
|
|
|
513 |
|
41108 |
inline void grab_until_space(string& to, const char*& from) { |
514 |
|
|
// i tried to use strchr here as an optimization, but it wasn't even faster.... |
515 |
|
41108 |
const char* params = strqchr(from, ' '); |
516 |
2/2
✓ Branch 0 taken 33962 times.
✓ Branch 1 taken 7146 times.
|
41108 |
if(params) { |
517 |
|
33962 |
to.assign(from, params - from); |
518 |
|
33962 |
from = params+1; |
519 |
|
|
} else { |
520 |
|
7146 |
to.assign(from); |
521 |
|
7146 |
from += to.length(); // now from points at a null byte |
522 |
|
|
} |
523 |
|
41108 |
} |
524 |
|
|
|
525 |
|
|
string &itrim(string &str, const char * left, const char * right); |
526 |
|
|
|
527 |
|
109713 |
inline string &lower(string &old) |
528 |
|
|
{ |
529 |
|
109713 |
int length = old.length(); |
530 |
4/4
✓ Branch 0 taken 561236 times.
✓ Branch 1 taken 60058 times.
✓ Branch 2 taken 246912 times.
✓ Branch 3 taken 49655 times.
|
917861 |
for (int i=0;i<length;i++) old.raw()[i]=(char)to_lower(old.data()[i]); |
531 |
|
109713 |
return old; |
532 |
|
|
} |
533 |
|
|
|
534 |
|
|
|
535 |
|
|
// Returns number of connected lines - 1 |
536 |
|
|
template<typename stringarraytype> |
537 |
|
53349 |
inline int getconnectedlines(stringarraytype& lines, int startline, string& out) |
538 |
|
|
{ |
539 |
|
53349 |
int count = 0; |
540 |
|
|
|
541 |
2/4
✓ Branch 0 taken 26532 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26835 times.
✗ Branch 3 not taken.
|
53367 |
for (int i = startline; lines[i]; i++) |
542 |
|
|
{ |
543 |
|
|
// The line should already be stripped of any comments at this point |
544 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26835 times.
|
53367 |
int linestartpos = (int)strlen(lines[i]); |
545 |
|
|
|
546 |
6/6
✓ Branch 0 taken 38371 times.
✓ Branch 1 taken 14996 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 19049 times.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 19304 times.
|
53367 |
if(linestartpos && lines[i][linestartpos - 1] == '\\') |
547 |
|
|
{ |
548 |
|
18 |
count++; |
549 |
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); |
550 |
|
18 |
continue; |
551 |
|
|
} |
552 |
|
|
else |
553 |
|
|
{ |
554 |
4/7
✓ Branch 0 taken 26523 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26523 times.
✓ Branch 3 taken 26826 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 26826 times.
✗ Branch 6 not taken.
|
53349 |
out += string(lines[i], linestartpos); |
555 |
|
53349 |
return count; |
556 |
|
|
} |
557 |
|
|
} |
558 |
|
|
|
559 |
|
✗ |
return count; |
560 |
|
|
} |
561 |
|
|
|