diff options
Diffstat (limited to 'src/msgfmt.c')
-rw-r--r-- | src/msgfmt.c | 566 |
1 files changed, 172 insertions, 394 deletions
diff --git a/src/msgfmt.c b/src/msgfmt.c index c5d43d7..98a9b88 100644 --- a/src/msgfmt.c +++ b/src/msgfmt.c @@ -1,28 +1,21 @@ /* msgfmt utility (C) 2012 rofl0r * released under the MIT license, see LICENSE for details */ +#define _BSD_SOURCE #include <stdio.h> #include <stdlib.h> +#include <stdint.h> #include <string.h> #include <ctype.h> +#include <limits.h> #include <assert.h> #include "poparser.h" -// in DO_NOTHING mode, we simply write the msgid twice, once for msgid, once for msgstr. -// TODO: maybe make it write "" instead of echoing the msgid. -//#define DO_NOTHING - -__attribute__((noreturn)) static void syntax(void) { - fprintf(stdout, - "Usage: msgfmt [OPTION] filename.po ...\n"); - exit(1); + fprintf(stdout, "Usage: msgfmt [OPTION] filename.po ...\n"); } -__attribute__((noreturn)) static void version(void) { - fprintf(stdout, - "msgfmt (GNU gettext-tools compatible) 99.9999.9999\n"); - exit(0); + fprintf(stdout, "msgfmt (GNU gettext-tools compatible) 99.9999.9999\n"); } #define streq(A, B) (!strcmp(A, B)) @@ -56,314 +49,114 @@ const struct mo_hdr def_hdr = { 0, }; - -// pass 0: collect numbers of strings, calculate size and offsets for tables -// print header -// pass 1: create in-memory string tables -enum passes { - pass_first = 0, - pass_collect_sizes = pass_first, - pass_second, - pass_max, -}; - struct strtbl { - unsigned len, off; + uint32_t len, off; }; struct strmap { - struct strtbl str, *trans; + struct strtbl str; + struct strtbl trans; }; struct callbackdata { - enum passes pass; - unsigned off; FILE* out; - 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; - char* pluralbuf2; - char* msgctxtbuf; - char* msgstrbuf1; - char* msgstrbuf2; - unsigned priv_type; - unsigned priv_len; - unsigned num[pe_maxstr]; - unsigned len[pe_maxstr]; - struct strmap *strlist; - struct strtbl *translist; - char *strbuffer[pe_maxstr]; - unsigned stroff[pe_maxstr]; - unsigned curr[pe_maxstr]; + enum po_stage stage; + size_t cnt; + size_t len[2]; + char* buf[2]; + struct strmap *list; }; static struct callbackdata *cb_for_qsort; -int strmap_comp(const void *a_, const void *b_) { +int strtbl_cmp(const void *a_, const void *b_) { const struct strmap *a = a_, *b = b_; - return strcmp(cb_for_qsort->strbuffer[0] + a->str.off, cb_for_qsort->strbuffer[0] + b->str.off); + return strcmp(cb_for_qsort->buf[0] + a->str.off, cb_for_qsort->buf[0] + b->str.off); } -enum sysdep_types { - st_priu32 = 0, - st_priu64, - st_priumax, - st_max -}; +int process_line_callback(po_message_t msg, void* user) { + struct callbackdata *d = (struct callbackdata *) user; + struct strtbl *str, *trans; + size_t m; + int cnt[st_max] = {0}; + int i, k; -static const char sysdep_str[][10]={ - [st_priu32] = "\x08<PRIu32>", - [st_priu64] = "\x08<PRIu64>", - [st_priumax] = "\x09<PRIuMAX>", -}; -static const char sysdep_repl[][8]={ - [st_priu32] = "\x02lu\0u", - [st_priu64] = "\x02lu\0llu", - [st_priumax] = "\x01ju" -}; -static const char *get_repl(enum sysdep_types type, unsigned nr) { - assert(nr < (unsigned)sysdep_repl[type][0]); - const char* p = sysdep_repl[type]+1; - while(nr--) p+=strlen(p)+1; - return p; -} -static void replace(char* text, unsigned textlen, const char* what, const char * with) { - char*p = text; - size_t la = strlen(what), li=strlen(with); - assert(la >= li); - for(p=text;textlen >= la;) { - if(!memcmp(p,what,la)) { - memcpy(p, with, li); - textlen -= la; - memmove(p+li,p+la,textlen+1); - p+=li; - } else { - p++; - textlen--; - } - } -} -static unsigned get_form(enum sysdep_types type, unsigned no, unsigned occurences[st_max]) { - unsigned i,divisor = 1; - for(i=type+1;i<st_max;i++) if(occurences[i]) divisor *= sysdep_repl[i][0]; - return (no/divisor)%sysdep_repl[type][0]; -} -static char** sysdep_transform(const char* text, unsigned textlen, unsigned *len, unsigned *count, int simulate) { - unsigned occurences[st_max] = {0}; - const char *p=text,*o; - unsigned i,j, l = textlen; - while(l && (o=strchr(p, '<'))) { - l-=o-p;p=o; - unsigned f = 0; - for(i=0;i<st_max;i++) - if(l>=(unsigned)sysdep_str[i][0] && !memcmp(p,sysdep_str[i]+1,sysdep_str[i][0])) { - occurences[i]++; - f=1; - p+=sysdep_str[i][0]; - l-=sysdep_str[i][0]; - break; - } - if(!f) p++,l--; - } - *count = 1; - for(i=0;i<st_max;i++) if(occurences[i]) *count *= sysdep_repl[i][0]; - l = textlen * *count; - for(i=0;i<*count;i++) for(j=0;j<st_max;j++) - if(occurences[j]) l-= occurences[j] * (sysdep_str[j][0] - strlen(get_repl(j, get_form(j, i, occurences)))); - *len = l+*count-1; - - char **out = 0; - if(!simulate) { - out = malloc((sizeof(char*)+textlen+1) * *count); - assert(out); - char *p = (void*)(out+*count); - for(i=0;i<*count;i++) { - out[i]=p; - memcpy(p, text, textlen+1); - p+=textlen+1; - } - for(i=0;i<*count;i++) for(j=0;j<st_max;j++) - if(occurences[j]) - replace(out[i], textlen, sysdep_str[j]+1, get_repl(j, get_form(j, i, occurences))); - } + if (msg->flags & PO_FUZZY) return 0; + if (msg->strlen[0] == 0) return 0; - return out; -} + switch(d->stage) { + case ps_size: + k = 1; + for (i=0; i < st_max; i++) + if (msg->sysdep[i]) + k *= msg->sysdep[i]; -static void error(const char* msg) { - fprintf(stderr, msg); - exit(1); -} + d->len[0] += (msg->id_len + 1)*k; -static inline void writemsg(struct callbackdata *d) { - 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 (msg->plural_len) + d->len[0] += (msg->plural_len + 1)*k; - 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->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->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->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->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]++; - } + if (msg->ctxt_len) + d->len[0] += (msg->ctxt_len + 1)*k; - d->pluralbuf2_len=d->pluralbuf1_len=d->ctxtbuf_len=d->msgidbuf1_len=d->msgidbuf2_len=0; -} + for (i=0; msg->strlen[i]; i++) + d->len[1] += (msg->strlen[i] + 1)*k; -static inline void writestr(struct callbackdata *d, struct po_info *info) { - // msgid xx; msgstr ""; is widely happened, it's invalid - - // 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->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; - } + d->cnt += k; + break; + case ps_parse: + for (k=1; k; d->cnt++) { + k = 0; - if(d->pluralstr_count && d->pluralstr_count <= info->nplurals) { - writemsg(d); - // plural <= nplurals is allowed - 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->msgstr1_len); - d->stroff[pe_msgstr]+=d->msgstr1_len; - d->curr[pe_msgstr]++; - - 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->msgstr2_len); - d->stroff[pe_msgstr]+=d->msgstr2_len; - d->curr[pe_msgstr]++; - } + str = &d->list[d->cnt].str; + trans = &d->list[d->cnt].trans; - d->msgstr1_len=d->msgstr2_len=d->pluralstr_count=0; - } -} + str->off = d->len[0]; + str->len = 0; -int process_line_callback(struct po_info* info, void* user) { - struct callbackdata *d = (struct callbackdata *) user; - assert(info->type == pe_msgid || info->type == pe_ctxt || info->type == pe_msgstr || info->type == pe_plural); - char **sysdeps; - unsigned len, count, i, l; - switch(d->pass) { - case pass_collect_sizes: - sysdep_transform(info->text, info->textlen, &len, &count, 1); - d->num[info->type] += count; - if(info->type == pe_msgid && count == 2 && d->priv_type == pe_ctxt) { - // ctxt meets msgid with sysdeps, multiply num and len to suit it - d->len[pe_ctxt] += d->priv_len +1; - d->num[pe_ctxt]++; + if (msg->ctxt_len) { + m = poparser_sysdep(msg->ctxt, &d->buf[0][d->len[0]], cnt); + str->len += m; + d->buf[0][d->len[0]+m-1] = 0x4; + d->len[0] += m; + } + + m = poparser_sysdep(msg->id, &d->buf[0][d->len[0]], cnt); + str->len += m; + d->len[0] += m; + + if (msg->plural_len) { + m = poparser_sysdep(msg->plural, &d->buf[0][d->len[0]], cnt); + str->len += m; + d->len[0] += m; } - if(count != 1 && info->type == pe_ctxt) { - // except msgid, str, plural, all other types should not have sysdeps - abort(); + + trans->off = d->len[1]; + trans->len = 0; + for (i=0; msg->strlen[i]; i++) { + m = poparser_sysdep(msg->str[i], &d->buf[1][d->len[1]], cnt); + trans->len += m; + d->len[1] += m; } - d->priv_type = info->type; - d->priv_len = len; - d->len[info->type] += 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->string_maxlen); - if(info->type == pe_msgid) { - 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->msgidbuf1_len = l+1; - } else { - memcpy(d->msgidbuf2, sysdeps[i], l+1); - d->msgidbuf2_len = l+1; - } - } else if(info->type == pe_plural) { - if(i==0) { - memcpy(d->pluralbuf1, sysdeps[i], l+1); - d->pluralbuf1_len = l+1; - } else { - memcpy(d->pluralbuf2, sysdeps[i], l+1); - d->pluralbuf2_len = l+1; - } - } else if(info->type == pe_ctxt) { - writestr(d, info); - 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->msgstr1_len], sysdeps[i], l+1); - d->msgstr1_len += l+1; - d->pluralstr_count++; - } else { - // sysdeps exist - memcpy(&d->msgstrbuf2[d->msgstr2_len], sysdeps[i], l+1); - d->msgstr2_len += l+1; - } + for (i=0; i < st_max; i++) { + if (cnt[i] < msg->sysdep[i]) { + cnt[i]++; + + // we have a carry + if (cnt[i] == msg->sysdep[i]) { + cnt[i] = 0; + continue; } + + k = 1; + break; } } - free(sysdeps); - break; - default: - abort(); + } + + break; + default: + abort(); } return 0; } @@ -371,113 +164,88 @@ int process_line_callback(struct po_info* info, void* user) { int process(FILE *in, FILE *out) { struct mo_hdr mohdr = def_hdr; char line[8192]; char *lp; + size_t off, i; + enum po_error t; char convbuf[32768]; struct callbackdata d = { - .num = { - [pe_msgid] = 0, - [pe_msgstr] = 0, - [pe_plural] = 0, - [pe_ctxt] = 0, - }, - .len = { - [pe_msgid] = 0, - [pe_msgstr] = 0, - [pe_plural] = 0, - [pe_ctxt] = 0, - }, - .off = 0, + .len = {0, 0}, + .cnt = 0, .out = out, - .pass = pass_first, - .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; mohdr.off_tbl_trans = mohdr.off_tbl_org; - for(d.pass = pass_first; d.pass <= pass_second; d.pass++) { - if(d.pass == pass_second) { - // start of second pass: - // ensure we dont output when there's no strings at all - if(d.num[pe_msgid] == 0) { - return 1; - } - - // check that data gathered in first pass is consistent - if((d.num[pe_msgstr] < d.num[pe_msgid]) || (d.num[pe_msgstr] > (d.num[pe_msgid] + d.num[pe_plural] * (p->info.nplurals - 1)))) { - // one should actually abort here, - // but gnu gettext simply writes an empty .mo and returns success. - //abort(); - fprintf(stderr, "warning: mismatch of msgid/msgstr count, writing empty .mo file\n"); - d.num[pe_msgid] = 0; - return 0; - } - 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); - d.strbuffer[pe_msgid] = calloc(d.len[pe_msgid]+d.len[pe_plural]+d.len[pe_ctxt], 1); - d.strbuffer[pe_msgstr] = calloc(d.len[pe_msgstr], 1); - d.stroff[pe_msgid] = d.stroff[pe_msgstr] = 0; - assert(d.msgidbuf1 && d.strlist && d.translist && d.strbuffer[pe_msgid] && d.strbuffer[pe_msgstr]); - } - - poparser_init(p, convbuf, sizeof(convbuf), process_line_callback, &d); + poparser_init(p, convbuf, sizeof(convbuf), process_line_callback, &d); + d.stage = p->stage; - while((lp = fgets(line, sizeof(line), in))) { - poparser_feed_line(p, lp, sizeof(line)); - } - poparser_finish(p); - if(d.pass == pass_second) - writestr(&d, &p->info); - - if(d.pass == pass_second) { - // calculate header fields from len and num arrays - mohdr.numstring = d.num[pe_msgid]; - mohdr.off_tbl_org = sizeof(struct mo_hdr); - mohdr.off_tbl_trans = mohdr.off_tbl_org + d.num[pe_msgid] * (sizeof(unsigned)*2); - // set offset startvalue - d.off = mohdr.off_tbl_trans + d.num[pe_msgid] * (sizeof(unsigned)*2); + while((lp = fgets(line, sizeof(line), in))) { + if ((t = poparser_feed_line(p, lp, strlen(line))) != po_success) + return t; + } + if ((t = poparser_finish(p)) != po_success) + return t; + + if (d.cnt == 0) return -1; + + d.list = (struct strmap*)malloc(sizeof(struct strmap)*d.cnt); + d.buf[0] = (char*)malloc(d.len[0]); + d.buf[1] = (char*)malloc(d.len[1]); + d.len[0] = 0; + d.len[1] = 0; + d.cnt = 0; + d.stage = p->stage; + + fseek(in, 0, SEEK_SET); + while ((lp = fgets(line, sizeof(line), in))) { + if ((t = poparser_feed_line(p, lp, strlen(line))) != po_success) { + free(d.list); + free(d.buf[0]); + free(d.buf[1]); + return t; } - fseek(in, 0, SEEK_SET); + } + if ((t = poparser_finish(p)) != po_success) { + free(d.list); + free(d.buf[0]); + free(d.buf[1]); + return t; } cb_for_qsort = &d; - qsort(d.strlist, d.num[pe_msgid], sizeof (struct strmap), strmap_comp); - unsigned i; + qsort(d.list, d.cnt, sizeof(struct strmap), strtbl_cmp); + cb_for_qsort = NULL; // print header + mohdr.numstring = d.cnt; + mohdr.off_tbl_org = sizeof(struct mo_hdr); + mohdr.off_tbl_trans = mohdr.off_tbl_org + d.cnt * sizeof(struct strtbl); fwrite(&mohdr, sizeof(mohdr), 1, out); - for(i = 0; i < d.num[pe_msgid]; i++) { - d.strlist[i].str.off += d.off; - fwrite(&d.strlist[i].str, sizeof(struct strtbl), 1, d.out); + + off = mohdr.off_tbl_trans + d.cnt * sizeof(struct strtbl); + for (i = 0; i < d.cnt; i++) { + d.list[i].str.off += off; + fwrite(&d.list[i].str, sizeof(struct strtbl), 1, d.out); } - for(i = 0; i < d.num[pe_msgid]; i++) { - d.strlist[i].trans->off += d.off + d.len[pe_msgid] + d.len[pe_plural] + d.len[pe_ctxt]; - fwrite(d.strlist[i].trans, sizeof(struct strtbl), 1, d.out); + + off += d.len[0]; + for (i = 0; i < d.cnt; i++) { + d.list[i].trans.off += off; + fwrite(&d.list[i].trans, sizeof(struct strtbl), 1, d.out); } - fwrite(d.strbuffer[pe_msgid], d.len[pe_msgid]+d.len[pe_plural]+d.len[pe_ctxt], 1, d.out); - fwrite(d.strbuffer[pe_msgstr], d.len[pe_msgstr], 1, d.out); + + fwrite(d.buf[0], d.len[0], 1, d.out); + fwrite(d.buf[1], d.len[1], 1, d.out); + + free(d.list); + free(d.buf[0]); + free(d.buf[1]); return 0; } - void set_file(int out, char* fn, FILE** dest) { if(streq(fn, "-")) { if(out) { @@ -505,11 +273,16 @@ void set_file(int out, char* fn, FILE** dest) { } int main(int argc, char**argv) { - if(argc == 1) syntax(); + if (argc == 1) { + syntax(); + return 0; + } + int arg = 1; FILE *out = NULL; FILE *in = NULL; int expect_in_fn = 1; + char path[PATH_MAX]; char* locale = NULL; char* dest = NULL; #define A argv[arg] @@ -539,19 +312,20 @@ int main(int argc, char**argv) { streq(A+2, "statistics") || strstarts(A+2, "check-accelerators=") || strstarts(A+2, "resource=") - ) { - } else if((dest = strstarts(A+2, "locale="))) { - locale = dest; - } else if((dest = strstarts(A+2, "output-file="))) { - set_file(1, dest, &out); - } else if(streq(A+2, "version")) { - version(); - } else if(streq(A+2, "help")) { - syntax(); - } else if (expect_in_fn) { - set_file(0, A, &in); - expect_in_fn = 0; - } + ) { + } else if((locale = strstarts(A+2, "locale="))) { + } else if((dest = strstarts(A+2, "output-file="))) { + set_file(1, dest, &out); + } else if(streq(A+2, "version")) { + version(); + return 0; + } else if(streq(A+2, "help")) { + syntax(); + return 0; + } else if (expect_in_fn) { + set_file(0, A, &in); + expect_in_fn = 0; + } } else if(streq(A + 1, "o")) { arg++; dest = A; @@ -568,8 +342,10 @@ int main(int argc, char**argv) { ) { } else if (streq(A+1, "V")) { version(); + return 0; } else if (streq(A+1, "h")) { syntax(); + return 0; } else if (streq(A+1, "l")) { arg++; locale = A; @@ -587,14 +363,14 @@ int main(int argc, char**argv) { } if (locale != NULL && dest != NULL) { - int sz = snprintf(NULL, 0, "%s/%s.msg", dest, locale); - char msg[sz+1]; - snprintf(msg, sizeof(msg), "%s/%s.msg", dest, locale); - FILE *fp = fopen(msg, "w"); + snprintf(path, sizeof(path), "%s/%s.msg", dest, locale); + FILE *fp = fopen(path, "w"); if (fp) { fclose(fp); return 0; - } else return 1; + } + + return -1; } if(out == NULL) { @@ -603,14 +379,16 @@ int main(int argc, char**argv) { } if(in == NULL || out == NULL) { - return 1; + return -1; } + int ret = process(in, out); fflush(in); fflush(out); + if(in != stdin) fclose(in); if(out != stdout) fclose(out); - if (ret == 1) { + if (ret < 0) { return remove(dest); } return ret; |