po file exporter, also for messages.

This commit is contained in:
Enno Rehling 2018-05-16 21:58:02 +02:00
parent 064a0872ed
commit 0f3e3c9e38
5 changed files with 106 additions and 0 deletions

View File

@ -56,6 +56,7 @@
#include <util/lists.h> #include <util/lists.h>
#include <util/log.h> #include <util/log.h>
#include <util/macros.h> #include <util/macros.h>
#include <util/nrmessage.h>
#include <util/rand.h> #include <util/rand.h>
#include <util/rng.h> #include <util/rng.h>
#include <util/xml.h> #include <util/xml.h>
@ -913,6 +914,25 @@ static int lua_rng_default(lua_State *L) {
return 0; return 0;
} }
static void export_locale(const struct locale *lang, const char *name) {
char fname[64];
FILE * F;
sprintf(fname, "strings.%s.po", name);
F = fopen(fname, "wt");
if (F) {
export_strings(lang, F);
export_messages(lang, F);
fclose(F);
}
}
static int tolua_export_locales(lua_State *L) {
UNUSED_ARG(L);
locale_foreach(export_locale);
return 0;
}
void tolua_bind_open(lua_State * L); void tolua_bind_open(lua_State * L);
int tolua_bindings_open(lua_State * L, const dictionary *inifile) int tolua_bindings_open(lua_State * L, const dictionary *inifile)
@ -1030,6 +1050,7 @@ int tolua_bindings_open(lua_State * L, const dictionary *inifile)
tolua_function(L, TOLUA_CAST "spells", tolua_get_spells); tolua_function(L, TOLUA_CAST "spells", tolua_get_spells);
tolua_function(L, TOLUA_CAST "read_xml", tolua_read_xml); tolua_function(L, TOLUA_CAST "read_xml", tolua_read_xml);
tolua_function(L, TOLUA_CAST "equip_newunits", tolua_equip_newunits); tolua_function(L, TOLUA_CAST "equip_newunits", tolua_equip_newunits);
tolua_function(L, TOLUA_CAST "export_locales", tolua_export_locales);
} tolua_endmodule(L); } tolua_endmodule(L);
return 1; return 1;
} }

View File

@ -221,6 +221,66 @@ void locale_setstring(locale * lang, const char *key, const char *value)
} }
} }
static const char *escape_str(const char *in, FILE *F) {
while (*in) {
char buffer[64];
size_t len = 0;
char *out = buffer;
while (sizeof(buffer) > len + 2) {
if (*in == '\0') break;
if (strchr("\\\"", *in) != NULL) {
*out++ = '\\';
++len;
}
*out++ = *in++;
++len;
}
if (len > 0) {
fwrite(buffer, 1, len, F);
}
}
return in;
}
void po_write_msg(FILE *F, const char *id, const char *str, const char *ctxt) {
if (ctxt) {
fputs("msgctxt \"", F);
escape_str(ctxt, F);
fputs("\"\nmsgid \"", F);
escape_str(id, F);
}
else {
fputs("msgid \"", F);
escape_str(id, F);
}
fputs("\"\nmsgstr \"", F);
escape_str(str, F);
fputs("\"\n\n", F);
}
void export_strings(const struct locale * lang, FILE *F) {
int i;
for (i = 0; i != SMAXHASH; ++i) {
const struct locale_str *find = lang->strings[i];
while (find) {
const char *dcolon = strstr(find->key, "::");
if (dcolon) {
size_t len = dcolon - find->key;
char ctxname[16];
assert(sizeof(ctxname) > len);
memcpy(ctxname, find->key, len);
ctxname[len] = '\0';
po_write_msg(F, dcolon + 2, find->str, ctxname);
}
else {
po_write_msg(F, find->key, find->str, NULL);
}
find = find->nexthash;
}
}
}
const char *locale_name(const locale * lang) const char *locale_name(const locale * lang)
{ {
return lang ? lang->name : "(null)"; return lang ? lang->name : "(null)";
@ -316,6 +376,13 @@ void *get_translation(const struct locale *lang, const char *str, int index) {
return NULL; return NULL;
} }
void locale_foreach(void(*callback)(const struct locale *, const char *)) {
const locale * lang;
for (lang = locales; lang; lang = lang->next) {
callback(lang, lang->name);
}
}
const char *localenames[] = { const char *localenames[] = {
"de", "en", "de", "en",
NULL NULL

View File

@ -20,6 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#define MY_LOCALE_H #define MY_LOCALE_H
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -56,6 +57,10 @@ extern "C" {
void make_locales(const char *str); void make_locales(const char *str);
void locale_foreach(void(*callback)(const struct locale *lang, const char *name));
void export_strings(const struct locale * lang, FILE *F);
void po_write_msg(FILE *F, const char *id, const char *str, const char *ctxt);
#define LOC(lang, s) (lang?locale_string(lang, s, true):s) #define LOC(lang, s) (lang?locale_string(lang, s, true):s)
enum { enum {

View File

@ -190,3 +190,14 @@ void free_nrmesssages(void) {
} }
} }
} }
void export_messages(const struct locale * lang, FILE *F) {
int i;
for (i = 0; i != NRT_MAXHASH; ++i) {
nrmessage_type *nrt = nrtypes[i];
while (nrt) {
po_write_msg(F, nrt->mtype->name, nrt->string, "message");
nrt = nrt->next;
}
}
}

View File

@ -14,6 +14,7 @@
#define H_UTIL_NRMESSAGE #define H_UTIL_NRMESSAGE
#include <stddef.h> #include <stddef.h>
#include <stdio.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -46,6 +47,7 @@ extern "C" {
int nr_level(const struct message *msg); int nr_level(const struct message *msg);
const char *nr_section(const struct message *msg); const char *nr_section(const struct message *msg);
void export_messages(const struct locale * lang, FILE *F);
/* before: /* before:
* fogblock;movement:0;de;{unit} konnte von {region} nicht nach {$dir direction} ausreisen, der Nebel war zu dicht. * fogblock;movement:0;de;{unit} konnte von {region} nicht nach {$dir direction} ausreisen, der Nebel war zu dicht.
* after: * after: