mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Make some changes noticed while porting to C++
This commit is contained in:
@@ -11,6 +11,11 @@
|
|||||||
|
|
||||||
#include "asm/lexer.h"
|
#include "asm/lexer.h"
|
||||||
|
|
||||||
|
enum FileStackNodeType {
|
||||||
|
NODE_REPT,
|
||||||
|
NODE_FILE,
|
||||||
|
NODE_MACRO,
|
||||||
|
};
|
||||||
|
|
||||||
struct FileStackNode {
|
struct FileStackNode {
|
||||||
struct FileStackNode *parent; // Pointer to parent node, for error reporting
|
struct FileStackNode *parent; // Pointer to parent node, for error reporting
|
||||||
@@ -21,11 +26,7 @@ struct FileStackNode {
|
|||||||
bool referenced; // If referenced, don't free!
|
bool referenced; // If referenced, don't free!
|
||||||
uint32_t ID; // Set only if referenced: ID within the object file, -1 if not output yet
|
uint32_t ID; // Set only if referenced: ID within the object file, -1 if not output yet
|
||||||
|
|
||||||
enum {
|
enum FileStackNodeType type;
|
||||||
NODE_REPT,
|
|
||||||
NODE_FILE,
|
|
||||||
NODE_MACRO,
|
|
||||||
} type;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FileStackReptNode { // NODE_REPT
|
struct FileStackReptNode { // NODE_REPT
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ void opt_G(char const chars[4]);
|
|||||||
void opt_P(uint8_t padByte);
|
void opt_P(uint8_t padByte);
|
||||||
void opt_Q(uint8_t precision);
|
void opt_Q(uint8_t precision);
|
||||||
void opt_L(bool optimize);
|
void opt_L(bool optimize);
|
||||||
void opt_W(char const *flag);
|
void opt_W(char *flag);
|
||||||
void opt_Parse(char const *option);
|
void opt_Parse(char *option);
|
||||||
|
|
||||||
void opt_Push(void);
|
void opt_Push(void);
|
||||||
void opt_Pop(void);
|
void opt_Pop(void);
|
||||||
|
|||||||
@@ -38,9 +38,9 @@ struct SectionSpec {
|
|||||||
extern struct Section *currentSection;
|
extern struct Section *currentSection;
|
||||||
|
|
||||||
struct Section *sect_FindSectionByName(char const *name);
|
struct Section *sect_FindSectionByName(char const *name);
|
||||||
void sect_NewSection(char const *name, uint32_t secttype, uint32_t org,
|
void sect_NewSection(char const *name, enum SectionType type, uint32_t org,
|
||||||
struct SectionSpec const *attributes, enum SectionModifier mod);
|
struct SectionSpec const *attributes, enum SectionModifier mod);
|
||||||
void sect_SetLoadSection(char const *name, uint32_t secttype, uint32_t org,
|
void sect_SetLoadSection(char const *name, enum SectionType type, uint32_t org,
|
||||||
struct SectionSpec const *attributes, enum SectionModifier mod);
|
struct SectionSpec const *attributes, enum SectionModifier mod);
|
||||||
void sect_EndLoadSection(void);
|
void sect_EndLoadSection(void);
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "platform.h" // __PRETTY_FUNCTION__
|
||||||
|
|
||||||
template<typename... Ts>
|
template<typename... Ts>
|
||||||
static inline void report() {
|
static inline void report() {
|
||||||
puts(__PRETTY_FUNCTION__);
|
puts(__PRETTY_FUNCTION__);
|
||||||
|
|||||||
@@ -27,16 +27,18 @@ extern bool beVerbose;
|
|||||||
extern bool isWRA0Mode;
|
extern bool isWRA0Mode;
|
||||||
extern bool disablePadding;
|
extern bool disablePadding;
|
||||||
|
|
||||||
|
enum FileStackNodeType {
|
||||||
|
NODE_REPT,
|
||||||
|
NODE_FILE,
|
||||||
|
NODE_MACRO,
|
||||||
|
};
|
||||||
|
|
||||||
struct FileStackNode {
|
struct FileStackNode {
|
||||||
struct FileStackNode *parent;
|
struct FileStackNode *parent;
|
||||||
// Line at which the parent context was exited; meaningless for the root level
|
// Line at which the parent context was exited; meaningless for the root level
|
||||||
uint32_t lineNo;
|
uint32_t lineNo;
|
||||||
|
|
||||||
enum {
|
enum FileStackNodeType type;
|
||||||
NODE_REPT,
|
|
||||||
NODE_FILE,
|
|
||||||
NODE_MACRO,
|
|
||||||
} type;
|
|
||||||
union {
|
union {
|
||||||
char *name; // NODE_FILE, NODE_MACRO
|
char *name; // NODE_FILE, NODE_MACRO
|
||||||
struct { // NODE_REPT
|
struct { // NODE_REPT
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#define RGBDS_LINK_SCRIPT_H
|
#define RGBDS_LINK_SCRIPT_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "linkdefs.h"
|
#include "linkdefs.h"
|
||||||
|
|
||||||
extern FILE * linkerScript;
|
extern FILE * linkerScript;
|
||||||
|
|||||||
@@ -27,6 +27,15 @@
|
|||||||
# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
|
# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// gcc has __PRETTY_FUNCTION__, MSVC has __FUNCSIG__, __func__ is standard
|
||||||
|
#ifndef __PRETTY_FUNCTION__
|
||||||
|
# ifdef __FUNCSIG__
|
||||||
|
# define __PRETTY_FUNCTION__ __FUNCSIG__
|
||||||
|
# else
|
||||||
|
# define __PRETTY_FUNCTION__ __func__
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
// MSVC doesn't use POSIX types or defines for `read`
|
// MSVC doesn't use POSIX types or defines for `read`
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# include <io.h>
|
# include <io.h>
|
||||||
|
|||||||
@@ -122,9 +122,8 @@ void charmap_Set(char const *name)
|
|||||||
|
|
||||||
void charmap_Push(void)
|
void charmap_Push(void)
|
||||||
{
|
{
|
||||||
struct CharmapStackEntry *stackEntry;
|
struct CharmapStackEntry *stackEntry = malloc(sizeof(*stackEntry));
|
||||||
|
|
||||||
stackEntry = malloc(sizeof(*stackEntry));
|
|
||||||
if (stackEntry == NULL)
|
if (stackEntry == NULL)
|
||||||
fatalerror("Failed to alloc charmap stack entry: %s\n", strerror(errno));
|
fatalerror("Failed to alloc charmap stack entry: %s\n", strerror(errno));
|
||||||
|
|
||||||
|
|||||||
@@ -386,7 +386,7 @@ static void changeSection(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set the current section by name and type
|
// Set the current section by name and type
|
||||||
void sect_NewSection(char const *name, uint32_t type, uint32_t org,
|
void sect_NewSection(char const *name, enum SectionType type, uint32_t org,
|
||||||
struct SectionSpec const *attribs, enum SectionModifier mod)
|
struct SectionSpec const *attribs, enum SectionModifier mod)
|
||||||
{
|
{
|
||||||
if (currentLoadSection)
|
if (currentLoadSection)
|
||||||
@@ -406,7 +406,7 @@ void sect_NewSection(char const *name, uint32_t type, uint32_t org,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set the current section by name and type
|
// Set the current section by name and type
|
||||||
void sect_SetLoadSection(char const *name, uint32_t type, uint32_t org,
|
void sect_SetLoadSection(char const *name, enum SectionType type, uint32_t org,
|
||||||
struct SectionSpec const *attribs, enum SectionModifier mod)
|
struct SectionSpec const *attribs, enum SectionModifier mod)
|
||||||
{
|
{
|
||||||
// Important info: currently, UNION and LOAD cannot interact, since UNION is prohibited in
|
// Important info: currently, UNION and LOAD cannot interact, since UNION is prohibited in
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ void processWarningFlag(char *flag)
|
|||||||
// Not an error, then check if this is a negation
|
// Not an error, then check if this is a negation
|
||||||
strncmp(flag, "no-", strlen("no-")) ? WARNING_ENABLED
|
strncmp(flag, "no-", strlen("no-")) ? WARNING_ENABLED
|
||||||
: WARNING_DISABLED;
|
: WARNING_DISABLED;
|
||||||
char const *rootFlag = state == WARNING_DISABLED ? flag + strlen("no-") : flag;
|
char *rootFlag = state == WARNING_DISABLED ? flag + strlen("no-") : flag;
|
||||||
|
|
||||||
// Is this a "parametric" warning?
|
// Is this a "parametric" warning?
|
||||||
if (state != WARNING_DISABLED) { // The `no-` form cannot be parametrized
|
if (state != WARNING_DISABLED) { // The `no-` form cannot be parametrized
|
||||||
|
|||||||
@@ -325,7 +325,7 @@ do { \
|
|||||||
tryReadSlice("MA5");
|
tryReadSlice("MA5");
|
||||||
mbc = BANDAI_TAMA5;
|
mbc = BANDAI_TAMA5;
|
||||||
break;
|
break;
|
||||||
case 'P':
|
case 'P': {
|
||||||
tryReadSlice("P1");
|
tryReadSlice("P1");
|
||||||
// Parse version
|
// Parse version
|
||||||
while (*ptr == ' ' || *ptr == '_')
|
while (*ptr == ' ' || *ptr == '_')
|
||||||
@@ -359,6 +359,7 @@ do { \
|
|||||||
tpp1Rev[1] = val;
|
tpp1Rev[1] = val;
|
||||||
mbc = TPP1;
|
mbc = TPP1;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return MBC_BAD;
|
return MBC_BAD;
|
||||||
}
|
}
|
||||||
@@ -1376,7 +1377,7 @@ do { \
|
|||||||
sgb = true;
|
sgb = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 't':
|
case 't': {
|
||||||
title = musl_optarg;
|
title = musl_optarg;
|
||||||
len = strlen(title);
|
len = strlen(title);
|
||||||
uint8_t maxLen = maxTitleLen();
|
uint8_t maxLen = maxTitleLen();
|
||||||
@@ -1388,6 +1389,7 @@ do { \
|
|||||||
}
|
}
|
||||||
titleLen = len;
|
titleLen = len;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 'V':
|
case 'V':
|
||||||
printf("rgbfix %s\n", get_package_version_string());
|
printf("rgbfix %s\n", get_package_version_string());
|
||||||
|
|||||||
@@ -419,7 +419,7 @@ static void parseHEXFile(std::filebuf &file) {
|
|||||||
static void parseACTFile(std::filebuf &file) {
|
static void parseACTFile(std::filebuf &file) {
|
||||||
// https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577411_pgfId-1070626
|
// https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577411_pgfId-1070626
|
||||||
|
|
||||||
std::array<char, 772> buf;
|
std::array<char, 772> buf{};
|
||||||
auto len = file.sgetn(buf.data(), buf.size());
|
auto len = file.sgetn(buf.data(), buf.size());
|
||||||
|
|
||||||
uint16_t nbColors = 256;
|
uint16_t nbColors = 256;
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ static struct SymbolList {
|
|||||||
} *symbolLists;
|
} *symbolLists;
|
||||||
|
|
||||||
unsigned int nbObjFiles;
|
unsigned int nbObjFiles;
|
||||||
static struct {
|
static struct FileStackNodes {
|
||||||
struct FileStackNode *nodes;
|
struct FileStackNode *nodes;
|
||||||
uint32_t nbNodes;
|
uint32_t nbNodes;
|
||||||
} *nodes;
|
} *nodes;
|
||||||
@@ -92,19 +92,6 @@ static int64_t readlong(FILE *file)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper macro for reading bytes from a file, and errors out if it fails to.
|
* Helper macro for reading bytes from a file, and errors out if it fails to.
|
||||||
* Differs from `tryGetc` in that the backing function is fgetc(1).
|
|
||||||
* Not as a function to avoid overhead in the general case.
|
|
||||||
* @param var The variable to stash the number into
|
|
||||||
* @param file The file to read from. Its position will be advanced
|
|
||||||
* @param ... A format string and related arguments; note that an extra string
|
|
||||||
* argument is provided, the reason for failure
|
|
||||||
*/
|
|
||||||
#define tryFgetc(var, file, ...) \
|
|
||||||
tryRead(fgetc, int, EOF, var, file, __VA_ARGS__)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Helper macro for reading bytes from a file, and errors out if it fails to.
|
|
||||||
* Differs from `tryGetc` in that the backing function is fgetc(1).
|
|
||||||
* Not as a function to avoid overhead in the general case.
|
* Not as a function to avoid overhead in the general case.
|
||||||
* @param var The variable to stash the number into
|
* @param var The variable to stash the number into
|
||||||
* @param file The file to read from. Its position will be advanced
|
* @param file The file to read from. Its position will be advanced
|
||||||
|
|||||||
@@ -36,12 +36,14 @@ struct SortedSymbol {
|
|||||||
uint16_t addr;
|
uint16_t addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SortedSections {
|
||||||
|
struct SortedSection *sections;
|
||||||
|
struct SortedSection *zeroLenSections;
|
||||||
|
};
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
uint32_t nbBanks; // Size of the array below (which may be NULL if this is 0)
|
uint32_t nbBanks; // Size of the array below (which may be NULL if this is 0)
|
||||||
struct SortedSections {
|
struct SortedSections *banks;
|
||||||
struct SortedSection *sections;
|
|
||||||
struct SortedSection *zeroLenSections;
|
|
||||||
} *banks;
|
|
||||||
} sections[SECTTYPE_INVALID];
|
} sections[SECTTYPE_INVALID];
|
||||||
|
|
||||||
// Defines the order in which types are output to the sym and map files
|
// Defines the order in which types are output to the sym and map files
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ char *includeFileName;
|
|||||||
|
|
||||||
static uint32_t lineNo;
|
static uint32_t lineNo;
|
||||||
|
|
||||||
static struct {
|
static struct FileNode {
|
||||||
FILE *file;
|
FILE *file;
|
||||||
uint32_t lineNo;
|
uint32_t lineNo;
|
||||||
char *name;
|
char *name;
|
||||||
@@ -153,14 +153,16 @@ enum LinkerScriptCommand {
|
|||||||
COMMAND_INVALID
|
COMMAND_INVALID
|
||||||
};
|
};
|
||||||
|
|
||||||
|
union LinkerScriptTokenAttr {
|
||||||
|
enum LinkerScriptCommand command;
|
||||||
|
enum SectionType secttype;
|
||||||
|
uint32_t number;
|
||||||
|
char *string;
|
||||||
|
};
|
||||||
|
|
||||||
struct LinkerScriptToken {
|
struct LinkerScriptToken {
|
||||||
enum LinkerScriptTokenType type;
|
enum LinkerScriptTokenType type;
|
||||||
union LinkerScriptTokenAttr {
|
union LinkerScriptTokenAttr attr;
|
||||||
enum LinkerScriptCommand command;
|
|
||||||
enum SectionType secttype;
|
|
||||||
uint32_t number;
|
|
||||||
char *string;
|
|
||||||
} attr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static char const * const commands[] = {
|
static char const * const commands[] = {
|
||||||
|
|||||||
@@ -225,10 +225,11 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) {
|
|||||||
|
|
||||||
// Now, let's parse the rest of the lines as they come!
|
// Now, let's parse the rest of the lines as they come!
|
||||||
|
|
||||||
struct {
|
struct FileSection {
|
||||||
struct Section *section;
|
struct Section *section;
|
||||||
uint16_t writeIndex;
|
uint16_t writeIndex;
|
||||||
} *fileSections = NULL;
|
};
|
||||||
|
struct FileSection *fileSections = NULL;
|
||||||
struct Symbol **fileSymbols = malloc(sizeof(*fileSymbols) * expectedNbSymbols);
|
struct Symbol **fileSymbols = malloc(sizeof(*fileSymbols) * expectedNbSymbols);
|
||||||
size_t nbSections = 0, nbSymbols = 0;
|
size_t nbSections = 0, nbSymbols = 0;
|
||||||
|
|
||||||
@@ -240,19 +241,18 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) {
|
|||||||
|
|
||||||
if (!data)
|
if (!data)
|
||||||
fatal(where, lineNo, "Failed to alloc data buffer: %s", strerror(errno));
|
fatal(where, lineNo, "Failed to alloc data buffer: %s", strerror(errno));
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
lineType = nextLine(&line, &bufLen, &lineNo, where, file);
|
lineType = nextLine(&line, &bufLen, &lineNo, where, file);
|
||||||
if (lineType == EOF)
|
if (lineType == EOF)
|
||||||
break;
|
break;
|
||||||
switch (lineType) {
|
switch (lineType) {
|
||||||
uint32_t tmp;
|
|
||||||
|
|
||||||
case 'M': // Module name
|
case 'M': // Module name
|
||||||
case 'O': // Assembler flags
|
case 'O': // Assembler flags
|
||||||
// Ignored
|
// Ignored
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'A':
|
case 'A': {
|
||||||
if (nbSections == expectedNbAreas)
|
if (nbSections == expectedNbAreas)
|
||||||
warning(where, lineNo, "Got more 'A' lines than the expected %" PRIu32, expectedNbAreas);
|
warning(where, lineNo, "Got more 'A' lines than the expected %" PRIu32, expectedNbAreas);
|
||||||
fileSections = realloc(fileSections, sizeof(*fileSections) * (nbSections + 1));
|
fileSections = realloc(fileSections, sizeof(*fileSections) * (nbSections + 1));
|
||||||
@@ -276,7 +276,9 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) {
|
|||||||
expectToken("size", 'A');
|
expectToken("size", 'A');
|
||||||
|
|
||||||
getToken(NULL, "'A' line is too short");
|
getToken(NULL, "'A' line is too short");
|
||||||
tmp = parseNumber(where, lineNo, token, numberType);
|
|
||||||
|
uint32_t tmp = parseNumber(where, lineNo, token, numberType);
|
||||||
|
|
||||||
if (tmp > UINT16_MAX)
|
if (tmp > UINT16_MAX)
|
||||||
fatal(where, lineNo, "Area \"%s\" is larger than the GB address space!?", curSection->name);
|
fatal(where, lineNo, "Area \"%s\" is larger than the GB address space!?", curSection->name);
|
||||||
curSection->size = tmp;
|
curSection->size = tmp;
|
||||||
@@ -353,6 +355,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) {
|
|||||||
#undef curSection
|
#undef curSection
|
||||||
++nbSections;
|
++nbSections;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 'S':
|
case 'S':
|
||||||
if (nbSymbols == expectedNbSymbols)
|
if (nbSymbols == expectedNbSymbols)
|
||||||
@@ -465,7 +468,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) {
|
|||||||
// Importantly, now we know that `nbBytes != 0`, which means "pending data"
|
// Importantly, now we know that `nbBytes != 0`, which means "pending data"
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'R': // Supposed to directly follow `T`
|
case 'R': { // Supposed to directly follow `T`
|
||||||
if (nbBytes == 0) {
|
if (nbBytes == 0) {
|
||||||
warning(where, lineNo, "'R' line with no 'T' line, ignoring");
|
warning(where, lineNo, "'R' line with no 'T' line, ignoring");
|
||||||
break;
|
break;
|
||||||
@@ -727,6 +730,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) {
|
|||||||
|
|
||||||
nbBytes = 0; // Do not allow two R lines to refer to the same T line
|
nbBytes = 0; // Do not allow two R lines to refer to the same T line
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 'P':
|
case 'P':
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -15,21 +15,21 @@
|
|||||||
|
|
||||||
HashMap sections;
|
HashMap sections;
|
||||||
|
|
||||||
struct ForEachArg {
|
struct ForEachSectionArg {
|
||||||
void (*callback)(struct Section *section, void *arg);
|
void (*callback)(struct Section *section, void *arg);
|
||||||
void *arg;
|
void *arg;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void forEach(void *section, void *arg)
|
static void forEach(void *section, void *arg)
|
||||||
{
|
{
|
||||||
struct ForEachArg *callbackArg = (struct ForEachArg *)arg;
|
struct ForEachSectionArg *callbackArg = (struct ForEachSectionArg *)arg;
|
||||||
|
|
||||||
callbackArg->callback((struct Section *)section, callbackArg->arg);
|
callbackArg->callback((struct Section *)section, callbackArg->arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sect_ForEach(void (*callback)(struct Section *, void *), void *arg)
|
void sect_ForEach(void (*callback)(struct Section *, void *), void *arg)
|
||||||
{
|
{
|
||||||
struct ForEachArg callbackArg = { .callback = callback, .arg = arg};
|
struct ForEachSectionArg callbackArg = { .callback = callback, .arg = arg};
|
||||||
|
|
||||||
hash_ForEach(sections, forEach, &callbackArg);
|
hash_ForEach(sections, forEach, &callbackArg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,21 +13,21 @@
|
|||||||
|
|
||||||
HashMap symbols;
|
HashMap symbols;
|
||||||
|
|
||||||
struct ForEachArg {
|
struct ForEachSymbolArg {
|
||||||
void (*callback)(struct Symbol *symbol, void *arg);
|
void (*callback)(struct Symbol *symbol, void *arg);
|
||||||
void *arg;
|
void *arg;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void forEach(void *symbol, void *arg)
|
static void forEach(void *symbol, void *arg)
|
||||||
{
|
{
|
||||||
struct ForEachArg *callbackArg = (struct ForEachArg *)arg;
|
struct ForEachSymbolArg *callbackArg = (struct ForEachSymbolArg *)arg;
|
||||||
|
|
||||||
callbackArg->callback((struct Symbol *)symbol, callbackArg->arg);
|
callbackArg->callback((struct Symbol *)symbol, callbackArg->arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sym_ForEach(void (*callback)(struct Symbol *, void *), void *arg)
|
void sym_ForEach(void (*callback)(struct Symbol *, void *), void *arg)
|
||||||
{
|
{
|
||||||
struct ForEachArg callbackArg = { .callback = callback, .arg = arg};
|
struct ForEachSymbolArg callbackArg = { .callback = callback, .arg = arg};
|
||||||
|
|
||||||
hash_ForEach(symbols, forEach, &callbackArg);
|
hash_ForEach(symbols, forEach, &callbackArg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ struct Attributes {
|
|||||||
static unsigned long long randbits = 0;
|
static unsigned long long randbits = 0;
|
||||||
static unsigned char randcount = 0;
|
static unsigned char randcount = 0;
|
||||||
|
|
||||||
static _Noreturn void fatal(char const *error) {
|
_Noreturn static void fatal(char const *error) {
|
||||||
fprintf(stderr, "FATAL: %s\n", error);
|
fprintf(stderr, "FATAL: %s\n", error);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user