Neuer Befehlespräfix: ! zur Unterdrückung von Fehlern.

This commit is contained in:
Enno Rehling 2017-03-25 10:37:13 +01:00
parent f941c5552f
commit b44c5e54bf
10 changed files with 125 additions and 34 deletions

View file

@ -16,6 +16,7 @@ function setup()
"attack" : "ATTACKIERE", "attack" : "ATTACKIERE",
"maketemp" : "MACHETEMP", "maketemp" : "MACHETEMP",
"end" : "ENDE", "end" : "ENDE",
"use" : "BENUTZEN",
"recruit" : "REKRUTIERE" "recruit" : "REKRUTIERE"
} }
}, },

View file

@ -20,6 +20,18 @@ function setup()
eressea.settings.set("NewbieImmunity", "0") eressea.settings.set("NewbieImmunity", "0")
end 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() function test_learn()
u:add_order("LERNEN Hiebwaffen") u:add_order("LERNEN Hiebwaffen")
_G.process_orders() _G.process_orders()

View file

@ -86,9 +86,6 @@ struct message *msg_feedback(const struct unit *u, struct order *ord,
variant var; variant var;
memset(args, 0, sizeof(args)); memset(args, 0, sizeof(args));
if (ord == NULL)
ord = u->thisorder;
if (!mtype) { if (!mtype) {
log_warning("trying to create message of unknown type \"%s\"\n", name); log_warning("trying to create message of unknown type \"%s\"\n", name);
if (!mt_find("missing_feedback")) { 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) { message * msg_error(const unit * u, struct order *ord, int mno) {
static char msgname[20]; static char msgname[20];
if (fval(u->faction, FFL_NPC)) if (ord && ord->_noerror) {
return 0; return NULL;
}
if (fval(u->faction, FFL_NPC)) {
return NULL;
}
sprintf(msgname, "error%d", mno); sprintf(msgname, "error%d", mno);
return msg_feedback(u, ord, msgname, ""); return msg_feedback(u, ord, msgname, "");
} }
@ -259,7 +260,9 @@ message * cmistake(const unit * u, struct order *ord, int mno, int mtype)
message * result; message * result;
UNUSED_ARG(mtype); UNUSED_ARG(mtype);
result = msg_error(u, ord, mno); result = msg_error(u, ord, mno);
ADDMSG(&u->faction->msgs, result); if (result) {
ADDMSG(&u->faction->msgs, result);
}
return result; return result;
} }
@ -267,7 +270,9 @@ void syntax_error(const struct unit *u, struct order *ord)
{ {
message * result; message * result;
result = msg_error(u, ord, 10); result = msg_error(u, ord, 10);
ADDMSG(&u->faction->msgs, result); if (result) {
ADDMSG(&u->faction->msgs, result);
}
} }
void free_messagelist(mlist *msgs) void free_messagelist(mlist *msgs)

View file

@ -1,6 +1,9 @@
#include <platform.h> #include <platform.h>
#include "messages.h" #include "messages.h"
#include "unit.h"
#include "order.h"
#include <CuTest.h> #include <CuTest.h>
#include <tests.h> #include <tests.h>
@ -68,11 +71,26 @@ static void test_merge_split(CuTest *tc) {
test_cleanup(); 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 *get_messages_suite(void) {
CuSuite *suite = CuSuiteNew(); CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_missing_message); SUITE_ADD_TEST(suite, test_missing_message);
SUITE_ADD_TEST(suite, test_merge_split); SUITE_ADD_TEST(suite, test_merge_split);
SUITE_ADD_TEST(suite, test_message); SUITE_ADD_TEST(suite, test_message);
SUITE_ADD_TEST(suite, test_noerror);
return suite; return suite;
} }

View file

