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

z00m128 / sjasmplus / 26135148044

20 May 2026 01:12AM UTC coverage: 97.798% (+0.5%) from 97.312%
26135148044

push

github

ped7g
CI: details tuning, switching coveralls.io to lcov data

Changes:
- Makefile has new target `coverage-lcov` producing web page with lcov
- using official coveralls github action to upload coverage
- processing coverage data for coveralls.io with lcov
- more diverse linux build runners (x64 + arm64, gcc container + ubuntu
runner)
- both macos-15 + macos-26 (arm64 only)
- test runner script shows sjasmplus version just before summary
- sjasmplus --version shows when unit tests are included ("+ut" version
suffix)
- `make clean` now also removes HTML coverage pages and
build/{examples|tests} folders

1 of 1 new or added line in 1 file covered. (100.0%)

154 existing lines in 14 files now uncovered.

10128 of 10356 relevant lines covered (97.8%)

172537.11 hits per line

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

98.14
/sjasm/io_err.cpp
1
/*
2

3
  SjASMPlus Z80 Cross Compiler - modified - error/warning module
4

5
  Copyright (c) 2006 Sjoerd Mastijn (original SW)
6
  Copyright (c) 2020 Peter Ped Helcmanovsky (error/warning module)
7

8
  This software is provided 'as-is', without any express or implied warranty.
9
  In no event will the authors be held liable for any damages arising from the
10
  use of this software.
11

12
  Permission is granted to anyone to use this software for any purpose,
13
  including commercial applications, and to alter it and redistribute it freely,
14
  subject to the following restrictions:
15

16
  1. The origin of this software must not be misrepresented; you must not claim
17
         that you wrote the original software. If you use this software in a product,
18
         an acknowledgment in the product documentation would be appreciated but is
19
         not required.
20

21
  2. Altered source versions must be plainly marked as such, and must not be
22
         misrepresented as being the original software.
23

24
  3. This notice may not be removed or altered from any source distribution.
25

26
*/
27

28
// io_err.cpp
29

30
#include "sjdefs.h"
31
#include <vector>
32
#include <map>
33
#include <algorithm>
34

35
TextFilePos skipEmitMessagePos;
36
const char* extraErrorWarningPrefix = nullptr;
37

38
static bool IsSkipErrors = false;
39
static char ErrorLine[LINEMAX2], ErrorLine2[LINEMAX2];
40
static aint PreviousErrorLine = -1L;
41

42
static const char* nullptr_message_txt = "<nullptr>";
43

44
static void initErrorLine() {                // adds filename + line of definition if possible
6,012✔
45
        *ErrorLine = 0;
6,012✔
46
        *ErrorLine2 = 0;
6,012✔
47
        // when OpenFile is reporting error, the filename is still nullptr, but pass==1 already
48
        if (pass < 1 || LASTPASS < pass || sourcePosStack.empty()) return;
6,012✔
49
        SPRINTF2(ErrorLine, LINEMAX2, "%s(%d): ", sourcePosStack.back().filename, sourcePosStack.back().line);
5,973✔
50
        // if the error filename:line is not identical with current source line, add ErrorLine2 about emit
51
        if (std::max(1, aint(IncludeLevel + 1)) < aint(sourcePosStack.size())) {
5,973✔
52
                auto previous = sourcePosStack.end() - 2;
189✔
53
                if (*previous == skipEmitMessagePos && previous != sourcePosStack.begin()) --previous;
189✔
54
                if (*previous != skipEmitMessagePos && *previous != sourcePosStack.back()) {
189✔
55
                        SPRINTF2(ErrorLine2, LINEMAX2, "%s(%d): ^ emitted from here\n", previous->filename, previous->line);
75✔
56
                }
57
        }
58
}
59

