From df5eaa6ef2713a9f86e670329fcd22eceeec27bc Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 16 Aug 2015 19:55:11 +0200 Subject: [PATCH 1/9] eliminate warning (unused variable) --- s/travis-build | 1 + src/kernel/ship.test.c | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/s/travis-build b/s/travis-build index 14aff5358..a6c920340 100755 --- a/s/travis-build +++ b/s/travis-build @@ -10,6 +10,7 @@ $BUILD/iniparser/inifile eressea.ini add lua:paths lunit:scripts fi } +set -e [ -z $BUILD ] && BUILD=Debug ; export BUILD s/cmake-init s/build diff --git a/src/kernel/ship.test.c b/src/kernel/ship.test.c index 380274a45..dc125cd9b 100644 --- a/src/kernel/ship.test.c +++ b/src/kernel/ship.test.c @@ -521,12 +521,10 @@ static void test_shipspeed_damage(CuTest *tc) { static void test_shipspeed(CuTest *tc) { ship *sh; const ship_type *stype; - region *r; unit *cap, *crew; test_cleanup(); sh = setup_ship(); - r = sh->region; stype = sh->type; CuAssertIntEquals_Msg(tc, "ship without a captain cannot move", 0, shipspeed(sh, NULL)); From dcececf4fa5b6ee56ea18d3f84cde70a78df65cc Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 17 Aug 2015 16:17:08 +0200 Subject: [PATCH 2/9] Debug: move errno testing closer to the report-writing, so we know which report caused the error. Fix: wrptr gets the result from _snprintf, which is int, not size_t. --- src/reports.c | 51 +++++++++++++++++++++++++------------------- src/util/bsdstring.c | 12 ++++++++++- src/util/bsdstring.h | 3 ++- 3 files changed, 42 insertions(+), 24 deletions(-) diff --git a/src/reports.c b/src/reports.c index 639b859bf..d632e06a0 100644 --- a/src/reports.c +++ b/src/reports.c @@ -1783,6 +1783,7 @@ int write_reports(faction * f, time_t ltime) bool gotit = false; struct report_context ctx; const char *encoding = "UTF-8"; + report_type *rtype; if (noreports) { return false; @@ -1798,36 +1799,42 @@ int write_reports(faction * f, time_t ltime) get_seen_interval(&ctx); } get_addresses(&ctx); - _mkdir(reportpath()); - do { - report_type *rtype = report_types; - + if (_access(reportpath(), 0) < 0) { + _mkdir(reportpath()); + } + if (errno) { + log_warning("errno was %d before writing reports", errno); errno = 0; - if (verbosity >= 2) { - log_printf(stdout, "Reports for %s:", factionname(f)); - } - for (; rtype != NULL; rtype = rtype->next) { - if (f->options & rtype->flag) { + } + if (verbosity >= 2) { + log_printf(stdout, "Reports for %s:", factionname(f)); + } + for (rtype = report_types; rtype != NULL; rtype = rtype->next) { + if (f->options & rtype->flag) { + int error; + do { char filename[MAX_PATH]; sprintf(filename, "%s/%d-%s.%s", reportpath(), turn, factionid(f), rtype->extension); + error = 0; if (rtype->write(filename, &ctx, encoding) == 0) { gotit = true; } - } + if (errno) { + char zText[64]; + log_warning("retrying, error %d during %s report for faction %s", error, rtype->extension, factionname(f)); + sprintf(zText, "waiting %u seconds before we retry", backup / 1000); + perror(zText); + _sleep(backup); + if (backup < maxbackup) { + backup *= 2; + } + error = errno; + errno = 0; + } + } while (error); } - - if (errno) { - char zText[64]; - log_warning("retrying, error %d during reports for faction %s", errno, factionname(f)); - sprintf(zText, "waiting %u seconds before we retry", backup / 1000); - perror(zText); - _sleep(backup); - if (backup < maxbackup) { - backup *= 2; - } - } - } while (errno); + } if (!gotit) { log_warning("No report for faction %s!", factionid(f)); } diff --git a/src/util/bsdstring.c b/src/util/bsdstring.c index 5ec87bfa1..b1237e2ae 100644 --- a/src/util/bsdstring.c +++ b/src/util/bsdstring.c @@ -7,8 +7,18 @@ #include "bsdstring.h" -int wrptr(char **ptr, size_t * size, size_t bytes) +int wrptr(char **ptr, size_t * size, int result) { + size_t bytes = (size_t)result; + if (result < 0) { + // _snprintf buffer was too small + if (*size > 0) { + **ptr = 0; + *size = 0; + } + errno = 0; + return ERANGE; + } if (bytes == 0) { return 0; } diff --git a/src/util/bsdstring.h b/src/util/bsdstring.h index 883e102e6..56fdd13fa 100644 --- a/src/util/bsdstring.h +++ b/src/util/bsdstring.h @@ -2,7 +2,7 @@ #define UTIL_BSDSTRING_H #include -extern int wrptr(char **ptr, size_t * size, size_t bytes); +extern int wrptr(char **ptr, size_t * size, int bytes); #ifndef HAVE_STRLCPY extern size_t strlcpy(char *dst, const char *src, size_t siz); @@ -16,6 +16,7 @@ extern size_t strlcat(char *dst, const char *src, size_t siz); extern size_t slprintf(char * dst, size_t size, const char * format, ...); #endif +#define WARN_STATIC_BUFFER_EX(foo) log_warning("%s: static buffer too small in %s:%d\n", (foo), __FILE__, __LINE__) #define WARN_STATIC_BUFFER() log_warning("static buffer too small in %s:%d\n", __FILE__, __LINE__) #define INFO_STATIC_BUFFER() log_info("static buffer too small in %s:%d\n", __FILE__, __LINE__) From 1806030baa187368b1555821cd32150abab4a18d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 17 Aug 2015 19:28:05 +0200 Subject: [PATCH 3/9] new all-in-one strlcpy and wrptr function --- src/util/bsdstring.c | 12 ++++++++++++ src/util/bsdstring.h | 10 ++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/util/bsdstring.c b/src/util/bsdstring.c index b1237e2ae..037f18eed 100644 --- a/src/util/bsdstring.c +++ b/src/util/bsdstring.c @@ -6,6 +6,7 @@ #include #include "bsdstring.h" +#include "log.h" int wrptr(char **ptr, size_t * size, int result) { @@ -61,6 +62,17 @@ size_t strlcpy(char *dst, const char *src, size_t siz) } #endif +char * strlcpy_w(char *dst, const char *src, size_t *siz, const char *err, const char *file, int line) +{ + size_t bytes = strlcpy(dst, src, *siz); + char * buf = dst; + if (wrptr(&buf, siz, bytes) != 0) + log_warning("%s: static buffer too small in %s:%d\n", err, file, line); + return buf; +} + + + #ifndef HAVE_STRLCAT #define HAVE_STRLCAT size_t strlcat(char *dst, const char *src, size_t siz) diff --git a/src/util/bsdstring.h b/src/util/bsdstring.h index 56fdd13fa..b1538bf4e 100644 --- a/src/util/bsdstring.h +++ b/src/util/bsdstring.h @@ -2,22 +2,24 @@ #define UTIL_BSDSTRING_H #include -extern int wrptr(char **ptr, size_t * size, int bytes); +int wrptr(char **ptr, size_t * size, int bytes); #ifndef HAVE_STRLCPY -extern size_t strlcpy(char *dst, const char *src, size_t siz); +size_t strlcpy(char *dst, const char *src, size_t siz); #endif +char * strlcpy_w(char *dst, const char *src, size_t *siz, const char *err, const char *file, int line); #ifndef HAVE_STRLCAT -extern size_t strlcat(char *dst, const char *src, size_t siz); +size_t strlcat(char *dst, const char *src, size_t siz); #endif #ifndef HAVE_SLPRINTF -extern size_t slprintf(char * dst, size_t size, const char * format, ...); +size_t slprintf(char * dst, size_t size, const char * format, ...); #endif #define WARN_STATIC_BUFFER_EX(foo) log_warning("%s: static buffer too small in %s:%d\n", (foo), __FILE__, __LINE__) #define WARN_STATIC_BUFFER() log_warning("static buffer too small in %s:%d\n", __FILE__, __LINE__) #define INFO_STATIC_BUFFER() log_info("static buffer too small in %s:%d\n", __FILE__, __LINE__) +#define STRLCPY(dst, src, siz, err) strlcpy_w((dst), (src), (siz), (err), __FILE__, __LINE__) #endif From 7e64f3177d70cc44594e7fe473c04bad7a54075a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 17 Aug 2015 19:35:07 +0200 Subject: [PATCH 4/9] refactoring: rewrite tests to use test_find_messagetype instead of assert_messages. tests: add cleanup of message_types to reduce global state. --- src/economy.test.c | 4 +- src/kernel/config.c | 1 + src/kernel/messages.test.c | 3 ++ src/laws.test.c | 6 +-- src/spy.test.c | 30 +++------------ src/tests.c | 58 +++------------------------- src/tests.h | 4 -- src/util/message.c | 78 ++++++++++++++++++++++++-------------- src/util/message.h | 14 +++---- 9 files changed, 74 insertions(+), 124 deletions(-) diff --git a/src/economy.test.c b/src/economy.test.c index 3feba7956..fe31e5976 100644 --- a/src/economy.test.c +++ b/src/economy.test.c @@ -142,10 +142,8 @@ static struct unit *create_recruiter(void) { static void test_heroes_dont_recruit(CuTest * tc) { unit *u; order *ord; - const message_type *msg_types[1]; test_cleanup(); - msg_types[0] = register_msg("error_herorecruit", 3, "unit:unit", "region:region", "command:order"); u = create_recruiter(); fset(u, UFL_HERO); @@ -155,7 +153,7 @@ static void test_heroes_dont_recruit(CuTest * tc) { economics(u->region); CuAssertIntEquals(tc, 1, u->number); - assert_messages(tc, u->faction->msgs->begin, msg_types, 1, true, 0); + CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "error_herorecruit")); test_cleanup(); } diff --git a/src/kernel/config.c b/src/kernel/config.c index 9c26ad85a..573126137 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -1676,6 +1676,7 @@ void attrib_init(void) void kernel_init(void) { register_reports(); + mt_clear(); if (!mt_find("missing_message")) { mt_register(mt_new_va("missing_message", "name:string", 0)); mt_register(mt_new_va("missing_feedback", "unit:unit", "region:region", "command:order", "name:string", 0)); diff --git a/src/kernel/messages.test.c b/src/kernel/messages.test.c index d3d4c7f90..295f4f576 100644 --- a/src/kernel/messages.test.c +++ b/src/kernel/messages.test.c @@ -17,6 +17,7 @@ void test_message(CuTest *tc) { message *msg; message_type *mtype = mt_new("custom", NULL); + test_cleanup(); mt_register(mtype); CuAssertPtrEquals(tc, mtype, (void *)mt_find("custom")); CuAssertIntEquals(tc, 0, mtype->nparameters); @@ -41,6 +42,7 @@ static void test_merge_split(CuTest *tc) { struct mlist **split; message_type *mtype = mt_new("custom", NULL); + test_cleanup(); mt_register(mtype); add_message(&mlist, msg_message(mtype->name, "")); add_message(&append, msg_message(mtype->name, "")); @@ -55,6 +57,7 @@ static void test_merge_split(CuTest *tc) { CuAssertPtrEquals(tc, append->begin, mlist->begin->next); split_messages(mlist, split); CuAssertPtrEquals(tc, 0, mlist->begin->next); + test_cleanup(); } CuSuite *get_messages_suite(void) { diff --git a/src/laws.test.c b/src/laws.test.c index 6e6faeadb..a824f4cab 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -745,14 +745,10 @@ static void test_peasant_luck_effect(CuTest *tc) { static void test_luck_message(CuTest *tc) { region* r; - const message_type *msg_types[1]; - test_cleanup(); r = test_create_region(0, 0, NULL); rsetpeasants(r, 1); - msg_types[0] = register_msg("peasantluck_success", 1, "births:int"); - demographics(); CuAssertPtrEquals_Msg(tc, "unexpected message", (void *)NULL, r->msgs); @@ -764,7 +760,7 @@ static void test_luck_message(CuTest *tc) { demographics(); - assert_messages(tc, r->msgs->begin, msg_types, 1, true, 0); + CuAssertPtrNotNull(tc, test_find_messagetype(r->msgs, "peasantluck_success")); test_cleanup(); } diff --git a/src/spy.test.c b/src/spy.test.c index 085cc5675..95f1a6dbc 100644 --- a/src/spy.test.c +++ b/src/spy.test.c @@ -24,20 +24,10 @@ #include -typedef enum { - M_BASE, - M_MAGE, - M_SKILLS, - M_FACTION, - M_ITEMS, - NUM_TYPES -} m_type; - typedef struct { region *r; unit *spy; unit *victim; - const message_type *msg_types[NUM_TYPES]; } spy_fixture; static void setup_spy(spy_fixture *fix) { @@ -45,12 +35,6 @@ static void setup_spy(spy_fixture *fix) { fix->r = test_create_region(0, 0, NULL); fix->spy = test_create_unit(test_create_faction(NULL), fix->r); fix->victim = test_create_unit(test_create_faction(NULL), fix->r); - fix->msg_types[M_BASE] = register_msg("spyreport", 3, "spy:unit", "target:unit", "status:string"); - fix->msg_types[M_MAGE] = register_msg("spyreport_mage", 3, "spy:unit", "target:unit", "type:string"); - fix->msg_types[M_SKILLS] = register_msg("spyreport_skills", 3, "spy:unit", "target:unit", "skills:string"); - fix->msg_types[M_FACTION] = register_msg("spyreport_faction", 3, "spy:unit", "target:unit", "faction:faction"); - fix->msg_types[M_ITEMS] = register_msg("spyreport_items", 3, "spy:unit", "target:unit", "items:items"); - } static void test_simple_spy_message(CuTest *tc) { @@ -60,8 +44,7 @@ static void test_simple_spy_message(CuTest *tc) { spy_message(0, fix.spy, fix.victim); - assert_messages(tc, fix.spy->faction->msgs->begin, fix.msg_types, 1, true, M_BASE); - + CuAssertPtrNotNull(tc, test_find_messagetype(fix.spy->faction->msgs, "spyreport")); test_cleanup(); } @@ -92,12 +75,11 @@ static void test_all_spy_message(CuTest *tc) { spy_message(99, fix.spy, fix.victim); - assert_messages(tc, fix.spy->faction->msgs->begin, fix.msg_types, 5, true, - M_BASE, - M_MAGE, - M_FACTION, - M_SKILLS, - M_ITEMS); + CuAssertPtrNotNull(tc, test_find_messagetype(fix.spy->faction->msgs, "spyreport")); + CuAssertPtrNotNull(tc, test_find_messagetype(fix.spy->faction->msgs, "spyreport_mage")); + CuAssertPtrNotNull(tc, test_find_messagetype(fix.spy->faction->msgs, "spyreport_skills")); + CuAssertPtrNotNull(tc, test_find_messagetype(fix.spy->faction->msgs, "spyreport_faction")); + CuAssertPtrNotNull(tc, test_find_messagetype(fix.spy->faction->msgs, "spyreport_items")); test_cleanup(); } diff --git a/src/tests.c b/src/tests.c index 1a61813b5..028fb888d 100644 --- a/src/tests.c +++ b/src/tests.c @@ -80,6 +80,11 @@ void test_cleanup(void) free_races(); free_spellbooks(); free_gamedata(); + mt_clear(); + if (!mt_find("missing_message")) { + mt_register(mt_new_va("missing_message", "name:string", 0)); + mt_register(mt_new_va("missing_feedback", "unit:unit", "region:region", "command:order", "name:string", 0)); + } } terrain_type * @@ -255,59 +260,6 @@ struct message * test_find_messagetype(struct message_list *msgs, const char *na return 0; } -const message_type *register_msg(const char *type, int n_param, ...) { - char **argv; - va_list args; - int i; - - va_start(args, n_param); - - argv = malloc(sizeof(char *) * (n_param + 1)); - for (i = 0; i < n_param; ++i) { - argv[i] = va_arg(args, char *); - } - argv[n_param] = 0; - va_end(args); - return mt_register(mt_new(type, (const char **)argv)); -} - -void assert_messages(struct CuTest * tc, struct mlist *msglist, const message_type **types, - int num_msgs, bool exact_match, ...) { - char buf[100]; - va_list args; - int found = 0, argc = -1; - struct message *msg; - bool match = true; - - va_start(args, exact_match); - - while (msglist) { - msg = msglist->msg; - if (found >= num_msgs) { - if (exact_match) { - slprintf(buf, sizeof(buf), "too many messages: %s", msg->type->name); - CuFail(tc, buf); - } else { - break; - } - } - if (exact_match || match) - argc = va_arg(args, int); - - match = strcmp(types[argc]->name, msg->type->name) == 0; - if (match) - ++found; - else if (exact_match) - CuAssertStrEquals(tc, types[argc]->name, msg->type->name); - - msglist = msglist->next; - } - - CuAssertIntEquals_Msg(tc, "not enough messages", num_msgs, found); - - va_end(args); -} - void disabled_test(void *suite, void (*test)(CuTest *), const char *name) { (void)test; fprintf(stderr, "%s: SKIP\n", name); diff --git a/src/tests.h b/src/tests.h index 7dd1464f3..27f5de2db 100644 --- a/src/tests.h +++ b/src/tests.h @@ -44,10 +44,6 @@ extern "C" { struct message * test_find_messagetype(struct message_list *msgs, const char *name); struct message * test_get_last_message(struct message_list *mlist); - const struct message_type *register_msg(const char *type, int n_param, ...); - void assert_messages(struct CuTest * tc, struct mlist *msglist, const struct message_type **types, - int num_msgs, bool exact_match, ...); - void disabled_test(void *suite, void (*)(struct CuTest *), const char *name); #define DISABLE_TEST(SUITE, TEST) disabled_test(SUITE, TEST, #TEST) diff --git a/src/util/message.c b/src/util/message.c index b082d9d98..073371b54 100644 --- a/src/util/message.c +++ b/src/util/message.c @@ -32,6 +32,32 @@ const char *mt_name(const message_type * mtype) return mtype->name; } +arg_type *argtypes = NULL; + +void +register_argtype(const char *name, void(*free_arg) (variant), +variant(*copy_arg) (variant), variant_type type) +{ + arg_type *atype = (arg_type *)malloc(sizeof(arg_type)); + atype->name = name; + atype->next = argtypes; + atype->release = free_arg; + atype->copy = copy_arg; + atype->vtype = type; + argtypes = atype; +} + +static arg_type *find_argtype(const char *name) +{ + arg_type *atype = argtypes; + while (atype != NULL) { + if (strcmp(atype->name, name) == 0) + return atype; + atype = atype->next; + } + return NULL; +} + message_type *mt_new(const char *name, const char *args[]) { int i, nparameters = 0; @@ -50,8 +76,8 @@ message_type *mt_new(const char *name, const char *args[]) mtype->name = _strdup(name); mtype->nparameters = nparameters; if (nparameters > 0) { - mtype->pnames = (const char **)malloc(sizeof(char *) * nparameters); - mtype->types = (const arg_type **)malloc(sizeof(arg_type *) * nparameters); + mtype->pnames = (char **)malloc(sizeof(char *) * nparameters); + mtype->types = (arg_type **)malloc(sizeof(arg_type *) * nparameters); } else { mtype->pnames = NULL; @@ -96,32 +122,6 @@ message_type *mt_new_va(const char *name, ...) return mt_new(name, args); } -arg_type *argtypes = NULL; - -void -register_argtype(const char *name, void(*free_arg) (variant), -variant(*copy_arg) (variant), variant_type type) -{ - arg_type *atype = (arg_type *)malloc(sizeof(arg_type)); - atype->name = name; - atype->next = argtypes; - atype->release = free_arg; - atype->copy = copy_arg; - atype->vtype = type; - argtypes = atype; -} - -const arg_type *find_argtype(const char *name) -{ - arg_type *atype = argtypes; - while (atype != NULL) { - if (strcmp(atype->name, name) == 0) - return atype; - atype = atype->next; - } - return NULL; -} - static variant copy_arg(const arg_type * atype, variant data) { assert(atype != NULL); @@ -161,6 +161,28 @@ message *msg_create(const struct message_type *mtype, variant args[]) #define MT_MAXHASH 1021 static quicklist *messagetypes[MT_MAXHASH]; +static void mt_free(void *val) { + message_type *mtype = (message_type *)val; + int i; + for (i = 0; i != mtype->nparameters; ++i) { + free(mtype->pnames[i]); + } + free(mtype->pnames); + free(mtype->types); + free(mtype->name); + free(mtype); +} + +void mt_clear(void) { + int i; + for (i = 0; i != MT_MAXHASH; ++i) { + quicklist *ql = messagetypes[i]; + ql_foreach(ql, mt_free); + ql_free(ql); + messagetypes[i] = 0; + } +} + const message_type *mt_find(const char *name) { unsigned int hash = hashstring(name) % MT_MAXHASH; diff --git a/src/util/message.h b/src/util/message.h index 7a9722224..b76f281a8 100644 --- a/src/util/message.h +++ b/src/util/message.h @@ -28,10 +28,10 @@ extern "C" { typedef struct message_type { unsigned int key; - const char *name; + char *name; int nparameters; - const char **pnames; - const struct arg_type **types; + char **pnames; + struct arg_type ** types; } message_type; typedef struct message { @@ -40,8 +40,9 @@ extern "C" { int refcount; } message; - extern struct message_type *mt_new(const char *name, const char **args); - extern struct message_type *mt_new_va(const char *name, ...); + void mt_clear(void); + struct message_type *mt_new(const char *name, const char **args); + struct message_type *mt_new_va(const char *name, ...); /* mt_new("simple_sentence", "subject:string", "predicate:string", * "object:string", "lang:locale", NULL); */ @@ -61,9 +62,8 @@ extern "C" { extern void register_argtype(const char *name, void(*free_arg) (variant), variant(*copy_arg) (variant), variant_type); - extern const struct arg_type *find_argtype(const char *name); - extern void(*msg_log_create) (const struct message * msg); + void(*msg_log_create) (const struct message * msg); #ifdef __cplusplus } From b999e3c963646df84b74941ba102487da8c307d9 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 17 Aug 2015 19:37:02 +0200 Subject: [PATCH 5/9] replace strlcpy/wrptr pairs with new STRLCPY macro. --- src/battle.c | 25 ++++++------------------- src/move.c | 26 +++++++------------------- src/report.c | 21 ++++++++++++++++++++- 3 files changed, 33 insertions(+), 39 deletions(-) diff --git a/src/battle.c b/src/battle.c index daf96ce1e..3413fa54f 100644 --- a/src/battle.c +++ b/src/battle.c @@ -2966,21 +2966,16 @@ static void print_header(battle * b) side *s; char *bufp = zText; size_t size = sizeof(zText) - 1; - size_t bytes; for (s = b->sides; s != b->sides + b->nsides; ++s) { fighter *df; for (df = s->fighters; df; df = df->next) { if (is_attacker(df)) { if (first) { - bytes = strlcpy(bufp, ", ", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, ", ", &size, "print_header"); } if (lastf) { - bytes = strlcpy(bufp, (const char *)lastf, size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, lastf, &size, "print_header"); first = true; } if (seematrix(f, s)) @@ -2992,20 +2987,12 @@ static void print_header(battle * b) } } if (first) { - bytes = strlcpy(bufp, " ", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = strlcpy(bufp, (const char *)LOC(f->locale, "and"), size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = strlcpy(bufp, " ", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, " ", &size, "print_header"); + bufp = STRLCPY(bufp, LOC(f->locale, "and"), &size, "print_header"); + bufp = STRLCPY(bufp, " ", &size, "print_header"); } if (lastf) { - bytes = strlcpy(bufp, (const char *)lastf, size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, lastf, &size, "print_header"); } m = msg_message("battle::starters", "factions", zText); diff --git a/src/move.c b/src/move.c index 4fd9e6dab..bf12641fc 100644 --- a/src/move.c +++ b/src/move.c @@ -1131,7 +1131,6 @@ static const char *shortdirections[MAXDIRECTIONS] = { static void cycle_route(order * ord, unit * u, int gereist) { - size_t bytes; int cm = 0; char tail[1024], *bufp = tail; char neworder[2048]; @@ -1172,25 +1171,17 @@ static void cycle_route(order * ord, unit * u, int gereist) if (!pause) { const char *loc = LOC(lang, shortdirections[d]); if (bufp != tail) { - bytes = strlcpy(bufp, " ", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, " ", &size, "cycle_route"); } - bytes = strlcpy(bufp, loc, size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, loc, &size, "cycle_route"); } } else if (strlen(neworder) > sizeof(neworder) / 2) break; else if (cm == gereist && !paused && pause) { const char *loc = LOC(lang, parameters[P_PAUSE]); - bytes = strlcpy(bufp, " ", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = strlcpy(bufp, loc, size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, " ", &size, "cycle_route"); + bufp = STRLCPY(bufp, loc, &size, "cycle_route"); paused = true; } else if (pause) { @@ -2568,12 +2559,9 @@ static int hunt(unit * u, order * ord) } rc = rconnect(rc, dir); while (moves < speed && (dir = hunted_dir(rc->attribs, id)) != NODIRECTION) { - bytes = strlcpy(bufp, " ", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = strlcpy(bufp, LOC(u->faction->locale, directions[dir]), size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + const char *loc = LOC(u->faction->locale, directions[dir]); + bufp = STRLCPY(bufp, " ", &size, "hunt"); + bufp = STRLCPY(bufp, loc, &size, "hunt"); moves++; rc = rconnect(rc, dir); } diff --git a/src/report.c b/src/report.c index ca8e50a91..7b8680ed8 100644 --- a/src/report.c +++ b/src/report.c @@ -100,6 +100,17 @@ extern int *storms; extern int weeks_per_month; extern int months_per_year; +static void check_errno(const char * file, int line) { + if (errno) { + char zText[64]; + sprintf(zText, "error %d during report at %s:%d", errno, file, line); + perror(zText); + errno = 0; + } +} + +#define CHECK_ERRNO() check_errno(__FILE__, __LINE__) + static char *gamedate_season(const struct locale *lang) { static char buf[256]; // FIXME: static return value @@ -1396,14 +1407,17 @@ static void durchreisende(stream *out, const region * r, const faction * f) } } if (size > 0) { + CHECK_ERRNO(); if (maxtravel == 1) { bytes = _snprintf(bufp, size, " %s", LOC(f->locale, "has_moved_one")); } else { bytes = _snprintf(bufp, size, " %s", LOC(f->locale, "has_moved_many")); } + CHECK_ERRNO(); if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + WARN_STATIC_BUFFER_EX("durchreisende"); + CHECK_ERRNO(); } *bufp = 0; paragraph(out, buf, 0, 0, 0); @@ -2206,6 +2220,7 @@ const char *charset) } ch = 0; + CHECK_ERRNO(); for (a = a_find(f->attribs, &at_showitem); a && a->type == &at_showitem; a = a->next) { const potion_type *ptype = @@ -2258,6 +2273,7 @@ const char *charset) } } newline(out); + CHECK_ERRNO(); centre(out, LOC(f->locale, "nr_alliances"), false); newline(out); @@ -2265,6 +2281,7 @@ const char *charset) rpline(out); + CHECK_ERRNO(); anyunits = 0; for (r = ctx->first; sr == NULL && r != ctx->last; r = r->next) { @@ -2389,6 +2406,7 @@ const char *charset) newline(out); rpline(out); + CHECK_ERRNO(); } if (!is_monsters(f)) { if (!anyunits) { @@ -2400,6 +2418,7 @@ const char *charset) } } fstream_done(&strm); + CHECK_ERRNO(); return 0; } From 1042c94fd9c6769c2db92e625bc0695343d1e012 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 17 Aug 2015 20:17:02 +0200 Subject: [PATCH 6/9] quickly fix gcc conversion warnings. lots of DRY. --- src/laws.c | 39 ++++++++++++++++++--------------------- src/move.c | 3 ++- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/src/laws.c b/src/laws.c index 50b7a9a07..a1e50c750 100755 --- a/src/laws.c +++ b/src/laws.c @@ -2320,7 +2320,8 @@ static bool display_race(faction * f, unit * u, const race * rc) name = rc_name_s(rc, NAME_SINGULAR); bytes = slprintf(bufp, size, "%s: ", LOC(f->locale, name)); - if (wrptr(&bufp, &size, bytes) != 0) + assert(bytes <= INT_MAX); + if (wrptr(&bufp, &size, (int)bytes) != 0) WARN_STATIC_BUFFER(); key = mkname("raceinfo", rc->_name); @@ -2329,36 +2330,38 @@ static bool display_race(faction * f, unit * u, const race * rc) info = LOC(f->locale, mkname("raceinfo", "no_info")); } - bytes = strlcpy(bufp, info, size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, info, &size, "display_race"); /* hp_p : Trefferpunkte */ bytes = slprintf(bufp, size, " %d %s", rc->hitpoints, LOC(f->locale, "stat_hitpoints")); - if (wrptr(&bufp, &size, bytes) != 0) + assert(bytes <= INT_MAX); + if (wrptr(&bufp, &size, (int)bytes) != 0) WARN_STATIC_BUFFER(); /* b_attacke : Angriff */ bytes = slprintf(bufp, size, ", %s: %d", LOC(f->locale, "stat_attack"), (rc->at_default + rc->at_bonus)); - if (wrptr(&bufp, &size, bytes) != 0) + assert(bytes <= INT_MAX); + if (wrptr(&bufp, &size, (int)bytes) != 0) WARN_STATIC_BUFFER(); /* b_defense : Verteidigung */ bytes = slprintf(bufp, size, ", %s: %d", LOC(f->locale, "stat_defense"), (rc->df_default + rc->df_bonus)); - if (wrptr(&bufp, &size, bytes) != 0) + assert(bytes <= INT_MAX); + if (wrptr(&bufp, &size, (int)bytes) != 0) WARN_STATIC_BUFFER(); /* b_armor : RĂ¼stung */ if (rc->armor > 0) { bytes = slprintf(bufp, size, ", %s: %d", LOC(f->locale, "stat_armor"), rc->armor); - if (wrptr(&bufp, &size, bytes) != 0) + assert(bytes <= INT_MAX); + if (wrptr(&bufp, &size, (int)bytes) != 0) WARN_STATIC_BUFFER(); } @@ -2377,30 +2380,23 @@ static bool display_race(faction * f, unit * u, const race * rc) } } if (rc->battle_flags & BF_EQUIPMENT) { - bytes = (size_t)_snprintf(bufp, size, " %s", LOC(f->locale, "stat_equipment")); - if (wrptr(&bufp, &size, bytes) != 0) + if (wrptr(&bufp, &size, _snprintf(bufp, size, " %s", LOC(f->locale, "stat_equipment"))) != 0) WARN_STATIC_BUFFER(); } if (rc->battle_flags & BF_RES_PIERCE) { - bytes = (size_t)_snprintf(bufp, size, " %s", LOC(f->locale, "stat_pierce")); - if (wrptr(&bufp, &size, bytes) != 0) + if (wrptr(&bufp, &size, _snprintf(bufp, size, " %s", LOC(f->locale, "stat_pierce"))) != 0) WARN_STATIC_BUFFER(); } if (rc->battle_flags & BF_RES_CUT) { - bytes = (size_t)_snprintf(bufp, size, " %s", LOC(f->locale, "stat_cut")); - if (wrptr(&bufp, &size, bytes) != 0) + if (wrptr(&bufp, &size, _snprintf(bufp, size, " %s", LOC(f->locale, "stat_cut"))) != 0) WARN_STATIC_BUFFER(); } if (rc->battle_flags & BF_RES_BASH) { - bytes = (size_t)_snprintf(bufp, size, " %s", LOC(f->locale, "stat_bash")); - if (wrptr(&bufp, &size, bytes) != 0) + if (wrptr(&bufp, &size, _snprintf(bufp, size, " %s", LOC(f->locale, "stat_bash"))) != 0) WARN_STATIC_BUFFER(); } - bytes = - (size_t)_snprintf(bufp, size, " %d %s", at_count, LOC(f->locale, - (at_count == 1) ? "stat_attack" : "stat_attacks")); - if (wrptr(&bufp, &size, bytes) != 0) + if (wrptr(&bufp, &size, _snprintf(bufp, size, " %d %s", at_count, LOC(f->locale, (at_count == 1) ? "stat_attack" : "stat_attacks"))) != 0) WARN_STATIC_BUFFER(); for (a = 0; a < RACE_ATTACKS; a++) { @@ -2439,7 +2435,8 @@ static bool display_race(faction * f, unit * u, const race * rc) bytes = 0; } - if (bytes && wrptr(&bufp, &size, bytes) != 0) + assert(bytes <= INT_MAX); + if (bytes && wrptr(&bufp, &size, (int)bytes) != 0) WARN_STATIC_BUFFER(); } } diff --git a/src/move.c b/src/move.c index bf12641fc..36db8f54e 100644 --- a/src/move.c +++ b/src/move.c @@ -2543,7 +2543,8 @@ static int hunt(unit * u, order * ord) bufp = command; bytes = slprintf(bufp, size, "%s %s", LOC(u->faction->locale, keyword(K_MOVE)), LOC(u->faction->locale, directions[dir])); - if (wrptr(&bufp, &size, bytes) != 0) + assert(bytes <= INT_MAX); + if (wrptr(&bufp, &size, (int)bytes) != 0) WARN_STATIC_BUFFER(); moves = 1; From e621b974654d4706cbff3a47e63a151bef1090a4 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 17 Aug 2015 20:22:02 +0200 Subject: [PATCH 7/9] Easy pratfall: Visual Studio includes limits.h through stdlib.h, but gcc/clang do not. --- src/move.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/move.c b/src/move.c index 36db8f54e..bd7ffb997 100644 --- a/src/move.c +++ b/src/move.c @@ -77,6 +77,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include int *storms; From 681697fd474e21537875dfc878001a8e43d20bec Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 17 Aug 2015 20:32:02 +0200 Subject: [PATCH 8/9] gcc still more picky than clang. --- src/spells.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/spells.c b/src/spells.c index 8b504487a..8833497d5 100644 --- a/src/spells.c +++ b/src/spells.c @@ -604,13 +604,15 @@ static int sp_summon_familiar(castorder * co) else { bytes = strlcpy(bufp, (const char *)", ", size); } - if (wrptr(&bufp, &size, bytes) != 0) + assert(bytes <= INT_MAX); + if (wrptr(&bufp, &size, (int)bytes) != 0) WARN_STATIC_BUFFER(); } bytes = strlcpy(bufp, (const char *)skillname((skill_t)sk, mage->faction->locale), size); - if (wrptr(&bufp, &size, bytes) != 0) + assert(bytes <= INT_MAX); + if (wrptr(&bufp, &size, (int)bytes) != 0) WARN_STATIC_BUFFER(); } } From c8cbeea6608587d7f51354f4931e82e6ab054828 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 17 Aug 2015 22:48:21 +0200 Subject: [PATCH 9/9] STRLCPY macro redefinition and fixes for gcc. work for monkeys. --- src/battle.c | 37 ++--- src/laws.c | 8 +- src/move.c | 12 +- src/reports.c | 315 ++++++++++++------------------------------- src/util/bsdstring.c | 11 +- src/util/bsdstring.h | 3 +- 6 files changed, 117 insertions(+), 269 deletions(-) diff --git a/src/battle.c b/src/battle.c index 3413fa54f..ebfde1548 100644 --- a/src/battle.c +++ b/src/battle.c @@ -2972,10 +2972,10 @@ static void print_header(battle * b) for (df = s->fighters; df; df = df->next) { if (is_attacker(df)) { if (first) { - bufp = STRLCPY(bufp, ", ", &size, "print_header"); + bufp = STRLCPY(bufp, ", ", size); } if (lastf) { - bufp = STRLCPY(bufp, lastf, &size, "print_header"); + bufp = STRLCPY(bufp, lastf, size); first = true; } if (seematrix(f, s)) @@ -2987,12 +2987,12 @@ static void print_header(battle * b) } } if (first) { - bufp = STRLCPY(bufp, " ", &size, "print_header"); - bufp = STRLCPY(bufp, LOC(f->locale, "and"), &size, "print_header"); - bufp = STRLCPY(bufp, " ", &size, "print_header"); + bufp = STRLCPY(bufp, " ", size); + bufp = STRLCPY(bufp, LOC(f->locale, "and"), size); + bufp = STRLCPY(bufp, " ", size); } if (lastf) { - bufp = STRLCPY(bufp, lastf, &size, "print_header"); + bufp = STRLCPY(bufp, lastf, size); } m = msg_message("battle::starters", "factions", zText); @@ -3723,7 +3723,6 @@ static int battle_report(battle * b) faction *fac = bf->faction; char buf[32 * MAXSIDES]; char *bufp = buf; - size_t bytes; size_t size = sizeof(buf) - 1; message *m; @@ -3746,34 +3745,24 @@ static int battle_report(battle * b) char buffer[32]; if (komma) { - bytes = strlcpy(bufp, ", ", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, ", ", size); } slprintf(buffer, sizeof(buffer), "%s %2d(%s): ", loc_army, army_index(s), abbrev); - - bytes = strlcpy(bufp, buffer, size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + + bufp = STRLCPY(bufp, buffer, size); for (r = FIGHT_ROW; r != NUMROWS; ++r) { if (alive[r]) { if (l != FIGHT_ROW) { - bytes = strlcpy(bufp, "+", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, "+", size); } while (k--) { - bytes = strlcpy(bufp, "0+", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, "0+", size); } sprintf(buffer, "%d", alive[r]); - - bytes = strlcpy(bufp, buffer, size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + + bufp = STRLCPY(bufp, buffer, size); k = 0; l = r + 1; diff --git a/src/laws.c b/src/laws.c index a1e50c750..44caa72f9 100755 --- a/src/laws.c +++ b/src/laws.c @@ -2330,7 +2330,7 @@ static bool display_race(faction * f, unit * u, const race * rc) info = LOC(f->locale, mkname("raceinfo", "no_info")); } - bufp = STRLCPY(bufp, info, &size, "display_race"); + bufp = STRLCPY(bufp, info, size); /* hp_p : Trefferpunkte */ bytes = @@ -2402,11 +2402,9 @@ static bool display_race(faction * f, unit * u, const race * rc) for (a = 0; a < RACE_ATTACKS; a++) { if (rc->attack[a].type != AT_NONE) { if (a != 0) - bytes = strlcpy(bufp, ", ", size); + bufp = STRLCPY(bufp, ", ", size); else - bytes = strlcpy(bufp, ": ", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, ": ", size); switch (rc->attack[a].type) { case AT_STANDARD: diff --git a/src/move.c b/src/move.c index bd7ffb997..131d87e74 100644 --- a/src/move.c +++ b/src/move.c @@ -1172,17 +1172,17 @@ static void cycle_route(order * ord, unit * u, int gereist) if (!pause) { const char *loc = LOC(lang, shortdirections[d]); if (bufp != tail) { - bufp = STRLCPY(bufp, " ", &size, "cycle_route"); + bufp = STRLCPY_EX(bufp, " ", &size, "cycle_route"); } - bufp = STRLCPY(bufp, loc, &size, "cycle_route"); + bufp = STRLCPY_EX(bufp, loc, &size, "cycle_route"); } } else if (strlen(neworder) > sizeof(neworder) / 2) break; else if (cm == gereist && !paused && pause) { const char *loc = LOC(lang, parameters[P_PAUSE]); - bufp = STRLCPY(bufp, " ", &size, "cycle_route"); - bufp = STRLCPY(bufp, loc, &size, "cycle_route"); + bufp = STRLCPY_EX(bufp, " ", &size, "cycle_route"); + bufp = STRLCPY_EX(bufp, loc, &size, "cycle_route"); paused = true; } else if (pause) { @@ -2562,8 +2562,8 @@ static int hunt(unit * u, order * ord) rc = rconnect(rc, dir); while (moves < speed && (dir = hunted_dir(rc->attribs, id)) != NODIRECTION) { const char *loc = LOC(u->faction->locale, directions[dir]); - bufp = STRLCPY(bufp, " ", &size, "hunt"); - bufp = STRLCPY(bufp, loc, &size, "hunt"); + bufp = STRLCPY_EX(bufp, " ", &size, "hunt"); + bufp = STRLCPY_EX(bufp, loc, &size, "hunt"); moves++; rc = rconnect(rc, dir); } diff --git a/src/reports.c b/src/reports.c index d632e06a0..c381ac831 100644 --- a/src/reports.c +++ b/src/reports.c @@ -225,26 +225,19 @@ const char **name, const char **basename, int *number, bool singular) } #define ORDERS_IN_NR 1 -static size_t buforder(char *bufp, size_t size, const order * ord, int mode) +static size_t buforder(char *buffer, size_t size, const order * ord, int mode) { - size_t tsize = 0; - size_t bytes; + char *bufp = buffer; - bytes = strlcpy(bufp, ", \"", size); - tsize += bytes; - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, ", \"", size); if (mode < ORDERS_IN_NR) { char cmd[ORDERSIZE]; get_command(ord, cmd, sizeof(cmd)); - bytes = strlcpy(bufp, cmd, size); + bufp = STRLCPY(bufp, cmd, size); } else { - bytes = strlcpy(bufp, "...", size); + bufp = STRLCPY(bufp, "...", size); } - tsize += bytes; - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); if (size > 1) { *bufp++ = '\"'; @@ -253,9 +246,8 @@ static size_t buforder(char *bufp, size_t size, const order * ord, int mode) else { WARN_STATIC_BUFFER(); } - ++tsize; - return tsize; + return bufp-buffer; } /** create a report of a list of items to a non-owner. @@ -465,7 +457,6 @@ size_t size) bool itemcloak = false; const curse_type *itemcloak_ct = 0; int result = 0; - size_t bytes; item results[MAX_INVENTORY]; itemcloak_ct = ct_find("itemcloak"); @@ -473,9 +464,7 @@ size_t size) itemcloak = curse_active(get_curse(u->attribs, itemcloak_ct)); } - bytes = strlcpy(bufp, unitname(u), size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, unitname(u), size); if (!isbattle) { attrib *a_otherfaction = a_find(u->attribs, &at_otherfaction); @@ -484,92 +473,61 @@ size_t size) attrib *a = a_find(u->attribs, &at_group); if (a) { group *g = (group *)a->data.v; - bytes = strlcpy(bufp, ", ", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = strlcpy(bufp, groupid(g, f), size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, ", ", size); + bufp = STRLCPY(bufp, groupid(g, f), size); } } if (getarnt) { - bytes = strlcpy(bufp, ", ", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = strlcpy(bufp, LOC(f->locale, "anonymous"), size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, ", ", size); + bufp = STRLCPY(bufp, LOC(f->locale, "anonymous"), size); } else if (a_otherfaction) { faction *otherfaction = get_otherfaction(a_otherfaction); if (otherfaction) { - bytes = strlcpy(bufp, ", ", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = strlcpy(bufp, factionname(otherfaction), size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, ", ", size); + bufp = STRLCPY(bufp, factionname(otherfaction), size); } } } else { if (getarnt) { - bytes = strlcpy(bufp, ", ", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = strlcpy(bufp, LOC(f->locale, "anonymous"), size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, ", ", size); + bufp = STRLCPY(bufp, LOC(f->locale, "anonymous"), size); } else { if (a_otherfaction && alliedunit(u, f, HELP_FSTEALTH)) { faction *f = get_otherfaction(a_otherfaction); int result = - (size_t)_snprintf(bufp, size, ", %s (%s)", factionname(f), + _snprintf(bufp, size, ", %s (%s)", factionname(f), factionname(u->faction)); - bytes = (size_t)result; - if (result < 0 || wrptr(&bufp, &size, bytes) != 0) + if (wrptr(&bufp, &size, result) != 0) WARN_STATIC_BUFFER(); } else { - bytes = strlcpy(bufp, ", ", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = strlcpy(bufp, factionname(fv), size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, ", ", size); + bufp = STRLCPY(bufp, factionname(fv), size); } } } } - bytes = strlcpy(bufp, ", ", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, ", ", size); if (u->faction != f && a_fshidden && a_fshidden->data.ca[0] == 1 && effskill(u, SK_STEALTH) >= 6) { - bytes = strlcpy(bufp, "? ", size); + bufp = STRLCPY(bufp, "? ", size); } else { - result = _snprintf(bufp, size, "%d ", u->number); - bytes = (size_t)result; + if (wrptr(&bufp, &size, _snprintf(bufp, size, "%d ", u->number))) + WARN_STATIC_BUFFER(); } - if (result < 0 || wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); pzTmp = get_racename(u->attribs); if (pzTmp) { - bytes = strlcpy(bufp, pzTmp, size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, pzTmp, size); if (u->faction == f && fval(u_race(u), RCF_SHAPESHIFTANY)) { - bytes = strlcpy(bufp, " (", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = strlcpy(bufp, racename(f->locale, u, u_race(u)), size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, " (", size); + bufp = STRLCPY(bufp, racename(f->locale, u, u_race(u)), size); if (size > 1) { strcpy(bufp++, ")"); --size; @@ -578,16 +536,10 @@ size_t size) } else { const race *irace = u_irace(u); - bytes = strlcpy(bufp, racename(f->locale, u, irace), size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, racename(f->locale, u, irace), size); if (u->faction == f && irace != u_race(u)) { - bytes = strlcpy(bufp, " (", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = strlcpy(bufp, racename(f->locale, u, u_race(u)), size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, " (", size); + bufp = STRLCPY(bufp, racename(f->locale, u, u_race(u)), size); if (size > 1) { strcpy(bufp++, ")"); --size; @@ -596,42 +548,26 @@ size_t size) } if (fval(u, UFL_HERO) && (u->faction == f || omniscient(f))) { - bytes = strlcpy(bufp, ", ", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = strlcpy(bufp, LOC(f->locale, "hero"), size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, ", ", size); + bufp = STRLCPY(bufp, LOC(f->locale, "hero"), size); } /* status */ if (u->number && (u->faction == f || telepath_see || isbattle)) { const char *c = hp_status(u); c = c ? LOC(f->locale, c) : 0; - bytes = strlcpy(bufp, ", ", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = strlcpy(bufp, report_kampfstatus(u, f->locale), size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, ", ", size); + bufp = STRLCPY(bufp, report_kampfstatus(u, f->locale), size); if (c || fval(u, UFL_HUNGER)) { - bytes = strlcpy(bufp, " (", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, " (", size); if (c) { - bytes = strlcpy(bufp, c, size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, c, size); } if (fval(u, UFL_HUNGER)) { if (c) { - bytes = strlcpy(bufp, ", ", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, ", ", size); } - bytes = strlcpy(bufp, LOC(f->locale, "unit_hungers"), size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, LOC(f->locale, "unit_hungers"), size); } if (size > 1) { strcpy(bufp++, ")"); @@ -640,29 +576,22 @@ size_t size) } } if (is_guard(u, GUARD_ALL) != 0) { - bytes = strlcpy(bufp, ", ", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = strlcpy(bufp, LOC(f->locale, "unit_guards"), size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, ", ", size); + bufp = STRLCPY(bufp, LOC(f->locale, "unit_guards"), size); } if ((b = usiege(u)) != NULL) { - bytes = strlcpy(bufp, ", belagert ", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = strlcpy(bufp, buildingname(b), size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, ", belagert ", size); + bufp = STRLCPY(bufp, buildingname(b), size); } dh = 0; if (u->faction == f || telepath_see) { skill *sv; for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) { - bytes = spskill(bufp, size, f->locale, u, sv, &dh, 1); - if (wrptr(&bufp, &size, bytes) != 0) + size_t bytes = spskill(bufp, size, f->locale, u, sv, &dh, 1); + assert(bytes <=INT_MAX); + if (wrptr(&bufp, &size, (int)bytes) != 0) WARN_STATIC_BUFFER(); } } @@ -689,26 +618,21 @@ size_t size) report_item(u, itm, f, &ic, NULL, &in, false); if (in == 0 || ic == NULL) continue; - bytes = strlcpy(bufp, ", ", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, ", ", size); if (!dh) { result = _snprintf(bufp, size, "%s: ", LOC(f->locale, "nr_inventory")); - bytes = (size_t)result; - if (result < 0 || wrptr(&bufp, &size, bytes) != 0) + if (wrptr(&bufp, &size, result) != 0) WARN_STATIC_BUFFER(); dh = 1; } if (in == 1) { - bytes = strlcpy(bufp, ic, size); + bufp = STRLCPY(bufp, ic, size); } else { - result = _snprintf(bufp, size, "%d %s", in, ic); - bytes = (size_t)result; + if (wrptr(&bufp, &size, _snprintf(bufp, size, "%d %s", in, ic))) + WARN_STATIC_BUFFER(); } - if (result < 0 || wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); } if (u->faction == f || telepath_see) { @@ -718,8 +642,7 @@ size_t size) quicklist *ql = book->spells; int qi, header, maxlevel = effskill(u, SK_MAGIC); int result = _snprintf(bufp, size, ". Aura %d/%d", get_spellpoints(u), max_spellpoints(u->region, u)); - size_t bytes = (size_t)result; - if (result < 0 || wrptr(&bufp, &size, bytes) != 0) { + if (wrptr(&bufp, &size, result) != 0) { WARN_STATIC_BUFFER(); } @@ -729,19 +652,15 @@ size_t size) int result = 0; if (!header) { result = _snprintf(bufp, size, ", %s: ", LOC(f->locale, "nr_spells")); - bytes = (size_t)result; header = 1; } else { - bytes = strlcpy(bufp, ", ", size); + result = (int)strlcpy(bufp, ", ", size); } - if (result < 0 || wrptr(&bufp, &size, bytes) != 0) { - WARN_STATIC_BUFFER(); - } - bytes = strlcpy(bufp, spell_name(sbe->sp, f->locale), size); - if (wrptr(&bufp, &size, bytes) != 0) { + if (wrptr(&bufp, &size, result) != 0) { WARN_STATIC_BUFFER(); } + bufp = STRLCPY(bufp, spell_name(sbe->sp, f->locale), size); } } @@ -752,8 +671,7 @@ size_t size) if (i != MAXCOMBATSPELLS) { int result = _snprintf(bufp, size, ", %s: ", LOC(f->locale, "nr_combatspells")); - size_t bytes = (size_t)result; - if (result < 0 || wrptr(&bufp, &size, bytes) != 0) + if (wrptr(&bufp, &size, result) != 0) WARN_STATIC_BUFFER(); dh = 0; @@ -763,30 +681,20 @@ size_t size) dh = 1; } else { - bytes = strlcpy(bufp, ", ", size); - if (bytes && wrptr(&bufp, &size, bytes) != 0) { - WARN_STATIC_BUFFER(); - } + bufp = STRLCPY(bufp, ", ", size); } sp = get_combatspell(u, i); if (sp) { int sl = get_combatspelllevel(u, i); - bytes = strlcpy(bufp, spell_name(sp, u->faction->locale), size); - if (bytes && wrptr(&bufp, &size, bytes) != 0) { - WARN_STATIC_BUFFER(); - } - + bufp = STRLCPY(bufp, spell_name(sp, u->faction->locale), size); if (sl > 0) { result = _snprintf(bufp, size, " (%d)", sl); - bytes = (size_t)result; - if (result < 0 || wrptr(&bufp, &size, bytes) != 0) + if (wrptr(&bufp, &size, result) != 0) WARN_STATIC_BUFFER(); } } else { - bytes = strlcpy(bufp, LOC(f->locale, "nr_nospells"), size); - if (bytes && wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, LOC(f->locale, "nr_nospells"), size); } } } @@ -798,8 +706,8 @@ size_t size) keyword_t kwd = getkeyword(ord); if (is_repeated(kwd)) { if (printed < ORDERS_IN_NR) { - bytes = buforder(bufp, size, ord, printed++); - if (wrptr(&bufp, &size, bytes) != 0) + int result = (int)buforder(bufp, size, ord, printed++); + if (wrptr(&bufp, &size, result) != 0) WARN_STATIC_BUFFER(); } else @@ -811,8 +719,8 @@ size_t size) keyword_t kwd = getkeyword(ord); if (is_repeated(kwd)) { if (printed < ORDERS_IN_NR) { - bytes = buforder(bufp, size, ord, printed++); - if (wrptr(&bufp, &size, bytes) != 0) + int result = (int)buforder(bufp, size, ord, printed++); + if (wrptr(&bufp, &size, result) != 0) WARN_STATIC_BUFFER(); } else @@ -825,14 +733,8 @@ size_t size) str = u_description(u, f->locale); if (str) { - bytes = strlcpy(bufp, "; ", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - - bytes = strlcpy(bufp, str, size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - + bufp = STRLCPY(bufp, "; ", size); + bufp = STRLCPY(bufp, str, size); i = str[strlen(str) - 1]; } if (i != '!' && i != '?' && i != '.') { @@ -843,15 +745,9 @@ size_t size) } pzTmp = uprivate(u); if (u->faction == f && pzTmp) { - bytes = strlcpy(bufp, " (Bem: ", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = strlcpy(bufp, pzTmp, size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = strlcpy(bufp, ")", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, " (Bem: ", size); + bufp = STRLCPY(bufp, pzTmp, size); + bufp = STRLCPY(bufp, ")", size); } dh = 0; @@ -877,8 +773,6 @@ const struct unit * u, struct skill * sv, int *dh, int days) { char *bufp = buffer; int i, effsk; - size_t bytes; - size_t tsize = 0; if (!u->number) return 0; @@ -888,65 +782,35 @@ const struct unit * u, struct skill * sv, int *dh, int days) } } - bytes = strlcpy(bufp, ", ", size); - tsize += bytes; - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, ", ", size); if (!*dh) { - bytes = strlcpy(bufp, LOC(lang, "nr_skills"), size); - tsize += bytes; - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - - bytes = strlcpy(bufp, ": ", size); - tsize += bytes; - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - + bufp = STRLCPY(bufp, LOC(lang, "nr_skills"), size); + bufp = STRLCPY(bufp, ": ", size); *dh = 1; } - bytes = strlcpy(bufp, skillname(sv->id, lang), size); - tsize += bytes; - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - - bytes = strlcpy(bufp, " ", size); - tsize += bytes; - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, skillname(sv->id, lang), size); + bufp = STRLCPY(bufp, " ", size); if (sv->id == SK_MAGIC) { sc_mage *mage = get_mage(u); if (mage && mage->magietyp != M_GRAY) { - bytes = - strlcpy(bufp, LOC(lang, mkname("school", + bufp = STRLCPY(bufp, LOC(lang, mkname("school", magic_school[mage->magietyp])), size); - tsize += bytes; - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - - bytes = strlcpy(bufp, " ", size); - tsize += bytes; - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, " ", size); } } if (sv->id == SK_STEALTH && fval(u, UFL_STEALTH)) { i = u_geteffstealth(u); if (i >= 0) { - bytes = slprintf(bufp, size, "%d/", i); - tsize += bytes; - if (wrptr(&bufp, &size, bytes) != 0) + if (wrptr(&bufp, &size, _snprintf(bufp, size, "%d/", i)) != 0) WARN_STATIC_BUFFER(); } } effsk = effskill(u, sv->id); - bytes = slprintf(bufp, size, "%d", effsk); - tsize += bytes; - if (wrptr(&bufp, &size, bytes) != 0) + if (wrptr(&bufp, &size, _snprintf(bufp, size, "%d", effsk)) != 0) WARN_STATIC_BUFFER(); if (u->faction->options & want(O_SHOWSKCHANGE)) { @@ -961,13 +825,11 @@ const struct unit * u, struct skill * sv, int *dh, int days) diff = effsk - oldeff; if (diff != 0) { - bytes = slprintf(bufp, size, " (%s%d)", (diff > 0) ? "+" : "", diff); - tsize += bytes; - if (wrptr(&bufp, &size, bytes) != 0) + if (wrptr(&bufp, &size, _snprintf(bufp, size, " (%s%d)", (diff > 0) ? "+" : "", diff)) != 0) WARN_STATIC_BUFFER(); } } - return tsize; + return bufp-buffer; } void split_paragraph(strlist ** SP, const char *s, unsigned int indent, unsigned int width, char mark) @@ -2327,8 +2189,7 @@ static void eval_resources(struct opstack **stack, const void *userdata) const char *rname = resourcename(res->type, (res->number != 1) ? NMF_PLURAL : 0); int result = _snprintf(bufp, size, "%d %s", res->number, LOC(lang, rname)); - size_t bytes = (size_t)result; - if (result < 0 || wrptr(&bufp, &size, bytes) != 0 || size < sizeof(buf) / 2) { + if (wrptr(&bufp, &size, result) != 0 || size < sizeof(buf) / 2) { WARN_STATIC_BUFFER(); break; } @@ -2367,9 +2228,7 @@ static void eval_regions(struct opstack **stack, const void *userdata) } for (i = begin; i < end; ++i) { const char *rname = (const char *)regionname(regions->regions[i], report); - size_t bytes = strlcpy(bufp, rname, size); - if (bytes && wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + bufp = STRLCPY(bufp, rname, size); if (i + 1 < end && size > 2) { strcat(bufp, ", "); @@ -2403,22 +2262,16 @@ static void eval_trail(struct opstack **stack, const void *userdata) region *r = regions->regions[i]; const char *trail = trailinto(r, lang); const char *rn = f_regionid_s(r, report); - int result = _snprintf(bufp, size, trail, rn); - size_t bytes = (size_t)result; - if (result < 0 || wrptr(&bufp, &size, bytes) != 0) + + if (wrptr(&bufp, &size, _snprintf(bufp, size, trail, rn)) != 0) WARN_STATIC_BUFFER(); if (i + 2 < end) { - bytes = strlcpy(bufp, ", ", size); + bufp = STRLCPY(bufp, ", ", size); } else if (i + 1 < end) { - bytes = strlcpy(bufp, LOC(lang, "list_and"), size); + bufp = STRLCPY(bufp, LOC(lang, "list_and"), size); } - else - bytes = 0; - - if (bytes && wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); } } *bufp = 0; diff --git a/src/util/bsdstring.c b/src/util/bsdstring.c index 037f18eed..96b71b595 100644 --- a/src/util/bsdstring.c +++ b/src/util/bsdstring.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "bsdstring.h" #include "log.h" @@ -66,8 +67,14 @@ char * strlcpy_w(char *dst, const char *src, size_t *siz, const char *err, const { size_t bytes = strlcpy(dst, src, *siz); char * buf = dst; - if (wrptr(&buf, siz, bytes) != 0) - log_warning("%s: static buffer too small in %s:%d\n", err, file, line); + assert(bytes <= INT_MAX); + if (wrptr(&buf, siz, (int)bytes) != 0) { + if (err) { + log_warning("%s: static buffer too small in %s:%d\n", err, file, line); + } else { + log_warning("static buffer too small in %s:%d\n", file, line); + } + } return buf; } diff --git a/src/util/bsdstring.h b/src/util/bsdstring.h index b1538bf4e..dad4d6281 100644 --- a/src/util/bsdstring.h +++ b/src/util/bsdstring.h @@ -20,6 +20,7 @@ size_t slprintf(char * dst, size_t size, const char * format, ...); #define WARN_STATIC_BUFFER_EX(foo) log_warning("%s: static buffer too small in %s:%d\n", (foo), __FILE__, __LINE__) #define WARN_STATIC_BUFFER() log_warning("static buffer too small in %s:%d\n", __FILE__, __LINE__) #define INFO_STATIC_BUFFER() log_info("static buffer too small in %s:%d\n", __FILE__, __LINE__) -#define STRLCPY(dst, src, siz, err) strlcpy_w((dst), (src), (siz), (err), __FILE__, __LINE__) +#define STRLCPY(dst, src, siz) strlcpy_w((dst), (src), &(siz), 0, __FILE__, __LINE__) +#define STRLCPY_EX(dst, src, siz, err) strlcpy_w((dst), (src), (siz), (err), __FILE__, __LINE__) #endif