summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrofl0r <retnyg@gmx.net>2017-10-16 06:35:27 +0100
committerrofl0r <retnyg@gmx.net>2017-10-16 06:35:27 +0100
commit581a472a26c0db02bf7ad5328682868a84982bd6 (patch)
treeb3fe8e382b2d86a6198df7f4757181087746bce1
parentce0d49fe0c35edb286b7bdfad142c347c40047cc (diff)
parent492ba8458b8d95de0a2d731c6e14ce23efad41db (diff)
downloadgettext-tiny-581a472a26c0db02bf7ad5328682868a84982bd6.tar.gz
Merge remote-tracking branch 'origin/msgmerge-stub'
-rw-r--r--src/msgfmt.c163
-rw-r--r--src/msgmerge.c39
2 files changed, 110 insertions, 92 deletions
diff --git a/src/msgfmt.c b/src/msgfmt.c
index 2dfb3da..d9db752 100644
--- a/src/msgfmt.c
+++ b/src/msgfmt.c
@@ -79,15 +79,15 @@ struct callbackdata {
enum passes pass;
unsigned off;
FILE* out;
- unsigned milen1;
- unsigned milen2;
- unsigned pllen1;
- unsigned pllen2;
- unsigned ctxtlen;
- unsigned mslen1;
- unsigned mslen2;
- unsigned msc;
- unsigned maxlen;
+ unsigned msgidbuf1_len;
+ unsigned msgidbuf2_len;
+ unsigned pluralbuf1_len;
+ unsigned pluralbuf2_len;
+ unsigned ctxtbuf_len;
+ unsigned msgstr1_len;
+ unsigned msgstr2_len;
+ unsigned pluralstr_count;
+ unsigned string_maxlen;
char* msgidbuf1;
char* msgidbuf2;
char* pluralbuf1;
@@ -204,85 +204,88 @@ static void error(const char* msg) {
}
static inline void writemsg(struct callbackdata *d) {
- if(d->milen1 != 0) {
+ if(d->msgidbuf1_len != 0) {
if(!d->strlist[d->curr[pe_msgid]].str.off)
d->strlist[d->curr[pe_msgid]].str.off=d->stroff[pe_msgid];
- if(d->ctxtlen != 0) {
- memcpy(d->strbuffer[pe_msgid] + d->stroff[pe_msgid], d->msgctxtbuf, d->ctxtlen);
- d->strlist[d->curr[pe_msgid]].str.len+=d->ctxtlen;
- d->stroff[pe_msgid]+=d->ctxtlen;
+ if(d->ctxtbuf_len != 0) {
+ memcpy(d->strbuffer[pe_msgid] + d->stroff[pe_msgid], d->msgctxtbuf, d->ctxtbuf_len);
+ d->strlist[d->curr[pe_msgid]].str.len+=d->ctxtbuf_len;
+ d->stroff[pe_msgid]+=d->ctxtbuf_len;
}
- memcpy(d->strbuffer[pe_msgid] + d->stroff[pe_msgid], d->msgidbuf1, d->milen1);
- d->stroff[pe_msgid]+=d->milen1;
- d->strlist[d->curr[pe_msgid]].str.len+=d->milen1-1;
- if(d->pllen1 != 0) {
- memcpy(d->strbuffer[pe_msgid] + d->stroff[pe_msgid], d->pluralbuf1, d->pllen1);
- d->strlist[d->curr[pe_msgid]].str.len+=d->pllen1;
- d->stroff[pe_msgid]+=d->pllen1;
+ memcpy(d->strbuffer[pe_msgid] + d->stroff[pe_msgid], d->msgidbuf1, d->msgidbuf1_len);
+ d->stroff[pe_msgid]+=d->msgidbuf1_len;
+ d->strlist[d->curr[pe_msgid]].str.len+=d->msgidbuf1_len-1;
+ if(d->pluralbuf1_len != 0) {
+ memcpy(d->strbuffer[pe_msgid] + d->stroff[pe_msgid], d->pluralbuf1, d->pluralbuf1_len);
+ d->strlist[d->curr[pe_msgid]].str.len+=d->pluralbuf1_len;
+ d->stroff[pe_msgid]+=d->pluralbuf1_len;
}
d->curr[pe_msgid]++;
}
- if(d->milen2 != 0) {
+ if(d->msgidbuf2_len != 0) {
if(!d->strlist[d->curr[pe_msgid]].str.off)
d->strlist[d->curr[pe_msgid]].str.off=d->stroff[pe_msgid];
- if(d->ctxtlen != 0) {
- memcpy(d->strbuffer[pe_msgid] + d->stroff[pe_msgid], d->msgctxtbuf, d->ctxtlen);
- d->strlist[d->curr[pe_msgid]].str.len+=d->ctxtlen;
- d->stroff[pe_msgid]+=d->ctxtlen;
+ if(d->ctxtbuf_len != 0) {
+ memcpy(d->strbuffer[pe_msgid] + d->stroff[pe_msgid], d->msgctxtbuf, d->ctxtbuf_len);
+ d->strlist[d->curr[pe_msgid]].str.len+=d->ctxtbuf_len;
+ d->stroff[pe_msgid]+=d->ctxtbuf_len;
}
- memcpy(d->strbuffer[pe_msgid] + d->stroff[pe_msgid], d->msgidbuf2, d->milen2);
- d->stroff[pe_msgid]+=d->milen2;
- d->strlist[d->curr[pe_msgid]].str.len+=d->milen2-1;
- if(d->pllen2 != 0) {
- memcpy(d->strbuffer[pe_msgid] + d->stroff[pe_msgid], d->pluralbuf2, d->pllen2);
- d->strlist[d->curr[pe_msgid]].str.len+=d->pllen2;
- d->stroff[pe_msgid]+=d->pllen2;
+ memcpy(d->strbuffer[pe_msgid] + d->stroff[pe_msgid], d->msgidbuf2, d->msgidbuf2_len);
+ d->stroff[pe_msgid]+=d->msgidbuf2_len;
+ d->strlist[d->curr[pe_msgid]].str.len+=d->msgidbuf2_len-1;
+ if(d->pluralbuf2_len != 0) {
+ memcpy(d->strbuffer[pe_msgid] + d->stroff[pe_msgid], d->pluralbuf2, d->pluralbuf2_len);
+ d->strlist[d->curr[pe_msgid]].str.len+=d->pluralbuf2_len;
+ d->stroff[pe_msgid]+=d->pluralbuf2_len;
}
d->curr[pe_msgid]++;
}
- d->pllen2=d->pllen1=d->ctxtlen=d->milen1=d->milen2=0;
+ d->pluralbuf2_len=d->pluralbuf1_len=d->ctxtbuf_len=d->msgidbuf1_len=d->msgidbuf2_len=0;
}
static inline void writestr(struct callbackdata *d, struct po_info *info) {
// msgid xx; msgstr ""; is widely happened, it's invalid
- if(!d->msc) {
- d->len[pe_msgid]-=d->milen1;
- d->len[pe_msgid]-=d->milen2;
- d->len[pe_plural]-=d->pllen1;
- d->len[pe_plural]-=d->pllen2;
- d->len[pe_ctxt]-=d->ctxtlen;
+
+ // https://github.com/sabotage-linux/gettext-tiny/issues/1
+ // no invalid, when empty, check d->num[pe_msgid]
+ if(!d->pluralstr_count && d->num[pe_msgid] > 0) {
+ d->len[pe_msgid]-=d->msgidbuf1_len;
+ d->len[pe_msgid]-=d->msgidbuf2_len;
+ d->len[pe_plural]-=d->pluralbuf1_len;
+ d->len[pe_plural]-=d->pluralbuf2_len;
+ d->len[pe_ctxt]-=d->ctxtbuf_len;
d->len[pe_msgstr]--;
d->num[pe_msgid]--;
d->num[pe_msgstr]--;
- d->pllen2=d->pllen1=d->ctxtlen=d->milen1=d->milen2=d->mslen1=d->mslen2=d->msc=0;
+ d->pluralbuf2_len=d->pluralbuf1_len=d->ctxtbuf_len=d->msgidbuf1_len=d->msgidbuf2_len=d->msgstr1_len=d->msgstr2_len=d->pluralstr_count=0;
return;
}
- if(d->msc && d->msc <= info->nplurals) {
+ if(d->pluralstr_count && d->pluralstr_count <= info->nplurals) {
writemsg(d);
// plural <= nplurals is allowed
- d->translist[d->curr[pe_msgstr]].len=d->mslen1-1;
+ d->translist[d->curr[pe_msgstr]].len=d->msgstr1_len-1;
d->translist[d->curr[pe_msgstr]].off=d->stroff[pe_msgstr];
d->strlist[d->curr[pe_msgstr]].trans = &d->translist[d->curr[pe_msgstr]];
- memcpy(d->strbuffer[pe_msgstr] + d->stroff[pe_msgstr], d->msgstrbuf1, d->mslen1);
- d->stroff[pe_msgstr]+=d->mslen1;
+ memcpy(d->strbuffer[pe_msgstr] + d->stroff[pe_msgstr], d->msgstrbuf1, d->msgstr1_len);
+ d->stroff[pe_msgstr]+=d->msgstr1_len;
d->curr[pe_msgstr]++;
- if(d->mslen2) {
- d->translist[d->curr[pe_msgstr]].len=d->mslen2-1;
+ if(d->msgstr2_len) {
+ d->translist[d->curr[pe_msgstr]].len=d->msgstr2_len-1;
d->translist[d->curr[pe_msgstr]].off=d->stroff[pe_msgstr];
d->strlist[d->curr[pe_msgstr]].trans = &d->translist[d->curr[pe_msgstr]];
- memcpy(d->strbuffer[pe_msgstr] + d->stroff[pe_msgstr], d->msgstrbuf2, d->mslen2);
- d->stroff[pe_msgstr]+=d->mslen2;
+ memcpy(d->strbuffer[pe_msgstr] + d->stroff[pe_msgstr], d->msgstrbuf2, d->msgstr2_len);
+ d->stroff[pe_msgstr]+=d->msgstr2_len;
d->curr[pe_msgstr]++;
}
- d->mslen1=d->mslen2=d->msc=0;
+ d->msgstr1_len=d->msgstr2_len=d->pluralstr_count=0;
}
}
@@ -309,50 +312,50 @@ int process_line_callback(struct po_info* info, void* user) {
d->priv_len = len;
d->len[info->type] += len +1;
- if(len+1 > d->maxlen)
- d->maxlen = len+1;
+ if(len+1 > d->string_maxlen)
+ d->string_maxlen = len+1;
break;
case pass_second:
sysdeps = sysdep_transform(info->text, info->textlen, &len, &count, 0);
for(i=0;i<count;i++) {
l = strlen(sysdeps[i]);
- assert(l+1 <= d->maxlen);
+ assert(l+1 <= d->string_maxlen);
if(info->type == pe_msgid) {
- if(i==0 && d->milen1)
+ if(i==0 && d->msgidbuf1_len)
writestr(d, info);
// just copy, it's written down when writemsg()
if(i==0) {
memcpy(d->msgidbuf1, sysdeps[i], l+1);
- d->milen1 = l+1;
+ d->msgidbuf1_len = l+1;
} else {
memcpy(d->msgidbuf2, sysdeps[i], l+1);
- d->milen2 = l+1;
+ d->msgidbuf2_len = l+1;
}
} else if(info->type == pe_plural) {
if(i==0) {
memcpy(d->pluralbuf1, sysdeps[i], l+1);
- d->pllen1 = l+1;
+ d->pluralbuf1_len = l+1;
} else {
memcpy(d->pluralbuf2, sysdeps[i], l+1);
- d->pllen2 = l+1;
+ d->pluralbuf2_len = l+1;
}
} else if(info->type == pe_ctxt) {
writestr(d, info);
- d->ctxtlen = l+1;
+ d->ctxtbuf_len = l+1;
memcpy(d->msgctxtbuf, sysdeps[i], l);
d->msgctxtbuf[l] = 0x4;//EOT
} else {
// just copy, it's written down when writestr()
if(l) {
if(i==0) {
- memcpy(&d->msgstrbuf1[d->mslen1], sysdeps[i], l+1);
- d->mslen1 += l+1;
- d->msc++;
+ memcpy(&d->msgstrbuf1[d->msgstr1_len], sysdeps[i], l+1);
+ d->msgstr1_len += l+1;
+ d->pluralstr_count++;
} else {
// sysdeps exist
- memcpy(&d->msgstrbuf2[d->mslen2], sysdeps[i], l+1);
- d->mslen2 += l+1;
+ memcpy(&d->msgstrbuf2[d->msgstr2_len], sysdeps[i], l+1);
+ d->msgstr2_len += l+1;
}
}
}
@@ -386,15 +389,15 @@ int process(FILE *in, FILE *out) {
.off = 0,
.out = out,
.pass = pass_first,
- .ctxtlen = 0,
- .pllen1 = 0,
- .pllen2 = 0,
- .milen1 = 0,
- .milen2 = 0,
- .mslen1 = 0,
- .mslen2 = 0,
- .msc = 0,
- .maxlen = 0,
+ .ctxtbuf_len = 0,
+ .pluralbuf1_len = 0,
+ .pluralbuf2_len = 0,
+ .msgidbuf1_len = 0,
+ .msgidbuf2_len = 0,
+ .msgstr1_len = 0,
+ .msgstr2_len = 0,
+ .pluralstr_count = 0,
+ .string_maxlen = 0,
};
struct po_parser pb, *p = &pb;
@@ -413,13 +416,13 @@ int process(FILE *in, FILE *out) {
return 0;
}
- d.msgidbuf1 = calloc(d.maxlen*5+2*d.maxlen*p->info.nplurals, 1);
- d.msgidbuf2 = d.msgidbuf1 + d.maxlen;
- d.pluralbuf1 = d.msgidbuf2 + d.maxlen;
- d.pluralbuf2 = d.pluralbuf1 + d.maxlen;
- d.msgctxtbuf = d.pluralbuf2 + d.maxlen;
- d.msgstrbuf1 = d.msgctxtbuf + d.maxlen;
- d.msgstrbuf2 = d.msgstrbuf1 + d.maxlen*p->info.nplurals;
+ d.msgidbuf1 = calloc(d.string_maxlen*5+2*d.string_maxlen*p->info.nplurals, 1);
+ d.msgidbuf2 = d.msgidbuf1 + d.string_maxlen;
+ d.pluralbuf1 = d.msgidbuf2 + d.string_maxlen;
+ d.pluralbuf2 = d.pluralbuf1 + d.string_maxlen;
+ d.msgctxtbuf = d.pluralbuf2 + d.string_maxlen;
+ d.msgstrbuf1 = d.msgctxtbuf + d.string_maxlen;
+ d.msgstrbuf2 = d.msgstrbuf1 + d.string_maxlen*p->info.nplurals;
d.strlist = calloc(d.num[pe_msgid] * sizeof(struct strmap), 1);
d.translist = calloc(d.num[pe_msgstr] * sizeof(struct strtbl), 1);
diff --git a/src/msgmerge.c b/src/msgmerge.c
index 9b7b4fd..9253106 100644
--- a/src/msgmerge.c
+++ b/src/msgmerge.c
@@ -36,18 +36,34 @@ struct fiLes {
FILE *po;
FILE *pot;
FILE *compend;
+ int plural_count;
+ enum po_entry prev_type;
};
/* currently we only output input strings as output strings
* i.e. there is no translation lookup at all */
int process_line_callback(struct po_info* info, void* user) {
- char convbuf[8192];
- FILE* out = (FILE*) user;
- size_t l;
- if(info->type == pe_msgid) {
- l = escape(info->text, convbuf, sizeof(convbuf));
- (void) l;
- fprintf(out, "msgid \"%s\"\nmsgstr \"%s\"\n", convbuf, convbuf);
+ struct fiLes* file = (struct fiLes*) user;
+ switch (info->type) {
+ case pe_msgid:
+ file->plural_count = 1;
+ fprintf(file->out, "\nmsgid \"%s\"\n", info->text);
+ file->prev_type = info->type;
+ break;
+ case pe_ctxt:
+ fprintf(file->out, "msgctxt \"%s\"\n", info->text);
+ break;
+ case pe_plural:
+ fprintf(file->out, "msgid_plural \"%s\"\n", info->text);
+ file->prev_type = info->type;
+ break;
+ case pe_msgstr:
+ if (file->prev_type == pe_plural) {
+ fprintf(file->out, "msgstr[%d] \"%s\"\n", file->plural_count++, info->text);
+ } else {
+ fprintf(file->out, "msgstr \"%s\"\n", info->text);
+ }
+ break;
}
return 0;
}
@@ -56,9 +72,9 @@ int process(struct fiLes *files, int update, int backup) {
(void) update; (void) backup;
struct po_parser pb, *p = &pb;
char line[4096], conv[8192], *lb;
- poparser_init(p, conv, sizeof(conv), process_line_callback, files->out);
- while((lb = fgets(line, sizeof(line), files->pot))) {
- poparser_feed_line(p, lb, sizeof(line) - (size_t)(lb - line));
+ poparser_init(p, conv, sizeof(conv), process_line_callback, files);
+ while((lb = fgets(line, sizeof(line), files->po))) {
+ poparser_feed_line(p, lb, sizeof(line));
}
poparser_finish(p);
return 0;
@@ -102,7 +118,7 @@ int main(int argc, char**argv) {
.pot = 0,
.compend = 0,
};
- struct fiLes files = {0,0,0,0};
+ struct fiLes files = {0,0,0,0,1,0};
char* backup_suffix = getenv("SIMPLE_BACKUP_SUFFIX");
if(!backup_suffix) backup_suffix = "~";
int update = 0;
@@ -209,7 +225,6 @@ int main(int argc, char**argv) {
}
if(update) {
fprintf(stdout, "error: update functionality unimplemented\n");
- exit(update);
}
if(!files.out || !files.po || !files.pot) syntax();
int ret = process(&files, update, backup);