60
static void trimAndAddEol(char* lineBuffer) {
11,972✔
61
        if (!lineBuffer[0]) return;                // ignore empty line buffer
11,972✔
62
        char* lastChar = lineBuffer + strlen(lineBuffer) - 1;
6,060✔
63
        while (lineBuffer < lastChar && (' ' == *lastChar || '\t' == *lastChar)) --lastChar;        // trim ending whitespace
10,109✔
64
        if ('\n' != *lastChar) lastChar[1] = '\n', lastChar[2] = 0;        // add EOL character if not present
6,060✔
65
}
66

67
static void outputErrorLine(const EOutputVerbosity errorLevel, int keywordPos, int keywordSz) {
6,012✔
68
        assert(0 <= keywordPos && 1 <= keywordSz && keywordPos + keywordSz <= int(strlen(ErrorLine)));        // keyword is mandatory
6,012✔
69
        auto lstFile = GetListingFile();
6,012✔
70
        if (!lstFile && errorLevel < Options::OutputVerbosity) return;        // no output required
6,012✔
71
        // trim end of error/warning line and add EOL char if needed
72
        trimAndAddEol(ErrorLine);
5,986✔
73
        trimAndAddEol(ErrorLine2);
5,986✔
74
        // always print the message into listing file (the OutputVerbosity does not apply to listing)
75
        if (lstFile) {
5,986✔
76
                fputs(ErrorLine, lstFile);
5,949✔
77
                if (*ErrorLine2) fputs(ErrorLine2, lstFile);
5,949✔
78
        }
79
        // print the error into stderr if OutputVerbosity allows this type of message
80
        if (Options::OutputVerbosity <= errorLevel) {
5,986✔
81
                if (keywordPos) cerr.write(ErrorLine, keywordPos);        // output filename and line position
37✔
82
                // colorize the keyword in message
83
                if (OV_ERROR == errorLevel) _CERR Options::tcols->error _END;
37✔
84
                if (OV_WARNING == errorLevel) _CERR Options::tcols->warning _END;
37✔
85
                cerr.write(ErrorLine + keywordPos, keywordSz);
37✔
86
                // switch color off for rest of message
87
                _CERR Options::tcols->end _END;
37✔
88
                _CERR ErrorLine + keywordPos + keywordSz _END;
37✔
89
                if (*ErrorLine2) _CERR ErrorLine2 _END;
37✔
90
        }
91
}
92

93
void Error(const char* message, const char* badValueMessage, EStatus type) {
23,337✔
94
        // check if it is correct pass by the type of error
95
        if (type == EARLY && LASTPASS <= pass) return;
23,337✔
96
        if ((type == SUPPRESS || type == IF_FIRST || type == PASS3) && pass < LASTPASS) return;
23,335✔
97
        if (PASS03 == type && 0 < pass && pass < LASTPASS) return;
5,254✔
98
        // check if this one should be skipped due to type constraints and current-error-state
99
        if (FATAL != type && PreviousErrorLine == CompiledCurrentLine) {
5,240✔
100
                // non-fatal error, on the same line as previous, maybe skip?
101
                if (IsSkipErrors || IF_FIRST == type) return;
884✔
102
        }
103
        // update current-error-state (reset "skip" on new parsed-line, set "skip" by SUPPRESS type)
104
        IsSkipErrors = (IsSkipErrors && (PreviousErrorLine == CompiledCurrentLine)) || (SUPPRESS == type);
4,508✔
105
        PreviousErrorLine = CompiledCurrentLine;
4,508✔
106
        ++ErrorCount;                                                        // number of non-skipped (!) errors
4,508✔
107

108
        DefineTable.Replace("__ERRORS__", ErrorCount);
4,508✔
109

110
        initErrorLine();
4,508✔
111
        const int errorTxtPos = strlen(ErrorLine);
4,508✔
112
        STRCAT(ErrorLine, LINEMAX2-1, "error: ");
4,508✔
113
        if (extraErrorWarningPrefix) STRCAT(ErrorLine, LINEMAX2-1, extraErrorWarningPrefix);
4,508✔
114
        STRCAT(ErrorLine, LINEMAX2-1, message ? message : nullptr_message_txt);
4,508✔
115
        if (badValueMessage) {
4,508✔
116
                STRCAT(ErrorLine, LINEMAX2-1, ": "); STRCAT(ErrorLine, LINEMAX2-1, badValueMessage);
4,075✔
117
        }
118
        outputErrorLine(OV_ERROR, errorTxtPos, 5);
4,508✔
119
        // terminate whole assembler in case of fatal error
120
        if (type == FATAL) {
4,508✔
121
                ExitASM(1);
12✔
122
        }
123
}
124

125
void ErrorInt(const char* message, aint badValue, EStatus type) {
171✔
126
        char numBuf[24];
127
        SPRINTF1(numBuf, 24, "%d", badValue);
171✔
128
        Error(message, numBuf, type);
171✔
129
}
171✔
130

UNCOV
131
void ErrorOOM() {                // out of memory
×
UNCOV
132
        Error("Not enough memory!", nullptr, FATAL);
×
UNCOV
133
}
×
134

135
static void WarningImpl(const char* id, const char* message, const char* badValueMessage, EWStatus type) {
1,531✔
136
        // turn the warning into error if "Warnings as errors" is switched on
137
        if (Options::syx.WarningsAsErrors) switch (type) {
1,531✔
138
                case W_EARLY:        Error(message, badValueMessage, EARLY); return;
2✔
139
                case W_PASS3:        Error(message, badValueMessage, PASS3); return;
15✔
140
                case W_PASS03:        Error(message, badValueMessage, PASS03); return;
1✔
141
                case W_ALL:                Error(message, badValueMessage, ALL); return;
9✔
142
        }
143

144
        ++WarningCount;
1,504✔
145
        DefineTable.Replace("__WARNINGS__", WarningCount);
1,504✔
146

147
        initErrorLine();
1,504✔
148
        const int warningTxtPos = strlen(ErrorLine);
1,504✔
149
        if (id) {
1,504✔
150
                STRCAT(ErrorLine, LINEMAX2-1, "warning[");
1,174✔
151
                STRCAT(ErrorLine, LINEMAX2-1, id);
1,174✔
152
                STRCAT(ErrorLine, LINEMAX2-1, "]: ");
1,174✔
153
        } else {
154
                STRCAT(ErrorLine, LINEMAX2-1, "warning: ");
330✔
155
        }
156
        if (extraErrorWarningPrefix) STRCAT(ErrorLine, LINEMAX2-1, extraErrorWarningPrefix);
1,504✔
157
        STRCAT(ErrorLine, LINEMAX2-1, message ? message : nullptr_message_txt);
1,504✔
158
        if (badValueMessage) {
1,504✔
159
                STRCAT(ErrorLine, LINEMAX2-1, ": "); STRCAT(ErrorLine, LINEMAX2-1, badValueMessage);
416✔
160
        }
161
        outputErrorLine(OV_WARNING, warningTxtPos, 7);
1,504✔
162
}
163

164
struct WarningEntry {
165
        bool enabled;
166
        const char* txt;
167
        const char* help;
168
};
169

170
typedef std::map<const char*, WarningEntry> messages_map;
171

172
const char* W_NO_RAMTOP = "noramtop";
173
const char* W_DEV_RAMTOP = "devramtop";
174
const char* W_FILE_ORG = "fileorg";
175
const char* W_DISPLACED_ORG = "displacedorg";
176
const char* W_ORG_PAGE = "orgpage";
177
const char* W_FWD_REF = "fwdref";
178
const char* W_LUA_MC_PASS = "luamc";
179
const char* W_NEX_STACK = "nexstack";
180
const char* W_SNA_48 = "sna48";
181
const char* W_SNA_128 = "sna128";
182
const char* W_TRD_EXT_INVALID = "trdext";
183
const char* W_TRD_EXT_3 = "trdext3";
184
const char* W_TRD_EXT_B = "trdextb";
185
const char* W_TRD_DUPLICATE = "trddup";
186
const char* W_RELOCATABLE_ALIGN = "relalign";
187
const char* W_READ_LOW_MEM = "rdlow";
188
const char* W_REL_DIVERTS = "reldiverts";
189
const char* W_REL_UNSTABLE = "relunstable";
190
const char* W_DISP_MEM_PAGE = "dispmempage";
191
const char* W_BP_FILE = "bpfile";
192
const char* W_SLD_SWAP = "sldswap";
193
const char* W_OUT0 = "out0";
194
const char* W_BACKSLASH = "backslash";
195
const char* W_OPKEYWORD = "opkeyword";
196
const char* W_BE_HOST = "behost";
197
const char* W_FAKE = "fake";
198
const char* W_ENABLE_ALL = "all";
199
const char* W_ZERO_DECIMAL = "decimalz";
200
const char* W_NON_ZERO_DECIMAL = "decimaln";
201
const char* W_SHORT_BLOCK = "shortblock";
202
const char* W_EMPTY_STRING = "emptystr";
203

