Line |
Branch |
Exec |
Source |
1 |
|
|
#pragma once |
2 |
|
|
|
3 |
|
|
#include "std-includes.h" |
4 |
|
|
#include "libmisc.h" |
5 |
|
|
#include <cstdint> |
6 |
|
|
#include <cstring> |
7 |
|
|
#include <utility> |
8 |
|
|
#include <string_view> |
9 |
|
|
|
10 |
|
|
//ty alcaro |
11 |
|
|
extern const unsigned char char_props[256]; |
12 |
|
1655422 |
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 |
|
243666 |
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 |
|
49610 |
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 |
|
14553 |
inline bool is_ualpha(unsigned char c) { return char_props[c] & 0x28; } |
23 |
|
124735 |
inline bool is_ualnum(unsigned char c) { return char_props[c] & 0x68; } |
24 |
|
7981 |
inline bool is_xdigit(unsigned char c) { return char_props[c] & 0x01; } |
25 |
|
|
|
26 |
|
1294925 |
inline char *copy(const char *source, int copy_length, char *dest) |
27 |
|
|
{ |
28 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 597756 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 597756 times.
|
1294925 |
memcpy(dest, source, copy_length*sizeof(char)); |
29 |
|
1294925 |
return dest; |
30 |
|
|
} |
31 |
|
|
|
32 |
|
|
class string { |
33 |
|
|
public: |
34 |
|
3019537 |
const char *data() const |
35 |
|
|
{ |
36 |
|
3019537 |
return data_ptr; |
37 |
|
|
} |
38 |
|
|
|
39 |
|
120860 |
char *temp_raw() const //things to cleanup and take a look at |
40 |
|
|
{ |
41 |
|
120860 |
return data_ptr; |
42 |
|
|
} |
43 |
|
|
|
44 |
|
442732 |
char *raw() const |
45 |
|
|
{ |
46 |
|
442732 |
return data_ptr; |
47 |
|
|
} |
48 |
|
|
|
49 |
|
3214121 |
int length() const |
50 |
|
|
{ |
51 |
|
3214121 |
return len; |
52 |
|
|
} |
53 |
|
|
|
54 |
|
1882059 |
void resize(unsigned int new_length) |
55 |
|
|
{ |
56 |
2/2
✓ Branch 0 taken 4559 times.
✓ Branch 1 taken 1877500 times.
|
1882059 |
if (new_length > capacity()) { |
57 |
|
4559 |
reallocate_capacity(new_length); |
58 |
|
|
} |
59 |
|
|
|
60 |
|
1882059 |
len = new_length; |
61 |
|
1882059 |
data_ptr[new_length] = 0; //always ensure null terminator |
62 |
|
1882059 |
} |
63 |
|
|
|
64 |
|
792 |
void truncate(int newlen) |
65 |
|
|
{ |
66 |
|
792 |
resize(newlen); |
67 |
|
792 |
} |
68 |
|
|
|
69 |
|
662849 |
void assign(const char * newstr) |
70 |
|
|
{ |
71 |
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 662846 times.
|
662849 |
if (!newstr) newstr = ""; |
72 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 313077 times.
|
662849 |
assign(newstr, strlen(newstr)); |
73 |
|
662849 |
} |
74 |
|
|
|
75 |
|
356630 |
void assign(const string &newstr) |
76 |
|
|
{ |
77 |
|
356630 |
assign(newstr.data(), newstr.length()); |
78 |
|
356630 |
} |
79 |
|
|
|
80 |
|
1098910 |
void assign(const char * newstr, int end) |
81 |
|
|
{ |
82 |
|
1098910 |
resize(end); |
83 |
|
1098910 |
copy(newstr, end, data_ptr); |
84 |
|
1098910 |
} |
85 |
|
|
|
86 |
|
|
|
87 |
|
237451 |
string& operator=(const char * newstr) |
88 |
|
|
{ |
89 |
|
237451 |
assign(newstr); |
90 |
|
237451 |
return *this; |
91 |
|
|
} |
92 |
|
|
|
93 |
|
356630 |
string& operator=(const string &newstr) |
94 |
|
|
{ |
95 |
|
356630 |
assign(newstr); |
96 |
|
356630 |
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 |
|
3384 |
string& append(const char *other, int start, int end) |
108 |
|
|
{ |
109 |
|
3384 |
int current_end = length(); |
110 |
|
3384 |
resize(length() + end - start); |
111 |
|
3384 |
copy(other + start, end - start, data_ptr + current_end); |
112 |
|
3384 |
return *this; |
113 |
|
|
} |
114 |
|
|
|
115 |
|
52401 |
string& operator+=(const string& other) |
116 |
|
|
{ |
117 |
|
52401 |
int current_end = length(); |
118 |
|
52401 |
resize(length() + other.length()); |
119 |
|
52401 |
copy(other.data(), other.length(), data_ptr + current_end); |
120 |
|
52401 |
return *this; |
121 |
|
|
} |
122 |
|
|
|
123 |
|
135851 |
string& operator+=(const char *other) |
124 |
|
|
{ |
125 |
|
135851 |
int current_end = length(); |
126 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62643 times.
|
135851 |
int otherlen=(int)strlen(other); |
127 |
|
135851 |
resize(length() + otherlen); |
128 |
|
135851 |
copy(other, otherlen, data_ptr + current_end); |
129 |
|
135851 |
return *this; |
130 |
|
|
} |
131 |
|
|
|
132 |
|
590717 |
string& operator+=(char c) |
133 |
|
|
{ |
134 |
|
590717 |
resize(length() + 1); |
135 |
|
590717 |
data_ptr[length() - 1] = c; |
136 |
|
590717 |
return *this; |
137 |
|
|
} |
138 |
|
|
|
139 |
|
|
string operator+(char right) const |
140 |
|
|
{ |
141 |
|
|
string ret=*this; |
142 |
|
|
ret+=right; |
143 |
|
|
return ret; |
144 |
|
|
} |
145 |
|
|
|
146 |
|
24725 |
string operator+(const char * right) const |
147 |
|
|
{ |
148 |
|
24725 |
string ret=*this; |
149 |
1/2
✓ Branch 0 taken 24725 times.
✗ Branch 1 not taken.
|
24725 |
ret+=right; |
150 |
|
24725 |
return ret; |
151 |
|
✗ |
} |
152 |
|
|
|
153 |
|
2108626 |
operator const char*() const |
154 |
|
|
{ |
155 |
|
2108626 |
return data(); |
156 |
|
|
} |
157 |
|
|
|
158 |
|
10658 |
explicit operator bool() const |
159 |
|
|
{ |
160 |
|
10658 |
return length(); |
161 |
|
|
} |
162 |
|
|
|
163 |
|
1387694 |
string() |
164 |
|
1387694 |
{ |
165 |
|
1387694 |
data_ptr = inlined.data; |
166 |
|
1387694 |
len = 0; |
167 |
|
1387694 |
inlined.data[0] = '\0'; |
168 |
|
1387694 |
} |
169 |
|
330966 |
string(const char * newstr) : string() |
170 |
|
|
{ |
171 |
1/2
✓ Branch 0 taken 330966 times.
✗ Branch 1 not taken.
|
330966 |
assign(newstr); |
172 |
|
330966 |
} |
173 |
|
67212 |
string(const char * newstr, int newlen) : string() |
174 |
|
|
{ |
175 |
1/2
✓ Branch 0 taken 67212 times.
✗ Branch 1 not taken.
|
67212 |
assign(newstr, newlen); |
176 |
|
67212 |
} |
177 |
|
94432 |
string(const string& old) : string() |
178 |
|
|
{ |
179 |
1/2
✓ Branch 0 taken 94432 times.
✗ Branch 1 not taken.
|
94432 |
assign(old.data()); |
180 |
|
94432 |
} |
181 |
|
|
|
182 |
|
14177 |
string(string &&move) noexcept : string() |
183 |
|
|
{ |
184 |
|
14177 |
*this = move; |
185 |
|
14177 |
} |
186 |
|
|
|
187 |
|
71508 |
string& operator=(string&& other) noexcept |
188 |
|
|
{ |
189 |
2/2
✓ Branch 0 taken 71470 times.
✓ Branch 1 taken 38 times.
|
71508 |
if (other.is_inlined()) { |
190 |
|
|
// No resources to steal so just do a normal assignment |
191 |
|
71470 |
*this = other; |
192 |
|
|
} else { |
193 |
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
|
38 |
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 |
|
✗ |
std::swap(data_ptr, other.data_ptr); |
199 |
|
|
} |
200 |
|
38 |
len = other.len; |
201 |
|
38 |
allocated = other.allocated; |
202 |
|
|
} |
203 |
|
71508 |
return *this; |
204 |
|
|
} |
205 |
|
|
|
206 |
|
1344597 |
~string() |
207 |
|
|
{ |
208 |
2/2
✓ Branch 0 taken 4417 times.
✓ Branch 1 taken 1340180 times.
|
1344597 |
if(!is_inlined()){ |
209 |
|
4417 |
free(data_ptr); |
210 |
|
|
} |
211 |
|
1344597 |
} |
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/2
✓ Branch 0 taken 4 times.
✓ Branch 1 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 |
|
|
#ifdef SERIALIZER |
247 |
|
|
void serialize(serializer & s) |
248 |
|
|
{ |
249 |
|
|
s(str, allocated.bufferlen); |
250 |
|
|
resize(strlen(str)); |
251 |
|
|
} |
252 |
|
|
#endif |
253 |
|
|
#define SERIALIZER_BANNED |
254 |
|
|
|
255 |
|
|
private: |
256 |
|
|
static const int scale_factor = 4; //scale sso |
257 |
|
|
static const int inline_capacity = ((sizeof(char *) + sizeof(int) * 2) * scale_factor) - 2; |
258 |
|
|
|
259 |
|
|
// Points to a malloc'd data block or to inlined.data |
260 |
|
|
char *data_ptr; |
261 |
|
|
unsigned int len; |
262 |
|
|
union { |
263 |
|
|
struct { |
264 |
|
|
// Actual allocated capacity is +1 this value, to cover for the terminating NUL |
265 |
|
|
unsigned int capacity; |
266 |
|
|
} allocated; |
267 |
|
|
struct { |
268 |
|
|
char data[inline_capacity + 1]; |
269 |
|
|
} inlined; |
270 |
|
|
}; |
271 |
|
|
|
272 |
|
|
void reallocate_capacity(unsigned int new_length); |
273 |
|
|
|
274 |
|
1882059 |
unsigned capacity() const |
275 |
|
|
{ |
276 |
2/2
✓ Branch 0 taken 1880477 times.
✓ Branch 1 taken 1582 times.
|
1882059 |
return is_inlined() ? inline_capacity : allocated.capacity; |
277 |
|
|
} |
278 |
|
|
|
279 |
|
3302761 |
bool is_inlined() const |
280 |
|
|
{ |
281 |
|
3302761 |
return data_ptr == inlined.data; |
282 |
|
|
} |
283 |
|
|
}; |
284 |
|
|
#define STR (string) |
285 |
|
|
|
286 |
|
|
#define ASAR_STRCMP_OPERATORS(op) \ |
287 |
|
|
inline bool operator op(const string& left, const string& right) { \ |
288 |
|
|
return strcmp(left, right) op 0; \ |
289 |
|
|
} \ |
290 |
|
|
inline bool operator op(const string& left, const char* right) { \ |
291 |
|
|
return strcmp(left, right) op 0; \ |
292 |
|
|
} \ |
293 |
|
|
inline bool operator op(const char* left, const string& right) { \ |
294 |
|
|
return strcmp(left, right) op 0; \ |
295 |
|
|
} |
296 |
|
|
|
297 |
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 3642 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 24587 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 20945 times.
|
58821 |
ASAR_STRCMP_OPERATORS(==) |
298 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2026 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2026 times.
|
5692 |
ASAR_STRCMP_OPERATORS(!=) |
299 |
|
|
ASAR_STRCMP_OPERATORS(<) |
300 |
|
|
ASAR_STRCMP_OPERATORS(<=) |
301 |
|
|
ASAR_STRCMP_OPERATORS(>) |
302 |
|
|
ASAR_STRCMP_OPERATORS(>=) |
303 |
|
|
#undef ASAR_STRCMP_OPERATORS |
304 |
|
|
|
305 |
|
|
template<> |
306 |
|
|
struct std::hash<string> { |
307 |
|
71871 |
size_t operator()(const ::string& s) const { |
308 |
|
71871 |
return std::hash<std::string_view>()(std::string_view(s.data(), s.length())); |
309 |
|
|
} |
310 |
|
|
}; |
311 |
|
|
|
312 |
|
|
char * readfile(const char * fname, const char * basepath); |
313 |
|
|
char * readfilenative(const char * fname); |
314 |
|
|
bool readfile(const char * fname, const char * basepath, char ** data, int * len);//if you want an uchar*, cast it |
315 |
|
|
char ** split(char * str, char key, int * len= nullptr); |
316 |
|
|
char ** qsplit(char * str, char key, int * len= nullptr); |
317 |
|
|
char ** qpsplit(char * str, char key, int * len= nullptr); |
318 |
|
|
char ** qsplitstr(char * str, const char * key, int * len= nullptr); |
319 |
|
|
bool confirmquotes(const char * str); |
320 |
|
|
bool confirmqpar(const char * str); |
321 |
|
|
char* strqpchr(char* str, char key); |
322 |
|
|
char* strqpstr(char* str, const char* key); |
323 |
|
|
|
324 |
|
✗ |
inline string hex(unsigned int value) |
325 |
|
|
{ |
326 |
|
✗ |
char buffer[64]; |
327 |
|
|
if(0); |
328 |
|
✗ |
else if (value<=0x000000FF) snprintf(buffer, sizeof(buffer), "%.2X", value); |
329 |
|
✗ |
else if (value<=0x0000FFFF) snprintf(buffer, sizeof(buffer), "%.4X", value); |
330 |
|
✗ |
else if (value<=0x00FFFFFF) snprintf(buffer, sizeof(buffer), "%.6X", value); |
331 |
|
✗ |
else snprintf(buffer, sizeof(buffer), "%.8X", value); |
332 |
|
✗ |
return buffer; |
333 |
|
|
} |
334 |
|
|
|
335 |
|
2 |
inline string hex(unsigned int value, int width) |
336 |
|
|
{ |
337 |
|
1 |
char buffer[64]; |
338 |
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
2 |
snprintf(buffer, sizeof(buffer), "%.*X", width, value); |
339 |
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
4 |
return buffer; |
340 |
|
|
} |
341 |
|
|
|
342 |
|
1376 |
inline string dec(int value) |
343 |
|
|
{ |
344 |
|
745 |
char buffer[64]; |
345 |
2/2
✓ Branch 0 taken 631 times.
✓ Branch 1 taken 745 times.
|
1376 |
snprintf(buffer, sizeof(buffer), "%i", value); |
346 |
1/2
✓ Branch 0 taken 1376 times.
✗ Branch 1 not taken.
|
2752 |
return buffer; |
347 |
|
|
} |
348 |
|
|
|
349 |
|
2166 |
inline string ftostr(double value) |
350 |
|
|
{ |
351 |
|
|
// randomdude999: With 100 digits of precision, the buffer needs to be approx. 311+100, |
352 |
|
|
// but let's be safe here https://stackoverflow.com/questions/7235456 |
353 |
|
1083 |
char rval[512]; |
354 |
|
|
// RPG Hacker: Ridiculously high precision, I know, but we're working with doubles |
355 |
|
|
// here and can afford it, so no need to waste any precision |
356 |
1/2
✓ Branch 0 taken 1083 times.
✗ Branch 1 not taken.
|
2166 |
snprintf(rval, sizeof(rval), "%.100f", value); |
357 |
1/2
✓ Branch 0 taken 2166 times.
✗ Branch 1 not taken.
|
2166 |
if (strchr(rval, '.'))//nuke useless zeroes |
358 |
|
|
{ |
359 |
|
2166 |
char * end=strrchr(rval, '\0')-1; |
360 |
2/2
✓ Branch 0 taken 216252 times.
✓ Branch 1 taken 2166 times.
|
218418 |
while (*end=='0') |
361 |
|
|
{ |
362 |
|
216252 |
*end='\0'; |
363 |
|
216252 |
end--; |
364 |
|
|
} |
365 |
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 6 times.
|
2166 |
if (*end=='.') *end='\0'; |
366 |
|
|
} |
367 |
1/2
✓ Branch 0 taken 2166 times.
✗ Branch 1 not taken.
|
4332 |
return rval; |
368 |
|
|
} |
369 |
|
|
|
370 |
|
|
// Same as above, but with variable precision |
371 |
|
24 |
inline string ftostrvar(double value, int precision) |
372 |
|
|
{ |
373 |
|
24 |
int clampedprecision = precision; |
374 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
|
24 |
if (clampedprecision < 0) clampedprecision = 0; |
375 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
|
24 |
if (clampedprecision > 100) clampedprecision = 100; |
376 |
|
|
|
377 |
|
|
// see above |
378 |
|
12 |
char rval[512]; |
379 |
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
|
24 |
snprintf(rval, sizeof(rval), "%.*f", clampedprecision, (double)value); |
380 |
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 2 times.
|
24 |
if (strchr(rval, '.'))//nuke useless zeroes |
381 |
|
|
{ |
382 |
|
22 |
char * end = strrchr(rval, '\0') - 1; |
383 |
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 22 times.
|
68 |
while (*end == '0') |
384 |
|
|
{ |
385 |
|
46 |
*end = '\0'; |
386 |
|
46 |
end--; |
387 |
|
|
} |
388 |
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 16 times.
|
22 |
if (*end == '.') *end = '\0'; |
389 |
|
|
} |
390 |
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
|
48 |
return rval; |
391 |
|
|
} |
392 |
|
|
|
393 |
|
83349 |
inline bool stribegin(const char * str, const char * key) |
394 |
|
|
{ |
395 |
2/2
✓ Branch 0 taken 227306 times.
✓ Branch 1 taken 7016 times.
|
234322 |
for (int i=0;key[i];i++) |
396 |
|
|
{ |
397 |
2/2
✓ Branch 0 taken 76333 times.
✓ Branch 1 taken 150973 times.
|
227306 |
if (to_lower(str[i])!=to_lower(key[i])) return false; |
398 |
|
|
} |
399 |
|
7016 |
return true; |
400 |
|
|
} |
401 |
|
|
|
402 |
|
|
inline bool striend(const char * str, const char * key) |
403 |
|
|
{ |
404 |
|
|
const char * keyend=strrchr(key, '\0'); |
405 |
|
|
const char * strend=strrchr(str, '\0'); |
406 |
|
|
if(keyend-key > strend-str) return false; |
407 |
|
|
|
408 |
|
|
while (key!=keyend) |
409 |
|
|
{ |
410 |
|
|
keyend--; |
411 |
|
|
strend--; |
412 |
|
|
if (to_lower(*strend)!=to_lower(*keyend)) return false; |
413 |
|
|
} |
414 |
|
|
return true; |
415 |
|
|
} |
416 |
|
|
|
417 |
|
|
inline bool stricmpwithupper(const char *word1, const char *word2) |
418 |
|
|
{ |
419 |
|
|
while(*word2) |
420 |
|
|
{ |
421 |
|
|
if(to_upper(*word1++) != *word2++) return true; |
422 |
|
|
} |
423 |
|
|
return *word1; |
424 |
|
|
} |
425 |
|
|
|
426 |
|
622856 |
inline bool stricmpwithlower(const char *word1, const char *word2) |
427 |
|
|
{ |
428 |
2/2
✓ Branch 0 taken 841390 times.
✓ Branch 1 taken 35840 times.
|
877230 |
while(*word2) |
429 |
|
|
{ |
430 |
2/2
✓ Branch 0 taken 587016 times.
✓ Branch 1 taken 254374 times.
|
841390 |
if(to_lower(*word1++) != *word2++) return true; |
431 |
|
|
} |
432 |
|
35840 |
return *word1; |
433 |
|
|
} |
434 |
|
|
|
435 |
|
|
//function: return the string without quotes around it, if any exists |
436 |
|
|
//if they don't exist, return it unaltered |
437 |
|
|
//it is not guaranteed to return str |
438 |
|
|
//it is not guaranteed to not edit str |
439 |
|
|
//the input must be freed even though it's garbage, the output must not |
440 |
|
6515 |
inline const char * dequote(char * str) |
441 |
|
|
{ |
442 |
2/2
✓ Branch 0 taken 780 times.
✓ Branch 1 taken 5735 times.
|
6515 |
if (*str!='"') return str; |
443 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2035 times.
|
5735 |
char *end = strrchr(str, '"'); |
444 |
1/2
✓ Branch 0 taken 5735 times.
✗ Branch 1 not taken.
|
5735 |
if (end) |
445 |
|
|
{ |
446 |
|
5735 |
*end = 0; |
447 |
|
5735 |
char *quote = str+1; |
448 |
7/10
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 3772 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 72 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 72 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2107 times.
✓ Branch 8 taken 72 times.
✓ Branch 9 taken 2035 times.
|
5879 |
while((quote = strstr(quote, "\"\""))) memmove(quote, quote+1, strlen(quote)); |
449 |
|
5735 |
return str + 1; |
450 |
|
|
} |
451 |
|
✗ |
return nullptr; |
452 |
|
|
} |
453 |
|
|
|
454 |
|
15559 |
inline char * strqchr(const char * str, char key) |
455 |
|
|
{ |
456 |
2/2
✓ Branch 0 taken 138348 times.
✓ Branch 1 taken 11765 times.
|
150113 |
while (*str != '\0') |
457 |
|
|
{ |
458 |
2/2
✓ Branch 0 taken 3792 times.
✓ Branch 1 taken 134556 times.
|
138348 |
if (*str == key) { return const_cast<char*>(str); } |
459 |
4/4
✓ Branch 0 taken 133905 times.
✓ Branch 1 taken 651 times.
✓ Branch 2 taken 184 times.
✓ Branch 3 taken 133721 times.
|
134556 |
else if (*str == '"' || *str == '\'') |
460 |
|
|
{ |
461 |
|
|
// Special case hack for ''', which is currently our official way of handling the ' character. |
462 |
|
|
// Even though it really stinks. |
463 |
5/6
✓ Branch 0 taken 184 times.
✓ Branch 1 taken 651 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 172 times.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
|
835 |
if (str[0] == '\'' && str[1] == '\'' && str[2] == '\'') { str += 2; } |
464 |
|
|
else |
465 |
|
|
{ |
466 |
|
823 |
char delimiter = *str; |
467 |
|
|
|
468 |
|
|
do |
469 |
|
|
{ |
470 |
|
8947 |
str++; |
471 |
|
|
|
472 |
|
|
// If we want to support backslash escapes, we'll have to add that right here. |
473 |
4/4
✓ Branch 0 taken 8126 times.
✓ Branch 1 taken 821 times.
✓ Branch 2 taken 8124 times.
✓ Branch 3 taken 2 times.
|
8947 |
} while (*str != delimiter && *str != '\0'); |
474 |
|
|
|
475 |
|
|
// This feels like a superfluous check, but I can't really find a clean way to avoid it. |
476 |
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 821 times.
|
823 |
if (*str == '\0') { return nullptr; } |
477 |
|
|
} |
478 |
|
|
} |
479 |
|
|
|
480 |
|
134554 |
str++; |
481 |
|
|
} |
482 |
|
|
|
483 |
|
11765 |
return nullptr; |
484 |
|
|
} |
485 |
|
|
|
486 |
|
2580 |
inline string substr(const char * str, int len) |
487 |
|
|
{ |
488 |
|
2580 |
return string(str, len); |
489 |
|
|
} |
490 |
|
|
|
491 |
|
|
|
492 |
|
64902 |
inline char *strip_whitespace(char *str) |
493 |
|
|
{ |
494 |
2/2
✓ Branch 0 taken 3499 times.
✓ Branch 1 taken 64902 times.
|
68401 |
while(is_space(*str)) str++; |
495 |
4/4
✓ Branch 0 taken 30165 times.
✓ Branch 1 taken 42305 times.
✓ Branch 2 taken 28911 times.
✓ Branch 3 taken 10527 times.
|
80046 |
for(int i = strlen(str) - 1; i >= 0; i--) |
496 |
|
|
{ |
497 |
2/2
✓ Branch 0 taken 43932 times.
✓ Branch 1 taken 15144 times.
|
59076 |
if(!is_space(str[i])) |
498 |
|
|
{ |
499 |
|
43932 |
str[i + 1] = 0; |
500 |
|
43932 |
return str; |
501 |
|
|
} |
502 |
|
|
} |
503 |
|
20970 |
return str; |
504 |
|
|
} |
505 |
|
267 |
inline void strip_whitespace(string &str) |
506 |
|
|
{ |
507 |
1/2
✓ Branch 0 taken 267 times.
✗ Branch 1 not taken.
|
267 |
str = string(strip_whitespace(str.temp_raw())); |
508 |
|
267 |
} |
509 |
|
|
|
510 |
|
|
string &itrim(string &str, const char * left, const char * right); |
511 |
|
|
|
512 |
|
7743 |
inline string &lower(string &old) |
513 |
|
|
{ |
514 |
|
7743 |
int length = old.length(); |
515 |
2/2
✓ Branch 0 taken 223781 times.
✓ Branch 1 taken 7743 times.
|
231524 |
for (int i=0;i<length;i++) old.raw()[i]=(char)to_lower(old.data()[i]); |
516 |
|
7743 |
return old; |
517 |
|
|
} |
518 |
|
|
|
519 |
|
|
|
520 |
|
|
// Returns number of connected lines - 1 |
521 |
|
|
template<typename stringarraytype> |
522 |
|
46405 |
inline int getconnectedlines(stringarraytype& lines, int startline, string& out) |
523 |
|
|
{ |
524 |
|
46405 |
int count = 0; |
525 |
|
|
|
526 |
1/2
✓ Branch 0 taken 46423 times.
✗ Branch 1 not taken.
|
46423 |
for (int i = startline; lines[i]; i++) |
527 |
|
|
{ |
528 |
|
|
// The line should already be stripped of any comments at this point |
529 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22526 times.
|
46423 |
int linestartpos = (int)strlen(lines[i]); |
530 |
|
|
|
531 |
4/4
✓ Branch 0 taken 33017 times.
✓ Branch 1 taken 13406 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 32999 times.
|
46423 |
if(linestartpos && lines[i][linestartpos - 1] == '\\') |
532 |
|
|
{ |
533 |
|
18 |
count++; |
534 |
2/4
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
|
18 |
out += string(lines[i], linestartpos - 1); |
535 |
|
18 |
continue; |
536 |
|
|
} |
537 |
|
|
else |
538 |
|
|
{ |
539 |
2/4
✓ Branch 0 taken 46405 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 46405 times.
✗ Branch 3 not taken.
|
46405 |
out += string(lines[i], linestartpos); |
540 |
|
46405 |
return count; |
541 |
|
|
} |
542 |
|
|
} |
543 |
|
|
|
544 |
|
✗ |
return count; |
545 |
|
|
} |
546 |
|
|
|