asar coverage - build #81


src/asar/
File: src/asar/libstr.h
Date: 2024-01-19 05:09:49
Lines:
216/221
97.7%
Functions:
44/45
97.8%
Branches:
412/556
74.1%

Line Branch Exec Source
1 #pragma once
2
3 #include "std-includes.h"
4 #include "libmisc.h"
5 #include <cstdint>
6 //ty alcaro
7 extern const unsigned char char_props[256];
8 1322795 static inline int to_lower(unsigned char c) { return c|(char_props[c]&0x20); }
9 114996 static inline int to_upper(unsigned char c) { return c&~(char_props[c]&0x20); }
10
11
10/10
✓ Branch 0 taken 44294 times.
✓ Branch 1 taken 14854 times.
✓ Branch 2 taken 44234 times.
✓ Branch 3 taken 48 times.
✓ Branch 4 taken 192 times.
✓ Branch 5 taken 60 times.
✓ Branch 6 taken 1716 times.
✓ Branch 7 taken 4390 times.
✓ Branch 8 taken 1746 times.
✓ Branch 9 taken 1716 times.
244122 inline bool is_space(unsigned char c) { return char_props[c] & 0x80; } // C standard says \f \v are space, but this one disagrees
12 52068 inline bool is_digit(unsigned char c) { return char_props[c] & 0x40; }
13 inline bool is_alpha(unsigned char c) { return char_props[c] & 0x20; }
14 3696 inline bool is_lower(unsigned char c) { return char_props[c] & 0x04; }
15 4962 inline bool is_upper(unsigned char c) { return char_props[c] & 0x02; }
16 inline bool is_alnum(unsigned char c) { return char_props[c] & 0x60; }
17 13528 inline bool is_ualpha(unsigned char c) { return char_props[c] & 0x28; }
18 138480 inline bool is_ualnum(unsigned char c) { return char_props[c] & 0x68; }
19
4/4
✓ Branch 0 taken 9336 times.
✓ Branch 1 taken 7076 times.
✓ Branch 2 taken 9828 times.
✓ Branch 3 taken 2772 times.
29012 inline bool is_xdigit(unsigned char c) { return char_props[c] & 0x01; }
20
21 inline char *copy(const char *source, int copy_length, char *dest)
22 {
23 1150327 memcpy(dest, source, copy_length*sizeof(char));
24 return dest;
25 }
26
27 class string {
28 public:
29 const char *data() const
30 {
31
262/380
✓ Branch 0 taken 5393 times.
✓ Branch 1 taken 403901 times.
✓ Branch 2 taken 397700 times.
✓ Branch 3 taken 2158 times.
✓ Branch 4 taken 4512 times.
✓ Branch 5 taken 27918 times.
✓ Branch 6 taken 28151 times.
✓ Branch 7 taken 2038 times.
✓ Branch 8 taken 6023 times.
✓ Branch 9 taken 987 times.
✓ Branch 10 taken 1122 times.
✓ Branch 11 taken 337 times.
✓ Branch 12 taken 888 times.
✓ Branch 13 taken 70 times.
✓ Branch 14 taken 642 times.
✓ Branch 15 taken 120 times.
✓ Branch 16 taken 8090 times.
✓ Branch 17 taken 122 times.
✓ Branch 18 taken 332 times.
✓ Branch 19 taken 456 times.
✓ Branch 20 taken 494 times.
✓ Branch 21 taken 381 times.
✓ Branch 22 taken 1179 times.
✓ Branch 23 taken 57 times.
✓ Branch 24 taken 438 times.
✓ Branch 25 taken 193 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 54 times.
✓ Branch 28 taken 24 times.
✓ Branch 29 taken 248 times.
✓ Branch 30 taken 120 times.
✓ Branch 31 taken 166 times.
✓ Branch 32 taken 8 times.
✓ Branch 33 taken 26585 times.
✓ Branch 34 taken 22053 times.
✓ Branch 35 taken 16 times.
✓ Branch 36 taken 284 times.
✓ Branch 37 taken 28124 times.
✓ Branch 38 taken 23563 times.
✓ Branch 39 taken 267 times.
✓ Branch 40 taken 242 times.
✓ Branch 41 taken 72 times.
✓ Branch 42 taken 95 times.
✓ Branch 43 taken 10 times.
✓ Branch 44 taken 140 times.
✓ Branch 45 taken 1318 times.
✓ Branch 46 taken 66 times.
✓ Branch 47 taken 1346 times.
✓ Branch 48 taken 260 times.
✓ Branch 49 taken 14 times.
✓ Branch 50 taken 404 times.
✓ Branch 51 taken 189 times.
✓ Branch 52 taken 985 times.
✓ Branch 53 taken 22205 times.
✓ Branch 54 taken 5245 times.
✓ Branch 55 taken 270 times.
✓ Branch 56 taken 1323 times.
✓ Branch 57 taken 266 times.
✓ Branch 58 taken 26173 times.
✓ Branch 59 taken 516 times.
✓ Branch 60 taken 153 times.
✓ Branch 61 taken 84 times.
✓ Branch 62 taken 22 times.
✓ Branch 63 taken 19777 times.
✓ Branch 64 taken 5049 times.
✓ Branch 65 taken 22270 times.
✓ Branch 66 taken 773 times.
✓ Branch 67 taken 1396 times.
✓ Branch 68 taken 1398 times.
✓ Branch 69 taken 141 times.
✓ Branch 70 taken 22152 times.
✓ Branch 71 taken 5218 times.
✓ Branch 72 taken 36 times.
✓ Branch 73 taken 1355 times.
✓ Branch 74 taken 29 times.
✓ Branch 75 taken 276 times.
✓ Branch 76 taken 63 times.
✓ Branch 77 taken 1362 times.
✓ Branch 78 taken 1347 times.
✓ Branch 79 taken 45 times.
✓ Branch 80 taken 1529 times.
✓ Branch 81 taken 57 times.
✓ Branch 82 taken 370 times.
✓ Branch 83 taken 82 times.
✓ Branch 84 taken 36 times.
✓ Branch 85 taken 708 times.
✓ Branch 86 taken 80 times.
✓ Branch 87 taken 36 times.
✓ Branch 88 taken 405 times.
✓ Branch 89 taken 1319 times.
✓ Branch 90 taken 1069 times.
✓ Branch 91 taken 1263 times.
✓ Branch 92 taken 61 times.
✓ Branch 93 taken 986 times.
✓ Branch 94 taken 48 times.
✓ Branch 95 taken 1078 times.
✓ Branch 96 taken 996 times.
✓ Branch 97 taken 36 times.
✓ Branch 98 taken 1162 times.
✓ Branch 99 taken 99 times.
✓ Branch 100 taken 1218 times.
✓ Branch 101 taken 4763 times.
✓ Branch 102 taken 6228 times.
✓ Branch 103 taken 3606 times.
✓ Branch 104 taken 28 times.
✓ Branch 105 taken 33 times.
✓ Branch 106 taken 8778 times.
✓ Branch 107 taken 48 times.
✓ Branch 108 taken 3633 times.
✓ Branch 109 taken 78 times.
✓ Branch 110 taken 598 times.
✓ Branch 111 taken 6494 times.
✓ Branch 112 taken 981 times.
✓ Branch 113 taken 271 times.
✓ Branch 114 taken 14 times.
✓ Branch 115 taken 129 times.
✓ Branch 116 taken 30 times.
✓ Branch 117 taken 3 times.
✓ Branch 118 taken 60 times.
✓ Branch 119 taken 30 times.
✓ Branch 120 taken 272 times.
✓ Branch 121 taken 999 times.
✓ Branch 122 taken 255 times.
✓ Branch 123 taken 1009 times.
✓ Branch 124 taken 39 times.
✗ Branch 125 not taken.
✓ Branch 126 taken 364 times.
✗ Branch 127 not taken.
✓ Branch 128 taken 273 times.
✓ Branch 129 taken 132 times.
✓ Branch 130 taken 150 times.
✗ Branch 131 not taken.
✓ Branch 132 taken 255 times.
✓ Branch 133 taken 1242 times.
✓ Branch 134 taken 39 times.
✓ Branch 135 taken 34 times.
✓ Branch 136 taken 13 times.
✓ Branch 137 taken 18 times.
✓ Branch 138 taken 42 times.
✓ Branch 139 taken 42 times.
✓ Branch 140 taken 49 times.
✓ Branch 141 taken 33 times.
✓ Branch 142 taken 4508 times.
✗ Branch 143 not taken.
✓ Branch 144 taken 7 times.
✓ Branch 145 taken 185 times.
✗ Branch 146 not taken.
✓ Branch 147 taken 15 times.
✓ Branch 148 taken 11 times.
✓ Branch 149 taken 4654 times.
✓ Branch 150 taken 26 times.
✓ Branch 151 taken 208 times.
✓ Branch 152 taken 182 times.
✓ Branch 153 taken 27 times.
✓ Branch 154 taken 24 times.
✗ Branch 155 not taken.
✓ Branch 156 taken 1000 times.
✓ Branch 157 taken 374 times.
✓ Branch 158 taken 181 times.
✓ Branch 159 taken 893 times.
✓ Branch 160 taken 896 times.
✗ Branch 161 not taken.
✓ Branch 162 taken 728 times.
✓ Branch 163 taken 1244 times.
✓ Branch 164 taken 72 times.
✓ Branch 165 taken 3 times.
✓ Branch 166 taken 3 times.
✗ Branch 167 not taken.
✗ Branch 168 not taken.
✓ Branch 169 taken 3 times.
✗ Branch 170 not taken.
✓ Branch 171 taken 3 times.
✗ Branch 172 not taken.
✗ Branch 173 not taken.
✓ Branch 174 taken 3 times.
✓ Branch 175 taken 3 times.
✗ Branch 176 not taken.
✗ Branch 177 not taken.
✓ Branch 178 taken 3 times.
✗ Branch 179 not taken.
✓ Branch 180 taken 3 times.
✗ Branch 181 not taken.
✗ Branch 182 not taken.
✓ Branch 183 taken 3 times.
✓ Branch 184 taken 30 times.
✗ Branch 185 not taken.
✓ Branch 186 taken 3 times.
✓ Branch 187 taken 60 times.
✓ Branch 188 taken 3 times.
✓ Branch 189 taken 30 times.
✗ Branch 190 not taken.
✗ Branch 191 not taken.
✓ Branch 192 taken 123 times.
✗ Branch 193 not taken.
✗ Branch 194 not taken.
✓ Branch 195 taken 60 times.
✓ Branch 196 taken 3 times.
✗ Branch 197 not taken.
✓ Branch 198 taken 6 times.
✗ Branch 199 not taken.
✓ Branch 200 taken 6 times.
✗ Branch 201 not taken.
✓ Branch 202 taken 33 times.
✗ Branch 203 not taken.
✓ Branch 204 taken 69 times.
✗ Branch 205 not taken.
✓ Branch 206 taken 3 times.
✗ Branch 207 not taken.
✓ Branch 208 taken 9 times.
✗ Branch 209 not taken.
✓ Branch 210 taken 12 times.
✗ Branch 211 not taken.
✓ Branch 212 taken 15 times.
✗ Branch 213 not taken.
✓ Branch 214 taken 12 times.
✗ Branch 215 not taken.
✓ Branch 216 taken 12 times.
✗ Branch 217 not taken.
✓ Branch 218 taken 9 times.
✗ Branch 219 not taken.
✓ Branch 220 taken 15 times.
✗ Branch 221 not taken.
✓ Branch 222 taken 18 times.
✗ Branch 223 not taken.
✓ Branch 224 taken 15 times.
✗ Branch 225 not taken.
✓ Branch 226 taken 12 times.
✗ Branch 227 not taken.
✓ Branch 228 taken 12 times.
✗ Branch 229 not taken.
✓ Branch 230 taken 9 times.
✗ Branch 231 not taken.
✓ Branch 232 taken 12 times.
✗ Branch 233 not taken.
✓ Branch 234 taken 12 times.
✗ Branch 235 not taken.
✓ Branch 236 taken 12 times.
✗ Branch 237 not taken.
✓ Branch 238 taken 18 times.
✗ Branch 239 not taken.
✓ Branch 240 taken 18 times.
✗ Branch 241 not taken.
✓ Branch 242 taken 6 times.
✗ Branch 243 not taken.
✓ Branch 244 taken 9 times.
✗ Branch 245 not taken.
✓ Branch 246 taken 12 times.
✗ Branch 247 not taken.
✓ Branch 248 taken 15 times.
✗ Branch 249 not taken.
✓ Branch 250 taken 12 times.
✗ Branch 251 not taken.
✓ Branch 252 taken 12 times.
✗ Branch 253 not taken.
✓ Branch 254 taken 9 times.
✗ Branch 255 not taken.
✓ Branch 256 taken 15 times.
✗ Branch 257 not taken.
✓ Branch 258 taken 18 times.
✗ Branch 259 not taken.
✓ Branch 260 taken 12 times.
✗ Branch 261 not taken.
✓ Branch 262 taken 6 times.
✗ Branch 263 not taken.
✓ Branch 264 taken 9 times.
✗ Branch 265 not taken.
✓ Branch 266 taken 15 times.
✗ Branch 267 not taken.
✓ Branch 268 taken 18 times.
✗ Branch 269 not taken.
✓ Branch 270 taken 12 times.
✗ Branch 271 not taken.
✓ Branch 272 taken 6 times.
✗ Branch 273 not taken.
✓ Branch 274 taken 6 times.
✗ Branch 275 not taken.
✓ Branch 276 taken 9 times.
✗ Branch 277 not taken.
✓ Branch 278 taken 12 times.
✗ Branch 279 not taken.
✓ Branch 280 taken 15 times.
✗ Branch 281 not taken.
✓ Branch 282 taken 12 times.
✗ Branch 283 not taken.
✓ Branch 284 taken 12 times.
✗ Branch 285 not taken.
✓ Branch 286 taken 6 times.
✗ Branch 287 not taken.
✓ Branch 288 taken 9 times.
✗ Branch 289 not taken.
✓ Branch 290 taken 12 times.
✗ Branch 291 not taken.
✓ Branch 292 taken 15 times.
✗ Branch 293 not taken.
✓ Branch 294 taken 27 times.
✗ Branch 295 not taken.
✓ Branch 296 taken 27 times.
✗ Branch 297 not taken.
✓ Branch 298 taken 21 times.
✗ Branch 299 not taken.
✓ Branch 300 taken 42 times.
✗ Branch 301 not taken.
✓ Branch 302 taken 63 times.
✗ Branch 303 not taken.
✓ Branch 304 taken 63 times.
✗ Branch 305 not taken.
✓ Branch 306 taken 36 times.
✗ Branch 307 not taken.
✓ Branch 308 taken 54 times.
✗ Branch 309 not taken.
✓ Branch 310 taken 72 times.
✗ Branch 311 not taken.
✓ Branch 312 taken 90 times.
✗ Branch 313 not taken.
✓ Branch 314 taken 72 times.
✗ Branch 315 not taken.
✓ Branch 316 taken 72 times.
✗ Branch 317 not taken.
✓ Branch 318 taken 36 times.
✗ Branch 319 not taken.
✓ Branch 320 taken 54 times.
✗ Branch 321 not taken.
✓ Branch 322 taken 57 times.
✗ Branch 323 not taken.
✓ Branch 324 taken 57 times.
✗ Branch 325 not taken.
✓ Branch 326 taken 21 times.
✗ Branch 327 not taken.
✓ Branch 328 taken 21 times.
✗ Branch 329 not taken.
✓ Branch 330 taken 21 times.
✗ Branch 331 not taken.
✓ Branch 332 taken 21 times.
✗ Branch 333 not taken.
✓ Branch 334 taken 6 times.
✗ Branch 335 not taken.
✓ Branch 336 taken 6 times.
✗ Branch 337 not taken.
✓ Branch 338 taken 6 times.
✗ Branch 339 not taken.
✓ Branch 340 taken 3 times.
✗ Branch 341 not taken.
✓ Branch 342 taken 6 times.
✗ Branch 343 not taken.
✓ Branch 344 taken 6 times.
✗ Branch 345 not taken.
✓ Branch 346 taken 6 times.
✗ Branch 347 not taken.
✓ Branch 348 taken 3 times.
✗ Branch 349 not taken.
✓ Branch 350 taken 6 times.
✗ Branch 351 not taken.
✓ Branch 352 taken 3 times.
✗ Branch 353 not taken.
✓ Branch 354 taken 3 times.
✗ Branch 355 not taken.
✓ Branch 356 taken 6 times.
✗ Branch 357 not taken.
✓ Branch 358 taken 6 times.
✗ Branch 359 not taken.
✓ Branch 360 taken 3 times.
✗ Branch 361 not taken.
✓ Branch 362 taken 3 times.
✗ Branch 363 not taken.
✓ Branch 364 taken 6 times.
✗ Branch 365 not taken.
✗ Branch 366 not taken.
✗ Branch 367 not taken.
✓ Branch 368 taken 3 times.
✗ Branch 369 not taken.
✓ Branch 370 taken 3 times.
✗ Branch 371 not taken.
✓ Branch 372 taken 3 times.
✗ Branch 373 not taken.
✗ Branch 374 not taken.
✗ Branch 375 not taken.
✓ Branch 376 taken 3 times.
✗ Branch 377 not taken.
✗ Branch 378 not taken.
✗ Branch 379 not taken.
1223826 return cached_data;
32 }
33
34 char *temp_raw() const //things to cleanup and take a look at
35 {
36
4/8
✓ Branch 0 taken 98444 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4608 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1464 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 120 times.
✗ Branch 7 not taken.
121650 return cached_data;
37 }
38
39 char *raw() const
40 {
41
5/8
✓ Branch 0 taken 1398 times.
✓ Branch 1 taken 50462 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 36 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 24 times.
1946693 return cached_data;
42 }
43
44 int length() const
45 {
46 3910243 return is_inlined() ? inlined.len : allocated.len;
47 }
48
49 1831475 void set_length(int length)
50 {
51
2/2
✓ Branch 0 taken 4742 times.
✓ Branch 1 taken 1826733 times.
1831475 if(length > max_inline_length_){
52 4742 inlined.len = (unsigned char)-1;
53 4742 allocated.len = length;
54 }else{
55 1826733 inlined.len = length;
56 }
57 1831475 }
58
59 void truncate(int newlen)
60 {
61 966 resize(newlen);
62 966 }
63
64 532710 void assign(const char * newstr)
65 {
66
2/2
✓ Branch 0 taken 236 times.
✓ Branch 1 taken 532474 times.
532710 if (!newstr) newstr = "";
67 532710 assign(newstr, strlen(newstr));
68 532710 }
69
70 331163 void assign(const string &newstr)
71 {
72 331163 assign(newstr, newstr.length());
73 331163 }
74
75 935561 void assign(const char * newstr, int end)
76 {
77 935561 resize(end);
78 935561 copy(newstr, length(), cached_data);
79 935561 }
80
81
82 string& operator=(const char * newstr)
83 {
84 256424 assign(newstr);
85 6650 return *this;
86 }
87
88 string& operator=(const string &newstr)
89 {
90 55905 assign(newstr);
91 20638 return *this;
92 }
93
94 string& append(const string& other, int start, int end)
95 {
96 int current_end = length();
97 resize(length() + end - start);
98 copy(other.cached_data + start, end - start, cached_data + current_end);
99 return *this;
100 }
101
102 3174 string& append(const char *other, int start, int end)
103 {
104 int current_end = length();
105 3174 resize(length() + end - start);
106 3174 copy(other + start, end - start, cached_data + current_end);
107 3174 return *this;
108 }
109
110 76032 string& operator+=(const string& other)
111 {
112 int current_end = length();
113 76032 resize(length() + other.length());
114 152064 copy(other.cached_data, other.length(), cached_data + current_end);
115 76032 return *this;
116 }
117
118 131888 string& operator+=(const char *other)
119 {
120 int current_end = length();
121 131888 int otherlen=(int)strlen(other);
122 131888 resize(length() + otherlen);
123 131888 copy(other, otherlen, cached_data + current_end);
124 131888 return *this;
125 }
126
127 683838 string& operator+=(char c)
128 {
129 683838 resize(length() + 1);
130 1367676 cached_data[length() - 1] = c;
131 683838 return *this;
132 }
133
134 string operator+(char right) const
135 {
136 string ret=*this;
137 ret+=right;
138 return ret;
139 }
140
141 string operator+(const char * right) const
142 {
143 4188 string ret=*this;
144 8376 ret+=right;
145 652 return ret;
146 }
147
148 8940 bool operator==(const char * right) const
149 {
150 8940 return !strcmp(data(), right);
151 }
152
153 74 bool operator==(const string& right) const
154 {
155 74 return !strcmp(data(), right.data());
156 }
157
158 6794 bool operator!=(const char * right) const
159 {
160 6794 return (strcmp(data(), right) != 0);
161 }
162
163 bool operator!=(const string& right) const
164 {
165 return (strcmp(data(), right.data()) != 0);
166 }
167
168 operator const char*() const
169 {
170 return data();
171 }
172
173 12878 explicit operator bool() const
174 {
175 12878 return length();
176 }
177
178 1204222 string()
179 1204222 {
180 //todo reduce I know this isn't all needed
181 1204222 allocated.bufferlen = 0;
182 1204222 allocated.str = 0;
183 1204222 allocated.len = 0;
184 1204222 inlined.len = 0;
185 1204222 cached_data = inlined.str;
186 1204222 next_resize = max_inline_length_+1;
187
188 998219 }
189 259430 string(const char * newstr) : string()
190 {
191 259430 assign(newstr);
192 227741 }
193 60910 string(const char * newstr, int newlen) : string()
194 {
195 60910 assign(newstr, newlen);
196 60253 }
197 16856 string(const string& old) : string()
198 {
199 16856 assign(old.data());
200 16749 }
201
202 6010 string(string &&move) : string()
203 {
204 *this = move;
205 6010 }
206
207 60702 string& operator=(string&& move)
208 {
209 if(!is_inlined()) free(allocated.str);
210 60702 if(!move.is_inlined()){
211 16 allocated.str = move.allocated.str;
212 16 allocated.bufferlen = move.allocated.bufferlen;
213 16 set_length(move.allocated.len);
214
215 16 move.inlined.len = 0;
216 16 move.inlined.str[0] = 0;
217 16 cached_data = allocated.str;
218 16 next_resize = move.next_resize;
219
220 }else{
221 60686 inlined.len = 0;
222 60686 cached_data = inlined.str;
223 60686 next_resize = max_inline_length_+1;
224 60686 assign(move);
225 }
226 60702 return *this;
227 }
228
229 3147355 ~string()
230 {
231 1823247 if(!is_inlined()){
232 5469 free(allocated.str);
233 }
234 3147355 }
235
236 //maybe these should return refs to chain. but also good not to encourage chaining
237 3184 void strip_prefix(char c)
238 {
239
2/2
✓ Branch 0 taken 1296 times.
✓ Branch 1 taken 1888 times.
3184 if(cached_data[0] == c){
240 1296 *this = string(cached_data + 1, length() - 1);
241 }
242 3184 }
243
244 126 void strip_suffix(char c)
245 {
246
1/2
✓ Branch 0 taken 126 times.
✗ Branch 1 not taken.
126 if(cached_data[length() - 1] == c){
247 126 truncate(length() - 1);
248 }
249 126 }
250
251 string& qreplace(const char * instr, const char * outstr);
252 string& qnormalize();
253
254 // RPG Hacker: My hack shmeck to get around no longer supporting text mode.
255 // Symbol files are currently the only thing that use text mode, anyways, and I don't even know
256 // if the emulators that read them care about line endings.
257 string& convert_line_endings_to_native()
258 {
259 #if defined(windows)
260 // RPG Hacker: This is quite stinky, but doing the replacement directly will lead to a dead-lock.
261 // \x08 = backspace should never appear inside a string, so I'm abusing it here.
262 return qreplace("\n", "\x08").qreplace("\x08", "\r\n");
263 #else
264 return *this;
265 #endif
266 }
267
268 #ifdef SERIALIZER
269 void serialize(serializer & s)
270 {
271 s(str, allocated.bufferlen);
272 set_length(strlen(str));
273 }
274 #endif
275 #define SERIALIZER_BANNED
276
277 private:
278 static const int scale_factor = 4; //scale sso
279 static const int max_inline_length_ = ((sizeof(char *) + sizeof(int) * 2) * scale_factor) - 2;
280 char *cached_data;
281 int next_resize;
282 struct si{
283 char str[max_inline_length_ + 1];
284 unsigned char len;
285 };
286
287 struct sa{
288 char *str;
289 int len;
290 int bufferlen ;
291 };
292 union{
293 si inlined;
294 sa allocated;
295 };
296
297
298 1831459 void resize(int new_length)
299 {
300 const char *old_data = data();
301
4/4
✓ Branch 0 taken 1827765 times.
✓ Branch 1 taken 3694 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 1032 times.
1832509 if(new_length >= next_resize || (!is_inlined() && new_length <= max_inline_length_)) {
302
3/4
✓ Branch 0 taken 3694 times.
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 40 times.
3752 if(new_length > max_inline_length_ && (is_inlined() || allocated.bufferlen <= new_length)){ //SSO or big to big
303 3694 int new_size = bitround(new_length + 1);
304
2/2
✓ Branch 0 taken 3654 times.
✓ Branch 1 taken 40 times.
3694 if(old_data == inlined.str){
305
1/2
✓ Branch 0 taken 3654 times.
✗ Branch 1 not taken.
7308 allocated.str = copy(old_data, min(length(), new_length), (char *)malloc(new_size));
306 }else{
307 40 allocated.str = (char *)realloc(allocated.str, new_size);
308 old_data = inlined.str; //this will prevent freeing a dead realloc ptr
309 }
310 3694 allocated.bufferlen = new_size;
311 3694 cached_data = allocated.str;
312 3694 next_resize = allocated.bufferlen;
313
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
18 }else if(length() > max_inline_length_ && new_length <= max_inline_length_){ //big to SSO
314 18 copy(old_data, new_length, inlined.str);
315 18 cached_data = inlined.str;
316 18 next_resize = max_inline_length_+1;
317 }
318
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 3694 times.
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
3712 if(old_data != inlined.str && old_data != data()){
319 18 free((char *)old_data);
320 }
321 }
322 1831459 set_length(new_length);
323
324 1831459 raw()[new_length] = 0; //always ensure null terminator
325 1831459 }
326
327 bool is_inlined() const
328 {
329
30/34
✓ Branch 0 taken 463304 times.
✓ Branch 1 taken 1308 times.
✓ Branch 2 taken 412018 times.
✓ Branch 3 taken 1828023 times.
✓ Branch 4 taken 6518 times.
✓ Branch 5 taken 3654 times.
✓ Branch 6 taken 126 times.
✓ Branch 7 taken 18 times.
✓ Branch 8 taken 32822 times.
✓ Branch 9 taken 14140 times.
✓ Branch 10 taken 35168 times.
✓ Branch 11 taken 1174301 times.
✓ Branch 12 taken 108842 times.
✓ Branch 13 taken 45682 times.
✓ Branch 14 taken 512574 times.
✓ Branch 15 taken 43950 times.
✓ Branch 16 taken 515014 times.
✓ Branch 17 taken 880 times.
✓ Branch 18 taken 181536 times.
✓ Branch 19 taken 498 times.
✓ Branch 20 taken 168270 times.
✓ Branch 21 taken 600 times.
✓ Branch 22 taken 58191 times.
✓ Branch 23 taken 346 times.
✓ Branch 24 taken 982035 times.
✓ Branch 25 taken 2392 times.
✓ Branch 26 taken 371038 times.
✓ Branch 27 taken 950 times.
✓ Branch 28 taken 44834 times.
✓ Branch 29 taken 266 times.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
6948596 return inlined.len != (unsigned char)-1;
330 }
331 };
332 #define STR (string)
333
334 char * readfile(const char * fname, const char * basepath);
335 char * readfilenative(const char * fname);
336 bool readfile(const char * fname, const char * basepath, char ** data, int * len);//if you want an uchar*, cast it
337 char ** split(char * str, char key, int * len= nullptr);
338 char ** qsplit(char * str, char key, int * len= nullptr);
339 char ** qpsplit(char * str, char key, int * len= nullptr);
340 char ** qsplitstr(char * str, const char * key, int * len= nullptr);
341 bool confirmquotes(const char * str);
342 bool confirmqpar(const char * str);
343 char* strqpchr(char* str, char key);
344 char* strqpstr(char* str, const char* key);
345
346 6 inline string hex(unsigned int value)
347 {
348 char buffer[64];
349 if(0);
350
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 else if (value<=0x000000FF) sprintf(buffer, "%.2X", value);
351
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 else if (value<=0x0000FFFF) sprintf(buffer, "%.4X", value);
352 else if (value<=0x00FFFFFF) sprintf(buffer, "%.6X", value);
353 else sprintf(buffer, "%.8X", value);
354 6 return buffer;
355 }
356
357 8 inline string hex(unsigned int value, int width)
358 {
359 char buffer[64];
360 8 sprintf(buffer, "%.*X", width, value);
361 8 return buffer;
362 }
363
364 2020 inline string dec(int value)
365 {
366 char buffer[64];
367 2020 sprintf(buffer, "%i", value);
368 2020 return buffer;
369 }
370
371 2166 inline string ftostr(double value)
372 {
373 // randomdude999: With 100 digits of precision, the buffer needs to be approx. 311+100,
374 // but let's be safe here https://stackoverflow.com/questions/7235456
375 char rval[512];
376 // RPG Hacker: Ridiculously high precision, I know, but we're working with doubles
377 // here and can afford it, so no need to waste any precision
378
1/2
✓ Branch 0 taken 1083 times.
✗ Branch 1 not taken.
2166 sprintf(rval, "%.100f", value);
379
1/2
✓ Branch 0 taken 2166 times.
✗ Branch 1 not taken.
2166 if (strchr(rval, '.'))//nuke useless zeroes
380 {
381 2166 char * end=strrchr(rval, '\0')-1;
382
2/2
✓ Branch 0 taken 216252 times.
✓ Branch 1 taken 2166 times.
218418 while (*end=='0')
383 {
384 216252 *end='\0';
385 216252 end--;
386 }
387
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 6 times.
2166 if (*end=='.') *end='\0';
388 }
389 2166 return rval;
390 }
391
392 // Same as above, but with variable precision
393 46 inline string ftostrvar(double value, int precision)
394 {
395 int clampedprecision = precision;
396 if (clampedprecision < 0) clampedprecision = 0;
397 46 if (clampedprecision > 100) clampedprecision = 100;
398
399 // see above
400 char rval[512];
401
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 1 times.
46 sprintf(rval, "%.*f", clampedprecision, (double)value);
402
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 2 times.
46 if (strchr(rval, '.'))//nuke useless zeroes
403 {
404 44 char * end = strrchr(rval, '\0') - 1;
405
2/2
✓ Branch 0 taken 138 times.
✓ Branch 1 taken 44 times.
182 while (*end == '0')
406 {
407 138 *end = '\0';
408 138 end--;
409 }
410
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 26 times.
44 if (*end == '.') *end = '\0';
411 }
412 46 return rval;
413 }
414
415 99018 inline bool stribegin(const char * str, const char * key)
416 {
417
2/2
✓ Branch 0 taken 122710 times.
✓ Branch 1 taken 7540 times.
130250 for (int i=0;key[i];i++)
418 {
419
2/2
✓ Branch 0 taken 31232 times.
✓ Branch 1 taken 91478 times.
122710 if (to_lower(str[i])!=to_lower(key[i])) return false;
420 }
421 return true;
422 }
423
424
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 3771 times.
7758 inline bool striend(const char * str, const char * key)
425 {
426 3879 const char * keyend=strrchr(key, '\0');
427 3879 const char * strend=strrchr(str, '\0');
428
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 7542 times.
7758 if(keyend-key > strend-str) return false;
429
430
2/2
✓ Branch 0 taken 8886 times.
✓ Branch 1 taken 966 times.
9852 while (key!=keyend)
431 {
432 8886 keyend--;
433 8886 strend--;
434
2/2
✓ Branch 0 taken 6576 times.
✓ Branch 1 taken 2310 times.
8886 if (to_lower(*strend)!=to_lower(*keyend)) return false;
435 }
436 return true;
437 }
438
439 101804 inline bool stricmpwithupper(const char *word1, const char *word2)
440 {
441
2/2
✓ Branch 0 taken 114996 times.
✓ Branch 1 taken 3782 times.
118778 while(*word2)
442 {
443
2/2
✓ Branch 0 taken 16974 times.
✓ Branch 1 taken 98022 times.
114996 if(to_upper(*word1++) != *word2++) return true;
444 }
445 3782 return *word1;
446 }
447
448 507936 inline bool stricmpwithlower(const char *word1, const char *word2)
449 {
450
2/2
✓ Branch 0 taken 719344 times.
✓ Branch 1 taken 35786 times.
755130 while(*word2)
451 {
452
2/2
✓ Branch 0 taken 247194 times.
✓ Branch 1 taken 472150 times.
719344 if(to_lower(*word1++) != *word2++) return true;
453 }
454 35786 return *word1;
455 }
456
457 //function: return the string without quotes around it, if any exists
458 //if they don't exist, return it unaltered
459 //it is not guaranteed to return str
460 //it is not guaranteed to not edit str
461 //the input must be freed even though it's garbage, the output must not
462 7390 inline const char * dequote(char * str)
463 {
464
2/2
✓ Branch 0 taken 6646 times.
✓ Branch 1 taken 744 times.
7390 if (*str!='"') return str;
465 5573 char *end = strrchr(str, '"');
466
1/2
✓ Branch 0 taken 6646 times.
✗ Branch 1 not taken.
6646 if (end)
467 {
468 6646 *end = 0;
469 6646 char *quote = str+1;
470
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 6646 times.
6790 while((quote = strstr(quote, "\"\""))) memmove(quote, quote+1, strlen(quote));
471 return str + 1;
472 }
473 return nullptr;
474 }
475
476 11634 inline char * strqchr(const char * str, char key)
477 {
478
2/2
✓ Branch 0 taken 110758 times.
✓ Branch 1 taken 8118 times.
118876 while (*str != '\0')
479 {
480
2/2
✓ Branch 0 taken 3514 times.
✓ Branch 1 taken 107244 times.
110758 if (*str == key) { return const_cast<char*>(str); }
481
4/4
✓ Branch 0 taken 106646 times.
✓ Branch 1 taken 598 times.
✓ Branch 2 taken 178 times.
✓ Branch 3 taken 106468 times.
107244 else if (*str == '"' || *str == '\'')
482 {
483 // Special case hack for ''', which is currently our official way of handling the ' character.
484 // Even though it really stinks.
485
5/6
✓ Branch 0 taken 178 times.
✓ Branch 1 taken 598 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 168 times.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
776 if (str[0] == '\'' && str[1] == '\'' && str[2] == '\'') { str += 2; }
486 else
487 {
488 char delimiter = *str;
489
490 do
491 {
492 9074 str++;
493
494 // If we want to support backslash escapes, we'll have to add that right here.
495
4/4
✓ Branch 0 taken 8310 times.
✓ Branch 1 taken 764 times.
✓ Branch 2 taken 8308 times.
✓ Branch 3 taken 2 times.
9074 } while (*str != delimiter && *str != '\0');
496
497 // This feels like a superfluous check, but I can't really find a clean way to avoid it.
498
2/2
✓ Branch 0 taken 764 times.
✓ Branch 1 taken 2 times.
766 if (*str == '\0') { return nullptr; }
499 }
500 }
501
502 107242 str++;
503 }
504
505 return nullptr;
506 }
507
508 inline string substr(const char * str, int len)
509 {
510 1276 return string(str, len);
511 }
512
513 //todo make these members
514 string &strip_prefix(string &str, char c);
515 string &strip_suffix(string &str, char c);
516
517
518 65390 inline char *strip_whitespace(char *str)
519 {
520
2/2
✓ Branch 0 taken 3796 times.
✓ Branch 1 taken 65390 times.
69186 while(is_space(*str)) str++;
521
2/2
✓ Branch 0 taken 61686 times.
✓ Branch 1 taken 19816 times.
81502 for(int i = strlen(str) - 1; i >= 0; i--)
522 {
523
2/2
✓ Branch 0 taken 45574 times.
✓ Branch 1 taken 16112 times.
61686 if(!is_space(str[i]))
524 {
525 45574 str[i + 1] = 0;
526 45574 return str;
527 }
528 }
529 return str;
530 }
531 3320 inline void strip_whitespace(string &str)
532 {
533 4980 str = string(strip_whitespace(str.temp_raw()));
534 3320 }
535
536 string &itrim(string &str, const char * left, const char * right);
537
538
2/2
✓ Branch 0 taken 11341 times.
✓ Branch 1 taken 6 times.
11347 inline string &lower(string &old)
539 {
540 int length = old.length();
541
2/2
✓ Branch 0 taken 319751 times.
✓ Branch 1 taken 11347 times.
331098 for (int i=0;i<length;i++) old.raw()[i]=(char)to_lower(old.data()[i]);
542 11347 return old;
543 }
544
545
546 // Returns number of connected lines - 1
547 template<typename stringarraytype>
548 44766 inline int getconnectedlines(stringarraytype& lines, int startline, string& out)
549 {
550 int count = 0;
551
552
1/2
✓ Branch 0 taken 44784 times.
✗ Branch 1 not taken.
44784 for (int i = startline; lines[i]; i++)
553 {
554 // The line should already be stripped of any comments at this point
555 44784 int linestartpos = (int)strlen(lines[i]);
556
557
4/4
✓ Branch 0 taken 32560 times.
✓ Branch 1 taken 12224 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 32542 times.
44784 if(linestartpos && lines[i][linestartpos - 1] == '\\')
558 {
559 18 count++;
560 18 out += string(lines[i], linestartpos - 1);
561 continue;
562 }
563 else
564 {
565 44766 out += string(lines[i], linestartpos);
566 44766 return count;
567 }
568 }
569
570 return count;
571 }
572