Group extern RGBASM variables in an Options struct

This commit is contained in:
Rangi42
2025-07-21 19:01:23 -04:00
parent d652212857
commit d1493a9f96
18 changed files with 133 additions and 156 deletions

View File

@@ -5,9 +5,6 @@
#include <stdint.h> #include <stdint.h>
extern uint8_t fixPrecision;
uint8_t fix_Precision();
int32_t fix_Sin(int32_t i, int32_t q); int32_t fix_Sin(int32_t i, int32_t q);
int32_t fix_Cos(int32_t i, int32_t q); int32_t fix_Cos(int32_t i, int32_t q);
int32_t fix_Tan(int32_t i, int32_t q); int32_t fix_Tan(int32_t i, int32_t q);

View File

@@ -47,8 +47,6 @@ struct FileStackNode {
std::string reptChain() const; std::string reptChain() const;
}; };
extern size_t maxRecursionDepth;
struct MacroArgs; struct MacroArgs;
bool fstk_DumpCurrent(); bool fstk_DumpCurrent();

View File

@@ -116,9 +116,6 @@ struct LexerState {
void clear(uint32_t lineNo_); void clear(uint32_t lineNo_);
}; };
extern char binDigits[2];
extern char gfxDigits[4];
void lexer_SetBinDigits(char const digits[2]); void lexer_SetBinDigits(char const digits[2]);
void lexer_SetGfxDigits(char const digits[4]); void lexer_SetGfxDigits(char const digits[4]);

View File

@@ -3,28 +3,51 @@
#ifndef RGBDS_ASM_MAIN_HPP #ifndef RGBDS_ASM_MAIN_HPP
#define RGBDS_ASM_MAIN_HPP #define RGBDS_ASM_MAIN_HPP
#include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <string> #include <string>
extern bool verbose;
#define verbosePrint(...) \
do { \
if (verbose) { \
fprintf(stderr, __VA_ARGS__); \
} \
} while (0)
enum MissingInclude { enum MissingInclude {
INC_ERROR, // A missing included file is an error that halts assembly INC_ERROR, // A missing included file is an error that halts assembly
GEN_EXIT, // A missing included file is assumed to be generated; exit normally GEN_EXIT, // A missing included file is assumed to be generated; exit normally
GEN_CONTINUE, // A missing included file is assumed to be generated; continue assembling GEN_CONTINUE, // A missing included file is assumed to be generated; continue assembling
}; };
extern FILE *dependFile; struct Options {
extern std::string targetFileName; uint8_t fixPrecision = 16; // -Q
extern MissingInclude missingIncludeState; size_t maxRecursionDepth; // -r
extern bool generatePhonyDeps; char binDigits[2] = {'0', '1'}; // -b
char gfxDigits[4] = {'0', '1', '2', '3'}; // -g
bool verbose = false; // -v
FILE *dependFile = nullptr; // -M
std::string targetFileName; // -MQ, -MT
MissingInclude missingIncludeState = INC_ERROR; // -MC, -MG
bool generatePhonyDeps = false; // -MP
std::string objectFileName; // -o
uint8_t padByte = 0; // -p
unsigned int maxErrors = 0; // -X
~Options() {
if (dependFile) {
fclose(dependFile);
}
}
void printDep(std::string const &depName) {
if (dependFile) {
fprintf(dependFile, "%s: %s\n", targetFileName.c_str(), depName.c_str());
}
}
};
extern Options options;
extern bool failedOnMissingInclude; extern bool failedOnMissingInclude;
#define verbosePrint(...) \
do { \
if (options.verbose) { \
fprintf(stderr, __VA_ARGS__); \
} \
} while (0)
#endif // RGBDS_ASM_MAIN_HPP #endif // RGBDS_ASM_MAIN_HPP

View File

