From 686bbdbf698ac7502805b2c6836b6b01c148deeb Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 10 Dec 2017 12:23:28 +0100 Subject: [PATCH 01/14] solve helpers.c without bsdstring --- src/helpers.c | 148 ++++++++++++++++++++++++-------------------------- 1 file changed, 72 insertions(+), 76 deletions(-) diff --git a/src/helpers.c b/src/helpers.c index 897e39720..6924dbf61 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -17,7 +17,6 @@ without prior permission by the authors of Eressea. #include #include -#include #include #include #include @@ -52,66 +51,64 @@ lua_giveitem(unit * s, unit * d, const item_type * itype, int n, struct order *o { lua_State *L = (lua_State *)global.vm_state; char fname[64]; - int result = -1; + int result = -1, len; const char *iname = itype->rtype->_name; assert(s != NULL); - strlcpy(fname, iname, sizeof(fname)); - strlcat(fname, "_give", sizeof(fname)); + len = snprintf(fname, sizeof(fname), "%s_give", iname); + if (len > 0 && (size_t)len < sizeof(fname)) { + lua_getglobal(L, fname); + if (lua_isfunction(L, -1)) { + tolua_pushusertype(L, s, TOLUA_CAST "unit"); + tolua_pushusertype(L, d, TOLUA_CAST "unit"); + tolua_pushstring(L, iname); + lua_pushinteger(L, n); - lua_getglobal(L, fname); - if (lua_isfunction(L, -1)) { - tolua_pushusertype(L, s, TOLUA_CAST "unit"); - tolua_pushusertype(L, d, TOLUA_CAST "unit"); - tolua_pushstring(L, iname); - lua_pushinteger(L, n); - - if (lua_pcall(L, 4, 1, 0) != 0) { - const char *error = lua_tostring(L, -1); - log_error("unit %s calling '%s': %s.\n", unitname(s), fname, error); - lua_pop(L, 1); + if (lua_pcall(L, 4, 1, 0) != 0) { + const char *error = lua_tostring(L, -1); + log_error("unit %s calling '%s': %s.\n", unitname(s), fname, error); + lua_pop(L, 1); + } + else { + result = (int)lua_tonumber(L, -1); + lua_pop(L, 1); + } } else { - result = (int)lua_tonumber(L, -1); + log_error("unit %s trying to call '%s' : not a function.\n", unitname(s), fname); lua_pop(L, 1); } } - else { - log_error("unit %s trying to call '%s' : not a function.\n", unitname(s), fname); - lua_pop(L, 1); - } - return result; } static int limit_resource_lua(const region * r, const resource_type * rtype) { char fname[64]; - int result = -1; + int result = -1, len; lua_State *L = (lua_State *)global.vm_state; - strlcpy(fname, rtype->_name, sizeof(fname)); - strlcat(fname, "_limit", sizeof(fname)); + len = snprintf(fname, sizeof(fname), "%s_limit", rtype->_name); + if (len > 0 && (size_t)len < sizeof(fname)) { + lua_getglobal(L, fname); + if (lua_isfunction(L, -1)) { + tolua_pushusertype(L, (void *)r, TOLUA_CAST "region"); - lua_getglobal(L, fname); - if (lua_isfunction(L, -1)) { - tolua_pushusertype(L, (void *)r, TOLUA_CAST "region"); - - if (lua_pcall(L, 1, 1, 0) != 0) { - const char *error = lua_tostring(L, -1); - log_error("limit(%s) calling '%s': %s.\n", regionname(r, NULL), fname, error); - lua_pop(L, 1); + if (lua_pcall(L, 1, 1, 0) != 0) { + const char *error = lua_tostring(L, -1); + log_error("limit(%s) calling '%s': %s.\n", regionname(r, NULL), fname, error); + lua_pop(L, 1); + } + else { + result = (int)lua_tonumber(L, -1); + lua_pop(L, 1); + } } else { - result = (int)lua_tonumber(L, -1); + log_error("limit(%s) calling '%s': not a function.\n", regionname(r, NULL), fname); lua_pop(L, 1); } } - else { - log_error("limit(%s) calling '%s': not a function.\n", regionname(r, NULL), fname); - lua_pop(L, 1); - } - return result; } @@ -120,25 +117,26 @@ produce_resource_lua(region * r, const resource_type * rtype, int norders) { lua_State *L = (lua_State *)global.vm_state; char fname[64]; + int len; - strlcpy(fname, rtype->_name, sizeof(fname)); - strlcat(fname, "_produce", sizeof(fname)); + len = snprintf(fname, sizeof(fname), "%s_produce", rtype->_name); + if (len > 0 && (size_t)len < sizeof(fname)) { + lua_getglobal(L, fname); + if (lua_isfunction(L, -1)) { + tolua_pushusertype(L, (void *)r, TOLUA_CAST "region"); + lua_pushinteger(L, norders); - lua_getglobal(L, fname); - if (lua_isfunction(L, -1)) { - tolua_pushusertype(L, (void *)r, TOLUA_CAST "region"); - lua_pushinteger(L, norders); - - if (lua_pcall(L, 2, 0, 0) != 0) { - const char *error = lua_tostring(L, -1); - log_error("produce(%s) calling '%s': %s.\n", regionname(r, NULL), fname, error); + if (lua_pcall(L, 2, 0, 0) != 0) { + const char *error = lua_tostring(L, -1); + log_error("produce(%s) calling '%s': %s.\n", regionname(r, NULL), fname, error); + lua_pop(L, 1); + } + } + else { + log_error("produce(%s) calling '%s': not a function.\n", regionname(r, NULL), fname); lua_pop(L, 1); } } - else { - log_error("produce(%s) calling '%s': not a function.\n", regionname(r, NULL), fname); - lua_pop(L, 1); - } } static void push_param(lua_State * L, char c, spllprm * param) @@ -216,32 +214,31 @@ static int lua_changeresource(unit * u, const struct resource_type *rtype, int delta) { lua_State *L = (lua_State *)global.vm_state; - int result = -1; + int len, result = -1; char fname[64]; - strlcpy(fname, rtype->_name, sizeof(fname)); - strlcat(fname, "_changeresource", sizeof(fname)); - - lua_getglobal(L, fname); - if (lua_isfunction(L, -1)) { - tolua_pushusertype(L, u, TOLUA_CAST "unit"); - lua_pushinteger(L, delta); - - if (lua_pcall(L, 2, 1, 0) != 0) { - const char *error = lua_tostring(L, -1); - log_error("change(%s) calling '%s': %s.\n", unitname(u), fname, error); - lua_pop(L, 1); + len = snprintf(fname, sizeof(fname), "%s_changeresource", rtype->_name); + if (len > 0 && (size_t)len < sizeof(fname)) { + lua_getglobal(L, fname); + if (lua_isfunction(L, -1)) { + tolua_pushusertype(L, u, TOLUA_CAST "unit"); + lua_pushinteger(L, delta); + + if (lua_pcall(L, 2, 1, 0) != 0) { + const char *error = lua_tostring(L, -1); + log_error("change(%s) calling '%s': %s.\n", unitname(u), fname, error); + lua_pop(L, 1); + } + else { + result = (int)lua_tonumber(L, -1); + lua_pop(L, 1); + } } else { - result = (int)lua_tonumber(L, -1); + log_error("change(%s) calling '%s': not a function.\n", unitname(u), fname); lua_pop(L, 1); } } - else { - log_error("change(%s) calling '%s': not a function.\n", unitname(u), fname); - lua_pop(L, 1); - } - return result; } @@ -250,13 +247,12 @@ static int use_item_lua(unit *u, const item_type *itype, int amount, struct order *ord) { lua_State *L = (lua_State *)global.vm_state; - int result = 0; + int len, result = 0; char fname[64]; int (*callout)(unit *, const item_type *, int, struct order *); - strlcpy(fname, "use_", sizeof(fname)); - strlcat(fname, itype->rtype->_name, sizeof(fname)); - + len = snprintf(fname, sizeof(fname), "use_%s", itype->rtype->_name); + if (len > 0 && (size_t)len < sizeof(fname)) { callout = (int(*)(unit *, const item_type *, int, struct order *))get_function(fname); if (callout) { return callout(u, itype, amount, ord); @@ -286,7 +282,7 @@ use_item_lua(unit *u, const item_type *itype, int amount, struct order *ord) log_error("no such callout: %s", fname); } log_error("use(%s) calling '%s': not a function.\n", unitname(u), fname); - + } return result; } From 2ca236e68cb355f9961c0b4d5a4de4082fc367b1 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 10 Dec 2017 20:54:02 +0100 Subject: [PATCH 02/14] Add lua tests for ROUTE. --- scripts/tests/common.lua | 22 ++++++++++++++++++++++ src/bind_unit.c | 25 +++++++++++++++++++++++++ src/economy.c | 10 +++++----- src/modules/autoseed.c | 5 +---- 4 files changed, 53 insertions(+), 9 deletions(-) diff --git a/scripts/tests/common.lua b/scripts/tests/common.lua index c186107c4..655c210fa 100644 --- a/scripts/tests/common.lua +++ b/scripts/tests/common.lua @@ -1112,3 +1112,25 @@ function test_build_castle() assert_equal(1, u.building.size) assert_equal(u.building.name, "Burg") end + +function test_route() + local r1 = region.create(0, 0, "plain") + local r2 = region.create(1, 0, "plain") + local f = faction.create("human", "route@example.com") + local u = unit.create(f, r1, 1) + u:add_order("ROUTE O W P") + process_orders() + assert_equal("ROUTE West PAUSE Ost", u:get_order(0)) + assert_equal(r2, u.region) +end + +function test_route_pause() + local r1 = region.create(0, 0, "plain") + local r2 = region.create(1, 0, "plain") + local f = faction.create("human", "route@example.com") + local u = unit.create(f, r1, 1) + u:add_order("ROUTE P O W") + process_orders() + assert_equal("ROUTE P O W", u:get_order(0)) + assert_equal(r1, u.region) +end diff --git a/src/bind_unit.c b/src/bind_unit.c index a7e8f61ab..f48965bfc 100644 --- a/src/bind_unit.c +++ b/src/bind_unit.c @@ -718,6 +718,30 @@ static int tolua_unit_set_region(lua_State * L) return 0; } +static int tolua_unit_get_order(lua_State * L) +{ + unit *self = (unit *)tolua_tousertype(L, 1, 0); + int index = (int)tolua_tonumber(L, 2, -1); + order *ord = NULL; + if (index < 0) { + ord = self->thisorder; + } + else { + int i; + ord = self->orders; + for (i = 0; ord && i != index; ++i) { + ord = ord->next; + } + } + if (ord) { + char buffer[1024]; + get_command(ord, self->faction->locale, buffer, sizeof(buffer)); + lua_pushstring(L, buffer); + return 1; + } + return 0; +} + static int tolua_unit_add_order(lua_State * L) { unit *self = (unit *)tolua_tousertype(L, 1, 0); @@ -972,6 +996,7 @@ void tolua_unit_open(lua_State * L) tolua_variable(L, TOLUA_CAST "weight", tolua_unit_get_weight, 0); tolua_variable(L, TOLUA_CAST "capacity", tolua_unit_get_capacity, 0); + tolua_function(L, TOLUA_CAST "get_order", tolua_unit_get_order); tolua_function(L, TOLUA_CAST "add_order", tolua_unit_add_order); tolua_function(L, TOLUA_CAST "clear_orders", tolua_unit_clear_orders); tolua_function(L, TOLUA_CAST "get_curse", tolua_unit_get_curse); diff --git a/src/economy.c b/src/economy.c index 759d60cb8..c7ab2247d 100644 --- a/src/economy.c +++ b/src/economy.c @@ -64,7 +64,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include #include -#include #include #include #include @@ -248,6 +247,7 @@ void add_recruits(unit * u, int number, int wanted) if (number > 0) { unit *unew; char equipment[64]; + int len; if (u->number == 0) { set_number(u, number); @@ -258,10 +258,10 @@ void add_recruits(unit * u, int number, int wanted) unew = create_unit(r, u->faction, number, u_race(u), 0, NULL, u); } - strlcpy(equipment, "new_", sizeof(equipment)); - strlcat(equipment, u_race(u)->_name, sizeof(equipment)); - equip_unit(unew, get_equipment(equipment)); - + len = snprintf(equipment, sizeof(equipment), "new_%s", u_race(u)->_name); + if (len > 0 && (size_t)len < sizeof(equipment)) { + equip_unit(unew, get_equipment(equipment)); + } if (unew != u) { transfermen(unew, u, unew->number); remove_unit(&r->units, unew); diff --git a/src/modules/autoseed.c b/src/modules/autoseed.c index 1e877459e..a574f2dfb 100644 --- a/src/modules/autoseed.c +++ b/src/modules/autoseed.c @@ -33,7 +33,6 @@ /* util includes */ #include #include -#include #include #include #include @@ -166,9 +165,7 @@ newfaction *read_newfactions(const char *filename) break; } if (password[0] == '\0') { - size_t sz; - sz = strlcpy(password, itoa36(rng_int()), sizeof(password)); - sz += strlcat(password, itoa36(rng_int()), sizeof(password)); + snprintf(password, sizeof(password), "%s%s", itoa36(rng_int()), itoa36(rng_int())); } for (f = factions; f; f = f->next) { if (strcmp(faction_getemail(f), email) == 0 && f->age < MINAGE_MULTI) { From 691dde596027b7d184b97e934c42ac01c0b5c9c2 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 11 Dec 2017 16:24:06 +0100 Subject: [PATCH 03/14] unit test ROUTE. --- scripts/tests/common.lua | 13 +++++++++++ src/direction.c | 9 ++++++++ src/direction.h | 2 ++ src/move.c | 46 +++++++++++++++++--------------------- src/move.test.c | 48 ++++++++++++++++++++++++++++++++++++++++ src/tests.c | 2 ++ 6 files changed, 94 insertions(+), 26 deletions(-) diff --git a/scripts/tests/common.lua b/scripts/tests/common.lua index 655c210fa..d0a419109 100644 --- a/scripts/tests/common.lua +++ b/scripts/tests/common.lua @@ -1124,6 +1124,19 @@ function test_route() assert_equal(r2, u.region) end +function test_route_horse() + local r1 = region.create(0, 0, "plain") + local r2 = region.create(1, 0, "plain") + local f = faction.create("human", "route@example.com") + local u = unit.create(f, r1, 1) + u:add_order("ROUTE O P W P") + u:add_item('horse', 1) + u:set_skill('riding', 1) + process_orders() + assert_equal("ROUTE West PAUSE Ost PAUSE", u:get_order(0)) + assert_equal(r2, u.region) +end + function test_route_pause() local r1 = region.create(0, 0, "plain") local r2 = region.create(1, 0, "plain") diff --git a/src/direction.c b/src/direction.c index 5e2333bbe..13feff13b 100644 --- a/src/direction.c +++ b/src/direction.c @@ -8,6 +8,15 @@ #include +const char *shortdirections[MAXDIRECTIONS] = { + "dir_nw", + "dir_ne", + "dir_east", + "dir_se", + "dir_sw", + "dir_west" +}; + void init_direction(const struct locale *lang, direction_t dir, const char *str) { void **tokens = get_translations(lang, UT_DIRECTIONS); variant token; diff --git a/src/direction.h b/src/direction.h index 14ced4c1c..724878663 100644 --- a/src/direction.h +++ b/src/direction.h @@ -21,6 +21,8 @@ extern "C" NODIRECTION = -1 } direction_t; + extern const char *shortdirections[MAXDIRECTIONS]; + direction_t get_direction(const char *s, const struct locale *); void init_directions(struct locale *lang); void init_direction(const struct locale *lang, direction_t dir, const char *str); diff --git a/src/move.c b/src/move.c index 798c3da27..592ca606f 100644 --- a/src/move.c +++ b/src/move.c @@ -1042,15 +1042,6 @@ int movewhere(const unit * u, const char *token, region * r, region ** resultp) return E_MOVE_OK; } -static const char *shortdirections[MAXDIRECTIONS] = { - "dir_nw", - "dir_ne", - "dir_east", - "dir_se", - "dir_sw", - "dir_west" -}; - static void cycle_route(order * ord, unit * u, int gereist) { int cm = 0; @@ -1063,13 +1054,11 @@ static void cycle_route(order * ord, unit * u, int gereist) order *norder; size_t size = sizeof(tail) - 1; - if (getkeyword(ord) != K_ROUTE) - return; + assert(getkeyword(ord) == K_ROUTE); tail[0] = '\0'; + neworder[0] = '\0'; + init_order(ord, u->faction->locale); - init_order_depr(ord); - - neworder[0] = 0; for (cm = 0;; ++cm) { const char *s; const struct locale *lang = u->faction->locale; @@ -1092,6 +1081,7 @@ static void cycle_route(order * ord, unit * u, int gereist) assert(!pause); if (!pause) { const char *loc = LOC(lang, shortdirections[d]); + assert(loc); if (bufp != tail) { bufp = STRLCPY_EX(bufp, " ", &size, "cycle_route"); } @@ -1371,7 +1361,7 @@ static void make_route(unit * u, order * ord, region_list ** routep) current = next; s = gettoken(token, sizeof(token)); error = movewhere(u, s, current, &next); - if (error) { + if (error != E_MOVE_OK) { message *msg = movement_error(u, s, ord, error); if (msg != NULL) { add_message(&u->faction->msgs, msg); @@ -1606,7 +1596,9 @@ static const region_list *travel_route(unit * u, int walkmode; setguard(u, false); - cycle_route(ord, u, steps); + if (getkeyword(ord) == K_ROUTE) { + cycle_route(ord, u, steps); + } if (mode == TRAVEL_RUNNING) { walkmode = 0; @@ -1936,7 +1928,9 @@ static void sail(unit * u, order * ord, region_list ** routep, bool drifting) unit *harbourmaster; /* nachdem alle Richtungen abgearbeitet wurden, und alle Einheiten * transferiert wurden, kann der aktuelle Befehl gelöscht werden. */ - cycle_route(ord, u, step); + if (getkeyword(ord) == K_ROUTE) { + cycle_route(ord, u, step); + } set_order(&u->thisorder, NULL); set_coast(sh, last_point, current_point); @@ -2026,7 +2020,7 @@ static const region_list *travel_i(unit * u, const region_list * route_begin, region *r = u->region; int mp; if (u->building && !can_leave(u)) { - cmistake(u, u->thisorder, 150, MSG_MOVE); + cmistake(u, ord, 150, MSG_MOVE); return route_begin; } switch (canwalk(u)) { @@ -2115,7 +2109,7 @@ static const region_list *travel_i(unit * u, const region_list * route_begin, /** traveling without ships * walking, flying or riding units use this function */ -static void travel(unit * u, region_list ** routep) +static void travel(unit * u, order *ord, region_list ** routep) { region *r = u->region; region_list *route_begin; @@ -2129,7 +2123,7 @@ static void travel(unit * u, region_list ** routep) ship *sh = u->ship; if (!can_leave(u)) { - cmistake(u, u->thisorder, 150, MSG_MOVE); + cmistake(u, ord, 150, MSG_MOVE); return; } @@ -2142,28 +2136,28 @@ static void travel(unit * u, region_list ** routep) if (sh) { unit *guard = is_guarded(r, u); if (guard) { - ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, + ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "region_guarded", "guard", guard)); return; } } if (u->ship && u_race(u)->flags & RCF_SWIM) { - cmistake(u, u->thisorder, 143, MSG_MOVE); + cmistake(u, ord, 143, MSG_MOVE); return; } } else if (u->ship && fval(u->ship, SF_MOVED)) { /* die Einheit ist auf einem Schiff, das sich bereits bewegt hat */ - cmistake(u, u->thisorder, 13, MSG_MOVE); + cmistake(u, ord, 13, MSG_MOVE); return; } - make_route(u, u->thisorder, routep); + make_route(u, ord, routep); route_begin = *routep; if (route_begin) { /* und ab die post: */ - travel_i(u, route_begin, NULL, u->thisorder, TRAVEL_NORMAL, &followers); + travel_i(u, route_begin, NULL, ord, TRAVEL_NORMAL, &followers); /* followers */ while (followers != NULL) { @@ -2204,7 +2198,7 @@ void move_cmd(unit * u, order * ord) sail(u, ord, &route, drifting); } else { - travel(u, &route); + travel(u, ord, &route); } fset(u, UFL_LONGACTION | UFL_NOTMOVING); diff --git a/src/move.test.c b/src/move.test.c index 7095da855..edb070bfb 100644 --- a/src/move.test.c +++ b/src/move.test.c @@ -545,6 +545,52 @@ static void test_movement_speed(CuTest *tc) { test_cleanup(); } +static void test_route_cycle(CuTest *tc) { + unit *u; + region *r; + struct locale *lang; + char buffer[32]; + + test_setup(); + test_create_region(1, 0, NULL); + r = test_create_region(2, 0, NULL); + lang = test_create_locale(); + CuAssertPtrNotNull(tc, LOC(lang, shortdirections[D_WEST])); + u = test_create_unit(test_create_faction(NULL), r); + u->faction->locale = lang; + CuAssertIntEquals(tc, RCF_WALK, u->_race->flags & RCF_WALK); + u->orders = create_order(K_ROUTE, u->faction->locale, "WEST EAST NW"); + CuAssertStrEquals(tc, "route WEST EAST NW", get_command(u->orders, lang, buffer, sizeof(buffer))); + init_order(u->orders, u->faction->locale); + move_cmd(u, u->orders); + CuAssertIntEquals(tc, 1, u->region->x); + CuAssertStrEquals(tc, "route east nw west", get_command(u->orders, lang, buffer, sizeof(buffer))); + test_cleanup(); +} + +static void test_route_pause(CuTest *tc) { + unit *u; + region *r; + struct locale *lang; + char buffer[32]; + + test_setup(); + test_create_region(1, 0, NULL); + r = test_create_region(2, 0, NULL); + lang = test_create_locale(); + CuAssertPtrNotNull(tc, LOC(lang, shortdirections[D_WEST])); + u = test_create_unit(test_create_faction(NULL), r); + u->faction->locale = lang; + CuAssertIntEquals(tc, RCF_WALK, u->_race->flags & RCF_WALK); + u->orders = create_order(K_ROUTE, u->faction->locale, "PAUSE EAST NW"); + CuAssertStrEquals(tc, "route PAUSE EAST NW", get_command(u->orders, lang, buffer, sizeof(buffer))); + init_order(u->orders, u->faction->locale); + move_cmd(u, u->orders); + CuAssertIntEquals(tc, 2, u->region->x); + CuAssertStrEquals(tc, "route PAUSE EAST NW", get_command(u->orders, lang, buffer, sizeof(buffer))); + test_cleanup(); +} + CuSuite *get_move_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -570,5 +616,7 @@ CuSuite *get_move_suite(void) SUITE_ADD_TEST(suite, test_ship_damage_overload); SUITE_ADD_TEST(suite, test_follow_ship_msg); SUITE_ADD_TEST(suite, test_drifting_ships); + SUITE_ADD_TEST(suite, test_route_cycle); + SUITE_ADD_TEST(suite, test_route_pause); return suite; } diff --git a/src/tests.c b/src/tests.c index d07124af3..70f006ef6 100644 --- a/src/tests.c +++ b/src/tests.c @@ -44,6 +44,7 @@ struct race *test_create_race(const char *name) rc->maintenance = 10; rc->hitpoints = 20; rc->maxaura = 100; + rc->flags |= RCF_WALK; rc->ec_flags |= ECF_GETITEM; rc->battle_flags = BF_EQUIPMENT; return rc; @@ -120,6 +121,7 @@ struct locale * test_create_locale(void) { locale_setstring(loc, alliance_kwd[i], alliance_kwd[i]); } for (i = 0; i != MAXDIRECTIONS; ++i) { + locale_setstring(loc, shortdirections[i], shortdirections[i] + 4); locale_setstring(loc, directions[i], directions[i]); init_direction(loc, i, directions[i]); init_direction(loc, i, coasts[i] + 7); From 9f391039b5b78b4458752281852fc90bc9792cce Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 11 Dec 2017 18:20:21 +0100 Subject: [PATCH 04/14] more bsdstring removal, str_replace, unit tests. --- res/core/de/strings.xml | 4 ++-- src/battle.c | 8 ++++---- src/creport.c | 8 ++++---- src/gmtool.c | 6 +++--- src/kernel/alliance.c | 4 ++-- src/kernel/building.c | 6 +++--- src/kernel/connection.c | 10 ++++++---- src/kernel/order.c | 2 +- src/kernel/unit.c | 7 ++----- src/util/base36.c | 24 +++++++++++++++++------- src/util/base36.h | 12 ++++++++---- src/util/language.c | 10 +++++----- src/util/message.c | 4 ++-- src/util/strings.c | 37 +++++++++++++++++++++++++++++++++++-- src/util/strings.h | 5 +++-- src/util/strings.test.c | 33 ++++++++++++++++++++++++--------- 16 files changed, 121 insertions(+), 59 deletions(-) diff --git a/res/core/de/strings.xml b/res/core/de/strings.xml index ea4acf758..b06ff0445 100644 --- a/res/core/de/strings.xml +++ b/res/core/de/strings.xml @@ -7337,8 +7337,8 @@ - eine zu %d%% vollendete Straße - a road that is %d%% complete + eine zu $percent%% vollendete Straße + a road that is $percent% complete diff --git a/src/battle.c b/src/battle.c index a58b0ab63..c12e6d46e 100644 --- a/src/battle.c +++ b/src/battle.c @@ -189,7 +189,7 @@ static char *sidename(side * s) static char sidename_buf[4][SIDENAMEBUFLEN]; /* STATIC_RESULT: used for return, not across calls */ bufno = bufno % 4; - strlcpy(sidename_buf[bufno], factionname(s->stealthfaction ? s->stealthfaction : s->faction), SIDENAMEBUFLEN); + strncpy(sidename_buf[bufno], factionname(s->stealthfaction ? s->stealthfaction : s->faction), SIDENAMEBUFLEN); return sidename_buf[bufno++]; } @@ -2886,10 +2886,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); + strlcpy(bufp, ", ", size); } if (lastf) { - bufp = STRLCPY(bufp, lastf, size); + strlcpy(bufp, lastf, size); first = true; } if (seematrix(f, s)) @@ -3579,7 +3579,7 @@ static int battle_report(battle * b) if (komma) { bufp = STRLCPY(bufp, ", ", size); } - slprintf(buffer, sizeof(buffer), "%s %2d(%s): ", + snprintf(buffer, sizeof(buffer), "%s %2d(%s): ", loc_army, army_index(s), abbrev); bufp = STRLCPY(bufp, buffer, size); diff --git a/src/creport.c b/src/creport.c index 89cf4c9ce..3f3e1bfb8 100644 --- a/src/creport.c +++ b/src/creport.c @@ -516,7 +516,7 @@ static void report_crtypes(FILE * F, const struct locale *lang) assert(hash > 0); fprintf(F, "MESSAGETYPE %u\n", hash); fputc('\"', F); - fputs(escape_string(nrt_string(nrt), buffer, sizeof(buffer)), F); + fputs(str_escape(nrt_string(nrt), buffer, sizeof(buffer)), F); fputs("\";text\n", F); fprintf(F, "\"%s\";section\n", nrt_section(nrt)); } @@ -1067,7 +1067,7 @@ static void cr_reportspell(FILE * F, spell * sp, int level, const struct locale const char *name = translate(mkname("spell", sp->sname), spell_name(sp, lang)); - fprintf(F, "ZAUBER %d\n", hashstring(sp->sname)); + fprintf(F, "ZAUBER %d\n", str_hash(sp->sname)); fprintf(F, "\"%s\";name\n", name); fprintf(F, "%d;level\n", level); fprintf(F, "%d;rank\n", sp->rank); @@ -1115,7 +1115,7 @@ static char *cr_output_resource(char *buf, const resource_type *rtype, assert(rtype); name = resourcename(rtype, NMF_PLURAL); assert(name); - buf += sprintf(buf, "RESOURCE %u\n", hashstring(rtype->_name)); + buf += sprintf(buf, "RESOURCE %u\n", str_hash(rtype->_name)); tname = LOC(loc, name); assert(tname); tname = translate(name, tname); @@ -1663,7 +1663,7 @@ report_computer(const char *filename, report_context * ctx, const char *bom) if (ptype == NULL) continue; ch = resourcename(ptype->itype->rtype, 0); - fprintf(F, "TRANK %d\n", hashstring(ch)); + fprintf(F, "TRANK %d\n", str_hash(ch)); fprintf(F, "\"%s\";Name\n", translate(ch, LOC(f->locale, ch))); fprintf(F, "%d;Stufe\n", ptype->level); diff --git a/src/gmtool.c b/src/gmtool.c index fcb8cff8b..1fba47be6 100644 --- a/src/gmtool.c +++ b/src/gmtool.c @@ -50,7 +50,6 @@ #include #include #include -#include #include #include @@ -58,6 +57,7 @@ #include #include #include +#include #include static int g_quit; @@ -1228,7 +1228,7 @@ static void handlekey(state * st, int c) else if (findmode == 'F') { faction *f = select_faction(st); if (f != NULL) { - strlcpy(locate, itoa36(f->no), sizeof(locate)); + itoab_r(f->no, 36, locate, sizeof(locate)); findmode = 'f'; } else { @@ -1254,7 +1254,7 @@ static void handlekey(state * st, int c) region *first = (mr && mr->r && mr->r->next) ? mr->r->next : regions; if (findmode == 'f') { - slprintf(sbuffer, sizeof(sbuffer), "find-faction: %s", locate); + snprintf(sbuffer, sizeof(sbuffer), "find-faction: %s", locate); statusline(st->wnd_status->handle, sbuffer); f = findfaction(atoi36(locate)); if (f == NULL) { diff --git a/src/kernel/alliance.c b/src/kernel/alliance.c index f0cdf3bbd..ba3929f1f 100644 --- a/src/kernel/alliance.c +++ b/src/kernel/alliance.c @@ -28,7 +28,6 @@ without prior permission by the authors of Eressea. /* util includes */ #include #include -#include #include #include #include @@ -40,6 +39,7 @@ without prior permission by the authors of Eressea. #include #include #include +#include alliance *alliances = NULL; @@ -422,7 +422,7 @@ const char *alliancename(const alliance * al) char *ibuf = idbuf[(++nextbuf) % 8]; if (al && al->name) { - slprintf(ibuf, sizeof(idbuf[0]), "%s (%s)", al->name, itoa36(al->id)); + snprintf(ibuf, sizeof(idbuf[0]), "%s (%s)", al->name, itoa36(al->id)); } else { return NULL; diff --git a/src/kernel/building.c b/src/kernel/building.c index ea01fe665..26d261e97 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -38,7 +38,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include #include -#include #include #include #include @@ -54,6 +53,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* libc includes */ #include #include +#include #include #include @@ -372,7 +372,7 @@ building *new_building(const struct building_type * btype, region * r, bname = parameters[P_GEBAEUDE]; } assert(bname); - slprintf(buffer, sizeof(buffer), "%s %s", bname, itoa36(b->no)); + snprintf(buffer, sizeof(buffer), "%s %s", bname, itoa36(b->no)); b->name = strdup(bname); return b; } @@ -489,7 +489,7 @@ int bt_effsize(const building_type * btype, const building * b, int bsize) const char *write_buildingname(const building * b, char *ibuf, size_t size) { - slprintf(ibuf, size, "%s (%s)", b->name, itoa36(b->no)); + snprintf(ibuf, size, "%s (%s)", b->name, itoa36(b->no)); return ibuf; } diff --git a/src/kernel/connection.c b/src/kernel/connection.c index b630429fe..2cae4ec8f 100644 --- a/src/kernel/connection.c +++ b/src/kernel/connection.c @@ -25,19 +25,21 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "unit.h" #include -#include +#include #include #include #include -#include #include +#include +#include #include /* libc includes */ #include #include #include +#include #include int nextborder = 0; @@ -514,8 +516,8 @@ static const char *b_nameroad(const connection * b, const region * r, else { int percent = MAX(1, 100 * local / r->terrain->max_road); if (local) { - slprintf(buffer, sizeof(buffer), LOC(f->locale, mkname("border", - "a_road_percent")), percent); + const char *temp = LOC(f->locale, mkname("border", "a_road_percent")); + str_replace(buffer, sizeof(buffer), temp, "$percent", itoa10(percent)); } else { return LOC(f->locale, mkname("border", "a_road_connection")); diff --git a/src/kernel/order.c b/src/kernel/order.c index baf26f615..605f44be9 100644 --- a/src/kernel/order.c +++ b/src/kernel/order.c @@ -170,7 +170,7 @@ int stream_order(struct stream *out, const struct order *ord, const struct local char obuf[1024]; swrite(" ", 1, 1, out); if (escape) { - text = escape_string(text, obuf, sizeof(obuf)); + text = str_escape(text, obuf, sizeof(obuf)); } swrite(text, 1, strlen(text), out); } diff --git a/src/kernel/unit.c b/src/kernel/unit.c index ee4da958c..87ccd5944 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -51,7 +51,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include #include -#include #include #include #include @@ -1458,9 +1457,7 @@ void default_name(const unit *u, char name[], int len) { else { result = parameters[P_UNIT]; } - strlcpy(name, result, len); - strlcat(name, " ", len); - strlcat(name, itoa36(u->no), len); + snprintf(name, len, "%s %s", result, itoa36(u->no)); } void name_unit(unit * u) @@ -1874,7 +1871,7 @@ static int nextbuf = 0; char *write_unitname(const unit * u, char *buffer, size_t size) { const char * name = unit_getname(u); - slprintf(buffer, size, "%s (%s)", name, itoa36(u->no)); + snprintf(buffer, size, "%s (%s)", name, itoa36(u->no)); buffer[size - 1] = 0; return buffer; } diff --git a/src/util/base36.c b/src/util/base36.c index 221ece870..ef7c38371 100644 --- a/src/util/base36.c +++ b/src/util/base36.c @@ -52,16 +52,14 @@ int atoi36(const char *str) return i * sign; } -const char *itoab(int i, int base) +const char *itoab_r(int i, int base, char *s, size_t len) { - static char sstr[80]; - char *s, *dst; + char *dst; static int index = 0; /* STATIC_XCALL: used across calls */ - s = sstr + (index * 20); - index = (index + 1) & 3; /* quick for % 4 */ - dst = s + 19; - (*dst--) = 0; + assert(len > 2); + dst = s + len - 2; + *dst = 0; if (i != 0) { int neg = 0; @@ -101,6 +99,18 @@ const char *itoab(int i, int base) return dst; } +const char *itoab(int i, int base) +{ + static char sstr[80]; + char *s; + static int index = 0; /* STATIC_XCALL: used across calls */ + + s = sstr + (index * 20); + index = (index + 1) & 3; /* quick for % 4 */ + + return itoab_r(i, base, s, 20); +} + const char *itoa36(int i) { return itoab(i, 36); diff --git a/src/util/base36.h b/src/util/base36.h index 650538219..804952ab7 100644 --- a/src/util/base36.h +++ b/src/util/base36.h @@ -18,15 +18,19 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #ifndef H_UTIL_BASE36 #define H_UTIL_BASE36 + +#include + #ifdef __cplusplus extern "C" { #endif + const char *itoab_r(int i, int base, char *result, size_t len); + const char *itoab(int i, int base); + const char *itoa36(int i); + const char *itoa10(int i); extern int atoi36(const char *s); - extern const char *itoab(int i, int base); - extern const char *itoa36(int i); - extern const char *itoa10(int i); - extern int i10toi36(int i); + int i10toi36(int i); #ifdef __cplusplus } diff --git a/src/util/language.c b/src/util/language.c index a1cda4d2f..8cd6188d2 100644 --- a/src/util/language.c +++ b/src/util/language.c @@ -56,7 +56,7 @@ unsigned int locale_index(const locale * lang) locale *get_locale(const char *name) { - unsigned int hkey = hashstring(name); + unsigned int hkey = str_hash(name); locale *l = locales; while (l && l->hashkey != hkey) l = l->next; @@ -68,7 +68,7 @@ static unsigned int nextlocaleindex = 0; locale *get_or_create_locale(const char *name) { locale *l; - unsigned int hkey = hashstring(name); + unsigned int hkey = str_hash(name); locale **lp = &locales; if (!locales) { @@ -120,7 +120,7 @@ void make_locales(const char *str) const char *locale_getstring(const locale * lang, const char *key) { - unsigned int hkey = hashstring(key); + unsigned int hkey = str_hash(key); unsigned int id = hkey & (SMAXHASH - 1); const struct locale_str *find; @@ -150,7 +150,7 @@ const char *locale_string(const locale * lang, const char *key, bool warn) assert(key); if (key != NULL) { - unsigned int hkey = hashstring(key); + unsigned int hkey = str_hash(key); unsigned int id = hkey & (SMAXHASH - 1); struct locale_str *find; @@ -188,7 +188,7 @@ const char *locale_string(const locale * lang, const char *key, bool warn) void locale_setstring(locale * lang, const char *key, const char *value) { - unsigned int hkey = hashstring(key); + unsigned int hkey = str_hash(key); unsigned int id = hkey & (SMAXHASH - 1); struct locale_str *find; if (!lang) { diff --git a/src/util/message.c b/src/util/message.c index e53010093..239863bd1 100644 --- a/src/util/message.c +++ b/src/util/message.c @@ -192,7 +192,7 @@ void mt_clear(void) { const message_type *mt_find(const char *name) { - unsigned int hash = hashstring(name) % MT_MAXHASH; + unsigned int hash = str_hash(name) % MT_MAXHASH; selist *ql = messagetypes[hash]; int qi; @@ -218,7 +218,7 @@ static unsigned int mt_id(const message_type * mtype) const message_type *mt_register(message_type * type) { - unsigned int hash = hashstring(type->name) % MT_MAXHASH; + unsigned int hash = str_hash(type->name) % MT_MAXHASH; selist **qlp = messagetypes + hash; if (selist_set_insert(qlp, type, NULL)) { diff --git a/src/util/strings.c b/src/util/strings.c index 4e7e17aa4..55d4ca5fb 100644 --- a/src/util/strings.c +++ b/src/util/strings.c @@ -45,7 +45,40 @@ char *set_string(char **s, const char *neu) return *s; } -unsigned int hashstring(const char *s) +void str_replace(char *buffer, size_t size, const char *tmpl, const char *var, const char *value) +{ + size_t val_len = strlen(value); + size_t var_len = strlen(var); + char *s = buffer; + while (buffer + size > s) { + char *p = strstr(tmpl, var); + size_t len; + if (p) { + len = p - tmpl; + } + else { + len = strlen(tmpl); + } + if (len < size) { + memmove(s, tmpl, len); + tmpl += len; + s += len; + size -= len; + if (p && val_len < size) { + tmpl += var_len; + memmove(s, value, val_len); + s += val_len; + size -= val_len; + } + } + if (!p) { + break; + } + } + *s = 0; +} + +unsigned int str_hash(const char *s) { unsigned int key = 0; assert(s); @@ -55,7 +88,7 @@ unsigned int hashstring(const char *s) return key & 0x7FFFFFFF; } -const char *escape_string(const char *str, char *buffer, +const char *str_escape(const char *str, char *buffer, size_t len) { const char *start = strchr(str, '\"'); diff --git a/src/util/strings.h b/src/util/strings.h index 05a435e2c..f63299d93 100644 --- a/src/util/strings.h +++ b/src/util/strings.h @@ -25,9 +25,10 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. extern "C" { #endif + void str_replace(char *buffer, size_t size, const char *tmpl, const char *var, const char *value); + const char *str_escape(const char *str, char *buffer, size_t len); char *set_string(char **s, const char *neu); - unsigned int hashstring(const char *s); - const char *escape_string(const char *str, char *buffer, size_t len); + unsigned int str_hash(const char *s); unsigned int jenkins_hash(unsigned int a); unsigned int wang_hash(unsigned int a); diff --git a/src/util/strings.test.c b/src/util/strings.test.c index bcee29e47..60a0b5d37 100644 --- a/src/util/strings.test.c +++ b/src/util/strings.test.c @@ -4,21 +4,36 @@ #include #include "strings.h" -static void test_escape_string(CuTest * tc) +static void test_str_escape(CuTest * tc) { char scratch[64]; - CuAssertStrEquals(tc, "12345678901234567890", escape_string("12345678901234567890", scratch, 16)); - CuAssertStrEquals(tc, "123456789\\\"12345", escape_string("123456789\"1234567890", scratch, 16)); - CuAssertStrEquals(tc, "1234567890123456", escape_string("1234567890123456\"890", scratch, 16)); - CuAssertStrEquals(tc, "hello world", escape_string("hello world", scratch, sizeof(scratch))); - CuAssertStrEquals(tc, "hello \\\"world\\\"", escape_string("hello \"world\"", scratch, sizeof(scratch))); - CuAssertStrEquals(tc, "\\\"\\\\", escape_string("\"\\", scratch, sizeof(scratch))); - CuAssertStrEquals(tc, "\\\\", escape_string("\\", scratch, sizeof(scratch))); + CuAssertStrEquals(tc, "12345678901234567890", str_escape("12345678901234567890", scratch, 16)); + CuAssertStrEquals(tc, "123456789\\\"12345", str_escape("123456789\"1234567890", scratch, 16)); + CuAssertStrEquals(tc, "1234567890123456", str_escape("1234567890123456\"890", scratch, 16)); + CuAssertStrEquals(tc, "hello world", str_escape("hello world", scratch, sizeof(scratch))); + CuAssertStrEquals(tc, "hello \\\"world\\\"", str_escape("hello \"world\"", scratch, sizeof(scratch))); + CuAssertStrEquals(tc, "\\\"\\\\", str_escape("\"\\", scratch, sizeof(scratch))); + CuAssertStrEquals(tc, "\\\\", str_escape("\\", scratch, sizeof(scratch))); +} + +static void test_str_replace(CuTest * tc) +{ + char result[64]; + str_replace(result, sizeof(result), "Hello $who!", "$who", "World"); + CuAssertStrEquals(tc, "Hello World!", result); +} + +static void test_str_hash(CuTest * tc) +{ + CuAssertIntEquals(tc, 0, str_hash("")); + CuAssertIntEquals(tc, 140703196, str_hash("Hodor")); } CuSuite *get_strings_suite(void) { CuSuite *suite = CuSuiteNew(); - SUITE_ADD_TEST(suite, test_escape_string); + SUITE_ADD_TEST(suite, test_str_hash); + SUITE_ADD_TEST(suite, test_str_escape); + SUITE_ADD_TEST(suite, test_str_replace); return suite; } From b297b4d43ca47864dfca327b6ade55f3d4d775ea Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 11 Dec 2017 18:35:30 +0100 Subject: [PATCH 05/14] eliminate some more strlcat calls. --- src/kernel/region.c | 2 +- src/kernel/ship.c | 5 ++--- src/modules/score.c | 3 +-- src/monsters.c | 2 +- src/names.c | 23 ++++++++++------------- src/randenc.c | 7 +++---- src/spells.c | 3 +-- 7 files changed, 19 insertions(+), 26 deletions(-) diff --git a/src/kernel/region.c b/src/kernel/region.c index 91afaabd4..81e9e4285 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -124,7 +124,7 @@ const char *write_regionname(const region * r, const faction * f, char *buffer, int nx = r->x, ny = r->y; pnormalize(&nx, &ny, pl); adjust_coordinates(f, &nx, &ny, pl); - slprintf(buf, size, "%s (%d,%d)", rname(r, lang), nx, ny); + snprintf(buf, size, "%s (%d,%d)", rname(r, lang), nx, ny); } return buffer; } diff --git a/src/kernel/ship.c b/src/kernel/ship.c index a55eada2e..88eb5c39f 100644 --- a/src/kernel/ship.c +++ b/src/kernel/ship.c @@ -36,7 +36,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include #include -#include #include #include #include @@ -217,7 +216,7 @@ ship *new_ship(const ship_type * stype, region * r, const struct locale *lang) sname = parameters[P_SHIP]; } assert(sname); - slprintf(buffer, sizeof(buffer), "%s %s", sname, itoa36(sh->no)); + snprintf(buffer, sizeof(buffer), "%s %s", sname, itoa36(sh->no)); sh->name = strdup(buffer); shash(sh); if (r) { @@ -283,7 +282,7 @@ void free_ships(void) const char *write_shipname(const ship * sh, char *ibuf, size_t size) { - slprintf(ibuf, size, "%s (%s)", sh->name, itoa36(sh->no)); + snprintf(ibuf, size, "%s (%s)", sh->name, itoa36(sh->no)); return ibuf; } diff --git a/src/modules/score.c b/src/modules/score.c index efb3465d4..202fc77b7 100644 --- a/src/modules/score.c +++ b/src/modules/score.c @@ -34,7 +34,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include -#include #include /* libc includes */ @@ -237,5 +236,5 @@ int default_score(const item_type *itype) { } void write_score(char *buffer, size_t size, score_t score) { - slprintf(buffer, size, "%lld", score); + snprintf(buffer, size, "%lld", score); } diff --git a/src/monsters.c b/src/monsters.c index 3b02b2be2..a17d9f1fa 100644 --- a/src/monsters.c +++ b/src/monsters.c @@ -82,7 +82,7 @@ static double attack_chance; /* rules.monsters.attack_chance, or default 0.4 */ static void give_peasants(unit *u, const item_type *itype, int reduce) { char buf[64]; - slprintf(buf, sizeof(buf), "%s 0 %d %s", LOC(u->faction->locale, keyword(K_GIVE)), reduce, LOC(u->faction->locale, itype->rtype->_name)); + snprintf(buf, sizeof(buf), "%s 0 %d %s", LOC(u->faction->locale, keyword(K_GIVE)), reduce, LOC(u->faction->locale, itype->rtype->_name)); unit_addorder(u, parse_order(buf, u->faction->locale)); } diff --git a/src/names.c b/src/names.c index ef2d58422..1201b9f41 100644 --- a/src/names.c +++ b/src/names.c @@ -262,7 +262,7 @@ static void dragon_name(unit * u) rnd = num_postfix / 6; rnd = (rng_int() % rnd) + ter * rnd; } - sprintf(zText, "dragon_postfix_%d", rnd); + snprintf(zText, sizeof(zText), "dragon_postfix_%d", rnd); str = locale_getstring(default_locale, zText); assert(str != NULL); @@ -271,28 +271,25 @@ static void dragon_name(unit * u) const char *no_article = strchr((const char *)str, ' '); assert(no_article); /* TODO: localization */ - sprintf(name, "Die %sn von %s", no_article + 1, rname(u->region, + snprintf(name, sizeof(name), "Die %sn von %s", no_article + 1, rname(u->region, default_locale)); } else { char n[32]; - size_t sz; - sz = strlcpy(n, silbe1[rng_int() % SIL1], sizeof(n)); - sz += strlcat(n, silbe2[rng_int() % SIL2], sizeof(n)); - sz += strlcat(n, silbe3[rng_int() % SIL3], sizeof(n)); + snprintf(n, sizeof(n), "%s%s%s", silbe1[rng_int() % SIL1], silbe2[rng_int() % SIL1], silbe3[rng_int() % SIL1]); if (rng_int() % 5 > 2) { sprintf(name, "%s, %s", n, str); /* "Name, der Titel" */ } else { - sz = strlcpy(name, (const char *)str, sizeof(name)); /* "Der Titel Name" */ + if (rng_int() % 3 == 0) { + /* TODO: localization */ + snprintf(name, sizeof(name), "%s %s von %s", n, str, rname(u->region, default_locale)); + } + else { + snprintf(name, sizeof(name), "%s %s", n, str); + } name[0] = (char)toupper(name[0]); /* TODO: UNICODE - should use towupper() */ - sz += strlcat(name, " ", sizeof(name)); - sz += strlcat(name, n, sizeof(name)); - } - if (rng_int() % 3 == 0) { - sz += strlcat(name, " von ", sizeof(name)); - sz += strlcat(name, (const char *)rname(u->region, default_locale), sizeof(name)); } } diff --git a/src/randenc.c b/src/randenc.c index 48f7a5827..3e1ac3554 100644 --- a/src/randenc.c +++ b/src/randenc.c @@ -53,7 +53,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include -#include #include #include #include @@ -62,10 +61,10 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include /* libc includes */ -#include #include #include #include +#include #include #include @@ -234,9 +233,9 @@ void find_manual(region * r, unit * u) break; } - slprintf(zLocation, sizeof(zLocation), "manual_location_%d", + snprintf(zLocation, sizeof(zLocation), "manual_location_%d", (int)(rng_int() % 4)); - slprintf(zBook, sizeof(zLocation), "manual_title_%s", skillnames[skill]); + snprintf(zBook, sizeof(zLocation), "manual_title_%s", skillnames[skill]); msg = msg_message("find_manual", "unit location book", u, zLocation, zBook); if (msg) { diff --git a/src/spells.c b/src/spells.c index b25b933fd..a9fa12127 100644 --- a/src/spells.c +++ b/src/spells.c @@ -61,7 +61,6 @@ #include #include #include -#include #include #include #include @@ -4643,7 +4642,7 @@ int sp_clonecopy(castorder * co) return 0; } - slprintf(name, sizeof(name), (const char *)LOC(mage->faction->locale, + snprintf(name, sizeof(name), (const char *)LOC(mage->faction->locale, "clone_of"), unitname(mage)); clone = create_unit(target_region, mage->faction, 1, get_race(RC_CLONE), 0, name, From d48b9611e128054df147584b48e45a26cad34702 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 11 Dec 2017 08:53:10 +0100 Subject: [PATCH 06/14] have cmake determine bsdstring requirement --- CMakeLists.txt | 3 +++ src/CMakeLists.txt | 4 ++++ src/platform.h | 4 ++-- src/util/CMakeLists.txt | 7 ++++++- src/util/bsdstring.h | 11 +++++++++++ 5 files changed, 26 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4aa4ca472..f1954c6b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,9 @@ if (MSVC) include(MSVC) endif (MSVC) +INCLUDE (CheckSymbolExists) +CHECK_SYMBOL_EXISTS(strlcat string.h HAVE_STRLCAT) + find_package (SQLite3) find_package (BerkeleyDB) find_package (Curses) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d3cfdafce..2d4ba17d1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -266,6 +266,10 @@ add_test(server test_eressea) install(TARGETS eressea DESTINATION "bin") +if (HAVE_STRLCAT) + add_definitions(-DHAVE_BSDSTRING) +endif(HAVE_STRLCAT) + if (DB_FOUND) include_directories (${DB_INCLUDE_DIR}) target_link_libraries(convert ${DB_LIBRARIES}) diff --git a/src/platform.h b/src/platform.h index 9e2ecfadb..968aa3ec3 100644 --- a/src/platform.h +++ b/src/platform.h @@ -29,8 +29,8 @@ #endif -#define _POSIX_C_SOURCE 200809L - +/* #define _POSIX_C_SOURCE 200809L +*/ #ifndef MAX_PATH # define MAX_PATH 4096 #endif diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 91ed118ae..e114e3c94 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -3,7 +3,6 @@ project(util C) SET(_TEST_FILES attrib.test.c base36.test.c -bsdstring.test.c # crmessage.test.c # dice.test.c # event.test.c @@ -60,6 +59,12 @@ unicode.c variant.c xml.c ) + +IF(HAVE_BSDSTRING) + SET (_TEST_FILES ${_TEST_FILES} bsdstring.test.c) + SET (_FILES ${_FILES} bsdstring.c) +ENDIF(HAVE_BSDSTRING) + FOREACH(_FILE ${_FILES}) LIST(APPEND _SOURCES ${PROJECT_NAME}/${_FILE}) ENDFOREACH(_FILE) diff --git a/src/util/bsdstring.h b/src/util/bsdstring.h index dad4d6281..583d176f3 100644 --- a/src/util/bsdstring.h +++ b/src/util/bsdstring.h @@ -4,6 +4,17 @@ #include int wrptr(char **ptr, size_t * size, int bytes); +#undef HAVE_STRLCAT +#undef HAVE_STRLCPY +#undef HAVE_SLPRINTF +#ifdef HAVE_BSDSTRING +#define HAVE_STRLCAT +#define HAVE_SLPRINT +#define HAVE_STRLCPY +#else +#include +#endif + #ifndef HAVE_STRLCPY size_t strlcpy(char *dst, const char *src, size_t siz); #endif From af7cc023886ae52ebe9351fcea8c9f1732ee329d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 11 Dec 2017 18:42:35 +0100 Subject: [PATCH 07/14] try to fix the build --- src/util/base36.c | 1 - src/util/bsdstring.c | 9 --------- src/util/bsdstring.h | 2 +- 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/util/base36.c b/src/util/base36.c index ef7c38371..3ded21a54 100644 --- a/src/util/base36.c +++ b/src/util/base36.c @@ -55,7 +55,6 @@ int atoi36(const char *str) const char *itoab_r(int i, int base, char *s, size_t len) { char *dst; - static int index = 0; /* STATIC_XCALL: used across calls */ assert(len > 2); dst = s + len - 2; diff --git a/src/util/bsdstring.c b/src/util/bsdstring.c index 4aa779495..f59b0ddaa 100644 --- a/src/util/bsdstring.c +++ b/src/util/bsdstring.c @@ -35,8 +35,6 @@ int wrptr(char **ptr, size_t * size, int result) return ERANGE; } -#ifndef HAVE_STRLCPY -#define HAVE_STRLCPY size_t strlcpy(char *dst, const char *src, size_t siz) { /* copied from OpenBSD source code */ register char *d = dst; @@ -61,7 +59,6 @@ size_t strlcpy(char *dst, const char *src, size_t siz) return (s - src - 1); /* count does not include NUL */ } -#endif char * strlcpy_w(char *dst, const char *src, size_t *siz, const char *err, const char *file, int line) { @@ -78,8 +75,6 @@ char * strlcpy_w(char *dst, const char *src, size_t *siz, const char *err, const return buf; } -#ifndef HAVE_STRLCAT -#define HAVE_STRLCAT size_t strlcat(char *dst, const char *src, size_t siz) { register char *d = dst; @@ -106,10 +101,7 @@ size_t strlcat(char *dst, const char *src, size_t siz) return (dlen + (s - src)); /* count does not include NUL */ } -#endif -#ifndef HAVE_SLPRINTF -#define HAVE_SLPRINTF size_t slprintf(char * dst, size_t size, const char * format, ...) { va_list args; @@ -125,4 +117,3 @@ size_t slprintf(char * dst, size_t size, const char * format, ...) return (size_t)result; } -#endif diff --git a/src/util/bsdstring.h b/src/util/bsdstring.h index 583d176f3..923cf60d8 100644 --- a/src/util/bsdstring.h +++ b/src/util/bsdstring.h @@ -9,7 +9,7 @@ int wrptr(char **ptr, size_t * size, int bytes); #undef HAVE_SLPRINTF #ifdef HAVE_BSDSTRING #define HAVE_STRLCAT -#define HAVE_SLPRINT +#define HAVE_SLPRINTF #define HAVE_STRLCPY #else #include From 93613b99af676898e09f9ecf59b3d1f6e9af1035 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 11 Dec 2017 19:23:56 +0100 Subject: [PATCH 08/14] slprintf is not in BSD (it's theft from samba). --- src/battle.c | 1 + src/kernel/faction.c | 2 +- src/laws.c | 1 + src/move.c | 1 + src/util/bsdstring.c | 18 ------------------ src/util/bsdstring.h | 5 ----- src/util/bsdstring.test.c | 19 ------------------- src/util/strings.c | 18 ++++++++++++++++++ src/util/strings.h | 3 +++ src/util/strings.test.c | 19 +++++++++++++++++++ 10 files changed, 44 insertions(+), 43 deletions(-) diff --git a/src/battle.c b/src/battle.c index c12e6d46e..92a2c54c5 100644 --- a/src/battle.c +++ b/src/battle.c @@ -69,6 +69,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include #include #include diff --git a/src/kernel/faction.c b/src/kernel/faction.c index 8da74e80e..f0010ddce 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -39,7 +39,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include #include -#include #include #include #include @@ -50,6 +49,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include #include diff --git a/src/laws.c b/src/laws.c index f03f76730..873dc470f 100644 --- a/src/laws.c +++ b/src/laws.c @@ -90,6 +90,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include #include diff --git a/src/move.c b/src/move.c index 592ca606f..69a84c2cd 100644 --- a/src/move.c +++ b/src/move.c @@ -78,6 +78,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include diff --git a/src/util/bsdstring.c b/src/util/bsdstring.c index f59b0ddaa..1ac1246fa 100644 --- a/src/util/bsdstring.c +++ b/src/util/bsdstring.c @@ -1,9 +1,7 @@ #include -#include #include #include #include -#include #include #include "bsdstring.h" @@ -101,19 +99,3 @@ size_t strlcat(char *dst, const char *src, size_t siz) return (dlen + (s - src)); /* count does not include NUL */ } - -size_t slprintf(char * dst, size_t size, const char * format, ...) -{ - va_list args; - int result; - - va_start(args, format); - result = vsnprintf(dst, size, format, args); - va_end(args); - if (result < 0 || result >= (int)size) { - dst[size - 1] = '\0'; - return size; - } - - return (size_t)result; -} diff --git a/src/util/bsdstring.h b/src/util/bsdstring.h index 923cf60d8..463a043c8 100644 --- a/src/util/bsdstring.h +++ b/src/util/bsdstring.h @@ -9,7 +9,6 @@ int wrptr(char **ptr, size_t * size, int bytes); #undef HAVE_SLPRINTF #ifdef HAVE_BSDSTRING #define HAVE_STRLCAT -#define HAVE_SLPRINTF #define HAVE_STRLCPY #else #include @@ -24,10 +23,6 @@ char * strlcpy_w(char *dst, const char *src, size_t *siz, const char *err, const size_t strlcat(char *dst, const char *src, size_t siz); #endif -#ifndef HAVE_SLPRINTF -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__) diff --git a/src/util/bsdstring.test.c b/src/util/bsdstring.test.c index d4276ef61..61453f893 100644 --- a/src/util/bsdstring.test.c +++ b/src/util/bsdstring.test.c @@ -42,29 +42,10 @@ static void test_strlcpy(CuTest * tc) errno = 0; } -static void test_slprintf(CuTest * tc) -{ - char buffer[32]; - - memset(buffer, 0x7f, sizeof(buffer)); - - CuAssertTrue(tc, slprintf(buffer, 4, "%s", "herpderp") > 3); - CuAssertStrEquals(tc, "her", buffer); - - CuAssertIntEquals(tc, 4, (int)slprintf(buffer, 8, "%s", "herp")); - CuAssertStrEquals(tc, "herp", buffer); - CuAssertIntEquals(tc, 0x7f, buffer[5]); - - CuAssertIntEquals(tc, 8, (int)slprintf(buffer, 8, "%s", "herpderp")); - CuAssertStrEquals(tc, "herpder", buffer); - CuAssertIntEquals(tc, 0x7f, buffer[8]); -} - CuSuite *get_bsdstring_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_strlcat); SUITE_ADD_TEST(suite, test_strlcpy); - SUITE_ADD_TEST(suite, test_slprintf); return suite; } diff --git a/src/util/strings.c b/src/util/strings.c index 55d4ca5fb..a63a694ce 100644 --- a/src/util/strings.c +++ b/src/util/strings.c @@ -22,10 +22,28 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "assert.h" /* libc includes */ +#include +#include #include #include #include +size_t str_slprintf(char * dst, size_t size, const char * format, ...) +{ + va_list args; + int result; + + va_start(args, format); + result = vsnprintf(dst, size, format, args); + va_end(args); + if (result < 0 || result >= (int)size) { + dst[size - 1] = '\0'; + return size; + } + + return (size_t)result; +} + char *set_string(char **s, const char *neu) { if (neu == NULL) { diff --git a/src/util/strings.h b/src/util/strings.h index f63299d93..9add04e23 100644 --- a/src/util/strings.h +++ b/src/util/strings.h @@ -29,6 +29,8 @@ extern "C" { const char *str_escape(const char *str, char *buffer, size_t len); char *set_string(char **s, const char *neu); unsigned int str_hash(const char *s); + size_t str_slprintf(char * dst, size_t size, const char * format, ...); + unsigned int jenkins_hash(unsigned int a); unsigned int wang_hash(unsigned int a); @@ -49,6 +51,7 @@ extern "C" { #define HASH1 JENKINS_HASH1 #define HASH2 JENKINS_HASH2 +#define slprintf str_slprintf #ifdef __cplusplus } diff --git a/src/util/strings.test.c b/src/util/strings.test.c index 60a0b5d37..14d62200a 100644 --- a/src/util/strings.test.c +++ b/src/util/strings.test.c @@ -29,11 +29,30 @@ static void test_str_hash(CuTest * tc) CuAssertIntEquals(tc, 140703196, str_hash("Hodor")); } +static void test_str_slprintf(CuTest * tc) +{ + char buffer[32]; + + memset(buffer, 0x7f, sizeof(buffer)); + + CuAssertTrue(tc, slprintf(buffer, 4, "%s", "herpderp") > 3); + CuAssertStrEquals(tc, "her", buffer); + + CuAssertIntEquals(tc, 4, (int)str_slprintf(buffer, 8, "%s", "herp")); + CuAssertStrEquals(tc, "herp", buffer); + CuAssertIntEquals(tc, 0x7f, buffer[5]); + + CuAssertIntEquals(tc, 8, (int)str_slprintf(buffer, 8, "%s", "herpderp")); + CuAssertStrEquals(tc, "herpder", buffer); + CuAssertIntEquals(tc, 0x7f, buffer[8]); +} + CuSuite *get_strings_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_str_hash); SUITE_ADD_TEST(suite, test_str_escape); SUITE_ADD_TEST(suite, test_str_replace); + SUITE_ADD_TEST(suite, test_str_slprintf); return suite; } From a74daa2474c9f02022eda91017475d996b4ae87b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 11 Dec 2017 19:31:42 +0100 Subject: [PATCH 09/14] fix mac build --- src/util/CMakeLists.txt | 7 +------ src/util/bsdstring.c | 32 +++++++++++++++++--------------- src/util/bsdstring.h | 18 ++++-------------- 3 files changed, 22 insertions(+), 35 deletions(-) diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index e114e3c94..d021ada72 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -3,6 +3,7 @@ project(util C) SET(_TEST_FILES attrib.test.c base36.test.c +bsdstring.test.c # crmessage.test.c # dice.test.c # event.test.c @@ -21,7 +22,6 @@ password.test.c # resolve.test.c rng.test.c strings.test.c -bsdstring.test.c functions.test.c log.test.c # translation.test.c @@ -60,11 +60,6 @@ variant.c xml.c ) -IF(HAVE_BSDSTRING) - SET (_TEST_FILES ${_TEST_FILES} bsdstring.test.c) - SET (_FILES ${_FILES} bsdstring.c) -ENDIF(HAVE_BSDSTRING) - FOREACH(_FILE ${_FILES}) LIST(APPEND _SOURCES ${PROJECT_NAME}/${_FILE}) ENDFOREACH(_FILE) diff --git a/src/util/bsdstring.c b/src/util/bsdstring.c index 1ac1246fa..f4499465b 100644 --- a/src/util/bsdstring.c +++ b/src/util/bsdstring.c @@ -33,6 +33,7 @@ int wrptr(char **ptr, size_t * size, int result) return ERANGE; } +#ifndef HAVE_BSDSTRING size_t strlcpy(char *dst, const char *src, size_t siz) { /* copied from OpenBSD source code */ register char *d = dst; @@ -58,21 +59,6 @@ size_t strlcpy(char *dst, const char *src, size_t siz) return (s - src - 1); /* count does not include NUL */ } -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; - 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; -} - size_t strlcat(char *dst, const char *src, size_t siz) { register char *d = dst; @@ -99,3 +85,19 @@ size_t strlcat(char *dst, const char *src, size_t siz) return (dlen + (s - src)); /* count does not include NUL */ } +#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; + 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 463a043c8..77c1b94ed 100644 --- a/src/util/bsdstring.h +++ b/src/util/bsdstring.h @@ -2,27 +2,17 @@ #define UTIL_BSDSTRING_H #include -int wrptr(char **ptr, size_t * size, int bytes); -#undef HAVE_STRLCAT -#undef HAVE_STRLCPY -#undef HAVE_SLPRINTF -#ifdef HAVE_BSDSTRING -#define HAVE_STRLCAT -#define HAVE_STRLCPY +#ifndef HAVE_BSDSTRING +size_t strlcpy(char *dst, const char *src, size_t siz); +size_t strlcat(char *dst, const char *src, size_t siz); #else #include #endif -#ifndef HAVE_STRLCPY -size_t strlcpy(char *dst, const char *src, size_t siz); -#endif +int wrptr(char **ptr, size_t * size, int bytes); char * strlcpy_w(char *dst, const char *src, size_t *siz, const char *err, const char *file, int line); -#ifndef HAVE_STRLCAT -size_t strlcat(char *dst, const char *src, size_t siz); -#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 77921a94bacdd399195e6501968908f294a626ae Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 11 Dec 2017 19:47:57 +0100 Subject: [PATCH 10/14] BUG 1986: Jedes Magiegebiet kann Vertraute rufen. --- res/e3a/spellbooks/cerddor.xml | 1 + res/e3a/spellbooks/common.xml | 1 - res/e3a/spellbooks/draig.xml | 1 + res/e3a/spellbooks/gray.xml | 1 - res/e3a/spellbooks/gwyrrd.xml | 1 + res/e3a/spellbooks/illaun.xml | 1 + src/kernel/save.c | 2 +- 7 files changed, 5 insertions(+), 3 deletions(-) diff --git a/res/e3a/spellbooks/cerddor.xml b/res/e3a/spellbooks/cerddor.xml index 3d5f0e08e..9b6e4cd8e 100644 --- a/res/e3a/spellbooks/cerddor.xml +++ b/res/e3a/spellbooks/cerddor.xml @@ -33,4 +33,5 @@ + diff --git a/res/e3a/spellbooks/common.xml b/res/e3a/spellbooks/common.xml index 0735bc248..688a1b9ae 100644 --- a/res/e3a/spellbooks/common.xml +++ b/res/e3a/spellbooks/common.xml @@ -34,7 +34,6 @@ - diff --git a/res/e3a/spellbooks/draig.xml b/res/e3a/spellbooks/draig.xml index 34b6e7642..d97a695b3 100644 --- a/res/e3a/spellbooks/draig.xml +++ b/res/e3a/spellbooks/draig.xml @@ -29,4 +29,5 @@ + diff --git a/res/e3a/spellbooks/gray.xml b/res/e3a/spellbooks/gray.xml index 9c0035e78..78645f907 100644 --- a/res/e3a/spellbooks/gray.xml +++ b/res/e3a/spellbooks/gray.xml @@ -127,7 +127,6 @@ - diff --git a/res/e3a/spellbooks/gwyrrd.xml b/res/e3a/spellbooks/gwyrrd.xml index ac51495cf..452100ace 100644 --- a/res/e3a/spellbooks/gwyrrd.xml +++ b/res/e3a/spellbooks/gwyrrd.xml @@ -30,4 +30,5 @@ + diff --git a/res/e3a/spellbooks/illaun.xml b/res/e3a/spellbooks/illaun.xml index 129e15f21..6b89df8fa 100644 --- a/res/e3a/spellbooks/illaun.xml +++ b/res/e3a/spellbooks/illaun.xml @@ -30,4 +30,5 @@ + diff --git a/src/kernel/save.c b/src/kernel/save.c index a044601aa..a37199318 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1429,7 +1429,7 @@ int read_game(gamedata *data) /* Burgen */ READ_INT(store, &p); if (p > 0 && !r->land) { - log_error("%s, uid=%d has %d buildings", regionname(r, NULL), r->uid, p); + log_error("%s, uid=%d has %d %s", regionname(r, NULL), r->uid, p, (p==1) ? "building" : "buildings"); } bp = &r->buildings; From 02248e0c543c237c39ec8ef0b7c8749a937d4335 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 12 Dec 2017 09:19:35 +0100 Subject: [PATCH 11/14] fix coverity scan errors --- CMakeLists.txt | 1 + src/CMakeLists.txt | 6 +++++- src/battle.c | 2 +- src/kernel/orderdb.c | 8 ++++++-- src/names.c | 2 +- 5 files changed, 14 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f1954c6b0..7507bd99f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ endif (MSVC) INCLUDE (CheckSymbolExists) CHECK_SYMBOL_EXISTS(strlcat string.h HAVE_STRLCAT) +CHECK_SYMBOL_EXISTS(strdup string.h HAVE_STRDUP) find_package (SQLite3) find_package (BerkeleyDB) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2d4ba17d1..9436a8946 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -267,9 +267,13 @@ add_test(server test_eressea) install(TARGETS eressea DESTINATION "bin") if (HAVE_STRLCAT) - add_definitions(-DHAVE_BSDSTRING) + add_definitions(-DHAVE_BSDSTRING) endif(HAVE_STRLCAT) +if (HAVE_STRDUP) + add_definitions(-DHAVE_STRDUP) +endif(HAVE_STRDUP) + if (DB_FOUND) include_directories (${DB_INCLUDE_DIR}) target_link_libraries(convert ${DB_LIBRARIES}) diff --git a/src/battle.c b/src/battle.c index 92a2c54c5..1e046675f 100644 --- a/src/battle.c +++ b/src/battle.c @@ -190,7 +190,7 @@ static char *sidename(side * s) static char sidename_buf[4][SIDENAMEBUFLEN]; /* STATIC_RESULT: used for return, not across calls */ bufno = bufno % 4; - strncpy(sidename_buf[bufno], factionname(s->stealthfaction ? s->stealthfaction : s->faction), SIDENAMEBUFLEN); + strlcpy(sidename_buf[bufno], factionname(s->stealthfaction ? s->stealthfaction : s->faction), SIDENAMEBUFLEN); return sidename_buf[bufno++]; } diff --git a/src/kernel/orderdb.c b/src/kernel/orderdb.c index d97c5fae3..b30131be4 100644 --- a/src/kernel/orderdb.c +++ b/src/kernel/orderdb.c @@ -6,6 +6,7 @@ #include +#include #include #include @@ -14,12 +15,15 @@ void odata_create(order_data **pdata, size_t len, const char *str) order_data *data; char *result; + assert(pdata); data = malloc(sizeof(order_data) + len + 1); data->_refcount = 1; result = (char *)(data + 1); data->_str = (len > 0) ? result : NULL; - if (str) strcpy(result, str); - if (pdata) *pdata = data; + if (str) { + strcpy(result, str); + } + *pdata = data; } void odata_release(order_data * od) diff --git a/src/names.c b/src/names.c index 1201b9f41..d85b91805 100644 --- a/src/names.c +++ b/src/names.c @@ -277,7 +277,7 @@ static void dragon_name(unit * u) else { char n[32]; - snprintf(n, sizeof(n), "%s%s%s", silbe1[rng_int() % SIL1], silbe2[rng_int() % SIL1], silbe3[rng_int() % SIL1]); + snprintf(n, sizeof(n), "%s%s%s", silbe1[rng_int() % SIL1], silbe2[rng_int() % SIL2], silbe3[rng_int() % SIL3]); if (rng_int() % 5 > 2) { sprintf(name, "%s, %s", n, str); /* "Name, der Titel" */ } From 761f40f782b36d72b7b4952be1b150e670c49dbb Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 12 Dec 2017 21:34:34 +0100 Subject: [PATCH 12/14] FFL_CURSED is forever --- src/battle.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/battle.c b/src/battle.c index 1e046675f..823fd89f1 100644 --- a/src/battle.c +++ b/src/battle.c @@ -1644,7 +1644,6 @@ static castorder * create_castorder_combat(castorder *co, fighter *fig, const sp return co; } -#ifdef FFL_CURSED static void summon_igjarjuk(battle *b, spellrank spellranks[]) { side *s; castorder *co; @@ -1682,7 +1681,6 @@ static void summon_igjarjuk(battle *b, spellrank spellranks[]) { } } } -#endif void do_combatmagic(battle * b, combatmagic_t was) { @@ -1694,11 +1692,9 @@ void do_combatmagic(battle * b, combatmagic_t was) memset(spellranks, 0, sizeof(spellranks)); -#ifdef FFL_CURSED if (was == DO_PRECOMBATSPELL) { summon_igjarjuk(b, spellranks); } -#endif for (s = b->sides; s != b->sides + b->nsides; ++s) { fighter *fig; for (fig = s->fighters; fig; fig = fig->next) { From 2d3451d7b8818fe1a65457bdaf5b71ba4e50cad6 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 12 Dec 2017 21:37:44 +0100 Subject: [PATCH 13/14] another HAVE_X define that was never defined, and pointless --- src/kernel/save.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/kernel/save.c b/src/kernel/save.c index a37199318..fe83f943a 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1569,14 +1569,12 @@ int writegame(const char *filename) create_directories(); join_path(datapath(), filename, path, sizeof(path)); -#ifdef HAVE_UNISTD_H /* make sure we don't overwrite an existing file (hard links) */ - if (remove(path)!=0) { - if (errno==ENOENT) { + if (remove(path) != 0) { + if (errno == ENOENT) { errno = 0; } } -#endif F = fopen(path, "wb"); if (!F) { perror(path); From 5977ca51b5fa5e4c4ee3cae5bbfc63dd8debaca0 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 15 Dec 2017 17:16:00 +0100 Subject: [PATCH 14/14] tests for insects, prepare for bug 1841 another test for appeasement, fix guard bug 2389 --- scripts/tests/common.lua | 13 ++++++ scripts/tests/e2/init.lua | 1 + scripts/tests/e2/insects.lua | 83 ++++++++++++++++++++++++++++++++++++ scripts/tests/spells.lua | 30 ++++++++++++- src/spells/combatspells.c | 2 +- 5 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 scripts/tests/e2/insects.lua diff --git a/scripts/tests/common.lua b/scripts/tests/common.lua index d0a419109..d76c2cfdf 100644 --- a/scripts/tests/common.lua +++ b/scripts/tests/common.lua @@ -1147,3 +1147,16 @@ function test_route_pause() assert_equal("ROUTE P O W", u:get_order(0)) assert_equal(r1, u.region) end + +function test_bug_2393_cart() + local r1 = region.create(0, 0, "plain") + local r2 = region.create(1, 0, "plain") + local f = faction.create("human", "cart@example.com") + local u = unit.create(f, r1, 2) + u:add_order("NACH O") + u:add_item('stone', 2) + u:add_item('horse', 2) + u:add_item('cart', 1) + process_orders() + assert_equal(r1, u.region) +end diff --git a/scripts/tests/e2/init.lua b/scripts/tests/e2/init.lua index 222723082..d8d21a5c8 100644 --- a/scripts/tests/e2/init.lua +++ b/scripts/tests/e2/init.lua @@ -1,3 +1,4 @@ +require 'tests.e2.insects' require 'tests.e2.spells' require 'tests.e2.buildings' require 'tests.e2.production' diff --git a/scripts/tests/e2/insects.lua b/scripts/tests/e2/insects.lua new file mode 100644 index 000000000..374bedff8 --- /dev/null +++ b/scripts/tests/e2/insects.lua @@ -0,0 +1,83 @@ +require "lunit" + +module("tests.e2.insects", package.seeall, lunit.testcase) + +function setup() + eressea.free_game() + eressea.settings.set("rules.food.flags", "4") + eressea.settings.set("nmr.timeout", "0") + eressea.settings.set("NewbieImmunity", "0") +end + +function test_move_to_glacier() + local r = region.create(0, 0, "plain") + local r2 = region.create(1, 0, "glacier") + local f = faction.create("insect", "insect@eressea.de", "de") + local u = unit.create(f, r, 1) + + u:clear_orders() + u:add_order("NACH OST") + process_orders() + assert_equal(r, u.region) +end + +function test_sail_into_glacier() + local r = region.create(0, 0, "ocean") + local r2 = region.create(1, 0, "glacier") + local f = faction.create("insect", "insect@eressea.de", "de") + local u1 = unit.create(f, r, 1, 'human') + local u2 = unit.create(f, r, 1, 'insect') + + u1.ship = ship.create(r, 'boat') + u1:set_skill("sailing", 10) + u1:clear_orders() + u1:add_order("NACH OST") + u2.ship = u1.ship + process_orders() + assert_equal(r, u2.region) +end + +function test_recruit_in_winter() + local r = region.create(0, 0, "plain") + local f = faction.create("insect", "insect@eressea.de", "de") + local u = unit.create(f, r, 1) + + u:add_item('money', 1000) + u:clear_orders() + u:add_order("REKRUTIERE 1") + set_turn(1010) + process_orders() + assert_equal('winter', get_season(get_turn())) + assert_equal(1, u.number) + + u:clear_orders() + u:add_order("REKRUTIERE 1") + set_turn(1011) + process_orders() + assert_equal('spring', get_season(get_turn())) + assert_equal(2, u.number) +end + +function test_recruit_in_desert() + local r = region.create(0, 0, "desert") + local f = faction.create("insect", "insect@eressea.de", "de") + local u = unit.create(f, r, 1) + + u:add_item('money', 1000) + u:clear_orders() + u:add_order("REKRUTIERE 1") + set_turn(1010) + process_orders() + assert_equal('winter', get_season(get_turn())) + assert_equal(2, u.number) +end + +function bug_1841_test_hunger_in_glacier() + local r = region.create(0, 0, "glacier") + local f = faction.create("insect", "insect@eressea.de", "de") + local u = unit.create(f, r, 1) + + local flags = u.flags + process_orders() + assert_equal(flags+2048, u.flags) +end diff --git a/scripts/tests/spells.lua b/scripts/tests/spells.lua index 1a8442f2e..de56472c3 100644 --- a/scripts/tests/spells.lua +++ b/scripts/tests/spells.lua @@ -81,7 +81,7 @@ function test_create_dreameye() assert_equal(amax - 5, u.aura_max) end -function test_appeasement() +function test_appeasement_can_move() local u1, u2, r1, r2, uno r1 = region.create(0, 0, 'plain') r2 = region.create(1, 0, 'plain') @@ -102,4 +102,32 @@ function test_appeasement() u2 = get_unit(uno) assert_not_nil(u2) assert_equal(r2, u2.region) + assert_equal(5, u2.status) +end + +function test_appeasement_break_guard() + local u1, u2, r1, r2, uno + r1 = region.create(0, 0, 'plain') + r2 = region.create(1, 0, 'plain') + u2 = unit.create(faction.create('human'), r1, 1) + u2.race = 'elf' + u2.name = 'Angsthase' + u2.magic = 'gwyrrd' + u2.guard = true + u2.status = 1 + u2:set_skill('magic', 5) + u2.aura = 10 + u2:add_spell('appeasement') + u2:add_order('BEWACHE') + u2:add_order('KAMPFZAUBER STUFE 1 Friedenslied') + uno = u2.id + u1 = unit.create(faction.create('human'), r1, 1) + u1:set_skill('polearm', 5) + u1:add_order('ATTACKIERE ' .. itoa36(uno)) + process_orders() + u2 = get_unit(uno) + assert_not_nil(u2) + assert_equal(r1, u2.region) + assert_equal(5, u2.status) + assert_equal(false, u2.guard) end diff --git a/src/spells/combatspells.c b/src/spells/combatspells.c index 8c139fb9c..688a389cb 100644 --- a/src/spells/combatspells.c +++ b/src/spells/combatspells.c @@ -1279,7 +1279,7 @@ int sp_appeasement(struct castorder * co) } /* und bewachen nicht */ setguard(mage, false); - /* irgendwie den langen befehl sperren */ + setstatus(mage, ST_FLEE); /* wir tun so, als w�re die Person geflohen */ fi->flags |= FIG_NOLOOT;