mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Use std::variant and automatic allocation for file stack node data
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
@@ -35,10 +36,18 @@ struct FileStackNode {
|
|||||||
uint32_t lineNo;
|
uint32_t lineNo;
|
||||||
|
|
||||||
enum FileStackNodeType type;
|
enum FileStackNodeType type;
|
||||||
union {
|
std::variant<
|
||||||
std::string *name; // NODE_FILE, NODE_MACRO
|
std::monostate, // Default constructed; `.type` and `.data` must be set manually
|
||||||
std::vector<uint32_t> *iters; // NODE_REPT
|
std::vector<uint32_t>, // NODE_REPT
|
||||||
};
|
std::string // NODE_FILE, NODE_MACRO
|
||||||
|
> data;
|
||||||
|
|
||||||
|
// REPT iteration counts since last named node, in reverse depth order
|
||||||
|
std::vector<uint32_t> &iters();
|
||||||
|
std::vector<uint32_t> const &iters() const;
|
||||||
|
// File name for files, file::macro name for macros
|
||||||
|
std::string &name();
|
||||||
|
std::string const &name() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper macro for printing verbose-mode messages
|
// Helper macro for printing verbose-mode messages
|
||||||
|
|||||||
@@ -7,9 +7,12 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <variant>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "link/assign.hpp"
|
#include "link/assign.hpp"
|
||||||
#include "link/object.hpp"
|
#include "link/object.hpp"
|
||||||
@@ -48,6 +51,26 @@ FILE *linkerScript;
|
|||||||
|
|
||||||
static uint32_t nbErrors = 0;
|
static uint32_t nbErrors = 0;
|
||||||
|
|
||||||
|
std::vector<uint32_t> &FileStackNode::iters() {
|
||||||
|
assert(std::holds_alternative<std::vector<uint32_t>>(data));
|
||||||
|
return std::get<std::vector<uint32_t>>(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint32_t> const &FileStackNode::iters() const {
|
||||||
|
assert(std::holds_alternative<std::vector<uint32_t>>(data));
|
||||||
|
return std::get<std::vector<uint32_t>>(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string &FileStackNode::name() {
|
||||||
|
assert(std::holds_alternative<std::string>(data));
|
||||||
|
return std::get<std::string>(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string const &FileStackNode::name() const {
|
||||||
|
assert(std::holds_alternative<std::string>(data));
|
||||||
|
return std::get<std::string>(data);
|
||||||
|
}
|
||||||
|
|
||||||
// Helper function to dump a file stack to stderr
|
// Helper function to dump a file stack to stderr
|
||||||
std::string const *dumpFileStack(struct FileStackNode const *node)
|
std::string const *dumpFileStack(struct FileStackNode const *node)
|
||||||
{
|
{
|
||||||
@@ -57,15 +80,15 @@ std::string const *dumpFileStack(struct FileStackNode const *node)
|
|||||||
lastName = dumpFileStack(node->parent);
|
lastName = dumpFileStack(node->parent);
|
||||||
// REPT nodes use their parent's name
|
// REPT nodes use their parent's name
|
||||||
if (node->type != NODE_REPT)
|
if (node->type != NODE_REPT)
|
||||||
lastName = node->name;
|
lastName = &node->name();
|
||||||
fprintf(stderr, "(%" PRIu32 ") -> %s", node->lineNo, lastName->c_str());
|
fprintf(stderr, "(%" PRIu32 ") -> %s", node->lineNo, lastName->c_str());
|
||||||
if (node->type == NODE_REPT) {
|
if (node->type == NODE_REPT) {
|
||||||
for (uint32_t iter : *node->iters)
|
for (uint32_t iter : node->iters())
|
||||||
fprintf(stderr, "::REPT~%" PRIu32, iter);
|
fprintf(stderr, "::REPT~%" PRIu32, iter);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert(node->type != NODE_REPT);
|
assert(node->type != NODE_REPT);
|
||||||
lastName = node->name;
|
lastName = &node->name();
|
||||||
fputs(lastName->c_str(), stderr);
|
fputs(lastName->c_str(), stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -157,23 +157,22 @@ static void readFileStackNode(FILE *file, std::vector<struct FileStackNode> &fil
|
|||||||
tryGetc(enum FileStackNodeType, node.type, file,
|
tryGetc(enum FileStackNodeType, node.type, file,
|
||||||
"%s: Cannot read node #%" PRIu32 "'s type: %s", fileName, i);
|
"%s: Cannot read node #%" PRIu32 "'s type: %s", fileName, i);
|
||||||
switch (node.type) {
|
switch (node.type) {
|
||||||
|
std::string *name;
|
||||||
case NODE_FILE:
|
case NODE_FILE:
|
||||||
case NODE_MACRO:
|
case NODE_MACRO:
|
||||||
tryReadstring(node.name, file,
|
tryReadstring(name, file,
|
||||||
"%s: Cannot read node #%" PRIu32 "'s file name: %s", fileName, i);
|
"%s: Cannot read node #%" PRIu32 "'s file name: %s", fileName, i);
|
||||||
|
node.data = *name;
|
||||||
|
delete name;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
uint32_t depth;
|
uint32_t depth;
|
||||||
case NODE_REPT:
|
case NODE_REPT:
|
||||||
tryReadlong(depth, file,
|
tryReadlong(depth, file,
|
||||||
"%s: Cannot read node #%" PRIu32 "'s rept depth: %s", fileName, i);
|
"%s: Cannot read node #%" PRIu32 "'s rept depth: %s", fileName, i);
|
||||||
node.iters = new(std::nothrow) std::vector<uint32_t>();
|
node.data = std::vector<uint32_t>(depth);
|
||||||
if (!node.iters)
|
|
||||||
fatal(NULL, 0, "%s: Failed to alloc node #%" PRIu32 "'s iters: %s",
|
|
||||||
fileName, i, strerror(errno));
|
|
||||||
node.iters->resize(depth);
|
|
||||||
for (uint32_t k = 0; k < depth; k++)
|
for (uint32_t k = 0; k < depth; k++)
|
||||||
tryReadlong((*node.iters)[k], file,
|
tryReadlong(node.iters()[k], file,
|
||||||
"%s: Cannot read node #%" PRIu32 "'s iter #%" PRIu32 ": %s",
|
"%s: Cannot read node #%" PRIu32 "'s iter #%" PRIu32 ": %s",
|
||||||
fileName, i, k);
|
fileName, i, k);
|
||||||
if (!node.parent)
|
if (!node.parent)
|
||||||
@@ -424,18 +423,16 @@ void obj_ReadFile(char const *fileName, unsigned int fileID)
|
|||||||
default: // This is (probably) a SDCC object file, defer the rest of detection to it
|
default: // This is (probably) a SDCC object file, defer the rest of detection to it
|
||||||
// Since SDCC does not provide line info, everything will be reported as coming from the
|
// Since SDCC does not provide line info, everything will be reported as coming from the
|
||||||
// object file. It's better than nothing.
|
// object file. It's better than nothing.
|
||||||
nodes[fileID].resize(1);
|
nodes[fileID].push_back({
|
||||||
struct FileStackNode &where = nodes[fileID][0];
|
.parent = NULL,
|
||||||
|
.lineNo = 0,
|
||||||
where.parent = NULL;
|
.type = NODE_FILE,
|
||||||
where.type = NODE_FILE;
|
.data = fileName
|
||||||
where.name = new(std::nothrow) std::string(fileName);
|
});
|
||||||
if (!where.name)
|
|
||||||
fatal(NULL, 0, "Failed to duplicate \"%s\"'s name: %s", fileName, strerror(errno));
|
|
||||||
|
|
||||||
std::vector<struct Symbol> &fileSymbols = symbolLists.emplace_front();
|
std::vector<struct Symbol> &fileSymbols = symbolLists.emplace_front();
|
||||||
|
|
||||||
sdobj_ReadFile(&where, file, fileSymbols);
|
sdobj_ReadFile(&nodes[fileID].back(), file, fileSymbols);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -570,14 +567,6 @@ void obj_Setup(unsigned int nbFiles)
|
|||||||
nodes.resize(nbFiles);
|
nodes.resize(nbFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void freeNode(struct FileStackNode &node)
|
|
||||||
{
|
|
||||||
if (node.type == NODE_REPT)
|
|
||||||
delete node.iters;
|
|
||||||
else
|
|
||||||
delete node.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void freeSection(struct Section *section)
|
static void freeSection(struct Section *section)
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
@@ -597,11 +586,6 @@ static void freeSection(struct Section *section)
|
|||||||
|
|
||||||
void obj_Cleanup(void)
|
void obj_Cleanup(void)
|
||||||
{
|
{
|
||||||
for (std::vector<struct FileStackNode> &fileNodes : nodes) {
|
|
||||||
for (struct FileStackNode &node : fileNodes)
|
|
||||||
freeNode(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
sym_CleanupSymbols();
|
sym_CleanupSymbols();
|
||||||
|
|
||||||
sect_ForEach(freeSection);
|
sect_ForEach(freeSection);
|
||||||
|
|||||||
@@ -299,7 +299,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
|
|||||||
strerror(errno));
|
strerror(errno));
|
||||||
// If the section is absolute, its name might not be unique; thus, mangle the name
|
// If the section is absolute, its name might not be unique; thus, mangle the name
|
||||||
if (curSection->modifier == SECTION_NORMAL) {
|
if (curSection->modifier == SECTION_NORMAL) {
|
||||||
curSection->name->append(*where->name);
|
curSection->name->append(where->name());
|
||||||
curSection->name->append(" ");
|
curSection->name->append(" ");
|
||||||
}
|
}
|
||||||
curSection->name->append(sectionName);
|
curSection->name->append(sectionName);
|
||||||
@@ -363,7 +363,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
|
|||||||
struct Symbol &symbol = fileSymbols.emplace_back();
|
struct Symbol &symbol = fileSymbols.emplace_back();
|
||||||
|
|
||||||
// Init other members
|
// Init other members
|
||||||
symbol.objFileName = where->name->c_str();
|
symbol.objFileName = where->name().c_str();
|
||||||
symbol.src = where;
|
symbol.src = where;
|
||||||
symbol.lineNo = lineNo;
|
symbol.lineNo = lineNo;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user