чување 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:
| M | TODO | | | 5 | +++++ |
| M | draw.c | | | 33 | +++++++++++---------------------- |
| M | draw.h | | | 3 | +-- |
| M | po.c | | | 11 | +++++------ |
| M | poe.c | | | 89 | ++++++++++++++++++++++++++++++++++++++++++------------------------------------- |
| M | util.c | | | 208 | ++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------- |
| M | util.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);