diff --git a/src/kernel/order.c b/src/kernel/order.c index 7099dab19..b7da372c1 100644 --- a/src/kernel/order.c +++ b/src/kernel/order.c @@ -67,8 +67,6 @@ keyword_t getkeyword(const order * ord) * keywords are expanded to their full length. */ char* get_command(const order *ord, const struct locale *lang, char *sbuffer, size_t size) { - order_data *od = NULL; - const char * text; keyword_t kwd = ORD_KEYWORD(ord); sbstring sbs; @@ -80,28 +78,35 @@ char* get_command(const order *ord, const struct locale *lang, char *sbuffer, si sbs_strcat(&sbs, "@"); } - if (ord->id < 0) { - skill_t sk = (skill_t)(100+ord->id); - assert(kwd == K_STUDY && sk != SK_MAGIC && sk < MAXSKILLS); - text = skillname(sk, lang); - } else { - od = odata_load(ord->id); - text = OD_STRING(od); - } if (kwd != NOKEYWORD) { const char *str = (const char *)LOC(lang, keyword(kwd)); assert(str); sbs_strcat(&sbs, str); - if (text) { - sbs_strcat(&sbs, " "); + if (ord->id < 0) { + skill_t sk = (skill_t)(100+ord->id); + assert(kwd == K_STUDY && sk != SK_MAGIC && sk < MAXSKILLS); + str = skillname(sk, lang); + if (str) { + if (strchr(str, ' ') == NULL) { + sbs_strcat(&sbs, " "); + sbs_strcat(&sbs, str); + } + else { + sbs_strcat(&sbs, " '"); + sbs_strcat(&sbs, str); + sbs_strcat(&sbs, "'"); + } + } + } else { + order_data *od = odata_load(ord->id); + str = OD_STRING(od); + if (str) { + sbs_strcat(&sbs, " "); + sbs_strcat(&sbs, str); + } + odata_release(od); } } - if (text) { - sbs_strcat(&sbs, text); - } - if (od) { - odata_release(od); - } return sbuffer; } @@ -118,30 +123,38 @@ int stream_order(struct stream *out, const struct order *ord, const struct local swrite("@", 1, 1, out); } - if (ord->id < 0) { - skill_t sk = (skill_t)(100 + ord->id); - assert(kwd == K_STUDY && sk != SK_MAGIC && sk < MAXSKILLS); - text = skillname(sk, lang); - } - else { - od = odata_load(ord->id); - text = OD_STRING(od); - } if (kwd != NOKEYWORD) { const char *str = (const char *)LOC(lang, keyword(kwd)); assert(str); swrite(str, 1, strlen(str), out); } - if (text) { - char obuf[1024]; - swrite(" ", 1, 1, out); - if (escape) { - text = str_escape(text, obuf, sizeof(obuf)); + if (ord->id < 0) { + skill_t sk = (skill_t)(100 + ord->id); + + assert(kwd == K_STUDY && sk != SK_MAGIC && sk < MAXSKILLS); + text = skillname(sk, lang); + if (strchr(text, ' ') != NULL) { + swrite(" '", 1, 2, out); + swrite(text, 1, strlen(text), out); + swrite("'", 1, 1, out); + } + else { + swrite(" ", 1, 1, out); + swrite(text, 1, strlen(text), out); } - swrite(text, 1, strlen(text), out); } - if (od) { + else { + od = odata_load(ord->id); + text = OD_STRING(od); + if (text) { + char obuf[1024]; + swrite(" ", 1, 1, out); + if (escape) { + text = str_escape(text, obuf, sizeof(obuf)); + } + swrite(text, 1, strlen(text), out); + } odata_release(od); } @@ -514,11 +527,27 @@ keyword_t init_order(const struct order *ord, const struct locale *lang) parser_od = NULL; } if (ord->id < 0) { + const char *str; skill_t sk = (skill_t)(100 + ord->id); + assert(sk < MAXSKILLS); assert(lang); assert(kwd == K_STUDY); - init_tokens_str(skillname(sk, lang)); + str = skillname(sk, lang); + if (strchr(str, ' ') == NULL) { + init_tokens_str(str); + } + else { + char token[32], *dup; + size_t len = strlen(str); + assert(len + 3 < sizeof(token)); + token[0] = '\''; + memcpy(token + 1, str, len); + token[len + 1] = '\''; + token[len + 2] = '\0'; + dup = str_strdup(token); + init_tokens_ex(dup, dup, free); + } } else { const char *str; diff --git a/src/kernel/order.test.c b/src/kernel/order.test.c index 74679db6e..acba56f0f 100644 --- a/src/kernel/order.test.c +++ b/src/kernel/order.test.c @@ -3,10 +3,14 @@ #include "order.h" #include +#include #include #include +#include +#include + #include #include #include @@ -331,11 +335,73 @@ static void test_study_orders(CuTest *tc) { test_teardown(); } +static void test_study_order(CuTest *tc) { + char token[32]; + stream out; + unit *u; + struct locale *lang; + + test_setup(); + lang = get_or_create_locale("de"); + locale_setstring(lang, mkname("skill", skillnames[SK_ALCHEMY]), "Alchemie"); + locale_setstring(lang, "keyword::study", "LERNE"); + init_keywords(lang); + init_skills(lang); + u = test_create_unit(test_create_faction(NULL), test_create_plain(0, 0)); + u->thisorder = create_order(K_STUDY, lang, "ALCH"); + CuAssertIntEquals(tc, K_STUDY, init_order(u->thisorder, lang)); + CuAssertStrEquals(tc, skillname(SK_ALCHEMY, lang), gettoken(token, sizeof(token))); + + CuAssertStrEquals(tc, "LERNE Alchemie", get_command(u->thisorder, lang, token, sizeof(token))); + + mstream_init(&out); + stream_order(&out, u->thisorder, lang, true); + swrite("\n", 1, 1, &out); + out.api->rewind(out.handle); + out.api->readln(out.handle, token, sizeof(token)); + CuAssertStrEquals(tc, "LERNE Alchemie", token); + mstream_done(&out); + + test_teardown(); +} + +static void test_study_order_quoted(CuTest *tc) { + char token[32]; + stream out; + unit *u; + struct locale *lang; + + test_setup(); + lang = get_or_create_locale("de"); + locale_setstring(lang, mkname("skill", skillnames[SK_WEAPONLESS]), "Waffenloser Kampf"); + locale_setstring(lang, "keyword::study", "LERNE"); + init_keywords(lang); + init_skills(lang); + u = test_create_unit(test_create_faction(NULL), test_create_plain(0, 0)); + u->thisorder = create_order(K_STUDY, lang, "Waffenloser~Kampf"); + CuAssertIntEquals(tc, K_STUDY, init_order(u->thisorder, lang)); + CuAssertStrEquals(tc, skillname(SK_WEAPONLESS, lang), gettoken(token, sizeof(token))); + + CuAssertStrEquals(tc, "LERNE 'Waffenloser Kampf'", get_command(u->thisorder, lang, token, sizeof(token))); + + mstream_init(&out); + stream_order(&out, u->thisorder, lang, true); + swrite("\n", 1, 1, &out); + out.api->rewind(out.handle); + out.api->readln(out.handle, token, sizeof(token)); + CuAssertStrEquals(tc, "LERNE 'Waffenloser Kampf'", token); + mstream_done(&out); + + test_teardown(); +} + CuSuite *get_order_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_create_order); SUITE_ADD_TEST(suite, test_study_orders); + SUITE_ADD_TEST(suite, test_study_order); + SUITE_ADD_TEST(suite, test_study_order_quoted); SUITE_ADD_TEST(suite, test_parse_order); SUITE_ADD_TEST(suite, test_parse_make); SUITE_ADD_TEST(suite, test_parse_make_temp); diff --git a/storage b/storage index d807ef5ce..5623ee652 160000 --- a/storage +++ b/storage @@ -1 +1 @@ -Subproject commit d807ef5ce64b3425b31fb440e0b93a4d233f517a +Subproject commit 5623ee6527e97af20c7d8efc03800b6fe1579744