diff --git a/src/economy.c b/src/economy.c index 1ee34fb9a..9d4c80ca0 100644 --- a/src/economy.c +++ b/src/economy.c @@ -1278,7 +1278,7 @@ int make_cmd(unit * u, struct order *ord) s = gettoken(token, sizeof(token)); if (s) { - m = atoi((const char *)s); + m = atoip(s); sprintf(ibuf, "%d", m); if (!strcmp(ibuf, (const char *)s)) { /* a quantity was given */ @@ -1882,7 +1882,7 @@ static bool sell(unit * u, request ** sellorders, struct order *ord) } } else { - n = s ? atoi(s) : 0; + n = s ? atoip(s) : 0; if (n == 0) { cmistake(u, ord, 27, MSG_COMMERCE); return false; @@ -2274,7 +2274,7 @@ static void breed_cmd(unit * u, struct order *ord) (void)init_order(ord); s = gettoken(token, sizeof(token)); - m = s ? atoi((const char *)s) : 0; + m = s ? atoip(s) : 0; if (m != 0) { /* first came a want-paramter */ s = gettoken(token, sizeof(token)); diff --git a/src/give.c b/src/give.c index 8f87cded3..781f39ca6 100644 --- a/src/give.c +++ b/src/give.c @@ -600,16 +600,19 @@ void give_cmd(unit * u, order * ord) } if (u2 && u_race(u2) == get_race(RC_SPELL)) { - ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "feedback_unit_not_found", - "")); + ADDMSG(&u->faction->msgs, msg_feedback(u, ord, + "feedback_unit_not_found", "")); return; } - else if (u2 && !alliedunit(u2, u->faction, HELP_GIVE) && !ucontact(u2, u)) { cmistake(u, ord, 40, MSG_COMMERCE); return; } - + else if (p == NOPARAM) { + /* the most likely case: giving items to someone. + * let's catch this and save ourselves the rest of the param_t checks. + */ + } else if (p == P_HERBS) { bool given = false; if ((u_race(u)->ec_flags & ECF_KEEP_ITEM) && u2 != NULL) { diff --git a/src/give.test.c b/src/give.test.c index c719ddd5c..0d6149750 100644 --- a/src/give.test.c +++ b/src/give.test.c @@ -23,6 +23,7 @@ #include struct give { + struct locale * lang; struct unit *src, *dst; struct region *r; struct faction *f1, *f2; @@ -46,10 +47,15 @@ static void setup_give(struct give *env) { ally * al = ally_add(&env->f2->allies, env->f1); al->status = HELP_GIVE; } + if (env->lang) { + locale_setstring(env->lang, env->itype->rtype->_name, "SILBER"); + init_locale(env->lang); + env->f1->locale = env->lang; + } } static void test_give_unit_to_peasants(CuTest * tc) { - struct give env; + struct give env = { 0 }; test_setup(); env.f1 = test_create_faction(0); env.f2 = 0; @@ -62,7 +68,7 @@ static void test_give_unit_to_peasants(CuTest * tc) { } static void test_give_unit(CuTest * tc) { - struct give env; + struct give env = { 0 }; test_setup(); env.f1 = test_create_faction(0); env.f2 = test_create_faction(0); @@ -81,7 +87,7 @@ static void test_give_unit(CuTest * tc) { } static void test_give_unit_in_ocean(CuTest * tc) { - struct give env; + struct give env = { 0 }; test_setup(); env.f1 = test_create_faction(0); env.f2 = 0; @@ -93,7 +99,7 @@ static void test_give_unit_in_ocean(CuTest * tc) { } static void test_give_men(CuTest * tc) { - struct give env; + struct give env = { 0 }; test_setup(); env.f2 = env.f1 = test_create_faction(0); setup_give(&env); @@ -104,7 +110,7 @@ static void test_give_men(CuTest * tc) { } static void test_give_men_magicians(CuTest * tc) { - struct give env; + struct give env = { 0 }; int p; message * msg; @@ -135,7 +141,7 @@ static void test_give_men_magicians(CuTest * tc) { } static void test_give_men_limit(CuTest * tc) { - struct give env; + struct give env = { 0 }; message *msg; test_setup(); env.f2 = test_create_faction(0); @@ -165,7 +171,7 @@ static void test_give_men_limit(CuTest * tc) { } static void test_give_men_in_ocean(CuTest * tc) { - struct give env; + struct give env = { 0 }; message * msg; test_setup(); @@ -181,7 +187,7 @@ static void test_give_men_in_ocean(CuTest * tc) { } static void test_give_men_too_many(CuTest * tc) { - struct give env; + struct give env = { 0 }; test_setup(); env.f2 = env.f1 = test_create_faction(0); setup_give(&env); @@ -192,7 +198,7 @@ static void test_give_men_too_many(CuTest * tc) { } static void test_give_men_none(CuTest * tc) { - struct give env; + struct give env = { 0 }; message * msg; test_setup(); @@ -207,7 +213,7 @@ static void test_give_men_none(CuTest * tc) { } static void test_give_men_other_faction(CuTest * tc) { - struct give env; + struct give env = { 0 }; message * msg; test_setup(); @@ -224,7 +230,7 @@ static void test_give_men_other_faction(CuTest * tc) { } static void test_give_men_requires_contact(CuTest * tc) { - struct give env; + struct give env = { 0 }; message * msg; order *ord; char cmd[32]; @@ -251,7 +257,7 @@ static void test_give_men_requires_contact(CuTest * tc) { } static void test_give_men_not_to_self(CuTest * tc) { - struct give env; + struct give env = { 0 }; message * msg; test_setup(); env.f2 = env.f1 = test_create_faction(0); @@ -264,7 +270,7 @@ static void test_give_men_not_to_self(CuTest * tc) { } static void test_give_peasants(CuTest * tc) { - struct give env; + struct give env = { 0 }; message * msg; test_setup(); @@ -281,7 +287,7 @@ static void test_give_peasants(CuTest * tc) { } static void test_give(CuTest * tc) { - struct give env; + struct give env = { 0 }; test_setup(); env.f2 = env.f1 = test_create_faction(0); @@ -298,8 +304,31 @@ static void test_give(CuTest * tc) { test_cleanup(); } +static void test_give_cmd(CuTest * tc) { + struct give env = { 0 }; + struct order *ord; + char cmd[32]; + + test_setup(); + env.lang = test_create_locale(); + env.f2 = env.f1 = test_create_faction(0); + setup_give(&env); + + i_change(&env.src->items, env.itype, 10); + + _snprintf(cmd, sizeof(cmd), "%s 5 %s", itoa36(env.dst->no), LOC(env.f1->locale, env.itype->rtype->_name)); + ord = create_order(K_GIVE, env.f1->locale, cmd); + assert(ord); + give_cmd(env.src, ord); + CuAssertIntEquals(tc, 5, i_get(env.src->items, env.itype)); + CuAssertIntEquals(tc, 5, i_get(env.dst->items, env.itype)); + + free_order(ord); + test_cleanup(); +} + static void test_give_herbs(CuTest * tc) { - struct give env; + struct give env = { 0 }; struct order *ord; char cmd[32]; @@ -321,7 +350,7 @@ static void test_give_herbs(CuTest * tc) { } static void test_give_okay(CuTest * tc) { - struct give env; + struct give env = { 0 }; test_setup(); env.f2 = env.f1 = test_create_faction(0); @@ -333,7 +362,7 @@ static void test_give_okay(CuTest * tc) { } static void test_give_denied_by_rules(CuTest * tc) { - struct give env; + struct give env = { 0 }; struct message *msg; test_setup(); @@ -348,7 +377,7 @@ static void test_give_denied_by_rules(CuTest * tc) { } static void test_give_dead_unit(CuTest * tc) { - struct give env; + struct give env = { 0 }; struct message *msg; test_setup(); @@ -363,7 +392,7 @@ static void test_give_dead_unit(CuTest * tc) { } static void test_give_new_unit(CuTest * tc) { - struct give env; + struct give env = { 0 }; test_setup(); env.f1 = test_create_faction(0); @@ -377,7 +406,7 @@ static void test_give_new_unit(CuTest * tc) { static void test_give_invalid_target(CuTest *tc) { // bug https://bugs.eressea.de/view.php?id=1685 - struct give env; + struct give env = { 0 }; order *ord; test_setup(); @@ -400,6 +429,7 @@ CuSuite *get_give_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_give); + SUITE_ADD_TEST(suite, test_give_cmd); SUITE_ADD_TEST(suite, test_give_men); SUITE_ADD_TEST(suite, test_give_men_magicians); SUITE_ADD_TEST(suite, test_give_men_limit); diff --git a/src/kernel/types.h b/src/kernel/types.h index 5187f9aec..da4fefecf 100644 --- a/src/kernel/types.h +++ b/src/kernel/types.h @@ -136,7 +136,7 @@ typedef enum { P_TREES, P_ALLIANCE, MAXPARAMS, - NOPARAM = -1 + NOPARAM } param_t; typedef enum { /* Fehler und Meldungen im Report */ diff --git a/src/keyword.c b/src/keyword.c index 0bd699836..199811669 100644 --- a/src/keyword.c +++ b/src/keyword.c @@ -14,6 +14,9 @@ const char * keyword(keyword_t kwd) { static char result[32]; // FIXME: static return value + if (kwd==NOKEYWORD) { + return NULL; + } if (!result[0]) { strcpy(result, "keyword::"); } diff --git a/src/keyword.test.c b/src/keyword.test.c index 903eb0c13..75c31904a 100644 --- a/src/keyword.test.c +++ b/src/keyword.test.c @@ -11,11 +11,13 @@ static void test_init_keywords(CuTest *tc) { struct locale *lang; - test_cleanup(); + test_setup(); lang = get_or_create_locale("en"); locale_setstring(lang, "keyword::move", "MOVE"); init_keywords(lang); CuAssertIntEquals(tc, K_MOVE, get_keyword("move", lang)); + CuAssertStrEquals(tc, "keyword::move", keyword(K_MOVE)); + CuAssertPtrEquals(tc, NULL, (void *)keyword(NOKEYWORD)); test_cleanup(); } diff --git a/src/laws.c b/src/laws.c index f5d65efc5..33fd56779 100644 --- a/src/laws.c +++ b/src/laws.c @@ -3693,7 +3693,7 @@ int use_cmd(unit * u, struct order *ord) cmistake(u, ord, 43, MSG_PRODUCE); return err; } - n = atoi((const char *)t); + n = atoip((const char *)t); if (n == 0) { if (isparam(t, u->faction->locale, P_ANY)) { /* BENUTZE ALLES Yanxspirit */ @@ -3841,7 +3841,7 @@ int claim_cmd(unit * u, struct order *ord) t = gettoken(token, sizeof(token)); if (t) { - n = atoi((const char *)t); + n = atoip((const char *)t); if (n == 0) { n = 1; } diff --git a/src/magic.c b/src/magic.c index 1ac2255c1..803f20c78 100644 --- a/src/magic.c +++ b/src/magic.c @@ -376,7 +376,7 @@ static int read_seenspell(attrib * a, void *owner, struct gamedata *data) char token[32]; READ_TOK(store, token, sizeof(token)); - i = atoi(token); + i = atoip(token); if (i != 0) { sp = find_spellbyid((unsigned int)i); } diff --git a/src/util/parser.c b/src/util/parser.c index 741fd573f..0fbde6769 100644 --- a/src/util/parser.c +++ b/src/util/parser.c @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -250,7 +251,7 @@ unsigned int atoip(const char *s) int n; assert(s); - n = atoi(s); + n = isdigit(s[0]) ? atoi(s) : 0; if (n < 0) n = 0; diff --git a/src/util/parser.test.c b/src/util/parser.test.c index da0d8dacb..c7ac0bb05 100644 --- a/src/util/parser.test.c +++ b/src/util/parser.test.c @@ -2,8 +2,16 @@ #include "parser.h" #include +#include #include +static void test_atoip(CuTest *tc) { + CuAssertIntEquals(tc, 0, atoip("ALLES")); + CuAssertIntEquals(tc, 0, errno); + CuAssertIntEquals(tc, 42, atoip("42")); + CuAssertIntEquals(tc, 0, atoip("-1")); +} + static void test_parse_token(CuTest *tc) { char lbuf[8]; const char *tok; @@ -103,12 +111,6 @@ static void test_getstrtoken(CuTest *tc) { CuAssertPtrEquals(tc, NULL, (void *)getstrtoken()); } -static void test_atoip(CuTest *tc) { - CuAssertIntEquals(tc, 42, atoip("42")); - CuAssertIntEquals(tc, 0, atoip("-42")); - CuAssertIntEquals(tc, 0, atoip("NOPE")); -} - CuSuite *get_parser_suite(void) { CuSuite *suite = CuSuiteNew();