204
static messages_map w_texts = {
205
        { W_NO_RAMTOP,
206
                { true,
207
                        "current device doesn't init memory in any way (RAMTOP is ignored)",
208
                        "Warn when device ignores <ramtop> argument."
209
                }
210
        },
211
        { W_DEV_RAMTOP,
212
                { true,
213
                        "[DEVICE] this device was already opened with different RAMTOP value",
214
                        "Warn when different <ramtop> is used for same device."
215
                }
216
        },
217
        { W_FILE_ORG,
218
                { true,
219
                        "ORG does not pad output file to reach target address, bytes skipped",
220
                        "Warn about ORG skipping bytes in OUTPUT/raw/TAPOUT file."
221
                }
222
        },
223
        { W_DISPLACED_ORG,
224
                { true,
225
                        "ORG-address set inside displaced block, the physical address is not modified, only displacement address",
226
                        "Warn about ORG-address used inside DISP block."
227
                }
228
        },
229
        { W_ORG_PAGE,
230
                { true,
231
                        "[ORG] page argument affects current slot while address is outside",
232
                        "Warn about ORG address vs page argument mismatch."
233
                }
234
        },
235
        { W_FWD_REF,
236
                { true,
237
                        "forward reference of symbol",
238
                        "Warn about using undefined symbol in risky way."
239
                }
240
        },
241
        { W_LUA_MC_PASS,
242
                { true,
243
                        "When lua script emits machine code bytes, use \"ALLPASS\" modifier",
244
                        "Warn when lua script is not ALLPASS, but emits bytes."
245
                }
246
        },
247
        { W_NEX_STACK,
248
                { true,
249
                        "[SAVENEX] non-zero data are in stackAddress area, may get overwritten by NEXLOAD",
250
                        "Warn when NEX stack points into non-empty memory."
251
                }
252
        },
253
        { W_SNA_48,
254
                { true,
255
                        "[SAVESNA] RAM <0x4000-0x4001> will be overwritten due to 48k snapshot imperfect format.",
256
                        "Warn when 48k SNA does use screen for stack."
257
                }
258
        },
259
        { W_SNA_128,
260
                { true,
261
                        "only 128kb will be written to snapshot",
262
                        "Warn when saving snapshot from 256+ki device."
263
                }
264
        },
265
        { W_TRD_EXT_INVALID,
266
                { true,
267
                        "invalid file extension, TRDOS official extensions are B, C, D and #.",
268
                        "Warn when TRD file uses unofficial/invalid extension."
269
                }
270
        },
271
        { W_TRD_EXT_3,
272
                { true,
273
                        "3-letter extension of TRDOS file (unofficial extension)",
274
                        "Warn when TRD file does use 3-letter extension."
275
                }
276
        },
277
        { W_TRD_EXT_B,
278
                { true,
279
                        "the \"B\" extension is always single letter",
280
                        "Warn when long extension starts with letter B (can not)."
281
                }
282
        },
283
        { W_TRD_DUPLICATE,
284
                { true,
285
                        "TRD file already exists, creating one more!",
286
                        "Warn when second file with same name is added to disk."
287
                }
288
        },
289
        { W_RELOCATABLE_ALIGN,
290
                { true,
291
                        "[ALIGN] inside relocation block: may become misaligned when relocated",
292
                        "Warn when align is used inside relocatable code."
293
                }
294
        },
295
        { W_READ_LOW_MEM,
296
                { false,
297
                        "Reading memory at low address",
298
                        "Warn when reading memory from addresses 0..255."
299
                }
300
        },
301
        { W_REL_DIVERTS,
302
                { true,
303
                        "Expression can't be relocated by simple \"+offset\" mechanics, value diverts differently.",
304
                        "Warn when relocated expression differs non-trivially."
305
                }
306
        },
307
        { W_REL_UNSTABLE,
308
                { true,
309
                        "Relocation makes one of the expressions unstable, resulting machine code is not relocatable",
310
                        "Warn when expression result can't be relocated."
311
                }
312
        },
313
        { W_DISP_MEM_PAGE,
314
                { true,
315
                        "DISP memory page differs from current mapping",
316
                        "Warn when DISP page differs from current mapping."
317
                }
318
        },
319
        { W_BP_FILE,
320
                { true,
321
                        "breakpoints file was not specified",
322
                        "Warn when SETBREAKPOINT is used without breakpoint file."
323
                }
324
        },
325
        { W_SLD_SWAP,
326
                { true,
327
                        "SLDOPT swapon/swapoff unevenly paired within macro/include",
328
                        "Warn when SLD swap on/off is uneven per macro/include."
329
                }
330
        },
331
        { W_OUT0,
332
                { true,
333
                        "'out (c),0' is unstable, on CMOS based chips it does `out (c),255`",
334
                        "Warn when instruction `out (c),0` is used."
335
                }
336
        },
337
        { W_BACKSLASH,
338
                { true,
339
                        "File name contains \\, use / instead (\\ fails on most of the supported platforms)",
340
                        "Warn when file name contains backslash."
341
                }
342
        },
343
        { W_OPKEYWORD,
344
                { true,
345
                        "Label collides with one of the operator keywords, try capitalizing it or other name",
346
                        "Warn when symbol name collides with operator keyword."
347
                }
348
        },
349
        { W_BE_HOST,
350
                { true,
351
                        "Big-endian host detected: support is experimental, please report any issues",
352
                        "Warn when big-endian host runs sjasmplus (experimental)."
353
                }
354
        },
355
        { W_FAKE,
356
                { true,        // fake-warnings are enabled/disabled through --syntax, this value here is always true
357
                                // the main reason is that fake warning enabled can be reset/push/pop by OPT
358
                        "Fake instruction",
359
                        "Warn when fake instruction is used in the source."
360
                }
361
        },
362
        { W_ZERO_DECIMAL,
363
                { false,
364
                        "decimal part is ignored",
365
                        "Warn when numeric constant has decimal part (equal to zero)"
366
                }
367
        },
368
        { W_NON_ZERO_DECIMAL,
369
                { true,
370
                        "decimal part is ignored",
371
                        "Warn when numeric constant has non zero decimal part"
372
                }
373
        },
374
        { W_SHORT_BLOCK,
375
                { true,
376
                        "init data for block truncated to length",
377
                        "Warn when block's length is shorter than init data"
378
                }
379
        },
380
        { W_EMPTY_STRING,
381
                { true,
382
                        "empty string",
383
                        "Warn when string literal is empty"
384
                }
385
        },
386
        { W_ENABLE_ALL,
387
                { false,
388
                        "",                // not emitted by code, just command-line option
389
                        "Enable/disable all id-warnings"
390
                }
391
        },
392
};
393