@ -99,6 +99,15 @@ char* get_command(const order *ord, char *sbuffer, size_t size) {
keyword_t kwd = ORD_KEYWORD(ord); keyword_t kwd = ORD_KEYWORD(ord);
int bytes; int bytes;
if (ord->_noerror) {
if (size > 0) {
*bufp++ = '!';
--size;
}
else {
WARN_STATIC_BUFFER();
}
}
if (ord->_persistent) { if (ord->_persistent) {
if (size > 0) { if (size > 0) {
*bufp++ = '@'; *bufp++ = '@';
@ -159,6 +168,7 @@ order *copy_order(const order * src)
order *ord = (order *)malloc(sizeof(order)); order *ord = (order *)malloc(sizeof(order));
ord->next = NULL; ord->next = NULL;
ord->_persistent = src->_persistent; ord->_persistent = src->_persistent;
ord->_noerror = src->_noerror;
ord->data = src->data; ord->data = src->data;
++ord->data->_refcount; ++ord->data->_refcount;
return ord; return ord;
@ -280,7 +290,7 @@ void close_orders(void) {
} }
static order *create_order_i(keyword_t kwd, const char *sptr, bool persistent, 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; order *ord = NULL;
int lindex; 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 = (order *)malloc(sizeof(order));
ord->_persistent = persistent; ord->_persistent = persistent;
ord->_noerror = noerror;
ord->next = NULL; ord->next = NULL;
ord->data = create_data(kwd, sptr, lindex); ord->data = create_data(kwd, sptr, lindex);
@ -373,7 +384,7 @@ order *create_order(keyword_t kwd, const struct locale * lang,
else { else {
zBuffer[0] = 0; 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) 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) { if (*s != 0) {
keyword_t kwd; keyword_t kwd;
const char *sptr; const char *sptr;
bool persistent = false; bool persistent = false, noerror = false;
const char * p; const char * p;
while (*s == '@') { while (*s == '!' || *s=='@') {
persistent = true; if (*s=='!') noerror = true;
else if (*s == '@') persistent = true;
++s; ++s;
} }
sptr = s; sptr = s;
@ -407,7 +419,7 @@ order *parse_order(const char *s, const struct locale * lang)
if (kwd != NOKEYWORD) { if (kwd != NOKEYWORD) {
while (isspace(*(unsigned char *)sptr)) ++sptr; while (isspace(*(unsigned char *)sptr)) ++sptr;
s = sptr; s = sptr;
return create_order_i(kwd, s, persistent, lang); return create_order_i(kwd, s, persistent, noerror, lang);
} }
} }
return NULL; return NULL;

View file

@ -37,6 +37,7 @@ extern "C" {
/* do not access this data: */ /* do not access this data: */
struct order_data *data; struct order_data *data;
bool _persistent; bool _persistent;
bool _noerror;
} order; } order;
/* constructor */ /* constructor */

View file

@ -14,14 +14,13 @@ static void test_create_order(CuTest *tc) {
order *ord; order *ord;
struct locale * lang; struct locale * lang;
test_cleanup(); test_setup();
lang = get_or_create_locale("en"); lang = test_create_locale();
locale_setstring(lang, "keyword::move", "MOVE");
ord = create_order(K_MOVE, lang, "NORTH"); ord = create_order(K_MOVE, lang, "NORTH");
CuAssertPtrNotNull(tc, ord); CuAssertPtrNotNull(tc, ord);
CuAssertIntEquals(tc, K_MOVE, getkeyword(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)); CuAssertIntEquals(tc, K_MOVE, init_order(ord));
CuAssertStrEquals(tc, "NORTH", getstrtoken()); CuAssertStrEquals(tc, "NORTH", getstrtoken());
@ -34,19 +33,44 @@ static void test_parse_order(CuTest *tc) {
order *ord; order *ord;
struct locale * lang; struct locale * lang;
test_cleanup(); test_setup();
lang = get_or_create_locale("en"); lang = test_create_locale();
locale_setstring(lang, "keyword::move", "MOVE");
init_keyword(lang, K_MOVE, "MOVE");
ord = parse_order("MOVE NORTH", lang); ord = parse_order("MOVE NORTH", lang);
CuAssertPtrNotNull(tc, ord); CuAssertPtrNotNull(tc, ord);
CuAssertTrue(tc, !ord->_noerror);
CuAssertTrue(tc, !ord->_persistent);
CuAssertIntEquals(tc, K_MOVE, getkeyword(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)); CuAssertIntEquals(tc, K_MOVE, init_order(ord));
CuAssertStrEquals(tc, "NORTH", getstrtoken()); CuAssertStrEquals(tc, "NORTH", getstrtoken());
free_order(ord); 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(); test_cleanup();
} }
@ -81,7 +105,7 @@ static void test_parse_make_temp(CuTest *tc) {
lang = get_or_create_locale("en"); lang = get_or_create_locale("en");
locale_setstring(lang, keyword(K_MAKE), "MAKE"); locale_setstring(lang, keyword(K_MAKE), "MAKE");
locale_setstring(lang, keyword(K_MAKETEMP), "MAKETEMP"); locale_setstring(lang, keyword(K_MAKETEMP), "MAKETEMP");
locale_setstring(lang, "TEMP", "TEMP"); locale_setstring(lang, parameters[P_TEMP], "TEMP");
init_locale(lang); init_locale(lang);
ord = parse_order("M T herp", lang); ord = parse_order("M T herp", lang);
@ -156,9 +180,9 @@ static void test_replace_order(CuTest *tc) {
struct locale * lang; struct locale * lang;
test_cleanup(); test_cleanup();
lang = get_or_create_locale("en"); lang = test_create_locale();
orig = create_order(K_MAKE, lang, 0); orig = create_order(K_MAKE, lang, NULL);
repl = create_order(K_ALLY, lang, 0); repl = create_order(K_ALLY, lang, NULL);
replace_order(&orders, orig, repl); replace_order(&orders, orig, repl);
CuAssertPtrEquals(tc, 0, orders); CuAssertPtrEquals(tc, 0, orders);
orders = orig; orders = orig;
@ -171,6 +195,25 @@ static void test_replace_order(CuTest *tc) {
test_cleanup(); 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 *get_order_suite(void)
{ {
CuSuite *suite = CuSuiteNew(); CuSuite *suite = CuSuiteNew();
@ -183,5 +226,6 @@ CuSuite *get_order_suite(void)
SUITE_ADD_TEST(suite, test_replace_order); SUITE_ADD_TEST(suite, test_replace_order);
SUITE_ADD_TEST(suite, test_skip_token); SUITE_ADD_TEST(suite, test_skip_token);
SUITE_ADD_TEST(suite, test_getstrtoken); SUITE_ADD_TEST(suite, test_getstrtoken);
SUITE_ADD_TEST(suite, test_get_command);
return suite; return suite;
} }

View file

@ -493,18 +493,12 @@ static order *make_movement_order(unit * u, const region * target, int moves,
if (plan == NULL) if (plan == NULL)
return 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]) { while (position != moves && plan[position + 1]) {
region *prev = plan[position]; region *prev = plan[position];
region *next = plan[++position]; region *next = plan[++position];
direction_t dir = reldirection(prev, next); direction_t dir = reldirection(prev, next);
assert(dir != NODIRECTION && dir != D_SPECIAL); assert(dir != NODIRECTION && dir != D_SPECIAL);
if (size > 1) { if (size > 1 && bufp != zOrder) {
*bufp++ = ' '; *bufp++ = ' ';
--size; --size;
} }
@ -516,7 +510,7 @@ static order *make_movement_order(unit * u, const region * target, int moves,
} }
*bufp = 0; *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) void random_growl(const unit *u, region *target, int rand)

View file

@ -66,6 +66,8 @@ static attrib *mk_piracy(const faction * pirate, const faction * target,
} }
static bool validate_pirate(unit *u, order *ord) { static bool validate_pirate(unit *u, order *ord) {
assert(u);
assert(ord);
if (fval(u_race(u), RCF_SWIM | RCF_FLY)) if (fval(u_race(u), RCF_SWIM | RCF_FLY))
return true; return true;
if (!u->ship) { if (!u->ship) {
@ -128,6 +130,7 @@ void piracy_cmd(unit * u)
int saff = 0; int saff = 0;
int *il; int *il;
assert(u->thisorder);
if (!validate_pirate(u, u->thisorder)) { if (!validate_pirate(u, u->thisorder)) {
return; return;
} }

View file

@ -137,6 +137,7 @@ static void test_piracy_cmd_errors(CuTest * tc) {
u_set_ship(u, test_create_ship(u->region, st_boat)); u_set_ship(u, test_create_ship(u->region, st_boat));
u2 = test_create_unit(u->faction, u->region); u2 = test_create_unit(u->faction, u->region);
u2->thisorder = create_order(K_PIRACY, f->locale, "");
u_set_ship(u2, u->ship); u_set_ship(u2, u->ship);
test_clear_messages(f); test_clear_messages(f);