From 41e8c13a0c1a5620daf1ef57c69fb8b8d0605742 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 17 Aug 2014 18:20:04 +0200 Subject: [PATCH 01/26] I do not like contractions. --- res/core/messages.xml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/res/core/messages.xml b/res/core/messages.xml index 88a5e4181..c38abc2a5 100644 --- a/res/core/messages.xml +++ b/res/core/messages.xml @@ -3768,8 +3768,9 @@ "$unit($unit) in $region($region): '$order($command)' - Die Einheit kann nicht bewachen, da sie versucht zu fliehen." - "$unit($unit) in $region($region): '$order($command)' - The unit cannot guard the region because it's trying to flee." - "$unit($unit) in $region($region): '$order($command)' - The unit cannot guard the region because it's trying to flee." + "$unit($unit) in $region($region): + '$order($command)' - The unit cannot guard the region because it + is trying to flee." @@ -3779,7 +3780,6 @@ "$unit($unit) in $region($region): '$order($command)' - Die Einheit kann den Befehl in dieser Runde nicht ausführen, da sie an einem Kampf teilgenommen hat." - "$unit($unit) in $region($region): '$order($command)' - The unit cannot execute this command because it has been in combat." "$unit($unit) in $region($region): '$order($command)' - The unit cannot execute this command because it has been in combat." @@ -8365,8 +8365,9 @@ - "$unit($unit) in $region($region): '$order($command)' - Es ist so schön friedlich, man möchte hier niemanden angreifen." - "$unit($unit) in $region($region): '$order($command)' - It's so quiet and peaceful, nobody wants to attack anybody right now." + "$unit($unit) in $region($region): '$order($command)' - Es ist so schön friedlich, man möchte hier niemanden angreifen." + "$unit($unit) in $region($region): + '$order($command)' - It is so quiet and peaceful, nobody wants to attack anybody right now." From 88b9d3c583a8bfba3dd2d037b17546aae2f5be1b Mon Sep 17 00:00:00 2001 From: CTD Date: Thu, 16 Oct 2014 14:40:22 +0200 Subject: [PATCH 02/26] =?UTF-8?q?Fix=20f=C3=BCr=20Leere=20Geb=C3=A4ude?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Der check war sinnlos, denn u->building wobei u der Besitzer ist, gibt ja im Fall das er der "Besitzer der größten Burg in der Region" ist eben diese Burg zurück. So geht das dann auch in E2. --- src/economy.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/economy.c b/src/economy.c index bb24fd5e5..bf7e4f288 100644 --- a/src/economy.c +++ b/src/economy.c @@ -1039,12 +1039,10 @@ static bool maintain(building * b, bool first) u = building_owner(b); if (u == NULL) return false; - /* If the owner is the region owner, check if biggest castle has the dontpay flag */ + /* If the owner is the region owner, check if dontpay flag is set for the building where he is in */ if (check_param(global.parameters, "rules.region_owner_pay_building", b->type->_name)) { - if (u == building_owner(largestbuilding(r, &cmp_taxes, false))) { - if (fval(u->building, BLD_DONTPAY)) { - return false; - } + if (fval(u->building, BLD_DONTPAY)) { + return false; } } for (c = 0; b->type->maintenance[c].number; ++c) { From 58547969f8cc472a4301a382971a4072b09ea592 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 18 Oct 2014 21:36:46 +0200 Subject: [PATCH 03/26] fix a crash when testing for the RESHOW ANY command. E2 crashed when no parameter was given. --- src/laws.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/laws.c b/src/laws.c index d329959cd..2150a65f0 100755 --- a/src/laws.c +++ b/src/laws.c @@ -2586,7 +2586,7 @@ int reshow_cmd(unit * u, struct order *ord) init_order(ord); s = getstrtoken(); - if (isparam(s, u->faction->locale, P_ANY)) { + if (s && isparam(s, u->faction->locale, P_ANY)) { p = getparam(u->faction->locale); s = NULL; } From aadd9377c20266f93a20e55a6564ddbecb488f82 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 18 Oct 2014 21:43:04 +0200 Subject: [PATCH 04/26] update build number --- src/build.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/build.h b/src/build.h index bb1b13a0c..f69bc269f 100644 --- a/src/build.h +++ b/src/build.h @@ -1,3 +1,3 @@ #define VERSION_MAJOR 3 #define VERSION_MINOR 3 -#define VERSION_BUILD 685 +#define VERSION_BUILD 687 From eb1d73e2c2a4ba9b1df406d037d72d3295b9037c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 19 Oct 2014 06:42:40 +0200 Subject: [PATCH 05/26] basic test for tolower function. --- src/test_eressea.c | 1 + src/util/CMakeLists.txt | 1 + src/util/unicode.test.c | 23 +++++++++++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 src/util/unicode.test.c diff --git a/src/test_eressea.c b/src/test_eressea.c index 94f8d6c67..6fa8767cb 100644 --- a/src/test_eressea.c +++ b/src/test_eressea.c @@ -35,6 +35,7 @@ int RunAllTests(void) ADD_TESTS(suite, bsdstring); ADD_TESTS(suite, functions); ADD_TESTS(suite, umlaut); + ADD_TESTS(suite, unicode); ADD_TESTS(suite, strings); /* kernel */ ADD_TESTS(suite, unit); diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 51ceadac7..a9fde29a8 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -7,6 +7,7 @@ strings.test.c bsdstring.test.c functions.test.c umlaut.test.c +unicode.test.c ) SET(_FILES diff --git a/src/util/unicode.test.c b/src/util/unicode.test.c new file mode 100644 index 000000000..52392fda4 --- /dev/null +++ b/src/util/unicode.test.c @@ -0,0 +1,23 @@ +#include +#include "unicode.h" +#include +#include +#include + +static void test_unicode_tolower(CuTest * tc) +{ + char buffer[32]; + CuAssertIntEquals(tc, 0, unicode_utf8_tolower(buffer, sizeof(buffer), "HeLlO W0Rld")); + CuAssertStrEquals(tc, "hello w0rld", buffer); + memset(buffer, 0, sizeof(buffer)); + buffer[5]='X'; + CuAssertIntEquals(tc, ENOMEM, unicode_utf8_tolower(buffer, 5, "HeLlO W0Rld")); + CuAssertStrEquals(tc, "helloX", buffer); +} + +CuSuite *get_unicode_suite(void) +{ + CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_unicode_tolower); + return suite; +} From 356697e44ec840d701833cfb413e4df23c303cbf Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 19 Oct 2014 20:02:06 +0200 Subject: [PATCH 06/26] improve test for attrib::nexttype correctness. --- src/util/attrib.test.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/util/attrib.test.c b/src/util/attrib.test.c index 2e15c8321..479809d1d 100644 --- a/src/util/attrib.test.c +++ b/src/util/attrib.test.c @@ -69,6 +69,13 @@ static void test_attrib_nexttype(CuTest * tc) CuAssertPtrEquals(tc, a, alist->nexttype); CuAssertPtrEquals(tc, 0, a->nexttype); + a_remove(&alist, alist); + CuAssertPtrEquals(tc, a, alist->nexttype); + + CuAssertPtrNotNull(tc, (a = a_add(&alist, a_new(&at_bar)))); + a_remove(&alist, alist->nexttype); + CuAssertPtrEquals(tc, a, alist->nexttype); + a_removeall(&alist, &at_foo); a_removeall(&alist, &at_bar); } From 96d5544b1ff8b8b6380dce34f20b956823b694f7 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 20 Oct 2014 17:13:32 +0200 Subject: [PATCH 07/26] Bug 2032: rename FIGHT back to COMBAT --- res/core/de/strings.xml | 2 +- res/core/en/strings.xml | 3 --- src/kernel/config.c | 2 +- src/keyword.c | 2 +- 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/res/core/de/strings.xml b/res/core/de/strings.xml index cd408f9ea..863b26e35 100644 --- a/res/core/de/strings.xml +++ b/res/core/de/strings.xml @@ -2173,7 +2173,7 @@ HELFEN - + KÄMPFEN diff --git a/res/core/en/strings.xml b/res/core/en/strings.xml index a85bb5a4f..98bfaf310 100644 --- a/res/core/en/strings.xml +++ b/res/core/en/strings.xml @@ -1451,9 +1451,6 @@ HELP - - FIGHT - COMBATSPELL diff --git a/src/kernel/config.c b/src/kernel/config.c index 67e145258..17484449d 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -673,7 +673,7 @@ static void init_gms(void) faction *f; for (f = factions; f; f = f->next) { - const attrib *a = a_findc(f->attribs, &at_gm); + attrib *a = a_find(f->attribs, &at_gm); if (a != NULL) fset(f, FFL_GM); diff --git a/src/keyword.c b/src/keyword.c index 23f55a609..25ace155b 100644 --- a/src/keyword.c +++ b/src/keyword.c @@ -103,7 +103,7 @@ const char *keywords[MAXKEYWORDS] = { "research", "give", "help", - "fight", + "combat", "ready", "buy", "contact", From f788f19f6c66c4ae4c10daf9ee7d994b227fea62 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 23 Oct 2014 16:14:01 +0200 Subject: [PATCH 08/26] fix tests that relied on translation structures being statically cached. clean up static cache, add test for German imperative (WIP) --- src/kernel/order.test.c | 1 + src/keyword.test.c | 14 +++++++++++++- src/skill.test.c | 4 ++-- src/util/language.c | 1 + 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/kernel/order.test.c b/src/kernel/order.test.c index 1d556c622..0ae35d0bc 100644 --- a/src/kernel/order.test.c +++ b/src/kernel/order.test.c @@ -32,6 +32,7 @@ static void test_parse_order(CuTest *tc) { struct locale * lang = get_or_create_locale("en"); locale_setstring(lang, "keyword::move", "MOVE"); + init_keyword(lang, K_MOVE, "MOVE"); ord = parse_order("MOVE NORTH", lang); CuAssertPtrNotNull(tc, ord); CuAssertIntEquals(tc, K_MOVE, getkeyword(ord)); diff --git a/src/keyword.test.c b/src/keyword.test.c index f2cde5ab1..46e8fbfdd 100644 --- a/src/keyword.test.c +++ b/src/keyword.test.c @@ -19,6 +19,18 @@ static void test_init_keywords(CuTest *tc) { test_cleanup(); } +static void test_infinitive(CuTest *tc) { + struct locale *lang; + test_cleanup(); + + lang = get_or_create_locale("de"); + init_keyword(lang, K_STUDY, "LERNEN"); + CuAssertIntEquals(tc, K_STUDY, get_keyword("LERN", lang)); + CuAssertIntEquals(tc, K_STUDY, get_keyword("LERNE", lang)); + CuAssertIntEquals(tc, K_STUDY, get_keyword("LERNEN", lang)); + test_cleanup(); +} + static void test_init_keyword(CuTest *tc) { struct locale *lang; test_cleanup(); @@ -76,6 +88,7 @@ static void test_get_shortest_match(CuTest *tc) { CuSuite *get_keyword_suite(void) { CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_infinitive); SUITE_ADD_TEST(suite, test_init_keyword); SUITE_ADD_TEST(suite, test_init_keywords); SUITE_ADD_TEST(suite, test_findkeyword); @@ -83,4 +96,3 @@ CuSuite *get_keyword_suite(void) SUITE_DISABLE_TEST(suite, test_get_keyword_default); return suite; } - diff --git a/src/skill.test.c b/src/skill.test.c index 00c884edc..48b293e04 100644 --- a/src/skill.test.c +++ b/src/skill.test.c @@ -11,8 +11,8 @@ static void test_init_skills(CuTest *tc) { test_cleanup(); lang = get_or_create_locale("de"); - locale_setstring(lang, "alchemy", "Alchemie"); - init_skills(lang); +// locale_setstring(lang, "alchemy", "Alchemie"); + init_skill(lang, SK_ALCHEMY, "Alchemie"); CuAssertIntEquals(tc, SK_ALCHEMY, get_skill("alchemie", lang)); test_cleanup(); } diff --git a/src/util/language.c b/src/util/language.c index e0384e9b6..c3e997553 100644 --- a/src/util/language.c +++ b/src/util/language.c @@ -261,4 +261,5 @@ void free_locales(void) free(locales); locales = next; } + memset(lstrs, 0, sizeof(lstrs)); // TODO: does this data need to be free'd? } \ No newline at end of file From 0a1209d0319fb80388e1047226e37a22891e1568 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 23 Oct 2014 16:37:00 +0200 Subject: [PATCH 09/26] verify that my plan for making the German infinitive an optional alias will work. --- src/keyword.test.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/keyword.test.c b/src/keyword.test.c index 46e8fbfdd..3f6828c76 100644 --- a/src/keyword.test.c +++ b/src/keyword.test.c @@ -1,6 +1,7 @@ #include #include "kernel/types.h" #include "kernel/config.h" +#include "kernel/order.h" #include "keyword.h" #include "util/language.h" #include "tests.h" @@ -20,14 +21,21 @@ static void test_init_keywords(CuTest *tc) { } static void test_infinitive(CuTest *tc) { + char buffer[32]; struct locale *lang; + struct order *ord; test_cleanup(); lang = get_or_create_locale("de"); + locale_setstring(lang, "keyword::study", "LERNE"); + init_keyword(lang, K_STUDY, "LERNE"); init_keyword(lang, K_STUDY, "LERNEN"); CuAssertIntEquals(tc, K_STUDY, get_keyword("LERN", lang)); CuAssertIntEquals(tc, K_STUDY, get_keyword("LERNE", lang)); CuAssertIntEquals(tc, K_STUDY, get_keyword("LERNEN", lang)); + + ord = create_order(K_STUDY, lang, ""); + CuAssertStrEquals(tc, "LERNE", get_command(ord, buffer, sizeof(buffer))); test_cleanup(); } From 0aec5592a078b9548549a455d7023d2b99a47646 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 29 Oct 2014 07:50:06 +0100 Subject: [PATCH 10/26] allow json config to contain a list of config files (includes). --- src/kernel/jsonconf.c | 36 +++++++++++++++++++--- src/kernel/jsonconf.test.c | 62 +++++++++++++++++++++++++------------- 2 files changed, 73 insertions(+), 25 deletions(-) diff --git a/src/kernel/jsonconf.c b/src/kernel/jsonconf.c index d8a0e59e6..2ba555e9e 100644 --- a/src/kernel/jsonconf.c +++ b/src/kernel/jsonconf.c @@ -627,15 +627,40 @@ static void json_keywords(cJSON *json) { static void json_races(cJSON *json) { cJSON *child; - if (json->type!=cJSON_Object) { + if (json->type != cJSON_Object) { log_error("races is not a json object: %d", json->type); return; } - for (child=json->child;child;child=child->next) { + for (child = json->child; child; child = child->next) { json_race(child, rc_get_or_create(child->string)); } } +static void json_configs(cJSON *json) { + cJSON *child; + if (json->type != cJSON_Array) { + log_error("config is not a json array: %d", json->type); + return; + } + for (child = json->child; child; child = child->next) { + cJSON *config; + char *data; + FILE *F = fopen(child->valuestring, "rt"); + if (F) { + size_t sz; + fseek(F, 0, SEEK_END); + sz = ftell(F); + rewind(F); + data = malloc(sz); + fread(data, 1, sz, F); + fclose(F); + config = cJSON_Parse(data); + free(data); + json_config(config); + } + } +} + void json_config(cJSON *json) { cJSON *child; if (json->type!=cJSON_Object) { @@ -646,10 +671,13 @@ void json_config(cJSON *json) { if (strcmp(child->string, "races")==0) { json_races(child); } - else if (strcmp(child->string, "items")==0) { + else if (strcmp(child->string, "items") == 0) { json_items(child); } - else if (strcmp(child->string, "ships")==0) { + else if (strcmp(child->string, "config") == 0) { + json_configs(child); + } + else if (strcmp(child->string, "ships") == 0) { json_ships(child); } else if (strcmp(child->string, "strings")==0) { diff --git a/src/kernel/jsonconf.test.c b/src/kernel/jsonconf.test.c index 42505f0bb..5ddba65ce 100644 --- a/src/kernel/jsonconf.test.c +++ b/src/kernel/jsonconf.test.c @@ -228,29 +228,29 @@ static void test_spells(CuTest * tc) CuAssertPtrEquals(tc, 0, find_spell("fireball")); } +static const char * building_data = "{\"buildings\": { " +"\"house\" : { " +"\"maintenance\" : " +"{ \"type\" : \"iron\", \"amount\" : 1, \"flags\" : [ \"required\", \"variable\" ] }" +"," +"\"construction\" : {" +"\"maxsize\" : 20," +"\"reqsize\" : 10," +"\"minskill\" : 1," +"\"materials\" : {" +"\"stone\" : 2," +"\"iron\" : 1" +"}}}," +"\"shed\" : {" +"\"maintenance\" : [" +"{ \"type\" : \"iron\", \"amount\" : 1 }," +"{ \"type\" : \"stone\", \"amount\" : 2 }" +"]}" +"}}"; + static void test_buildings(CuTest * tc) { - const char * data = "{\"buildings\": { " - "\"house\" : { " - "\"maintenance\" : " - "{ \"type\" : \"iron\", \"amount\" : 1, \"flags\" : [ \"required\", \"variable\" ] }" - "," - "\"construction\" : {" - "\"maxsize\" : 20," - "\"reqsize\" : 10," - "\"minskill\" : 1," - "\"materials\" : {" - "\"stone\" : 2," - "\"iron\" : 1" - "}}}," - "\"shed\" : {" - "\"maintenance\" : [" - "{ \"type\" : \"iron\", \"amount\" : 1 }," - "{ \"type\" : \"stone\", \"amount\" : 2 }" - "]}" - "}}"; - - cJSON *json = cJSON_Parse(data); + cJSON *json = cJSON_Parse(building_data); const building_type *bt; test_cleanup(); @@ -292,6 +292,25 @@ static void test_buildings(CuTest * tc) test_cleanup(); } +static void test_configs(CuTest * tc) +{ + const char * data = "{\"config\": [ \"test.json\" ] }"; + FILE *F; + cJSON *json = cJSON_Parse(data); + + test_cleanup(); + + F = fopen("test.json", "wt"); + fwrite(building_data, 1, strlen(building_data), F); + fclose(F); + CuAssertPtrNotNull(tc, json); + CuAssertPtrEquals(tc, 0, buildingtypes); + json_config(json); + CuAssertPtrNotNull(tc, buildingtypes); + unlink("test.json"); + test_cleanup(); +} + static void test_terrains(CuTest * tc) { const char * data = "{\"terrains\": { \"plain\" : { \"flags\" : [ \"land\", \"fly\", \"walk\" ] } }}"; @@ -404,6 +423,7 @@ CuSuite *get_jsonconf_suite(void) SUITE_ADD_TEST(suite, test_items); SUITE_ADD_TEST(suite, test_ships); SUITE_ADD_TEST(suite, test_buildings); + SUITE_ADD_TEST(suite, test_configs); SUITE_ADD_TEST(suite, test_castles); SUITE_ADD_TEST(suite, test_terrains); SUITE_ADD_TEST(suite, test_races); From f9c5d58f41415c6da9cb19aa489c61d18735e743 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 29 Oct 2014 08:30:07 +0100 Subject: [PATCH 11/26] read json config file if available. missed an include, broke the build. --- scripts/eressea/xmlconf.lua | 1 + src/bind_config.c | 18 ++++++++++++++++++ src/kernel/jsonconf.c | 5 +++-- src/kernel/jsonconf.test.c | 2 ++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/scripts/eressea/xmlconf.lua b/scripts/eressea/xmlconf.lua index 1aaa39bdd..0840a31f7 100644 --- a/scripts/eressea/xmlconf.lua +++ b/scripts/eressea/xmlconf.lua @@ -6,3 +6,4 @@ if config.install then confdir = config.install .. '/' .. confdir end read_xml(confdir .. 'config.xml', confdir .. 'catalog.xml') +eressea.config.read(confdir .. 'config.json') diff --git a/src/bind_config.c b/src/bind_config.c index e0930481f..2de4c0d2a 100644 --- a/src/bind_config.c +++ b/src/bind_config.c @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include "kernel/building.h" #include "kernel/race.h" @@ -50,6 +52,22 @@ int config_parse(const char *json) int config_read(const char *filename) { + FILE *F = fopen(filename, "rt"); + if (F) { + int result; + char *data; + size_t sz; + + fseek(F, 0, SEEK_END); + sz = ftell(F); + rewind(F); + data = malloc(sz); + fread(data, 1, sz, F); + fclose(F); + result = config_parse(data); + free(data); + return result; + } return 1; } diff --git a/src/kernel/jsonconf.c b/src/kernel/jsonconf.c index 2ba555e9e..b6d6ece6b 100644 --- a/src/kernel/jsonconf.c +++ b/src/kernel/jsonconf.c @@ -643,10 +643,10 @@ static void json_configs(cJSON *json) { return; } for (child = json->child; child; child = child->next) { - cJSON *config; - char *data; FILE *F = fopen(child->valuestring, "rt"); if (F) { + cJSON *config; + char *data; size_t sz; fseek(F, 0, SEEK_END); sz = ftell(F); @@ -657,6 +657,7 @@ static void json_configs(cJSON *json) { config = cJSON_Parse(data); free(data); json_config(config); + cJSON_Delete(config); } } } diff --git a/src/kernel/jsonconf.test.c b/src/kernel/jsonconf.test.c index 5ddba65ce..b7fabc3e3 100644 --- a/src/kernel/jsonconf.test.c +++ b/src/kernel/jsonconf.test.c @@ -15,6 +15,7 @@ #include #include #include +#include #include static const struct race * race_with_flag(const char * name) { @@ -393,6 +394,7 @@ static void test_keywords(CuTest * tc) CuAssertIntEquals(tc, K_MOVE, get_keyword("nach", lang)); CuAssertStrEquals(tc, "LERNEN", locale_string(lang, "keyword::study")); + CuAssertStrEquals(tc, "NACH", locale_string(lang, "keyword::move")); test_cleanup(); } From 6bd52012c028a3e24e857b67f76262447bed35a7 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 29 Oct 2014 19:40:09 +0100 Subject: [PATCH 12/26] read keywords from json configuration, use German imperative forms. --- conf/e2/config.json | 5 + conf/e3/config.json | 5 + conf/e4/config.json | 5 + conf/keywords.json | 65 ++++++++++++ res/core/de/strings.xml | 193 ------------------------------------ scripts/eressea/xmlconf.lua | 11 +- src/bind_config.c | 14 ++- src/bind_config.h | 2 +- src/config.pkg | 2 +- src/config.pkg.c | 10 +- src/kernel/config.c | 14 --- src/kernel/config.h | 2 - src/kernel/jsonconf.c | 20 +++- src/kernel/jsonconf.h | 3 +- src/kernel/jsonconf.test.c | 24 ++++- src/kernel/save.c | 1 + src/laws.c | 2 +- src/util/language.c | 28 +++++- src/util/language.h | 4 +- 19 files changed, 177 insertions(+), 233 deletions(-) create mode 100644 conf/e2/config.json create mode 100644 conf/e3/config.json create mode 100644 conf/e4/config.json create mode 100644 conf/keywords.json diff --git a/conf/e2/config.json b/conf/e2/config.json new file mode 100644 index 000000000..b2acffcb3 --- /dev/null +++ b/conf/e2/config.json @@ -0,0 +1,5 @@ +{ + "include": [ + "keywords.json" + ] +} diff --git a/conf/e3/config.json b/conf/e3/config.json new file mode 100644 index 000000000..b2acffcb3 --- /dev/null +++ b/conf/e3/config.json @@ -0,0 +1,5 @@ +{ + "include": [ + "keywords.json" + ] +} diff --git a/conf/e4/config.json b/conf/e4/config.json new file mode 100644 index 000000000..b2acffcb3 --- /dev/null +++ b/conf/e4/config.json @@ -0,0 +1,5 @@ +{ + "include": [ + "keywords.json" + ] +} diff --git a/conf/keywords.json b/conf/keywords.json new file mode 100644 index 000000000..bc5538810 --- /dev/null +++ b/conf/keywords.json @@ -0,0 +1,65 @@ +{ + "keywords": { + "de": { + "//" : "//", + "banner": "BANNER", + "work": [ "ARBEITE", "ARBEITEN" ], + "attack": ["ATTACKIERE", "ATTACKIEREN"], + "steal": [ "BEKLAUE", "BEKLAUEN" ], + "besiege": ["BELAGERE", "BELAGERN" ], + "name": [ "BENENNE", "BENENNEN" ], + "use": [ "BENUTZE", "BENUTZEN" ], + "describe": [ "BESCHREIBE", "BESCHREIBEN" ], + "enter": ["BETRETE", "BETRETEN"], + "guard": ["BEWACHE", "BEWACHEN"], + "message": "BOTSCHAFT", + "end": "ENDE", + "ride": ["REITE", "REITEN"], + "number": "NUMMER", + "follow": ["FOLGE","FOLGEN"], + "research": ["FORSCHE", "FORSCHEN"], + "give": "GIB", + "help": [ "HELFE", "HELFEN" ], + "combat": [ "KÄMPFE", "KÄMPFEN" ], + "ready" : "KAMPFZAUBER", + "buy" : [ "KAUFE", "KAUFEN"], + "contact": [ "KONTAKT", "KONTAKTIEREN"], + "teach": ["LEHRE", "LEHREN"], + "study": ["LERNE", "LERNEN"], + "make": ["MACHE", "MACHEN"], + "maketemp": ["MACHE TEMP", "MACHETEMP"], + "move" : "NACH", + "password" : "PASSWORD", + "recruit": ["REKRUTIERE", "REKRUTIEREN"], + "reserve": ["RESERVIERE", "RESERVIEREN"], + "route": "ROUTE", + "sabotage": ["SABOTIERE", "SABOTIEREN"], + "option": "OPTION", + "spy": ["SPIONIERE", "SPIONIEREN"], + "quit": "STIRB", + "hide": ["TARNE", "TARNEN"], + "carry": ["TRANSPORTIERE", "TRANSPORTIEREN"], + "tax": ["TREIBE", "TREIBEN", "STEUERN"], + "entertain": ["UNTERHALTE", "UNTERHALTEN"], + "sell": ["VERKAUFE", "VERKAUFEN"], + "leave": ["VERLASSE", "VERLASSEN"], + "forget": ["VERGISS", "VERGESSEN"], + "cast": ["ZAUBERE", "ZAUBERN"], + "show": ["ZEIGE", "ZEIGEN"], + "destroy": ["ZERSTÖRE", "ZERSTÖREN"], + "grow": ["ZÃœCHTE", "ZÃœCHTEN"], + "default": "DEFAULT", + "origin": "URSPRUNG", + "email": "EMAIL", + "piracy": "PIRATERIE", + "group": "GRUPPE", + "sort": ["SORTIERE", "SORTIEREN"], + "prefix": "PRÄFIX", + "plant": ["PFLANZE", "PFLANZEN"], + "alliance": "ALLIANZ", + "claim": ["BEANSPRUCHE", "BEANSPRUCHEN"], + "promote": ["BEFÖRDERE", "BEFÖRDERUNG"], + "pay": ["BEZAHLE", "BEZAHLEN"] + } + } +} diff --git a/res/core/de/strings.xml b/res/core/de/strings.xml index 863b26e35..ddf8ced6d 100644 --- a/res/core/de/strings.xml +++ b/res/core/de/strings.xml @@ -2111,199 +2111,6 @@ - - - - // - - - BANNER - - - ARBEITEN - - - ATTACKIEREN - - - BEANSPRUCHEN - - - BEKLAUEN - - - BELAGERE - - - BENENNEN - - - BENUTZEN - - - BESCHREIBEN - - - BETRETEN - - - GIB - - - BEWACHEN - - - BOTSCHAFT - - - ENDE - - - FAHREN - - - NUMMER - - - FOLGEN - - - FORSCHEN - - - HELFEN - - - KÄMPFEN - - - KAMPFZAUBER - - - KAUFEN - - - KONTAKTIEREN - - - LEHREN - - - LERNEN - - - LOCALE - - - MACHEN - - - MACHETEMP - - - NACH - - - ALLIANZ - - - BEFÖRDERUNG - - - BEZAHLEN - - - PFLANZEN - - - PRÄFIX - - - INFO - - - PASSWORT - - - REKRUTIEREN - - - RESERVIEREN - - - ROUTE - - - SABOTIEREN - - - OPTION - - - SPIONIEREN - - - STIRB - - - TARNEN - - - TRANSPORTIEREN - - - TREIBEN - - - UNTERHALTEN - - - VERKAUFEN - - - VERLASSEN - - - VERGESSEN - - - ZAUBERE - - - ZEIGEN - - - ZERSTÖREN - - - ZÃœCHTEN - - - DEFAULT - - - REPORT - - - URSPRUNG - - - EMAIL - - - PIRATERIE - - - LOCALE - - - GRUPPE - - - SORTIEREN - - - Optionen diff --git a/scripts/eressea/xmlconf.lua b/scripts/eressea/xmlconf.lua index 0840a31f7..8ddd09539 100644 --- a/scripts/eressea/xmlconf.lua +++ b/scripts/eressea/xmlconf.lua @@ -1,9 +1,10 @@ local confdir = 'conf/' -if config.rules then - confdir = confdir .. config.rules .. '/' -end if config.install then confdir = config.install .. '/' .. confdir end -read_xml(confdir .. 'config.xml', confdir .. 'catalog.xml') -eressea.config.read(confdir .. 'config.json') +rules='' +if config.rules then + rules = config.rules .. '/' +end +read_xml(confdir .. rules .. 'config.xml', confdir .. rules .. 'catalog.xml') +eressea.config.read(rules .. 'config.json', confdir) diff --git a/src/bind_config.c b/src/bind_config.c index 2de4c0d2a..e87f65fb5 100644 --- a/src/bind_config.c +++ b/src/bind_config.c @@ -50,9 +50,19 @@ int config_parse(const char *json) return 1; } -int config_read(const char *filename) +int config_read(const char *filename, const char * relpath) { - FILE *F = fopen(filename, "rt"); + char name[MAX_PATH]; + FILE *F; + + json_relpath = relpath; + if (relpath) { + _snprintf(name, sizeof(name), "%s/%s", relpath, filename); + F = fopen(name, "rt"); + } + else { + F = fopen(filename, "rt"); + } if (F) { int result; char *data; diff --git a/src/bind_config.h b/src/bind_config.h index 27f59f853..aa6efde05 100644 --- a/src/bind_config.h +++ b/src/bind_config.h @@ -6,7 +6,7 @@ extern "C" { void config_reset(void); int config_parse(const char *json); -int config_read(const char *filename); +int config_read(const char *filename, const char * relpath); #ifdef __cplusplus } diff --git a/src/config.pkg b/src/config.pkg index 33f94bed8..d0cb3f905 100644 --- a/src/config.pkg +++ b/src/config.pkg @@ -5,7 +5,7 @@ $#include "bind_config.h" module eressea { module config { void config_reset @ reset(void); - int config_read @ read(const char *filename); + int config_read @ read(const char *filename, const char *relpath); int config_parse @ parse(const char *json); } } diff --git a/src/config.pkg.c b/src/config.pkg.c index c4225ff7b..cc4bb6965 100644 --- a/src/config.pkg.c +++ b/src/config.pkg.c @@ -57,16 +57,18 @@ static int tolua_config_eressea_config_read00(lua_State* tolua_S) #ifndef TOLUA_RELEASE tolua_Error tolua_err; if ( - !tolua_isstring(tolua_S,1,0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) + !tolua_isstring(tolua_S, 1, 0, &tolua_err) || + !tolua_isstring(tolua_S, 2, 0, &tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) ) goto tolua_lerror; else #endif { - const char* filename = ((const char*) tolua_tostring(tolua_S,1,0)); + const char* filename = ((const char*)tolua_tostring(tolua_S, 1, 0)); + const char* relpath = ((const char*)tolua_tostring(tolua_S, 2, 0)); { - int tolua_ret = (int) config_read(filename); + int tolua_ret = (int) config_read(filename, relpath); tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); } } diff --git a/src/kernel/config.c b/src/kernel/config.c index 17484449d..15e77b987 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -1961,20 +1961,6 @@ void kernel_done(void) gc_done(); } -const char *localenames[] = { - "de", "en", - NULL -}; - -void init_locales(void) -{ - int l; - for (l = 0; localenames[l]; ++l) { - struct locale *lang = get_or_create_locale(localenames[l]); - init_locale(lang); - } -} - /* TODO: soll hier weg */ extern struct attrib_type at_shiptrail; diff --git a/src/kernel/config.h b/src/kernel/config.h index 13c552c84..c7fd0f225 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -101,7 +101,6 @@ extern "C" { /* ------------------------------------------------------------- */ void add_translation(struct critbit_tree **cb, const char *str, int i); void init_translations(const struct locale *lang, int ut, const char * (*string_cb)(int i), int maxstrings); - void init_locales(void); int shipspeed(const struct ship *sh, const struct unit *u); #define i2b(i) ((bool)((i)?(true):(false))) @@ -171,7 +170,6 @@ extern "C" { /* returns a value between [0..xpct_2], generated with two dice */ int distribute(int old, int new_value, int n); - void init_locales(void); void init_locale(struct locale *lang); int newunitid(void); diff --git a/src/kernel/jsonconf.c b/src/kernel/jsonconf.c index b6d6ece6b..d09aaf6ff 100644 --- a/src/kernel/jsonconf.c +++ b/src/kernel/jsonconf.c @@ -636,14 +636,24 @@ static void json_races(cJSON *json) { } } -static void json_configs(cJSON *json) { +const char * json_relpath; + +static void json_include(cJSON *json) { cJSON *child; if (json->type != cJSON_Array) { log_error("config is not a json array: %d", json->type); return; } for (child = json->child; child; child = child->next) { - FILE *F = fopen(child->valuestring, "rt"); + FILE *F; + if (json_relpath) { + char name[MAX_PATH]; + _snprintf(name, sizeof(name), "%s/%s", json_relpath, child->valuestring); + F = fopen(name, "rt"); + } + else { + F = fopen(child->valuestring, "rt"); + } if (F) { cJSON *config; char *data; @@ -668,6 +678,7 @@ void json_config(cJSON *json) { log_error("config is not a json object: %d", json->type); return; } + reset_locales(); for (child=json->child;child;child=child->next) { if (strcmp(child->string, "races")==0) { json_races(child); @@ -675,8 +686,8 @@ void json_config(cJSON *json) { else if (strcmp(child->string, "items") == 0) { json_items(child); } - else if (strcmp(child->string, "config") == 0) { - json_configs(child); + else if (strcmp(child->string, "include") == 0) { + json_include(child); } else if (strcmp(child->string, "ships") == 0) { json_ships(child); @@ -705,6 +716,5 @@ void json_config(cJSON *json) { log_error("config contains unknown attribute %s", child->string); } } - init_locales(); } diff --git a/src/kernel/jsonconf.h b/src/kernel/jsonconf.h index 9d0f1467e..6940386e9 100644 --- a/src/kernel/jsonconf.h +++ b/src/kernel/jsonconf.h @@ -18,7 +18,8 @@ extern "C" { struct cJSON; void json_config(struct cJSON *str); - + extern const char * json_relpath; + #ifdef __cplusplus } #endif diff --git a/src/kernel/jsonconf.test.c b/src/kernel/jsonconf.test.c index b7fabc3e3..7a401b8f7 100644 --- a/src/kernel/jsonconf.test.c +++ b/src/kernel/jsonconf.test.c @@ -10,6 +10,7 @@ #include "race.h" #include "ship.h" #include "spell.h" +#include "order.h" #include "terrain.h" #include "util/language.h" #include @@ -295,7 +296,7 @@ static void test_buildings(CuTest * tc) static void test_configs(CuTest * tc) { - const char * data = "{\"config\": [ \"test.json\" ] }"; + const char * data = "{\"include\": [ \"test.json\" ] }"; FILE *F; cJSON *json = cJSON_Parse(data); @@ -416,6 +417,26 @@ static void test_strings(CuTest * tc) CuAssertStrEquals(tc, "LERNEN", locale_string(lang, "study")); } +static void test_infinitive_from_config(CuTest *tc) { + char buffer[32]; + struct locale *lang; + struct order *ord; + const char * data = "{\"keywords\": { \"de\" : { \"study\" : [ \"LERNE\", \"LERNEN\" ] }}}"; + + cJSON *json = cJSON_Parse(data); + CuAssertPtrNotNull(tc, json); + json_config(json); + + lang = get_or_create_locale("de"); + CuAssertIntEquals(tc, K_STUDY, get_keyword("LERN", lang)); + CuAssertIntEquals(tc, K_STUDY, get_keyword("LERNE", lang)); + CuAssertIntEquals(tc, K_STUDY, get_keyword("LERNEN", lang)); + + ord = create_order(K_STUDY, lang, ""); + CuAssertStrEquals(tc, "LERNE", get_command(ord, buffer, sizeof(buffer))); + test_cleanup(); +} + CuSuite *get_jsonconf_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -433,6 +454,7 @@ CuSuite *get_jsonconf_suite(void) SUITE_ADD_TEST(suite, test_strings); SUITE_ADD_TEST(suite, test_spells); SUITE_ADD_TEST(suite, test_flags); + SUITE_ADD_TEST(suite, test_infinitive_from_config); return suite; } diff --git a/src/kernel/save.c b/src/kernel/save.c index c52eae383..6f443598a 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1460,6 +1460,7 @@ int readgame(const char *filename, int backup) storage store; FILE *F; + init_locales(); log_printf(stdout, "- reading game data from %s\n", filename); sprintf(path, "%s/%s", datapath(), filename); diff --git a/src/laws.c b/src/laws.c index 2b9171083..038c9a550 100755 --- a/src/laws.c +++ b/src/laws.c @@ -4562,10 +4562,10 @@ int init_data(const char *filename, const char *catalog) { int l; l = read_xml(filename, catalog); + reset_locales(); if (l) { return l; } - init_locales(); if (turn < 0) { turn = first_turn; } diff --git a/src/util/language.c b/src/util/language.c index c3e997553..1e8cd1a4b 100644 --- a/src/util/language.c +++ b/src/util/language.c @@ -243,8 +243,32 @@ void *get_translation(const struct locale *lang, const char *str, int index) { return NULL; } -void free_locales(void) +const char *localenames[] = { + "de", "en", + NULL +}; + +extern void init_locale(struct locale *lang); + +static int locale_init = 0; + +void init_locales(void) { + int l; + if (locale_init) return; + for (l = 0; localenames[l]; ++l) { + struct locale *lang = get_or_create_locale(localenames[l]); + init_locale(lang); + } + locale_init = 1; +} + +void reset_locales(void) { + locale_init = 0; +} + +void free_locales(void) { + locale_init = 0; while (locales) { int i; locale * next = locales->next; @@ -262,4 +286,4 @@ void free_locales(void) locales = next; } memset(lstrs, 0, sizeof(lstrs)); // TODO: does this data need to be free'd? -} \ No newline at end of file +} diff --git a/src/util/language.h b/src/util/language.h index 7083dec1f..5dd35c7b2 100644 --- a/src/util/language.h +++ b/src/util/language.h @@ -29,7 +29,9 @@ extern "C" { /** managing multiple locales: **/ extern struct locale *get_locale(const char *name); extern struct locale *get_or_create_locale(const char *key); - extern void free_locales(void); + void init_locales(void); + void free_locales(void); + void reset_locales(void); /** operations on locales: **/ extern void locale_setstring(struct locale *lang, const char *key, From 9f2d2e0f929d3a3c28ff60a64d873387e5be678f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 29 Oct 2014 20:01:55 +0100 Subject: [PATCH 13/26] fix broken test that didn't like the new init_locale() requirements. --- src/kernel/jsonconf.test.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/kernel/jsonconf.test.c b/src/kernel/jsonconf.test.c index 7a401b8f7..6c555bfc6 100644 --- a/src/kernel/jsonconf.test.c +++ b/src/kernel/jsonconf.test.c @@ -103,7 +103,7 @@ static void test_races(CuTest * tc) static void test_findrace(CuTest *tc) { const char * data = "{\"races\": { \"dwarf\": {} }, \"strings\": { \"de\" : { \"race::dwarf\" : \"Zwerg\" } } }"; cJSON *json = cJSON_Parse(data); - const struct locale *lang; + struct locale *lang; const race *rc; CuAssertPtrNotNull(tc, json); @@ -112,6 +112,7 @@ static void test_findrace(CuTest *tc) { CuAssertPtrEquals(tc, 0, (void *)findrace("Zwerg", lang)); json_config(json); + init_locale(lang); rc = findrace("Zwerg", lang); CuAssertPtrNotNull(tc, rc); CuAssertStrEquals(tc, "dwarf", rc->_name); From 526c561b901f9170576bc8197b67b10caeef638d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 29 Oct 2014 21:08:16 +0100 Subject: [PATCH 14/26] some minor cleanup in laws.h --- src/bindings.c | 16 ++++++++++++++++ src/laws.c | 15 --------------- src/laws.h | 3 --- src/laws.test.c | 1 + 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/bindings.c b/src/bindings.c index 94caa2d42..1446dac15 100755 --- a/src/bindings.c +++ b/src/bindings.c @@ -68,6 +68,7 @@ without prior permission by the authors of Eressea. #include #include #include +#include #include @@ -1001,6 +1002,21 @@ static int tolua_get_spells(lua_State * L) return tolua_quicklist_push(L, "spell_list", "spell", spells); } +static int init_data(const char *filename, const char *catalog) +{ + int l; + l = read_xml(filename, catalog); + reset_locales(); + if (l) { + return l; + } + if (turn < 0) { + turn = first_turn; + } + return 0; +} + + int tolua_read_xml(lua_State * L) { const char *filename = tolua_tostring(L, 1, "config.xml"); diff --git a/src/laws.c b/src/laws.c index 038c9a550..98eefca0d 100755 --- a/src/laws.c +++ b/src/laws.c @@ -83,7 +83,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include #include @@ -4557,17 +4556,3 @@ void update_subscriptions(void) } fclose(F); } - -int init_data(const char *filename, const char *catalog) -{ - int l; - l = read_xml(filename, catalog); - reset_locales(); - if (l) { - return l; - } - if (turn < 0) { - turn = first_turn; - } - return 0; -} diff --git a/src/laws.h b/src/laws.h index 3ffc35f08..c9fdc095f 100755 --- a/src/laws.h +++ b/src/laws.h @@ -24,13 +24,10 @@ extern "C" { extern int writepasswd(void); void demographics(void); - void last_orders(void); - void find_address(void); void update_guards(void); void update_subscriptions(void); void deliverMail(struct faction *f, struct region *r, struct unit *u, const char *s, struct unit *receiver); - int init_data(const char *filename, const char *catalog); bool renamed_building(const struct building * b); int rename_building(struct unit * u, struct order * ord, struct building * b, const char *name); diff --git a/src/laws.test.c b/src/laws.test.c index 48283b017..d456769b1 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -57,6 +57,7 @@ static void test_rename_building(CuTest * tc) rename_building(u, NULL, b, "Villa Nagel"); CuAssertStrEquals(tc, "Villa Nagel", b->name); + CuAssertTrue(tc, renamed_building(b)); } static void test_rename_building_twice(CuTest * tc) From aa4a93435ed5fdf4adb1af34a1b4205ebd0853b5 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 30 Oct 2014 07:50:01 +0100 Subject: [PATCH 15/26] add missing tests for contacting during a siege. --- src/laws.test.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/laws.test.c b/src/laws.test.c index d456769b1..43ce3dc1f 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -2,6 +2,7 @@ #include #include "laws.h" +#include #include #include #include @@ -63,9 +64,9 @@ static void test_rename_building(CuTest * tc) static void test_rename_building_twice(CuTest * tc) { region *r; - building *b; unit *u; faction *f; + building *b; building_type *btype; test_cleanup(); @@ -86,6 +87,37 @@ static void test_rename_building_twice(CuTest * tc) CuAssertStrEquals(tc, "Villa Kunterbunt", b->name); } +static void test_contact(CuTest * tc) +{ + region *r; + unit *u1, *u2, *u3; + building *b; + building_type *btype; + + test_cleanup(); + test_create_world(); + + btype = bt_get_or_create("castle"); + r = findregion(0, 0); + b = new_building(btype, r, default_locale); + u1 = test_create_unit(test_create_faction(0), r); + u2 = test_create_unit(test_create_faction(0), r); + u3 = test_create_unit(test_create_faction(0), r); + set_level(u3, SK_PERCEPTION, 2); + usetsiege(u3, b); + b->besieged = 1; + CuAssertIntEquals(tc, 1, can_contact(r, u1, u2)); + + u_set_building(u1, b); + CuAssertIntEquals(tc, 0, can_contact(r, u1, u2)); + u1->faction->allies = calloc(1, sizeof(ally)); + u1->faction->allies->faction = u2->faction; + u1->faction->allies->status = HELP_ALL; + CuAssertIntEquals(tc, HELP_GIVE, can_contact(r, u1, u2)); + u_set_building(u2, b); + CuAssertIntEquals(tc, 1, can_contact(r, u1, u2)); +} + static void test_fishing_feeds_2_people(CuTest * tc) { const resource_type *rtype; @@ -413,5 +445,6 @@ CuSuite *get_laws_suite(void) SUITE_ADD_TEST(suite, test_reserve_cmd); SUITE_ADD_TEST(suite, test_new_units); SUITE_ADD_TEST(suite, test_cannot_create_unit_above_limit); + SUITE_ADD_TEST(suite, test_contact); return suite; } From e9c13cc328a603a77724e4995013e842768b8112 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 30 Oct 2014 17:48:02 +0100 Subject: [PATCH 16/26] cosmetic changes, quick and easy assert to prevent too many magicians. --- src/kernel/pool.c | 4 +--- src/kernel/unit.c | 11 +++++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/kernel/pool.c b/src/kernel/pool.c index e38c31011..5c6a942e7 100644 --- a/src/kernel/pool.c +++ b/src/kernel/pool.c @@ -177,11 +177,9 @@ int count) } if (rtype->flags & RTF_POOLED && mode & ~(GET_SLACK | GET_RESERVE)) { for (v = r->units; v && use < count; v = v->next) - if (u != v) { + if (u != v && (u->items || rtype->uget)) { int mask; - if (v->items == NULL && rtype->uget == NULL) - continue; if ((urace(v)->ec_flags & GIVEITEM) == 0) continue; diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 27dff7f0c..a039d9c3a 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -1161,10 +1161,13 @@ skill *add_skill(unit * u, skill_t id) ++u->skill_size; u->skills = realloc(u->skills, u->skill_size * sizeof(skill)); sv = (u->skills + u->skill_size - 1); - sv->level = (unsigned char)0; - sv->weeks = (unsigned char)1; - sv->old = (unsigned char)0; - sv->id = (unsigned char)id; + sv->level = 0; + sv->weeks = 1; + sv->old = 0; + sv->id = id; + if (id == SK_MAGIC && u->faction) { + assert(max_magicians(u->faction) >= u->number); + } return sv; } From c8d5d524125ff377594fec16ba02913e18647816 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 31 Oct 2014 07:51:57 +0100 Subject: [PATCH 17/26] add test for pool, fix a problem with (unused) feature that pools from allies. --- src/kernel/pool.c | 2 +- src/kernel/pool.h | 4 +- src/kernel/pool.test.c | 96 +++++++++++++++++++++++++++++++----------- 3 files changed, 75 insertions(+), 27 deletions(-) diff --git a/src/kernel/pool.c b/src/kernel/pool.c index 5c6a942e7..6706ed80c 100644 --- a/src/kernel/pool.c +++ b/src/kernel/pool.c @@ -167,7 +167,7 @@ int count) if ((mode & GET_SLACK) && (mode & GET_RESERVE)) use = have; - else { + else if (mode & (GET_SLACK|GET_RESERVE)) { int reserve = get_reservation(u, rtype); int slack = _max(0, have - reserve); if (mode & GET_RESERVE) diff --git a/src/kernel/pool.h b/src/kernel/pool.h index 6de15bf3c..d6f4766c6 100644 --- a/src/kernel/pool.h +++ b/src/kernel/pool.h @@ -29,8 +29,8 @@ extern "C" { #define GET_POOLED_SLACK 0x08 #define GET_POOLED_RESERVE 0x10 #define GET_POOLED_FORCE 0x20 /* ignore f->options pools */ -#define GET_ALLIED_SLACK 0x30 -#define GET_ALLIED_RESERVE 0x40 +#define GET_ALLIED_SLACK 0x40 +#define GET_ALLIED_RESERVE 0x80 /* for convenience: */ #define GET_DEFAULT (GET_RESERVE|GET_SLACK|GET_POOLED_SLACK) diff --git a/src/kernel/pool.test.c b/src/kernel/pool.test.c index ad700f6a8..8b42f1be9 100644 --- a/src/kernel/pool.test.c +++ b/src/kernel/pool.test.c @@ -1,47 +1,95 @@ #include #include +#include "ally.h" #include "pool.h" #include "magic.h" #include "unit.h" #include "item.h" +#include "faction.h" #include "region.h" #include "skill.h" #include #include +#include + +void test_pool(CuTest *tc) { + unit *u1, *u2, *u3; + faction *f; + region *r; + struct resource_type *rtype; + + test_cleanup(); + test_create_world(); + rtype = rt_get_or_create("money"); + it_get_or_create(rtype); + f = test_create_faction(0); + r = findregion(0, 0); + assert(r && f && rtype && rtype->itype); + u1 = test_create_unit(f, r); + u2 = test_create_unit(f, r); + u3 = test_create_unit(test_create_faction(0), r); + assert(u1 && u2); + i_change(&u1->items, rtype->itype, 100); + set_resvalue(u1, rtype, 50); + i_change(&u2->items, rtype->itype, 200); + set_resvalue(u2, rtype, 100); + i_change(&u3->items, rtype->itype, 400); + set_resvalue(u3, rtype, 200); + + CuAssertIntEquals(tc, 50, get_pooled(u1, rtype, GET_SLACK, 40)); + CuAssertIntEquals(tc, 50, get_pooled(u1, rtype, GET_SLACK, INT_MAX)); + CuAssertIntEquals(tc, 100, get_pooled(u1, rtype, GET_SLACK | GET_RESERVE, INT_MAX)); + CuAssertIntEquals(tc, 150, get_pooled(u1, rtype, GET_SLACK | GET_POOLED_SLACK, INT_MAX)); + CuAssertIntEquals(tc, 100, get_pooled(u1, rtype, GET_POOLED_SLACK, INT_MAX)); + CuAssertIntEquals(tc, 200, get_pooled(u1, rtype, GET_POOLED_SLACK | GET_POOLED_RESERVE, INT_MAX)); + + u3->faction->allies = calloc(1, sizeof(ally)); + u3->faction->allies->faction = f; + u3->faction->allies->status = HELP_GUARD; + CuAssertIntEquals(tc, 0, get_pooled(u1, rtype, GET_ALLIED_SLACK | GET_ALLIED_RESERVE, INT_MAX)); + u3->faction->allies->status = HELP_MONEY; + CuAssertIntEquals(tc, 200, get_pooled(u1, rtype, GET_ALLIED_SLACK, INT_MAX)); + CuAssertIntEquals(tc, 200, get_pooled(u1, rtype, GET_ALLIED_RESERVE, INT_MAX)); + CuAssertIntEquals(tc, 400, get_pooled(u1, rtype, GET_ALLIED_SLACK | GET_ALLIED_RESERVE, INT_MAX)); + + CuAssertIntEquals(tc, 100, get_pooled(u1, rtype, GET_ALL, 50)); + CuAssertIntEquals(tc, 300, get_pooled(u1, rtype, GET_ALL, 150)); + CuAssertIntEquals(tc, 300, get_pooled(u1, rtype, GET_ALL, INT_MAX)); +} void test_change_resource(CuTest * tc) { - struct unit * u; - struct faction * f; - struct region * r; - const char * names[] = { "money", "aura", "permaura", "horse", "hp", 0 }; - int i; + struct unit * u; + struct faction * f; + struct region * r; + const char * names[] = { "money", "aura", "permaura", "horse", "hp", 0 }; + int i; - test_cleanup(); - test_create_world(); - enable_skill(SK_MAGIC, true); + test_cleanup(); + test_create_world(); + enable_skill(SK_MAGIC, true); - r = findregion(0, 0); - f = test_create_faction(0); - u = test_create_unit(f, r); - CuAssertPtrNotNull(tc, u); - set_level(u, SK_MAGIC, 5); - create_mage(u, M_DRAIG); + r = findregion(0, 0); + f = test_create_faction(0); + u = test_create_unit(f, r); + CuAssertPtrNotNull(tc, u); + set_level(u, SK_MAGIC, 5); + create_mage(u, M_DRAIG); - for (i=0;names[i];++i) { - const struct resource_type *rtype = rt_find(names[i]); - int have = get_resource(u, rtype); - CuAssertIntEquals(tc, have+1, change_resource(u, rtype, 1)); - CuAssertIntEquals(tc, have+1, get_resource(u, rtype)); - } + for (i = 0; names[i]; ++i) { + const struct resource_type *rtype = rt_find(names[i]); + int have = get_resource(u, rtype); + CuAssertIntEquals(tc, have + 1, change_resource(u, rtype, 1)); + CuAssertIntEquals(tc, have + 1, get_resource(u, rtype)); + } } CuSuite *get_pool_suite(void) { - CuSuite *suite = CuSuiteNew(); -/* SUITE_ADD_TEST(suite, test_pool); */ - SUITE_ADD_TEST(suite, test_change_resource); - return suite; + CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_pool); + SUITE_ADD_TEST(suite, test_change_resource); + return suite; } From f27a77d288dbb9195c3a4f027dba1ee8703b5c3b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 31 Oct 2014 15:13:05 +0100 Subject: [PATCH 18/26] refactoring: use add_ally instead of manually crating the structure all over the code. --- src/kernel/faction.c | 4 +- src/kernel/group.c | 269 ++++++++++++++++++++--------------------- src/kernel/pool.test.c | 8 +- src/kernel/save.c | 3 +- src/laws.c | 4 +- src/laws.test.c | 6 +- 6 files changed, 143 insertions(+), 151 deletions(-) diff --git a/src/kernel/faction.c b/src/kernel/faction.c index de9ba6ed1..5cb152e47 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -430,10 +430,8 @@ void set_alliance(faction * a, faction * b, int status) sfp = &sf->next; } if (*sfp == NULL) { - ally *sf = *sfp = malloc(sizeof(ally)); - sf->next = NULL; + ally *sf = ally_add(sfp, b); sf->status = status; - sf->faction = b; return; } (*sfp)->status |= status; diff --git a/src/kernel/group.c b/src/kernel/group.c index 99e2a1a61..510c327ac 100755 --- a/src/kernel/group.c +++ b/src/kernel/group.c @@ -1,7 +1,7 @@ /* Copyright (c) 1998-2010, Enno Rehling - Katja Zedel +Katja Zedel Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -50,203 +50,200 @@ static int maxgid; static group *new_group(faction * f, const char *name, int gid) { - group **gp = &f->groups; - int index = gid % GMAXHASH; - group *g = calloc(sizeof(group), 1); + group **gp = &f->groups; + int index = gid % GMAXHASH; + group *g = calloc(sizeof(group), 1); - while (*gp) - gp = &(*gp)->next; - *gp = g; + while (*gp) + gp = &(*gp)->next; + *gp = g; - maxgid = _max(gid, maxgid); - g->name = _strdup(name); - g->gid = gid; + maxgid = _max(gid, maxgid); + g->name = _strdup(name); + g->gid = gid; - g->nexthash = ghash[index]; - return ghash[index] = g; + g->nexthash = ghash[index]; + return ghash[index] = g; } static void init_group(faction * f, group * g) { - ally *a, **an; + ally *a, **an; - an = &g->allies; - for (a = f->allies; a; a = a->next) - if (a->faction) { - ally *ga = calloc(sizeof(ally), 1); - *ga = *a; - *an = ga; - an = &ga->next; - } + an = &g->allies; + for (a = f->allies; a; a = a->next) + if (a->faction) { + ally *ga = ally_add(an, a->faction); + ga->status = a->status; + an = &ga->next; + } } static group *find_groupbyname(group * g, const char *name) { - while (g && unicode_utf8_strcasecmp(name, g->name) != 0) - g = g->next; - return g; + while (g && unicode_utf8_strcasecmp(name, g->name) != 0) + g = g->next; + return g; } static group *find_group(int gid) { - int index = gid % GMAXHASH; - group *g = ghash[index]; - while (g && g->gid != gid) - g = g->nexthash; - return g; + int index = gid % GMAXHASH; + group *g = ghash[index]; + while (g && g->gid != gid) + g = g->nexthash; + return g; } static int read_group(attrib * a, void *owner, struct storage *store) { - group *g; - int gid; + group *g; + int gid; - READ_INT(store, &gid); - a->data.v = g = find_group(gid); - if (g != 0) { - g->members++; - return AT_READ_OK; - } - return AT_READ_FAIL; + READ_INT(store, &gid); + a->data.v = g = find_group(gid); + if (g != 0) { + g->members++; + return AT_READ_OK; + } + return AT_READ_FAIL; } static void write_group(const attrib * a, const void *owner, struct storage *store) { - group *g = (group *) a->data.v; - WRITE_INT(store, g->gid); + group *g = (group *)a->data.v; + WRITE_INT(store, g->gid); } attrib_type at_group = { /* attribute for units assigned to a group */ -"grp", + "grp", DEFAULT_INIT, - DEFAULT_FINALIZE, DEFAULT_AGE, write_group, read_group, ATF_UNIQUE}; + DEFAULT_FINALIZE, DEFAULT_AGE, write_group, read_group, ATF_UNIQUE }; void free_group(group * g) { - int index = g->gid % GMAXHASH; - group **g_ptr = ghash + index; - while (*g_ptr && (*g_ptr)->gid != g->gid) - g_ptr = &(*g_ptr)->nexthash; - assert(*g_ptr == g); - *g_ptr = g->nexthash; + int index = g->gid % GMAXHASH; + group **g_ptr = ghash + index; + while (*g_ptr && (*g_ptr)->gid != g->gid) + g_ptr = &(*g_ptr)->nexthash; + assert(*g_ptr == g); + *g_ptr = g->nexthash; - while (g->allies) { - ally *a = g->allies; - g->allies = a->next; - free(a); - } - free(g->name); - free(g); + while (g->allies) { + ally *a = g->allies; + g->allies = a->next; + free(a); + } + free(g->name); + free(g); } group * get_group(const struct unit *u) { - if (fval(u, UFL_GROUP)) { - attrib * a = a_find(u->attribs, &at_group); - if (a) { - return (group *) a->data.v; + if (fval(u, UFL_GROUP)) { + attrib * a = a_find(u->attribs, &at_group); + if (a) { + return (group *)a->data.v; + } } - } - return 0; + return 0; } void set_group(struct unit *u, struct group *g) { - attrib *a = NULL; + attrib *a = NULL; - if (fval(u, UFL_GROUP)) { - a = a_find(u->attribs, &at_group); - } - - if (a) { - group *og = (group *) a->data.v; - if (og == g) - return; - --og->members; - } - - if (g) { - if (!a) { - a = a_add(&u->attribs, a_new(&at_group)); - fset(u, UFL_GROUP); + if (fval(u, UFL_GROUP)) { + a = a_find(u->attribs, &at_group); + } + + if (a) { + group *og = (group *)a->data.v; + if (og == g) + return; + --og->members; + } + + if (g) { + if (!a) { + a = a_add(&u->attribs, a_new(&at_group)); + fset(u, UFL_GROUP); + } + a->data.v = g; + g->members++; + } + else if (a) { + a_remove(&u->attribs, a); + freset(u, UFL_GROUP); } - a->data.v = g; - g->members++; - } else if (a) { - a_remove(&u->attribs, a); - freset(u, UFL_GROUP); - } } bool join_group(unit * u, const char *name) { - group *g = NULL; + group *g = NULL; - if (name && name[0]) { - g = find_groupbyname(u->faction->groups, name); - if (g == NULL) { - g = new_group(u->faction, name, ++maxgid); - init_group(u->faction, g); + if (name && name[0]) { + g = find_groupbyname(u->faction->groups, name); + if (g == NULL) { + g = new_group(u->faction, name, ++maxgid); + init_group(u->faction, g); + } } - } - set_group(u, g); - return true; + set_group(u, g); + return true; } void write_groups(struct storage *store, group * g) { - while (g) { - ally *a; - WRITE_INT(store, g->gid); - WRITE_STR(store, g->name); - for (a = g->allies; a; a = a->next) { - if (a->faction) { - write_faction_reference(a->faction, store); - WRITE_INT(store, a->status); - } + while (g) { + ally *a; + WRITE_INT(store, g->gid); + WRITE_STR(store, g->name); + for (a = g->allies; a; a = a->next) { + if (a->faction) { + write_faction_reference(a->faction, store); + WRITE_INT(store, a->status); + } + } + WRITE_INT(store, 0); + a_write(store, g->attribs, g); + WRITE_SECTION(store); + g = g->next; } WRITE_INT(store, 0); - a_write(store, g->attribs, g); - WRITE_SECTION(store); - g = g->next; - } - WRITE_INT(store, 0); } void read_groups(struct storage *store, faction * f) { - for (;;) { - ally **pa; - group *g; - int gid; - char buf[1024]; - - READ_INT(store, &gid); - if (gid == 0) - break; - READ_STR(store, buf, sizeof(buf)); - g = new_group(f, buf, gid); - pa = &g->allies; for (;;) { - ally *a; - variant fid; - READ_INT(store, &fid.i); - if (fid.i <= 0) - break; - if (global.data_version < STORAGE_VERSION && fid.i == 0) - break; - a = malloc(sizeof(ally)); - *pa = a; - pa = &a->next; - READ_INT(store, &a->status); + ally **pa; + group *g; + int gid; + char buf[1024]; - a->faction = findfaction(fid.i); - if (!a->faction) - ur_add(fid, &a->faction, resolve_faction); + READ_INT(store, &gid); + if (gid == 0) + break; + READ_STR(store, buf, sizeof(buf)); + g = new_group(f, buf, gid); + pa = &g->allies; + for (;;) { + ally *a; + variant fid; + + READ_INT(store, &fid.i); + if (fid.i <= 0) + break; + if (global.data_version < STORAGE_VERSION && fid.i == 0) + break; + a = ally_add(pa, findfaction(fid.i)); + READ_INT(store, &a->status); + if (!a->faction) + ur_add(fid, &a->faction, resolve_faction); + } + *pa = 0; + a_read(store, &g->attribs, g); } - *pa = 0; - a_read(store, &g->attribs, g); - } } diff --git a/src/kernel/pool.test.c b/src/kernel/pool.test.c index 8b42f1be9..1a0432460 100644 --- a/src/kernel/pool.test.c +++ b/src/kernel/pool.test.c @@ -19,6 +19,7 @@ void test_pool(CuTest *tc) { faction *f; region *r; struct resource_type *rtype; + ally *al; test_cleanup(); test_create_world(); @@ -45,11 +46,10 @@ void test_pool(CuTest *tc) { CuAssertIntEquals(tc, 100, get_pooled(u1, rtype, GET_POOLED_SLACK, INT_MAX)); CuAssertIntEquals(tc, 200, get_pooled(u1, rtype, GET_POOLED_SLACK | GET_POOLED_RESERVE, INT_MAX)); - u3->faction->allies = calloc(1, sizeof(ally)); - u3->faction->allies->faction = f; - u3->faction->allies->status = HELP_GUARD; + al = ally_add(&u3->faction->allies, f); + al->status = HELP_GUARD; CuAssertIntEquals(tc, 0, get_pooled(u1, rtype, GET_ALLIED_SLACK | GET_ALLIED_RESERVE, INT_MAX)); - u3->faction->allies->status = HELP_MONEY; + al->status = HELP_MONEY; CuAssertIntEquals(tc, 200, get_pooled(u1, rtype, GET_ALLIED_SLACK, INT_MAX)); CuAssertIntEquals(tc, 200, get_pooled(u1, rtype, GET_ALLIED_RESERVE, INT_MAX)); CuAssertIntEquals(tc, 400, get_pooled(u1, rtype, GET_ALLIED_SLACK | GET_ALLIED_RESERVE, INT_MAX)); diff --git a/src/kernel/save.c b/src/kernel/save.c index 6f443598a..77a33b50f 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1119,8 +1119,7 @@ static ally **addally(const faction * f, ally ** sfp, int aid, int state) if (state == 0) return sfp; - sf = calloc(1, sizeof(ally)); - sf->faction = af; + sf = ally_add(sfp, af); if (!sf->faction) { variant id; id.i = aid; diff --git a/src/laws.c b/src/laws.c index 98eefca0d..ed319023e 100755 --- a/src/laws.c +++ b/src/laws.c @@ -1348,10 +1348,8 @@ int ally_cmd(unit * u, struct order *ord) return 0; } else { - sf = calloc(1, sizeof(ally)); - sf->faction = f; + sf = ally_add(sfp, f); sf->status = 0; - addlist(sfp, sf); } } switch (keyword) { diff --git a/src/laws.test.c b/src/laws.test.c index 43ce3dc1f..6549d1bf6 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -93,6 +93,7 @@ static void test_contact(CuTest * tc) unit *u1, *u2, *u3; building *b; building_type *btype; + ally *al; test_cleanup(); test_create_world(); @@ -110,9 +111,8 @@ static void test_contact(CuTest * tc) u_set_building(u1, b); CuAssertIntEquals(tc, 0, can_contact(r, u1, u2)); - u1->faction->allies = calloc(1, sizeof(ally)); - u1->faction->allies->faction = u2->faction; - u1->faction->allies->status = HELP_ALL; + al = ally_add(&u1->faction->allies, u2->faction); + al->status = HELP_ALL; CuAssertIntEquals(tc, HELP_GIVE, can_contact(r, u1, u2)); u_set_building(u2, b); CuAssertIntEquals(tc, 1, can_contact(r, u1, u2)); From cf110d7788eff7a581f2ea362df410c1f859077a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 31 Oct 2014 15:38:37 +0100 Subject: [PATCH 19/26] fix allies with null faction (to be resolved later). --- src/kernel/ally.c | 52 ++++++++++++++++++++++-------------------- src/kernel/ally.test.c | 36 ++++++++++++++++++++--------- 2 files changed, 52 insertions(+), 36 deletions(-) diff --git a/src/kernel/ally.c b/src/kernel/ally.c index cf5772fd6..3ebc7c1ce 100644 --- a/src/kernel/ally.c +++ b/src/kernel/ally.c @@ -4,36 +4,38 @@ #include ally * ally_find(ally *al, const struct faction *f) { - for (;al;al=al->next) { - if (al->faction==f) return al; - } - return 0; + for (; al; al = al->next) { + if (al->faction == f) return al; + } + return 0; } ally * ally_add(ally **al_p, struct faction *f) { - ally * al; - while (*al_p) { - al = *al_p; - if (al->faction==f) return al; - al_p = &al->next; - } - al = (ally *)malloc(sizeof(ally)); - al->faction = f; - al->status = 0; - al->next = 0; - *al_p = al; - return al; + ally * al; + if (f) { + while (*al_p) { + al = *al_p; + if (al->faction == f) return al; + al_p = &al->next; + } + } + al = (ally *)malloc(sizeof(ally)); + al->faction = f; + al->status = 0; + al->next = 0; + *al_p = al; + return al; } void ally_remove(ally **al_p, struct faction *f) { - ally * al; - while (*al_p) { - al = *al_p; - if (al->faction==f) { - *al_p = al->next; - free(al); - break; + ally * al; + while (*al_p) { + al = *al_p; + if (al->faction == f) { + *al_p = al->next; + free(al); + break; + } + al_p = &al->next; } - al_p = &al->next; - } } diff --git a/src/kernel/ally.test.c b/src/kernel/ally.test.c index 7a3155159..fb35d25f7 100644 --- a/src/kernel/ally.test.c +++ b/src/kernel/ally.test.c @@ -7,22 +7,36 @@ static void test_ally(CuTest * tc) { - ally * al = 0; - struct faction * f1 = test_create_faction(0); + ally * al = 0; + struct faction * f1 = test_create_faction(0); - ally_add(&al, f1); - CuAssertPtrNotNull(tc, al); - CuAssertPtrEquals(tc, f1, ally_find(al, f1)->faction); + ally_add(&al, f1); + CuAssertPtrNotNull(tc, al); + CuAssertPtrEquals(tc, f1, ally_find(al, f1)->faction); - ally_remove(&al, f1); - CuAssertPtrEquals(tc, 0, al); - CuAssertPtrEquals(tc, 0, ally_find(al, f1)); + ally_remove(&al, f1); + CuAssertPtrEquals(tc, 0, al); + CuAssertPtrEquals(tc, 0, ally_find(al, f1)); +} + +static void test_ally_null(CuTest * tc) +{ + ally *a1 = 0, *a2 = 0; + + a1 = ally_add(&a1, 0); + a2 = ally_add(&a1, 0); + CuAssertPtrNotNull(tc, a1); + CuAssertPtrNotNull(tc, a2); + CuAssertPtrEquals(tc, a2, a1->next); + CuAssertPtrEquals(tc, 0, a2->next); + free(a1); + free(a2); } CuSuite *get_ally_suite(void) { - CuSuite *suite = CuSuiteNew(); - SUITE_ADD_TEST(suite, test_ally); - return suite; + CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_ally); + return suite; } From 838155179f599caeb127c3349b3f7a1bf3ac9f73 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 31 Oct 2014 15:38:53 +0100 Subject: [PATCH 20/26] fix backwards compatible code for at_permission. --- src/modules/gmcmd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/gmcmd.c b/src/modules/gmcmd.c index 9a5085ecf..d98ae9dbe 100644 --- a/src/modules/gmcmd.c +++ b/src/modules/gmcmd.c @@ -45,9 +45,9 @@ static int read_permissions(attrib * a, void *owner, struct storage *store) { - attrib *attr = NULL; - a_read(store, &attr, owner); - a_remove(&attr, a); + assert(!a); + a_read(store, &a, owner); + a_remove(&a, a); return AT_READ_OK; } From 997d1ffd4b9dbcf3c3a671a33d4e7c10e640838d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 31 Oct 2014 15:52:40 +0100 Subject: [PATCH 21/26] Fix some crashes that happened while debugging an old data file. --- src/kernel/save.c | 7 ++++--- src/reports.c | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/kernel/save.c b/src/kernel/save.c index 77a33b50f..f6fb4c540 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1119,6 +1119,10 @@ static ally **addally(const faction * f, ally ** sfp, int aid, int state) if (state == 0) return sfp; + while (*sfp) { + sfp = &(*sfp)->next; + } + sf = ally_add(sfp, af); if (!sf->faction) { variant id; @@ -1127,9 +1131,6 @@ static ally **addally(const faction * f, ally ** sfp, int aid, int state) } sf->status = state & HELP_ALL; - while (*sfp) - sfp = &(*sfp)->next; - *sfp = sf; return &sf->next; } diff --git a/src/reports.c b/src/reports.c index 1939fa972..e7ca9c314 100644 --- a/src/reports.c +++ b/src/reports.c @@ -1183,7 +1183,7 @@ link_seen(seen_region * seehash[], const region * first, const region * last) } r = r->next; } - sr->next = 0; + if (sr) sr->next = 0; } seen_region *find_seen(struct seen_region *seehash[], const region * r) From 9848ba08d00cdbd3f1324a04f9677f2fc6f700a4 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 31 Oct 2014 15:54:25 +0100 Subject: [PATCH 22/26] fix gcc and clang builds: missing include --- src/kernel/pool.test.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/kernel/pool.test.c b/src/kernel/pool.test.c index 1a0432460..7a45475db 100644 --- a/src/kernel/pool.test.c +++ b/src/kernel/pool.test.c @@ -13,6 +13,7 @@ #include #include #include +#include void test_pool(CuTest *tc) { unit *u1, *u2, *u3; From 6e24fe9be29c213d816b87fc907fc1600f5af480 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 31 Oct 2014 16:51:57 +0100 Subject: [PATCH 23/26] fix gcc build, ebable new test. --- src/kernel/ally.c | 10 ++++------ src/kernel/ally.test.c | 1 + 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/kernel/ally.c b/src/kernel/ally.c index 3ebc7c1ce..ed53cbce4 100644 --- a/src/kernel/ally.c +++ b/src/kernel/ally.c @@ -12,12 +12,10 @@ ally * ally_find(ally *al, const struct faction *f) { ally * ally_add(ally **al_p, struct faction *f) { ally * al; - if (f) { - while (*al_p) { - al = *al_p; - if (al->faction == f) return al; - al_p = &al->next; - } + while (*al_p) { + al = *al_p; + if (f && al->faction == f) return al; + al_p = &al->next; } al = (ally *)malloc(sizeof(ally)); al->faction = f; diff --git a/src/kernel/ally.test.c b/src/kernel/ally.test.c index fb35d25f7..c5c47298f 100644 --- a/src/kernel/ally.test.c +++ b/src/kernel/ally.test.c @@ -37,6 +37,7 @@ CuSuite *get_ally_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_ally); + SUITE_ADD_TEST(suite, test_ally_null); return suite; } From 1d7c193de6f5b1e0fd4ed655ae01fc20da2aa9b6 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 31 Oct 2014 19:01:13 +0100 Subject: [PATCH 24/26] more test coverage for resource pooling. --- src/kernel/pool.test.c | 76 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/src/kernel/pool.test.c b/src/kernel/pool.test.c index 7a45475db..e6594bfac 100644 --- a/src/kernel/pool.test.c +++ b/src/kernel/pool.test.c @@ -15,6 +15,34 @@ #include #include +void test_reservation(CuTest *tc) { + unit *u; + faction *f; + region *r; + struct resource_type *rtype; + test_cleanup(); + test_create_world(); + rtype = rt_get_or_create("money"); + it_get_or_create(rtype); + f = test_create_faction(0); + r = findregion(0, 0); + assert(r && f && rtype && rtype->itype); + u = test_create_unit(f, r); + assert(u); + i_change(&u->items, rtype->itype, 100); + CuAssertIntEquals(tc, 100, get_resource(u, rtype)); + CuAssertIntEquals(tc, 0, get_reservation(u, rtype)); + CuAssertIntEquals(tc, 50, change_reservation(u, rtype, 50)); + CuAssertIntEquals(tc, 100, change_reservation(u, rtype, 50)); + CuAssertIntEquals(tc, 50, set_resvalue(u, rtype, 50)); + CuAssertIntEquals(tc, 100, get_resource(u, rtype)); + CuAssertIntEquals(tc, 200, change_resource(u, rtype, 100)); + CuAssertIntEquals(tc, 200, get_resource(u, rtype)); + CuAssertIntEquals(tc, 200, i_get(u->items, rtype->itype)); + + test_cleanup(); +} + void test_pool(CuTest *tc) { unit *u1, *u2, *u3; faction *f; @@ -60,6 +88,52 @@ void test_pool(CuTest *tc) { CuAssertIntEquals(tc, 300, get_pooled(u1, rtype, GET_ALL, INT_MAX)); } +void test_pool_use(CuTest *tc) { + unit *u1, *u2, *u3; + faction *f; + region *r; + struct resource_type *rtype; + ally *al; + + test_cleanup(); + test_create_world(); + rtype = rt_get_or_create("money"); + it_get_or_create(rtype); + f = test_create_faction(0); + r = findregion(0, 0); + assert(r && f && rtype && rtype->itype); + u1 = test_create_unit(f, r); + u2 = test_create_unit(f, r); + u3 = test_create_unit(test_create_faction(0), r); + assert(u1 && u2); + i_change(&u1->items, rtype->itype, 100); + set_resvalue(u1, rtype, 50); + i_change(&u2->items, rtype->itype, 200); + set_resvalue(u2, rtype, 100); + i_change(&u3->items, rtype->itype, 400); + set_resvalue(u3, rtype, 200); + al = ally_add(&u3->faction->allies, f); + al->status = HELP_MONEY; + + CuAssertIntEquals(tc, 10, use_pooled(u1, rtype, GET_SLACK, 10)); + CuAssertIntEquals(tc, 40, use_pooled(u1, rtype, GET_SLACK, 50)); + CuAssertIntEquals(tc, 50, i_get(u1->items, rtype->itype)); + + CuAssertIntEquals(tc, 50, get_reservation(u1, rtype)); + CuAssertIntEquals(tc, 10, use_pooled(u1, rtype, GET_RESERVE, 10)); + CuAssertIntEquals(tc, 40, i_get(u1->items, rtype->itype)); + CuAssertIntEquals(tc, 40, get_reservation(u1, rtype)); + CuAssertIntEquals(tc, 40, use_pooled(u1, rtype, GET_RESERVE, 50)); + + CuAssertIntEquals(tc, 10, use_pooled(u1, rtype, GET_POOLED_SLACK, 10)); + CuAssertIntEquals(tc, 90, use_pooled(u1, rtype, GET_POOLED_SLACK, 100)); + CuAssertIntEquals(tc, 100, i_get(u2->items, rtype->itype)); + CuAssertIntEquals(tc, 10, use_pooled(u1, rtype, GET_POOLED_RESERVE, 10)); + CuAssertIntEquals(tc, 90, get_reservation(u2, rtype)); + CuAssertIntEquals(tc, 90, use_pooled(u1, rtype, GET_POOLED_RESERVE, 100)); + CuAssertIntEquals(tc, 0, i_get(u2->items, rtype->itype)); +} + void test_change_resource(CuTest * tc) { struct unit * u; @@ -90,7 +164,9 @@ void test_change_resource(CuTest * tc) CuSuite *get_pool_suite(void) { CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_reservation); SUITE_ADD_TEST(suite, test_pool); + SUITE_ADD_TEST(suite, test_pool_use); SUITE_ADD_TEST(suite, test_change_resource); return suite; } From 483a2ba3de4ea54a11d35de9143a7d50e69022f6 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 31 Oct 2014 19:15:26 +0100 Subject: [PATCH 25/26] add missing tests for groups. --- src/kernel/CMakeLists.txt | 1 + src/kernel/group.h | 4 ---- src/kernel/group.test.c | 45 +++++++++++++++++++++++++++++++++++++++ src/test_eressea.c | 1 + 4 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 src/kernel/group.test.c diff --git a/src/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt index 9566317e7..a1ea20a64 100644 --- a/src/kernel/CMakeLists.txt +++ b/src/kernel/CMakeLists.txt @@ -3,6 +3,7 @@ project(kernel C) SET(_TEST_FILES build.test.c config.test.c +group.test.c faction.test.c unit.test.c save.test.c diff --git a/src/kernel/group.h b/src/kernel/group.h index ea312542c..076761d98 100755 --- a/src/kernel/group.h +++ b/src/kernel/group.h @@ -22,9 +22,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. extern "C" { #endif -/* bitfield value for group::flags */ -#define GFL_ALIVE 0x01 /* There is at least one struct unit in the group */ - struct gamedata; typedef struct group { @@ -34,7 +31,6 @@ extern "C" { struct attrib *attribs; char *name; struct ally *allies; - int flags; int gid; int members; } group; diff --git a/src/kernel/group.test.c b/src/kernel/group.test.c new file mode 100644 index 000000000..c1bd01d59 --- /dev/null +++ b/src/kernel/group.test.c @@ -0,0 +1,45 @@ +#include +#include "types.h" +#include "group.h" +#include "faction.h" +#include "unit.h" +#include "region.h" + +#include +#include +#include + +static void test_group(CuTest * tc) +{ + unit *u; + region *r; + faction *f; + group *g; + + test_cleanup(); + test_create_world(); + r = findregion(0, 0); + f = test_create_faction(0); + assert(r && f); + u = test_create_unit(f, r); + assert(u); + CuAssertTrue(tc, join_group(u, "hodor")); + CuAssertPtrNotNull(tc, (g = get_group(u))); + CuAssertStrEquals(tc, "hodor", g->name); + CuAssertIntEquals(tc, 1, g->members); + set_group(u, 0); + CuAssertIntEquals(tc, 0, g->members); + CuAssertPtrEquals(tc, 0, get_group(u)); + set_group(u, g); + CuAssertIntEquals(tc, 1, g->members); + CuAssertPtrEquals(tc, g, get_group(u)); + test_cleanup(); +} + +CuSuite *get_group_suite(void) +{ + CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_group); + return suite; +} + diff --git a/src/test_eressea.c b/src/test_eressea.c index 6fa8767cb..17958c7b2 100644 --- a/src/test_eressea.c +++ b/src/test_eressea.c @@ -40,6 +40,7 @@ int RunAllTests(void) /* kernel */ ADD_TESTS(suite, unit); ADD_TESTS(suite, faction); + ADD_TESTS(suite, group); ADD_TESTS(suite, build); ADD_TESTS(suite, pool); ADD_TESTS(suite, curse); From 5b6663cad799d5db6c71c1f4e1493ada6f45a634 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 31 Oct 2014 22:03:00 +0100 Subject: [PATCH 26/26] Assert that magicians are single-person units in a few places. Bug 2028 claims that this is not always the case, though I cannot prove it. --- src/kernel/unit.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/kernel/unit.c b/src/kernel/unit.c index a039d9c3a..6e7f1eaa0 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -702,6 +702,7 @@ void set_level(unit * u, skill_t sk, int value) { skill *sv = u->skills; + assert(sk != SK_MAGIC || is_monsters(u->faction) || u->number == 1); if (!skill_enabled(sk)) return; @@ -1165,8 +1166,8 @@ skill *add_skill(unit * u, skill_t id) sv->weeks = 1; sv->old = 0; sv->id = id; - if (id == SK_MAGIC && u->faction) { - assert(max_magicians(u->faction) >= u->number); + if (id == SK_MAGIC && u->faction && !is_monsters(u->faction)) { + assert(u->number==1 && max_magicians(u->faction) >= u->number); } return sv; }