394
static messages_map::iterator findWarningByIdText(const char* id) {
621✔
395
        // like w_texts.find(id) but compares id content (string), not pointer
396
        return std::find_if(w_texts.begin(), w_texts.end(), [id](const auto& v){ return !strcmp(id, v.first); } );
15,246✔
397
}
398

399
static bool & warning_state(messages_map::value_type & v) {
831✔
400
        // W_FAKE (ID "fake") stores enabled/disabled state in Options::syx to handle reset/push/pop of the state
401
        if (W_FAKE == v.first) return Options::syx.FakeWarning;
831✔
402
        // other warnings have global state stored in w_texts map
403
        return v.second.enabled;
818✔
404
}
405

406
bool suppressedById(const char* id) {
3,475✔
407
        assert(id);
3,475✔
408
        if (nullptr == eolComment) return false;
3,475✔
409
        const size_t idLength = strlen(id);
314✔
410
        assert(0 < idLength);
314✔
411
        const char* commentToCheck = eolComment;
314✔
412
        while (const char* idPos = strstr(commentToCheck, id)) {
333✔
413
                if (!strcmp(id, W_FAKE)) return true;                                // "fake" only is enough to suppress those
159✔
414
                commentToCheck = idPos + idLength;
151✔
415
                if ('-' == commentToCheck[0] && 'o' == commentToCheck[1] && 'k' == commentToCheck[2]) {
151✔
416
                        return true;
132✔
417
                }
418
        }
19✔
419
        return false;
174✔
420
}
421

422
static bool isInactiveTypeInCurrentPass(EWStatus type) {
4,574✔
423
        switch (type) {
4,574✔
424
                case W_EARLY:        // "early" is inactive during pass3+
54✔
425
                        return LASTPASS <= pass;
54✔
426
                case W_PASS3:        // "pass3" is inactive during 0..2 pass
4,473✔
427
                        return pass < LASTPASS;
4,473✔
428
                case W_PASS03:        // "pass03" is inactive during 1..2 pass
6✔
429
                        return 0 < pass && pass < LASTPASS;
6✔
430
                default:                // never inactive for other types (W_ALL)
41✔
431
                        return false;
41✔
432
        }
433
}
434

435
void Warning(const char* message, const char* badValueMessage, EWStatus type) {
796✔
436
        if (isInactiveTypeInCurrentPass(type)) return;
796✔
437
        WarningImpl(nullptr, message, badValueMessage, type);
342✔
438
}
439

440
void WarningById(const char* id, const char* badValueMessage, EWStatus type) {
3,778✔
441
        if (isInactiveTypeInCurrentPass(type)) return;
3,940✔
442

443
        // id-warnings could be suppressed by "id-ok" anywhere in eol comment
444
        if (suppressedById(id)) return;
1,351✔
445

446
        const messages_map::const_iterator idMessage = w_texts.find(id);        // searching by id POINTER!
1,241✔
447
        assert(idMessage != w_texts.end());
1,241✔
448

449
        if (!idMessage->second.enabled) return;
1,241✔
450
        WarningImpl(id, idMessage->second.txt, badValueMessage, type);
1,189✔
451
}
452

453
void WarningById(const char* id, int badValue, EWStatus type) {
367✔
454
        char buf[32];
455
        SPRINTF1(buf, 32, "%d", badValue);
367✔
456
        WarningById(id, buf, type);
367✔
457
}
367✔
458

