asar coverage - build #148


src/asar/
File: src/asar/libstr.h
Date: 2024-01-24 00:08:41
Lines:
230/238
96.6%
Functions:
54/55
98.2%
Branches:
424/635
66.8%

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 5803341 static inline int to_lower(unsigned char c) { return c|(char_props[c]&0x20); }
9 static inline int to_upper(unsigned char c) { return c&~(char_props[c]&0x20); }
10
11
10/10
✓ Branch 0 taken 74190 times.
✓ Branch 1 taken 29100 times.
✓ Branch 2 taken 74100 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 288 times.
✓ Branch 5 taken 90 times.
✓ Branch 6 taken 2583 times.
✓ Branch 7 taken 6621 times.
✓ Branch 8 taken 2637 times.
✓ Branch 9 taken 2583 times.
769320 inline bool is_space(unsigned char c) { return char_props[c] & 0x80; } // C standard says \f \v are space, but this one disagrees
12 150809 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 5166 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 41586 inline bool is_ualpha(unsigned char c) { return char_props[c] & 0x28; }
18 397626 inline bool is_ualnum(unsigned char c) { return char_props[c] & 0x68; }
19
4/4
✓ Branch 0 taken 9504 times.
✓ Branch 1 taken 10293 times.
✓ Branch 2 taken 756 times.
✓ Branch 3 taken 261 times.
41680 inline bool is_xdigit(unsigned char c) { return char_props[c] & 0x01; }
20
21 1967918 inline char *copy(const char *source, int copy_length, char *dest)
22 {
23 4515789 memcpy(dest, source, copy_length*sizeof(char));
24 1967918 return dest;
25 }
26
27 class string {
28 public:
29 7080607 const char *data() const
30 {
31
226/367
✓ Branch 0 taken 5066 times.
✓ Branch 1 taken 971377 times.
✓ Branch 2 taken 955812 times.
✓ Branch 3 taken 3078 times.
✓ Branch 4 taken 5227 times.
✓ Branch 5 taken 2205 times.
✓ Branch 6 taken 15654 times.
✓ Branch 7 taken 4070 times.
✓ Branch 8 taken 15887 times.
✓ Branch 9 taken 5439 times.
✓ Branch 10 taken 1665 times.
✓ Branch 11 taken 2415 times.
✓ Branch 12 taken 1152 times.
✓ Branch 13 taken 206 times.
✓ Branch 14 taken 1596 times.
✓ Branch 15 taken 476 times.
✓ Branch 16 taken 11384 times.
✓ Branch 17 taken 434 times.
✓ Branch 18 taken 504 times.
✓ Branch 19 taken 1060 times.
✓ Branch 20 taken 210 times.
✓ Branch 21 taken 5306 times.
✓ Branch 22 taken 1181 times.
✓ Branch 23 taken 382 times.
✓ Branch 24 taken 369 times.
✓ Branch 25 taken 144 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 668 times.
✓ Branch 28 taken 551 times.
✓ Branch 29 taken 108 times.
✓ Branch 30 taken 238 times.
✓ Branch 31 taken 540 times.
✓ Branch 32 taken 216 times.
✓ Branch 33 taken 80709 times.
✓ Branch 34 taken 48 times.
✓ Branch 35 taken 828 times.
✓ Branch 36 taken 1404 times.
✓ Branch 37 taken 84624 times.
✓ Branch 38 taken 783 times.
✓ Branch 39 taken 4952 times.
✓ Branch 40 taken 18 times.
✓ Branch 41 taken 5751 times.
✓ Branch 42 taken 3 times.
✓ Branch 43 taken 51 times.
✓ Branch 44 taken 48 times.
✗ Branch 45 not taken.
✓ Branch 46 taken 51 times.
✓ Branch 47 taken 164 times.
✗ Branch 48 not taken.
✓ Branch 49 taken 33 times.
✓ Branch 50 taken 1141 times.
✓ Branch 51 taken 3 times.
✓ Branch 52 taken 1215 times.
✓ Branch 53 taken 65216 times.
✓ Branch 54 taken 15009 times.
✓ Branch 55 taken 114 times.
✗ Branch 56 not taken.
✓ Branch 57 taken 520 times.
✓ Branch 58 taken 15794 times.
✗ Branch 59 not taken.
✓ Branch 60 taken 409 times.
✓ Branch 61 taken 108 times.
✓ Branch 62 taken 152 times.
✗ Branch 63 not taken.
✓ Branch 64 taken 59775 times.
✓ Branch 65 taken 15012 times.
✓ Branch 66 taken 119 times.
✓ Branch 67 taken 39 times.
✗ Branch 68 not taken.
✓ Branch 69 taken 90 times.
✓ Branch 70 taken 82755 times.
✓ Branch 71 taken 9 times.
✓ Branch 72 taken 9 times.
✓ Branch 73 taken 67377 times.
✓ Branch 74 taken 15474 times.
✗ Branch 75 not taken.
✓ Branch 76 taken 192 times.
✓ Branch 77 taken 9 times.
✗ Branch 78 not taken.
✓ Branch 79 taken 201 times.
✓ Branch 80 taken 18 times.
✓ Branch 81 taken 4236 times.
✓ Branch 82 taken 71 times.
✓ Branch 83 taken 771 times.
✓ Branch 84 taken 342 times.
✓ Branch 85 taken 21 times.
✓ Branch 86 taken 153 times.
✗ Branch 87 not taken.
✓ Branch 88 taken 46 times.
✓ Branch 89 taken 153 times.
✗ Branch 90 not taken.
✓ Branch 91 taken 142 times.
✓ Branch 92 taken 81 times.
✗ Branch 93 not taken.
✓ Branch 94 taken 169 times.
✓ Branch 95 taken 81 times.
✗ Branch 96 not taken.
✓ Branch 97 taken 133 times.
✓ Branch 98 taken 2889 times.
✓ Branch 99 taken 9 times.
✓ Branch 100 taken 33 times.
✓ Branch 101 taken 3117 times.
✓ Branch 102 taken 15000 times.
✓ Branch 103 taken 45 times.
✓ Branch 104 taken 2934 times.
✗ Branch 105 not taken.
✓ Branch 106 taken 51 times.
✓ Branch 107 taken 45 times.
✗ Branch 108 not taken.
✓ Branch 109 taken 10840 times.
✓ Branch 110 taken 72 times.
✓ Branch 111 taken 10828 times.
✓ Branch 112 taken 9 times.
✓ Branch 113 taken 18 times.
✓ Branch 114 taken 15568 times.
✗ Branch 115 not taken.
✗ Branch 116 not taken.
✓ Branch 117 taken 11 times.
✓ Branch 118 taken 349 times.
✗ Branch 119 not taken.
✓ Branch 120 taken 9 times.
✗ Branch 121 not taken.
✓ Branch 122 taken 15462 times.
✓ Branch 123 taken 54 times.
✗ Branch 124 not taken.
✓ Branch 125 taken 54 times.
✓ Branch 126 taken 9 times.
✓ Branch 127 taken 54 times.
✗ Branch 128 not taken.
✓ Branch 129 taken 12 times.
✓ Branch 130 taken 141 times.
✗ Branch 131 not taken.
✗ Branch 132 not taken.
✗ Branch 133 not taken.
✗ Branch 134 not taken.
✓ Branch 135 taken 9 times.
✗ Branch 136 not taken.
✓ Branch 137 taken 9 times.
✓ Branch 138 taken 12 times.
✗ Branch 139 not taken.
✓ Branch 140 taken 9692 times.
✗ Branch 141 not taken.
✓ Branch 142 taken 3 times.
✓ Branch 143 taken 583 times.
✗ Branch 144 not taken.
✓ Branch 145 taken 9 times.
✓ Branch 146 taken 577 times.
✓ Branch 147 taken 6 times.
✓ Branch 148 taken 571 times.
✗ Branch 149 not taken.
✓ Branch 150 taken 12 times.
✗ Branch 151 not taken.
✓ Branch 152 taken 1834 times.
✓ Branch 153 taken 237 times.
✗ Branch 154 not taken.
✗ Branch 155 not taken.
✗ Branch 156 not taken.
✓ Branch 157 taken 9 times.
✗ Branch 158 not taken.
✓ Branch 159 taken 12 times.
✗ Branch 160 not taken.
✗ Branch 161 not taken.
✗ Branch 162 not taken.
✓ Branch 163 taken 9 times.
✗ Branch 164 not taken.
✓ Branch 165 taken 9 times.
✗ Branch 166 not taken.
✓ Branch 167 taken 3 times.
✗ Branch 168 not taken.
✓ Branch 169 taken 9 times.
✗ Branch 170 not taken.
✓ Branch 171 taken 9 times.
✗ Branch 172 not taken.
✗ Branch 173 not taken.
✗ Branch 174 not taken.
✓ Branch 175 taken 93 times.
✗ Branch 176 not taken.
✓ Branch 177 taken 189 times.
✗ Branch 178 not taken.
✓ Branch 179 taken 180 times.
✗ Branch 180 not taken.
✓ Branch 181 taken 9 times.
✗ Branch 182 not taken.
✓ Branch 183 taken 3 times.
✗ Branch 184 not taken.
✓ Branch 185 taken 72 times.
✗ Branch 186 not taken.
✓ Branch 187 taken 180 times.
✗ Branch 188 not taken.
✗ Branch 189 not taken.
✗ Branch 190 not taken.
✓ Branch 191 taken 12 times.
✗ Branch 192 not taken.
✓ Branch 193 taken 9 times.
✗ Branch 194 not taken.
✓ Branch 195 taken 18 times.
✗ Branch 196 not taken.
✓ Branch 197 taken 27 times.
✗ Branch 198 not taken.
✓ Branch 199 taken 51 times.
✗ Branch 200 not taken.
✓ Branch 201 taken 33 times.
✗ Branch 202 not taken.
✓ Branch 203 taken 42 times.
✗ Branch 204 not taken.
✓ Branch 205 taken 51 times.
✗ Branch 206 not taken.
✓ Branch 207 taken 51 times.
✗ Branch 208 not taken.
✓ Branch 209 taken 45 times.
✗ Branch 210 not taken.
✓ Branch 211 taken 33 times.
✗ Branch 212 not taken.
✓ Branch 213 taken 90 times.
✗ Branch 214 not taken.
✓ Branch 215 taken 105 times.
✗ Branch 216 not taken.
✓ Branch 217 taken 279 times.
✓ Branch 218 taken 3 times.
✓ Branch 219 taken 81 times.
✗ Branch 220 not taken.
✓ Branch 221 taken 99 times.
✗ Branch 222 not taken.
✓ Branch 223 taken 99 times.
✗ Branch 224 not taken.
✓ Branch 225 taken 84 times.
✓ Branch 226 taken 3 times.
✓ Branch 227 taken 81 times.
✗ Branch 228 not taken.
✓ Branch 229 taken 1170 times.
✓ Branch 230 taken 35235 times.
✓ Branch 231 taken 5913 times.
✓ Branch 232 taken 30627 times.
✓ Branch 233 taken 18 times.
✓ Branch 234 taken 5889 times.
✓ Branch 235 taken 24 times.
✓ Branch 236 taken 27 times.
✓ Branch 237 taken 24 times.
✗ Branch 238 not taken.
✓ Branch 239 taken 27 times.
✗ Branch 240 not taken.
✓ Branch 241 taken 9 times.
✗ Branch 242 not taken.
✓ Branch 243 taken 18 times.
✗ Branch 244 not taken.
✓ Branch 245 taken 27 times.
✗ Branch 246 not taken.
✓ Branch 247 taken 27 times.
✗ Branch 248 not taken.
✓ Branch 249 taken 9 times.
✗ Branch 250 not taken.
✓ Branch 251 taken 9 times.
✗ Branch 252 not taken.
✓ Branch 253 taken 18 times.
✗ Branch 254 not taken.
✓ Branch 255 taken 27 times.
✗ Branch 256 not taken.
✓ Branch 257 taken 27 times.
✗ Branch 258 not taken.
✓ Branch 259 taken 9 times.
✗ Branch 260 not taken.
✓ Branch 261 taken 9 times.
✗ Branch 262 not taken.
✓ Branch 263 taken 18 times.
✗ Branch 264 not taken.
✓ Branch 265 taken 27 times.
✗ Branch 266 not taken.
✓ Branch 267 taken 27 times.
✗ Branch 268 not taken.
✓ Branch 269 taken 27 times.
✗ Branch 270 not taken.
✓ Branch 271 taken 27 times.
✗ Branch 272 not taken.
✓ Branch 273 taken 9 times.
✗ Branch 274 not taken.
✓ Branch 275 taken 9 times.
✗ Branch 276 not taken.
✓ Branch 277 taken 9 times.
✗ Branch 278 not taken.
✓ Branch 279 taken 18 times.
✗ Branch 280 not taken.
✓ Branch 281 taken 27 times.
✗ Branch 282 not taken.
✓ Branch 283 taken 27 times.
✗ Branch 284 not taken.
✓ Branch 285 taken 9 times.
✗ Branch 286 not taken.
✓ Branch 287 taken 18 times.
✗ Branch 288 not taken.
✓ Branch 289 taken 27 times.
✗ Branch 290 not taken.
✓ Branch 291 taken 27 times.
✗ Branch 292 not taken.
✓ Branch 293 taken 54 times.
✗ Branch 294 not taken.
✓ Branch 295 taken 54 times.
✗ Branch 296 not taken.
✓ Branch 297 taken 54 times.
✗ Branch 298 not taken.
✓ Branch 299 taken 108 times.
✗ Branch 300 not taken.
✓ Branch 301 taken 162 times.
✗ Branch 302 not taken.
✓ Branch 303 taken 162 times.
✗ Branch 304 not taken.
✓ Branch 305 taken 54 times.
✗ Branch 306 not taken.
✓ Branch 307 taken 108 times.
✗ Branch 308 not taken.
✓ Branch 309 taken 162 times.
✗ Branch 310 not taken.
✓ Branch 311 taken 162 times.
✗ Branch 312 not taken.
✓ Branch 313 taken 54 times.
✗ Branch 314 not taken.
✓ Branch 315 taken 54 times.
✗ Branch 316 not taken.
✓ Branch 317 taken 54 times.
✗ Branch 318 not taken.
✓ Branch 319 taken 54 times.
✗ Branch 320 not taken.
✓ Branch 321 taken 9 times.
✗ Branch 322 not taken.
✓ Branch 323 taken 9 times.
✗ Branch 324 not taken.
✓ Branch 325 taken 9 times.
✗ Branch 326 not taken.
✓ Branch 327 taken 9 times.
✗ Branch 328 not taken.
✓ Branch 329 taken 9 times.
✗ Branch 330 not taken.
✓ Branch 331 taken 9 times.
✗ Branch 332 not taken.
✓ Branch 333 taken 9 times.
✗ Branch 334 not taken.
✓ Branch 335 taken 9 times.
✗ Branch 336 not taken.
✓ Branch 337 taken 9 times.
✗ Branch 338 not taken.
✗ Branch 339 not taken.
✗ Branch 340 not taken.
✓ Branch 341 taken 9 times.
✗ Branch 342 not taken.
✓ Branch 343 taken 9 times.
✗ Branch 344 not taken.
✓ Branch 345 taken 9 times.
✗ Branch 346 not taken.
✗ Branch 347 not taken.
✗ Branch 348 not taken.
✓ Branch 349 taken 9 times.
✗ Branch 350 not taken.
✓ Branch 351 taken 9 times.
✗ Branch 352 not taken.
✗ Branch 353 not taken.
✗ Branch 354 not taken.
✓ Branch 355 taken 9 times.
✗ Branch 356 not taken.
✓ Branch 357 taken 9 times.
✗ Branch 358 not taken.
✓ Branch 359 taken 9 times.
✗ Branch 360 not taken.
✗ Branch 361 not taken.
✗ Branch 362 not taken.
✓ Branch 363 taken 9 times.
✗ Branch 364 not taken.
✗ Branch 365 not taken.
✗ Branch 366 not taken.
10114162 return cached_data;
32 }
33
34 184727 char *temp_raw() const //things to cleanup and take a look at
35 {
36
4/8
✓ Branch 0 taken 162912 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7068 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2259 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 180 times.
✗ Branch 7 not taken.
394528 return cached_data;
37 }
38
39 3278383 char *raw() const
40 {
41
5/8
✓ Branch 0 taken 2106 times.
✓ Branch 1 taken 83385 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 54 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 36 times.
7368859 return cached_data;
42 }
43
44 6849336 int length() const
45 {
46
2/2
✓ Branch 0 taken 6697219 times.
✓ Branch 1 taken 152117 times.
15616782 return is_inlined() ? inlined.len : allocated.len;
47 }
48
49 6837158 void set_length(int length)
50 {
51
2/2
✓ Branch 0 taken 38561 times.
✓ Branch 1 taken 6798597 times.
6837158 if(length > max_inline_length_){
52 38561 inlined.len = (unsigned char)-1;
53 38561 allocated.len = length;
54 }else{
55 6798597 inlined.len = length;
56 }
57 6837158 }
58
59 1188 void truncate(int newlen)
60 {
61 2376 resize(newlen);
62 2376 }
63
64 1997976 void assign(const char * newstr)
65 {
66
2/2
✓ Branch 0 taken 12073 times.
✓ Branch 1 taken 1985903 times.
1997976 if (!newstr) newstr = "";
67 1997976 assign(newstr, strlen(newstr));
68 1997976 }
69
70 1342318 void assign(const string &newstr)
71 {
72 1342318 assign(newstr, newstr.length());
73 1342318 }
74
75 3597943 void assign(const char * newstr, int end)
76 {
77 3597943 resize(end);
78 3597943 copy(newstr, length(), cached_data);
79 3597943 }
80
81
82 358578 string& operator=(const char * newstr)
83 {
84 799217 assign(newstr);
85 367892 return *this;
86 }
87
88 421795 string& operator=(const string &newstr)
89 {
90 549057 assign(newstr);
91 453524 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 9564 string& append(const char *other, int start, int end)
103 {
104 4785 int current_end = length();
105 9564 resize(length() + end - start);
106 9564 copy(other + start, end - start, cached_data + current_end);
107 9564 return *this;
108 }
109
110 216840 string& operator+=(const string& other)
111 {
112 84738 int current_end = length();
113 216840 resize(length() + other.length());
114 348942 copy(other.cached_data, other.length(), cached_data + current_end);
115 216840 return *this;
116 }
117
118 670010 string& operator+=(const char *other)
119 {
120 290235 int current_end = length();
121 670010 int otherlen=(int)strlen(other);
122 670010 resize(length() + otherlen);
123 670010 copy(other, otherlen, cached_data + current_end);
124 670010 return *this;
125 }
126
127 2340197 string& operator+=(char c)
128 {
129 2340197 resize(length() + 1);
130 3696874 cached_data[length() - 1] = c;
131 2340197 return *this;
132 }
133
134 string operator+(char right) const
135 {
136 string ret=*this;
137 ret+=right;
138 return ret;
139 }
140
141 56990 string operator+(const char * right) const
142 {
143 56990 string ret=*this;
144
1/2
✓ Branch 0 taken 56990 times.
✗ Branch 1 not taken.
148261 ret+=right;
145 62586 return ret;
146 }
147
148 20774 bool operator==(const char * right) const
149 {
150 20774 return !strcmp(data(), right);
151 }
152
153 222 bool operator==(const string& right) const
154 {
155 222 return !strcmp(data(), right.data());
156 }
157
158 27654 bool operator!=(const char * right) const
159 {
160 27654 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 3833374 operator const char*() const
169 {
170 3833374 return data();
171 }
172
173 35484 explicit operator bool() const
174 {
175 35484 return length();
176 }
177
178 4464383 string()
179 4464383 {
180 //todo reduce I know this isn't all needed
181 4464383 allocated.bufferlen = 0;
182 4464383 allocated.str = 0;
183 4464383 allocated.len = 0;
184 4464383 inlined.len = 0;
185 4464383 cached_data = inlined.str;
186 4464383 next_resize = max_inline_length_+1;
187
188 3487786 }
189 1001871 string(const char * newstr) : string()
190 {
191
1/2
✓ Branch 0 taken 457760 times.
✗ Branch 1 not taken.
1001871 assign(newstr);
192 906217 }
193 224973 string(const char * newstr, int newlen) : string()
194 {
195
1/2
✓ Branch 0 taken 102924 times.
✗ Branch 1 not taken.
224973 assign(newstr, newlen);
196 224946 }
197 196888 string(const string& old) : string()
198 {
199
1/2
✓ Branch 0 taken 81338 times.
✗ Branch 1 not taken.
196888 assign(old.data());
200 196567 }
201
202 25023 string(string &&move) : string()
203 {
204
1/2
✓ Branch 0 taken 9297 times.
✗ Branch 1 not taken.
9297 *this = move;
205 25023 }
206
207 389107 string& operator=(string&& move)
208 {
209
2/2
✓ Branch 0 taken 82 times.
✓ Branch 1 taken 138662 times.
138826 if(!is_inlined()) free(allocated.str);
210
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 138636 times.
389107 if(!move.is_inlined()){
211 228 allocated.str = move.allocated.str;
212 228 allocated.bufferlen = move.allocated.bufferlen;
213 228 set_length(move.allocated.len);
214
215 228 move.inlined.len = 0;
216 228 move.inlined.str[0] = 0;
217 228 cached_data = allocated.str;
218 228 next_resize = move.next_resize;
219
220 }else{
221 388879 inlined.len = 0;
222 388879 cached_data = inlined.str;
223 388879 next_resize = max_inline_length_+1;
224 388879 assign(move);
225 }
226 389107 return *this;
227 }
228
229 11017220 ~string()
230 {
231
2/2
✓ Branch 0 taken 8848 times.
✓ Branch 1 taken 1917656 times.
6471862 if(!is_inlined()){
232 29560 free(allocated.str);
233 }
234 11017220 }
235
236 //maybe these should return refs to chain. but also good not to encourage chaining
237 5005 void strip_prefix(char c)
238 {
239
2/2
✓ Branch 0 taken 1430 times.
✓ Branch 1 taken 3575 times.
5005 if(cached_data[0] == c){
240
3/6
✓ Branch 0 taken 716 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 716 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 716 times.
✗ Branch 5 not taken.
1430 *this = string(cached_data + 1, length() - 1);
241 }
242 5005 }
243
244 void strip_suffix(char c)
245 {
246 if(cached_data[length() - 1] == c){
247 truncate(length() - 1);
248 }
249 }
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 6836930 void resize(int new_length)
299 {
300 2941852 const char *old_data = data();
301
8/8
✓ Branch 0 taken 6815741 times.
✓ Branch 1 taken 21189 times.
✓ Branch 2 taken 8580 times.
✓ Branch 3 taken 2932704 times.
✓ Branch 4 taken 922 times.
✓ Branch 5 taken 7549 times.
✓ Branch 6 taken 11194 times.
✓ Branch 7 taken 2930658 times.
6846634 if(new_length >= next_resize || (!is_inlined() && new_length <= max_inline_length_)) {
302
7/8
✓ Branch 0 taken 21189 times.
✓ Branch 1 taken 1031 times.
✓ Branch 2 taken 420 times.
✓ Branch 3 taken 10220 times.
✓ Branch 4 taken 420 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 10272 times.
✓ Branch 7 taken 922 times.
22588 if(new_length > max_inline_length_ && (is_inlined() || allocated.bufferlen <= new_length)){ //SSO or big to big
303 21189 int new_size = bitround(new_length + 1);
304
2/2
✓ Branch 0 taken 20401 times.
✓ Branch 1 taken 788 times.
21189 if(old_data == inlined.str){
305
1/2
✓ Branch 0 taken 10549 times.
✗ Branch 1 not taken.
30950 allocated.str = copy(old_data, min(length(), new_length), (char *)malloc(new_size));
306 }else{
307 788 allocated.str = (char *)realloc(allocated.str, new_size);
308 420 old_data = inlined.str; //this will prevent freeing a dead realloc ptr
309 }
310 21189 allocated.bufferlen = new_size;
311 21189 cached_data = allocated.str;
312 21189 next_resize = allocated.bufferlen;
313
5/6
✓ Branch 0 taken 922 times.
✓ Branch 1 taken 109 times.
✓ Branch 2 taken 922 times.
✓ Branch 3 taken 109 times.
✓ Branch 4 taken 922 times.
✗ Branch 5 not taken.
1031 }else if(length() > max_inline_length_ && new_length <= max_inline_length_){ //big to SSO
314 1031 copy(old_data, new_length, inlined.str);
315 1031 cached_data = inlined.str;
316 1031 next_resize = max_inline_length_+1;
317 }
318
5/6
✓ Branch 0 taken 1031 times.
✓ Branch 1 taken 21189 times.
✓ Branch 2 taken 1031 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 922 times.
✓ Branch 5 taken 10272 times.
22220 if(old_data != inlined.str && old_data != data()){
319 1031 free((char *)old_data);
320 }
321 }
322 6836930 set_length(new_length);
323
324 6836930 raw()[new_length] = 0; //always ensure null terminator
325 6836930 }
326
327 11995180 bool is_inlined() const
328 {
329
52/82
✓ Branch 0 taken 1157816 times.
✓ Branch 1 taken 2672560 times.
✓ Branch 2 taken 993703 times.
✓ Branch 3 taken 1215818 times.
✓ Branch 4 taken 15592 times.
✓ Branch 5 taken 1948 times.
✓ Branch 6 taken 357 times.
✓ Branch 7 taken 9 times.
✓ Branch 8 taken 40681 times.
✓ Branch 9 taken 1609989 times.
✓ Branch 10 taken 33728 times.
✓ Branch 11 taken 865951 times.
✓ Branch 12 taken 148653 times.
✓ Branch 13 taken 178675 times.
✓ Branch 14 taken 1115029 times.
✓ Branch 15 taken 70851 times.
✓ Branch 16 taken 2511156 times.
✓ Branch 17 taken 38247 times.
✓ Branch 18 taken 616740 times.
✓ Branch 19 taken 690 times.
✓ Branch 20 taken 237523 times.
✓ Branch 21 taken 882 times.
✓ Branch 22 taken 227768 times.
✓ Branch 23 taken 920 times.
✓ Branch 24 taken 834532 times.
✓ Branch 25 taken 4403 times.
✓ Branch 26 taken 310700 times.
✓ Branch 27 taken 5485 times.
✓ Branch 28 taken 96559 times.
✓ Branch 29 taken 5413 times.
✓ Branch 30 taken 95314 times.
✓ Branch 31 taken 5413 times.
✓ Branch 32 taken 108 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 36 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 504 times.
✗ Branch 37 not taken.
✓ Branch 38 taken 270 times.
✗ Branch 39 not taken.
✓ Branch 40 taken 2286 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 3438 times.
✗ Branch 43 not taken.
✓ Branch 44 taken 3555 times.
✗ Branch 45 not taken.
✓ Branch 46 taken 4338 times.
✗ Branch 47 not taken.
✓ Branch 48 taken 99 times.
✗ Branch 49 not taken.
✓ Branch 50 taken 171 times.
✗ Branch 51 not taken.
✓ Branch 52 taken 90 times.
✗ Branch 53 not taken.
✓ Branch 54 taken 180 times.
✗ Branch 55 not taken.
✓ Branch 56 taken 252 times.
✗ Branch 57 not taken.
✓ Branch 58 taken 324 times.
✗ Branch 59 not taken.
✓ Branch 60 taken 72 times.
✗ Branch 61 not taken.
✓ Branch 62 taken 224934 times.
✓ Branch 63 taken 738 times.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✓ Branch 73 taken 1062 times.
✗ Branch 74 not taken.
✓ Branch 75 taken 1062 times.
✓ Branch 76 taken 34644 times.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
27136167 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 18 inline string hex(unsigned int value)
347 {
348 char buffer[64];
349 if(0);
350
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 else if (value<=0x000000FF) sprintf(buffer, "%.2X", value);
351
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 else if (value<=0x0000FFFF) sprintf(buffer, "%.4X", value);
352 else if (value<=0x00FFFFFF) sprintf(buffer, "%.6X", value);
353 else sprintf(buffer, "%.8X", value);
354
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
27 return buffer;
355 }
356
357 700 inline string hex(unsigned int value, int width)
358 {
359 char buffer[64];
360 700 sprintf(buffer, "%.*X", width, value);
361
1/2
✓ Branch 0 taken 350 times.
✗ Branch 1 not taken.
1050 return buffer;
362 }
363
364 20125 inline string dec(int value)
365 {
366 char buffer[64];
367 20125 sprintf(buffer, "%i", value);
368
1/2
✓ Branch 0 taken 7950 times.
✗ Branch 1 not taken.
28075 return buffer;
369 }
370
371 6498 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 6498 sprintf(rval, "%.100f", value);
379
1/2
✓ Branch 0 taken 6498 times.
✗ Branch 1 not taken.
6498 if (strchr(rval, '.'))//nuke useless zeroes
380 {
381 6498 char * end=strrchr(rval, '\0')-1;
382
2/2
✓ Branch 0 taken 648756 times.
✓ Branch 1 taken 6498 times.
655254 while (*end=='0')
383 {
384 648756 *end='\0';
385 648756 end--;
386 }
387
2/2
✓ Branch 0 taken 6480 times.
✓ Branch 1 taken 18 times.
6498 if (*end=='.') *end='\0';
388 }
389
1/2
✓ Branch 0 taken 3249 times.
✗ Branch 1 not taken.
9747 return rval;
390 }
391
392 // Same as above, but with variable precision
393 138 inline string ftostrvar(double value, int precision)
394 {
395 69 int clampedprecision = precision;
396
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 if (clampedprecision < 0) clampedprecision = 0;
397
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
138 if (clampedprecision > 100) clampedprecision = 100;
398
399 // see above
400 char rval[512];
401 138 sprintf(rval, "%.*f", clampedprecision, (double)value);
402
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 6 times.
138 if (strchr(rval, '.'))//nuke useless zeroes
403 {
404 132 char * end = strrchr(rval, '\0') - 1;
405
2/2
✓ Branch 0 taken 414 times.
✓ Branch 1 taken 132 times.
546 while (*end == '0')
406 {
407 414 *end = '\0';
408 414 end--;
409 }
410
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 78 times.
132 if (*end == '.') *end = '\0';
411 }
412
1/2
✓ Branch 0 taken 69 times.
✗ Branch 1 not taken.
207 return rval;
413 }
414
415 262714 inline bool stribegin(const char * str, const char * key)
416 {
417
2/2
✓ Branch 0 taken 900627 times.
✓ Branch 1 taken 26187 times.
926814 for (int i=0;key[i];i++)
418 {
419
2/2
✓ Branch 0 taken 571592 times.
✓ Branch 1 taken 329035 times.
900627 if (to_lower(str[i])!=to_lower(key[i])) return false;
420 }
421 5595 return true;
422 }
423
424 inline bool striend(const char * str, const char * key)
425 {
426 const char * keyend=strrchr(key, '\0');
427 const char * strend=strrchr(str, '\0');
428 if(keyend-key > strend-str) return false;
429
430 while (key!=keyend)
431 {
432 keyend--;
433 strend--;
434 if (to_lower(*strend)!=to_lower(*keyend)) return false;
435 }
436 return true;
437 }
438
439 inline bool stricmpwithupper(const char *word1, const char *word2)
440 {
441 while(*word2)
442 {
443 if(to_upper(*word1++) != *word2++) return true;
444 }
445 return *word1;
446 }
447
448 1900560 inline bool stricmpwithlower(const char *word1, const char *word2)
449 {
450
2/2
✓ Branch 0 taken 2605404 times.
✓ Branch 1 taken 115052 times.
2720456 while(*word2)
451 {
452
2/2
✓ Branch 0 taken 1219981 times.
✓ Branch 1 taken 1385423 times.
2605404 if(to_lower(*word1++) != *word2++) return true;
453 }
454 115052 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 29319 inline const char * dequote(char * str)
463 {
464
2/2
✓ Branch 0 taken 17886 times.
✓ Branch 1 taken 11433 times.
29319 if (*str!='"') return str;
465 27066 char *end = strrchr(str, '"');
466
1/2
✓ Branch 0 taken 27066 times.
✗ Branch 1 not taken.
27066 if (end)
467 {
468 27066 *end = 0;
469 27066 char *quote = str+1;
470
2/2
✓ Branch 0 taken 432 times.
✓ Branch 1 taken 27066 times.
27498 while((quote = strstr(quote, "\"\""))) memmove(quote, quote+1, strlen(quote));
471 10317 return str + 1;
472 }
473 return nullptr;
474 }
475
476 35529 inline char * strqchr(const char * str, char key)
477 {
478
2/2
✓ Branch 0 taken 337934 times.
✓ Branch 1 taken 24762 times.
362696 while (*str != '\0')
479 {
480
2/2
✓ Branch 0 taken 10761 times.
✓ Branch 1 taken 327173 times.
337934 if (*str == key) { return const_cast<char*>(str); }
481
4/4
✓ Branch 0 taken 325332 times.
✓ Branch 1 taken 1841 times.
✓ Branch 2 taken 534 times.
✓ Branch 3 taken 324798 times.
327173 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 534 times.
✓ Branch 1 taken 1841 times.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 504 times.
✓ Branch 4 taken 30 times.
✗ Branch 5 not taken.
2375 if (str[0] == '\'' && str[1] == '\'' && str[2] == '\'') { str += 2; }
486 else
487 {
488 1207 char delimiter = *str;
489
490 do
491 {
492 27031 str++;
493
494 // If we want to support backslash escapes, we'll have to add that right here.
495
4/4
✓ Branch 0 taken 24692 times.
✓ Branch 1 taken 2339 times.
✓ Branch 2 taken 24686 times.
✓ Branch 3 taken 6 times.
27031 } 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 1138 times.
✓ Branch 1 taken 1207 times.
2345 if (*str == '\0') { return nullptr; }
499 }
500 }
501
502 327167 str++;
503 }
504
505 12410 return nullptr;
506 }
507
508 3921 inline string substr(const char * str, int len)
509 {
510 3921 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 202647 inline char *strip_whitespace(char *str)
519 {
520
2/2
✓ Branch 0 taken 11146 times.
✓ Branch 1 taken 202647 times.
213793 while(is_space(*str)) str++;
521
2/2
✓ Branch 0 taken 189710 times.
✓ Branch 1 taken 60265 times.
249975 for(int i = strlen(str) - 1; i >= 0; i--)
522 {
523
2/2
✓ Branch 0 taken 142382 times.
✓ Branch 1 taken 47328 times.
189710 if(!is_space(str[i]))
524 {
525 142382 str[i + 1] = 0;
526 142382 return str;
527 }
528 }
529 30158 return str;
530 }
531 6717 inline void strip_whitespace(string &str)
532 {
533
2/4
✓ Branch 0 taken 3364 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3364 times.
✗ Branch 3 not taken.
10070 str = string(strip_whitespace(str.temp_raw()));
534 6717 }
535
536 string &itrim(string &str, const char * left, const char * right);
537
538
2/2
✓ Branch 0 taken 34094 times.
✓ Branch 1 taken 18 times.
34195 inline string &lower(string &old)
539 {
540 83 int length = old.length();
541
2/2
✓ Branch 0 taken 956166 times.
✓ Branch 1 taken 34195 times.
990361 for (int i=0;i<length;i++) old.raw()[i]=(char)to_lower(old.data()[i]);
542 34195 return old;
543 }
544
545
546 // Returns number of connected lines - 1
547 template<typename stringarraytype>
548 143169 inline int getconnectedlines(stringarraytype& lines, int startline, string& out)
549 {
550 68448 int count = 0;
551
552
1/2
✓ Branch 0 taken 143223 times.
✗ Branch 1 not taken.
143223 for (int i = startline; lines[i]; i++)
553 {
554 // The line should already be stripped of any comments at this point
555 143223 int linestartpos = (int)strlen(lines[i]);
556
557
4/4
✓ Branch 0 taken 105657 times.
✓ Branch 1 taken 37566 times.
✓ Branch 2 taken 54 times.
✓ Branch 3 taken 105603 times.
143223 if(linestartpos && lines[i][linestartpos - 1] == '\\')
558 {
559 54 count++;
560
2/4
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
54 out += string(lines[i], linestartpos - 1);
561 27 continue;
562 }
563 else
564 {
565
2/4
✓ Branch 0 taken 68448 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 68448 times.
✗ Branch 3 not taken.
143169 out += string(lines[i], linestartpos);
566 143169 return count;
567 }
568 }
569
570 return count;
571 }
572