diff options
author | 2025-04-08 01:32:41 +0100 | |
---|---|---|
committer | 2025-04-08 01:35:13 +0100 | |
commit | 6c8cd62277a9c81d1d24c146067c405ec90cbfb2 (patch) | |
tree | e2560cc8b3174b4481770464b886f7af3a2234a7 | |
parent | 25838ab4eb1fc94f59186cb24b75f440f9062f9a (diff) | |
download | sst-6c8cd62277a9c81d1d24c146067c405ec90cbfb2.tar.gz sst-6c8cd62277a9c81d1d24c146067c405ec90cbfb2.zip |
Put some error paths in the fridge
-rw-r--r-- | src/build/cmeta.c | 16 | ||||
-rw-r--r-- | src/build/gluegen.c | 102 | ||||
-rw-r--r-- | src/build/mkentprops.c | 59 | ||||
-rw-r--r-- | src/build/mkgamedata.c | 42 |
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); _("") |