aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Michael Smith <mikesmiffy128@gmail.com> 2025-04-08 01:32:41 +0100
committerGravatar Michael Smith <mikesmiffy128@gmail.com> 2025-04-08 01:35:13 +0100
commit6c8cd62277a9c81d1d24c146067c405ec90cbfb2 (patch)
treee2560cc8b3174b4481770464b886f7af3a2234a7
parent25838ab4eb1fc94f59186cb24b75f440f9062f9a (diff)
downloadsst-6c8cd62277a9c81d1d24c146067c405ec90cbfb2.tar.gz
sst-6c8cd62277a9c81d1d24c146067c405ec90cbfb2.zip
Put some error paths in the fridge
-rw-r--r--src/build/cmeta.c16
-rw-r--r--src/build/gluegen.c102
-rw-r--r--src/build/mkentprops.c59
-rw-r--r--src/build/mkgamedata.c42
4 files changed, 115 insertions, 104 deletions
diff --git a/src/build/cmeta.c b/src/build/cmeta.c
index 78b3887..434be76 100644
--- a/src/build/cmeta.c
+++ b/src/build/cmeta.c
@@ -67,21 +67,21 @@ Type *array_of(Type *base, int len) {
#include "../3p/openbsd/asprintf.c" // missing from libc; plonked here for now
#endif
-static noreturn die(int status, const char *s) {
+static cold noreturn die(int status, const char *s) {
fprintf(stderr, "cmeta: fatal: %s\n", s);
exit(status);
}
struct cmeta cmeta_loadfile(const os_char *path) {
int f = os_open_read(path);
- if (f == -1) die(100, "couldn't open file");
+ if_cold (f == -1) die(100, "couldn't open file");
vlong len = os_fsize(f);
- if (len > 1u << 30 - 1) die(2, "input file is far too large");
+ if_cold (len > 1u << 30 - 1) die(2, "input file is far too large");
struct cmeta ret;
ret.sbase = malloc(len + 1);
ret.sbase[len] = '\0'; // chibicc needs a null terminator
- if (!ret.sbase) die(100, "couldn't allocate memory");
- if (os_read(f, ret.sbase, len) != len) die(100, "couldn't read file");
+ if_cold (!ret.sbase) die(100, "couldn't allocate memory");
+ if_cold (os_read(f, ret.sbase, len) != len) die(100, "couldn't read file");
int maxitems = len / 4; // shortest word is "END"
ret.nitems = 0;
// eventual overall memory requirement: file size * 6. seems fine to me.
@@ -90,13 +90,13 @@ struct cmeta cmeta_loadfile(const os_char *path) {
//ret.itemoffs = malloc(maxitems * sizeof(*ret.itemoffs));
//if (!ret.itemoffs) die(100, "couldn't allocate memory");
ret.itemtoks = malloc(maxitems * sizeof(*ret.itemtoks));
- if (!ret.itemtoks) die(100, "couldn't allocate memory");
+ if_cold (!ret.itemtoks) die(100, "couldn't allocate memory");
ret.itemtypes = malloc(maxitems * sizeof(*ret.itemtypes));
- if (!ret.itemtypes) die(100, "couldn't allocate memory");
+ if_cold (!ret.itemtypes) die(100, "couldn't allocate memory");
os_close(f);
#ifdef _WIN32
char *realname = malloc(wcslen(path) + 1);
- if (!realname) die(100, "couldn't allocate memory");
+ if_cold (!realname) die(100, "couldn't allocate memory");
// XXX: being lazy about Unicode right now; a general purpose tool should
// implement WTF8 or something. SST itself doesn't have any unicode paths
// though, so we don't really care as much. this code still sucks though.
diff --git a/src/build/gluegen.c b/src/build/gluegen.c
index 70054f1..4abfd2b 100644
--- a/src/build/gluegen.c
+++ b/src/build/gluegen.c
@@ -29,19 +29,15 @@
#define fS "s"
#endif
-static inline noreturn die(int status, const char *s) {
+static cold noreturn die(int status, const char *s) {
fprintf(stderr, "gluegen: fatal: %s\n", s);
exit(status);
}
-static inline noreturn diefile(int status, const os_char *f, int line,
+static cold noreturn diefile(int status, const os_char *f, int line,
const char *s) {
- if (line) {
- fprintf(stderr, "gluegen: fatal: %" fS ":%d: %s\n", f, line, s);
- }
- else {
- fprintf(stderr, "gluegen: fatal: %" fS ": %s\n", f, s);
- }
+ if (line) fprintf(stderr, "gluegen: fatal: %" fS ":%d: %s\n", f, line, s);
+ else fprintf(stderr, "gluegen: fatal: %" fS ": %s\n", f, s);
exit(status);
}
@@ -330,7 +326,7 @@ static inline void handle(s16 mod, s16 mods, s16 *featdescs, s16 *events,
for (u32 i = 0; i != cm->nitems; ++i) {
switch_exhaust_enum(cmeta_item, cm->itemtypes[i]) {
case CMETA_ITEM_DEF_CVAR:
- if (!cmeta_nparams(cm, i)) {
+ if_cold (!cmeta_nparams(cm, i)) {
diefile(2, file, cmeta_line(cm, i),
"cvar macro missing required parameter");
}
@@ -349,7 +345,7 @@ static inline void handle(s16 mod, s16 mods, s16 *featdescs, s16 *events,
}
break;
case CMETA_ITEM_DEF_CCMD:
- if (!cmeta_nparams(cm, i)) {
+ if_cold (!cmeta_nparams(cm, i)) {
diefile(2, file, cmeta_line(cm, i),
"ccmd macro missing required parameter");
}
@@ -392,7 +388,7 @@ static inline void handle(s16 mod, s16 mods, s16 *featdescs, s16 *events,
}
break;
case CMETA_ITEM_DEF_EVENT:
- if (!cmeta_nparams(cm, i)) {
+ if_cold (!cmeta_nparams(cm, i)) {
diefile(2, file, cmeta_line(cm, i),
"event macro missing required parameter");
}
@@ -410,7 +406,7 @@ static inline void handle(s16 mod, s16 mods, s16 *featdescs, s16 *events,
}
else {
e = r.stridx;
- if (event_owners[e]) {
+ if_cold (event_owners[e]) {
diefile(2, file, cmeta_line(cm, i),
"conflicting event definition");
}
@@ -425,7 +421,7 @@ static inline void handle(s16 mod, s16 mods, s16 *featdescs, s16 *events,
break;
case CMETA_ITEM_HANDLE_EVENT:
int nparams = cmeta_nparams(cm, i);
- if (!nparams) {
+ if_cold (!nparams) {
diefile(2, file, cmeta_line(cm, i),
"event handler macro missing required parameter");
}
@@ -450,7 +446,8 @@ static inline void handle(s16 mod, s16 mods, s16 *featdescs, s16 *events,
// note: if no param given, featdesc will still be null
cmeta_param_foreach (param, cm, i) {
mod_featdescs[mod] = param;
- if (!radix_insertidx(featdescs, mod_featdescs, mod, true)) {
+ if_cold (!radix_insertidx(featdescs, mod_featdescs, mod,
+ true)) {
diefile(2, file, cmeta_line(cm, i),
"duplicate feature description text");
}
@@ -458,7 +455,7 @@ static inline void handle(s16 mod, s16 mods, s16 *featdescs, s16 *events,
}
break;
case CMETA_ITEM_REQUIRE:
- if (!cmeta_nparams(cm, i)) {
+ if_cold (!cmeta_nparams(cm, i)) {
diefile(2, file, cmeta_line(cm, i),
"dependency macro missing required parameter");
}
@@ -479,7 +476,7 @@ static inline void handle(s16 mod, s16 mods, s16 *featdescs, s16 *events,
canpreinit = false;
s16 depmod = radix_lookup(mods, mod_names, param.s,
param.len, false);
- if (!depmod) {
+ if_cold (!depmod) {
fprintf(stderr, "cmeta_fatal: %" fS ":%d: "
"feature `%.*s` does not exist\n",
file, cmeta_line(cm, i),
@@ -511,7 +508,7 @@ static inline void handle(s16 mod, s16 mods, s16 *featdescs, s16 *events,
}
break;
case CMETA_ITEM_INIT:
- if (hasinit) {
+ if_cold (hasinit) {
diefile(2, file, cmeta_line(cm, i), "multiple INIT blocks");
}
hasinit = true;
@@ -519,7 +516,7 @@ static inline void handle(s16 mod, s16 mods, s16 *featdescs, s16 *events,
needfeat = "INIT block defined";
break;
case CMETA_ITEM_PREINIT:
- if (haspreinit) {
+ if_cold (haspreinit) {
diefile(2, file, cmeta_line(cm, i),
"multiple PREINIT blocks");
}
@@ -528,29 +525,29 @@ static inline void handle(s16 mod, s16 mods, s16 *featdescs, s16 *events,
needfeat = "PREINIT block defined";
break;
case CMETA_ITEM_END:
- if (mod_flags[mod] & HAS_END) {
+ if_cold (mod_flags[mod] & HAS_END) {
diefile(2, file, cmeta_line(cm, i), "multiple END blocks");
}
mod_flags[mod] |= HAS_END;
needfeat = "END block defined";
}
}
- if (needfeat && !isfeat) {
+ if_cold (needfeat && !isfeat) {
fprintf(stderr, "gluegen: fatal: %" fS ": %s without FEATURE()", file,
needfeat);
exit(2);
}
- if (isfeat && !hasinit) {
+ if_cold (isfeat && !hasinit) {
diefile(2, file, 0, "feature is missing INIT block");
}
- if (!canpreinit && haspreinit) {
+ if_cold (!canpreinit && haspreinit) {
diefile(2, file, 0, "cannot use dependencies along with PREINIT");
}
}
static int dfs(s16 mod, bool first);
static int dfs_inner(s16 mod, s16 dep, bool first) {
- if (!(mod_flags[dep] & HAS_INIT)) {
+ if_cold (!(mod_flags[dep] & HAS_INIT)) {
fprintf(stderr, "gluegen: fatal: feature `%.*s` tried to depend on "
"non-feature module `%.*s`\n",
mod_names[mod].len, mod_names[mod].s,
@@ -563,8 +560,7 @@ static int dfs_inner(s16 mod, s16 dep, bool first) {
// *so* horrendously and I'm not in the mood to replace stdio for this
// (maybe another time!)
case 1:
- fprintf(stderr, ".-> %.*s\n",
- mod_names[mod].len, mod_names[mod].s);
+ fprintf(stderr, ".-> %.*s\n", mod_names[mod].len, mod_names[mod].s);
return 2;
case 2:
fprintf(stderr, first ? "'-- %.*s\n" : "| %.*s\n",
@@ -575,7 +571,7 @@ static int dfs_inner(s16 mod, s16 dep, bool first) {
}
static int dfs(s16 mod, bool first) {
if (mod_flags[mod] & DFS_SEEN) return 0;
- if (mod_flags[mod] & DFS_SEEING) {
+ if_cold (mod_flags[mod] & DFS_SEEING) {
fprintf(stderr, "gluegen: fatal: feature dependency cycle:\n");
return 1;
}
@@ -593,15 +589,15 @@ static int dfs(s16 mod, bool first) {
static inline void sortfeatures() {
for (int i = 1; i < nmods; ++i) {
- if ((mod_flags[i] & HAS_INIT) && dfs(i, true)) exit(2);
+ if_cold ((mod_flags[i] & HAS_INIT) && dfs(i, true)) exit(2);
}
}
-static inline noreturn diewrite() { die(100, "couldn't write to file"); }
+static cold noreturn diewrite() { die(100, "couldn't write to file"); }
#define _(x) \
- if (fprintf(out, "%s\n", x) < 0) diewrite();
+ if_cold (fprintf(out, "%s\n", x) < 0) diewrite();
#define F(f, ...) \
- if (fprintf(out, f "\n", __VA_ARGS__) < 0) diewrite();
+ if_cold (fprintf(out, f "\n", __VA_ARGS__) < 0) diewrite();
#define H_() \
_("/* This file is autogenerated by src/build/gluegen.c. DO NOT EDIT! */")
#define H() H_() _("")
@@ -628,7 +624,7 @@ _( " }")
static int evargs(FILE *out, s16 i, const char *suffix) {
int j = 1;
- if (fprintf(out, "(") < 0) diewrite();
+ if_cold (fprintf(out, "(") < 0) diewrite();
list_foreach (struct cmeta_slice, param, event_params + i) {
if (param.len == 4 && !memcmp(param.s, "void", 4)) {
// UGH, crappy special case for (void). with C23 this could be
@@ -644,23 +640,23 @@ static int evargs(FILE *out, s16 i, const char *suffix) {
}
++j;
}
- if (fputs(suffix, out) < 0) diewrite();
+ if_cold (fputs(suffix, out) < 0) diewrite();
return j;
}
static int evargs_notype(FILE *out, s16 i, const char *suffix) {
int j = 1;
- if (fprintf(out, "(") < 0) diewrite();
+ if_cold (fprintf(out, "(") < 0) diewrite();
list_foreach(struct cmeta_slice, param, event_params + i) {
if (param.len == 4 && !memcmp(param.s, "void", 4)) {
break;
}
- if (fprintf(out, "%sa%d", j == 1 ? "" : ", ", j) < 0) {
+ if_cold (fprintf(out, "%sa%d", j == 1 ? "" : ", ", j) < 0) {
diewrite();
}
++j;
}
- if (fputs(suffix, out) < 0) diewrite();
+ if_cold (fputs(suffix, out) < 0) diewrite();
return j;
}
@@ -844,14 +840,14 @@ _( "}")
for (int i = 1; i < nevents; ++i) {
const char *prefix = event_predicateflags[i] ?
"bool CHECK_" : "void EMIT_";
- if (fprintf(out, "\n%s%.*s", prefix,
+ if_cold (fprintf(out, "\n%s%.*s", prefix,
event_names[i].len, event_names[i].s) < 0) {
diewrite();
}
evargs(out, i, ") {\n");
list_foreach(s16, mod, event_handlers + i) {
const char *type = event_predicateflags[i] ? "bool" : "void";
- if (fprintf(out, "\t%s _evhandler_%.*s_%.*s", type,
+ if_cold (fprintf(out, "\t%s _evhandler_%.*s_%.*s", type,
mod_names[mod].len, mod_names[mod].s,
event_names[i].len, event_names[i].s) < 0) {
diewrite();
@@ -859,15 +855,15 @@ _( "}")
evargs(out, i, ");\n");
if (event_predicateflags[i]) {
if (mod_flags[mod] & HAS_INIT) {
- if (fprintf(out, "\tif (has_%.*s && !",
+ if_cold (fprintf(out, "\tif (has_%.*s && !",
mod_names[mod].len, mod_names[mod].s) < 0) {
diewrite();
}
}
- else if (fputs("\tif (!", out) < 0) {
+ else if_cold (fputs("\tif (!", out) < 0) {
diewrite();
}
- if (fprintf(out, "_evhandler_%.*s_%.*s",
+ if_cold (fprintf(out, "_evhandler_%.*s_%.*s",
mod_names[mod].len, mod_names[mod].s,
event_names[i].len, event_names[i].s) < 0) {
diewrite();
@@ -875,14 +871,16 @@ _( "}")
evargs_notype(out, i, ")) return false;\n");
}
else {
- if (fputc('\t', out) < 0) diewrite();
- if ((mod_flags[mod] & HAS_INIT) && fprintf(out, "if (has_%.*s) ",
- mod_names[mod].len, mod_names[mod].s) < 0) {
- diewrite();
+ if_cold (fputc('\t', out) < 0) diewrite();
+ if ((mod_flags[mod] & HAS_INIT)) {
+ if_cold (fprintf(out, "if (has_%.*s) ",
+ mod_names[mod].len, mod_names[mod].s) < 0) {
+ diewrite();
+ }
}
- if (fprintf(out, "_evhandler_%.*s_%.*s",
- mod_names[mod].len, mod_names[mod].s,
- event_names[i].len, event_names[i].s) < 0) {
+ if_cold (fprintf(out, "_evhandler_%.*s_%.*s",
+ mod_names[mod].len, mod_names[mod].s,
+ event_names[i].len, event_names[i].s) < 0) {
diewrite();
}
evargs_notype(out, i, ");\n");
@@ -897,7 +895,7 @@ _( "}")
int OS_MAIN(int argc, os_char *argv[]) {
s16 modlookup = 0, featdesclookup = 0, eventlookup = 0;
- if (argc > MAX_MODULES) {
+ if_cold (argc > MAX_MODULES) {
die(2, "too many files passed - increase MAX_MODULES in gluegen.c!");
}
nmods = argc;
@@ -931,7 +929,7 @@ int OS_MAIN(int argc, os_char *argv[]) {
modname.s = p; modname.len = len - lastpart - 2;
}
mod_names[i] = modname;
- if (!radix_insertidx(&modlookup, mod_names, i, false)) {
+ if_cold (!radix_insertidx(&modlookup, mod_names, i, false)) {
// XXX: might have to fix this some day to handle subdirs and such.
// for now we rely on it happening not to be a problem basically lol
diefile(2, f, 0, "duplicate module name");
@@ -944,7 +942,7 @@ int OS_MAIN(int argc, os_char *argv[]) {
// double check that events are defined. the compiler would also catch this,
// but we can do it faster and with arguably more helpful error information.
for (int i = 1; i < nevents; ++i) {
- if (!event_owners[i]) {
+ if_cold (!event_owners[i]) {
fprintf(stderr, "gluegen: fatal: undefined event %.*s\n",
event_names[i].len, event_names[i].s);
exit(2);
@@ -953,10 +951,10 @@ int OS_MAIN(int argc, os_char *argv[]) {
sortfeatures();
FILE *out = fopen(".build/include/glue.gen.h", "wb");
- if (!out) die(100, "couldn't open .build/include/glue.gen.h");
+ if_cold (!out) die(100, "couldn't open .build/include/glue.gen.h");
H()
gencode(out, featdesclookup);
- if (fflush(out)) die(100, "couldn't finish writing output");
+ if_cold (fflush(out)) die(100, "couldn't finish writing output");
return 0;
}
diff --git a/src/build/mkentprops.c b/src/build/mkentprops.c
index 287bdaa..bd4b082 100644
--- a/src/build/mkentprops.c
+++ b/src/build/mkentprops.c
@@ -29,11 +29,11 @@
#define fS "s"
#endif
-static noreturn die(int status, const char *s) {
+static cold noreturn die(int status, const char *s) {
fprintf(stderr, "mkentprops: fatal: %s\n", s);
exit(status);
}
-static noreturn dieparse(const os_char *file, int line, const char *s) {
+static cold noreturn dieparse(const os_char *file, int line, const char *s) {
fprintf(stderr, "mkentprops: %" fS ":%d: %s\n", file, line, s);
exit(2);
}
@@ -57,7 +57,7 @@ static int art_nnodes = 0;
#define ART_NULL ((u16)-1)
static inline int art_newnode() {
- if (art_nnodes == ART_MAXNODES) die(2, "out of tree nodes");
+ if_cold (art_nnodes == ART_MAXNODES) die(2, "out of tree nodes");
return art_nnodes++;
}
@@ -79,7 +79,7 @@ static int decls[MAXDECLS];
static int ndecls = 0;
static inline int art_newleaf() {
- if (art_nleaves == ART_MAXLEAVES) die(2, "out of leaf nodes");
+ if_cold (art_nleaves == ART_MAXLEAVES) die(2, "out of leaf nodes");
return art_nleaves++;
}
@@ -152,7 +152,7 @@ static struct art_leaf *helpgetleaf(u16 *art, const char *s, int len,
++*countvar;
}
// if parsefile is null then we don't care about dupes (looking at subtable)
- else if (parsefile && art_leaves[leaf.leafidx].varstr != VAR_NONE) {
+ else if (parsefile) if_cold (art_leaves[leaf.leafidx].varstr != VAR_NONE) {
dieparse(parsefile, parseline, "duplicate property name");
}
return art_leaves + leaf.leafidx;
@@ -160,26 +160,26 @@ static struct art_leaf *helpgetleaf(u16 *art, const char *s, int len,
static inline void handleentry(char *k, char *v, int vlen,
const os_char *file, int line) {
- if (ndecls == MAXDECLS) die(2, "out of declaration entries");
+ if_cold (ndecls == MAXDECLS) die(2, "out of declaration entries");
decls[ndecls++] = k - sbase;
char *propname = memchr(v, '/', vlen);
- if (!propname) {
+ if_cold (!propname) {
dieparse(file, line, "network name not in class/property format");
}
*propname++ = '\0';
int sublen = propname - v;
- if (sublen > 65535) {
+ if_cold (sublen > 65535) {
dieparse(file, line, "network class name is far too long");
}
vlen -= sublen;
struct art_leaf *leaf = helpgetleaf(&art_root, v, sublen, 0, 0, &nclasses);
u16 *subtree = &leaf->subtree;
for (;;) {
- if (vlen > 65535) {
+ if_cold (vlen > 65535) {
dieparse(file, line, "property (SendTable) name is far too long");
}
char *nextpart = memchr(propname, '/', vlen);
- if (!nextpart) {
+ if_cold (!nextpart) {
leaf = helpgetleaf(subtree, propname, vlen, file, line,
&leaf->nsubs);
leaf->varstr = k - sbase;
@@ -196,7 +196,9 @@ static inline void handleentry(char *k, char *v, int vlen,
static inline void parse(const os_char *file, int len) {
char *s = sbase; // for convenience
- if (s[len - 1] != '\n') dieparse(file, 0, "invalid text file (missing EOL)");
+ if_cold (s[len - 1] != '\n') {
+ dieparse(file, 0, "invalid text file (missing EOL)");
+ }
enum { BOL = 0, KEY = 4, KWS = 8, VAL = 12, COM = 16, ERR = -1 };
static const s8 statetrans[] = {
// layout: any, space|tab, #, \n
@@ -217,8 +219,12 @@ static inline void parse(const os_char *file, int len) {
}
int newstate = statetrans[transidx];
if_cold (newstate == ERR) {
- if (state == BOL) dieparse(file, line, "unexpected indentation");
- if (s[i] == '\n') dieparse(file, line, "unexpected end of line");
+ if_cold (state == BOL) {
+ dieparse(file, line, "unexpected indentation");
+ }
+ if_cold (s[i] == '\n') {
+ dieparse(file, line, "unexpected end of line");
+ }
dieparse(file, line, "unexpected comment");
}
switch_exhaust (newstate) {
@@ -239,11 +245,14 @@ static inline void parse(const os_char *file, int len) {
}
}
-static inline noreturn diewrite() { die(100, "couldn't write to file"); }
-#define _(x) if (fprintf(out, "%s\n", x) < 0) diewrite();
-#define _i(x) for (int i = 0; i < indent; ++i) fputc('\t', out); _(x)
-#define F(f, ...) if (fprintf(out, f "\n", __VA_ARGS__) < 0) diewrite();
-#define Fi(...) for (int i = 0; i < indent; ++i) fputc('\t', out); F(__VA_ARGS__)
+static cold noreturn diewrite() { die(100, "couldn't write to file"); }
+#define _(x) if_cold (fprintf(out, "%s\n", x) < 0) diewrite();
+#define _doindent() \
+ for (int i = 0; i < indent; ++i) \
+ if_cold (fputc('\t', out) == EOF) diewrite();
+#define _i(x) _doindent(); _(x)
+#define F(f, ...) if_cold (fprintf(out, f "\n", __VA_ARGS__) < 0) diewrite();
+#define Fi(...) _doindent(); F(__VA_ARGS__)
#define H() \
_( "/* This file is autogenerated by src/build/mkentprops.c. DO NOT EDIT! */") \
_( "")
@@ -360,24 +369,24 @@ _( "}")
}
int OS_MAIN(int argc, os_char *argv[]) {
- if (argc != 2) die(1, "wrong number of arguments");
+ if_cold (argc != 2) die(1, "wrong number of arguments");
int f = os_open_read(argv[1]);
- if (f == -1) die(100, "couldn't open file");
+ if_cold (f == -1) die(100, "couldn't open file");
vlong len = os_fsize(f);
- if (len > 1u << 30 - 1) die(2, "input file is far too large");
+ if_cold (len > 1u << 30 - 1) die(2, "input file is far too large");
sbase = malloc(len);
- if (!sbase) die(100, "couldn't allocate memory");
- if (os_read(f, sbase, len) != len) die(100, "couldn't read file");
+ if_cold (!sbase) die(100, "couldn't allocate memory");
+ if_cold (os_read(f, sbase, len) != len) die(100, "couldn't read file");
os_close(f);
parse(argv[1], len);
FILE *out = fopen(".build/include/entprops.gen.h", "wb");
- if (!out) die(100, "couldn't open entprops.gen.h");
+ if_cold (!out) die(100, "couldn't open entprops.gen.h");
H();
dodecls(out);
out = fopen(".build/include/entpropsinit.gen.h", "wb");
- if (!out) die(100, "couldn't open entpropsinit.gen.h");
+ if_cold (!out) die(100, "couldn't open entpropsinit.gen.h");
H();
doinit(out);
return 0;
diff --git a/src/build/mkgamedata.c b/src/build/mkgamedata.c
index b05f1e5..325cda2 100644
--- a/src/build/mkgamedata.c
+++ b/src/build/mkgamedata.c
@@ -16,7 +16,6 @@
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
#include "../intdefs.h"
#include "../langext.h"
@@ -28,7 +27,7 @@
#define fS "s"
#endif
-static noreturn die(int status, const char *s) {
+static cold noreturn die(int status, const char *s) {
fprintf(stderr, "mkentprops: fatal: %s\n", s);
exit(status);
}
@@ -37,7 +36,7 @@ static noreturn die(int status, const char *s) {
static char *sbase = 0;
static const os_char *const *srcnames;
-static noreturn dieparse(int file, int line, const char *s) {
+static cold noreturn dieparse(int file, int line, const char *s) {
fprintf(stderr, "mkentprops: %" fS ":%d: %s\n", srcnames[file], line, s);
exit(2);
}
@@ -92,7 +91,9 @@ static inline void handleentry(char *k, char *v, int indent,
*/
static void parse(int file, char *s, int len) {
- if (s[len - 1] != '\n') dieparse(file, 0, "invalid text file (missing EOL)");
+ if_cold (s[len - 1] != '\n') {
+ dieparse(file, 0, "invalid text file (missing EOL)");
+ }
enum { BOL = 0, KEY = 4, KWS = 8, VAL = 12, COM = 16, ERR = -1 };
static const s8 statetrans[] = {
// layout: any, space|tab, #, \n
@@ -147,11 +148,14 @@ static void parse(int file, char *s, int len) {
}
}
-static inline noreturn diewrite() { die(100, "couldn't write to file"); }
-#define _(x) if (fprintf(out, "%s\n", x) < 0) diewrite();
-#define _i(x) for (int i = 0; i < indent; ++i) fputc('\t', out); _(x)
-#define F(f, ...) if (fprintf(out, f "\n", __VA_ARGS__) < 0) diewrite();
-#define Fi(...) for (int i = 0; i < indent; ++i) fputc('\t', out); F(__VA_ARGS__)
+static cold noreturn diewrite() { die(100, "couldn't write to file"); }
+#define _(x) if_cold (fprintf(out, "%s\n", x) < 0) diewrite();
+#define _doindent() \
+ for (int i = 0; i < indent; ++i) \
+ if_cold (fputc('\t', out) == EOF) diewrite();
+#define _i(x) _doindent(); _(x)
+#define F(f, ...) if_cold (fprintf(out, f "\n", __VA_ARGS__) < 0) diewrite();
+#define Fi(...) _doindent(); F(__VA_ARGS__)
#define H() \
_( "/* This file is autogenerated by src/build/mkgamedata.c. DO NOT EDIT! */") \
_( "")
@@ -168,7 +172,7 @@ static inline void knowngames(FILE *out) {
for (++i; indents[i] != 0; ++i) if (i == nents - 1) return;
}
F( "#line %d \"%" fS "\"", srclines[i], srcnames[srcfiles[i]])
- if (fprintf(out, "#define _GAMES_WITH_%s (", sbase + tags[i]) < 0) {
+ if_cold (fprintf(out, "#define _GAMES_WITH_%s (", sbase + tags[i]) < 0) {
diewrite();
}
const char *pipe = "";
@@ -176,7 +180,7 @@ F( "#line %d \"%" fS "\"", srclines[i], srcnames[srcfiles[i]])
// don't attempt to optimise for nested conditionals because that's
// way more complicated and also basically defeats the purpose.
if (indents[j] != 1) continue;
- if (fprintf(out, "%s \\\n\t _gametype_tag_%s", pipe,
+ if_cold (fprintf(out, "%s \\\n\t _gametype_tag_%s", pipe,
sbase + tags[j]) < 0) {
diewrite();
}
@@ -265,37 +269,37 @@ int OS_MAIN(int argc, os_char *argv[]) {
srcnames = (const os_char *const *)argv;
int sbase_len = 0, sbase_max = 65536;
sbase = malloc(sbase_max);
- if (!sbase) die(100, "couldn't allocate memory");
+ if_cold (!sbase) die(100, "couldn't allocate memory");
int n = 1;
for (++argv; *argv; ++argv, ++n) {
int f = os_open_read(*argv);
- if (f == -1) die(100, "couldn't open file");
+ if_cold (f == -1) die(100, "couldn't open file");
vlong len = os_fsize(f);
- if (sbase_len + len > 1u << 29) {
+ if_cold (sbase_len + len > 1u << 29) {
die(2, "combined input files are far too large");
}
- if (sbase_len + len > sbase_max) {
+ if_cold (sbase_len + len > sbase_max) {
fprintf(stderr, "mkgamedata: warning: need to resize string. "
"increase sbase_max to avoid this extra work!\n");
sbase_max *= 4;
sbase = realloc(sbase, sbase_max);
- if (!sbase) die(100, "couldn't grow memory allocation");
+ if_cold (!sbase) die(100, "couldn't grow memory allocation");
}
char *s = sbase + sbase_len;
- if (os_read(f, s, len) != len) die(100, "couldn't read file");
+ if_cold (os_read(f, s, len) != len) die(100, "couldn't read file");
os_close(f);
parse(n, s, len);
sbase_len += len;
}
FILE *out = fopen(".build/include/gamedata.gen.h", "wb");
- if (!out) die(100, "couldn't open gamedata.gen.h");
+ if_cold (!out) die(100, "couldn't open gamedata.gen.h");
H();
knowngames(out);
decls(out);
out = fopen(".build/include/gamedatainit.gen.h", "wb");
- if (!out) die(100, "couldn't open gamedatainit.gen.h");
+ if_cold (!out) die(100, "couldn't open gamedatainit.gen.h");
H();
defs(out);
_("")