| 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 |
|
1632325 |
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 |
|
274399 |
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 |
|
47326 |
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 |
|
16478 |
inline bool is_ualpha(unsigned char c) { return char_props[c] & 0x28; } |
| 23 |
|
122467 |
inline bool is_ualnum(unsigned char c) { return char_props[c] & 0x68; } |
| 24 |
|
7297 |
inline bool is_xdigit(unsigned char c) { return char_props[c] & 0x01; } |
| 25 |
|
|
|
| 26 |
|
1088501 |
inline char *copy(const char *source, int copy_length, char *dest) |
| 27 |
|
|
{ |
| 28 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 542983 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 542983 times.
|
1088501 |
memcpy(dest, source, copy_length*sizeof(char)); |
| 29 |
|
1088501 |
return dest; |
| 30 |
|
|
} |
| 31 |
|
|
|
| 32 |
|
|
class string { |
| 33 |
|
|
public: |
| 34 |
|
4572998 |
const char *data() const |
| 35 |
|
|
{ |
| 36 |
|
4572998 |
return data_ptr; |
| 37 |
|
|
} |
| 38 |
|
|
|
| 39 |
|
86514 |
char *temp_raw() const //things to cleanup and take a look at |
| 40 |
|
|
{ |
| 41 |
|
86514 |
return data_ptr; |
| 42 |
|
|
} |
| 43 |
|
|
|
| 44 |
|
835421 |
char *raw() const |
| 45 |
|
|
{ |
| 46 |
|
835421 |
return data_ptr; |
| 47 |
|
|
} |
| 48 |
|
|
|
| 49 |
|
4537261 |
int length() const |
| 50 |
|
|
{ |
| 51 |
|
4537261 |
return len; |
| 52 |
|
|
} |
| 53 |
|
|
|
| 54 |
|
1946229 |
void resize(unsigned int new_length) |
| 55 |
|
|
{ |
| 56 |
3/3
✓ Branch 0 taken 1256 times.
✓ Branch 1 taken 975679 times.
✓ Branch 2 taken 969294 times.
|
1946229 |
if (new_length > capacity()) { |
| 57 |
|
2714 |
reallocate_capacity(new_length); |
| 58 |
|
|
} |
| 59 |
|
|
|
| 60 |
|
1946229 |
len = new_length; |
| 61 |
|
1946229 |
data_ptr[new_length] = 0; //always ensure null terminator |
| 62 |
|
1946229 |
} |
| 63 |
|
|
|
| 64 |
|
804 |
void truncate(int newlen) |
| 65 |
|
|
{ |
| 66 |
|
804 |
resize(newlen); |
| 67 |
|
804 |
} |
| 68 |
|
|
|
| 69 |
|
211360 |
void assign(const char * newstr) |
| 70 |
|
|
{ |
| 71 |
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 211255 times.
|
211360 |
if (!newstr) newstr = ""; |
| 72 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 107204 times.
|
211360 |
assign(newstr, strlen(newstr)); |
| 73 |
|
211360 |
} |
| 74 |
|
|
|
| 75 |
|
289227 |
void assign(const string &newstr) |
| 76 |
|
|
{ |
| 77 |
|
289227 |
assign(newstr.data(), newstr.length()); |
| 78 |
|
289227 |
} |
| 79 |
|
|
|
| 80 |
|
901273 |
void assign(const char * newstr, int end) |
| 81 |
|
|
{ |
| 82 |
|
901273 |
resize(end); |
| 83 |
|
901273 |
copy(newstr, end, data_ptr); |
| 84 |
|
901273 |
} |
| 85 |
|
|
|
| 86 |
|
|
|
| 87 |
|
12734 |
string& operator=(const char * newstr) |
| 88 |
|
|
{ |
| 89 |
|
12734 |
assign(newstr); |
| 90 |
|
12734 |
return *this; |
| 91 |
|
|
} |
| 92 |
|
|
|
| 93 |
|
289227 |
string& operator=(const string &newstr) |
| 94 |
|
|
{ |
| 95 |
|
289227 |
assign(newstr); |
| 96 |
|
289227 |
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 |
|
3632 |
string& append(const char *other, int start, int end) |
| 108 |
|
|
{ |
| 109 |
|
3632 |
int current_end = length(); |
| 110 |
|
3632 |
resize(length() + end - start); |
| 111 |
|
3632 |
copy(other + start, end - start, data_ptr + current_end); |
| 112 |
|
3632 |
return *this; |
| 113 |
|
|
} |
| 114 |
|
|
|
| 115 |
|
64792 |
string& operator+=(const string& other) |
| 116 |
|
|
{ |
| 117 |
|
64792 |
int current_end = length(); |
| 118 |
|
64792 |
resize(length() + other.length()); |
| 119 |
|
64792 |
copy(other.data(), other.length(), data_ptr + current_end); |
| 120 |
|
64792 |
return *this; |
| 121 |
|
|
} |
| 122 |
|
|
|
| 123 |
|
116271 |
string& operator+=(const char *other) |
| 124 |
|
|
{ |
| 125 |
|
116271 |
int current_end = length(); |
| 126 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58409 times.
|
116271 |
int otherlen=(int)strlen(other); |
| 127 |
|
116271 |
resize(length() + otherlen); |
| 128 |
|
116271 |
copy(other, otherlen, data_ptr + current_end); |
| 129 |
|
116271 |
return *this; |
| 130 |
|
|
} |
| 131 |
|
|
|
| 132 |
|
859453 |
string& operator+=(char c) |
| 133 |
|
|
{ |
| 134 |
|
859453 |
resize(length() + 1); |
| 135 |
|
859453 |
data_ptr[length() - 1] = c; |
| 136 |
|
859453 |
return *this; |
| 137 |
|
|
} |
| 138 |
|
|
|
| 139 |
|
|
string operator+(char right) const |
| 140 |
|
|
{ |
| 141 |
|
|
string ret=*this; |
| 142 |
|
|
ret+=right; |
| 143 |
|
|
return ret; |
| 144 |
|
|
} |
| 145 |
|
|
|
| 146 |
|
45708 |
string operator+(const char * right) const |
| 147 |
|
|
{ |
| 148 |
|
45708 |
string ret=*this; |
| 149 |
1/2
✓ Branch 0 taken 45708 times.
✗ Branch 1 not taken.
|
45708 |
ret+=right; |
| 150 |
|
45708 |
return ret; |
| 151 |
|
✗ |
} |
| 152 |
|
|
|
| 153 |
|
2858809 |
operator const char*() const |
| 154 |
|
|
{ |
| 155 |
|
2858809 |
return data(); |
| 156 |
|
|
} |
| 157 |
|
|
|
| 158 |
|
10308 |
explicit operator bool() const |
| 159 |
|
|
{ |
| 160 |
|
10308 |
return length(); |
| 161 |
|
|
} |
| 162 |
|
|
|
| 163 |
|
1119389 |
string() |
| 164 |
|
1119389 |
{ |
| 165 |
|
1119389 |
data_ptr = inlined.data; |
| 166 |
|
1119389 |
len = 0; |
| 167 |
|
1119389 |
inlined.data[0] = '\0'; |
| 168 |
|
1119389 |
} |
| 169 |
|
191438 |
string(const char * newstr) : string() |
| 170 |
|
|
{ |
| 171 |
2/3
✓ Branch 0 taken 94299 times.
✓ Branch 1 taken 97139 times.
✗ Branch 2 not taken.
|
191438 |
assign(newstr); |
| 172 |
|
191438 |
} |
| 173 |
|
84555 |
string(const char * newstr, int newlen) : string() |
| 174 |
|
|
{ |
| 175 |
2/3
✓ Branch 0 taken 42128 times.
✓ Branch 1 taken 42427 times.
✗ Branch 2 not taken.
|
84555 |
assign(newstr, newlen); |
| 176 |
|
84555 |
} |
| 177 |
|
270133 |
string(const string& old) : string() |
| 178 |
|
|
{ |
| 179 |
2/4
✓ Branch 0 taken 134257 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 135876 times.
✗ Branch 3 not taken.
|
270133 |
assign(old.data(), old.length()); |
| 180 |
|
270133 |
} |
| 181 |
|
|
|
| 182 |
|
25916 |
string(string &&move) noexcept : string() |
| 183 |
|
|
{ |
| 184 |
|
25916 |
*this = move; |
| 185 |
|
25916 |
} |
| 186 |
|
|
|
| 187 |
|
113040 |
string& operator=(string&& other) noexcept |
| 188 |
|
|
{ |
| 189 |
3/3
✓ Branch 0 taken 56262 times.
✓ Branch 1 taken 56739 times.
✓ Branch 2 taken 39 times.
|
113040 |
if (other.is_inlined()) { |
| 190 |
|
|
// No resources to steal so just do a normal assignment |
| 191 |
|
112963 |
*this = other; |
| 192 |
|
|
} else { |
| 193 |
3/3
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 39 times.
✓ Branch 2 taken 21 times.
|
77 |
if (is_inlined()) { |
| 194 |
|
35 |
data_ptr = other.data_ptr; |
| 195 |
|
35 |
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 |
|
77 |
len = other.len; |
| 201 |
|
77 |
allocated = other.allocated; |
| 202 |
|
|
} |
| 203 |
|
113040 |
return *this; |
| 204 |
|
|
} |
| 205 |
|
|
|
| 206 |
|
1069915 |
~string() |
| 207 |
|
|
{ |
| 208 |
3/3
✓ Branch 0 taken 1199 times.
✓ Branch 1 taken 530682 times.
✓ Branch 2 taken 538034 times.
|
1069915 |
if(!is_inlined()){ |
| 209 |
|
2568 |
free(data_ptr); |
| 210 |
|
|
} |
| 211 |
|
1069915 |
} |
| 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 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 6 times.
|
10 |
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 |
|
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 |
|
1946229 |
unsigned capacity() const |
| 266 |
|
|
{ |
| 267 |
3/3
✓ Branch 0 taken 974833 times.
✓ Branch 1 taken 970553 times.
✓ Branch 2 taken 843 times.
|
1946229 |
return is_inlined() ? inline_capacity : allocated.capacity; |
| 268 |
|
|
} |
| 269 |
|
|
|
| 270 |
|
3131975 |
bool is_inlined() const |
| 271 |
|
|
{ |
| 272 |
|
3131975 |
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 4559 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 31517 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 26958 times.
|
62533 |
ASAR_STRCMP_OPERATORS(==) |
| 289 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5453 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5453 times.
|
10872 |
ASAR_STRCMP_OPERATORS(!=) |
| 290 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
|
4 |
ASAR_STRCMP_OPERATORS(<) |
| 291 |
|
✗ |
ASAR_STRCMP_OPERATORS(<=) |
| 292 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
2 |
ASAR_STRCMP_OPERATORS(>) |
| 293 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
2 |
ASAR_STRCMP_OPERATORS(>=) |
| 294 |
|
|
#undef ASAR_STRCMP_OPERATORS |
| 295 |
|
|
|
| 296 |
|
|
template<> |
| 297 |
|
|
struct std::hash<string> { |
| 298 |
|
65011 |
size_t operator()(const ::string& s) const { |
| 299 |
|
65011 |
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 |
|
1056 |
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 |
|
3266 |
inline string dec(int64_t value) |
| 336 |
|
|
{ |
| 337 |
|
1682 |
char buffer[64]; |
| 338 |
2/2
✓ Branch 0 taken 1584 times.
✓ Branch 1 taken 1682 times.
|
3266 |
snprintf(buffer, sizeof(buffer), "%" PRId64, value); |
| 339 |
1/2
✓ Branch 0 taken 3266 times.
✗ Branch 1 not taken.
|
6532 |
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 |
|
20 |
inline string ftostrvar(double value, int precision) |
| 366 |
|
|
{ |
| 367 |
|
20 |
int clampedprecision = precision; |
| 368 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
|
20 |
if (clampedprecision < 0) clampedprecision = 0; |
| 369 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
|
20 |
if (clampedprecision > 100) clampedprecision = 100; |
| 370 |
|
|
|
| 371 |
|
|
// see above |
| 372 |
|
10 |
char rval[512]; |
| 373 |
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
|
20 |
snprintf(rval, sizeof(rval), "%.*f", clampedprecision, (double)value); |
| 374 |
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 2 times.
|
20 |
if (strchr(rval, '.'))//nuke useless zeroes |
| 375 |
|
|
{ |
| 376 |
|
18 |
char * end = strrchr(rval, '\0') - 1; |
| 377 |
3/3
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 9 times.
|
64 |
while (*end == '0') |
| 378 |
|
|
{ |
| 379 |
|
46 |
*end = '\0'; |
| 380 |
|
46 |
end--; |
| 381 |
|
|
} |
| 382 |
3/3
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 6 times.
|
18 |
if (*end == '.') *end = '\0'; |
| 383 |
|
|
} |
| 384 |
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
|
40 |
return rval; |
| 385 |
|
|
} |
| 386 |
|
|
|
| 387 |
|
123529 |
inline bool stribegin(const char * str, const char * key) |
| 388 |
|
|
{ |
| 389 |
4/4
✓ Branch 0 taken 206481 times.
✓ Branch 1 taken 7427 times.
✓ Branch 2 taken 172818 times.
✓ Branch 3 taken 2443 times.
|
389169 |
for (int i=0;key[i];i++) |
| 390 |
|
|
{ |
| 391 |
4/4
✓ Branch 0 taken 54105 times.
✓ Branch 1 taken 152376 times.
✓ Branch 2 taken 59554 times.
✓ Branch 3 taken 113264 times.
|
379299 |
if (to_lower(str[i])!=to_lower(key[i])) return false; |
| 392 |
|
|
} |
| 393 |
|
9870 |
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 |
|
27616 |
inline bool stricmpwithlower(const char *word1, const char *word2) |
| 421 |
|
|
{ |
| 422 |
3/3
✓ Branch 0 taken 16040 times.
✓ Branch 1 taken 16601 times.
✓ Branch 2 taken 261 times.
|
32902 |
while(*word2) |
| 423 |
|
|
{ |
| 424 |
4/4
✓ Branch 0 taken 13419 times.
✓ Branch 1 taken 2621 times.
✓ Branch 2 taken 13677 times.
✓ Branch 3 taken 2665 times.
|
32382 |
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 |
3/3
✓ Branch 0 taken 372 times.
✓ Branch 1 taken 5774 times.
✓ Branch 2 taken 5381 times.
|
11527 |
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 |
|
57987 |
inline char * strqchr(char * str, char key) |
| 454 |
|
|
{ |
| 455 |
3/3
✓ Branch 0 taken 187516 times.
✓ Branch 1 taken 199735 times.
✓ Branch 2 taken 9877 times.
|
397128 |
while (*str != '\0') |
| 456 |
|
|
{ |
| 457 |
3/3
✓ Branch 0 taken 19072 times.
✓ Branch 1 taken 187732 times.
✓ Branch 2 taken 170699 times.
|
377503 |
if (*str == key) { return str; } |
| 458 |
6/6
✓ Branch 0 taken 167951 times.
✓ Branch 1 taken 170691 times.
✓ Branch 2 taken 807 times.
✓ Branch 3 taken 167645 times.
✓ Branch 4 taken 306 times.
✓ Branch 5 taken 169892 times.
|
339143 |
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 799 times.
✓ Branch 2 taken 516 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.
|
1606 |
if (str[0] == '\'' && str[1] == '\'' && str[2] == '\'') { str += 2; } |
| 463 |
|
|
else |
| 464 |
|
|
{ |
| 465 |
|
1576 |
char delimiter = *str; |
| 466 |
|
|
|
| 467 |
|
|
do |
| 468 |
|
|
{ |
| 469 |
|
11242 |
str++; |
| 470 |
|
|
|
| 471 |
|
|
// If we want to support backslash escapes, we'll have to add that right here. |
| 472 |
6/6
✓ Branch 0 taken 4801 times.
✓ Branch 1 taken 5650 times.
✓ Branch 2 taken 5591 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 4866 times.
✓ Branch 5 taken 1 times.
|
11242 |
} 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 784 times.
✓ Branch 2 taken 791 times.
|
1576 |
if (*str == '\0') { return nullptr; } |
| 476 |
|
|
} |
| 477 |
|
|
} |
| 478 |
|
|
|
| 479 |
|
339141 |
str++; |
| 480 |
|
|
} |
| 481 |
|
|
|
| 482 |
|
19625 |
return nullptr; |
| 483 |
|
|
} |
| 484 |
|
|
|
| 485 |
|
41318 |
inline const char * strqchr(const char * str, char key) { |
| 486 |
|
41318 |
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 |
|
72701 |
inline char *strip_whitespace(char *str) |
| 496 |
|
|
{ |
| 497 |
4/4
✓ Branch 0 taken 1532 times.
✓ Branch 1 taken 36147 times.
✓ Branch 2 taken 1971 times.
✓ Branch 3 taken 36554 times.
|
76204 |
while(is_space(*str)) str++; |
| 498 |
4/4
✓ Branch 0 taken 32171 times.
✓ Branch 1 taken 48100 times.
✓ Branch 2 taken 32516 times.
✓ Branch 3 taken 11616 times.
|
87849 |
for(int i = strlen(str) - 1; i >= 0; i--) |
| 499 |
|
|
{ |
| 500 |
4/4
✓ Branch 0 taken 24601 times.
✓ Branch 1 taken 7570 times.
✓ Branch 2 taken 24938 times.
✓ Branch 3 taken 7578 times.
|
64687 |
if(!is_space(str[i])) |
| 501 |
|
|
{ |
| 502 |
|
49539 |
str[i + 1] = 0; |
| 503 |
|
49539 |
return str; |
| 504 |
|
|
} |
| 505 |
|
|
} |
| 506 |
|
23162 |
return str; |
| 507 |
|
|
} |
| 508 |
|
266 |
inline void strip_whitespace(string &str) |
| 509 |
|
|
{ |
| 510 |
2/4
✓ Branch 0 taken 126 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 140 times.
✗ Branch 3 not taken.
|
266 |
str = string(strip_whitespace(str.temp_raw())); |
| 511 |
|
266 |
} |
| 512 |
|
|
|
| 513 |
|
41258 |
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 |
|
41258 |
const char* params = strqchr(from, ' '); |
| 516 |
2/2
✓ Branch 0 taken 34070 times.
✓ Branch 1 taken 7188 times.
|
41258 |
if(params) { |
| 517 |
|
34070 |
to.assign(from, params - from); |
| 518 |
|
34070 |
from = params+1; |
| 519 |
|
|
} else { |
| 520 |
|
7188 |
to.assign(from); |
| 521 |
|
7188 |
from += to.length(); // now from points at a null byte |
| 522 |
|
|
} |
| 523 |
|
41258 |
} |
| 524 |
|
|
|
| 525 |
|
|
string &itrim(string &str, const char * left, const char * right); |
| 526 |
|
|
|
| 527 |
|
110133 |
inline string &lower(string &old) |
| 528 |
|
|
{ |
| 529 |
|
110133 |
int length = old.length(); |
| 530 |
4/4
✓ Branch 0 taken 562900 times.
✓ Branch 1 taken 60329 times.
✓ Branch 2 taken 247881 times.
✓ Branch 3 taken 49804 times.
|
920914 |
for (int i=0;i<length;i++) old.raw()[i]=(char)to_lower(old.data()[i]); |
| 531 |
|
110133 |
return old; |
| 532 |
|
|
} |
| 533 |
|
|
|
| 534 |
|
|
|
| 535 |
|
|
// Returns number of connected lines - 1 |
| 536 |
|
|
template<typename stringarraytype> |
| 537 |
|
53595 |
inline int getconnectedlines(stringarraytype& lines, int startline, string& out) |
| 538 |
|
|
{ |
| 539 |
|
53595 |
int count = 0; |
| 540 |
|
|
|
| 541 |
2/4
✓ Branch 0 taken 26685 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26928 times.
✗ Branch 3 not taken.
|
53613 |
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 26928 times.
|
53613 |
int linestartpos = (int)strlen(lines[i]); |
| 545 |
|
|
|
| 546 |
6/6
✓ Branch 0 taken 38509 times.
✓ Branch 1 taken 15104 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 19145 times.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 19346 times.
|
53613 |
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 26676 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26676 times.
✓ Branch 3 taken 26919 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 26919 times.
✗ Branch 6 not taken.
|
53595 |
out += string(lines[i], linestartpos); |
| 555 |
|
53595 |
return count; |
| 556 |
|
|
} |
| 557 |
|
|
} |
| 558 |
|
|
|
| 559 |
|
✗ |
return count; |
| 560 |
|
|
} |
| 561 |
|
|
|