summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxhe <xw897002528@gmail.com>2020-01-22 18:41:00 +0800
committerxhe <xw897002528@gmail.com>2020-01-22 22:18:06 +0800
commit29c38d04e39c9b0ccea4d2e99ef197910431dbc4 (patch)
tree6d9ab0328f24d7b6c588d9233531faa06cec0835
parentc83067e03d2929f358dbdc10bea49d3df0e5e78e (diff)
downloadgettext-tiny-29c38d04e39c9b0ccea4d2e99ef197910431dbc4.tar.gz
poparser: support feeds anything[2/2]
this is the second patch. It mainly changes the working method of feed_line(). Previously, feed_line() assumes the input is a complete whole line. Also it uses the buffer passed by init() to do iconv things. Now, feed_line() assumes nothing about the input. It accumulates strings until a complete line is feeded. A postive return value says the poparser is expecting more strings and it's not an error. But after when you feed all the data, poparser should consumes all tokens exactly, so the last call to feed_line() should return 0. And that introduce the 2nd issue. Incomplete strings will not be consumed , so it needs to be stored. Thus, we alloc an internal buffer. When we do not need to do iconv, we just copy new strings after old strings. Or let iconv do the copy. This also elimates the need of passing an iconv buffer to poparser. now msgfmt and msgmerge use fread. and poparser_feed_line() is renamed as poparser_feed().
-rw-r--r--src/msgfmt.c29
-rw-r--r--src/msgmerge.c33
-rw-r--r--src/poparser.c455
-rw-r--r--src/poparser.h19
4 files changed, 291 insertions, 245 deletions
diff --git a/src/msgfmt.c b/src/msgfmt.c
index 1120ff6..a7b72da 100644
--- a/src/msgfmt.c
+++ b/src/msgfmt.c
@@ -160,10 +160,9 @@ int process_line_callback(po_message_t msg, void* user) {
int process(FILE *in, FILE *out, bool strict) {
struct mo_hdr mohdr = def_hdr;
- char line[8192]; char *lp;
- size_t off, i;
+ char line[4096];
+ size_t off, i, sz;
enum po_error t;
- char convbuf[32768];
struct callbackdata d = {
.len = {0, 0},
@@ -175,15 +174,19 @@ int process(FILE *in, FILE *out, bool strict) {
mohdr.off_tbl_trans = mohdr.off_tbl_org;
- poparser_init(p, convbuf, sizeof(convbuf), process_line_callback, &d);
+ poparser_init(p, process_line_callback, &d);
p->strict = strict;
d.stage = p->stage;
- while((lp = fgets(line, sizeof(line), in))) {
- if ((t = poparser_feed_line(p, lp, strlen(line))) != po_success)
- return t;
+ while((sz = fread(line, 1, sizeof(line), in)) != 0) {
+ if ((t = poparser_feed(p, line, sz)) < 0)
+ return -t;
+ }
+ if (ferror(in)) {
+ fprintf(stderr, "file read error\n");
+ return -1;
}
- if ((t = poparser_finish(p)) != po_success)
+ if ((t = poparser_finish(p)) < 0)
return t;
if (strict && d.cnt == 0) return -(po_error_last+1);
@@ -197,15 +200,19 @@ int process(FILE *in, FILE *out, bool strict) {
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) {
+ while((sz = fread(line, 1, sizeof(line), in)) != 0) {
+ if ((t = poparser_feed(p, line, sz)) < 0) {
free(d.list);
free(d.buf[0]);
free(d.buf[1]);
return t;
}
}
- if ((t = poparser_finish(p)) != po_success) {
+ if (ferror(in)) {
+ fprintf(stderr, "file read error\n");
+ return -1;
+ }
+ if ((t = poparser_finish(p)) < 0) {
free(d.list);
free(d.buf[0]);
free(d.buf[1]);
diff --git a/src/msgmerge.c b/src/msgmerge.c
index 26499c2..36420e7 100644
--- a/src/msgmerge.c
+++ b/src/msgmerge.c
@@ -99,32 +99,43 @@ int process(struct fiLes *files, int update, int backup) {
(void) update; (void) backup;
enum po_error t;
struct po_parser pb, *p = &pb;
- char line[8192], conv[32768], *lb;
+ char line[4096];
+ size_t sz;
files->stage = ps_size;
files->len = 0;
- poparser_init(p, conv, sizeof(conv), process_line_callback, files);
- while((lb = fgets(line, sizeof(line), files->po))) {
- if ((t = poparser_feed_line(p, lb, strlen(line))) != po_success)
- return t;
+ poparser_init(p, process_line_callback, files);
+ while((sz = fread(line, 1, sizeof(line), files->po)) != 0) {
+ if ((t = poparser_feed(p, line, sz)) < 0)
+ return -t;
}
- if ((t = poparser_finish(p)) != po_success)
+ if (ferror(files->po)) {
+ fprintf(stderr, "file read error\n");
+ return -1;
+ }
+ if ((t = poparser_finish(p)) < 0) {
free(files->buf);
+ return -t;
+ }
files->stage = ps_parse;
files->len *= 2;
files->buf = (char*)malloc(files->len);
fseek(files->po, 0, SEEK_SET);
- while((lb = fgets(line, sizeof(line), files->po))) {
- if ((t = poparser_feed_line(p, lb, strlen(line))) != po_success) {
+ while((sz = fread(line, 1, sizeof(line), files->po)) != 0) {
+ if ((t = poparser_feed(p, line, sz)) < 0) {
free(files->buf);
- return t;
+ return -t;
}
}
- if ((t = poparser_finish(p)) != po_success) {
+ if (ferror(files->po)) {
+ fprintf(stderr, "file read error\n");
+ return -1;
+ }
+ if ((t = poparser_finish(p)) < 0) {
free(files->buf);
- return t;
+ return -t;
}
free(files->buf);
diff --git a/src/poparser.c b/src/poparser.c
index 2780372..dd794f4 100644
--- a/src/poparser.c
+++ b/src/poparser.c
@@ -3,6 +3,7 @@
#include <stdint.h>
#include <string.h>
#include <iconv.h>
+#include <errno.h>
#include "poparser.h"
#include "StringEscape.h"
@@ -31,11 +32,14 @@ static const int sysdep[st_max]={
[st_priumax] = PO_SYSDEP_PRIUMAX,
};
-void poparser_init(struct po_parser *p, char* workbuf, size_t bufsize, poparser_callback cb, void* cbdata) {
+void poparser_init(struct po_parser *p, poparser_callback cb, void* cbdata) {
int cnt;
memset(p, 0, sizeof(struct po_parser));
- p->buf = workbuf;
- p->bufsize = bufsize;
+ p->bufsize = 4096;
+ p->buf = malloc(p->bufsize);
+ p->iconv_bufsize = 4096;
+ p->iconv_buf = malloc(p->iconv_bufsize);
+ p->bufpos = 0;
p->cb = cb;
p->cbdata = cbdata;
p->hdr.nplurals = MAX_NPLURALS;
@@ -44,43 +48,40 @@ void poparser_init(struct po_parser *p, char* workbuf, size_t bufsize, poparser_
p->max_plural_len = 1;
for (cnt = 0; cnt < MAX_NPLURALS; cnt++)
p->max_strlen[cnt] = 1;
- p->strcnt = 0;
- p->first = true;
+ p->current_strcnt = 0;
+ p->current_trans_index = 0;
}
static inline enum po_error poparser_feed_hdr(struct po_parser *p, char* msg) {
char *x, *y;
- if (p->first && msg) {
- if ((x = strstr(msg, "charset="))) {
- for (y = x; *y && *y != '\\' && !isspace(*y); y++);
+ if (!msg || p->stage != ps_parse || p->current_trans_index != 0)
+ return po_success;
- if ((uintptr_t)(y-x-7) > sizeof(p->hdr.charset))
- return -po_unsupported_charset;
+ if ((x = strstr(msg, "charset="))) {
+ for (y = x; *y && *y != '\\' && !isspace(*y); y++);
- memcpy(p->hdr.charset, x+8, y-x-8);
- p->hdr.charset[y-x-8] = 0;
+ if ((uintptr_t)(y-x-7) > sizeof(p->hdr.charset))
+ return -po_unsupported_charset;
- p->cd = iconv_open("UTF-8", p->hdr.charset);
- if (p->cd == (iconv_t)-1) {
- p->cd = 0;
- if (p->strict) return -po_unsupported_charset;
- }
- }
+ memcpy(p->hdr.charset, x+8, y-x-8);
+ p->hdr.charset[y-x-8] = 0;
- if ((x = strstr(msg, "nplurals="))) {
- p->hdr.nplurals = *(x+9) - '0';
+ p->cd = iconv_open("UTF-8", p->hdr.charset);
+ if (p->cd == (iconv_t)-1) {
+ p->cd = 0;
+ if (p->strict) return -po_unsupported_charset;
}
}
+ if ((x = strstr(msg, "nplurals="))) {
+ p->hdr.nplurals = *(x+9) - '0';
+ }
+
return po_success;
}
static inline enum po_error poparser_clean(struct po_parser *p, po_message_t msg) {
- if (p->strcnt) {
- if (p->first) p->first = false;
-
- msg->strlen[p->strcnt] = 0;
-
+ if (p->current_strcnt) {
// PO_SYSDEP_PRIUMAX == 0, it has no effects to our codes
switch (msg->sysdep) {
case PO_SYSDEP_PRIU32:
@@ -104,266 +105,278 @@ static inline enum po_error poparser_clean(struct po_parser *p, po_message_t msg
msg->id_len = 0;
msg->plural_len = 0;
msg->flags = 0;
- p->strcnt = 0;
+ p->current_strcnt = 0;
+ p->current_trans_index++;
}
return po_success;
}
-enum po_error poparser_feed_line(struct po_parser *p, char* in, size_t in_len) {
- char *line = in;
- size_t line_pos;
- size_t line_len = in_len;
+enum po_error poparser_feed(struct po_parser *p, char* in, size_t in_len) {
+ enum po_error t = po_success;
po_message_t msg = &p->msg;
int cnt = 0;
- enum po_error t;
size_t len;
char *x, *y, *z;
- // if we need to conv encodings
- if (p->cd) {
- x = p->buf;
- len = p->bufsize;
- if (iconv(p->cd, &line, &line_len, &x, &len) == (size_t)-1)
- return -po_failed_iconv;
-
- if (line_len != 0)
- return -po_failed_iconv;
-
- line_len = x - p->buf;
- line = p->buf;
+ if ( (p->bufsize - p->bufpos) < in_len ) {
+ p->bufsize += + in_len;
+ p->buf = realloc(p->buf, p->bufsize);
}
-
- for (line_pos=0; line_pos < line_len;) {
- switch (line[line_pos]) {
- case '\n':
- case ' ':
- line_pos++;
- break;
- case '#':
- if (p->previous == po_str) {
- if ( (t = poparser_clean(p, msg)) != po_success)
- return t;
- }
-
- switch (line[line_pos+1]) {
- case ',':
- x = &line[line_pos+2];
- while (*x && (y = strpbrk(x, " ,\n"))) {
- if (y != x && !memcmp(x, "fuzzy", y-x)) {
- msg->flags |= PO_FUZZY;
- }
- x = y + strspn(y, " ,\n");
- }
- break;
- case '.':
- // extracted comments for translators, ignore
- case ':':
- // reference comments for translators, ignore
- case '|':
- // previous untranslated strings for translators, ignore
- default:
- // ignore normal comments
- break;
- }
-
- // whole line is commented
- line_pos = line_len;
- break;
- case '"':
- y = x = &line[line_pos+1];
- while (true) {
- if ( (y = strchr(y, '"')) == NULL)
- return -po_excepted_token;
-
- // only if it's not an escaped "
- if (*(y-1) != '\\') break;
- }
-
- len = y - x;
- *y = 0;
- line_pos += len + 2;
-
- for (cnt = 0; cnt < st_max; cnt++) {
- if (strstr(x, sysdep_str[cnt])) {
- msg->sysdep |= sysdep[cnt];
+ memcpy(&p->buf[p->bufpos], in, in_len);
+ p->bufpos += in_len;
+ p->buf[p->bufpos] = 0;
+
+ x = p->buf;
+ for (;(z = strpbrk(x, "\r\n")) != NULL;x=z) {
+ // make null terminator for the current line, then point to next line
+ *z++ = 0;
+
+ // if we need to conv encodings
+ if (p->cd) {
+ in_len = z - x;
+ y = p->iconv_buf;
+ len = p->iconv_bufsize;
+
+ errno = 0;
+ while (iconv(p->cd, &x, &in_len, &y, &len) == (size_t)-1) {
+ if (errno == E2BIG) {
+ // not big enough buffer
+ len = y - p->iconv_buf;
+ p->iconv_buf = realloc(p->iconv_buf, p->iconv_bufsize + in_len * 4);
+ p->iconv_bufsize += in_len * 4;
+ y = &p->iconv_buf[len];
+ len = p->iconv_bufsize - len;
+ } else {
+ t = -po_failed_iconv;
+ goto exit;
}
}
- switch (p->previous) {
- case po_str:
- if ((t = poparser_feed_hdr(p, x)) != po_success) {
- return t;
- }
-
- cnt = p->strcnt - 1;
- if (p->stage == ps_parse) {
- len = unescape(x, &msg->str[cnt][msg->strlen[cnt]], p->max_strlen[cnt]);
- }
-
- msg->strlen[cnt] += len;
- break;
- case po_plural:
- if (p->stage == ps_parse) {
- len = unescape(x, &msg->plural[msg->plural_len], p->max_plural_len);
- }
+ x = p->iconv_buf;
+ }
- msg->plural_len += len;
+ while (x && *x != 0) {
+ switch (*x++) {
+ case ' ':
+ case '\t':
break;
- case po_id:
- if (p->stage == ps_parse) {
- len = unescape(x, &msg->id[msg->id_len], p->max_id_len);
+ case '#':
+ if (p->current_entry == po_str) {
+ if ( (t = poparser_clean(p, msg)) != po_success) {
+ goto exit;
+ }
}
- msg->id_len += len;
- break;
- case po_ctxt:
- if (p->stage == ps_parse) {
- len = unescape(x, &msg->ctxt[msg->ctxt_len], p->max_ctxt_len);
+ switch (*x) {
+ case ',':
+ for (x = strtok(x, " ,"); x; x = strtok(NULL, " ")) {
+ if (!strcmp(x, "fuzzy")) {
+ msg->flags |= PO_FUZZY;
+ }
+ }
+ break;
+ case '.':
+ // extracted comments for translators, ignore
+ case ':':
+ // reference comments for translators, ignore
+ case '|':
+ // current_entry untranslated strings for translators, ignore
+ default:
+ // ignore normal comments
+ break;
}
- msg->ctxt_len += len;
+ x = NULL;
break;
- default:
- return -po_invalid_entry;
- }
-
- break;
- default:
- if ((z = strstarts(&line[line_pos], "msg"))) {
- if ( (x = strchr(z, '"')) == NULL)
- return -po_excepted_token;
-
- y = ++x;
+ case '"':
+ y = x;
while (true) {
- if ( (y = strchr(y, '"')) == NULL)
- return -po_excepted_token;
+ if ( (y = strchr(y, '"')) == NULL) {
+ t = -po_excepted_token;
+ goto exit;
+ }
// only if it's not an escaped "
if (*(y-1) != '\\') break;
+ else y++;
}
len = y - x;
*y = 0;
- line_pos += y - &line[line_pos] + 1;
-
- if ((y = strstarts(z, "ctxt")) && isspace(*y)) {
- if ( (t = poparser_clean(p, msg)) != po_success)
- return t;
- if (msg->id_len || msg->plural_len)
- return -po_invalid_entry;
-
- for (cnt = 0; cnt < st_max; cnt++) {
- if (strstr(x, sysdep_str[cnt])) {
- msg->sysdep |= sysdep[cnt];
- }
+ for (cnt = 0; cnt < st_max; cnt++) {
+ if (strstr(x, sysdep_str[cnt])) {
+ msg->sysdep |= sysdep[cnt];
}
+ }
+ switch (p->current_entry) {
+ case po_str:
if (p->stage == ps_parse) {
- if (msg->ctxt == NULL) {
- return -po_internal;
+ if (msg->str[p->current_strcnt - 1] == NULL) {
+ t = -po_internal;
+ goto exit;
}
- len = unescape(x, msg->ctxt, p->max_ctxt_len);
- }
-
- msg->ctxt_len = len;
- p->previous = po_ctxt;
- } else if ((y = strstarts(z, "id")) && isspace(*y)) {
- if ( (t = poparser_clean(p, msg)) != po_success)
- return t;
+ len = unescape(x, &msg->str[p->current_strcnt - 1][msg->strlen[p->current_strcnt - 1]], p->max_strlen[p->current_strcnt - 1]);
+ msg->strlen[p->current_strcnt - 1] += len;
- if (msg->plural_len)
- return -po_invalid_entry;
-
- for (cnt = 0; cnt < st_max; cnt++) {
- if (strstr(x, sysdep_str[cnt])) {
- msg->sysdep |= sysdep[cnt];
+ if ((t = poparser_feed_hdr(p, x)) != po_success) {
+ goto exit;
}
+ } else if (p->stage == ps_size) {
+
+ msg->strlen[p->current_strcnt - 1] += len;
+ if (p->max_strlen[p->current_strcnt - 1] < msg->strlen[p->current_strcnt - 1])
+ p->max_strlen[p->current_strcnt - 1] = msg->strlen[p->current_strcnt - 1] + 1;
}
+ break;
+ case po_plural:
+ if (p->stage == ps_parse) {
+ if (msg->plural == NULL) {
+ t = -po_internal;
+ goto exit;
+ }
+ len = unescape(x, &msg->plural[msg->plural_len], p->max_plural_len);
+ msg->plural_len += len;
+ } else if (p->stage == ps_size) {
+ msg->plural_len += len;
+ if (p->max_plural_len < msg->plural_len)
+ p->max_plural_len = msg->plural_len + 1;
+ }
+ break;
+ case po_id:
if (p->stage == ps_parse) {
if (msg->id == NULL) {
- return -po_internal;
+ t = -po_internal;
+ goto exit;
}
- len = unescape(x, msg->id, p->max_id_len);
+ len = unescape(x, &msg->id[msg->id_len], p->max_id_len);
+ msg->id_len += len;
+ } else if (p->stage == ps_size) {
+ msg->id_len += len;
+ if (p->max_id_len < msg->id_len)
+ p->max_id_len = msg->id_len + 1;
}
-
- msg->id_len = len;
- p->previous = po_id;
- } else if ((y = strstarts(z, "id_plural")) && isspace(*y)) {
- if (!msg->id_len || p->strcnt)
- return -po_invalid_entry;
-
+ break;
+ case po_ctxt:
if (p->stage == ps_parse) {
- if (msg->plural == NULL) {
- return -po_internal;
+ if (msg->ctxt == NULL) {
+ t = -po_internal;
+ goto exit;
}
- len = unescape(x, msg->plural, p->max_plural_len);
+ len = unescape(x, &msg->ctxt[msg->ctxt_len], p->max_ctxt_len);
+ msg->ctxt_len += len;
+ } else if (p->stage == ps_size) {
+ msg->ctxt_len += len;
+ if (p->max_ctxt_len < msg->ctxt_len)
+ p->max_ctxt_len = msg->ctxt_len + 1;
}
+ break;
+ }
- msg->plural_len = len;
- p->previous = po_plural;
- } else if ((y = strstarts(z, "str"))) {
- if (!msg->id_len && !p->first)
- return -po_invalid_entry;
-
- if (isspace(*y)) {
- if (p->strcnt || msg->plural_len)
- return -po_invalid_entry;
+ x = y + 1;
+ break;
+ case 'm':
+ if ((y = strstarts(x, "sgctxt"))) {
+ if ( (t = poparser_clean(p, msg)) != po_success) {
+ goto exit;
+ }
- cnt = (p->strcnt = 1) - 1;
- } else if (*y == '[') {
- if (!msg->plural_len)
- return -po_invalid_entry;
+ if (msg->id_len || msg->plural_len) {
+ t = -po_invalid_entry;
+ goto exit;
+ }
- if (y[2] != ']' || !isspace(y[3])) return -po_excepted_token;
+ msg->ctxt_len = 0;
+ p->current_entry = po_ctxt;
+ } else if ((y = strstarts(x, "sgid_plural"))) {
+ if (!msg->id_len || p->current_strcnt) {
+ t = -po_invalid_entry;
+ goto exit;
+ }
- p->strcnt = (cnt = y[1] - '0') + 1;
+ msg->plural_len = 0;
+ p->current_entry = po_plural;
+ } else if ((y = strstarts(x, "sgid"))) {
+ if ( (t = poparser_clean(p, msg)) != po_success) {
+ goto exit;
+ }
- if (p->strict && p->strcnt > p->hdr.nplurals) {
- return -po_plurals_overflow;
- }
- } else {
- return -po_excepted_token;
+ if (msg->plural_len) {
+ t = -po_invalid_entry;
+ goto exit;
}
- if ((t = poparser_feed_hdr(p, x)) != po_success) {
- return t;
+ msg->id_len = 0;
+ p->current_entry = po_id;
+ } else if ((y = strstarts(x, "sgstr"))) {
+ if (p->current_trans_index != 0 && !msg->id_len) {
+ t = -po_invalid_entry;
+ goto exit;
}
- if (p->stage == ps_parse) {
- if (msg->str[cnt] == NULL) {
- return -po_internal;
+ if (*y == '[') {
+ if (!msg->plural_len) {
+ t = -po_invalid_entry;
+ goto exit;
+ }
+
+ if (y[2] != ']') {
+ t = -po_excepted_token;
+ goto exit;
}
- len = unescape(x, msg->str[cnt], p->max_strlen[cnt]);
+ p->current_strcnt = y[1] - '0' + 1;
+
+ if (p->strict && p->current_strcnt > p->hdr.nplurals) {
+ t = -po_plurals_overflow;
+ goto exit;
+ }
+
+ y += 3; // skip [n]
+ } else {
+ if (p->current_strcnt || msg->plural_len) {
+ t = -po_invalid_entry;
+ goto exit;
+ }
+
+ p->current_strcnt = 1;
}
- msg->strlen[cnt] = len;
- p->previous = po_str;
+ msg->strlen[p->current_strcnt - 1] = 0;
+ p->current_entry = po_str;
} else {
- return -po_invalid_entry;
+ t = -po_invalid_entry;
+ goto exit;
}
+
+ x = y;
+ break;
+ default:
+ t = -po_invalid_entry;
+ goto exit;
}
}
+ }
- if (p->stage == ps_size) {
- if (p->max_strlen[cnt] < msg->strlen[cnt])
- p->max_strlen[cnt] = msg->strlen[cnt] + 1;
- if (p->max_plural_len < msg->plural_len)
- p->max_plural_len = msg->plural_len + 1;
- if (p->max_id_len < msg->id_len)
- p->max_id_len = msg->id_len + 1;
- if (p->max_ctxt_len < msg->ctxt_len)
- p->max_ctxt_len = msg->ctxt_len + 1;
- }
+exit:
+ // if loop done normally, use x
+ if (z == 0) z = x;
+
+ // if goto(in case z!=0), use z
+ if (z != p->buf) {
+ // drop consumed lines
+ len = p->buf + p->bufpos - z;
+ memcpy(p->buf, z, len);
+ p->bufpos = len;
}
- return po_success;
+ return t;
}
enum po_error poparser_finish(struct po_parser *p) {
@@ -373,6 +386,8 @@ enum po_error poparser_finish(struct po_parser *p) {
po_message_t msg = &p->msg;
if (p->stage == ps_size) {
+ if ( (t = poparser_feed(p, "\n", 1)) != po_success)
+ return t;
if ( (t = poparser_clean(p, msg)) != po_success)
return t;
@@ -391,8 +406,12 @@ enum po_error poparser_finish(struct po_parser *p) {
msg->str[cnt] = msg->str[cnt-1] + p->max_strlen[cnt-1];
p->hdr.nplurals = 2;
- p->first = true;
+ p->current_trans_index = 0;
+ p->bufpos = 0;
+ p->iconv_bufpos = 0;
} else {
+ if ( (t = poparser_feed(p, "\n", 1)) != po_success)
+ return t;
if ( (t = poparser_clean(p, msg)) != po_success)
return t;
if (msg->ctxt) free(msg->ctxt);
diff --git a/src/poparser.h b/src/poparser.h
index 3f7db7d..43b1faa 100644
--- a/src/poparser.h
+++ b/src/poparser.h
@@ -67,17 +67,26 @@ struct po_parser {
enum po_stage stage;
// private parts
- bool first;
bool strict;
iconv_t cd;
- enum po_entry previous;
- unsigned strcnt;
+
+ size_t current_trans_index;
+ enum po_entry current_entry;
+ unsigned current_strcnt;
+
size_t max_ctxt_len;
size_t max_id_len;
size_t max_plural_len;
size_t max_strlen[MAX_NPLURALS];
+
char *buf;
size_t bufsize;
+ size_t bufpos;
+
+ char *iconv_buf;
+ size_t iconv_bufpos;
+ size_t iconv_bufsize;
+
poparser_callback cb;
void *cbdata;
};
@@ -93,8 +102,8 @@ enum po_error {
po_error_last = po_internal,
};
-void poparser_init(struct po_parser *p, char* workbuf, size_t bufsize, poparser_callback cb, void* cbdata);
-enum po_error poparser_feed_line(struct po_parser *p, char* line, size_t buflen);
+void poparser_init(struct po_parser *p, poparser_callback cb, void* cbdata);
+enum po_error poparser_feed(struct po_parser *p, char* line, size_t buflen);
enum po_error poparser_finish(struct po_parser *p);
#endif