@@ -5,10 +5,10 @@
#include <stdint.h> #include <stdint.h>
void opt_B(char const chars[2]); void opt_B(char const binDigits[2]);
void opt_G(char const chars[4]); void opt_G(char const gfxDigits[4]);
void opt_P(uint8_t padByte); void opt_P(uint8_t padByte);
void opt_Q(uint8_t precision); void opt_Q(uint8_t fixPrecision);
void opt_W(char const *flag); void opt_W(char const *flag);
void opt_Parse(char const *option); void opt_Parse(char const *option);

View File

@@ -16,8 +16,6 @@ struct FileStackNode;
enum StateFeature { STATE_EQU, STATE_VAR, STATE_EQUS, STATE_CHAR, STATE_MACRO, NB_STATE_FEATURES }; enum StateFeature { STATE_EQU, STATE_VAR, STATE_EQUS, STATE_CHAR, STATE_MACRO, NB_STATE_FEATURES };
extern std::string objectFileName;
void out_RegisterNode(std::shared_ptr<FileStackNode> node); void out_RegisterNode(std::shared_ptr<FileStackNode> node);
void out_SetFileName(std::string const &name); 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);

View File

@@ -12,8 +12,6 @@
#include "linkdefs.hpp" #include "linkdefs.hpp"
extern uint8_t fillByte;
struct Expression; struct Expression;
struct FileStackNode; struct FileStackNode;
struct Section; struct Section;

View File

