forked from github/server
load strings from po file, not xml.
This commit is contained in:
parent
9ca945cb2c
commit
c596402e4a
5 changed files with 166 additions and 3 deletions
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"include": [
|
||||
"config://res/translations/strings.de.po",
|
||||
"config://res/translations/strings.en.po",
|
||||
"config://res/core/messages.xml",
|
||||
"config://res/core/de/strings.xml",
|
||||
"config://res/core/en/strings.xml",
|
||||
"config://res/eressea/strings.xml",
|
||||
"config://res/eressea/spellinfo.xml",
|
||||
"config://res/names-undead.xml",
|
||||
|
|
|
@ -126,6 +126,7 @@ set (ERESSEA_SRC
|
|||
summary.c
|
||||
travelthru.c
|
||||
monsters.c
|
||||
pofile.c
|
||||
wormhole.c
|
||||
xmlreader.c
|
||||
${SPELLS_SRC}
|
||||
|
|
|
@ -45,6 +45,7 @@ without prior permission by the authors of Eressea.
|
|||
#include "keyword.h"
|
||||
#include "move.h"
|
||||
#include "prefix.h"
|
||||
#include "pofile.h"
|
||||
#include "skill.h"
|
||||
|
||||
/* external libraries */
|
||||
|
@ -1020,6 +1021,40 @@ static int include_xml(const char *uri) {
|
|||
return err;
|
||||
}
|
||||
|
||||
static int add_po_string(const char *msgid, const char *msgstr, const char *msgctxt, void *data) {
|
||||
struct locale * lang = (struct locale *)data;
|
||||
const char * key = msgid;
|
||||
if (msgctxt) {
|
||||
key = mkname(msgctxt, msgid);
|
||||
}
|
||||
locale_setstring(lang, key, msgstr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int include_po(const char *uri) {
|
||||
char name[PATH_MAX], lname[8];
|
||||
const char *filename = uri_to_file(uri, name, sizeof(name));
|
||||
const char *pos = strstr(filename, ".po");
|
||||
if (pos) {
|
||||
const char *str = --pos;
|
||||
while (str > filename && *str != '.') --str;
|
||||
if ((pos - str) < sizeof(lname)) {
|
||||
struct locale * lang;
|
||||
memcpy(lname, str+1, pos - str);
|
||||
lname[pos - str] = 0;
|
||||
lang = get_or_create_locale(lname);
|
||||
if (lang) {
|
||||
int err = pofile_read(filename, add_po_string, lang);
|
||||
if (err < 0) {
|
||||
log_error("could not parse XML from %s", uri);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void json_include(cJSON *json) {
|
||||
cJSON *child;
|
||||
if (json->type != cJSON_Array) {
|
||||
|
@ -1030,7 +1065,10 @@ static void json_include(cJSON *json) {
|
|||
const char *uri = child->valuestring;
|
||||
int err;
|
||||
|
||||
if (strstr(uri, ".xml") != NULL) {
|
||||
if (strstr(uri, ".po") != NULL) {
|
||||
err = include_po(uri);
|
||||
}
|
||||
else if (strstr(uri, ".xml") != NULL) {
|
||||
err = include_xml(uri);
|
||||
}
|
||||
else {
|
||||
|
|
116
src/pofile.c
Normal file
116
src/pofile.c
Normal file
|
@ -0,0 +1,116 @@
|
|||
#ifdef _MSC_VER
|
||||
#include <platform.h>
|
||||
#endif
|
||||
|
||||
#include "pofile.h"
|
||||
|
||||
#include "util/log.h"
|
||||
#include "util/strings.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAXLINE 2048
|
||||
static char po_line[MAXLINE];
|
||||
static int po_lineno;
|
||||
|
||||
char * read_line(FILE *F) {
|
||||
char * read = fgets(po_line, MAXLINE, F);
|
||||
++po_lineno;
|
||||
return read;
|
||||
}
|
||||
|
||||
char * read_multiline(FILE *F, char *line, char *buffer, size_t size) {
|
||||
char *output = buffer;
|
||||
while (line) {
|
||||
size_t len;
|
||||
char *read = line;
|
||||
while (read[0] && isspace(read[0])) {
|
||||
/* eat whitespace */
|
||||
++read;
|
||||
}
|
||||
if (read[0] != '"') {
|
||||
break;
|
||||
}
|
||||
++read;
|
||||
str_unescape(read);
|
||||
len = strlen(read);
|
||||
if (len >= 2) {
|
||||
/* strip trailing quote (and possible newline) */
|
||||
if (read[len - 1] == '\n') {
|
||||
--len;
|
||||
}
|
||||
if (read[len - 1] == '"') {
|
||||
--len;
|
||||
}
|
||||
if (size > len) {
|
||||
/* copy into buffer */
|
||||
memcpy(output, read, len);
|
||||
output += len;
|
||||
size -= len;
|
||||
output[0] = '\0';
|
||||
}
|
||||
}
|
||||
line = read_line(F);
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
int pofile_read(const char *filename, int (*callback)(const char *msgid, const char *msgstr, const char *msgctxt, void *data), void *data) {
|
||||
FILE * F = fopen(filename, "rt");
|
||||
char msgctxt[32];
|
||||
char msgid[64];
|
||||
char msgstr[2048];
|
||||
char *line;
|
||||
int err = 0;
|
||||
|
||||
if (!F) {
|
||||
log_error("could not open %s", filename);
|
||||
}
|
||||
|
||||
msgctxt[0] = 0;
|
||||
msgid[0] = 0;
|
||||
line = read_line(F);
|
||||
while (line) {
|
||||
char token[8];
|
||||
int err = sscanf(line, "%8s", token);
|
||||
if (err == 1) {
|
||||
char *text = NULL;
|
||||
size_t size, len = strlen(token);
|
||||
|
||||
line = line + len + 1;
|
||||
if (len == 7 && memcmp(token, "msgctxt", 7) == 0) {
|
||||
text = msgctxt;
|
||||
size = sizeof(msgctxt);
|
||||
}
|
||||
else if (len == 5 && memcmp(token, "msgid", 5) == 0) {
|
||||
text = msgid;
|
||||
size = sizeof(msgid);
|
||||
}
|
||||
else if (len == 6 && memcmp(token, "msgstr", 6) == 0) {
|
||||
line = read_multiline(F, line, msgstr, sizeof(msgstr));
|
||||
if (msgid[0]) {
|
||||
err = callback(msgid, msgstr, msgctxt[0] ? msgctxt : NULL, data);
|
||||
if (err != 0) {
|
||||
break;
|
||||
}
|
||||
msgctxt[0] = 0;
|
||||
msgid[0] = 0;
|
||||
}
|
||||
}
|
||||
if (text) {
|
||||
line = read_multiline(F, line, text, size);
|
||||
}
|
||||
}
|
||||
else {
|
||||
line = read_line(F);
|
||||
}
|
||||
}
|
||||
if (ferror(F)) {
|
||||
log_error("read error in %s:%d.", filename, po_lineno);
|
||||
return -1;
|
||||
}
|
||||
fclose(F);
|
||||
return err;
|
||||
}
|
8
src/pofile.h
Normal file
8
src/pofile.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef H_POFILE
|
||||
#define H_POFILE
|
||||
|
||||
int pofile_read(const char *filename, int (*callback)(const char *msgid, const char *msgstr, const char *msgctxt, void *data), void *data);
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue