asar coverage - build #278


src/asar/
File: src/asar/libstr.h
Date: 2025-03-05 17:13:33
Lines:
206/221
93.2%
Functions:
58/62
93.5%
Branches:
161/231
69.7%

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 1450708 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 238217 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 49749 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 14715 inline bool is_ualpha(unsigned char c) { return char_props[c] & 0x28; }
23 120831 inline bool is_ualnum(unsigned char c) { return char_props[c] & 0x68; }
24 7334 inline bool is_xdigit(unsigned char c) { return char_props[c] & 0x01; }
25
26 791786 inline char *copy(const char *source, int copy_length, char *dest)
27 {
28
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 373149 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 373149 times.
791786 memcpy(dest, source, copy_length*sizeof(char));
29 791786 return dest;
30 }
31
32 class string {
33 public:
34 2569072 const char *data() const
35 {
36 2569072 return data_ptr;
37 }
38
39 115793 char *temp_raw() const //things to cleanup and take a look at
40 {
41 115793 return data_ptr;
42 }
43
44 264907 char *raw() const
45 {
46 264907 return data_ptr;
47 }
48
49 2530279 int length() const
50 {
51 2530279 return len;
52 }
53
54 1303693 void resize(unsigned int new_length)
55 {
56
3/3
✓ Branch 0 taken 1572 times.
✓ Branch 1 taken 698706 times.
✓ Branch 2 taken 603415 times.
1303693 if (new_length > capacity()) {
57 3437 reallocate_capacity(new_length);
58 }
59
60 1303693 len = new_length;
61 1303693 data_ptr[new_length] = 0; //always ensure null terminator
62 1303693 }
63
64 792 void truncate(int newlen)
65 {
66 792 resize(newlen);
67 792 }
68
69 463160 void assign(const char * newstr)
70 {
71
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 463157 times.
463160 if (!newstr) newstr = "";
72
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 223643 times.
463160 assign(newstr, strlen(newstr));
73 463160 }
74
75 112877 void assign(const string &newstr)
76 {
77 112877 assign(newstr.data(), newstr.length());
78 112877 }
79
80 651626 void assign(const char * newstr, int end)
81 {
82 651626 resize(end);
83 651626 copy(newstr, end, data_ptr);
84 651626 }
85
86
87 14177 string& operator=(const char * newstr)
88 {
89 14177 assign(newstr);
90 14177 return *this;
91 }
92
93 112877 string& operator=(const string &newstr)
94 {
95 112877 assign(newstr);
96 112877 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 3408 string& append(const char *other, int start, int end)
108 {
109 3408 int current_end = length();
110 3408 resize(length() + end - start);
111 3408 copy(other + start, end - start, data_ptr + current_end);
112 3408 return *this;
113 }
114
115 50090 string& operator+=(const string& other)
116 {
117 50090 int current_end = length();
118 50090 resize(length() + other.length());
119 50090 copy(other.data(), other.length(), data_ptr + current_end);
120 50090 return *this;
121 }
122
123 83415 string& operator+=(const char *other)
124 {
125 83415 int current_end = length();
126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39104 times.
83415 int otherlen=(int)strlen(other);
127 83415 resize(length() + otherlen);
128 83415 copy(other, otherlen, data_ptr + current_end);
129 83415 return *this;
130 }
131
132 514358 string& operator+=(char c)
133 {
134 514358 resize(length() + 1);
135 514358 data_ptr[length() - 1] = c;
136 514358 return *this;
137 }
138
139 string operator+(char right) const
140 {
141 string ret=*this;
142 ret+=right;
143 return ret;
144 }
145
146 19097 string operator+(const char * right) const
147 {
148 19097 string ret=*this;
149
1/2
✓ Branch 0 taken 19097 times.
✗ Branch 1 not taken.
19097 ret+=right;
150 19097 return ret;
151 }
152
153 1772471 operator const char*() const
154 {
155 1772471 return data();
156 }
157
158 10280 explicit operator bool() const
159 {
160 10280 return length();
161 }
162
163 894236 string()
164 894236 {
165 894236 data_ptr = inlined.data;
166 894236 len = 0;
167 894236 inlined.data[0] = '\0';
168 894236 }
169 267407 string(const char * newstr) : string()
170 {
171
2/3
✓ Branch 0 taken 138021 times.
✓ Branch 1 taken 129386 times.
✗ Branch 2 not taken.
267407 assign(newstr);
172 267407 }
173 63282 string(const char * newstr, int newlen) : string()
174 {
175
2/3
✓ Branch 0 taken 32957 times.
✓ Branch 1 taken 30325 times.
✗ Branch 2 not taken.
63282 assign(newstr, newlen);
176 63282 }
177 181576 string(const string& old) : string()
178 {
179
2/4
✓ Branch 0 taken 92997 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88579 times.
✗ Branch 3 not taken.
181576 assign(old.data());
180 181576 }
181
182 20184 string(string &&move) noexcept : string()
183 {
184 20184 *this = move;
185 20184 }
186
187 45660 string& operator=(string&& other) noexcept
188 {
189
3/3
✓ Branch 0 taken 27666 times.
✓ Branch 1 taken 17953 times.
✓ Branch 2 taken 41 times.
45660 if (other.is_inlined()) {
190 // No resources to steal so just do a normal assignment
191 45580 *this = other;
192 } else {
193
3/3
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 41 times.
✓ Branch 2 taken 21 times.
80 if (is_inlined()) {
194 38 data_ptr = other.data_ptr;
195 38 other.data_ptr = 0;
196 } else {
197 // Give our old allocation back so other can free it for us
198 42 std::swap(data_ptr, other.data_ptr);
199 }
200 80 len = other.len;
201 80 allocated = other.allocated;
202 }
203 45660 return *this;
204 }
205
206 875403 ~string()
207 {
208
3/3
✓ Branch 0 taken 1513 times.
✓ Branch 1 taken 451992 times.
✓ Branch 2 taken 421898 times.
875403 if(!is_inlined()){
209 3285 free(data_ptr);
210 }
211 875403 }
212
213 //maybe these should return refs to chain. but also good not to encourage chaining
214 11 void strip_prefix(char c)
215 {
216
2/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 7 times.
11 if(data()[0] == c){
217
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
4 std::memmove(data_ptr, data_ptr + 1, length() - 1);
218 4 resize(length() - 1);
219 }
220 11 }
221
222 void strip_suffix(char c)
223 {
224 if (data()[length() - 1] == c) {
225 truncate(length() - 1);
226 }
227 }
228
229 string& qreplace(const char * instr, const char * outstr);
230 string& qnormalize();
231
232 // RPG Hacker: My hack shmeck to get around no longer supporting text mode.
233 // Symbol files are currently the only thing that use text mode, anyways, and I don't even know
234 // if the emulators that read them care about line endings.
235 string& convert_line_endings_to_native()
236 {
237 #if defined(windows)
238 // RPG Hacker: This is quite stinky, but doing the replacement directly will lead to a dead-lock.
239 // \x08 = backspace should never appear inside a string, so I'm abusing it here.
240 return qreplace("\n", "\x08").qreplace("\x08", "\r\n");
241 #else
242 return *this;
243 #endif
244 }
245
246 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 1303693 unsigned capacity() const
266 {
267
3/3
✓ Branch 0 taken 697733 times.
✓ Branch 1 taken 605064 times.
✓ Branch 2 taken 896 times.
1303693 return is_inlined() ? inline_capacity : allocated.capacity;
268 }
269
270 2228273 bool is_inlined() const
271 {
272 2228273 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 3566 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 26021 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 22455 times.
60197 ASAR_STRCMP_OPERATORS(==)
289
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1632 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1632 times.
4237 ASAR_STRCMP_OPERATORS(!=)
290
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
12 ASAR_STRCMP_OPERATORS(<)
291 ASAR_STRCMP_OPERATORS(<=)
292
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
6 ASAR_STRCMP_OPERATORS(>)
293
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
6 ASAR_STRCMP_OPERATORS(>=)
294 #undef ASAR_STRCMP_OPERATORS
295
296 template<>
297 struct std::hash<string> {
298 72839 size_t operator()(const ::string& s) const {
299 72839 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
315 inline string hex(unsigned int value)
316 {
317 char buffer[64];
318 if(0);
319 else if (value<=0x000000FF) snprintf(buffer, sizeof(buffer), "%.2X", value);
320 else if (value<=0x0000FFFF) snprintf(buffer, sizeof(buffer), "%.4X", value);
321 else if (value<=0x00FFFFFF) snprintf(buffer, sizeof(buffer), "%.6X", value);
322 else snprintf(buffer, sizeof(buffer), "%.8X", value);
323 return buffer;
324 }
325
326 2 inline string hex(unsigned int value, int width)
327 {
328 1 char buffer[64];
329
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 snprintf(buffer, sizeof(buffer), "%.*X", width, value);
330
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 return buffer;
331 }
332
333 3310 inline string dec(int64_t value)
334 {
335 1710 char buffer[64];
336
2/2
✓ Branch 0 taken 1600 times.
✓ Branch 1 taken 1710 times.
3310 snprintf(buffer, sizeof(buffer), "%" PRId64, value);
337
1/2
✓ Branch 0 taken 3310 times.
✗ Branch 1 not taken.
6620 return buffer;
338 }
339
340 // todo this function sucks, replace with std::to_chars
341 258 inline string ftostr(double value)
342 {
343 // randomdude999: With 100 digits of precision, the buffer needs to be approx. 311+100,
344 // but let's be safe here https://stackoverflow.com/questions/7235456
345 129 char rval[512];
346 // RPG Hacker: Ridiculously high precision, I know, but we're working with doubles
347 // here and can afford it, so no need to waste any precision
348
1/2
✓ Branch 0 taken 129 times.
✗ Branch 1 not taken.
258 snprintf(rval, sizeof(rval), "%.100f", value);
349
1/2
✓ Branch 0 taken 258 times.
✗ Branch 1 not taken.
258 if (strchr(rval, '.'))//nuke useless zeroes
350 {
351 258 char * end=strrchr(rval, '\0')-1;
352
3/3
✓ Branch 0 taken 12726 times.
✓ Branch 1 taken 12855 times.
✓ Branch 2 taken 129 times.
25710 while (*end=='0')
353 {
354 25452 *end='\0';
355 25452 end--;
356 }
357
3/3
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 129 times.
✓ Branch 2 taken 3 times.
258 if (*end=='.') *end='\0';
358 }
359
1/2
✓ Branch 0 taken 258 times.
✗ Branch 1 not taken.
516 return rval;
360 }
361
362 // Same as above, but with variable precision
363 24 inline string ftostrvar(double value, int precision)
364 {
365 24 int clampedprecision = precision;
366
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 if (clampedprecision < 0) clampedprecision = 0;
367
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 if (clampedprecision > 100) clampedprecision = 100;
368
369 // see above
370 12 char rval[512];
371
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
24 snprintf(rval, sizeof(rval), "%.*f", clampedprecision, (double)value);
372
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 2 times.
24 if (strchr(rval, '.'))//nuke useless zeroes
373 {
374 22 char * end = strrchr(rval, '\0') - 1;
375
3/3
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 34 times.
✓ Branch 2 taken 11 times.
68 while (*end == '0')
376 {
377 46 *end = '\0';
378 46 end--;
379 }
380
3/3
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 8 times.
22 if (*end == '.') *end = '\0';
381 }
382
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
48 return rval;
383 }
384
385 80843 inline bool stribegin(const char * str, const char * key)
386 {
387
4/4
✓ Branch 0 taken 112589 times.
✓ Branch 1 taken 4061 times.
✓ Branch 2 taken 77478 times.
✓ Branch 3 taken 1908 times.
196036 for (int i=0;key[i];i++)
388 {
389
4/4
✓ Branch 0 taken 37178 times.
✓ Branch 1 taken 75411 times.
✓ Branch 2 taken 37696 times.
✓ Branch 3 taken 39782 times.
190067 if (to_lower(str[i])!=to_lower(key[i])) return false;
390 }
391 5969 return true;
392 }
393
394 inline bool striend(const char * str, const char * key)
395 {
396 const char * keyend=strrchr(key, '\0');
397 const char * strend=strrchr(str, '\0');
398 if(keyend-key > strend-str) return false;
399
400 while (key!=keyend)
401 {
402 keyend--;
403 strend--;
404 if (to_lower(*strend)!=to_lower(*keyend)) return false;
405 }
406 return true;
407 }
408
409 inline bool stricmpwithupper(const char *word1, const char *word2)
410 {
411 while(*word2)
412 {
413 if(to_upper(*word1++) != *word2++) return true;
414 }
415 return *word1;
416 }
417
418 568674 inline bool stricmpwithlower(const char *word1, const char *word2)
419 {
420
3/3
✓ Branch 0 taken 408928 times.
✓ Branch 1 taken 382988 times.
✓ Branch 2 taken 16917 times.
808833 while(*word2)
421 {
422
4/4
✓ Branch 0 taken 283881 times.
✓ Branch 1 taken 125047 times.
✓ Branch 2 taken 250200 times.
✓ Branch 3 taken 115112 times.
774240 if(to_lower(*word1++) != *word2++) return true;
423 }
424 34593 return *word1;
425 }
426
427 //function: return the string without quotes around it, if any exists
428 //if they don't exist, return it unaltered
429 //it is not guaranteed to return str
430 //it is not guaranteed to not edit str
431 //the input must be freed even though it's garbage, the output must not
432 4902 inline const char * dequote(char * str)
433 {
434
3/3
✓ Branch 0 taken 372 times.
✓ Branch 1 taken 2971 times.
✓ Branch 2 taken 1559 times.
4902 if (*str!='"') return str;
435
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1559 times.
4122 char *end = strrchr(str, '"');
436
1/2
✓ Branch 0 taken 4122 times.
✗ Branch 1 not taken.
4122 if (end)
437 {
438 4122 *end = 0;
439 4122 char *quote = str+1;
440
4/4
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 4194 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 1559 times.
4266 while((quote = strstr(quote, "\"\""))) {
441
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));
442 144 quote++;
443 }
444 4122 return str + 1;
445 }
446 return nullptr;
447 }
448
449 15749 inline char * strqchr(const char * str, char key)
450 {
451
3/3
✓ Branch 0 taken 68973 times.
✓ Branch 1 taken 76315 times.
✓ Branch 2 taken 5999 times.
151287 while (*str != '\0')
452 {
453
3/3
✓ Branch 0 taken 1922 times.
✓ Branch 1 taken 68979 times.
✓ Branch 2 taken 68489 times.
139390 if (*str == key) { return const_cast<char*>(str); }
454
6/6
✓ Branch 0 taken 66704 times.
✓ Branch 1 taken 68480 times.
✓ Branch 2 taken 449 times.
✓ Branch 3 taken 66611 times.
✓ Branch 4 taken 93 times.
✓ Branch 5 taken 68040 times.
135540 else if (*str == '"' || *str == '\'')
455 {
456 // Special case hack for ''', which is currently our official way of handling the ' character.
457 // Even though it really stinks.
458
8/9
✓ Branch 0 taken 93 times.
✓ Branch 1 taken 440 times.
✓ Branch 2 taken 362 times.
✓ Branch 3 taken 87 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 87 times.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
889 if (str[0] == '\'' && str[1] == '\'' && str[2] == '\'') { str += 2; }
459 else
460 {
461 877 char delimiter = *str;
462
463 do
464 {
465 9091 str++;
466
467 // If we want to support backslash escapes, we'll have to add that right here.
468
6/6
✓ Branch 0 taken 4070 times.
✓ Branch 1 taken 4579 times.
✓ Branch 2 taken 4511 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 4145 times.
✓ Branch 5 taken 1 times.
9091 } while (*str != delimiter && *str != '\0');
469
470 // This feels like a superfluous check, but I can't really find a clean way to avoid it.
471
3/3
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 434 times.
✓ Branch 2 taken 442 times.
877 if (*str == '\0') { return nullptr; }
472 }
473 }
474
475 135538 str++;
476 }
477
478 11897 return nullptr;
479 }
480
481 2580 inline string substr(const char * str, int len)
482 {
483 2580 return string(str, len);
484 }
485
486
487 63967 inline char *strip_whitespace(char *str)
488 {
489
4/4
✓ Branch 0 taken 1532 times.
✓ Branch 1 taken 32239 times.
✓ Branch 2 taken 1971 times.
✓ Branch 3 taken 31728 times.
67470 while(is_space(*str)) str++;
490
4/4
✓ Branch 0 taken 29248 times.
✓ Branch 1 taken 42287 times.
✓ Branch 2 taken 28661 times.
✓ Branch 3 taken 10643 times.
79111 for(int i = strlen(str) - 1; i >= 0; i--)
491 {
492
4/4
✓ Branch 0 taken 21680 times.
✓ Branch 1 taken 7568 times.
✓ Branch 2 taken 21085 times.
✓ Branch 3 taken 7576 times.
57909 if(!is_space(str[i]))
493 {
494 42765 str[i + 1] = 0;
495 42765 return str;
496 }
497 }
498 21202 return str;
499 }
500 267 inline void strip_whitespace(string &str)
501 {
502
2/4
✓ Branch 0 taken 126 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 141 times.
✗ Branch 3 not taken.
267 str = string(strip_whitespace(str.temp_raw()));
503 267 }
504
505 string &itrim(string &str, const char * left, const char * right);
506
507 5635 inline string &lower(string &old)
508 {
509 5635 int length = old.length();
510
4/4
✓ Branch 0 taken 168255 times.
✓ Branch 1 taken 5633 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 2 times.
173896 for (int i=0;i<length;i++) old.raw()[i]=(char)to_lower(old.data()[i]);
511 5635 return old;
512 }
513
514
515 // Returns number of connected lines - 1
516 template<typename stringarraytype>
517 45338 inline int getconnectedlines(stringarraytype& lines, int startline, string& out)
518 {
519 45338 int count = 0;
520
521
2/4
✓ Branch 0 taken 23030 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 22326 times.
✗ Branch 3 not taken.
45356 for (int i = startline; lines[i]; i++)
522 {
523 // The line should already be stripped of any comments at this point
524
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22326 times.
45356 int linestartpos = (int)strlen(lines[i]);
525
526
6/6
✓ Branch 0 taken 31776 times.
✓ Branch 1 taken 13580 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 16255 times.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 15503 times.
45356 if(linestartpos && lines[i][linestartpos - 1] == '\\')
527 {
528 18 count++;
529
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);
530 18 continue;
531 }
532 else
533 {
534
4/7
✓ Branch 0 taken 23021 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 23021 times.
✓ Branch 3 taken 22317 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 22317 times.
✗ Branch 6 not taken.
45338 out += string(lines[i], linestartpos);
535 45338 return count;
536 }
537 }
538
539 return count;
540 }
541