poe

Уређивач .po фајлова
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

чување 030fe558d1eaa60bcdaacac1f7eda82a23ad425d
родитељ 0f382d2c0b0df6ba7e1465b73ec0529f23a1d046
Аутор: Страхиња Радић <contact@strahinja.org>
Датум:   Thu, 16 Dec 2021 21:09:21 +0100

Continued WIP: Transition to u32_next_line

Signed-off-by: Страхиња Радић <contact@strahinja.org>

Diffstat:
MTODO | 5+++++
Mdraw.c | 33+++++++++++----------------------
Mdraw.h | 3+--
Mpo.c | 11+++++------
Mpoe.c | 89++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mutil.c | 208++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
Mutil.h | 7+++++--
измењених датотека: 7, додавања: 210(+), брисања: 146(-)

diff --git a/TODO b/TODO @@ -2,6 +2,11 @@ ==== [ ] Wrap long msgids/msgstrs when saving + [ ] Transition to u32_next_line + [ ] Fix: When saving a msgstr, \n gets added (check + nlines) + [ ] Convert po.c:save_file to u32_next_line (currently + deletes all strings!) < > Wrap long lines? Not if it would complicate the code too much. diff --git a/draw.c b/draw.c @@ -208,45 +208,34 @@ set_nplurals(struct DrawState* state, struct PoEntry* entry) * wrap - if >0, also wrap lines */ struct BufferLine* -split(const uint32_t* s, const size_t num_lines, const size_t wrap) +split(const uint32_t* s, const size_t wrap) { if (!s) return NULL; - size_t nlines = num_lines; + size_t nlines = 0; struct BufferLine* newbuf = NULL; struct BufferLine* pnewbuf = NULL; const uint32_t* ps = s; - if (!nlines) - nlines = u32_lines_in_string(s, wrap); - + nlines = u32_lines_in_string(s, wrap); newbuf = calloc(nlines, sizeof(struct BufferLine)); if (!newbuf) return NULL; pnewbuf = newbuf; - for (size_t i = 0; i < nlines; i++) + while (*ps) { + uint32_t* newtext = NULL; + size_t len = 0; + init_bufferline(pnewbuf); - uint32_t* newtext = calloc(MAXBUFLINE, sizeof(uint32_t)); + len = u32_next_line(s, &ps, wrap); + newtext = calloc(len, sizeof(uint32_t)); if (!newtext) return NULL; pnewbuf->text = newtext; - size_t len = u32_line_length(ps, NULL, wrap); - if (wrap > 0 && len > wrap) - { - pnewbuf->length = u32_strncpy(pnewbuf->text, ps, - MIN(wrap + 1, MAXBUFLINE)); - ps += wrap; - } - else - { - pnewbuf->length = u32_strncpy(pnewbuf->text, ps, - MIN(len + (wrap > 0 && ps[len] ? 2 : 0) + 1, - MAXBUFLINE)); - ps += len + (ps[len] ? 2 : 0); - } + pnewbuf->length = len; pnewbuf++; } @@ -805,7 +794,7 @@ draw_status(const struct DrawState* state) pseg->callback(buf, MAXBUFLINE, pseg->format, state); else - strncpy(buf, pseg->format, MAXBUFLINE); + strncpy(buf, pseg->format, MAXBUFLINE-1); buf[MAXBUFLINE - 1] = 0; if (pseg == status_segments + LEN(status_segments) - 1) seg_size = state->maxx - 1 - current_start; diff --git a/draw.h b/draw.h @@ -99,8 +99,7 @@ void init_drawstate(struct DrawState* state, char* error, char* filename, char* prompt); void free_drawstate(struct DrawState* state); struct DrawState* set_nplurals(struct DrawState* state, struct PoEntry* entry); -struct BufferLine* split(const uint32_t* s, const size_t num_lines, - const size_t wrap); +struct BufferLine* split(const uint32_t* s, const size_t wrap); size_t display_length(const struct DrawState* state, uint32_t* buffer, const size_t max_index); size_t input_length(const struct DrawState* state, uint32_t* buffer, diff --git a/po.c b/po.c @@ -481,6 +481,7 @@ load_file(struct DrawState* dstate, long* lineno, long* col) return LOAD_ERR_NONE; } +/* TODO: Convert to u32_next_line (currently deletes all strings) */ int save_file(const struct PoEntry* entries, const size_t real_msgid_count, const char* filename, const int nplurals) @@ -597,7 +598,7 @@ save_loop_entries_start: if (num_lines > 1) { struct BufferLine* msgid_split = split(current->msgid, - num_lines, SAVE_WRAP_WIDTH); + SAVE_WRAP_WIDTH); struct BufferLine* pmsgid_split = NULL; if (!msgid_split) @@ -650,8 +651,7 @@ save_loop_entries_start: if (num_lines > 1) { struct BufferLine* msgid_split - = split(current->msgid_plural, num_lines, - SAVE_WRAP_WIDTH); + = split(current->msgid_plural, SAVE_WRAP_WIDTH); struct BufferLine* pmsgid_split = NULL; if (!msgid_split) @@ -708,8 +708,7 @@ save_loop_entries_start: strftime(now, MAXDATEBUF, "%F %H:%M%z", now_tm); struct BufferLine* msgstr_split - = split(*current->msgstr, num_lines, - SAVE_WRAP_WIDTH); + = split(*current->msgstr, SAVE_WRAP_WIDTH); struct BufferLine* pmsgstr_split = NULL; if (!msgstr_split) @@ -779,7 +778,7 @@ save_loop_entries_start: { struct BufferLine* msgstr_split = split(*(current->msgstr + m), - num_lines, SAVE_WRAP_WIDTH); + SAVE_WRAP_WIDTH); struct BufferLine* pmsgstr_split = NULL; if (!msgstr_split) diff --git a/poe.c b/poe.c @@ -260,7 +260,7 @@ load_info(struct DrawState* state) pnewbuf = newbuf; size_t newlen = 0; - uint32_t* pumsgid = NULL; + const uint32_t* pumsgid = NULL; if (current->msgid) { pumsgid = current->msgid; @@ -271,17 +271,18 @@ load_info(struct DrawState* state) pnewbuf->fg = EDIT_MSGID_HEADING_FG; pnewbuf->bg = EDIT_MSGID_HEADING_BG; pnewbuf++; - for (size_t i = 0; i < msgid_num_lines; i++) + while (*pumsgid) { - size_t len = u32_line_length(pumsgid, 0); - newlen = 0; - u32_strncpy(pnewbuf->text, pumsgid, + size_t len = 0; + const uint32_t* old_pumsgid = pumsgid; + + len = u32_next_line(current->msgid, &pumsgid, 0); + u32_strncpy(pnewbuf->text, old_pumsgid, MIN(len + 1, MAXBUFLINE)); newlen = u32_decode_tabs(pnewbuf->text, MAXBUFLINE); pnewbuf->length = newlen; if (newlen > state->info_rows_maxlen) state->info_rows_maxlen = newlen; - pumsgid += len + (pumsgid[len] ? 2 : 0); pnewbuf++; } } @@ -296,17 +297,18 @@ load_info(struct DrawState* state) pnewbuf->bg = EDIT_MSGID_HEADING_BG; pnewbuf++; pumsgid = current->msgid_plural; - for (size_t i = 0; i < msgid_plural_num_lines; i++) + while (*pumsgid) { - size_t len = u32_line_length(pumsgid, 0); - newlen = 0; - u32_strncpy(pnewbuf->text, pumsgid, + size_t len = 0; + const uint32_t* old_pumsgid = pumsgid; + + len = u32_next_line(current->msgid_plural, &pumsgid, 0); + u32_strncpy(pnewbuf->text, old_pumsgid, MIN(len + 1, MAXBUFLINE)); newlen = u32_decode_tabs(pnewbuf->text, MAXBUFLINE); pnewbuf->length = newlen; if (newlen > state->info_rows_maxlen) state->info_rows_maxlen = newlen; - pumsgid += len + (pumsgid[len] ? 2 : 0); pnewbuf++; } if (first->plural_forms) @@ -433,20 +435,21 @@ load_msgstr(struct DrawState* state) if (current->msgstr_count > 0) { - uint32_t* pumsgstr = *(current->msgstr + msgstr_index); + const uint32_t* pumsgstr = *(current->msgstr + msgstr_index); if (pumsgstr) { pnewbuf = newbuf; - for (size_t i = 0; i < num_lines; i++) + while (*pumsgstr) { - size_t len = u32_line_length(pumsgstr, 0); + size_t len = 0; size_t newlen = 0; - u32_strncpy(pnewbuf->text, pumsgstr, + const uint32_t* old_pumsgstr = pumsgstr; + len = u32_next_line(*(current->msgstr + msgstr_index), &pumsgstr, 0); + u32_strncpy(pnewbuf->text, old_pumsgstr, MIN(len + 1, MAXBUFLINE)); newlen = u32_decode_tabs(pnewbuf->text, MAXBUFLINE); pnewbuf->length = newlen; - pumsgstr += len + (pumsgstr[len] ? 2 : 0); pnewbuf++; } } @@ -877,7 +880,7 @@ copy_msgid_to_input(struct DrawState* state) state->input_buffer + state->input_rows_count - i - 1); struct BufferLine* newbuf = realloc(state->input_buffer, msgid_num_lines * sizeof(struct BufferLine)); - uint32_t* pmsgid = current->msgid; + const uint32_t* pmsgid = current->msgid; if (!newbuf) return NULL; @@ -893,18 +896,19 @@ copy_msgid_to_input(struct DrawState* state) pbuffer->text = newtext; } - if (pmsgid) - for (size_t i = 0; i < msgid_num_lines; i++) - { - pbuffer = newbuf + i; - size_t len = u32_line_length(pmsgid, 0); - size_t newlen = 0; - u32_strncpy(pbuffer->text, pmsgid, - MIN(len + 1, MAXBUFLINE)); - newlen = u32_decode_tabs(pbuffer->text, MAXBUFLINE); - pbuffer->length = newlen; - pmsgid += len + (pmsgid[len] ? 2 : 0); - } + pbuffer = newbuf; + while (pmsgid && *pmsgid) + { + size_t len = 0; + size_t newlen = 0; + const uint32_t* old_pmsgid = pmsgid; + len = u32_next_line(current->msgid, &pmsgid, 0); + u32_strncpy(pbuffer->text, old_pmsgid, + MIN(len + 1, MAXBUFLINE)); + newlen = u32_decode_tabs(pbuffer->text, MAXBUFLINE); + pbuffer->length = newlen; + pbuffer++; + } state->input_rows_count = msgid_num_lines; state->input_buffer = newbuf; @@ -930,7 +934,7 @@ yank_msgstr_to_paste_buffer(struct DrawState* state) size_t lines_to_init = 0; size_t lines_to_free = 0; struct BufferLine* newbuf = NULL; - uint32_t* pmsgstr = NULL; + const uint32_t* pmsgstr = NULL; struct BufferLine* pbuffer = NULL; if (!current->msgstr || !*(current->msgstr + state->msgstr_index)) @@ -976,18 +980,19 @@ yank_msgstr_to_paste_buffer(struct DrawState* state) pbuffer->text = newtext; } - if (pmsgstr) - for (size_t i = 0; i < msgstr_num_lines; i++) - { - pbuffer = newbuf + i; - size_t len = u32_line_length(pmsgstr, 0); - size_t newlen = 0; - u32_strncpy(pbuffer->text, pmsgstr, - MIN(len + 1, MAXBUFLINE)); - newlen = u32_decode_tabs(pbuffer->text, MAXBUFLINE); - pbuffer->length = newlen; - pmsgstr += len + (pmsgstr[len] ? 2 : 0); - } + pbuffer = newbuf; + while (*pmsgstr) + { + size_t len = 0; + size_t newlen = 0; + const uint32_t* old_pmsgstr = pmsgstr; + + len = u32_next_line(*(current->msgstr + state->msgstr_index), &pmsgstr, 0); + u32_strncpy(pbuffer->text, old_pmsgstr, MIN(len + 1, MAXBUFLINE)); + newlen = u32_decode_tabs(pbuffer->text, MAXBUFLINE); + pbuffer->length = newlen; + pbuffer++; + } state->paste_rows_count = msgstr_num_lines; state->paste_buffer = newbuf; diff --git a/util.c b/util.c @@ -41,6 +41,9 @@ unicode_string_to_u8(char* s, const uint32_t* us, const size_t max) const uint32_t* pus = us; size_t added = 0; + if (!pus) + return added; + *s = 0; while (*pus) { @@ -215,74 +218,101 @@ u8_u32_strncpy(char* to, const uint32_t* from, size_t max) return strlen(to); } -size_t -u8_line_length(const char* s, const char** sptr, const size_t wrap) -{ - size_t len = 0; - if (!s) - return len; - const char* ps = s; - size_t last_nonblank = 0; - int have_last_nonblank = 0; - if (sptr) - *sptr = ps; - while (*ps) - { - if (wrap > 0 && ps > s + wrap) - return have_last_nonblank ? last_nonblank + 1 : wrap; - if (!u8_is_word_boundary(*ps) && u8_is_word_boundary(*(ps + 1))) - { - last_nonblank = ps - s; - have_last_nonblank = 1; - } - if (*ps == '\\' && *(ps + 1) == 'n') - return len; - ps++; - len++; - if (sptr) - *sptr = ps; - } - return len; -} +/* + *size_t + *u8_line_length(const char* s, const char** sptr, const size_t wrap) + *{ + * size_t len = 0; + * if (!s) + * return len; + * const char* ps = s; + * size_t last_nonblank = 0; + * int have_last_nonblank = 0; + * if (sptr) + * *sptr = ps; + * while (*ps) + * { + * if (wrap > 0 && ps > s + wrap) + * return have_last_nonblank ? last_nonblank + 1 : wrap; + * if (!u8_is_word_boundary(*ps) && u8_is_word_boundary(*(ps + 1))) + * { + * last_nonblank = ps - s; + * have_last_nonblank = 1; + * } + * if (*ps == '\\' && *(ps + 1) == 'n') + * return len; + * ps++; + * len++; + * if (sptr) + * *sptr = ps; + * } + * return len; + *} + */ -size_t -u32_line_length(const uint32_t* s, const uint32_t** sptr, const size_t wrap) -{ - size_t len = 0; - if (!s) - return len; - const uint32_t* ps = s; - size_t last_nonblank = 0; - int have_last_nonblank = 0; - if (sptr) - *sptr = ps; - while (*ps) - { - if (wrap > 0 && ps > s + wrap) - return have_last_nonblank ? last_nonblank : wrap; - if (!u32_is_word_boundary(*ps) && u32_is_word_boundary(*(ps + 1))) - { - last_nonblank = ps - s; - have_last_nonblank = 1; - } - if (*ps == '\\' && *(ps + 1) == 'n') - return len; - ps++; - len++; - if (sptr) - *sptr = ps; - } - return len; -} +/* + *size_t + *u32_line_length(const uint32_t* s, const uint32_t** sptr, const size_t wrap) + *{ + * size_t len = 0; + * if (!s) + * return len; + * const uint32_t* ps = s; + * size_t last_nonblank = 0; + * int have_last_nonblank = 0; + * if (sptr) + * *sptr = ps; + * while (*ps) + * { + * if (wrap > 0 && ps > s + wrap) + * return have_last_nonblank ? last_nonblank : wrap; + * if (!u32_is_word_boundary(*ps) && u32_is_word_boundary(*(ps + 1))) + * { + * last_nonblank = ps - s; + * have_last_nonblank = 1; + * } + * if (*ps == '\\' && *(ps + 1) == 'n') + * return len; + * ps++; + * len++; + * if (sptr) + * *sptr = ps; + * } + * return len; + *} + */ + +/* wrap - if >0, also wrap lines + * */ +/* + *size_t + *u8_lines_in_string(const char* s, const size_t wrap) + *{ + * size_t result = 1; + * const char* ps = NULL; + * size_t len = 0; + * + * if (!s) + * return result; + * + * ps = s; + * while (*ps) + * { + * len = u8_line_length(s, &ps, wrap); + * ps += len; + * result++; + * } + * return result; + *} + */ /* wrap - if >0, also wrap lines * */ size_t -u8_lines_in_string(const char* s, const size_t wrap) +u32_lines_in_string(const uint32_t* s, const size_t wrap) { size_t result = 1; - const char* ps = NULL; - size_t len = 0; + const uint32_t* ps = NULL; if (!s) return result; @@ -290,32 +320,66 @@ u8_lines_in_string(const char* s, const size_t wrap) ps = s; while (*ps) { - len = u8_line_length(s, &ps, wrap); - ps += len; + u32_next_line(s, &ps, wrap); result++; } return result; } -/* wrap - if >0, also wrap lines - * */ +/* + * returns line length + * s - entire string (multiple lines) + * next_line - pointer to the next line; if NULL, only line length is returned + * wrap - wrap lines to this many characters (runes); if 0, don't wrap + */ size_t -u32_lines_in_string(const uint32_t* s, const size_t wrap) +u32_next_line(const uint32_t* s, const uint32_t** next_line, const size_t wrap) { - size_t result = 1; + size_t result = 0; const uint32_t* ps = NULL; - size_t len = 0; - + const uint32_t* start = NULL; + size_t last_nonblank = 0; + int have_last_nonblank = 0; + if (!s) return result; - ps = s; + start = s; + if (next_line) + start = *next_line; + ps = start; while (*ps) { - len = u32_line_length(s, &ps, wrap); - ps += len; + if (wrap > 0 && ps > start + wrap) + { + if (next_line) + { + if (have_last_nonblank) + *next_line = start + last_nonblank; + } + return have_last_nonblank ? have_last_nonblank : wrap; + } + + if (*ps == '\\' && *(ps+1) == 'n') + { + if (next_line) + *next_line = ps + 2; + return result; + } + + if (!u32_is_word_boundary(*ps) && u32_is_word_boundary(*(ps+1))) + { + last_nonblank = ps - start; + have_last_nonblank = 1; + } + + ps++; result++; } + + if (next_line) + *next_line = ps; + return result; } diff --git a/util.h b/util.h @@ -39,10 +39,13 @@ size_t u32_strncpy(uint32_t* to, const uint32_t* from, size_t max); size_t u32_strncat(uint32_t* to, const uint32_t* from, size_t max); size_t u32_u8_strncpy(uint32_t* to, const char* from, size_t max); size_t u8_u32_strncpy(char* to, const uint32_t* from, size_t max); -size_t u8_line_length(const char* s, const char** sptr, const size_t wrap); -size_t u32_line_length(const uint32_t* s, const uint32_t** sptr, const size_t wrap); +/* + *size_t u8_line_length(const char* s, const char** sptr, const size_t wrap); + *size_t u32_line_length(const uint32_t* s, const uint32_t** sptr, const size_t wrap); + */ size_t u8_lines_in_string(const char* s, const size_t wrap); size_t u32_lines_in_string(const uint32_t* s, const size_t wrap); +size_t u32_next_line(const uint32_t* s, const uint32_t** sptr, const size_t wrap); int u8_is_word_boundary(const uint8_t ch); int u32_is_word_boundary(const uint32_t ch); int starts_with(const char* s, const char* with);