From f788f19f6c66c4ae4c10daf9ee7d994b227fea62 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 23 Oct 2014 16:14:01 +0200 Subject: [PATCH 1/6] 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 2/6] 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 3/6] 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 4/6] 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 5/6] 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 6/6] 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);