luci-base: handle more po format features in po2lmo
- Extract and store the plural calculation function in .lmo files - Handle plural translation messages - Handle translation contexts Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
parent
901a0821f6
commit
9c1bac4168
1 changed files with 136 additions and 79 deletions
|
@ -116,19 +116,30 @@ static void print_index(void *array, int n, FILE *out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum fieldtype {
|
||||||
|
UNSPEC = 0,
|
||||||
|
MSG_CTXT = 1,
|
||||||
|
MSG_ID = 2,
|
||||||
|
MSG_ID_PLURAL = 3,
|
||||||
|
MSG_STR = 4
|
||||||
|
};
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
char line[4096];
|
char line[4096];
|
||||||
char key[4096];
|
char key[4096];
|
||||||
char val[4096];
|
char val[4096];
|
||||||
char tmp[4096];
|
char tmp[4096];
|
||||||
int state = 0;
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
int length = 0;
|
int length = 0;
|
||||||
int n_entries = 0;
|
int n_entries = 0;
|
||||||
void *array = NULL;
|
void *array = NULL;
|
||||||
lmo_entry_t *entry = NULL;
|
lmo_entry_t *entry = NULL;
|
||||||
uint32_t key_id, val_id;
|
uint32_t key_id, val_id;
|
||||||
|
enum fieldtype type = UNSPEC, prev_type = UNSPEC;
|
||||||
|
int plural_num = -1, prev_plural_num = -1;
|
||||||
|
char *ctxt = NULL, *id = NULL, *p;
|
||||||
|
int eof, esc;
|
||||||
|
|
||||||
FILE *in;
|
FILE *in;
|
||||||
FILE *out;
|
FILE *out;
|
||||||
|
@ -136,71 +147,62 @@ int main(int argc, char *argv[])
|
||||||
if( (argc != 3) || ((in = fopen(argv[1], "r")) == NULL) || ((out = fopen(argv[2], "w")) == NULL) )
|
if( (argc != 3) || ((in = fopen(argv[1], "r")) == NULL) || ((out = fopen(argv[2], "w")) == NULL) )
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
|
|
||||||
memset(line, 0, sizeof(key));
|
while (1) {
|
||||||
memset(key, 0, sizeof(val));
|
line[0] = 0;
|
||||||
memset(val, 0, sizeof(val));
|
eof = !fgets(line, sizeof(line), in);
|
||||||
|
|
||||||
while( (NULL != fgets(line, sizeof(line), in)) || (state >= 2 && feof(in)) )
|
if (!strncmp(line, "msgctxt \"", 9)) {
|
||||||
{
|
free(ctxt);
|
||||||
if( state == 0 && strstr(line, "msgid \"") == line )
|
type = MSG_CTXT;
|
||||||
{
|
ctxt = NULL;
|
||||||
switch(extract_string(line, key, sizeof(key)))
|
|
||||||
{
|
|
||||||
case -1:
|
|
||||||
die("Syntax error in msgid");
|
|
||||||
case 0:
|
|
||||||
state = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
state = 2;
|
|
||||||
}
|
}
|
||||||
|
else if (!strncmp(line, "msgid \"", 7)) {
|
||||||
|
if (prev_type != MSG_CTXT) {
|
||||||
|
free(ctxt);
|
||||||
|
ctxt = NULL;
|
||||||
}
|
}
|
||||||
else if( state == 1 || state == 2 )
|
|
||||||
{
|
free(id);
|
||||||
if( strstr(line, "msgstr \"") == line || state == 2 )
|
type = MSG_ID;
|
||||||
{
|
id = NULL;
|
||||||
switch(extract_string(line, val, sizeof(val)))
|
|
||||||
{
|
|
||||||
case -1:
|
|
||||||
state = 4;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
state = 3;
|
|
||||||
}
|
}
|
||||||
|
else if (!strncmp(line, "msgid_plural \"", 14)) {
|
||||||
|
type = MSG_ID_PLURAL;
|
||||||
}
|
}
|
||||||
|
else if (!strncmp(line, "msgstr \"", 8) || !strncmp(line, "msgstr[", 7)) {
|
||||||
|
type = MSG_STR;
|
||||||
|
|
||||||
|
if (line[6] == '[')
|
||||||
|
plural_num = strtoul(line + 7, NULL, 10);
|
||||||
else
|
else
|
||||||
{
|
plural_num = -1;
|
||||||
switch(extract_string(line, tmp, sizeof(tmp)))
|
|
||||||
{
|
|
||||||
case -1:
|
|
||||||
state = 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
strcat(key, tmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if( state == 3 )
|
|
||||||
{
|
|
||||||
switch(extract_string(line, tmp, sizeof(tmp)))
|
|
||||||
{
|
|
||||||
case -1:
|
|
||||||
state = 4;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
strcat(val, tmp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( state == 4 )
|
if (type != prev_type || plural_num != prev_plural_num || eof) {
|
||||||
{
|
switch (prev_type) {
|
||||||
if( strlen(key) > 0 && strlen(val) > 0 )
|
case MSG_CTXT:
|
||||||
{
|
ctxt = strdup(val);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MSG_ID:
|
||||||
|
id = strdup(val);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MSG_STR:
|
||||||
|
if (id && id[0] && val[0]) {
|
||||||
|
if (ctxt && ctxt[0] && prev_plural_num > -1)
|
||||||
|
snprintf(key, sizeof(key), "%s\1%s\2%d", ctxt, id, prev_plural_num);
|
||||||
|
else if (ctxt && ctxt[0])
|
||||||
|
snprintf(key, sizeof(key), "%s\1%s", ctxt, id);
|
||||||
|
else if (prev_plural_num > -1)
|
||||||
|
snprintf(key, sizeof(key), "%s\2%d", id, prev_plural_num);
|
||||||
|
else
|
||||||
|
snprintf(key, sizeof(key), "%s", id);
|
||||||
|
|
||||||
key_id = sfh_hash(key, strlen(key));
|
key_id = sfh_hash(key, strlen(key));
|
||||||
val_id = sfh_hash(val, strlen(val));
|
val_id = sfh_hash(val, strlen(val));
|
||||||
|
|
||||||
if( key_id != val_id )
|
if (key_id != val_id) {
|
||||||
{
|
|
||||||
n_entries++;
|
n_entries++;
|
||||||
array = realloc(array, n_entries * sizeof(lmo_entry_t));
|
array = realloc(array, n_entries * sizeof(lmo_entry_t));
|
||||||
entry = (lmo_entry_t *)array + n_entries - 1;
|
entry = (lmo_entry_t *)array + n_entries - 1;
|
||||||
|
@ -209,7 +211,7 @@ int main(int argc, char *argv[])
|
||||||
die("Out of memory");
|
die("Out of memory");
|
||||||
|
|
||||||
entry->key_id = key_id;
|
entry->key_id = key_id;
|
||||||
entry->val_id = val_id;
|
entry->val_id = prev_plural_num + 1;
|
||||||
entry->offset = offset;
|
entry->offset = offset;
|
||||||
entry->length = strlen(val);
|
entry->length = strlen(val);
|
||||||
|
|
||||||
|
@ -219,25 +221,80 @@ int main(int argc, char *argv[])
|
||||||
offset += length;
|
offset += length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (id && id[0] == 0) {
|
||||||
|
for (id = val, p = val; *p; p++) {
|
||||||
|
if (esc) {
|
||||||
|
if (*p == 'n') {
|
||||||
|
p[-1] = 0;
|
||||||
|
|
||||||
state = 0;
|
if (!strncasecmp(id, "Plural-Forms: ", 14)) {
|
||||||
memset(key, 0, sizeof(key));
|
id += 14;
|
||||||
memset(val, 0, sizeof(val));
|
|
||||||
|
n_entries++;
|
||||||
|
array = realloc(array, n_entries * sizeof(lmo_entry_t));
|
||||||
|
entry = (lmo_entry_t *)array + n_entries - 1;
|
||||||
|
|
||||||
|
if (!array)
|
||||||
|
die("Out of memory");
|
||||||
|
|
||||||
|
entry->key_id = 0;
|
||||||
|
entry->val_id = 0;
|
||||||
|
entry->offset = offset;
|
||||||
|
entry->length = strlen(id);
|
||||||
|
|
||||||
|
length = strlen(id) + ((4 - (strlen(id) % 4)) % 4);
|
||||||
|
|
||||||
|
print(id, length, 1, out);
|
||||||
|
offset += length;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(line, 0, sizeof(line));
|
id = p + 1;
|
||||||
|
esc = 0;
|
||||||
|
}
|
||||||
|
else if (*p == '\\') {
|
||||||
|
esc = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
id = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
val[0] = 0;
|
||||||
|
prev_type = type;
|
||||||
|
prev_plural_num = plural_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eof)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (prev_type != UNSPEC) {
|
||||||
|
switch (extract_string(line, tmp, sizeof(tmp))) {
|
||||||
|
case -1:
|
||||||
|
type = UNSPEC;
|
||||||
|
plural_num = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
strcat(val, tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
print_index(array, n_entries, out);
|
print_index(array, n_entries, out);
|
||||||
|
|
||||||
if( offset > 0 )
|
if (offset > 0) {
|
||||||
{
|
|
||||||
print_uint32(offset, out);
|
print_uint32(offset, out);
|
||||||
fsync(fileno(out));
|
fsync(fileno(out));
|
||||||
fclose(out);
|
fclose(out);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
fclose(out);
|
fclose(out);
|
||||||
unlink(argv[2]);
|
unlink(argv[2]);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue