poe

Уређивач .po фајлова
git clone https://git.sr.ht/~strahinja/poe
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

чување 2c28fc7b8a12be6dee7ed5ae1a0b757ea9187095
родитељ dae42a22a79331911b6a9208f824814e73ec4fac
Аутор: Страхиња Радић <sr@strahinja.org>
Датум:   Thu, 12 Feb 2026 11:08:10 +0100

Add C_ACTION, redraw_status; (mostly) tidy up load_file

Diffstat:
Mconfig.def.h | 1+
Mdraw.c | 8++++++++
Mdraw.h | 1+
Mpo.c | 70+++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Mpoe.c | 13+++++++++++++
Mpoe.h | 1+
измењених датотека: 6, додавања: 71(+), брисања: 23(-)

diff --git a/config.def.h b/config.def.h @@ -4,6 +4,7 @@ /* clang-format off */ static const struct Color colors[] = { + [C_ACTION] = { .fg = TB_BLACK, .bg = TB_WHITE }, [C_CLEAR] = { .fg = TB_DEFAULT, .bg = TB_DEFAULT }, [C_DLG] = { .fg = TB_BLACK, .bg = TB_WHITE }, [C_EDIT_MSGID] = { .fg = TB_BLACK | TB_BOLD, diff --git a/draw.c b/draw.c @@ -495,6 +495,14 @@ draw_status(const struct DrawState* state) NULL, 0, 0)) return 1; } + else if (state->action) + { + if (draw_string(0, state->maxy - 1, colors[C_ACTION].fg, + colors[C_ACTION].bg, actions[state->action], + strlen(actions[state->action]) + 2, maxx, 1, 1, + CENTER, 0, 1, NULL, 0, 0)) + return 1; + } else if (state->error) { if (draw_string(0, state->maxy - 1, colors[C_ERROR].fg, diff --git a/draw.h b/draw.h @@ -31,6 +31,7 @@ typedef enum { LEFT, CENTER, RIGHT } Alignment; typedef enum { + C_ACTION, C_CLEAR, C_DLG, C_EDIT_MSGID, diff --git a/po.c b/po.c @@ -23,6 +23,7 @@ extern const char* flag_strings[]; // TODO: Check ifdef PLURAL_ ... extern int print_error(const int code, const char* msg, ...); +extern void redraw_status(struct DrawState* state); char* format_flags(char* buffer, const size_t max, const struct PoEntry* entry, @@ -424,18 +425,23 @@ load_file(struct DrawState* dstate, long* lineno, long* col) struct PoEntry* entry = NULL; struct PoEntry* current = NULL; FILE* input = NULL; - char input_line[MAXBUFLINE]; + char* input_line = NULL; ParseState pstate = PS_NONE; int has_plural_msgid = 0; + ssize_t input_size = limits[L_LINE_MAX]; ssize_t non_obsolete_sofar = 0; /* lines to tolerate the lack of msgid */ int msgid_counter = PO_DETECTION_LINES; int msgstr_index = -1; + assert(dstate != NULL); + input_line = malloc(input_size); + if (!input_line) + goto load_file_alloc_error; dstate->msgid_size = 0; newchunk = calloc(ALLOC_DELTA, sizeof(struct PoEntry)); if (!newchunk) - return LOAD_ERR_CANT_ALLOC; + goto load_file_alloc_error; dstate->msgid_count = 0; dstate->msgid_size = ALLOC_DELTA; @@ -444,47 +450,51 @@ load_file(struct DrawState* dstate, long* lineno, long* col) dstate->untranslated_count++; if (!(input = fopen(dstate->filename, "rt"))) - return LOAD_ERR_CANT_OPEN_FILE; + return 1; + + dstate->action = ACT_READING; + redraw_status(dstate); + while (!feof(input)) { - if (!fgets(input_line, MAXBUFLINE, input)) + char* eol = NULL; + int result; + + if (!fgets(input_line, input_size, input)) continue; - char* eol = strchr(input_line, '\n'); + eol = strchr(input_line, '\n'); if (eol) *eol = 0; - int result; result = parse_po_line(input_line, dstate, &entry, &pstate, col, &msgstr_index); if (entry && entry->msgid_plural) has_plural_msgid = 1; - if (result == PARSE_ERR_NONE) + switch(result) { + case PARSE_ERR_NONE: if (pstate & PS_MSGID) msgid_counter = -1; else if (msgid_counter != -1) msgid_counter--; if (msgid_counter == 0) - return LOAD_ERR_NOT_PO_FILE; - } - else if (result == PARSE_ERR_SYNTAX) - { + { + dstate->error = ERR_NOTPO_FILE; + return 1; + } + break; + case PARSE_ERR_SYNTAX: dstate->error = ERR_SYNTAX; - // TODO: Handle this properly - } - else - { - free(dstate->entries); - dstate->entries = NULL; - return LOAD_PARSE_ERR(result); + return 1; + default: + goto load_file_alloc_error; } (*lineno)++; } - fclose(input); /* when the .po file is not a standard text file (no LF at end) */ if (dstate->msgid_count > 1) @@ -499,12 +509,18 @@ load_file(struct DrawState* dstate, long* lineno, long* col) entry->obsolete = 1; } if (has_plural_msgid && !dstate->entries->plural_forms) + { dstate->error = ERR_NO_PLURAL_FORMS; + goto load_file_cleanup; + } } /* file has < PO_DETECTION_LINES */ if (msgid_counter > 0) - return LOAD_ERR_NOT_PO_FILE; + { + dstate->error = ERR_NOTPO_FILE; + goto load_file_cleanup; + } dstate->first_shown_msgid = dstate->msgid_count > 0 ? 1 : 0; update_statistics(dstate->entries, dstate, entry); @@ -525,7 +541,14 @@ load_file(struct DrawState* dstate, long* lineno, long* col) current++; } - return LOAD_ERR_NONE; +load_file_cleanup: + fclose(input); + dstate->action = ACT_IDLE; + free(input_line); + return dstate->error != ERR_NONE; + +load_file_alloc_error: + return 1; } int @@ -1058,8 +1081,9 @@ parse_po_line(const char* line, struct DrawState* dstate, *token = 0; char* ptoken = token; - if (!line) - return PARSE_ERR_INVAL; + assert(line != NULL); + /*if (!line) + return PARSE_ERR_INVAL;*/ if (starts_with(line, "msgid ")) { diff --git a/poe.c b/poe.c @@ -845,6 +845,19 @@ quit_callback(struct DrawState* state, struct tb_event* ev) return 0; } +void +redraw_status(struct DrawState* state) +{ + assert(state != NULL); + if (state->recalculate_size) + { + recalculate_size(state); + state->recalculate_size = 0; + } + (void)draw_status(state); + tb_present(); +} + static int cancel_close(struct DrawState* state) { diff --git a/poe.h b/poe.h @@ -70,6 +70,7 @@ static size_t prev_msgid(struct DrawState* state, const int delta); static int prev_plural(struct DrawState* state); int print_error(const int code, const char* msg, ...); static int quit_callback(struct DrawState* state, struct tb_event* ev); +void redraw_status(struct DrawState* state); static int save_msgstr(struct DrawState* state); static int show_edit(struct DrawState* state); static int show_help(struct DrawState* state);