asar coverage - build #273


src/asar/
File: src/asar/libstr.h
Date: 2025-03-03 20:49:12
Lines:
203/219
92.7%
Functions:
57/61
93.4%
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
9 //ty alcaro
10 extern const unsigned char char_props[256];
11 1477028 static inline int to_lower(unsigned char c) { return c|(char_props[c]&0x20); }
12 static inline int to_upper(unsigned char c) { return c&~(char_props[c]&0x20); }
13
14 239096 inline bool is_space(unsigned char c) { return char_props[c] & 0x80; } // C standard says \f \v are space, but this one disagrees
15 // TODO is this opaque table lookup really faster than c >= '0' && c <= '9'?
16 49595 inline bool is_digit(unsigned char c) { return char_props[c] & 0x40; }
17 inline bool is_alpha(unsigned char c) { return char_props[c] & 0x20; }
18 inline bool is_lower(unsigned char c) { return char_props[c] & 0x04; }
19 106 inline bool is_upper(unsigned char c) { return char_props[c] & 0x02; }
20 inline bool is_alnum(unsigned char c) { return char_props[c] & 0x60; }
21 14510 inline bool is_ualpha(unsigned char c) { return char_props[c] & 0x28; }
22 120561 inline bool is_ualnum(unsigned char c) { return char_props[c] & 0x68; }
23 7334 inline bool is_xdigit(unsigned char c) { return char_props[c] & 0x01; }
24
25 784902 inline char *copy(const char *source, int copy_length, char *dest)
26 {
27
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 367765 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 367765 times.
784902 memcpy(dest, source, copy_length*sizeof(char));
28 784902 return dest;
29 }
30
31 class string {
32 public:
33 2437354 const char *data() const
34 {
35 2437354 return data_ptr;
36 }
37
38 116588 char *temp_raw() const //things to cleanup and take a look at
39 {
40 116588 return data_ptr;
41 }
42
43 373176 char *raw() const
44 {
45 373176 return data_ptr;
46 }
47
48 2644312 int length() const
49 {
50 2644312 return len;
51 }
52
53 1306426 void resize(unsigned int new_length)
54 {
55
3/3
✓ Branch 0 taken 1554 times.
✓ Branch 1 taken 704105 times.
✓ Branch 2 taken 600767 times.
1306426 if (new_length > capacity()) {
56 3399 reallocate_capacity(new_length);
57 }
58
59 1306426 len = new_length;
60 1306426 data_ptr[new_length] = 0; //always ensure null terminator
61 1306426 }
62
63 792 void truncate(int newlen)
64 {
65 792 resize(newlen);
66 792 }
67
68 422416 void assign(const char * newstr)
69 {
70
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 422413 times.
422416 if (!newstr) newstr = "";
71
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 202723 times.
422416 assign(newstr, strlen(newstr));
72 422416 }
73
74 101501 void assign(const string &newstr)
75 {
76 101501 assign(newstr.data(), newstr.length());
77 101501 }
78
79 599907 void assign(const char * newstr, int end)
80 {
81 599907 resize(end);
82 599907 copy(newstr, end, data_ptr);
83 599907 }
84
85
86 18658 string& operator=(const char * newstr)
87 {
88 18658 assign(newstr);
89 18658 return *this;
90 }
91
92 101501 string& operator=(const string &newstr)
93 {
94 101501 assign(newstr);
95 101501 return *this;
96 }
97
98 string& append(const string& other, int start, int end)
99 {
100 int current_end = length();
101 resize(length() + end - start);
102 copy(other.data() + start, end - start, data_ptr + current_end);
103 return *this;
104 }
105
106 3402 string& append(const char *other, int start, int end)
107 {
108 3402 int current_end = length();
109 3402 resize(length() + end - start);
110 3402 copy(other + start, end - start, data_ptr + current_end);
111 3402 return *this;
112 }
113
114 50279 string& operator+=(const string& other)
115 {
116 50279 int current_end = length();
117 50279 resize(length() + other.length());
118 50279 copy(other.data(), other.length(), data_ptr + current_end);
119 50279 return *this;
120 }
121
122 128105 string& operator+=(const char *other)
123 {
124 128105 int current_end = length();
125
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60832 times.
128105 int otherlen=(int)strlen(other);
126 128105 resize(length() + otherlen);
127 128105 copy(other, otherlen, data_ptr + current_end);
128 128105 return *this;
129 }
130
131 523937 string& operator+=(char c)
132 {
133 523937 resize(length() + 1);
134 523937 data_ptr[length() - 1] = c;
135 523937 return *this;
136 }
137
138 string operator+(char right) const
139 {
140 string ret=*this;
141 ret+=right;
142 return ret;
143 }
144
145 19853 string operator+(const char * right) const
146 {
147 19853 string ret=*this;
148
1/2
✓ Branch 0 taken 19853 times.
✗ Branch 1 not taken.
19853 ret+=right;
149 19853 return ret;
150 }
151
152 1842136 operator const char*() const
153 {
154 1842136 return data();
155 }
156
157 10392 explicit operator bool() const
158 {
159 10392 return length();
160 }
161
162 885948 string()
163 885948 {
164 885948 data_ptr = inlined.data;
165 885948 len = 0;
166 885948 inlined.data[0] = '\0';
167 885948 }
168 313428 string(const char * newstr) : string()
169 {
170
2/3
✓ Branch 0 taken 162003 times.
✓ Branch 1 taken 151425 times.
✗ Branch 2 not taken.
313428 assign(newstr);
171 313428 }
172 63734 string(const char * newstr, int newlen) : string()
173 {
174
2/3
✓ Branch 0 taken 33300 times.
✓ Branch 1 taken 30434 times.
✗ Branch 2 not taken.
63734 assign(newstr, newlen);
175 63734 }
176 90330 string(const string& old) : string()
177 {
178
2/4
✓ Branch 0 taken 46836 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 43494 times.
✗ Branch 3 not taken.
90330 assign(old.data());
179 90330 }
180
181 12725 string(string &&move) noexcept : string()
182 {
183 12725 *this = move;
184 12725 }
185
186 42146 string& operator=(string&& other) noexcept
187 {
188
3/3
✓ Branch 0 taken 26088 times.
✓ Branch 1 taken 16038 times.
✓ Branch 2 taken 20 times.
42146 if (other.is_inlined()) {
189 // No resources to steal so just do a normal assignment
190 42108 *this = other;
191 } else {
192
2/3
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
38 if (is_inlined()) {
193 38 data_ptr = other.data_ptr;
194 38 other.data_ptr = 0;
195 } else {
196 // Give our old allocation back so other can free it for us
197 std::swap(data_ptr, other.data_ptr);
198 }
199 38 len = other.len;
200 38 allocated = other.allocated;
201 }
202 42146 return *this;
203 }
204
205 867120 ~string()
206 {
207
3/3
✓ Branch 0 taken 1495 times.
✓ Branch 1 taken 449474 times.
✓ Branch 2 taken 416151 times.
867120 if(!is_inlined()){
208 3247 free(data_ptr);
209 }
210 867120 }
211
212 //maybe these should return refs to chain. but also good not to encourage chaining
213 11 void strip_prefix(char c)
214 {
215
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){
216
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);
217 4 resize(length() - 1);
218 }
219 11 }
220
221 void strip_suffix(char c)
222 {
223 if (data()[length() - 1] == c) {
224 truncate(length() - 1);
225 }
226 }
227
228 string& qreplace(const char * instr, const char * outstr);
229 string& qnormalize();
230
231 // RPG Hacker: My hack shmeck to get around no longer supporting text mode.
232 // Symbol files are currently the only thing that use text mode, anyways, and I don't even know
233 // if the emulators that read them care about line endings.
234 string& convert_line_endings_to_native()
235 {
236 #if defined(windows)
237 // RPG Hacker: This is quite stinky, but doing the replacement directly will lead to a dead-lock.
238 // \x08 = backspace should never appear inside a string, so I'm abusing it here.
239 return qreplace("\n", "\x08").qreplace("\x08", "\r\n");
240 #else
241 return *this;
242 #endif
243 }
244
245 private:
246 static const int scale_factor = 4; //scale sso
247 static const int inline_capacity = ((sizeof(char *) + sizeof(int) * 2) * scale_factor) - 2;
248
249 // Points to a malloc'd data block or to inlined.data
250 char *data_ptr;
251 unsigned int len;
252 union {
253 struct {
254 // Actual allocated capacity is +1 this value, to cover for the terminating NUL
255 unsigned int capacity;
256 } allocated;
257 struct {
258 char data[inline_capacity + 1];
259 } inlined;
260 };
261
262 void reallocate_capacity(unsigned int new_length);
263
264 1306426 unsigned capacity() const
265 {
266
3/3
✓ Branch 0 taken 703113 times.
✓ Branch 1 taken 602396 times.
✓ Branch 2 taken 917 times.
1306426 return is_inlined() ? inline_capacity : allocated.capacity;
267 }
268
269 2219129 bool is_inlined() const
270 {
271 2219129 return data_ptr == inlined.data;
272 }
273 };
274 #define STR (string)
275
276 #define ASAR_STRCMP_OPERATORS(op) \
277 inline bool operator op(const string& left, const string& right) { \
278 return strcmp(left, right) op 0; \
279 } \
280 inline bool operator op(const string& left, const char* right) { \
281 return strcmp(left, right) op 0; \
282 } \
283 inline bool operator op(const char* left, const string& right) { \
284 return strcmp(left, right) op 0; \
285 }
286
287
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 3565 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 23566 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 20001 times.
55453 ASAR_STRCMP_OPERATORS(==)
288
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1685 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1685 times.
4420 ASAR_STRCMP_OPERATORS(!=)
289
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
12 ASAR_STRCMP_OPERATORS(<)
290 ASAR_STRCMP_OPERATORS(<=)
291
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
6 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 #undef ASAR_STRCMP_OPERATORS
294
295 template<>
296 struct std::hash<string> {
297 67875 size_t operator()(const ::string& s) const {
298 67875 return std::hash<std::string_view>()(std::string_view(s.data(), s.length()));
299 }
300 };
301
302 char * readfile(const char * fname, const char * basepath);
303 char * readfilenative(const char * fname);
304 bool readfile(const char * fname, const char * basepath, char ** data, int * len);//if you want an uchar*, cast it
305 char ** split(char * str, char key, int * len= nullptr);
306 char ** qsplit(char * str, char key, int * len= nullptr);
307 char ** qpsplit(char * str, char key, int * len= nullptr);
308 char ** qsplitstr(char * str, const char * key, int * len= nullptr);
309 bool confirmquotes(const char * str);
310 bool confirmqpar(const char * str);
311 char* strqpchr(char* str, char key);
312 char* strqpstr(char* str, const char* key);
313
314 inline string hex(unsigned int value)
315 {
316 char buffer[64];
317 if(0);
318 else if (value<=0x000000FF) snprintf(buffer, sizeof(buffer), "%.2X", value);
319 else if (value<=0x0000FFFF) snprintf(buffer, sizeof(buffer), "%.4X", value);
320 else if (value<=0x00FFFFFF) snprintf(buffer, sizeof(buffer), "%.6X", value);
321 else snprintf(buffer, sizeof(buffer), "%.8X", value);
322 return buffer;
323 }
324
325 2 inline string hex(unsigned int value, int width)
326 {
327 1 char buffer[64];
328
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 snprintf(buffer, sizeof(buffer), "%.*X", width, value);
329
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 return buffer;
330 }
331
332 1402 inline string dec(int value)
333 {
334 756 char buffer[64];
335
2/2
✓ Branch 0 taken 646 times.
✓ Branch 1 taken 756 times.
1402 snprintf(buffer, sizeof(buffer), "%i", value);
336
1/2
✓ Branch 0 taken 1402 times.
✗ Branch 1 not taken.
2804 return buffer;
337 }
338
339 2166 inline string ftostr(double value)
340 {
341 // randomdude999: With 100 digits of precision, the buffer needs to be approx. 311+100,
342 // but let's be safe here https://stackoverflow.com/questions/7235456
343 1083 char rval[512];
344 // RPG Hacker: Ridiculously high precision, I know, but we're working with doubles
345 // here and can afford it, so no need to waste any precision
346
1/2
✓ Branch 0 taken 1083 times.
✗ Branch 1 not taken.
2166 snprintf(rval, sizeof(rval), "%.100f", value);
347
1/2
✓ Branch 0 taken 2166 times.
✗ Branch 1 not taken.
2166 if (strchr(rval, '.'))//nuke useless zeroes
348 {
349 2166 char * end=strrchr(rval, '\0')-1;
350
3/3
✓ Branch 0 taken 108126 times.
✓ Branch 1 taken 109209 times.
✓ Branch 2 taken 1083 times.
218418 while (*end=='0')
351 {
352 216252 *end='\0';
353 216252 end--;
354 }
355
3/3
✓ Branch 0 taken 1080 times.
✓ Branch 1 taken 1083 times.
✓ Branch 2 taken 3 times.
2166 if (*end=='.') *end='\0';
356 }
357
1/2
✓ Branch 0 taken 2166 times.
✗ Branch 1 not taken.
4332 return rval;
358 }
359
360 // Same as above, but with variable precision
361 24 inline string ftostrvar(double value, int precision)
362 {
363 24 int clampedprecision = precision;
364
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 if (clampedprecision < 0) clampedprecision = 0;
365
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 if (clampedprecision > 100) clampedprecision = 100;
366
367 // see above
368 12 char rval[512];
369
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
24 snprintf(rval, sizeof(rval), "%.*f", clampedprecision, (double)value);
370
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 2 times.
24 if (strchr(rval, '.'))//nuke useless zeroes
371 {
372 22 char * end = strrchr(rval, '\0') - 1;
373
3/3
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 34 times.
✓ Branch 2 taken 11 times.
68 while (*end == '0')
374 {
375 46 *end = '\0';
376 46 end--;
377 }
378
3/3
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 8 times.
22 if (*end == '.') *end = '\0';
379 }
380
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
48 return rval;
381 }
382
383 81215 inline bool stribegin(const char * str, const char * key)
384 {
385
4/4
✓ Branch 0 taken 116232 times.
✓ Branch 1 taken 4191 times.
✓ Branch 2 taken 78594 times.
✓ Branch 3 taken 1908 times.
200925 for (int i=0;key[i];i++)
386 {
387
4/4
✓ Branch 0 taken 37311 times.
✓ Branch 1 taken 78921 times.
✓ Branch 2 taken 37805 times.
✓ Branch 3 taken 40789 times.
194826 if (to_lower(str[i])!=to_lower(key[i])) return false;
388 }
389 6099 return true;
390 }
391
392 inline bool striend(const char * str, const char * key)
393 {
394 const char * keyend=strrchr(key, '\0');
395 const char * strend=strrchr(str, '\0');
396 if(keyend-key > strend-str) return false;
397
398 while (key!=keyend)
399 {
400 keyend--;
401 strend--;
402 if (to_lower(*strend)!=to_lower(*keyend)) return false;
403 }
404 return true;
405 }
406
407 inline bool stricmpwithupper(const char *word1, const char *word2)
408 {
409 while(*word2)
410 {
411 if(to_upper(*word1++) != *word2++) return true;
412 }
413 return *word1;
414 }
415
416 575724 inline bool stricmpwithlower(const char *word1, const char *word2)
417 {
418
3/3
✓ Branch 0 taken 415275 times.
✓ Branch 1 taken 385612 times.
✓ Branch 2 taken 16967 times.
817854 while(*word2)
419 {
420
4/4
✓ Branch 0 taken 288819 times.
✓ Branch 1 taken 126456 times.
✓ Branch 2 taken 252135 times.
✓ Branch 3 taken 115674 times.
783084 if(to_lower(*word1++) != *word2++) return true;
421 }
422 34770 return *word1;
423 }
424
425 //function: return the string without quotes around it, if any exists
426 //if they don't exist, return it unaltered
427 //it is not guaranteed to return str
428 //it is not guaranteed to not edit str
429 //the input must be freed even though it's garbage, the output must not
430 5235 inline const char * dequote(char * str)
431 {
432
3/3
✓ Branch 0 taken 372 times.
✓ Branch 1 taken 3173 times.
✓ Branch 2 taken 1690 times.
5235 if (*str!='"') return str;
433
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1690 times.
4455 char *end = strrchr(str, '"');
434
1/2
✓ Branch 0 taken 4455 times.
✗ Branch 1 not taken.
4455 if (end)
435 {
436 4455 *end = 0;
437 4455 char *quote = str+1;
438
7/10
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 2837 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 72 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 72 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1762 times.
✓ Branch 8 taken 72 times.
✓ Branch 9 taken 1690 times.
4599 while((quote = strstr(quote, "\"\""))) memmove(quote, quote+1, strlen(quote));
439 4455 return str + 1;
440 }
441 return nullptr;
442 }
443
444 15755 inline char * strqchr(const char * str, char key)
445 {
446
3/3
✓ Branch 0 taken 68965 times.
✓ Branch 1 taken 76308 times.
✓ Branch 2 taken 6000 times.
151273 while (*str != '\0')
447 {
448
3/3
✓ Branch 0 taken 1924 times.
✓ Branch 1 taken 68971 times.
✓ Branch 2 taken 68479 times.
139374 if (*str == key) { return const_cast<char*>(str); }
449
6/6
✓ Branch 0 taken 66698 times.
✓ Branch 1 taken 68470 times.
✓ Branch 2 taken 445 times.
✓ Branch 3 taken 66605 times.
✓ Branch 4 taken 93 times.
✓ Branch 5 taken 68034 times.
135520 else if (*str == '"' || *str == '\'')
450 {
451 // Special case hack for ''', which is currently our official way of handling the ' character.
452 // Even though it really stinks.
453
8/9
✓ Branch 0 taken 93 times.
✓ Branch 1 taken 436 times.
✓ Branch 2 taken 358 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.
881 if (str[0] == '\'' && str[1] == '\'' && str[2] == '\'') { str += 2; }
454 else
455 {
456 869 char delimiter = *str;
457
458 do
459 {
460 9073 str++;
461
462 // If we want to support backslash escapes, we'll have to add that right here.
463
6/6
✓ Branch 0 taken 4065 times.
✓ Branch 1 taken 4570 times.
✓ Branch 2 taken 4502 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 4140 times.
✓ Branch 5 taken 1 times.
9073 } while (*str != delimiter && *str != '\0');
464
465 // This feels like a superfluous check, but I can't really find a clean way to avoid it.
466
3/3
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 430 times.
✓ Branch 2 taken 438 times.
869 if (*str == '\0') { return nullptr; }
467 }
468 }
469
470 135518 str++;
471 }
472
473 11899 return nullptr;
474 }
475
476 2580 inline string substr(const char * str, int len)
477 {
478 2580 return string(str, len);
479 }
480
481
482 64158 inline char *strip_whitespace(char *str)
483 {
484
4/4
✓ Branch 0 taken 1532 times.
✓ Branch 1 taken 32373 times.
✓ Branch 2 taken 1971 times.
✓ Branch 3 taken 31785 times.
67661 while(is_space(*str)) str++;
485
4/4
✓ Branch 0 taken 29374 times.
✓ Branch 1 taken 42352 times.
✓ Branch 2 taken 28710 times.
✓ Branch 3 taken 10651 times.
79302 for(int i = strlen(str) - 1; i >= 0; i--)
486 {
487
4/4
✓ Branch 0 taken 21806 times.
✓ Branch 1 taken 7568 times.
✓ Branch 2 taken 21134 times.
✓ Branch 3 taken 7576 times.
58084 if(!is_space(str[i]))
488 {
489 42940 str[i + 1] = 0;
490 42940 return str;
491 }
492 }
493 21218 return str;
494 }
495 267 inline void strip_whitespace(string &str)
496 {
497
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()));
498 267 }
499
500 string &itrim(string &str, const char * left, const char * right);
501
502 5895 inline string &lower(string &old)
503 {
504 5895 int length = old.length();
505
4/4
✓ Branch 0 taken 175145 times.
✓ Branch 1 taken 5893 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 2 times.
181046 for (int i=0;i<length;i++) old.raw()[i]=(char)to_lower(old.data()[i]);
506 5895 return old;
507 }
508
509
510 // Returns number of connected lines - 1
511 template<typename stringarraytype>
512 45527 inline int getconnectedlines(stringarraytype& lines, int startline, string& out)
513 {
514 45527 int count = 0;
515
516
2/4
✓ Branch 0 taken 23163 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 22382 times.
✗ Branch 3 not taken.
45545 for (int i = startline; lines[i]; i++)
517 {
518 // The line should already be stripped of any comments at this point
519
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22382 times.
45545 int linestartpos = (int)strlen(lines[i]);
520
521
6/6
✓ Branch 0 taken 31953 times.
✓ Branch 1 taken 13592 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 16382 times.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 15553 times.
45545 if(linestartpos && lines[i][linestartpos - 1] == '\\')
522 {
523 18 count++;
524
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);
525 18 continue;
526 }
527 else
528 {
529
4/7
✓ Branch 0 taken 23154 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 23154 times.
✓ Branch 3 taken 22373 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 22373 times.
✗ Branch 6 not taken.
45527 out += string(lines[i], linestartpos);
530 45527 return count;
531 }
532 }
533
534 return count;
535 }
536