asar coverage - build #275


src/asar/
File: src/asar/libstr.h
Date: 2025-03-04 15:51:07
Lines:
205/221
92.8%
Functions:
58/62
93.5%
Branches:
160/231
69.3%

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 1466023 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 238742 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 784048 inline char *copy(const char *source, int copy_length, char *dest)
27 {
28
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 368157 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 368157 times.
784048 memcpy(dest, source, copy_length*sizeof(char));
29 784048 return dest;
30 }
31
32 class string {
33 public:
34 2419628 const char *data() const
35 {
36 2419628 return data_ptr;
37 }
38
39 116213 char *temp_raw() const //things to cleanup and take a look at
40 {
41 116213 return data_ptr;
42 }
43
44 369577 char *raw() const
45 {
46 369577 return data_ptr;
47 }
48
49 2626147 int length() const
50 {
51 2626147 return len;
52 }
53
54 1301488 void resize(unsigned int new_length)
55 {
56
3/3
✓ Branch 0 taken 1559 times.
✓ Branch 1 taken 699946 times.
✓ Branch 2 taken 599983 times.
1301488 if (new_length > capacity()) {
57 3409 reallocate_capacity(new_length);
58 }
59
60 1301488 len = new_length;
61 1301488 data_ptr[new_length] = 0; //always ensure null terminator
62 1301488 }
63
64 792 void truncate(int newlen)
65 {
66 792 resize(newlen);
67 792 }
68
69 421065 void assign(const char * newstr)
70 {
71
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 421062 times.
421065 if (!newstr) newstr = "";
72
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 202433 times.
421065 assign(newstr, strlen(newstr));
73 421065 }
74
75 102800 void assign(const string &newstr)
76 {
77 102800 assign(newstr.data(), newstr.length());
78 102800 }
79
80 599769 void assign(const char * newstr, int end)
81 {
82 599769 resize(end);
83 599769 copy(newstr, end, data_ptr);
84 599769 }
85
86
87 18424 string& operator=(const char * newstr)
88 {
89 18424 assign(newstr);
90 18424 return *this;
91 }
92
93 102800 string& operator=(const string &newstr)
94 {
95 102800 assign(newstr);
96 102800 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 50300 string& operator+=(const string& other)
116 {
117 50300 int current_end = length();
118 50300 resize(length() + other.length());
119 50300 copy(other.data(), other.length(), data_ptr + current_end);
120 50300 return *this;
121 }
122
123 127352 string& operator+=(const char *other)
124 {
125 127352 int current_end = length();
126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60563 times.
127352 int otherlen=(int)strlen(other);
127 127352 resize(length() + otherlen);
128 127352 copy(other, otherlen, data_ptr + current_end);
129 127352 return *this;
130 }
131
132 519863 string& operator+=(char c)
133 {
134 519863 resize(length() + 1);
135 519863 data_ptr[length() - 1] = c;
136 519863 return *this;
137 }
138
139 string operator+(char right) const
140 {
141 string ret=*this;
142 ret+=right;
143 return ret;
144 }
145
146 19517 string operator+(const char * right) const
147 {
148 19517 string ret=*this;
149
1/2
✓ Branch 0 taken 19517 times.
✗ Branch 1 not taken.
19517 ret+=right;
150 19517 return ret;
151 }
152
153 1826290 operator const char*() const
154 {
155 1826290 return data();
156 }
157
158 10280 explicit operator bool() const
159 {
160 10280 return length();
161 }
162
163 885809 string()
164 885809 {
165 885809 data_ptr = inlined.data;
166 885809 len = 0;
167 885809 inlined.data[0] = '\0';
168 885809 }
169 312067 string(const char * newstr) : string()
170 {
171
2/3
✓ Branch 0 taken 161071 times.
✓ Branch 1 taken 150996 times.
✗ Branch 2 not taken.
312067 assign(newstr);
172 312067 }
173 63597 string(const char * newstr, int newlen) : string()
174 {
175
2/3
✓ Branch 0 taken 33182 times.
✓ Branch 1 taken 30415 times.
✗ Branch 2 not taken.
63597 assign(newstr, newlen);
176 63597 }
177 90574 string(const string& old) : string()
178 {
179
2/4
✓ Branch 0 taken 46872 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 43702 times.
✗ Branch 3 not taken.
90574 assign(old.data());
180 90574 }
181
182 12797 string(string &&move) noexcept : string()
183 {
184 12797 *this = move;
185 12797 }
186
187 43754 string& operator=(string&& other) noexcept
188 {
189
3/3
✓ Branch 0 taken 26828 times.
✓ Branch 1 taken 16906 times.
✓ Branch 2 taken 20 times.
43754 if (other.is_inlined()) {
190 // No resources to steal so just do a normal assignment
191 43716 *this = other;
192 } else {
193
2/3
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
38 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 std::swap(data_ptr, other.data_ptr);
199 }
200 38 len = other.len;
201 38 allocated = other.allocated;
202 }
203 43754 return *this;
204 }
205
206 866977 ~string()
207 {
208
3/3
✓ Branch 0 taken 1500 times.
✓ Branch 1 taken 448712 times.
✓ Branch 2 taken 416765 times.
866977 if(!is_inlined()){
209 3257 free(data_ptr);
210 }
211 866977 }
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 1301488 unsigned capacity() const
266 {
267
3/3
✓ Branch 0 taken 698954 times.
✓ Branch 1 taken 601617 times.
✓ Branch 2 taken 917 times.
1301488 return is_inlined() ? inline_capacity : allocated.capacity;
268 }
269
270 2215666 bool is_inlined() const
271 {
272 2215666 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 23434 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 19868 times.
55124 ASAR_STRCMP_OPERATORS(==)
289
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1662 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1662 times.
4342 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 67512 size_t operator()(const ::string& s) const {
299 67512 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 81053 inline bool stribegin(const char * str, const char * key)
386 {
387
4/4
✓ Branch 0 taken 114689 times.
✓ Branch 1 taken 4136 times.
✓ Branch 2 taken 78108 times.
✓ Branch 3 taken 1908 times.
198841 for (int i=0;key[i];i++)
388 {
389
4/4
✓ Branch 0 taken 37253 times.
✓ Branch 1 taken 77436 times.
✓ Branch 2 taken 37756 times.
✓ Branch 3 taken 40352 times.
192797 if (to_lower(str[i])!=to_lower(key[i])) return false;
390 }
391 6044 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 572874 inline bool stricmpwithlower(const char *word1, const char *word2)
419 {
420
3/3
✓ Branch 0 taken 412678 times.
✓ Branch 1 taken 384563 times.
✓ Branch 2 taken 16947 times.
814188 while(*word2)
421 {
422
4/4
✓ Branch 0 taken 286806 times.
✓ Branch 1 taken 125872 times.
✓ Branch 2 taken 251370 times.
✓ Branch 3 taken 115442 times.
779490 if(to_lower(*word1++) != *word2++) return true;
423 }
424 34698 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 5007 inline const char * dequote(char * str)
433 {
434
3/3
✓ Branch 0 taken 372 times.
✓ Branch 1 taken 3046 times.
✓ Branch 2 taken 1589 times.
5007 if (*str!='"') return str;
435
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1589 times.
4227 char *end = strrchr(str, '"');
436
1/2
✓ Branch 0 taken 4227 times.
✗ Branch 1 not taken.
4227 if (end)
437 {
438 4227 *end = 0;
439 4227 char *quote = str+1;
440
4/4
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 4299 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 1589 times.
4371 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 4227 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 64072 inline char *strip_whitespace(char *str)
488 {
489
4/4
✓ Branch 0 taken 1532 times.
✓ Branch 1 taken 32314 times.
✓ Branch 2 taken 1971 times.
✓ Branch 3 taken 31758 times.
67575 while(is_space(*str)) str++;
490
4/4
✓ Branch 0 taken 29323 times.
✓ Branch 1 taken 42317 times.
✓ Branch 2 taken 28691 times.
✓ Branch 3 taken 10643 times.
79216 for(int i = strlen(str) - 1; i >= 0; i--)
491 {
492
4/4
✓ Branch 0 taken 21755 times.
✓ Branch 1 taken 7568 times.
✓ Branch 2 taken 21115 times.
✓ Branch 3 taken 7576 times.
58014 if(!is_space(str[i]))
493 {
494 42870 str[i + 1] = 0;
495 42870 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 5785 inline string &lower(string &old)
508 {
509 5785 int length = old.length();
510
4/4
✓ Branch 0 taken 172230 times.
✓ Branch 1 taken 5783 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 2 times.
178021 for (int i=0;i<length;i++) old.raw()[i]=(char)to_lower(old.data()[i]);
511 5785 return old;
512 }
513
514
515 // Returns number of connected lines - 1
516 template<typename stringarraytype>
517 45443 inline int getconnectedlines(stringarraytype& lines, int startline, string& out)
518 {
519 45443 int count = 0;
520
521
2/4
✓ Branch 0 taken 23105 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 22356 times.
✗ Branch 3 not taken.
45461 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 22356 times.
45461 int linestartpos = (int)strlen(lines[i]);
525
526
6/6
✓ Branch 0 taken 31881 times.
✓ Branch 1 taken 13580 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 16330 times.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 15533 times.
45461 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 23096 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 23096 times.
✓ Branch 3 taken 22347 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 22347 times.
✗ Branch 6 not taken.
45443 out += string(lines[i], linestartpos);
535 45443 return count;
536 }
537 }
538
539 return count;
540 }
541