459
void CliWoption(const char* option) {
630✔
460
        if (!option[0]) {
630✔
461
                // from command line 0 == pass, from source by OPT the pass is above zero
462
                Error("no argument after -W", (0 == pass) ? nullptr : bp, PASS03);
3✔
463
                return;
15✔
464
        }
465
        // check for specific id, with possible "no-" prefix ("-Wabs" vs "-Wno-abs")
466
        const bool enable = strncmp("no-", option, 3);
627✔
467
        const char* id = enable ? option : option + 3;
627✔
468
        // handle ID "all"
469
        if (!strcmp(id, W_ENABLE_ALL)) {
627✔
470
                for (auto & warning_entry : w_texts) warning_state(warning_entry) = enable;
192✔
471
                return;
6✔
472
        }
473
        auto warning_it = findWarningByIdText(id);
621✔
474
        if (w_texts.end() == warning_it) {
621✔
475
                Warning("unknown warning id in -W option", id, W_PASS03);
6✔
476
                return;
6✔
477
        }
478
        warning_state(*warning_it) = enable;
615✔
479
}
480

481
static const char* spaceFiller = "               ";
482
static const char* txt_on        = "on";
483
static const char* txt_off        = "off";
484
static const char* txt_none        = "      ";
485
static constexpr const int STATE_TXT_BUFFER_SIZE = 64;
486

487
static void initWarningStateTxt(char* buffer, const char* id) {
31✔
488
        if (W_ENABLE_ALL == id) {
31✔
489
                STRCPY(buffer, STATE_TXT_BUFFER_SIZE, txt_none);
1✔
490
                return;
1✔
491
        }
492
        const bool state = warning_state(*w_texts.find(id));
30✔
493
        buffer[0] = '[';
30✔
494
        STRCPY(buffer + 1, STATE_TXT_BUFFER_SIZE-1, state ? Options::tcols->display : Options::tcols->warning);
30✔
495
        STRCAT(buffer, STATE_TXT_BUFFER_SIZE, state ? txt_on : txt_off);
30✔
496
        STRCAT(buffer, STATE_TXT_BUFFER_SIZE, Options::tcols->end);
30✔
497
        STRCAT(buffer, STATE_TXT_BUFFER_SIZE, "] ");
30✔
498
        if (state) STRCAT(buffer, STATE_TXT_BUFFER_SIZE, " ");
30✔
499
}
500

501
void PrintHelpWarnings() {
1✔
502
        char state_txt[STATE_TXT_BUFFER_SIZE+1];
503
        _COUT "The following options control compiler warning messages:" _ENDL;
1✔
504
        std::vector<const char*> ids;
1✔
505
        ids.reserve(w_texts.size());
1✔
506
        for (const auto& w_text : w_texts) ids.push_back(w_text.first);
32✔
507
        std::sort(ids.begin(), ids.end(), [](const char* a, const char* b) -> bool { return (strcmp(a,b) < 0); } );
201✔
508
        for (const auto& id : ids) {
32✔
509
                assert(strlen(id) < strlen(spaceFiller));
31✔
510
                initWarningStateTxt(state_txt, id);
31✔
511
                _COUT " -W" _CMDL Options::tcols->bold _CMDL Options::tcols->warning _CMDL id _CMDL Options::tcols->end _CMDL spaceFiller+strlen(id) _CMDL state_txt _CMDL w_texts[id].help _ENDL;
31✔
512
        }
513
        _COUT "Use -W" _CMDL Options::tcols->bold _CMDL Options::tcols->warning _CMDL "no-" _CMDL Options::tcols->end;
1✔
514
        _COUT " prefix to disable specific warning, example: " _CMDL Options::tcols->display _CMDL "-Wno-out0" _CMDL Options::tcols->end _ENDL;
1✔
515
        _COUT "Use -ok suffix in comment to suppress it per line, example: ";
1✔
516
        _COUT Options::tcols->display _CMDL "out (c),0 ; out0-ok" _CMDL Options::tcols->end _ENDL;
1✔
517
}
1✔
518

519
//eof io_err.cpp
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

© 2026 Coveralls, Inc