• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ParadoxGameConverters / commonItems / 12846535547

18 Jan 2025 06:41PM UTC coverage: 75.846% (-1.7%) from 77.556%
12846535547

Pull #274

github

web-flow
Merge 8b9494010 into b007cb890
Pull Request #274: Eliminate warnings

279 of 358 new or added lines in 13 files covered. (77.93%)

38 existing lines in 2 files now uncovered.

1837 of 2422 relevant lines covered (75.85%)

240.46 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.01
/ParserHelpers.cpp
1
#include "ParserHelpers.h"
2
#include "CommonRegexes.h"
3
#include "Log.h"
4
#include "StringUtils.h"
5
#include <charconv>
6
#include <sstream>
7

8

9

10
namespace commonItems
11
{
12

13
std::string getNextLexeme(std::istream& theStream);
14

15

16
void ignoreItem([[maybe_unused]] const std::string& unused, std::istream& theStream)
147✔
17
{
18
        auto next = getNextLexeme(theStream);
147✔
19
        if (next == "=")
147✔
20
        {
21
                next = getNextLexeme(theStream);
139✔
22
        }
23
        if (next == "rgb" || next == "hsv") // Needed for ignoring color. Example: "color2 = rgb { 2 4 8 }"
147✔
24
        {
25
                if (theStream.peek() == '{')
6✔
26
                {
27
                        next = getNextLexeme(theStream);
4✔
28
                }
29
                else // don't go further in cases like "type = rgb"
30
                {
31
                        return;
2✔
32
                }
33
        }
34
        if (next == "{")
145✔
35
        {
36
                auto braceDepth = 1;
11✔
37
                while (true)
38
                {
39
                        if (theStream.eof())
41✔
40
                        {
41
                                return;
11✔
42
                        }
43

44
                        auto token = getNextLexeme(theStream);
41✔
45
                        if (token == "{")
41✔
46
                        {
47
                                braceDepth++;
3✔
48
                        }
49
                        else if (token == "}")
38✔
50
                        {
51
                                braceDepth--;
14✔
52
                                if (braceDepth == 0)
14✔
53
                                {
54
                                        return;
11✔
55
                                }
56
                        }
57
                }
71✔
58
        }
59
}
147✔
60

61
void ignoreAndLogItem(const std::string& keyword, std::istream& theStream)
3✔
62
{
63
        Log(LogLevel::Debug) << "Ignoring keyword: " << keyword;
3✔
64
        ignoreItem(keyword, theStream);
3✔
65
}
3✔
66

67

NEW
68
void ignoreObject([[maybe_unused]] const std::string& unused, std::istream& theStream)
×
69
{
70
        auto braceDepth = 0;
×
71
        while (true)
72
        {
73
                if (theStream.eof())
×
74
                {
75
                        return;
×
76
                }
77

78
                auto token = getNextLexeme(theStream);
×
79
                if (token == "{")
×
80
                {
81
                        braceDepth++;
×
82
                }
83
                else if (token == "}")
×
84
                {
85
                        braceDepth--;
×
86
                        if (braceDepth == 0)
×
87
                        {
88
                                return;
×
89
                        }
90
                }
91
        }
×
92
}
93

94

NEW
95
void ignoreString([[maybe_unused]] const std::string& unused, std::istream& theStream)
×
96
{
97
        singleString ignore(theStream);
×
98
}
×
99

100

101

102
template <std::integral T> T stringToInteger(const std::string& str, bool skipPartialMatchWarning) // for integral types only
105✔
103
{
104
        T theInteger = 0;
105✔
105
        const auto last = str.data() + str.size();
105✔
106
        const auto [ptr, ec] = std::from_chars(str.data(), last, theInteger);
105✔
107
        if (ec != std::errc() || (!skipPartialMatchWarning && ptr != last)) // conversion either failed or was successful but not all characters matched
105✔
108
        {
109
                Log(LogLevel::Warning) << "string to integer - invalid argument: " << str;
5✔
110
        }
111
        return theInteger;
105✔
112
}
113
template signed char stringToInteger<signed char>(const std::string& str, bool skipPartialMatchWarning);
114
template unsigned char stringToInteger<unsigned char>(const std::string& str, bool skipPartialMatchWarning);
115
template short stringToInteger<short>(const std::string& str, bool skipPartialMatchWarning);
116
template unsigned short stringToInteger<unsigned short>(const std::string& str, bool skipPartialMatchWarning);
117
template int stringToInteger<int>(const std::string& str, bool skipPartialMatchWarning);
118
template unsigned int stringToInteger<unsigned int>(const std::string& str, bool skipPartialMatchWarning);
119
template long stringToInteger<long>(const std::string& str, bool skipPartialMatchWarning);
120
template unsigned long stringToInteger<unsigned long>(const std::string& str, bool skipPartialMatchWarning);
121
template long long stringToInteger<long long>(const std::string& str, bool skipPartialMatchWarning);
122
template unsigned long long stringToInteger<unsigned long long>(const std::string& str, bool skipPartialMatchWarning);
123

124
double stringToDouble(const std::string& str)
77✔
125
{
126
        double theDouble = 0.0;
77✔
127
        const auto last = str.data() + str.size();
77✔
128
        if (const auto [ptr, ec] = std::from_chars(str.data(), last, theDouble);
77✔
129
                 ec != std::errc() || ptr != last) // conversion either failed or was successful but not all characters matched
75✔
130
        {
131
                Log(LogLevel::Warning) << "string to double - invalid argument: " << str;
4✔
132
        }
133
        return theDouble;
77✔
134
}
135

136

137
[[nodiscard]] std::vector<int> getInts(std::istream& theStream)
6✔
138
{
139
        return intList{theStream}.getInts();
12✔
140
}
141

142

143
[[nodiscard]] std::vector<long long> getLlongs(std::istream& theStream)
1✔
144
{
145
        return llongList{theStream}.getLlongs();
2✔
146
}
147

148

149
[[nodiscard]] std::vector<unsigned long long> getULlongs(std::istream& theStream)
1✔
150
{
151
        return ullongList{theStream}.getULlongs();
2✔
152
}
153

154

155
[[nodiscard]] std::vector<double> getDoubles(std::istream& theStream)
9✔
156
{
157
        return doubleList{theStream}.getDoubles();
18✔
158
}
159

160

161
[[nodiscard]] std::vector<std::string> getStrings(std::istream& theStream)
29✔
162
{
163
        return stringList{theStream}.getStrings();
58✔
164
}
165

166

167
[[nodiscard]] int getInt(std::istream& theStream)
10✔
168
{
169
        return singleInt{theStream}.getInt();
10✔
170
}
171

172

173
[[nodiscard]] long long getLlong(std::istream& theStream)
2✔
174
{
175
        return singleLlong{theStream}.getLlong();
2✔
176
}
177

178

179
[[nodiscard]] unsigned long long getULlong(std::istream& theStream)
2✔
180
{
181
        return singleULlong{theStream}.getULlong();
2✔
182
}
183

184

185
[[nodiscard]] double getDouble(std::istream& theStream)
2✔
186
{
187
        return singleDouble{theStream}.getDouble();
2✔
188
}
189

190

191
[[nodiscard]] std::string getString(std::istream& theStream)
700✔
192
{
193
        return singleString{theStream}.getString();
1,400✔
194
}
195

196

197
intList::intList(std::istream& theStream)
13✔
198
{
199
        registerRegex(integerRegex, [this](const std::string& theInt, [[maybe_unused]] std::istream& unused) {
13✔
200
                integers.push_back(stringToInteger<int>(theInt));
26✔
201
        });
26✔
202
        registerRegex(quotedIntegerRegex, [this](const std::string& theInt, [[maybe_unused]] std::istream& unused) {
13✔
203
                const auto newInt = theInt.substr(1, theInt.size() - 2);
9✔
204
                integers.push_back(stringToInteger<int>(newInt));
9✔
205
        });
9✔
206

207
        parseStream(theStream);
13✔
208
}
13✔
209

210

211
llongList::llongList(std::istream& theStream)
8✔
212
{
213
        registerRegex(integerRegex, [this](const std::string& theLongLong, [[maybe_unused]] std::istream& unused) {
8✔
214
                llongs.push_back(stringToInteger<long long>(theLongLong));
15✔
215
        });
15✔
216
        registerRegex(quotedIntegerRegex, [this](const std::string& theLongLong, [[maybe_unused]] std::istream& unused) {
8✔
217
                const auto newLlong = theLongLong.substr(1, theLongLong.size() - 2);
6✔
218
                llongs.push_back(stringToInteger<long long>(newLlong));
6✔
219
        });
6✔
220

221
        parseStream(theStream);
8✔
222
}
8✔
223

224

225
ullongList::ullongList(std::istream& theStream)
6✔
226
{
227
        registerRegex(integerRegex, [this](const std::string& theUnsignedLongLong, [[maybe_unused]] std::istream& unused) {
6✔
228
                ullongs.push_back(stringToInteger<unsigned long long>(theUnsignedLongLong));
12✔
229
        });
12✔
230
        registerRegex(quotedIntegerRegex, [this](const std::string& theUnsignedLongLong, [[maybe_unused]] std::istream& unused) {
6✔
231
                const auto newULlong = theUnsignedLongLong.substr(1, theUnsignedLongLong.size() - 2);
3✔
232
                ullongs.push_back(stringToInteger<unsigned long long>(newULlong));
3✔
233
        });
3✔
234

235
        parseStream(theStream);
6✔
236
}
6✔
237

238

239
singleInt::singleInt(std::istream& theStream)
16✔
240
{
241
        getNextTokenWithoutMatching(theStream); // remove equals
16✔
242
        const auto token = remQuotes(*getNextTokenWithoutMatching(theStream));
16✔
243

244
        theInt = stringToInteger<int>(token);
16✔
245
}
16✔
246

247

248
singleLlong::singleLlong(std::istream& theStream)
8✔
249
{
250
        getNextTokenWithoutMatching(theStream); // remove equals
8✔
251
        const auto token = remQuotes(*getNextTokenWithoutMatching(theStream));
8✔
252

253
        theLongLong = stringToInteger<long long>(token);
8✔
254
}
8✔
255

256

257
singleULlong::singleULlong(std::istream& theStream)
6✔
258
{
259
        getNextTokenWithoutMatching(theStream); // equals
6✔
260
        const auto token = remQuotes(*getNextTokenWithoutMatching(theStream));
6✔
261

262
        theUnsignedLongLong = stringToInteger<unsigned long long>(token);
6✔
263
}
6✔
264

265

266
simpleObject::simpleObject(std::istream& theStream)
5✔
267
{
268
        getNextTokenWithoutMatching(theStream); // remove equals
5✔
269

270
        auto braceDepth = 0;
5✔
271
        std::string key;
5✔
272
        while (true)
273
        {
274
                if (theStream.eof())
73✔
275
                {
276
                        return;
×
277
                }
278

279
                char inputChar;
280
                theStream >> inputChar;
73✔
281

282
                if (inputChar == '{')
73✔
283
                {
284
                        braceDepth++;
6✔
285
                }
286
                else if (inputChar == '}')
67✔
287
                {
288
                        braceDepth--;
6✔
289
                        if (braceDepth == 0)
6✔
290
                        {
291
                                return;
5✔
292
                        }
293
                }
294
                else if (braceDepth > 1)
61✔
295
                {
296
                        // Internal object; ignore.
297
                }
298
                else if (inputChar == '=')
36✔
299
                {
300
                        auto value = getNextTokenWithoutMatching(theStream);
4✔
301
                        values[key] = *value;
4✔
302
                        key.clear();
4✔
303
                }
4✔
304
                else if (!std::isspace(inputChar))
32✔
305
                {
306
                        key += inputChar;
12✔
307
                }
308
        }
68✔
309
}
5✔
310

311

312
std::string simpleObject::getValue(const std::string& key) const
8✔
313
{
314
        if (const auto valueItr = values.find(key); valueItr != values.end())
8✔
315
        {
316
                return valueItr->second;
4✔
317
        }
318
        return {};
4✔
319
}
320

321

322
int simpleObject::getValueAsInt(const std::string& key) const
5✔
323
{
324
        const auto value = getValue(key);
5✔
325
        if (value.empty())
5✔
326
        {
327
                return 0;
3✔
328
        }
329
        return stringToInteger<int>(value);
2✔
330
}
5✔
331

332

333
doubleList::doubleList(std::istream& theStream)
24✔
334
{
335
        registerRegex(floatRegex, [this](const std::string& theDouble, [[maybe_unused]] std::istream& unused) {
24✔
336
                doubles.push_back(stringToDouble(theDouble));
61✔
337
        });
61✔
338
        registerRegex(quotedFloatRegex, [this](const std::string& theDouble, [[maybe_unused]] std::istream& unused) {
24✔
339
                const auto newDouble = remQuotes(theDouble);
6✔
340
                doubles.push_back(stringToDouble(newDouble));
6✔
341
        });
6✔
342

343
        parseStream(theStream);
24✔
344
}
24✔
345

346

347
singleDouble::singleDouble(std::istream& theStream)
7✔
348
{
349
        getNextTokenWithoutMatching(theStream); // remove equals
7✔
350
        const auto token = remQuotes(*getNextTokenWithoutMatching(theStream));
7✔
351

352
        theDouble = stringToDouble(token);
7✔
353
}
7✔
354

355

356
blobList::blobList(std::istream& theStream)
8✔
357
{
358
        auto next = getNextLexeme(theStream);
8✔
359
        if (next == "=")
8✔
360
        {
361
                next = getNextLexeme(theStream);
7✔
362
        }
363
        while (true)
364
        {
365
                if (next != "{")
8✔
366
                {
367
                        break;
2✔
368
                }
369

370
                auto braceDepth = 0;
6✔
371
                std::string toReturn;
6✔
372
                while (true)
373
                {
374
                        if (theStream.eof())
300✔
375
                        {
376
                                return;
×
377
                        }
378
                        char inputChar;
379
                        theStream >> inputChar;
300✔
380
                        if (inputChar == '{')
300✔
381
                        {
382
                                if (braceDepth > 0)
15✔
383
                                {
384
                                        toReturn += inputChar;
2✔
385
                                }
386
                                braceDepth++;
15✔
387
                        }
388
                        else if (inputChar == '}')
285✔
389
                        {
390
                                braceDepth--;
21✔
391
                                if (braceDepth > 0)
21✔
392
                                {
393
                                        toReturn += inputChar;
2✔
394
                                }
395
                                else if (braceDepth == 0)
19✔
396
                                {
397
                                        blobs.emplace_back(toReturn);
13✔
398
                                        toReturn.clear();
13✔
399
                                }
400
                                else if (braceDepth == -1)
6✔
401
                                {
402
                                        return;
6✔
403
                                }
404
                        }
405
                        else if (braceDepth == 0)
264✔
406
                        {
407
                                // Ignore this character. Only look for blobs.
408
                        }
409
                        else
410
                        {
411
                                toReturn += inputChar;
162✔
412
                        }
413
                }
294✔
414
        }
6✔
415
}
8✔
416

417

418
stringList::stringList(std::istream& theStream)
34✔
419
{
420
        registerKeyword(R"("")", []([[maybe_unused]] std::istream& unused) {
34✔
421
        });
×
422
        registerRegex(stringRegex, [this](const std::string& theString, [[maybe_unused]] std::istream& unused) {
34✔
423
                strings.push_back(theString);
36✔
424
        });
36✔
425
        registerRegex(quotedStringRegex, [this](const std::string& theString, [[maybe_unused]] std::istream& unused) {
34✔
426
                strings.emplace_back(remQuotes(theString));
35✔
427
        });
35✔
428

429
        parseStream(theStream);
34✔
430
}
34✔
431

432

433
singleString::singleString(std::istream& theStream)
712✔
434
{
435
        getNextTokenWithoutMatching(theStream); // equals sign
712✔
436
        theString = remQuotes(*getNextTokenWithoutMatching(theStream));
712✔
437
}
712✔
438

439

440
stringOfObject::stringOfObject(std::istream& theStream)
1✔
441
{
442
        auto braceDepth = 0;
1✔
443
        while (true)
444
        {
445
                if (theStream.eof())
34✔
446
                {
447
                        return;
1✔
448
                }
449

450
                char inputChar;
451
                theStream >> inputChar;
34✔
452

453
                theString += inputChar;
34✔
454

455
                if (inputChar == '{')
34✔
456
                {
457
                        braceDepth++;
2✔
458
                }
459
                else if (inputChar == '}')
32✔
460
                {
461
                        braceDepth--;
2✔
462
                        if (braceDepth == 0)
2✔
463
                        {
464
                                return;
1✔
465
                        }
466
                }
467
        }
33✔
468
}
×
469

470

471
stringOfItem::stringOfItem(std::istream& theStream)
14✔
472
{
473
        auto next = getNextLexeme(theStream);
14✔
474
        if (next == "=")
14✔
475
        {
476
                theString += next + " ";
6✔
477
                next = getNextLexeme(theStream);
6✔
478
        }
479
        theString += next;
14✔
480

481
        if (next == "{")
14✔
482
        {
483
                bool inQuotes = false;
11✔
484
                auto braceDepth = 1;
11✔
485
                while (true)
486
                {
487
                        if (theStream.eof())
205✔
488
                        {
489
                                return;
11✔
490
                        }
491

492
                        char inputChar;
493
                        theStream >> inputChar;
205✔
494

495
                        theString += inputChar;
205✔
496

497
                        if (inputChar == '\"')
205✔
498
                        {
499
                                if (!inQuotes)
8✔
500
                                {
501
                                        inQuotes = true;
4✔
502
                                }
503
                                else
504
                                {
505
                                        inQuotes = false;
4✔
506
                                }
507
                        }
508
                        if (inputChar == '{' && !inQuotes)
205✔
509
                        {
510
                                braceDepth++;
2✔
511
                        }
512
                        else if (inputChar == '}' && !inQuotes)
203✔
513
                        {
514
                                braceDepth--;
13✔
515
                                if (braceDepth == 0)
13✔
516
                                {
517
                                        return;
11✔
518
                                }
519
                        }
520
                }
194✔
521
        }
522
}
14✔
523

524

525
stringsOfItems::stringsOfItems(std::istream& theStream)
1✔
526
{
527
        registerRegex(catchallRegex, [this](const std::string& itemName, std::istream& lambda_stream) {
1✔
528
                const stringOfItem theItem(lambda_stream);
2✔
529
                theStrings.push_back(itemName + " " + theItem.getString() + "\n");
2✔
530
        });
2✔
531

532
        parseStream(theStream);
1✔
533
}
1✔
534

535

536
stringsOfItemNames::stringsOfItemNames(std::istream& theStream)
2✔
537
{
538
        registerRegex(catchallRegex, [this](const std::string& itemName, std::istream& lambda_stream) {
2✔
539
                ignoreItem(itemName, lambda_stream);
4✔
540
                theStrings.push_back(itemName);
4✔
541
        });
4✔
542

543
        parseStream(theStream);
2✔
544
}
2✔
545

546

547
assignments::assignments(std::istream& theStream)
1✔
548
{
549
        registerRegex(catchallRegex, [this](const std::string& assignmentName, std::istream& lambda_stream) {
1✔
550
                getNextTokenWithoutMatching(lambda_stream); // remove equals
2✔
551
                auto assignmentValue = getNextTokenWithoutMatching(lambda_stream);
2✔
552
                theAssignments.emplace(std::make_pair(assignmentName, *assignmentValue));
2✔
553
        });
2✔
554

555
        parseStream(theStream);
1✔
556
}
1✔
557

558
} // namespace commonItems
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc