Pass std::string references to output functions

This commit is contained in:
Rangi42
2024-03-18 11:45:51 -04:00
committed by Sylvie
parent 7b11c528ef
commit 6cabb8c9af
4 changed files with 81 additions and 80 deletions

View File

@@ -4,20 +4,21 @@
#define RGBDS_ASM_OUTPUT_H #define RGBDS_ASM_OUTPUT_H
#include <stdint.h> #include <stdint.h>
#include <string>
#include "linkdefs.hpp" #include "linkdefs.hpp"
struct Expression; struct Expression;
struct FileStackNode; struct FileStackNode;
extern char const *objectName; extern std::string objectName;
void out_RegisterNode(FileStackNode *node); void out_RegisterNode(FileStackNode *node);
void out_ReplaceNode(FileStackNode *node); void out_ReplaceNode(FileStackNode *node);
void out_SetFileName(char *s); void out_SetFileName(std::string const &name);
void out_CreatePatch(uint32_t type, Expression const &expr, uint32_t ofs, uint32_t pcShift); void out_CreatePatch(uint32_t type, Expression const &expr, uint32_t ofs, uint32_t pcShift);
void out_CreateAssert( void out_CreateAssert(
AssertionType type, Expression const &expr, char const *message, uint32_t ofs AssertionType type, Expression const &expr, std::string const &message, uint32_t ofs
); );
void out_WriteObject(); void out_WriteObject();

View File

@@ -362,7 +362,7 @@ int main(int argc, char *argv[]) {
} }
} }
if (targetFileName.empty() && objectName) if (targetFileName.empty() && !objectName.empty())
targetFileName = objectName; targetFileName = objectName;
if (argc == musl_optind) { if (argc == musl_optind) {
@@ -413,7 +413,7 @@ int main(int argc, char *argv[]) {
return 0; return 0;
// If no path specified, don't write file // If no path specified, don't write file
if (objectName != nullptr) if (!objectName.empty())
out_WriteObject(); out_WriteObject();
return 0; return 0;
} }

View File

@@ -29,7 +29,7 @@ struct Assertion {
std::string message; std::string message;
}; };
char const *objectName; std::string objectName;
// List of symbols to put in the object file // List of symbols to put in the object file
static std::vector<Symbol *> objectSymbols; static std::vector<Symbol *> objectSymbols;
@@ -39,20 +39,20 @@ static std::deque<Assertion> assertions;
static std::deque<FileStackNode *> fileStackNodes; static std::deque<FileStackNode *> fileStackNodes;
// Write a long to a file (little-endian) // Write a long to a file (little-endian)
static void putlong(uint32_t n, FILE *f) { static void putlong(uint32_t n, FILE *file) {
uint8_t bytes[] = { uint8_t bytes[] = {
(uint8_t)n, (uint8_t)n,
(uint8_t)(n >> 8), (uint8_t)(n >> 8),
(uint8_t)(n >> 16), (uint8_t)(n >> 16),
(uint8_t)(n >> 24), (uint8_t)(n >> 24),
}; };
fwrite(bytes, 1, sizeof(bytes), f); fwrite(bytes, 1, sizeof(bytes), file);
} }
// Write a NUL-terminated string to a file // Write a NUL-terminated string to a file
static void putstring(std::string const &s, FILE *f) { static void putstring(std::string const &s, FILE *file) {
fputs(s.c_str(), f); fputs(s.c_str(), file);
putc('\0', f); putc('\0', file);
} }
void out_RegisterNode(FileStackNode *node) { void out_RegisterNode(FileStackNode *node) {
@@ -90,56 +90,56 @@ static uint32_t getSectIDIfAny(Section *sect) {
} }
// Write a patch to a file // Write a patch to a file
static void writepatch(Patch const &patch, FILE *f) { static void writepatch(Patch const &patch, FILE *file) {
assert(patch.src->ID != (uint32_t)-1); assert(patch.src->ID != (uint32_t)-1);
putlong(patch.src->ID, f); putlong(patch.src->ID, file);
putlong(patch.lineNo, f); putlong(patch.lineNo, file);
putlong(patch.offset, f); putlong(patch.offset, file);
putlong(getSectIDIfAny(patch.pcSection), f); putlong(getSectIDIfAny(patch.pcSection), file);
putlong(patch.pcOffset, f); putlong(patch.pcOffset, file);
putc(patch.type, f); putc(patch.type, file);
putlong(patch.rpn.size(), f); putlong(patch.rpn.size(), file);
fwrite(patch.rpn.data(), 1, patch.rpn.size(), f); fwrite(patch.rpn.data(), 1, patch.rpn.size(), file);
} }
// Write a section to a file // Write a section to a file
static void writesection(Section const &sect, FILE *f) { static void writesection(Section const &sect, FILE *file) {
putstring(sect.name, f); putstring(sect.name, file);
putlong(sect.size, f); putlong(sect.size, file);
bool isUnion = sect.modifier == SECTION_UNION; bool isUnion = sect.modifier == SECTION_UNION;
bool isFragment = sect.modifier == SECTION_FRAGMENT; bool isFragment = sect.modifier == SECTION_FRAGMENT;
putc(sect.type | isUnion << 7 | isFragment << 6, f); putc(sect.type | isUnion << 7 | isFragment << 6, file);
putlong(sect.org, f); putlong(sect.org, file);
putlong(sect.bank, f); putlong(sect.bank, file);
putc(sect.align, f); putc(sect.align, file);
putlong(sect.alignOfs, f); putlong(sect.alignOfs, file);
if (sect_HasData(sect.type)) { if (sect_HasData(sect.type)) {
fwrite(sect.data.data(), 1, sect.size, f); fwrite(sect.data.data(), 1, sect.size, file);
putlong(sect.patches.size(), f); putlong(sect.patches.size(), file);
for (Patch const &patch : sect.patches) for (Patch const &patch : sect.patches)
writepatch(patch, f); writepatch(patch, file);
} }
} }
// Write a symbol to a file // Write a symbol to a file
static void writesymbol(Symbol const &sym, FILE *f) { static void writesymbol(Symbol const &sym, FILE *file) {
putstring(sym.name, f); putstring(sym.name, file);
if (!sym.isDefined()) { if (!sym.isDefined()) {
putc(SYMTYPE_IMPORT, f); putc(SYMTYPE_IMPORT, file);
} else { } else {
assert(sym.src->ID != (uint32_t)-1); assert(sym.src->ID != (uint32_t)-1);
putc(sym.isExported ? SYMTYPE_EXPORT : SYMTYPE_LOCAL, f); putc(sym.isExported ? SYMTYPE_EXPORT : SYMTYPE_LOCAL, file);
putlong(sym.src->ID, f); putlong(sym.src->ID, file);
putlong(sym.fileLine, f); putlong(sym.fileLine, file);
putlong(getSectIDIfAny(sym.getSection()), f); putlong(getSectIDIfAny(sym.getSection()), file);
putlong(sym.getOutputValue(), f); putlong(sym.getOutputValue(), file);
} }
} }
@@ -294,7 +294,7 @@ void out_CreatePatch(uint32_t type, Expression const &expr, uint32_t ofs, uint32
// Creates an assert that will be written to the object file // Creates an assert that will be written to the object file
void out_CreateAssert( void out_CreateAssert(
AssertionType type, Expression const &expr, char const *message, uint32_t ofs AssertionType type, Expression const &expr, std::string const &message, uint32_t ofs
) { ) {
Assertion &assertion = assertions.emplace_front(); Assertion &assertion = assertions.emplace_front();
@@ -302,24 +302,24 @@ void out_CreateAssert(
assertion.message = message; assertion.message = message;
} }
static void writeassert(Assertion &assert, FILE *f) { static void writeassert(Assertion &assert, FILE *file) {
writepatch(assert.patch, f); writepatch(assert.patch, file);
putstring(assert.message, f); putstring(assert.message, file);
} }
static void writeFileStackNode(FileStackNode const &node, FILE *f) { static void writeFileStackNode(FileStackNode const &node, FILE *file) {
putlong(node.parent ? node.parent->ID : (uint32_t)-1, f); putlong(node.parent ? node.parent->ID : (uint32_t)-1, file);
putlong(node.lineNo, f); putlong(node.lineNo, file);
putc(node.type, f); putc(node.type, file);
if (node.type != NODE_REPT) { if (node.type != NODE_REPT) {
putstring(node.name(), f); putstring(node.name(), file);
} else { } else {
std::vector<uint32_t> const &nodeIters = node.iters(); std::vector<uint32_t> const &nodeIters = node.iters();
putlong(nodeIters.size(), f); putlong(nodeIters.size(), file);
// Iters are stored by decreasing depth, so reverse the order for output // Iters are stored by decreasing depth, so reverse the order for output
for (uint32_t i = nodeIters.size(); i--;) for (uint32_t i = nodeIters.size(); i--;)
putlong(nodeIters[i], f); putlong(nodeIters[i], file);
} }
} }
@@ -332,31 +332,31 @@ static void registerUnregisteredSymbol(Symbol &sym) {
// Write an objectfile // Write an objectfile
void out_WriteObject() { void out_WriteObject() {
FILE *f; FILE *file;
if (strcmp(objectName, "-")) { if (objectName != "-") {
f = fopen(objectName, "wb"); file = fopen(objectName.c_str(), "wb");
} else { } else {
objectName = "<stdout>"; objectName = "<stdout>";
f = fdopen(STDOUT_FILENO, "wb"); file = fdopen(STDOUT_FILENO, "wb");
} }
if (!f) if (!file)
err("Failed to open object file '%s'", objectName); err("Failed to open object file '%s'", objectName.c_str());
// Also write symbols that weren't written above // Also write symbols that weren't written above
sym_ForEach(registerUnregisteredSymbol); sym_ForEach(registerUnregisteredSymbol);
fprintf(f, RGBDS_OBJECT_VERSION_STRING); fprintf(file, RGBDS_OBJECT_VERSION_STRING);
putlong(RGBDS_OBJECT_REV, f); putlong(RGBDS_OBJECT_REV, file);
putlong(objectSymbols.size(), f); putlong(objectSymbols.size(), file);
putlong(sectionList.size(), f); putlong(sectionList.size(), file);
putlong(fileStackNodes.size(), f); putlong(fileStackNodes.size(), file);
for (auto it = fileStackNodes.begin(); it != fileStackNodes.end(); it++) { for (auto it = fileStackNodes.begin(); it != fileStackNodes.end(); it++) {
FileStackNode const *node = *it; FileStackNode const *node = *it;
writeFileStackNode(*node, f); writeFileStackNode(*node, file);
// The list is supposed to have decrementing IDs // The list is supposed to have decrementing IDs
if (it + 1 != fileStackNodes.end() && it[1]->ID != node->ID - 1) if (it + 1 != fileStackNodes.end() && it[1]->ID != node->ID - 1)
@@ -369,24 +369,24 @@ void out_WriteObject() {
} }
for (Symbol const *sym : objectSymbols) for (Symbol const *sym : objectSymbols)
writesymbol(*sym, f); writesymbol(*sym, file);
for (auto it = sectionList.rbegin(); it != sectionList.rend(); it++) for (auto it = sectionList.rbegin(); it != sectionList.rend(); it++)
writesection(*it, f); writesection(*it, file);
putlong(assertions.size(), f); putlong(assertions.size(), file);
for (Assertion &assert : assertions) for (Assertion &assert : assertions)
writeassert(assert, f); writeassert(assert, file);
fclose(f); fclose(file);
} }
// Set the objectfilename // Set the objectfilename
void out_SetFileName(char *s) { void out_SetFileName(std::string const &name) {
if (objectName) if (!objectName.empty())
warnx("Overriding output filename %s", objectName); warnx("Overriding output filename %s", objectName.c_str());
objectName = s; objectName = name;
if (verbose) if (verbose)
printf("Output filename %s\n", objectName); printf("Output filename %s\n", objectName.c_str());
} }

View File

@@ -88,7 +88,7 @@
); );
static void compoundAssignment(std::string const &symName, RPNCommand op, int32_t constValue); static void compoundAssignment(std::string const &symName, RPNCommand op, int32_t constValue);
static void failAssert(AssertionType type); static void failAssert(AssertionType type);
static void failAssertMsg(AssertionType type, char const *msg); static void failAssertMsg(AssertionType type, std::string const &message);
// The CPU encodes instructions in a logical way, so most instructions actually follow patterns. // The CPU encodes instructions in a logical way, so most instructions actually follow patterns.
// These enums thus help with bit twiddling to compute opcodes. // These enums thus help with bit twiddling to compute opcodes.
@@ -824,9 +824,9 @@ assert:
} }
| POP_ASSERT assert_type relocexpr COMMA string { | POP_ASSERT assert_type relocexpr COMMA string {
if (!$3.isKnown) { if (!$3.isKnown) {
out_CreateAssert($2, $3, $5.c_str(), sect_GetOutputOffset()); out_CreateAssert($2, $3, $5, sect_GetOutputOffset());
} else if ($3.val == 0) { } else if ($3.val == 0) {
failAssertMsg($2, $5.c_str()); failAssertMsg($2, $5);
} }
} }
| POP_STATIC_ASSERT assert_type const { | POP_STATIC_ASSERT assert_type const {
@@ -835,7 +835,7 @@ assert:
} }
| POP_STATIC_ASSERT assert_type const COMMA string { | POP_STATIC_ASSERT assert_type const COMMA string {
if ($3 == 0) if ($3 == 0)
failAssertMsg($2, $5.c_str()); failAssertMsg($2, $5);
} }
; ;
@@ -2736,15 +2736,15 @@ static void failAssert(AssertionType type) {
} }
} }
static void failAssertMsg(AssertionType type, char const *msg) { static void failAssertMsg(AssertionType type, std::string const &message) {
switch (type) { switch (type) {
case ASSERT_FATAL: case ASSERT_FATAL:
fatalerror("Assertion failed: %s\n", msg); fatalerror("Assertion failed: %s\n", message.c_str());
case ASSERT_ERROR: case ASSERT_ERROR:
error("Assertion failed: %s\n", msg); error("Assertion failed: %s\n", message.c_str());
break; break;
case ASSERT_WARN: case ASSERT_WARN:
warning(WARNING_ASSERT, "Assertion failed: %s\n", msg); warning(WARNING_ASSERT, "Assertion failed: %s\n", message.c_str());
break; break;
} }
} }