diff --git a/src/kernel/save.c b/src/kernel/save.c index eb072c03d..1c55db3ea 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -122,6 +122,41 @@ char *rns(FILE * f, char *c, size_t size) return c; } +struct order *read_order(const char *s, const struct locale *lang) { + assert(s); + assert(lang); + if (s[0]) { + keyword_t kwd; + char token[64]; + const char *stok; + + stok = parse_token(&s, token, sizeof(token)); + if (stok) { + param_t param = findparam(token, lang); + switch (param) { + case P_UNIT: + case P_REGION: + return NULL; + case P_FACTION: + case P_NEXT: + case P_GAMENAME: + /* these terminate the orders, so we apply extra checking */ + if (strlen(stok) >= 3) { + return NULL; + } + break; + default: + break; + } + } + /* Nun wird der Befehl erzeut und eingehängt */ + kwd = get_keyword(stok, lang); + if (kwd != NOKEYWORD) { + return create_order(kwd, lang, s); + } + } + return NULL; +} static unit *unitorders(FILE * F, int enc, struct faction *f) { @@ -164,6 +199,7 @@ static unit *unitorders(FILE * F, int enc, struct faction *f) for (;;) { const char *s; + order * ord; /* Erst wenn wir sicher sind, dass kein Befehl * eingegeben wurde, checken wir, ob nun eine neue * Einheit oder ein neuer Spieler drankommt */ @@ -172,49 +208,13 @@ static unit *unitorders(FILE * F, int enc, struct faction *f) if (s == NULL) break; - if (s[0]) { - if (s[0] != '@') { - char token[64]; - const char *stok = s; - stok = parse_token(&stok, token, sizeof(token)); - - if (stok) { - bool quit = false; - param_t param = findparam(stok, u->faction->locale); - switch (param) { - case P_UNIT: - case P_REGION: - quit = true; - break; - case P_FACTION: - case P_NEXT: - case P_GAMENAME: - /* these terminate the orders, so we apply extra checking */ - if (strlen(stok) >= 3) { - quit = true; - break; - } - else { - quit = false; - } - break; - default: - break; - } - if (quit) { - break; - } - } - } - /* Nun wird der Befehl erzeut und eingehängt */ - *ordp = parse_order(s, u->faction->locale); - if (*ordp) { - ordp = &(*ordp)->next; - } - else { - ADDMSG(&f->msgs, msg_message("parse_error", "unit command", u, s)); - } + ord = read_order(s, f->locale); + if (!ord) { + ADDMSG(&f->msgs, msg_message("parse_error", "unit command", u, s)); + break; } + *ordp = ord; + ordp = &(*ordp)->next; } } @@ -304,7 +304,7 @@ int readorders(const char *filename) } init_tokens_str(b); s = gettoken(token, sizeof(token)); - p = (s && s[0] != '@') ? findparam(s, lang) : NOPARAM; + p = (s && s[0] != '@' && s[0] != '!') ? findparam(s, lang) : NOPARAM; } while ((p != P_UNIT || !f) && p != P_FACTION && p != P_NEXT && p != P_GAMENAME); } diff --git a/src/kernel/save.h b/src/kernel/save.h index 763ff66b6..f706a311b 100644 --- a/src/kernel/save.h +++ b/src/kernel/save.h @@ -31,6 +31,8 @@ extern "C" { struct spellbook; struct unit; struct building; + struct order; + struct locale; struct faction; struct region; struct ship; @@ -43,6 +45,8 @@ extern "C" { /* TODO: is this *really* still in use? */ extern int enc_gamedata; + struct order *read_order(const char *s, const struct locale *lang); + int readorders(const char *filename); int readgame(const char *filename); int writegame(const char *filename); diff --git a/src/kernel/save.test.c b/src/kernel/save.test.c index 81d5a507d..f70d6ff07 100644 --- a/src/kernel/save.test.c +++ b/src/kernel/save.test.c @@ -5,6 +5,7 @@ #include #include "save.h" +#include "order.h" #include "version.h" #include "building.h" #include "ship.h" @@ -452,6 +453,25 @@ static void test_version_no(CuTest *tc) { CuAssertIntEquals(tc, 0x10203, version_no("1.2.3-what.is.42")); } +static void test_read_order(CuTest *tc) { + char cmd[32]; + order *ord; + struct locale * lang; + + test_setup(); + lang = test_create_locale(); + + ord = read_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))); + free_order(ord); + + test_cleanup(); +} + CuSuite *get_save_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -468,6 +488,7 @@ CuSuite *get_save_suite(void) SUITE_ADD_TEST(suite, test_readwrite_dead_faction_group); SUITE_ADD_TEST(suite, test_read_password); SUITE_ADD_TEST(suite, test_read_password_external); + SUITE_ADD_TEST(suite, test_read_order); SUITE_ADD_TEST(suite, test_version_no); return suite;