From b44c5e54bfb892d304e80c97290596ac55dfc633 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 25 Mar 2017 10:37:13 +0100 Subject: [PATCH] =?UTF-8?q?Neuer=20Befehlespr=C3=A4fix:=20!=20zur=20Unterd?= =?UTF-8?q?r=C3=BCckung=20von=20Fehlern.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/tests/laws.lua | 1 + scripts/tests/orders.lua | 12 +++++++ src/kernel/messages.c | 19 +++++++---- src/kernel/messages.test.c | 18 ++++++++++ src/kernel/order.c | 24 +++++++++---- src/kernel/order.h | 1 + src/kernel/order.test.c | 70 +++++++++++++++++++++++++++++++------- src/monsters.c | 10 ++---- src/piracy.c | 3 ++ src/piracy.test.c | 1 + 10 files changed, 125 insertions(+), 34 deletions(-) diff --git a/scripts/tests/laws.lua b/scripts/tests/laws.lua index 8b64ffb7f..3a724a440 100644 --- a/scripts/tests/laws.lua +++ b/scripts/tests/laws.lua @@ -16,6 +16,7 @@ function setup() "attack" : "ATTACKIERE", "maketemp" : "MACHETEMP", "end" : "ENDE", + "use" : "BENUTZEN", "recruit" : "REKRUTIERE" } }, diff --git a/scripts/tests/orders.lua b/scripts/tests/orders.lua index d88a59293..af0919640 100644 --- a/scripts/tests/orders.lua +++ b/scripts/tests/orders.lua @@ -20,6 +20,18 @@ function setup() eressea.settings.set("NewbieImmunity", "0") end +function test_no_errors() + turn_begin() + u:add_order("!BENUTZEN 23 Yanxspirit") + turn_process() + assert_equal(0, f:count_msg_type('error43')) + u:clear_orders() + u:add_order("BENUTZEN 23 Yanxspirit") + turn_process() + assert_equal(1, f:count_msg_type('error43')) + turn_end() +end + function test_learn() u:add_order("LERNEN Hiebwaffen") _G.process_orders() diff --git a/src/kernel/messages.c b/src/kernel/messages.c index f74e9c0d7..a157e276c 100644 --- a/src/kernel/messages.c +++ b/src/kernel/messages.c @@ -86,9 +86,6 @@ struct message *msg_feedback(const struct unit *u, struct order *ord, variant var; memset(args, 0, sizeof(args)); - if (ord == NULL) - ord = u->thisorder; - if (!mtype) { log_warning("trying to create message of unknown type \"%s\"\n", name); if (!mt_find("missing_feedback")) { @@ -248,8 +245,12 @@ void addmessage(region * r, faction * f, const char *s, msg_t mtype, int level) message * msg_error(const unit * u, struct order *ord, int mno) { static char msgname[20]; - if (fval(u->faction, FFL_NPC)) - return 0; + if (ord && ord->_noerror) { + return NULL; + } + if (fval(u->faction, FFL_NPC)) { + return NULL; + } sprintf(msgname, "error%d", mno); return msg_feedback(u, ord, msgname, ""); } @@ -259,7 +260,9 @@ message * cmistake(const unit * u, struct order *ord, int mno, int mtype) message * result; UNUSED_ARG(mtype); result = msg_error(u, ord, mno); - ADDMSG(&u->faction->msgs, result); + if (result) { + ADDMSG(&u->faction->msgs, result); + } return result; } @@ -267,7 +270,9 @@ void syntax_error(const struct unit *u, struct order *ord) { message * result; result = msg_error(u, ord, 10); - ADDMSG(&u->faction->msgs, result); + if (result) { + ADDMSG(&u->faction->msgs, result); + } } void free_messagelist(mlist *msgs) diff --git a/src/kernel/messages.test.c b/src/kernel/messages.test.c index 7b0f2dd5e..9cc3a138b 100644 --- a/src/kernel/messages.test.c +++ b/src/kernel/messages.test.c @@ -1,6 +1,9 @@ #include #include "messages.h" +#include "unit.h" +#include "order.h" + #include #include @@ -68,11 +71,26 @@ static void test_merge_split(CuTest *tc) { test_cleanup(); } +static void test_noerror(CuTest *tc) { + unit *u; + struct locale *lang; + + test_setup(); + lang = test_create_locale(); + u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL)); + u->thisorder = parse_order("!@move", lang); + CuAssertTrue(tc, u->thisorder->_persistent); + CuAssertTrue(tc, u->thisorder->_noerror); + CuAssertPtrEquals(tc, NULL, msg_error(u, u->thisorder, 100)); + test_cleanup(); +} + CuSuite *get_messages_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_missing_message); SUITE_ADD_TEST(suite, test_merge_split); SUITE_ADD_TEST(suite, test_message); + SUITE_ADD_TEST(suite, test_noerror); return suite; } diff --git a/src/kernel/order.c b/src/kernel/order.c index 776190b67..9e7a45991 100644 --- a/src/kernel/order.c +++ b/src/kernel/order.c @@ -99,6 +99,15 @@ char* get_command(const order *ord, char *sbuffer, size_t size) { keyword_t kwd = ORD_KEYWORD(ord); int bytes; + if (ord->_noerror) { + if (size > 0) { + *bufp++ = '!'; + --size; + } + else { + WARN_STATIC_BUFFER(); + } + } if (ord->_persistent) { if (size > 0) { *bufp++ = '@'; @@ -159,6 +168,7 @@ order *copy_order(const order * src) order *ord = (order *)malloc(sizeof(order)); ord->next = NULL; ord->_persistent = src->_persistent; + ord->_noerror = src->_noerror; ord->data = src->data; ++ord->data->_refcount; return ord; @@ -280,7 +290,7 @@ void close_orders(void) { } static order *create_order_i(keyword_t kwd, const char *sptr, bool persistent, - const struct locale *lang) + bool noerror, const struct locale *lang) { order *ord = NULL; int lindex; @@ -313,6 +323,7 @@ static order *create_order_i(keyword_t kwd, const char *sptr, bool persistent, ord = (order *)malloc(sizeof(order)); ord->_persistent = persistent; + ord->_noerror = noerror; ord->next = NULL; ord->data = create_data(kwd, sptr, lindex); @@ -373,7 +384,7 @@ order *create_order(keyword_t kwd, const struct locale * lang, else { zBuffer[0] = 0; } - return create_order_i(kwd, zBuffer, false, lang); + return create_order_i(kwd, zBuffer, false, false, lang); } order *parse_order(const char *s, const struct locale * lang) @@ -386,11 +397,12 @@ order *parse_order(const char *s, const struct locale * lang) if (*s != 0) { keyword_t kwd; const char *sptr; - bool persistent = false; + bool persistent = false, noerror = false; const char * p; - while (*s == '@') { - persistent = true; + while (*s == '!' || *s=='@') { + if (*s=='!') noerror = true; + else if (*s == '@') persistent = true; ++s; } sptr = s; @@ -407,7 +419,7 @@ order *parse_order(const char *s, const struct locale * lang) if (kwd != NOKEYWORD) { while (isspace(*(unsigned char *)sptr)) ++sptr; s = sptr; - return create_order_i(kwd, s, persistent, lang); + return create_order_i(kwd, s, persistent, noerror, lang); } } return NULL; diff --git a/src/kernel/order.h b/src/kernel/order.h index 7f4b00a5e..bf4d02982 100644 --- a/src/kernel/order.h +++ b/src/kernel/order.h @@ -37,6 +37,7 @@ extern "C" { /* do not access this data: */ struct order_data *data; bool _persistent; + bool _noerror; } order; /* constructor */ diff --git a/src/kernel/order.test.c b/src/kernel/order.test.c index f5eb51c6f..876d75b1e 100644 --- a/src/kernel/order.test.c +++ b/src/kernel/order.test.c @@ -14,14 +14,13 @@ static void test_create_order(CuTest *tc) { order *ord; struct locale * lang; - test_cleanup(); - lang = get_or_create_locale("en"); + test_setup(); + lang = test_create_locale(); - locale_setstring(lang, "keyword::move", "MOVE"); ord = create_order(K_MOVE, lang, "NORTH"); CuAssertPtrNotNull(tc, ord); CuAssertIntEquals(tc, K_MOVE, getkeyword(ord)); - CuAssertStrEquals(tc, "MOVE NORTH", get_command(ord, cmd, sizeof(cmd))); + CuAssertStrEquals(tc, "move NORTH", get_command(ord, cmd, sizeof(cmd))); CuAssertIntEquals(tc, K_MOVE, init_order(ord)); CuAssertStrEquals(tc, "NORTH", getstrtoken()); @@ -34,19 +33,44 @@ static void test_parse_order(CuTest *tc) { order *ord; struct locale * lang; - test_cleanup(); - lang = get_or_create_locale("en"); + test_setup(); + lang = test_create_locale(); - locale_setstring(lang, "keyword::move", "MOVE"); - init_keyword(lang, K_MOVE, "MOVE"); ord = parse_order("MOVE NORTH", lang); CuAssertPtrNotNull(tc, ord); + CuAssertTrue(tc, !ord->_noerror); + CuAssertTrue(tc, !ord->_persistent); CuAssertIntEquals(tc, K_MOVE, getkeyword(ord)); - CuAssertStrEquals(tc, "MOVE NORTH", get_command(ord, cmd, sizeof(cmd))); + CuAssertStrEquals(tc, "move NORTH", get_command(ord, cmd, sizeof(cmd))); CuAssertIntEquals(tc, K_MOVE, init_order(ord)); CuAssertStrEquals(tc, "NORTH", getstrtoken()); free_order(ord); + + ord = parse_order("!MOVE NORTH", lang); + CuAssertPtrNotNull(tc, ord); + CuAssertTrue(tc, ord->_noerror); + CuAssertTrue(tc, !ord->_persistent); + free_order(ord); + + ord = parse_order("@MOVE NORTH", lang); + CuAssertPtrNotNull(tc, ord); + CuAssertTrue(tc, !ord->_noerror); + CuAssertTrue(tc, ord->_persistent); + free_order(ord); + + ord = parse_order("@!MOVE NORTH", lang); + CuAssertPtrNotNull(tc, ord); + CuAssertTrue(tc, ord->_noerror); + CuAssertTrue(tc, ord->_persistent); + free_order(ord); + + ord = parse_order("!@MOVE NORTH", lang); + CuAssertPtrNotNull(tc, ord); + CuAssertTrue(tc, ord->_noerror); + CuAssertTrue(tc, ord->_persistent); + free_order(ord); + test_cleanup(); } @@ -81,7 +105,7 @@ static void test_parse_make_temp(CuTest *tc) { lang = get_or_create_locale("en"); locale_setstring(lang, keyword(K_MAKE), "MAKE"); locale_setstring(lang, keyword(K_MAKETEMP), "MAKETEMP"); - locale_setstring(lang, "TEMP", "TEMP"); + locale_setstring(lang, parameters[P_TEMP], "TEMP"); init_locale(lang); ord = parse_order("M T herp", lang); @@ -156,9 +180,9 @@ static void test_replace_order(CuTest *tc) { struct locale * lang; test_cleanup(); - lang = get_or_create_locale("en"); - orig = create_order(K_MAKE, lang, 0); - repl = create_order(K_ALLY, lang, 0); + lang = test_create_locale(); + orig = create_order(K_MAKE, lang, NULL); + repl = create_order(K_ALLY, lang, NULL); replace_order(&orders, orig, repl); CuAssertPtrEquals(tc, 0, orders); orders = orig; @@ -171,6 +195,25 @@ static void test_replace_order(CuTest *tc) { test_cleanup(); } +static void test_get_command(CuTest *tc) { + struct locale * lang; + order *ord; + char buf[64]; + + test_setup(); + lang = test_create_locale(); + ord = create_order(K_MAKE, lang, "iron"); + CuAssertStrEquals(tc, "make iron", get_command(ord, buf, sizeof(buf))); + ord->_noerror = true; + CuAssertStrEquals(tc, "!make iron", get_command(ord, buf, sizeof(buf))); + ord->_persistent = true; + CuAssertStrEquals(tc, "!@make iron", get_command(ord, buf, sizeof(buf))); + ord->_noerror = false; + CuAssertStrEquals(tc, "@make iron", get_command(ord, buf, sizeof(buf))); + free_order(ord); + test_cleanup(); +} + CuSuite *get_order_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -183,5 +226,6 @@ CuSuite *get_order_suite(void) SUITE_ADD_TEST(suite, test_replace_order); SUITE_ADD_TEST(suite, test_skip_token); SUITE_ADD_TEST(suite, test_getstrtoken); + SUITE_ADD_TEST(suite, test_get_command); return suite; } diff --git a/src/monsters.c b/src/monsters.c index 0d9857024..4edaeedea 100644 --- a/src/monsters.c +++ b/src/monsters.c @@ -493,18 +493,12 @@ static order *make_movement_order(unit * u, const region * target, int moves, if (plan == NULL) return NULL; - bytes = - (int)strlcpy(bufp, - (const char *)LOC(u->faction->locale, keyword(K_MOVE)), size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - while (position != moves && plan[position + 1]) { region *prev = plan[position]; region *next = plan[++position]; direction_t dir = reldirection(prev, next); assert(dir != NODIRECTION && dir != D_SPECIAL); - if (size > 1) { + if (size > 1 && bufp != zOrder) { *bufp++ = ' '; --size; } @@ -516,7 +510,7 @@ static order *make_movement_order(unit * u, const region * target, int moves, } *bufp = 0; - return parse_order(zOrder, u->faction->locale); + return create_order(K_MOVE, u->faction->locale, zOrder); } void random_growl(const unit *u, region *target, int rand) diff --git a/src/piracy.c b/src/piracy.c index 80b1dd47a..3025d484c 100644 --- a/src/piracy.c +++ b/src/piracy.c @@ -66,6 +66,8 @@ static attrib *mk_piracy(const faction * pirate, const faction * target, } static bool validate_pirate(unit *u, order *ord) { + assert(u); + assert(ord); if (fval(u_race(u), RCF_SWIM | RCF_FLY)) return true; if (!u->ship) { @@ -128,6 +130,7 @@ void piracy_cmd(unit * u) int saff = 0; int *il; + assert(u->thisorder); if (!validate_pirate(u, u->thisorder)) { return; } diff --git a/src/piracy.test.c b/src/piracy.test.c index 40e66af18..33860e03f 100644 --- a/src/piracy.test.c +++ b/src/piracy.test.c @@ -137,6 +137,7 @@ static void test_piracy_cmd_errors(CuTest * tc) { u_set_ship(u, test_create_ship(u->region, st_boat)); u2 = test_create_unit(u->faction, u->region); + u2->thisorder = create_order(K_PIRACY, f->locale, ""); u_set_ship(u2, u->ship); test_clear_messages(f);