poe

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

чување 6604a5ec32d9102ed35338a8949c0205cb0ebf8a
родитељ 9b1a6e6257b870bbd453efb56a2095f009e94e20
Аутор: Страхиња Радић <contact@strahinja.org>
Датум:   Sat, 25 Dec 2021 16:04:43 +0100

Finish conversion of po.c:save_file to u32_next_line

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

Diffstat:
M.gitignore | 2++
Mconfig.def.h | 4++++
Mconfig.h | 4++++
Mdraw.c | 45+++------------------------------------------
Mdraw.h | 3+--
Mpo.c | 182+++++++-------------------------------------------------------------------------
Mpoe.c | 97+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Mutil.c | 152+++++++++++++++++--------------------------------------------------------------
Mutil.h | 14++++----------
Awrap_next_line_logic | 23+++++++++++++++++++++++
измењених датотека: 10, додавања: 137(+), брисања: 389(-)

diff --git a/.gitignore b/.gitignore @@ -1,5 +1,6 @@ .cache .redo +.gdbinit *.session .do_built .do_built.dir @@ -11,6 +12,7 @@ *.swp *.did nohup.out +*.err *.gz *.xz *.pdf diff --git a/config.def.h b/config.def.h @@ -1,4 +1,8 @@ /* See the file LICENSE for copyright and license details. */ + +#define SAVE_WRAP_WIDTH 70 +#define WRAP_FIRST_MSGSTR 0 + #define DLG_FG TB_BLACK #define DLG_BG TB_WHITE #define EDIT_MSGID_FG TB_BLACK | TB_BOLD diff --git a/config.h b/config.h @@ -1,4 +1,8 @@ /* See the file LICENSE for copyright and license details. */ + +#define SAVE_WRAP_WIDTH 70 +#define WRAP_FIRST_MSGSTR 0 + #define DLG_FG TB_BLACK #define DLG_BG TB_WHITE #define EDIT_MSGID_FG TB_BLACK | TB_BOLD diff --git a/draw.c b/draw.c @@ -203,45 +203,6 @@ set_nplurals(struct DrawState* state, struct PoEntry* entry) return state; } -/* - * num_lines - number of lines when split; set to 0 to automatically calculate - * wrap - if >0, also wrap lines - */ -struct BufferLine* -split(const uint32_t* s, const size_t wrap) -{ - if (!s) - return NULL; - - size_t nlines = 0; - struct BufferLine* newbuf = NULL; - struct BufferLine* pnewbuf = NULL; - const uint32_t* ps = s; - - nlines = u32_lines_in_string(s, wrap); - newbuf = calloc(nlines, sizeof(struct BufferLine)); - if (!newbuf) - return NULL; - - pnewbuf = newbuf; - while (*ps) - { - uint32_t* newtext = NULL; - size_t len = 0; - - init_bufferline(pnewbuf); - len = u32_next_line(s, &ps, wrap); - newtext = calloc(len, sizeof(uint32_t)); - if (!newtext) - return NULL; - pnewbuf->text = newtext; - pnewbuf->length = len; - pnewbuf++; - } - - return newbuf; -} - /* Calculates display length of an input buffer line. * max_index = the input index up to which the length is calculated */ @@ -667,7 +628,7 @@ draw_editbox(const struct DrawState* state) u32_draw_string(startx + 1, starty + 1 + i, curline->fg == 0 ? fg : curline->fg, curline->bg == 0 ? bg : curline->bg, - curline->text, w - 1, w - 1, 1, 1, LEFT, + curline->text, w - 2, w - 2, 1, 1, LEFT, state->info_first_shown_column, 1, NULL, 0, 0); } @@ -695,7 +656,7 @@ draw_editbox(const struct DrawState* state) dlen = display_length(state, curline->text, curline->length); if (dlen > state->input_first_shown_column) u32_draw_string(startx + 1, endy - h / 2 - 1 + i, fg, - bg, curline->text, w - 1, w - 1, 1, 1, LEFT, + bg, curline->text, w - 2, w - 2, 1, 1, LEFT, state->input_first_shown_column, 1, NULL, 0, 0); } @@ -794,7 +755,7 @@ draw_status(const struct DrawState* state) pseg->callback(buf, MAXBUFLINE, pseg->format, state); else - strncpy(buf, pseg->format, MAXBUFLINE-1); + 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 @@ -91,7 +91,7 @@ struct StatusSegment { Alignment alignment; }; -extern struct PoEntry entries[]; +extern struct PoEntry* entries; void init_bufferline(struct BufferLine* bl); void free_bufferline(struct BufferLine* bl); @@ -99,7 +99,6 @@ 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 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 @@ -6,6 +6,7 @@ #include "po.h" #include "draw.h" +#include "config.h" #include "util.h" #include "version.h" @@ -592,8 +593,8 @@ save_loop_entries_start: if (current->msgid) { size_t msgid_size = current->msgid_size * UTF8REPMAX; - size_t num_lines - = u32_lines_in_string(current->msgid, SAVE_WRAP_WIDTH); + size_t num_lines = u32_lines_in_string(current->msgid, 1, + SAVE_WRAP_WIDTH); if (num_lines > 1) { const uint32_t* pumsgid = current->msgid; @@ -606,7 +607,7 @@ save_loop_entries_start: char* u8_msgid = NULL; const uint32_t* old_pumsgid = pumsgid; - len = u32_next_line(current->msgid, &pumsgid, + len = u32_next_line(current->msgid, &pumsgid, 1, SAVE_WRAP_WIDTH); if (len == 0) continue; @@ -619,38 +620,6 @@ save_loop_entries_start: fprintf(output, "\"%s\"\n", u8_msgid); free(u8_msgid); } - - /* - * struct BufferLine* msgid_split - * = split(current->msgid, SAVE_WRAP_WIDTH); struct - * BufferLine* pmsgid_split = NULL; - * - * if (!msgid_split) - * return - * SAVE_ERR_CANT_ALLOC; - * - * fprintf(output, "msgid - * \"\"\n"); for (size_t i = 0; i < num_lines; i++) - * { - * pmsgid_split = - * msgid_split + i; int last = i == num_lines - 1; - * char* u8_msgid = - * calloc(current->msgid_size, UTF8REPMAX); if - * (!u8_msgid) return SAVE_ERR_CANT_ALLOC; size_t len = - * u32_strlen(pmsgid_split->text); - * unicode_string_to_u8(u8_msgid, - * pmsgid_split->text, - * msgid_size); if (!(last && len == 0)) fprintf(output, - * "\"%s\"\n", u8_msgid); free(u8_msgid); - * } - * for (size_t i = 0; i < - * num_lines; i++) - * { - * pmsgid_split = - * msgid_split + i; free_bufferline(pmsgid_split); - * } - * free(msgid_split); - */ } else { @@ -671,7 +640,7 @@ save_loop_entries_start: { size_t msgid_plural_size = current->msgid_plural_size * UTF8REPMAX; - size_t num_lines = u32_lines_in_string(current->msgid_plural, + size_t num_lines = u32_lines_in_string(current->msgid_plural, 1, SAVE_WRAP_WIDTH); if (num_lines > 1) { @@ -686,7 +655,7 @@ save_loop_entries_start: const uint32_t* old_pumsgid = pumsgid; len = u32_next_line(current->msgid_plural, - &pumsgid, SAVE_WRAP_WIDTH); + &pumsgid, 1, SAVE_WRAP_WIDTH); if (len == 0) continue; @@ -698,41 +667,6 @@ save_loop_entries_start: fprintf(output, "\"%s\"\n", u8_msgid); free(u8_msgid); } - - /* - * struct BufferLine* msgid_split - * = - * split(current->msgid_plural, SAVE_WRAP_WIDTH); struct - * BufferLine* pmsgid_split = NULL; - * - * if (!msgid_split) - * return - * SAVE_ERR_CANT_ALLOC; - * - * fprintf(output, "msgid_plural - * \"\"\n"); for (size_t i = 0; i < num_lines; i++) - * { - * pmsgid_split = - * msgid_split + i; int last = i == num_lines - 1; - * char* u8_msgid - * = - * calloc(current->msgid_plural_size, UTF8REPMAX); if - * (!u8_msgid) return SAVE_ERR_CANT_ALLOC; size_t len = - * u32_strlen(pmsgid_split->text); - * unicode_string_to_u8(u8_msgid, - * pmsgid_split->text, - * msgid_plural_size); if (!(last && len == 0)) - * fprintf(output, - * "\"%s\"\n", u8_msgid); free(u8_msgid); - * } - * for (size_t i = 0; i < - * num_lines; i++) - * { - * pmsgid_split = - * msgid_split + i; free_bufferline(pmsgid_split); - * } - * free(msgid_split); - */ } else { @@ -749,7 +683,7 @@ save_loop_entries_start: if (current->msgstr_count == 1) { - size_t num_lines = u32_lines_in_string(*current->msgstr, + size_t num_lines = u32_lines_in_string(*current->msgstr, 1, SAVE_WRAP_WIDTH); if (num_lines > 1) { @@ -771,7 +705,11 @@ save_loop_entries_start: const uint32_t* old_pumsgstr = pumsgstr; len = u32_next_line(*current->msgstr, &pumsgstr, - SAVE_WRAP_WIDTH); + 1, + ((first_entry && WRAP_FIRST_MSGSTR) + || !first_entry) + ? SAVE_WRAP_WIDTH + : 0); if (len == 0) continue; @@ -806,61 +744,6 @@ save_loop_entries_start: if (first_entry && !seen_generator) fprintf(output, "\"X-Generator: poe %s\"\n", VERSION); - - /* - * struct BufferLine* - * msgstr_split = split(*current->msgstr, - * SAVE_WRAP_WIDTH); struct BufferLine* pmsgstr_split = - * NULL; - * - * if (!msgstr_split) - * return - * SAVE_ERR_CANT_ALLOC; - * - * fprintf(output, "msgstr - * \"\"\n"); for (size_t i = 0; i < num_lines; i++) - * { - * pmsgstr_split = - * msgstr_split + i; int last = i == num_lines - 1; - * char - * u8_msgstr[MAXMSGLINE * UTF8REPMAX]; size_t len = - * u32_strlen(pmsgstr_split->text); - * unicode_string_to_u8(u8_msgstr, - * pmsgstr_split->text, - * MAXMSGLINE * - * UTF8REPMAX); - * - * if (first_entry - * && - * starts_with(u8_msgstr, "PO-Revision-Date: ")) - * fprintf(output, - * "\"PO-Revision-Date:" - * " - * %s\\n\"\n", now); else if (first_entry - * && - * starts_with(u8_msgstr, "X-Generator: ")) - * { - * seen_generator - * = 1; fprintf(output, - * "\"X-Generator:" - * " poe - * %s" - * "\\n\"\n", - * VERSION); - * } - * else if (!(last && len - * == 0)) fprintf(output, "\"%s\"\n", u8_msgstr); - * } - * if (first_entry && - * !seen_generator) fprintf(output, "\"X-Generator: poe - * %s\"\n", VERSION); for (size_t i = 0; i < num_lines; - * i++) - * { - * pmsgstr_split = - * msgstr_split + i; free_bufferline(pmsgstr_split); - * } - * free(msgstr_split); - */ } else if (current->msgid_plural && (!*current->msgstr || !**current->msgstr)) @@ -879,7 +762,7 @@ save_loop_entries_start: for (size_t m = 0; m < current->msgstr_count; m++) { size_t num_lines = u32_lines_in_string(*current->msgstr, - SAVE_WRAP_WIDTH); + 1, SAVE_WRAP_WIDTH); if (num_lines > 1) { const uint32_t* pumsgstr @@ -895,7 +778,7 @@ save_loop_entries_start: len = u32_next_line(*(current->msgstr + m), - &pumsgstr, SAVE_WRAP_WIDTH); + &pumsgstr, 1, SAVE_WRAP_WIDTH); if (len == 0) continue; @@ -908,43 +791,6 @@ save_loop_entries_start: fprintf(output, "\"%s\"\n", u8_msgstr); free(u8_msgstr); } - - /* - * struct BufferLine* - * msgstr_split = split(*(current->msgstr + m), - * SAVE_WRAP_WIDTH); - * struct BufferLine* - * pmsgstr_split = NULL; - * - * if (!msgstr_split) - * return - * SAVE_ERR_CANT_ALLOC; - * - * fprintf(output, - * "msgstr[%ld] \"\"\n", m); for (size_t i = 0; - * i < num_lines; i++) - * { - * pmsgstr_split - * = msgstr_split + i; int last = i == num_lines - * - 1; char u8_msgstr[MAXMSGLINE * UTF8REPMAX]; - * size_t - * len = u32_strlen( pmsgstr_split->text); - * unicode_string_to_u8(u8_msgstr, - * pmsgstr_split->text, - * MAXMSGLINE - * * UTF8REPMAX); if (!(last && len == 0)) - * fprintf(output, - * "\"%s\"\n", u8_msgstr); - * } - * for (size_t i - * = 0; i < num_lines; i++) - * { - * pmsgstr_split - * = msgstr_split + i; - * free_bufferline(pmsgstr_split); - * } - * free(msgstr_split); - */ } else { diff --git a/poe.c b/poe.c @@ -214,9 +214,9 @@ load_info(struct DrawState* state) { struct PoEntry* first = &state->entries[0]; struct PoEntry* current = &state->entries[state->msgid_number - 1]; - size_t msgid_num_lines = u32_lines_in_string(current->msgid, 0); + size_t msgid_num_lines = u32_lines_in_string(current->msgid, 0, 0); size_t msgid_plural_num_lines - = u32_lines_in_string(current->msgid_plural, 0); + = u32_lines_in_string(current->msgid_plural, 0, 0); size_t num_lines = 0; struct BufferLine* newbuf = NULL; struct BufferLine* pnewbuf = NULL; @@ -258,8 +258,8 @@ load_info(struct DrawState* state) state->info_rows_count = num_lines; - pnewbuf = newbuf; - size_t newlen = 0; + pnewbuf = newbuf; + size_t newlen = 0; const uint32_t* pumsgid = NULL; if (current->msgid) { @@ -273,10 +273,10 @@ load_info(struct DrawState* state) pnewbuf++; while (*pumsgid) { - size_t len = 0; + size_t len = 0; const uint32_t* old_pumsgid = pumsgid; - len = u32_next_line(current->msgid, &pumsgid, 0); + len = u32_next_line(current->msgid, &pumsgid, 0, 0); u32_strncpy(pnewbuf->text, old_pumsgid, MIN(len + 1, MAXBUFLINE)); newlen = u32_decode_tabs(pnewbuf->text, MAXBUFLINE); @@ -299,10 +299,11 @@ load_info(struct DrawState* state) pumsgid = current->msgid_plural; while (*pumsgid) { - size_t len = 0; + size_t len = 0; const uint32_t* old_pumsgid = pumsgid; - len = u32_next_line(current->msgid_plural, &pumsgid, 0); + len = u32_next_line(current->msgid_plural, &pumsgid, 0, + 0); u32_strncpy(pnewbuf->text, old_pumsgid, MIN(len + 1, MAXBUFLINE)); newlen = u32_decode_tabs(pnewbuf->text, MAXBUFLINE); @@ -407,8 +408,7 @@ load_msgstr(struct DrawState* state) struct PoEntry* current = &state->entries[state->msgid_number - 1]; size_t num_lines = current->msgstr_count == 0 ? 1 - : u32_lines_in_string( - *(current->msgstr + msgstr_index), 0); + : u32_lines_in_string(*(current->msgstr + msgstr_index), 0, 0); struct BufferLine* newbuf = NULL; struct BufferLine* pnewbuf = NULL; @@ -441,10 +441,12 @@ load_msgstr(struct DrawState* state) pnewbuf = newbuf; while (*pumsgstr) { - size_t len = 0; - size_t newlen = 0; + size_t len = 0; + size_t newlen = 0; const uint32_t* old_pumsgstr = pumsgstr; - len = u32_next_line(*(current->msgstr + msgstr_index), &pumsgstr, 0); + len = u32_next_line(*(current->msgstr + + msgstr_index), + &pumsgstr, 0, 0); u32_strncpy(pnewbuf->text, old_pumsgstr, MIN(len + 1, MAXBUFLINE)); newlen = u32_decode_tabs(pnewbuf->text, @@ -757,12 +759,12 @@ move_search_prev_word(struct DrawState* state) int i = state->search_column; uint32_t* pline = state->search; - if (i > 0 && u32_is_word_boundary(pline[i - 1])) + if (i > 0 && u32_is_word_boundary(pline[i - 1], 0)) i--; - while (i > 0 && u32_is_word_boundary(pline[i])) + while (i > 0 && u32_is_word_boundary(pline[i], 0)) i--; - while (i > 0 && !u32_is_word_boundary(pline[i]) - && !u32_is_word_boundary(pline[i - 1])) + while (i > 0 && !u32_is_word_boundary(pline[i], 0) + && !u32_is_word_boundary(pline[i - 1], 0)) i--; state->search_column = i; @@ -788,9 +790,9 @@ move_search_next_word(struct DrawState* state) uint32_t* pline = state->search; size_t len = u32_strlen(state->search); - while (i < len && !u32_is_word_boundary(pline[i])) + while (i < len && !u32_is_word_boundary(pline[i], 0)) i++; - while (i < len && u32_is_word_boundary(pline[i])) + while (i < len && u32_is_word_boundary(pline[i], 0)) i++; state->search_column = i; state->search_display_column @@ -814,12 +816,12 @@ erase_search_prev_word(struct DrawState* state) uint32_t* pline = state->search; - if (i > 0 && u32_is_word_boundary(pline[i - 1])) + if (i > 0 && u32_is_word_boundary(pline[i - 1], 0)) i--; - while (i > 0 && u32_is_word_boundary(pline[i])) + while (i > 0 && u32_is_word_boundary(pline[i], 0)) i--; - while (i > 0 && !u32_is_word_boundary(pline[i]) - && !u32_is_word_boundary(pline[i - 1])) + while (i > 0 && !u32_is_word_boundary(pline[i], 0) + && !u32_is_word_boundary(pline[i - 1], 0)) i--; int d = state->search_column - i; @@ -868,7 +870,7 @@ copy_msgid_to_input(struct DrawState* state) } struct PoEntry* current = &state->entries[state->msgid_number - 1]; - size_t msgid_num_lines = u32_lines_in_string(current->msgid, 0); + size_t msgid_num_lines = u32_lines_in_string(current->msgid, 0, 0); size_t lines_to_init = state->input_rows_count < msgid_num_lines ? msgid_num_lines - state->input_rows_count : 0; @@ -899,13 +901,12 @@ copy_msgid_to_input(struct DrawState* state) pbuffer = newbuf; while (pmsgid && *pmsgid) { - size_t len = 0; - size_t newlen = 0; + 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); + len = u32_next_line(current->msgid, &pmsgid, 0, 0); + u32_strncpy(pbuffer->text, old_pmsgid, MIN(len + 1, MAXBUFLINE)); + newlen = u32_decode_tabs(pbuffer->text, MAXBUFLINE); pbuffer->length = newlen; pbuffer++; } @@ -949,7 +950,7 @@ yank_msgstr_to_paste_buffer(struct DrawState* state) msgstr_num_lines = u32_lines_in_string(*(current->msgstr + state->msgstr_index), - 0); + 0, 0); lines_to_init = state->paste_rows_count < msgstr_num_lines ? msgstr_num_lines - state->paste_rows_count : 0; @@ -983,13 +984,15 @@ yank_msgstr_to_paste_buffer(struct DrawState* state) pbuffer = newbuf; while (*pmsgstr) { - size_t len = 0; - size_t newlen = 0; + 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); + len = u32_next_line(*(current->msgstr + state->msgstr_index), + &pmsgstr, 0, 0); + u32_strncpy(pbuffer->text, old_pmsgstr, + MIN(len + 1, MAXBUFLINE)); + newlen = u32_decode_tabs(pbuffer->text, MAXBUFLINE); pbuffer->length = newlen; pbuffer++; } @@ -1448,12 +1451,12 @@ move_prev_word(struct DrawState* state) int i = state->input_column; uint32_t* pline = state->input_buffer[state->input_row].text; - if (i > 0 && u32_is_word_boundary(pline[i - 1])) + if (i > 0 && u32_is_word_boundary(pline[i - 1], 0)) i--; - while (i > 0 && u32_is_word_boundary(pline[i])) + while (i > 0 && u32_is_word_boundary(pline[i], 0)) i--; - while (i > 0 && !u32_is_word_boundary(pline[i]) - && !u32_is_word_boundary(pline[i - 1])) + while (i > 0 && !u32_is_word_boundary(pline[i], 0) + && !u32_is_word_boundary(pline[i - 1], 0)) i--; state->input_column = i; @@ -1477,9 +1480,9 @@ move_next_word(struct DrawState* state) uint32_t* pline = state->input_buffer[state->input_row].text; size_t len = state->input_buffer[state->input_row].length; - while (i < len && !u32_is_word_boundary(pline[i])) + while (i < len && !u32_is_word_boundary(pline[i], 0)) i++; - while (i < len && u32_is_word_boundary(pline[i])) + while (i < len && u32_is_word_boundary(pline[i], 0)) i++; state->input_column = i; state->input_display_column = display_length(state, @@ -1505,12 +1508,12 @@ erase_prev_word(struct DrawState* state) uint32_t* pline = state->input_buffer[state->input_row].text; - if (i > 0 && u32_is_word_boundary(pline[i - 1])) + if (i > 0 && u32_is_word_boundary(pline[i - 1], 0)) i--; - while (i > 0 && u32_is_word_boundary(pline[i])) + while (i > 0 && u32_is_word_boundary(pline[i], 0)) i--; - while (i > 0 && !u32_is_word_boundary(pline[i]) - && !u32_is_word_boundary(pline[i - 1])) + while (i > 0 && !u32_is_word_boundary(pline[i], 0) + && !u32_is_word_boundary(pline[i - 1], 0)) i--; int d = state->input_column - i; @@ -2235,7 +2238,7 @@ main(int argc, char** argv) state.first_shown_msgid = state.msgid_number; tb_init(); - error[0] = 0; + error[0] = 0; state.maxx = 0; while (state.running) diff --git a/util.c b/util.c @@ -48,10 +48,10 @@ unicode_string_to_u8(char* s, const uint32_t* us, const size_t max) while (*pus) { int len = tb_utf8_unicode_to_char(ch, *pus); - ch[len] = 0; - if (added + len + 1 > max) + if (added + 1 > max) break; - strncat(s, ch, 8); + strncat(s, ch, len); + added++; pus++; } return added; @@ -218,100 +218,12 @@ 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 - *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 -u32_lines_in_string(const uint32_t* s, const size_t wrap) +u32_lines_in_string(const uint32_t* s, const int include_eol, const size_t wrap) { - size_t result = 1; + size_t result = 1; const uint32_t* ps = NULL; if (!s) @@ -320,7 +232,7 @@ u32_lines_in_string(const uint32_t* s, const size_t wrap) ps = s; while (*ps) { - u32_next_line(s, &ps, wrap); + u32_next_line(s, &ps, include_eol, wrap); if (*ps) result++; } @@ -334,14 +246,15 @@ u32_lines_in_string(const uint32_t* s, const size_t wrap) * wrap - wrap lines to this many characters (runes); if 0, don't wrap */ size_t -u32_next_line(const uint32_t* s, const uint32_t** next_line, const size_t wrap) +u32_next_line(const uint32_t* s, const uint32_t** next_line, + const int include_eol, const size_t wrap) { - size_t result = 0; - const uint32_t* ps = NULL; - const uint32_t* start = NULL; - size_t last_nonblank = 0; + size_t result = 0; + const uint32_t* ps = NULL; + const uint32_t* start = NULL; + size_t last_nonblank = 0; int have_last_nonblank = 0; - + if (!s) return result; @@ -351,26 +264,29 @@ u32_next_line(const uint32_t* s, const uint32_t** next_line, const size_t wrap) ps = start; while (*ps) { - if (wrap > 0 && ps > start + wrap) + if (wrap > 0 && result > wrap) { + size_t cutoff = wrap; + + if (have_last_nonblank) + cutoff = last_nonblank + 1; if (next_line) - { - if (have_last_nonblank) - *next_line = start + last_nonblank; - } - return have_last_nonblank ? have_last_nonblank : wrap; + *next_line = start + cutoff; + + return cutoff; } - if (*ps == '\\' && *(ps+1) == 'n') + if (*ps == '\\' && *(ps + 1) == 'n') { if (next_line) *next_line = ps + 2; - return result; + return result + (include_eol ? 2 : 0); } - - if (!u32_is_word_boundary(*ps) && u32_is_word_boundary(*(ps+1))) + + if (!u32_is_word_boundary(*ps, 1) + && u32_is_word_boundary(*(ps + 1), 1)) { - last_nonblank = ps - start; + last_nonblank = ps - start; have_last_nonblank = 1; } @@ -381,19 +297,15 @@ u32_next_line(const uint32_t* s, const uint32_t** next_line, const size_t wrap) if (next_line) *next_line = ps; - return result; -} - -int -u8_is_word_boundary(const uint8_t ch) -{ - return u32_strchr((uint32_t*)L" \t()[]{},.;:/\\", ch) != NULL; + return result + 1; } int -u32_is_word_boundary(const uint32_t ch) +u32_is_word_boundary(const uint32_t ch, const int strictly_whitespace) { - return u32_strchr((uint32_t*)L" \t()[]{},.;:/\\", ch) != NULL; + return strictly_whitespace + ? u32_strchr((uint32_t*)L" \v\t", ch) != NULL + : u32_strchr((uint32_t*)L" \v\t()[]{},.;:/\\", ch) != NULL; } int diff --git a/util.h b/util.h @@ -24,7 +24,6 @@ enum { #define MAXMSGLINE 1024 #define MSGDELTA 1024 #define MAXPATH 1024 -#define SAVE_WRAP_WIDTH 70 /* maximum chars for UTF-8 representations of Unicode chars, per Unicode char */ #define UTF8REPMAX 6 @@ -39,15 +38,10 @@ 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_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); +size_t u32_lines_in_string(const uint32_t* s, const int include_eol, const size_t wrap); +size_t u32_next_line(const uint32_t* s, const uint32_t** sptr, + const int include_eol, const size_t wrap); +int u32_is_word_boundary(const uint32_t ch, const int strictly_whitespace); int starts_with(const char* s, const char* with); int u32_starts_with(const uint32_t* s, const uint32_t* with); const char* u8_basename(const char* path); diff --git a/wrap_next_line_logic b/wrap_next_line_logic @@ -0,0 +1,23 @@ + + 01234567890123456789012345678901234567 + | wrap = 13 + "Quickbrown fox|umps overthesleepy dog." + ^ ^^ | + | || ps = 14 > start + (wrap = 13) + | |`------ start + last_nonblank + 1 = 10 + | last_nonblank = 9 + start + + | wrap = 28 + "Quickbrown foxjumps overthesl|epy dog." + ^ ^ ^ | + | | | ps = 29 > start + (wrap = 28) + | | new last_nonblank = 18 + | last_nonblank = 9 + start + + + + + +