Replace some macros with static functions or constants

This commit is contained in:
Rangi42
2024-03-07 16:03:27 -05:00
parent 90356ee669
commit aed172071b
6 changed files with 157 additions and 165 deletions

View File

@@ -19,7 +19,7 @@
#ifdef _MSC_VER
#define S_IFMT _S_IFMT
#define S_IFDIR _S_IFDIR
#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#endif
// gcc has __PRETTY_FUNCTION__, MSVC has __FUNCSIG__, __func__ is standard
@@ -49,7 +49,7 @@
#ifdef _MSC_VER
#include <fcntl.h>
#define O_RDWR _O_RDWR
#define S_ISREG(field) ((field)&_S_IFREG)
#define S_ISREG(field) ((field) & _S_IFREG)
#define O_BINARY _O_BINARY
#define O_TEXT _O_TEXT
#elif !defined(O_BINARY) // Cross-compilers define O_BINARY

View File

@@ -15,13 +15,6 @@
#define M_PI 3.14159265358979323846
#endif
#define fix2double(i, q) ((double)((i) / pow(2.0, q)))
#define double2fix(d, q) ((int32_t)round((d)*pow(2.0, q)))
// 2*pi radians == 1 turn
#define turn2rad(f) ((f) * (M_PI * 2))
#define rad2turn(r) ((r) / (M_PI * 2))
uint8_t fixPrecision;
uint8_t fix_Precision() {
@@ -32,6 +25,22 @@ double fix_PrecisionFactor() {
return pow(2.0, fixPrecision);
}
static double fix2double(int32_t i, int32_t q) {
return i / pow(2.0, q);
}
static int32_t double2fix(double d, int32_t q) {
return (int32_t)round(d * pow(2.0, q));
}
static double turn2rad(double t) {
return t * (M_PI * 2);
}
static double rad2turn(double r) {
return r / (M_PI * 2);
}
int32_t fix_Sin(int32_t i, int32_t q) {
return double2fix(sin(turn2rad(fix2double(i, q))), q);
}

View File

@@ -50,48 +50,49 @@
#include <memoryapi.h> // MapViewOfFile
#include <handleapi.h> // CloseHandle
// clang-format on
#define MAP_FAILED nullptr
#define mapFile(ptr, fd, path, size) \
do { \
(ptr) = MAP_FAILED; \
HANDLE file = CreateFileA( \
path, \
GENERIC_READ, \
FILE_SHARE_READ, \
nullptr, \
OPEN_EXISTING, \
FILE_FLAG_POSIX_SEMANTICS | FILE_FLAG_RANDOM_ACCESS, \
nullptr \
); \
HANDLE mappingObj; \
if (file == INVALID_HANDLE_VALUE) \
break; \
mappingObj = CreateFileMappingA(file, nullptr, PAGE_READONLY, 0, 0, nullptr); \
if (mappingObj != INVALID_HANDLE_VALUE) \
(ptr) = MapViewOfFile(mappingObj, FILE_MAP_READ, 0, 0, 0); \
CloseHandle(mappingObj); \
CloseHandle(file); \
} while (0)
#define munmap(ptr, size) UnmapViewOfFile((ptr))
static void mapFile(void *&mappingAddr, int fd, char const *path, size_t) {
mappingAddr = MAP_FAILED;
HANDLE file = CreateFileA(
path,
GENERIC_READ,
FILE_SHARE_READ,
nullptr,
OPEN_EXISTING,
FILE_FLAG_POSIX_SEMANTICS | FILE_FLAG_RANDOM_ACCESS,
nullptr
);
HANDLE mappingObj;
if (file == INVALID_HANDLE_VALUE)
return;
mappingObj = CreateFileMappingA(file, nullptr, PAGE_READONLY, 0, 0, nullptr);
if (mappingObj != INVALID_HANDLE_VALUE)
mappingAddr = MapViewOfFile(mappingObj, FILE_MAP_READ, 0, 0, 0);
CloseHandle(mappingObj);
CloseHandle(file);
}
static int munmap(void *mappingAddr, size_t) {
return UnmapViewOfFile(mappingAddr) == 0 ? -1 : 0;
}
#else // defined(_MSC_VER) || defined(__MINGW32__)
#include <sys/mman.h>
#define mapFile(ptr, fd, path, size) \
do { \
(ptr) = mmap(nullptr, (size), PROT_READ, MAP_PRIVATE, (fd), 0); \
if ((ptr) == 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 \
* the file while reading it. That's still better than not opening it at all, \
* though \
*/ \
if (verbose) \
printf("mmap(%s, MAP_PRIVATE) failed, retrying with MAP_SHARED\n", path); \
(ptr) = mmap(nullptr, (size), PROT_READ, MAP_SHARED, (fd), 0); \
} \
} while (0)
static void mapFile(void *&mappingAddr, int fd, char const *path, size_t size) {
mappingAddr = mmap(nullptr, size, PROT_READ, MAP_PRIVATE, fd, 0);
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
// the file while reading it. That's still better than not opening it at all, though.
if (verbose)
printf("mmap(%s, MAP_PRIVATE) failed, retrying with MAP_SHARED\n", path);
mappingAddr = mmap(nullptr, size, PROT_READ, MAP_SHARED, fd, 0);
}
}
#endif // !( defined(_MSC_VER) || defined(__MINGW32__) )
// Bison 3.6 changed token "types" to "kinds"; cast to int for simple compatibility

View File

@@ -583,21 +583,12 @@ void sym_Init(time_t now) {
sym_AddVar("_RS", 0)->isBuiltin = true;
#define addSym(fn, name, val) \
do { \
Symbol *sym = fn(name, val); \
assert(sym); \
sym->isBuiltin = true; \
} while (0)
#define addNumber(name, val) addSym(sym_AddEqu, name, val)
#define addString(name, val) addSym(sym_AddString, name, val)
addString("__RGBDS_VERSION__", get_package_version_string());
addNumber("__RGBDS_MAJOR__", PACKAGE_VERSION_MAJOR);
addNumber("__RGBDS_MINOR__", PACKAGE_VERSION_MINOR);
addNumber("__RGBDS_PATCH__", PACKAGE_VERSION_PATCH);
sym_AddString("__RGBDS_VERSION__", get_package_version_string())->isBuiltin = true;
sym_AddEqu("__RGBDS_MAJOR__", PACKAGE_VERSION_MAJOR)->isBuiltin = true;
sym_AddEqu("__RGBDS_MINOR__", PACKAGE_VERSION_MINOR)->isBuiltin = true;
sym_AddEqu("__RGBDS_PATCH__", PACKAGE_VERSION_PATCH)->isBuiltin = true;
#ifdef PACKAGE_VERSION_RC
addNumber("__RGBDS_RC__", PACKAGE_VERSION_RC);
sym_AddEqu("__RGBDS_RC__", PACKAGE_VERSION_RC)->isBuiltin = true;
#endif
if (now == (time_t)-1) {
@@ -626,21 +617,17 @@ void sym_Init(time_t now) {
time_utc
);
addString("__TIME__", savedTIME);
addString("__DATE__", savedDATE);
addString("__ISO_8601_LOCAL__", savedTIMESTAMP_ISO8601_LOCAL);
addString("__ISO_8601_UTC__", savedTIMESTAMP_ISO8601_UTC);
sym_AddString("__TIME__", savedTIME)->isBuiltin = true;
sym_AddString("__DATE__", savedDATE)->isBuiltin = true;
sym_AddString("__ISO_8601_LOCAL__", savedTIMESTAMP_ISO8601_LOCAL)->isBuiltin = true;
sym_AddString("__ISO_8601_UTC__", savedTIMESTAMP_ISO8601_UTC)->isBuiltin = true;
addNumber("__UTC_YEAR__", time_utc->tm_year + 1900);
addNumber("__UTC_MONTH__", time_utc->tm_mon + 1);
addNumber("__UTC_DAY__", time_utc->tm_mday);
addNumber("__UTC_HOUR__", time_utc->tm_hour);
addNumber("__UTC_MINUTE__", time_utc->tm_min);
addNumber("__UTC_SECOND__", time_utc->tm_sec);
#undef addNumber
#undef addString
#undef addSym
sym_AddEqu("__UTC_YEAR__", time_utc->tm_year + 1900)->isBuiltin = true;
sym_AddEqu("__UTC_MONTH__", time_utc->tm_mon + 1)->isBuiltin = true;
sym_AddEqu("__UTC_DAY__", time_utc->tm_mday)->isBuiltin = true;
sym_AddEqu("__UTC_HOUR__", time_utc->tm_hour)->isBuiltin = true;
sym_AddEqu("__UTC_MINUTE__", time_utc->tm_min)->isBuiltin = true;
sym_AddEqu("__UTC_SECOND__", time_utc->tm_sec)->isBuiltin = true;
labelScope = std::nullopt;
anonLabelID = 0;

View File

@@ -1218,36 +1218,38 @@ finish:
return nbErrors;
}
static void parseByte(uint16_t &output, char name) {
if (musl_optarg[0] == 0) {
report("error: Argument to option '%c' may not be empty\n", name);
} else {
char *endptr;
unsigned long value;
if (musl_optarg[0] == '$') {
value = strtoul(&musl_optarg[1], &endptr, 16);
} else {
value = strtoul(musl_optarg, &endptr, 0);
}
if (*endptr) {
report(
"error: Expected number as argument to option '%c', got %s\n",
name,
musl_optarg
);
} else if (value > 0xFF) {
report("error: Argument to option '%c' is larger than 255: %lu\n", name, value);
} else {
output = value;
}
}
}
int main(int argc, char *argv[]) {
nbErrors = 0;
for (int ch; (ch = musl_getopt_long_only(argc, argv, optstring, longopts, nullptr)) != -1;) {
switch (ch) {
size_t len;
#define parseByte(output, name) \
do { \
char *endptr; \
unsigned long tmp; \
\
if (musl_optarg[0] == 0) { \
report("error: Argument to option '" name "' may not be empty\n"); \
} else { \
if (musl_optarg[0] == '$') { \
tmp = strtoul(&musl_optarg[1], &endptr, 16); \
} else { \
tmp = strtoul(musl_optarg, &endptr, 0); \
} \
if (*endptr) \
report( \
"error: Expected number as argument to option '" name "', got %s\n", \
musl_optarg \
); \
else if (tmp > 0xFF) \
report("error: Argument to option '" name "' is larger than 255: %lu\n", tmp); \
else \
output = tmp; \
} \
} while (0)
case 'C':
case 'c':
@@ -1334,7 +1336,7 @@ int main(int argc, char *argv[]) {
break;
case 'l':
parseByte(oldLicensee, "l");
parseByte(oldLicensee, 'l');
break;
case 'm':
@@ -1360,7 +1362,7 @@ int main(int argc, char *argv[]) {
break;
case 'n':
parseByte(romVersion, "n");
parseByte(romVersion, 'n');
break;
case 'O':
@@ -1368,11 +1370,11 @@ int main(int argc, char *argv[]) {
break;
case 'p':
parseByte(padValue, "p");
parseByte(padValue, 'p');
break;
case 'r':
parseByte(ramSize, "r");
parseByte(ramSize, 'r');
break;
case 's':
@@ -1405,7 +1407,6 @@ int main(int argc, char *argv[]) {
printUsage();
exit(1);
}
#undef parseByte
}
if ((cartridgeType & 0xFF00) == TPP1 && !japanese)

View File

@@ -35,9 +35,9 @@ static void pushRPN(int32_t value, bool comesFromError) {
// has popped any values with the error flag set.
static bool isError = false;
static int32_t popRPN(FileStackNode const *node, uint32_t lineNo) {
static int32_t popRPN(Patch const &patch) {
if (rpnStack.empty())
fatal(node, lineNo, "Internal error, RPN stack empty");
fatal(patch.src, patch.lineNo, "Internal error, RPN stack empty");
RPNStackEntry entry = rpnStack.front();
@@ -48,11 +48,9 @@ static int32_t popRPN(FileStackNode const *node, uint32_t lineNo) {
// RPN operators
static uint32_t getRPNByte(
uint8_t const *&expression, int32_t &size, FileStackNode const *node, uint32_t lineNo
) {
static uint32_t getRPNByte(uint8_t const *&expression, int32_t &size, Patch const &patch) {
if (!size--)
fatal(node, lineNo, "Internal error, RPN expression overread");
fatal(patch.src, patch.lineNo, "Internal error, RPN expression overread");
return *expression++;
}
@@ -77,8 +75,6 @@ static Symbol const *getSymbol(std::vector<Symbol> const &symbolList, uint32_t i
* errors caused by the value should be suppressed.
*/
static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fileSymbols) {
// Small shortcut to avoid a lot of repetition
#define popRPN() popRPN(patch.src, patch.lineNo)
uint8_t const *expression = patch.rpnExpression.data();
int32_t size = (int32_t)patch.rpnExpression.size();
@@ -87,7 +83,7 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
while (size > 0) {
enum RPNCommand command =
(enum RPNCommand)getRPNByte(expression, size, patch.src, patch.lineNo);
(enum RPNCommand)getRPNByte(expression, size, patch);
int32_t value;
isError = false;
@@ -102,120 +98,120 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
Section const *sect;
case RPN_ADD:
value = popRPN() + popRPN();
value = popRPN(patch) + popRPN(patch);
break;
case RPN_SUB:
value = popRPN();
value = popRPN() - value;
value = popRPN(patch);
value = popRPN(patch) - value;
break;
case RPN_MUL:
value = popRPN() * popRPN();
value = popRPN(patch) * popRPN(patch);
break;
case RPN_DIV:
value = popRPN();
value = popRPN(patch);
if (value == 0) {
if (!isError)
error(patch.src, patch.lineNo, "Division by 0");
isError = true;
popRPN();
popRPN(patch);
value = INT32_MAX;
} else {
value = op_divide(popRPN(), value);
value = op_divide(popRPN(patch), value);
}
break;
case RPN_MOD:
value = popRPN();
value = popRPN(patch);
if (value == 0) {
if (!isError)
error(patch.src, patch.lineNo, "Modulo by 0");
isError = true;
popRPN();
popRPN(patch);
value = 0;
} else {
value = op_modulo(popRPN(), value);
value = op_modulo(popRPN(patch), value);
}
break;
case RPN_NEG:
value = -popRPN();
value = -popRPN(patch);
break;
case RPN_EXP:
value = popRPN();
value = popRPN(patch);
if (value < 0) {
if (!isError)
error(patch.src, patch.lineNo, "Exponent by negative");
isError = true;
popRPN();
popRPN(patch);
value = 0;
} else {
value = op_exponent(popRPN(), value);
value = op_exponent(popRPN(patch), value);
}
break;
case RPN_OR:
value = popRPN() | popRPN();
value = popRPN(patch) | popRPN(patch);
break;
case RPN_AND:
value = popRPN() & popRPN();
value = popRPN(patch) & popRPN(patch);
break;
case RPN_XOR:
value = popRPN() ^ popRPN();
value = popRPN(patch) ^ popRPN(patch);
break;
case RPN_NOT:
value = ~popRPN();
value = ~popRPN(patch);
break;
case RPN_LOGAND:
value = popRPN();
value = popRPN() && value;
value = popRPN(patch);
value = popRPN(patch) && value;
break;
case RPN_LOGOR:
value = popRPN();
value = popRPN() || value;
value = popRPN(patch);
value = popRPN(patch) || value;
break;
case RPN_LOGNOT:
value = !popRPN();
value = !popRPN(patch);
break;
case RPN_LOGEQ:
value = popRPN() == popRPN();
value = popRPN(patch) == popRPN(patch);
break;
case RPN_LOGNE:
value = popRPN() != popRPN();
value = popRPN(patch) != popRPN(patch);
break;
case RPN_LOGGT:
value = popRPN();
value = popRPN() > value;
value = popRPN(patch);
value = popRPN(patch) > value;
break;
case RPN_LOGLT:
value = popRPN();
value = popRPN() < value;
value = popRPN(patch);
value = popRPN(patch) < value;
break;
case RPN_LOGGE:
value = popRPN();
value = popRPN() >= value;
value = popRPN(patch);
value = popRPN(patch) >= value;
break;
case RPN_LOGLE:
value = popRPN();
value = popRPN() <= value;
value = popRPN(patch);
value = popRPN(patch) <= value;
break;
case RPN_SHL:
value = popRPN();
value = op_shift_left(popRPN(), value);
value = popRPN(patch);
value = op_shift_left(popRPN(patch), value);
break;
case RPN_SHR:
value = popRPN();
value = op_shift_right(popRPN(), value);
value = popRPN(patch);
value = op_shift_right(popRPN(patch), value);
break;
case RPN_USHR:
value = popRPN();
value = op_shift_right_unsigned(popRPN(), value);
value = popRPN(patch);
value = op_shift_right_unsigned(popRPN(patch), value);
break;
case RPN_BANK_SYM:
value = 0;
for (uint8_t shift = 0; shift < 32; shift += 8)
value |= getRPNByte(expression, size, patch.src, patch.lineNo) << shift;
value |= getRPNByte(expression, size, patch) << shift;
symbol = getSymbol(fileSymbols, value);
if (!symbol) {
@@ -245,7 +241,7 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
// `expression` is not guaranteed to be '\0'-terminated. If it is not,
// `getRPNByte` will have a fatal internal error.
name = (char const *)expression;
while (getRPNByte(expression, size, patch.src, patch.lineNo))
while (getRPNByte(expression, size, patch))
;
sect = sect_GetSection(name);
@@ -277,7 +273,7 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
case RPN_SIZEOF_SECT:
// This has assumptions commented in the `RPN_BANK_SECT` case above.
name = (char const *)expression;
while (getRPNByte(expression, size, patch.src, patch.lineNo))
while (getRPNByte(expression, size, patch))
;
sect = sect_GetSection(name);
@@ -299,7 +295,7 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
case RPN_STARTOF_SECT:
// This has assumptions commented in the `RPN_BANK_SECT` case above.
name = (char const *)expression;
while (getRPNByte(expression, size, patch.src, patch.lineNo))
while (getRPNByte(expression, size, patch))
;
sect = sect_GetSection(name);
@@ -320,7 +316,7 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
break;
case RPN_SIZEOF_SECTTYPE:
value = getRPNByte(expression, size, patch.src, patch.lineNo);
value = getRPNByte(expression, size, patch);
if (value < 0 || value >= SECTTYPE_INVALID) {
error(patch.src, patch.lineNo, "Requested SIZEOF() an invalid section type");
isError = true;
@@ -331,7 +327,7 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
break;
case RPN_STARTOF_SECTTYPE:
value = getRPNByte(expression, size, patch.src, patch.lineNo);
value = getRPNByte(expression, size, patch);
if (value < 0 || value >= SECTTYPE_INVALID) {
error(patch.src, patch.lineNo, "Requested STARTOF() an invalid section type");
isError = true;
@@ -342,7 +338,7 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
break;
case RPN_HRAM:
value = popRPN();
value = popRPN(patch);
if (!isError && (value < 0 || (value > 0xFF && value < 0xFF00) || value > 0xFFFF)) {
error(patch.src, patch.lineNo, "Value %" PRId32 " is not in HRAM range", value);
isError = true;
@@ -351,7 +347,7 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
break;
case RPN_RST:
value = popRPN();
value = popRPN(patch);
// Acceptable values are 0x00, 0x08, 0x10, ..., 0x38
// They can be easily checked with a bitmask
if (value & ~0x38) {
@@ -365,13 +361,13 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
case RPN_CONST:
value = 0;
for (uint8_t shift = 0; shift < 32; shift += 8)
value |= getRPNByte(expression, size, patch.src, patch.lineNo) << shift;
value |= getRPNByte(expression, size, patch) << shift;
break;
case RPN_SYM:
value = 0;
for (uint8_t shift = 0; shift < 32; shift += 8)
value |= getRPNByte(expression, size, patch.src, patch.lineNo) << shift;
value |= getRPNByte(expression, size, patch) << shift;
if (value == -1) { // PC
if (!patch.pcSection) {
@@ -414,9 +410,7 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
error(patch.src, patch.lineNo, "RPN stack has %zu entries on exit, not 1", rpnStack.size());
isError = false;
return popRPN();
#undef popRPN
return popRPN(patch);
}
void patch_CheckAssertions(std::deque<Assertion> &assertions) {