@@ -7,7 +7,7 @@
#include "diagnostics.hpp" #include "diagnostics.hpp"
extern unsigned int nbErrors, maxErrors; extern unsigned int nbErrors;
enum WarningLevel { enum WarningLevel {
LEVEL_DEFAULT, // Warnings that are enabled by default LEVEL_DEFAULT, // Warnings that are enabled by default

View File

@@ -10,12 +10,6 @@
#define M_PI 3.14159265358979323846 #define M_PI 3.14159265358979323846
#endif #endif
uint8_t fixPrecision;
uint8_t fix_Precision() {
return fixPrecision;
}
static double fix2double(int32_t i, int32_t q) { static double fix2double(int32_t i, int32_t q) {
return i / pow(2.0, q); return i / pow(2.0, q);
} }

View File

@@ -10,6 +10,7 @@
#include <string.h> #include <string.h>
#include "asm/fixpoint.hpp" #include "asm/fixpoint.hpp"
#include "asm/main.hpp" // options
#include "asm/warning.hpp" #include "asm/warning.hpp"
void FormatSpec::useCharacter(int c) { void FormatSpec::useCharacter(int c) {
@@ -258,7 +259,7 @@ void FormatSpec::appendNumber(std::string &str, uint32_t value) const {
useFracWidth = 255; useFracWidth = 255;
} }
size_t defaultPrec = fix_Precision(); size_t defaultPrec = options.fixPrecision;
size_t usePrec = hasPrec ? precision : defaultPrec; size_t usePrec = hasPrec ? precision : defaultPrec;
if (usePrec < 1 || usePrec > 31) { if (usePrec < 1 || usePrec > 31) {
error( error(

View File

@@ -42,7 +42,6 @@ struct Context {
}; };
static std::stack<Context> contextStack; static std::stack<Context> contextStack;
size_t maxRecursionDepth;
// The first include path for `fstk_FindFile` to try is none at all // The first include path for `fstk_FindFile` to try is none at all
static std::vector<std::string> includePaths = {""}; static std::vector<std::string> includePaths = {""};
@@ -134,11 +133,9 @@ static bool isValidFilePath(std::string const &path) {
} }
static void printDep(std::string const &path) { static void printDep(std::string const &path) {
if (dependFile) { options.printDep(path);
fprintf(dependFile, "%s: %s\n", targetFileName.c_str(), path.c_str()); if (options.dependFile && options.generatePhonyDeps && isValidFilePath(path)) {
if (generatePhonyDeps && isValidFilePath(path)) { fprintf(options.dependFile, "%s:\n", path.c_str());
fprintf(dependFile, "%s:\n", path.c_str());
}
} }
} }
@@ -151,7 +148,7 @@ std::optional<std::string> fstk_FindFile(std::string const &path) {
} }
errno = ENOENT; errno = ENOENT;
if (missingIncludeState != INC_ERROR) { if (options.missingIncludeState != INC_ERROR) {
printDep(path); printDep(path);
} }
return std::nullopt; return std::nullopt;
@@ -212,8 +209,8 @@ bool yywrap() {
} }
static void checkRecursionDepth() { static void checkRecursionDepth() {
if (contextStack.size() > maxRecursionDepth) { if (contextStack.size() > options.maxRecursionDepth) {
fatal("Recursion limit (%zu) exceeded", maxRecursionDepth); fatal("Recursion limit (%zu) exceeded", options.maxRecursionDepth);
} }
} }
@@ -304,18 +301,18 @@ static Context &newReptContext(int32_t reptLineNo, ContentSpan const &span, uint
} }
bool fstk_FileError(std::string const &path, char const *functionName) { bool fstk_FileError(std::string const &path, char const *functionName) {
if (missingIncludeState == INC_ERROR) { if (options.missingIncludeState == INC_ERROR) {
error("Error opening %s file '%s': %s", functionName, path.c_str(), strerror(errno)); error("Error opening %s file '%s': %s", functionName, path.c_str(), strerror(errno));
} else { } else {
failedOnMissingInclude = true; failedOnMissingInclude = true;
// LCOV_EXCL_START // LCOV_EXCL_START
if (missingIncludeState == GEN_EXIT) { if (options.missingIncludeState == GEN_EXIT) {
verbosePrint( verbosePrint(
"Aborting (-MG) on %s file '%s' (%s)\n", functionName, path.c_str(), strerror(errno) "Aborting (-MG) on %s file '%s' (%s)\n", functionName, path.c_str(), strerror(errno)
); );
return true; return true;
} }
assume(missingIncludeState == GEN_CONTINUE); assume(options.missingIncludeState == GEN_CONTINUE);
// LCOV_EXCL_STOP // LCOV_EXCL_STOP
} }
return false; return false;
@@ -406,13 +403,13 @@ void fstk_NewRecursionDepth(size_t newDepth) {
if (contextStack.size() > newDepth + 1) { if (contextStack.size() > newDepth + 1) {
fatal("Recursion limit (%zu) exceeded", newDepth); fatal("Recursion limit (%zu) exceeded", newDepth);
} }
maxRecursionDepth = newDepth; options.maxRecursionDepth = newDepth;
} }
void fstk_Init(std::string const &mainPath, size_t maxDepth) { void fstk_Init(std::string const &mainPath, size_t maxDepth) {
newFileContext(mainPath, true); newFileContext(mainPath, true);
maxRecursionDepth = maxDepth; options.maxRecursionDepth = maxDepth;
for (std::string const &name : preIncludeNames) { for (std::string const &name : preIncludeNames) {
if (std::optional<std::string> fullPath = fstk_FindFile(name); fullPath) { if (std::optional<std::string> fullPath = fstk_FindFile(name); fullPath) {

View File

@@ -587,8 +587,8 @@ static void beginExpansion(std::shared_ptr<std::string> str, std::optional<std::
} }
void lexer_CheckRecursionDepth() { void lexer_CheckRecursionDepth() {
if (lexerState->expansions.size() > maxRecursionDepth + 1) { if (lexerState->expansions.size() > options.maxRecursionDepth + 1) {
fatal("Recursion limit (%zu) exceeded", maxRecursionDepth); fatal("Recursion limit (%zu) exceeded", options.maxRecursionDepth);
} }
} }
@@ -1043,10 +1043,10 @@ static uint32_t readFractionalPart(uint32_t integer) {
if (state >= READFRACTIONALPART_PRECISION) { if (state >= READFRACTIONALPART_PRECISION) {
error("Invalid fixed-point constant, no significant digits after 'q'"); error("Invalid fixed-point constant, no significant digits after 'q'");
} }
precision = fixPrecision; precision = options.fixPrecision;
} else if (precision > 31) { } else if (precision > 31) {
error("Fixed-point constant precision must be between 1 and 31"); error("Fixed-point constant precision must be between 1 and 31");
precision = fixPrecision; precision = options.fixPrecision;
} }
if (integer >= (1ULL << (32 - precision))) { if (integer >= (1ULL << (32 - precision))) {
@@ -1060,9 +1060,6 @@ static uint32_t readFractionalPart(uint32_t integer) {
return (integer << precision) | fractional; return (integer << precision) | fractional;
} }
char binDigits[2];
char gfxDigits[4];
static bool isValidDigit(char c) { static bool isValidDigit(char c) {
return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '.' return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '.'
|| c == '#' || c == '@'; || c == '#' || c == '@';
@@ -1094,14 +1091,14 @@ static bool checkDigitErrors(char const *digits, size_t n, char const *type) {
} }
void lexer_SetBinDigits(char const digits[2]) { void lexer_SetBinDigits(char const digits[2]) {
if (size_t n = std::size(binDigits); checkDigitErrors(digits, n, "binary")) { if (size_t n = std::size(options.binDigits); checkDigitErrors(digits, n, "binary")) {
memcpy(binDigits, digits, n); memcpy(options.binDigits, digits, n);
} }
} }
void lexer_SetGfxDigits(char const digits[4]) { void lexer_SetGfxDigits(char const digits[4]) {
if (size_t n = std::size(gfxDigits); checkDigitErrors(digits, n, "graphics")) { if (size_t n = std::size(options.gfxDigits); checkDigitErrors(digits, n, "graphics")) {
memcpy(gfxDigits, digits, n); memcpy(options.gfxDigits, digits, n);
} }
} }
@@ -1114,9 +1111,9 @@ static uint32_t readBinaryNumber() {
if (c == '_' && !empty) { if (c == '_' && !empty) {
continue; continue;
} else if (c == '0' || c == binDigits[0]) { } else if (c == '0' || c == options.binDigits[0]) {
bit = 0; bit = 0;
} else if (c == '1' || c == binDigits[1]) { } else if (c == '1' || c == options.binDigits[1]) {
bit = 1; bit = 1;
} else { } else {
break; break;
@@ -1227,13 +1224,13 @@ static uint32_t readGfxConstant() {
if (c == '_' && width > 0) { if (c == '_' && width > 0) {
continue; continue;
} else if (c == '0' || c == gfxDigits[0]) { } else if (c == '0' || c == options.gfxDigits[0]) {
pixel = 0; pixel = 0;
} else if (c == '1' || c == gfxDigits[1]) { } else if (c == '1' || c == options.gfxDigits[1]) {
pixel = 1; pixel = 1;
} else if (c == '2' || c == gfxDigits[2]) { } else if (c == '2' || c == options.gfxDigits[2]) {
pixel = 2; pixel = 2;
} else if (c == '3' || c == gfxDigits[3]) { } else if (c == '3' || c == options.gfxDigits[3]) {
pixel = 3; pixel = 3;
} else { } else {
break; break;
@@ -1297,8 +1294,8 @@ static Token readIdentifier(char firstChar, bool raw) {
// Functions to read strings // Functions to read strings
static std::shared_ptr<std::string> readInterpolation(size_t depth) { static std::shared_ptr<std::string> readInterpolation(size_t depth) {
if (depth > maxRecursionDepth) { if (depth > options.maxRecursionDepth) {
fatal("Recursion limit (%zu) exceeded", maxRecursionDepth); fatal("Recursion limit (%zu) exceeded", options.maxRecursionDepth);
} }
std::string fmtBuf; std::string fmtBuf;
@@ -1891,7 +1888,8 @@ static Token yylex_NORMAL() {
if (c == '=') { if (c == '=') {
shiftChar(); shiftChar();
return Token(T_(POP_MODEQ)); return Token(T_(POP_MODEQ));
} else if (c == '0' || c == '1' || c == binDigits[0] || c == binDigits[1]) { } else if (c == '0' || c == '1' || c == options.binDigits[0]
|| c == options.binDigits[1]) {
return Token(T_(NUMBER), readBinaryNumber()); return Token(T_(NUMBER), readBinaryNumber());
} }
return Token(T_(OP_MOD)); return Token(T_(OP_MOD));

View File

@@ -24,12 +24,8 @@
#include "asm/symbol.hpp" #include "asm/symbol.hpp"
#include "asm/warning.hpp" #include "asm/warning.hpp"
bool verbose = false; // -v Options options;
FILE *dependFile = nullptr; // -M
MissingInclude missingIncludeState = INC_ERROR; // -MC, -MG
bool generatePhonyDeps = false; // -MP
std::string targetFileName; // -MQ, -MT
bool failedOnMissingInclude = false; bool failedOnMissingInclude = false;
// Escapes Make-special chars from a string // Escapes Make-special chars from a string
@@ -178,20 +174,10 @@ int main(int argc, char *argv[]) {
now = static_cast<time_t>(strtoul(sourceDateEpoch, nullptr, 0)); now = static_cast<time_t>(strtoul(sourceDateEpoch, nullptr, 0));
} }
Defer closeDependFile{[&] {
if (dependFile) {
fclose(dependFile);
}
}};
// Perform some init for below // Perform some init for below
sym_Init(now); sym_Init(now);
// Set defaults // Set defaults
opt_B("01");
opt_G("0123");
opt_P(0);
opt_Q(16);
sym_SetExportAll(false); sym_SetExportAll(false);
uint32_t maxDepth = 64; uint32_t maxDepth = 64;
char const *dependFileName = nullptr; char const *dependFileName = nullptr;
@@ -199,7 +185,7 @@ int main(int argc, char *argv[]) {
std::string newTarget; std::string newTarget;
// Maximum of 100 errors only applies if rgbasm is printing errors to a terminal. // Maximum of 100 errors only applies if rgbasm is printing errors to a terminal.
if (isatty(STDERR_FILENO)) { if (isatty(STDERR_FILENO)) {
maxErrors = 100; options.maxErrors = 100;
} }
for (int ch; (ch = musl_getopt_long_only(argc, argv, optstring, longopts, nullptr)) != -1;) { for (int ch; (ch = musl_getopt_long_only(argc, argv, optstring, longopts, nullptr)) != -1;) {
@@ -248,17 +234,17 @@ int main(int argc, char *argv[]) {
break; break;
case 'M': case 'M':
if (dependFile) { if (options.dependFile) {
warnx("Overriding dependfile %s", dependFileName); warnx("Overriding dependfile %s", dependFileName);
} }
if (strcmp("-", musl_optarg)) { if (strcmp("-", musl_optarg)) {
dependFile = fopen(musl_optarg, "w"); options.dependFile = fopen(musl_optarg, "w");
dependFileName = musl_optarg; dependFileName = musl_optarg;
} else { } else {
dependFile = stdout; options.dependFile = stdout;
dependFileName = "<stdout>"; dependFileName = "<stdout>";
} }
if (dependFile == nullptr) { if (options.dependFile == nullptr) {
// LCOV_EXCL_START // LCOV_EXCL_START
fatal("Failed to open dependfile \"%s\": %s", dependFileName, strerror(errno)); fatal("Failed to open dependfile \"%s\": %s", dependFileName, strerror(errno));
// LCOV_EXCL_STOP // LCOV_EXCL_STOP
@@ -340,7 +326,7 @@ int main(int argc, char *argv[]) {
case 'v': case 'v':
// LCOV_EXCL_START // LCOV_EXCL_START
verbose = true; options.verbose = true;
break; break;
// LCOV_EXCL_STOP // LCOV_EXCL_STOP
@@ -352,34 +338,34 @@ int main(int argc, char *argv[]) {
warnings.state.warningsEnabled = false; warnings.state.warningsEnabled = false;
break; break;
unsigned long maxValue; unsigned long maxErrors;
case 'X': case 'X':
maxValue = strtoul(musl_optarg, &endptr, 0); maxErrors = strtoul(musl_optarg, &endptr, 0);
if (musl_optarg[0] == '\0' || *endptr != '\0') { if (musl_optarg[0] == '\0' || *endptr != '\0') {
fatal("Invalid argument for option 'X'"); fatal("Invalid argument for option 'X'");
} }
if (maxValue > UINT_MAX) { if (maxErrors > UINT_MAX) {
fatal("Argument for option 'X' must be between 0 and %u", UINT_MAX); fatal("Argument for option 'X' must be between 0 and %u", UINT_MAX);
} }
maxErrors = maxValue; options.maxErrors = maxErrors;
break; break;
// Long-only options // Long-only options
case 0: case 0:
switch (depType) { switch (depType) {
case 'C': case 'C':
missingIncludeState = GEN_CONTINUE; options.missingIncludeState = GEN_CONTINUE;
break; break;
case 'G': case 'G':
missingIncludeState = GEN_EXIT; options.missingIncludeState = GEN_EXIT;
break; break;
case 'P': case 'P':
generatePhonyDeps = true; options.generatePhonyDeps = true;
break; break;
case 'Q': case 'Q':
@@ -388,10 +374,10 @@ int main(int argc, char *argv[]) {
if (depType == 'Q') { if (depType == 'Q') {
newTarget = make_escape(newTarget); newTarget = make_escape(newTarget);
} }
if (!targetFileName.empty()) { if (!options.targetFileName.empty()) {
targetFileName += ' '; options.targetFileName += ' ';
} }
targetFileName += newTarget; options.targetFileName += newTarget;
break; break;
} }
break; break;
@@ -405,8 +391,8 @@ int main(int argc, char *argv[]) {
} }
} }
if (targetFileName.empty() && !objectFileName.empty()) { if (options.targetFileName.empty() && !options.objectFileName.empty()) {
targetFileName = objectFileName; options.targetFileName = options.objectFileName;
} }
if (argc == musl_optind) { if (argc == musl_optind) {
@@ -419,14 +405,11 @@ int main(int argc, char *argv[]) {
verbosePrint("Assembling %s\n", mainFileName.c_str()); // LCOV_EXCL_LINE verbosePrint("Assembling %s\n", mainFileName.c_str()); // LCOV_EXCL_LINE
if (dependFile) { if (options.dependFile && options.targetFileName.empty()) {
if (targetFileName.empty()) {
fatal("Dependency files can only be created if a target file is specified with either " fatal("Dependency files can only be created if a target file is specified with either "
"-o, -MQ or -MT"); "-o, -MQ or -MT");
} }
options.printDep(mainFileName);
fprintf(dependFile, "%s: %s\n", targetFileName.c_str(), mainFileName.c_str());
}
charmap_New(DEFAULT_CHARMAP_NAME, nullptr); charmap_New(DEFAULT_CHARMAP_NAME, nullptr);

View File

@@ -12,6 +12,7 @@
#include "asm/fixpoint.hpp" #include "asm/fixpoint.hpp"
#include "asm/fstack.hpp" #include "asm/fstack.hpp"
#include "asm/lexer.hpp" #include "asm/lexer.hpp"
#include "asm/main.hpp" // options
#include "asm/section.hpp" #include "asm/section.hpp"
#include "asm/warning.hpp" #include "asm/warning.hpp"
@@ -19,31 +20,31 @@ struct OptStackEntry {
char binDigits[2]; char binDigits[2];
char gfxDigits[4]; char gfxDigits[4];
uint8_t fixPrecision; uint8_t fixPrecision;
uint8_t fillByte; uint8_t padByte;
size_t maxRecursionDepth; size_t maxRecursionDepth;
DiagnosticsState<WarningID> warningStates; DiagnosticsState<WarningID> warningStates;
}; };
static std::stack<OptStackEntry> stack; static std::stack<OptStackEntry> stack;
void opt_B(char const chars[2]) { void opt_B(char const binDigits[2]) {
lexer_SetBinDigits(chars); lexer_SetBinDigits(binDigits);
} }
void opt_G(char const chars[4]) { void opt_G(char const gfxDigits[4]) {
lexer_SetGfxDigits(chars); lexer_SetGfxDigits(gfxDigits);
} }
void opt_P(uint8_t padByte) { void opt_P(uint8_t padByte) {
fillByte = padByte; options.padByte = padByte;
} }
void opt_Q(uint8_t precision) { void opt_Q(uint8_t fixPrecision) {
fixPrecision = precision; options.fixPrecision = fixPrecision;
} }
void opt_R(size_t newDepth) { void opt_R(size_t maxRecursionDepth) {
fstk_NewRecursionDepth(newDepth); fstk_NewRecursionDepth(maxRecursionDepth);
lexer_CheckRecursionDepth(); lexer_CheckRecursionDepth();
} }
@@ -97,15 +98,15 @@ void opt_Parse(char const *s) {
} }
if (strlen(precisionArg) <= 2) { if (strlen(precisionArg) <= 2) {
int result; int result;
unsigned int precision; unsigned int fixPrecision;
result = sscanf(precisionArg, "%u", &precision); result = sscanf(precisionArg, "%u", &fixPrecision);
if (result != 1) { if (result != 1) {
error("Invalid argument for option 'Q'"); error("Invalid argument for option 'Q'");
} else if (precision < 1 || precision > 31) { } else if (fixPrecision < 1 || fixPrecision > 31) {
error("Argument for option 'Q' must be between 1 and 31"); error("Argument for option 'Q' must be between 1 and 31");
} else { } else {
opt_Q(precision); opt_Q(fixPrecision);
} }
} else { } else {
error("Invalid argument for option 'Q'"); error("Invalid argument for option 'Q'");
@@ -124,14 +125,14 @@ void opt_Parse(char const *s) {
} }
char *endptr; char *endptr;
unsigned long newDepth = strtoul(s, &endptr, 10); unsigned long maxRecursionDepth = strtoul(s, &endptr, 10);
if (*endptr != '\0') { if (*endptr != '\0') {
error("Invalid argument to option 'r' (\"%s\")", s); error("Invalid argument to option 'r' (\"%s\")", s);
} else if (errno == ERANGE) { } else if (errno == ERANGE) {
error("Argument to 'r' is out of range (\"%s\")", s); error("Argument to 'r' is out of range (\"%s\")", s);
} else { } else {
opt_R(newDepth); opt_R(maxRecursionDepth);
} }
break; break;
} }
@@ -153,17 +154,12 @@ void opt_Parse(char const *s) {
void opt_Push() { void opt_Push() {
OptStackEntry entry; OptStackEntry entry;
// Both of these are pulled from lexer.hpp memcpy(entry.binDigits, options.binDigits, std::size(options.binDigits));
memcpy(entry.binDigits, binDigits, std::size(binDigits)); memcpy(entry.gfxDigits, options.gfxDigits, std::size(options.gfxDigits));
memcpy(entry.gfxDigits, gfxDigits, std::size(gfxDigits)); entry.padByte = options.padByte;
entry.fixPrecision = options.fixPrecision;
entry.fixPrecision = fixPrecision; // Pulled from fixpoint.hpp entry.maxRecursionDepth = options.maxRecursionDepth;
entry.warningStates = warnings.state;
entry.fillByte = fillByte; // Pulled from section.hpp
entry.warningStates = warnings.state; // Pulled from warning.hpp
entry.maxRecursionDepth = maxRecursionDepth; // Pulled from fstack.h
stack.push(entry); stack.push(entry);
} }
@@ -179,7 +175,7 @@ void opt_Pop() {
opt_B(entry.binDigits); opt_B(entry.binDigits);
opt_G(entry.gfxDigits); opt_G(entry.gfxDigits);
opt_P(entry.fillByte); opt_P(entry.padByte);
opt_Q(entry.fixPrecision); opt_Q(entry.fixPrecision);
opt_R(entry.maxRecursionDepth); opt_R(entry.maxRecursionDepth);

View File

@@ -30,8 +30,6 @@ struct Assertion {
std::string message; std::string message;
}; };
std::string objectFileName;
// 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;
@@ -316,21 +314,23 @@ static void writeFileStackNode(FileStackNode const &node, FILE *file) {
} }
void out_WriteObject() { void out_WriteObject() {
if (objectFileName.empty()) { if (options.objectFileName.empty()) {
return; return;
} }
FILE *file; FILE *file;
if (objectFileName != "-") { if (options.objectFileName != "-") {
file = fopen(objectFileName.c_str(), "wb"); file = fopen(options.objectFileName.c_str(), "wb");
} else { } else {
objectFileName = "<stdout>"; options.objectFileName = "<stdout>";
(void)setmode(STDOUT_FILENO, O_BINARY); (void)setmode(STDOUT_FILENO, O_BINARY);
file = stdout; file = stdout;
} }
if (!file) { if (!file) {
// LCOV_EXCL_START // LCOV_EXCL_START
fatal("Failed to open object file '%s': %s", objectFileName.c_str(), strerror(errno)); fatal(
"Failed to open object file '%s': %s", options.objectFileName.c_str(), strerror(errno)
);
// LCOV_EXCL_STOP // LCOV_EXCL_STOP
} }
Defer closeFile{[&] { fclose(file); }}; Defer closeFile{[&] { fclose(file); }};
@@ -370,11 +370,11 @@ void out_WriteObject() {
} }
void out_SetFileName(std::string const &name) { void out_SetFileName(std::string const &name) {
if (!objectFileName.empty()) { if (!options.objectFileName.empty()) {
warnx("Overriding output filename %s", objectFileName.c_str()); warnx("Overriding output filename %s", options.objectFileName.c_str());
} }
objectFileName = name; options.objectFileName = name;
verbosePrint("Output filename %s\n", objectFileName.c_str()); // LCOV_EXCL_LINE verbosePrint("Output filename %s\n", options.objectFileName.c_str()); // LCOV_EXCL_LINE
} }
static void dumpString(std::string const &escape, FILE *file) { static void dumpString(std::string const &escape, FILE *file) {

View File

@@ -1671,13 +1671,13 @@ iconst:
precision_arg: precision_arg:
%empty { %empty {
$$ = fix_Precision(); $$ = options.fixPrecision;
} }
| COMMA iconst { | COMMA iconst {
$$ = $2; $$ = $2;
if ($$ < 1 || $$ > 31) { if ($$ < 1 || $$ > 31) {
::error("Fixed-point precision must be between 1 and 31, not %" PRId32, $$); ::error("Fixed-point precision must be between 1 and 31, not %" PRId32, $$);
$$ = fix_Precision(); $$ = options.fixPrecision;
} }
} }
; ;

View File

@@ -24,8 +24,6 @@
using namespace std::literals; using namespace std::literals;
uint8_t fillByte;
struct UnionStackEntry { struct UnionStackEntry {
uint32_t start; uint32_t start;
uint32_t size; uint32_t size;
@@ -782,7 +780,7 @@ void sect_Skip(uint32_t skip, bool ds) {
} }
// We know we're in a code SECTION // We know we're in a code SECTION
while (skip--) { while (skip--) {
writeByte(fillByte); writeByte(options.padByte);
} }
} }
} }

View File

@@ -18,7 +18,6 @@
#include "asm/main.hpp" #include "asm/main.hpp"
unsigned int nbErrors = 0; unsigned int nbErrors = 0;
unsigned int maxErrors = 0;
// clang-format off: nested initializers // clang-format off: nested initializers
Diagnostics<WarningLevel, WarningID> warnings = { Diagnostics<WarningLevel, WarningID> warnings = {
@@ -81,7 +80,7 @@ static void printDiag(
static void incrementErrors() { static void incrementErrors() {
// This intentionally makes 0 act as "unlimited" (or at least "limited to sizeof(unsigned)") // This intentionally makes 0 act as "unlimited" (or at least "limited to sizeof(unsigned)")
if (++nbErrors == maxErrors) { if (++nbErrors == options.maxErrors) {
fprintf( fprintf(
stderr, stderr,
"Assembly aborted after the maximum of %u error%s! (configure with " "Assembly aborted after the maximum of %u error%s! (configure with "