Add assertions

Closes #292
This commit is contained in:
ISSOtm
2020-03-05 02:58:48 +01:00
parent 03967bd623
commit fb58166e5d
18 changed files with 506 additions and 82 deletions

View File

@@ -13,13 +13,15 @@
#include <errno.h>
#include <limits.h>
#include "link/object.h"
#include "link/main.h"
#include "link/symbol.h"
#include "link/section.h"
#include "link/assign.h"
#include "link/main.h"
#include "link/object.h"
#include "link/patch.h"
#include "link/section.h"
#include "link/symbol.h"
#include "extern/err.h"
#include "helpers.h"
#include "linkdefs.h"
static struct SymbolList {
@@ -28,6 +30,8 @@ static struct SymbolList {
struct SymbolList *next;
} *symbolLists;
static struct Assertion *assertions;
/***** Helper functions for reading object files *****/
/*
@@ -232,7 +236,7 @@ static void readPatch(FILE *file, struct Patch *patch,
}
/**
* Reads a RGB6 section from a file.
* Reads a section from a file.
* @param file The file to read from
* @param section The struct to fill
* @param fileName The filename to report in errors
@@ -331,6 +335,29 @@ static void linkSymToSect(struct Symbol const *symbol, struct Section *section)
section->nbSymbols++;
}
/**
* Reads an assertion from a file
* @param file The file to read from
* @param assert The struct to fill
* @param fileName The filename to report in errors
*/
static void readAssertion(FILE *file, struct Assertion *assert,
char const *fileName, struct Section *fileSections[],
uint32_t i)
{
char assertName[sizeof("Assertion #" EXPAND_AND_STR(UINT32_MAX))];
uint32_t sectionID;
snprintf(assertName, sizeof(assertName), "Assertion #%u", i);
readPatch(file, &assert->patch, fileName, assertName, 0);
tryReadlong(sectionID, file, "%s: Cannot read assertion's section ID: %s",
fileName);
assert->section = fileSections[sectionID];
tryReadstr(assert->message, file, "%s: Cannot read assertion's message: %s",
fileName);
}
/**
* Reads an object file of any supported format
* @param fileName The filename to report for errors
@@ -451,12 +478,29 @@ void obj_ReadFile(char const *fileName)
}
}
uint32_t nbAsserts;
tryReadlong(nbAsserts, file, "%s: Cannot read number of assertions: %s",
fileName);
verbosePrint("Reading %u assertions...\n", nbAsserts);
for (uint32_t i = 0; i < nbAsserts; i++) {
struct Assertion *assertion = malloc(sizeof(*assertion));
if (!assertion)
err(1, "%s: Couldn't create new assertion", fileName);
readAssertion(file, assertion, fileName, fileSections, i);
assertion->next = assertions;
assertions = assertion;
}
fclose(file);
}
void obj_DoSanityChecks(void)
{
sect_DoSanityChecks();
patch_CheckAssertions(assertions);
}
static void freeSection(struct Section *section, void *arg)

View File

@@ -340,6 +340,48 @@ static int32_t computeRPNExpr(struct Patch const *patch,
#undef popRPN
}
void patch_CheckAssertions(struct Assertion *assert)
{
verbosePrint("Checking assertions...");
initRPNStack();
uint8_t failures = 0;
while (assert) {
if (!computeRPNExpr(&assert->patch, assert->section)) {
switch ((enum AssertionType)assert->patch.type) {
case ASSERT_FATAL:
errx(1, "%s: %s", assert->patch.fileName,
assert->message[0] ? assert->message
: "assert failure");
/* Not reached */
break; /* Here so checkpatch doesn't complain */
case ASSERT_ERROR:
fprintf(stderr, "%s: %s\n",
assert->patch.fileName,
assert->message[0] ? assert->message
: "assert failure");
failures++;
break;
case ASSERT_WARN:
warnx("%s: %s", assert->patch.fileName,
assert->message[0] ? assert->message
: "assert failure");
break;
}
}
struct Assertion *next = assert->next;
free(assert);
assert = next;
}
freeRPNStack();
if (failures)
errx(1, "%u assertions failed!", failures);
}
/**
* Applies all of a section's patches
* @param section The section to patch
@@ -399,3 +441,4 @@ void patch_ApplyPatches(void)
sect_ForEach(applyPatches, NULL);
freeRPNStack();
}