asar coverage - build #


src/asar/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
240 of 255, 0 excluded
94.1%
Functions:
62 of 66, 0 excluded
93.9%
Branches:
179 of 312, 0 excluded
57.4%

libstr.h
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 1853595 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 222231 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 47646 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 16764 inline bool is_ualpha(unsigned char c) { return char_props[c] & 0x28; }
23 123999 inline bool is_ualnum(unsigned char c) { return char_props[c] & 0x68; }
24 7345 inline bool is_xdigit(unsigned char c) { return char_props[c] & 0x01; }
25
26 978048 inline char *copy(const char *source, int copy_length, char *dest)
27 {
28
2/4
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 487777 times.
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 487777 times.
978048 memcpy(dest, source, copy_length*sizeof(char));
29 978048 return dest;
30 }
31
32 class string {
33 public:
34 4662034 const char *data() const
35 {
36 4662034 return data_ptr;
37 }
38
39 71178 char *temp_raw() const //things to cleanup and take a look at
40 {
41 71178 return data_ptr;
42 }
43
44 875035 char *raw() const
45 {
46 875035 return data_ptr;
47 }
48
49 4569105 int length() const
50 {
51 4569105 return len;
52 }
53
54 1910751 void resize(unsigned int new_length)
55 {
56
4/4
✓ Branch 3 → 4 taken 1520 times.
✓ Branch 3 → 5 taken 956303 times.
✓ Branch 4 → 5 taken 2106 times.
✓ Branch 4 → 7 taken 950822 times.
1910751 if (new_length > capacity()) {
57 3626 reallocate_capacity(new_length);
58 }
59
60 1910751 len = new_length;
61 1910751 data_ptr[new_length] = 0; //always ensure null terminator
62 1910751 }
63
64 804 void truncate(int newlen)
65 {
66 804 resize(newlen);
67 804 }
68
69 251367 void assign(const char * newstr)
70 {
71
2/2
✓ Branch 2 → 3 taken 108 times.
✓ Branch 2 → 4 taken 251259 times.
251367 if (!newstr) newstr = "";
72
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 127336 times.
251367 assign(newstr, strlen(newstr));
73 251367 }
74
75 288706 void assign(const string &newstr)
76 {
77 288706 assign(newstr.data(), newstr.length());
78 288706 }
79
80 858739 void assign(const char * newstr, int end)
81 {
82 858739 resize(end);
83 858739 copy(newstr, end, data_ptr);
84 858739 }
85
86
87 12762 string& operator=(const char * newstr)
88 {
89 12762 assign(newstr);
90 12762 return *this;
91 }
92
93 288706 string& operator=(const string &newstr)
94 {
95 288706 assign(newstr);
96 288706 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 3752 string& append(const char *other, int start, int end)
108 {
109 3752 int current_end = length();
110 3752 resize(length() + end - start);
111 3752 copy(other + start, end - start, data_ptr + current_end);
112 3752 return *this;
113 }
114
115 11343 string& operator+=(const string& other)
116 {
117 11343 int current_end = length();
118 11343 resize(length() + other.length());
119 11343 copy(other.data(), other.length(), data_ptr + current_end);
120 11343 return *this;
121 }
122
123 100872 string& operator+=(const char *other)
124 {
125 100872 int current_end = length();
126
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 50691 times.
100872 int otherlen=(int)strlen(other);
127 100872 resize(length() + otherlen);
128 100872 copy(other, otherlen, data_ptr + current_end);
129 100872 return *this;
130 }
131
132 935237 string& operator+=(char c)
133 {
134 935237 resize(length() + 1);
135 935237 data_ptr[length() - 1] = c;
136 935237 return *this;
137 }
138
139 2 string operator+(char right) const
140 {
141 2 string ret=*this;
142
1/4
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 6 not taken.
✓ Branch 4 → 5 taken 2 times.
✗ Branch 4 → 7 not taken.
2 ret+=right;
143 2 return ret;
144 }
145
146 45819 string operator+(const char * right) const
147 {
148 45819 string ret=*this;
149
2/4
✓ Branch 3 → 4 taken 22806 times.
✗ Branch 3 → 6 not taken.
✓ Branch 4 → 5 taken 23013 times.
✗ Branch 4 → 7 not taken.
45819 ret+=right;
150 45819 return ret;
151 }
152
153 3020558 operator const char*() const
154 {
155 3020558 return data();
156 }
157
158 10390 explicit operator bool() const
159 {
160 10390 return length();
161 }
162
163 992094 string()
164 992094 {
165 992094 data_ptr = inlined.data;
166 992094 len = 0;
167 992094 inlined.data[0] = '\0';
168 992094 }
169 231392 string(const char * newstr) : string()
170 {
171
2/6
string::string(char const*):
✓ Branch 3 → 4 taken 114148 times.
✗ Branch 3 → 5 not taken.
string::string(char const*):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
✓ Branch 6 → 7 taken 117244 times.
✗ Branch 6 → 8 not taken.
231392 assign(newstr);
172 231392 }
173 31084 string(const char * newstr, int newlen) : string()
174 {
175
2/6
string::string(char const*, int):
✓ Branch 3 → 4 taken 15515 times.
✗ Branch 3 → 5 not taken.
string::string(char const*, int):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
✓ Branch 6 → 7 taken 15569 times.
✗ Branch 6 → 8 not taken.
31084 assign(newstr, newlen);
176 31084 }
177 241286 string(const string& old) : string()
178 {
179
2/6
string::string(string const&):
✓ Branch 5 → 6 taken 119870 times.
✗ Branch 5 → 7 not taken.
string::string(string const&):
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 7 not taken.
✓ Branch 10 → 11 taken 121416 times.
✗ Branch 10 → 12 not taken.
241286 assign(old.data(), old.length());
180 241286 }
181
182 25434 string(string &&move) noexcept : string()
183 {
184 25434 *this = move;
185 25434 }
186
187 112985 string& operator=(string&& other) noexcept
188 {
189
4/4
✓ Branch 3 → 4 taken 56192 times.
✓ Branch 3 → 5 taken 77 times.
✓ Branch 4 → 5 taken 56608 times.
✓ Branch 4 → 8 taken 108 times.
112985 if (other.is_inlined()) {
190 // No resources to steal so just do a normal assignment
191 112800 *this = other;
192 } else {
193
4/4
✓ Branch 6 → 7 taken 47 times.
✓ Branch 6 → 8 taken 30 times.
✓ Branch 10 → 11 taken 78 times.
✓ Branch 10 → 15 taken 30 times.
185 if (is_inlined()) {
194 125 data_ptr = other.data_ptr;
195 125 other.data_ptr = 0;
196 } else {
197 // Give our old allocation back so other can free it for us
198 60 std::swap(data_ptr, other.data_ptr);
199 }
200 185 len = other.len;
201 185 allocated = other.allocated;
202 }
203 112985 return *this;
204 }
205
206 942617 ~string()
207 {
208
4/6
string::~string():
✓ Branch 3 → 4 taken 1426 times.
✓ Branch 3 → 5 taken 465620 times.
string::~string():
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
✓ Branch 4 → 5 taken 2035 times.
✓ Branch 4 → 7 taken 473536 times.
942617 if(!is_inlined()){
209 3461 free(data_ptr);
210 }
211 942617 }
212
213 //maybe these should return refs to chain. but also good not to encourage chaining
214 10 void strip_prefix(char c)
215 {
216
2/4
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 7 not taken.
✓ Branch 5 → 6 taken 4 times.
✓ Branch 5 → 19 taken 6 times.
10 if(data()[0] == c){
217
2/4
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 13 taken 4 times.
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 15 taken 4 times.
4 std::memmove(data_ptr, data_ptr + 1, length() - 1);
218 4 resize(length() - 1);
219 }
220 10 }
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 1910751 unsigned capacity() const
266 {
267
4/4
✓ Branch 3 → 4 taken 956836 times.
✓ Branch 3 → 5 taken 987 times.
✓ Branch 4 → 5 taken 951415 times.
✓ Branch 4 → 6 taken 1513 times.
1910751 return is_inlined() ? inline_capacity : allocated.capacity;
268 }
269
270 2970164 bool is_inlined() const
271 {
272 2970164 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
6/12
operator==(char const*, string const&):
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 27 times.
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 27 times.
operator==(string const&, char const*):
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 4649 times.
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 4649 times.
operator==(string const&, string const&):
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 27369 times.
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 27369 times.
63478 ASAR_STRCMP_OPERATORS(==)
289
2/4
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 5457 times.
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 5457 times.
10880 ASAR_STRCMP_OPERATORS(!=)
290
2/4
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 2 times.
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 2 times.
4 ASAR_STRCMP_OPERATORS(<)
291 ASAR_STRCMP_OPERATORS(<=)
292
2/4
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 1 time.
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 1 time.
2 ASAR_STRCMP_OPERATORS(>)
293
2/4
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 1 time.
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 1 time.
2 ASAR_STRCMP_OPERATORS(>=)
294 #undef ASAR_STRCMP_OPERATORS
295
296 template<>
297 struct std::hash<string> {
298 66087 size_t operator()(const ::string& s) const {
299 66087 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 1062 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/4
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 7 not taken.
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 1 time.
2 snprintf(buffer, sizeof(buffer), "%.*X", width, value);
332
2/6
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 6 not taken.
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 7 not taken.
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 9 not taken.
4 return buffer;
333 }
334
335 3278 inline string dec(int64_t value)
336 {
337 1688 char buffer[64];
338
2/4
dec(long):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 1688 times.
dec(long long):
✓ Branch 2 → 3 taken 1590 times.
✗ Branch 2 → 7 not taken.
3278 snprintf(buffer, sizeof(buffer), "%" PRId64, value);
339
2/6
dec(long):
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 6 not taken.
✓ Branch 5 → 6 taken 1688 times.
✗ Branch 5 → 9 not taken.
dec(long long):
✓ Branch 3 → 4 taken 1590 times.
✗ Branch 3 → 7 not taken.
6556 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 2 → 3 taken 129 times.
✗ Branch 2 → 13 not taken.
258 snprintf(rval, sizeof(rval), "%.100f", value);
351
1/5
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 8 not taken.
✓ Branch 3 → 4 taken 258 times.
✗ Branch 3 → 9 not taken.
✗ Branch 3 → 15 not taken.
258 if (strchr(rval, '.'))//nuke useless zeroes
352 {
353 258 char * end=strrchr(rval, '\0')-1;
354
4/6
✗ Branch 5 → 4 not taken.
✗ Branch 5 → 6 not taken.
✓ Branch 6 → 5 taken 12726 times.
✓ Branch 6 → 7 taken 129 times.
✓ Branch 10 → 6 taken 12726 times.
✓ Branch 10 → 11 taken 129 times.
25710 while (*end=='0')
355 {
356 25452 *end='\0';
357 25452 end--;
358 }
359
4/6
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 8 not taken.
✓ Branch 7 → 8 taken 126 times.
✓ Branch 7 → 9 taken 3 times.
✓ Branch 12 → 13 taken 126 times.
✓ Branch 12 → 15 taken 3 times.
258 if (*end=='.') *end='\0';
360 }
361
2/6
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 12 not taken.
✓ Branch 9 → 10 taken 129 times.
✗ Branch 9 → 13 not taken.
✓ Branch 15 → 16 taken 129 times.
✗ Branch 15 → 19 not taken.
516 return rval;
362 }
363
364 // Same as above, but with variable precision
365 20 inline string ftostrvar(double value, int precision)
366 {
367 20 int clampedprecision = precision;
368
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 20 times.
20 if (clampedprecision < 0) clampedprecision = 0;
369
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 20 times.
20 if (clampedprecision > 100) clampedprecision = 100;
370
371 // see above
372 10 char rval[512];
373
1/2
✓ Branch 6 → 7 taken 10 times.
✗ Branch 6 → 17 not taken.
20 snprintf(rval, sizeof(rval), "%.*f", clampedprecision, (double)value);
374
3/5
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 12 not taken.
✓ Branch 7 → 8 taken 18 times.
✓ Branch 7 → 13 taken 1 time.
✓ Branch 7 → 19 taken 1 time.
20 if (strchr(rval, '.'))//nuke useless zeroes
375 {
376 18 char * end = strrchr(rval, '\0') - 1;
377
4/6
✗ Branch 9 → 8 not taken.
✗ Branch 9 → 10 not taken.
✓ Branch 10 → 9 taken 23 times.
✓ Branch 10 → 11 taken 9 times.
✓ Branch 14 → 10 taken 23 times.
✓ Branch 14 → 15 taken 9 times.
64 while (*end == '0')
378 {
379 46 *end = '\0';
380 46 end--;
381 }
382
4/6
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 12 not taken.
✓ Branch 11 → 12 taken 3 times.
✓ Branch 11 → 13 taken 6 times.
✓ Branch 16 → 17 taken 3 times.
✓ Branch 16 → 19 taken 6 times.
18 if (*end == '.') *end = '\0';
383 }
384
2/6
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 16 not taken.
✓ Branch 13 → 14 taken 10 times.
✗ Branch 13 → 17 not taken.
✓ Branch 19 → 20 taken 10 times.
✗ Branch 19 → 23 not taken.
40 return rval;
385 }
386
387 149446 inline bool stribegin(const char * str, const char * key)
388 {
389
4/4
✓ Branch 8 → 3 taken 251767 times.
✓ Branch 8 → 9 taken 7447 times.
✓ Branch 14 → 3 taken 218276 times.
✓ Branch 14 → 15 taken 2463 times.
479953 for (int i=0;key[i];i++)
390 {
391
4/4
✓ Branch 5 → 6 taken 66964 times.
✓ Branch 5 → 7 taken 184803 times.
✓ Branch 9 → 10 taken 72572 times.
✓ Branch 9 → 11 taken 145704 times.
470043 if (to_lower(str[i])!=to_lower(key[i])) return false;
392 }
393 9910 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 27766 inline bool stricmpwithlower(const char *word1, const char *word2)
421 {
422
4/4
✓ Branch 7 → 3 taken 16118 times.
✓ Branch 7 → 8 taken 259 times.
✓ Branch 12 → 3 taken 16420 times.
✓ Branch 12 → 13 taken 261 times.
33058 while(*word2)
423 {
424
4/4
✓ Branch 4 → 5 taken 13494 times.
✓ Branch 4 → 6 taken 2624 times.
✓ Branch 8 → 9 taken 13752 times.
✓ Branch 8 → 10 taken 2668 times.
32538 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 11527 inline const char * dequote(char * str)
435 {
436
4/4
✓ Branch 2 → 3 taken 372 times.
✓ Branch 2 → 4 taken 5378 times.
✓ Branch 3 → 4 taken 396 times.
✓ Branch 3 → 5 taken 5381 times.
11527 if (*str!='"') return str;
437
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 5381 times.
10759 char *end = strrchr(str, '"');
438
2/4
✓ Branch 4 → 5 taken 5378 times.
✗ Branch 4 → 11 not taken.
✓ Branch 7 → 8 taken 5381 times.
✗ Branch 7 → 29 not taken.
10759 if (end)
439 {
440 // make sure the closing quote is at the end of the argument
441
2/4
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 5378 times.
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 5381 times.
10759 if(end[1] != 0) return nullptr;
442 10759 *end = 0;
443 10759 char *quote = str+1;
444
5/6
✓ Branch 9 → 8 taken 72 times.
✓ Branch 9 → 10 taken 5378 times.
✗ Branch 24 → 25 not taken.
✓ Branch 24 → 26 taken 5453 times.
✓ Branch 26 → 15 taken 72 times.
✓ Branch 26 → 27 taken 5381 times.
10903 while((quote = strstr(quote, "\"\""))) {
445
3/6
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 72 times.
✗ Branch 18 → 19 not taken.
✓ Branch 18 → 20 taken 72 times.
✗ Branch 20 → 21 not taken.
✓ Branch 20 → 22 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 42134 inline char * strqchr(char * str, char key)
454 {
455
4/4
✓ Branch 18 → 3 taken 122587 times.
✓ Branch 18 → 19 taken 3597 times.
✓ Branch 34 → 3 taken 123763 times.
✓ Branch 34 → 35 taken 3645 times.
253592 while (*str != '\0')
456 {
457
4/4
✓ Branch 3 → 4 taken 17338 times.
✓ Branch 3 → 5 taken 105249 times.
✓ Branch 4 → 5 taken 17554 times.
✓ Branch 4 → 6 taken 106209 times.
246350 if (*str == key) { return str; }
458
8/8
✓ Branch 5 → 6 taken 105054 times.
✓ Branch 5 → 7 taken 195 times.
✓ Branch 6 → 7 taken 213 times.
✓ Branch 6 → 17 taken 104841 times.
✓ Branch 7 → 8 taken 106014 times.
✓ Branch 7 → 10 taken 195 times.
✓ Branch 9 → 10 taken 213 times.
✓ Branch 9 → 31 taken 105801 times.
211458 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
10/12
✓ Branch 7 → 8 taken 213 times.
✓ Branch 7 → 11 taken 195 times.
✓ Branch 8 → 9 taken 9 times.
✓ Branch 8 → 11 taken 204 times.
✓ Branch 9 → 10 taken 9 times.
✗ Branch 9 → 11 not taken.
✓ Branch 11 → 12 taken 213 times.
✓ Branch 11 → 20 taken 195 times.
✓ Branch 14 → 15 taken 9 times.
✓ Branch 14 → 20 taken 204 times.
✓ Branch 17 → 18 taken 9 times.
✗ Branch 17 → 20 not taken.
816 if (str[0] == '\'' && str[1] == '\'' && str[2] == '\'') { str += 2; }
463 else
464 {
465 798 char delimiter = *str;
466
467 do
468 {
469 3996 str++;
470
471 // If we want to support backslash escapes, we'll have to add that right here.
472
6/8
✓ Branch 12 → 13 taken 1599 times.
✓ Branch 12 → 15 taken 399 times.
✓ Branch 13 → 14 taken 1599 times.
✗ Branch 13 → 15 not taken.
✓ Branch 24 → 25 taken 1599 times.
✓ Branch 24 → 28 taken 399 times.
✓ Branch 26 → 27 taken 1599 times.
✗ Branch 26 → 28 not taken.
3996 } 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
2/4
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 399 times.
✗ Branch 29 → 30 not taken.
✓ Branch 29 → 31 taken 399 times.
798 if (*str == '\0') { return nullptr; }
476 }
477 }
478
479 211458 str++;
480 }
481
482 7242 return nullptr;
483 }
484
485 41486 inline const char * strqchr(const char * str, char key) {
486 41486 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 44898 inline char *strip_whitespace(char *str)
496 {
497
4/4
✓ Branch 5 → 3 taken 49 times.
✓ Branch 5 → 6 taken 22307 times.
✓ Branch 7 → 3 taken 56 times.
✓ Branch 7 → 8 taken 22591 times.
45003 while(is_space(*str)) str++;
498
5/6
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 22591 times.
✓ Branch 11 → 7 taken 21058 times.
✓ Branch 11 → 12 taken 1299 times.
✓ Branch 19 → 11 taken 21336 times.
✓ Branch 19 → 20 taken 1313 times.
45006 for(int i = strlen(str) - 1; i >= 0; i--)
499 {
500
4/4
✓ Branch 8 → 9 taken 21008 times.
✓ Branch 8 → 10 taken 50 times.
✓ Branch 14 → 15 taken 21278 times.
✓ Branch 14 → 18 taken 58 times.
42394 if(!is_space(str[i]))
501 {
502 42286 str[i + 1] = 0;
503 42286 return str;
504 }
505 }
506 2612 return str;
507 }
508 266 inline void strip_whitespace(string &str)
509 {
510
2/4
✓ Branch 4 → 5 taken 126 times.
✗ Branch 4 → 8 not taken.
✓ Branch 6 → 7 taken 140 times.
✗ Branch 6 → 13 not taken.
266 str = string(strip_whitespace(str.temp_raw()));
511 266 }
512
513 41426 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 41426 const char* params = strqchr(from, ' ');
516
4/4
✓ Branch 3 → 4 taken 16999 times.
✓ Branch 3 → 6 taken 3582 times.
✓ Branch 4 → 5 taken 17215 times.
✓ Branch 4 → 12 taken 3630 times.
41426 if(params) {
517 34214 to.assign(from, params - from);
518 34214 from = params+1;
519 } else {
520 7212 to.assign(from);
521 7212 from += to.length(); // now from points at a null byte
522 }
523 41426 }
524
525 string &itrim(string &str, const char * left, const char * right);
526
527 110569 inline string &lower(string &old)
528 {
529 110569 int length = old.length();
530
4/4
✓ Branch 8 → 4 taken 601470 times.
✓ Branch 8 → 9 taken 60555 times.
✓ Branch 15 → 5 taken 248865 times.
✓ Branch 15 → 16 taken 50014 times.
960904 for (int i=0;i<length;i++) old.raw()[i]=(char)to_lower(old.data()[i]);
531 110569 return old;
532 }
533
534