mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-23 19:42:08 +00:00
Use LCOV_EXCL comments to exclude some lines from test coverage (#1662)
This commit is contained in:
@@ -119,9 +119,11 @@ void fstk_SetPreIncludeFile(std::string const &path) {
|
||||
warnx("Overriding pre-included filename %s", preIncludeName.c_str());
|
||||
}
|
||||
preIncludeName = path;
|
||||
// LCOV_EXCL_START
|
||||
if (verbose) {
|
||||
printf("Pre-included filename %s\n", preIncludeName.c_str());
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
static void printDep(std::string const &path) {
|
||||
@@ -308,9 +310,11 @@ void fstk_RunInclude(std::string const &path, bool preInclude) {
|
||||
|
||||
if (!fullPath) {
|
||||
if (generatedMissingIncludes && !preInclude) {
|
||||
// LCOV_EXCL_START
|
||||
if (verbose) {
|
||||
printf("Aborting (-MG) on INCLUDE file '%s' (%s)\n", path.c_str(), strerror(errno));
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
failedOnMissingInclude = true;
|
||||
} else {
|
||||
error("Unable to open included file '%s': %s\n", path.c_str(), strerror(errno));
|
||||
@@ -319,7 +323,7 @@ void fstk_RunInclude(std::string const &path, bool preInclude) {
|
||||
}
|
||||
|
||||
if (!newFileContext(*fullPath, false)) {
|
||||
fatalerror("Failed to set up lexer for file include\n");
|
||||
fatalerror("Failed to set up lexer for file include\n"); // LCOV_EXCL_LINE
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ struct FileUnmapDeleter {
|
||||
|
||||
static char *mapFile(int fd, std::string const &path, size_t size) {
|
||||
void *mappingAddr = mmap(nullptr, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
// LCOV_EXCL_START
|
||||
if (mappingAddr == MAP_FAILED && errno == ENOTSUP) {
|
||||
// The implementation may not support MAP_PRIVATE; try again with MAP_SHARED
|
||||
// instead, offering, I believe, weaker guarantees about external modifications to
|
||||
@@ -86,6 +87,7 @@ static char *mapFile(int fd, std::string const &path, size_t size) {
|
||||
}
|
||||
mappingAddr = mmap(nullptr, size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
return mappingAddr != MAP_FAILED ? static_cast<char *>(mappingAddr) : nullptr;
|
||||
}
|
||||
|
||||
@@ -412,21 +414,27 @@ bool LexerState::setFileAsNextState(std::string const &filePath, bool updateStat
|
||||
if (filePath == "-") {
|
||||
path = "<stdin>";
|
||||
content.emplace<BufferedContent>(STDIN_FILENO);
|
||||
// LCOV_EXCL_START
|
||||
if (verbose) {
|
||||
printf("Opening stdin\n");
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
} else {
|
||||
struct stat statBuf;
|
||||
if (stat(filePath.c_str(), &statBuf) != 0) {
|
||||
// LCOV_EXCL_START
|
||||
error("Failed to stat file \"%s\": %s\n", filePath.c_str(), strerror(errno));
|
||||
return false;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
path = filePath;
|
||||
|
||||
int fd = open(path.c_str(), O_RDONLY);
|
||||
if (fd < 0) {
|
||||
// LCOV_EXCL_START
|
||||
error("Failed to open file \"%s\": %s\n", path.c_str(), strerror(errno));
|
||||
return false;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
bool isMmapped = false;
|
||||
@@ -438,9 +446,11 @@ bool LexerState::setFileAsNextState(std::string const &filePath, bool updateStat
|
||||
content.emplace<ViewedContent>(
|
||||
std::shared_ptr<char[]>(mappingAddr, FileUnmapDeleter(size)), size
|
||||
);
|
||||
// LCOV_EXCL_START
|
||||
if (verbose) {
|
||||
printf("File \"%s\" is mmap()ped\n", path.c_str());
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
isMmapped = true;
|
||||
}
|
||||
}
|
||||
@@ -448,6 +458,7 @@ bool LexerState::setFileAsNextState(std::string const &filePath, bool updateStat
|
||||
if (!isMmapped) {
|
||||
// Sometimes mmap() fails or isn't available, so have a fallback
|
||||
content.emplace<BufferedContent>(fd);
|
||||
// LCOV_EXCL_START
|
||||
if (verbose) {
|
||||
if (statBuf.st_size == 0) {
|
||||
printf("File \"%s\" is empty\n", path.c_str());
|
||||
@@ -457,6 +468,7 @@ bool LexerState::setFileAsNextState(std::string const &filePath, bool updateStat
|
||||
);
|
||||
}
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
}
|
||||
|
||||
@@ -552,7 +564,9 @@ size_t BufferedContent::readMore(size_t startIndex, size_t nbChars) {
|
||||
ssize_t nbReadChars = read(fd, &buf[startIndex], nbChars);
|
||||
|
||||
if (nbReadChars == -1) {
|
||||
// LCOV_EXCL_START
|
||||
fatalerror("Error while reading \"%s\": %s\n", lexerState->path.c_str(), strerror(errno));
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
size += nbReadChars;
|
||||
@@ -761,7 +775,9 @@ int LexerState::peekCharAhead() {
|
||||
// and `.peekCharAhead()` will continue with its parent
|
||||
assume(exp.offset <= exp.size());
|
||||
if (exp.offset + distance < exp.size()) {
|
||||
return static_cast<uint8_t>((*exp.contents)[exp.offset + distance]);
|
||||
// Macro args can't be recursive, since `peek()` marks them as scanned, so
|
||||
// this is a failsafe that (as far as I can tell) won't ever actually run.
|
||||
return static_cast<uint8_t>((*exp.contents)[exp.offset + distance]); // LCOV_EXCL_LINE
|
||||
}
|
||||
distance -= exp.size() - exp.offset;
|
||||
}
|
||||
@@ -1323,8 +1339,11 @@ static void appendEscapedString(std::string &str, std::string const &escape) {
|
||||
str += "\\n";
|
||||
break;
|
||||
case '\r':
|
||||
// A literal CR in a string may get treated as a LF, so '\r' is not tested.
|
||||
// LCOV_EXCL_START
|
||||
str += "\\r";
|
||||
break;
|
||||
// LCOV_EXCL_STOP
|
||||
case '\t':
|
||||
str += "\\t";
|
||||
break;
|
||||
@@ -2163,7 +2182,8 @@ static Token skipIfBlock(bool toEndc) {
|
||||
|
||||
case T_(POP_ELIF):
|
||||
if (lexer_ReachedELSEBlock()) {
|
||||
fatalerror("Found ELIF after an ELSE block\n");
|
||||
// This should be redundant, as the parser handles this error first.
|
||||
fatalerror("Found ELIF after an ELSE block\n"); // LCOV_EXCL_LINE
|
||||
}
|
||||
if (!toEndc && lexer_GetIFDepth() == startingDepth) {
|
||||
return token;
|
||||
@@ -2255,9 +2275,8 @@ static Token yylex_SKIP_TO_ENDR() {
|
||||
|
||||
case T_(POP_ENDR):
|
||||
depth--;
|
||||
if (!depth) {
|
||||
return Token(T_(YYEOF)); // yywrap() will finish the REPT/FOR loop
|
||||
}
|
||||
// `lexer_CaptureRept` has already guaranteed that the `ENDR`s are balanced
|
||||
assume(depth > 0);
|
||||
break;
|
||||
|
||||
case T_(POP_IF):
|
||||
|
||||
@@ -87,6 +87,7 @@ static option const longopts[] = {
|
||||
{nullptr, no_argument, nullptr, 0 }
|
||||
};
|
||||
|
||||
// LCOV_EXCL_START
|
||||
static void printUsage() {
|
||||
fputs(
|
||||
"Usage: rgbasm [-EhVvw] [-b chars] [-D name[=value]] [-g chars] [-I path]\n"
|
||||
@@ -107,6 +108,7 @@ static void printUsage() {
|
||||
stderr
|
||||
);
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
time_t now = time(nullptr);
|
||||
@@ -176,8 +178,10 @@ int main(int argc, char *argv[]) {
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
// LCOV_EXCL_START
|
||||
printUsage();
|
||||
exit(0);
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
case 'I':
|
||||
fstk_AddIncludePath(musl_optarg);
|
||||
@@ -195,7 +199,7 @@ int main(int argc, char *argv[]) {
|
||||
dependFileName = "<stdout>";
|
||||
}
|
||||
if (dependFile == nullptr) {
|
||||
err("Failed to open dependfile \"%s\"", dependFileName);
|
||||
err("Failed to open dependfile \"%s\"", dependFileName); // LCOV_EXCL_LINE
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -302,9 +306,11 @@ int main(int argc, char *argv[]) {
|
||||
if (stateFileSpecs.find(name) != stateFileSpecs.end()) {
|
||||
warnx("Overriding state filename %s", name);
|
||||
}
|
||||
// LCOV_EXCL_START
|
||||
if (verbose) {
|
||||
printf("State filename %s\n", name);
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
stateFileSpecs.emplace(name, std::move(features));
|
||||
break;
|
||||
}
|
||||
@@ -314,8 +320,10 @@ int main(int argc, char *argv[]) {
|
||||
exit(0);
|
||||
|
||||
case 'v':
|
||||
// LCOV_EXCL_START
|
||||
verbose = true;
|
||||
break;
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
case 'W':
|
||||
opt_W(musl_optarg);
|
||||
@@ -367,8 +375,10 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
// Unrecognized options
|
||||
default:
|
||||
// LCOV_EXCL_START
|
||||
printUsage();
|
||||
exit(1);
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,7 +401,7 @@ int main(int argc, char *argv[]) {
|
||||
std::string mainFileName = argv[musl_optind];
|
||||
|
||||
if (verbose) {
|
||||
printf("Assembling %s\n", mainFileName.c_str());
|
||||
printf("Assembling %s\n", mainFileName.c_str()); // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
if (dependFile) {
|
||||
|
||||
@@ -61,7 +61,7 @@ void out_RegisterNode(std::shared_ptr<FileStackNode> node) {
|
||||
}
|
||||
}
|
||||
|
||||
// Return a section's ID, or UINT32_MAX if the section is not in the list
|
||||
// Return a section's ID, or UINT32_MAX if the section does not exist
|
||||
static uint32_t getSectIDIfAny(Section *sect) {
|
||||
if (!sect) {
|
||||
return UINT32_MAX;
|
||||
@@ -71,7 +71,8 @@ static uint32_t getSectIDIfAny(Section *sect) {
|
||||
return static_cast<uint32_t>(search->second);
|
||||
}
|
||||
|
||||
fatalerror("Unknown section '%s'\n", sect->name.c_str());
|
||||
// Every section that exists should be in `sectionMap`
|
||||
fatalerror("Unknown section '%s'\n", sect->name.c_str()); // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
static void writePatch(Patch const &patch, FILE *file) {
|
||||
@@ -175,7 +176,7 @@ static void writeRpn(std::vector<uint8_t> &rpnexpr, std::vector<uint8_t> const &
|
||||
sym = sym_FindExactSymbol(symName);
|
||||
if (sym->isConstant()) {
|
||||
rpnexpr[rpnptr++] = RPN_CONST;
|
||||
value = sym_GetConstantValue(symName);
|
||||
value = sym->getConstantValue();
|
||||
} else {
|
||||
rpnexpr[rpnptr++] = RPN_SYM;
|
||||
registerUnregisteredSymbol(*sym); // Ensure that `sym->ID` is set
|
||||
@@ -323,7 +324,7 @@ void out_WriteObject() {
|
||||
file = stdout;
|
||||
}
|
||||
if (!file) {
|
||||
err("Failed to open object file '%s'", objectFileName.c_str());
|
||||
err("Failed to open object file '%s'", objectFileName.c_str()); // LCOV_EXCL_LINE
|
||||
}
|
||||
Defer closeFile{[&] { fclose(file); }};
|
||||
|
||||
@@ -343,14 +344,7 @@ void out_WriteObject() {
|
||||
writeFileStackNode(node, file);
|
||||
|
||||
// The list is supposed to have decrementing IDs
|
||||
if (it + 1 != fileStackNodes.end() && it[1]->ID != node.ID - 1) {
|
||||
fatalerror(
|
||||
"Internal error: fstack node #%" PRIu32 " follows #%" PRIu32
|
||||
". Please report this to the developers!\n",
|
||||
it[1]->ID,
|
||||
node.ID
|
||||
);
|
||||
}
|
||||
assume(it + 1 == fileStackNodes.end() || it[1]->ID == node.ID - 1);
|
||||
}
|
||||
|
||||
for (Symbol const *sym : objectSymbols) {
|
||||
@@ -373,9 +367,11 @@ void out_SetFileName(std::string const &name) {
|
||||
warnx("Overriding output filename %s", objectFileName.c_str());
|
||||
}
|
||||
objectFileName = name;
|
||||
// LCOV_EXCL_START
|
||||
if (verbose) {
|
||||
printf("Output filename %s\n", objectFileName.c_str());
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
static void dumpString(std::string const &escape, FILE *file) {
|
||||
@@ -528,7 +524,7 @@ void out_WriteState(std::string name, std::vector<StateFeature> const &features)
|
||||
file = stdout;
|
||||
}
|
||||
if (!file) {
|
||||
err("Failed to open state file '%s'", name.c_str());
|
||||
err("Failed to open state file '%s'", name.c_str()); // LCOV_EXCL_LINE
|
||||
}
|
||||
Defer closeFile{[&] { fclose(file); }};
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ void Expression::makeSymbol(std::string const &symName) {
|
||||
*ptr++ = RPN_SYM;
|
||||
memcpy(ptr, sym->name.c_str(), nameLen);
|
||||
} else {
|
||||
data = static_cast<int32_t>(sym_GetConstantValue(symName));
|
||||
data = static_cast<int32_t>(sym->getConstantValue());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,42 +325,12 @@ void Expression::makeUnaryOp(RPNCommand op, Expression &&src) {
|
||||
case RPN_TZCOUNT:
|
||||
data = val != 0 ? ctz(uval) : 32;
|
||||
break;
|
||||
|
||||
case RPN_LOGOR:
|
||||
case RPN_LOGAND:
|
||||
case RPN_LOGEQ:
|
||||
case RPN_LOGGT:
|
||||
case RPN_LOGLT:
|
||||
case RPN_LOGGE:
|
||||
case RPN_LOGLE:
|
||||
case RPN_LOGNE:
|
||||
case RPN_ADD:
|
||||
case RPN_SUB:
|
||||
case RPN_XOR:
|
||||
case RPN_OR:
|
||||
case RPN_AND:
|
||||
case RPN_SHL:
|
||||
case RPN_SHR:
|
||||
case RPN_USHR:
|
||||
case RPN_MUL:
|
||||
case RPN_DIV:
|
||||
case RPN_MOD:
|
||||
case RPN_EXP:
|
||||
case RPN_BANK_SYM:
|
||||
case RPN_BANK_SECT:
|
||||
case RPN_BANK_SELF:
|
||||
case RPN_SIZEOF_SECT:
|
||||
case RPN_STARTOF_SECT:
|
||||
case RPN_SIZEOF_SECTTYPE:
|
||||
case RPN_STARTOF_SECTTYPE:
|
||||
case RPN_HRAM:
|
||||
case RPN_RST:
|
||||
case RPN_BIT_INDEX:
|
||||
case RPN_CONST:
|
||||
case RPN_SYM:
|
||||
default:
|
||||
// `makeUnaryOp` should never be called with a non-unary operator!
|
||||
// LCOV_EXCL_START
|
||||
unreachable_();
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
} else if (op == RPN_LOGNOT && tryConstLogNot(src)) {
|
||||
data = 0;
|
||||
} else if (int32_t constVal; op == RPN_LOW && (constVal = tryConstLow(src)) != -1) {
|
||||
@@ -503,29 +473,12 @@ void Expression::makeBinaryOp(RPNCommand op, Expression &&src1, Expression const
|
||||
|
||||
data = op_exponent(lval, rval);
|
||||
break;
|
||||
|
||||
case RPN_NEG:
|
||||
case RPN_NOT:
|
||||
case RPN_LOGNOT:
|
||||
case RPN_BANK_SYM:
|
||||
case RPN_BANK_SECT:
|
||||
case RPN_BANK_SELF:
|
||||
case RPN_SIZEOF_SECT:
|
||||
case RPN_STARTOF_SECT:
|
||||
case RPN_SIZEOF_SECTTYPE:
|
||||
case RPN_STARTOF_SECTTYPE:
|
||||
case RPN_HRAM:
|
||||
case RPN_RST:
|
||||
case RPN_BIT_INDEX:
|
||||
case RPN_HIGH:
|
||||
case RPN_LOW:
|
||||
case RPN_BITWIDTH:
|
||||
case RPN_TZCOUNT:
|
||||
case RPN_CONST:
|
||||
case RPN_SYM:
|
||||
default:
|
||||
// `makeBinaryOp` should never be called with a non-binary operator!
|
||||
// LCOV_EXCL_START
|
||||
unreachable_();
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
} else if (op == RPN_SUB && src1.isDiffConstant(src2.symbolOf())) {
|
||||
data = src1.symbolOf()->getValue() - src2.symbolOf()->getValue();
|
||||
} else if ((op == RPN_LOGAND || op == RPN_AND) && tryConstZero(src1, src2)) {
|
||||
|
||||
@@ -875,9 +875,11 @@ void sect_BinaryFile(std::string const &name, int32_t startPos) {
|
||||
}
|
||||
if (!file) {
|
||||
if (generatedMissingIncludes) {
|
||||
// LCOV_EXCL_START
|
||||
if (verbose) {
|
||||
printf("Aborting (-MG) on INCBIN file '%s' (%s)\n", name.c_str(), strerror(errno));
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
failedOnMissingInclude = true;
|
||||
} else {
|
||||
error("Error opening INCBIN file '%s': %s\n", name.c_str(), strerror(errno));
|
||||
@@ -942,9 +944,11 @@ void sect_BinaryFileSlice(std::string const &name, int32_t startPos, int32_t len
|
||||
}
|
||||
if (!file) {
|
||||
if (generatedMissingIncludes) {
|
||||
// LCOV_EXCL_START
|
||||
if (verbose) {
|
||||
printf("Aborting (-MG) on INCBIN file '%s' (%s)\n", name.c_str(), strerror(errno));
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
failedOnMissingInclude = true;
|
||||
} else {
|
||||
error("Error opening INCBIN file '%s': %s\n", name.c_str(), strerror(errno));
|
||||
|
||||
@@ -325,19 +325,6 @@ uint32_t Symbol::getConstantValue() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t sym_GetConstantValue(std::string const &symName) {
|
||||
if (Symbol const *sym = sym_FindScopedSymbol(symName); sym) {
|
||||
return sym->getConstantValue();
|
||||
}
|
||||
|
||||
if (sym_IsPurgedScoped(symName)) {
|
||||
error("'%s' not defined; it was purged\n", symName.c_str());
|
||||
} else {
|
||||
error("'%s' not defined\n", symName.c_str());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::pair<Symbol const *, Symbol const *> sym_GetCurrentLabelScopes() {
|
||||
return {globalScope, localScope};
|
||||
}
|
||||
@@ -528,8 +515,10 @@ static uint32_t anonLabelID = 0;
|
||||
|
||||
Symbol *sym_AddAnonLabel() {
|
||||
if (anonLabelID == UINT32_MAX) {
|
||||
// LCOV_EXCL_START
|
||||
error("Only %" PRIu32 " anonymous labels can be created!", anonLabelID);
|
||||
return nullptr;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
std::string anon = sym_MakeAnonLabelName(0, true); // The direction is important!
|
||||
@@ -555,6 +544,7 @@ std::string sym_MakeAnonLabelName(uint32_t ofs, bool neg) {
|
||||
} else {
|
||||
ofs--; // We're referencing symbols that haven't been created yet...
|
||||
if (ofs > UINT32_MAX - anonLabelID) {
|
||||
// LCOV_EXCL_START
|
||||
error(
|
||||
"Reference to anonymous label %" PRIu32 " after, when only %" PRIu32
|
||||
" may still be created\n",
|
||||
@@ -562,6 +552,7 @@ std::string sym_MakeAnonLabelName(uint32_t ofs, bool neg) {
|
||||
UINT32_MAX - anonLabelID
|
||||
);
|
||||
} else {
|
||||
// LCOV_EXCL_STOP
|
||||
id = anonLabelID + ofs;
|
||||
}
|
||||
}
|
||||
@@ -571,8 +562,11 @@ std::string sym_MakeAnonLabelName(uint32_t ofs, bool neg) {
|
||||
|
||||
void sym_Export(std::string const &symName) {
|
||||
if (symName.starts_with('!')) {
|
||||
// LCOV_EXCL_START
|
||||
// The parser does not accept anonymous labels for an `EXPORT` directive
|
||||
error("Anonymous labels cannot be exported\n");
|
||||
return;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
Symbol *sym = sym_FindScopedSymbol(symName);
|
||||
@@ -654,11 +648,13 @@ void sym_Init(time_t now) {
|
||||
sym_AddEqu("__RGBDS_RC__"s, PACKAGE_VERSION_RC)->isBuiltin = true;
|
||||
#endif
|
||||
|
||||
// LCOV_EXCL_START
|
||||
if (now == static_cast<time_t>(-1)) {
|
||||
warn("Failed to determine current time");
|
||||
// Fall back by pretending we are at the Epoch
|
||||
now = 0;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
tm const *time_local = localtime(&now);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user