poe

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

чување a0a3658a72a6427a747c29f178bdd8b34d4a23fb
родитељ ddea1d96402bef04d974eca1ab5c5bf737c465f8
Аутор: Страхиња Радић <contact@strahinja.org>
Датум:   Mon,  5 Jul 2021 18:22:14 +0200

Reorganized init_drawstate and free_drawstate into separate functions; detection of .po format is now correctly given higher priority than syntax errors

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

Diffstat:
Mdraw.c | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Mdraw.h | 3+++
Mpo.c | 11+++++++----
Mpo.h | 2+-
Mpoe.c | 144++++++++++++++++++++++++++++++++-----------------------------------------------
измењених датотека: 5, додавања: 137(+), брисања: 98(-)

diff --git a/draw.c b/draw.c @@ -33,7 +33,7 @@ const char* errors[] = { [ERR_DLG_OPEN] = "Press Esc to close dialog or q/C-Q to quit", [ERR_DLG_OPEN_QUIT] = "Press Esc to close dialog", [ERR_EMPTY_FILE] = "No msgids to edit", - [ERR_CANT_ALLOC] = "Memory allocation failed - exit advised", + [ERR_CANT_ALLOC] = "Memory allocation failed", [ERR_CANT_SAVE] = "File is not writeable", [ERR_CANT_MOVE] = "Cannot move temporary file" }; @@ -41,7 +41,6 @@ const char* flag_strings[] = { [FL_C_FORMAT] = "c-format", [FL_FUZZY] = "fuzzy" }; -const char* empty_file_text = "*** Empty file ***"; const char* first_entry_msgid = "*** SPECIAL: file info ***"; const char* program_name = "poe"; const char* prompt_dirty = "File changed, save [y/n/ESC]?"; @@ -72,6 +71,72 @@ free_bufferline(struct BufferLine* bl) bl->bg = 0; } +void +init_drawstate(struct DrawState* state, char* error, char* filename, + char* prompt) +{ + state->error = error; + state->filename = filename; + state->input_buffer = NULL; + state->input_column = 0; + state->input_first_shown_column = 0; + state->input_first_shown_row = 0; + state->input_rows_count = 0; + state->input_display_column = 0; + state->saved_column = -1; + state->info_buffer = NULL; + state->info_first_shown_column = 0; + state->info_first_shown_row = 0; + state->info_rows_count = 0; + state->prompt = prompt; + state->prompt_callback = NULL; + state->running = 1; + state->dirty = 0; + state->in_prompt = 0; + state->show_help = 0; + state->show_edit = 0; + state->edit_info_focused = 0; + state->msgid_number = state->msgid_count > 0 ? 1 : 0; + state->msgstr_index = 0; + state->first_shown_msgid = state->msgid_number; +} + +void +free_drawstate(struct DrawState* state) +{ + struct BufferLine* current = NULL; + struct PoEntry* current_entry = NULL; + size_t i = 0; + + if (state->input_buffer) + { + for (i = 0; i < state->input_rows_count; i++) + { + current = state->input_buffer+i; + free_bufferline(current); + } + free(state->input_buffer); + } + if (state->info_buffer) + { + for (i = 0; i < state->info_rows_count; i++) + { + current = state->info_buffer+i; + free_bufferline(current); + } + free(state->info_buffer); + } + if (state->entries) + { + for (i = 0; i < state->msgid_count; i++) + { + current_entry = state->entries+i; + free_po_entry(current_entry); + } + free(state->entries); + } +} + struct BufferLine* split(const uint32_t* s) { @@ -315,12 +380,6 @@ draw_editbox(const struct DrawState* state) if (state->info_first_shown_row + (h-3)/2 + 2 <= state->info_rows_count) u32_draw_string(endx-2, starty+(h-3)/2+1, fg, bg, (uint32_t*)L"\u2193", 1, 1, 0, 0, LEFT); - /* - *u32_draw_string(startx+1, starty+1, EDIT_MSGID_FG, EDIT_MSGID_BG, - * state->entries[state->msgid_number-1].msgid, w-2, - * w-2, 1, 1, LEFT); - */ - fg = state->edit_info_focused ? EDIT_MSGSTR_FG : EDIT_MSGSTR_FOCUS_FG; diff --git a/draw.h b/draw.h @@ -77,6 +77,9 @@ extern struct PoEntry entries[]; void init_bufferline(struct BufferLine* bl); void free_bufferline(struct BufferLine* bl); +void init_drawstate(struct DrawState* state, char* error, char* filename, + char* prompt); +void free_drawstate(struct DrawState* state); struct BufferLine* split(const uint32_t* s); void draw_rect(const int startx, const int endx, const int starty, const int endy, const uint16_t fg, const uint16_t bg); diff --git a/po.c b/po.c @@ -306,7 +306,7 @@ add_ref_comment(struct PoEntry* entry, const char* comment) int load_file(struct PoEntry** entries, size_t* entries_size, size_t* entries_count, const char* filename, long* lineno, - long* col) + long* col, char* error) { struct PoEntry* newchunk = calloc(ALLOC_DELTA, sizeof(struct PoEntry)); struct PoEntry* entry = NULL; @@ -338,10 +338,10 @@ load_file(struct PoEntry** entries, size_t* entries_size, *eol = 0; int result; - if ((result = parse_po_line(input_line, entries, entries_size, + result = parse_po_line(input_line, entries, entries_size, entries_count, &entry, &state, - col, &msgstr_index)) == - PARSE_ERR_NONE) + col, &msgstr_index); + if (result == PARSE_ERR_NONE) { if (state & PS_MSGID) msgid_counter = -1; @@ -351,6 +351,9 @@ load_file(struct PoEntry** entries, size_t* entries_size, if (msgid_counter == 0) return LOAD_ERR_NOT_PO_FILE; } + else if (result == PARSE_ERR_SYNTAX) + sprintf(error, "%s:%ld:%ld: Syntax error", + filename, *lineno, *col); else { if (*entries) diff --git a/po.h b/po.h @@ -94,7 +94,7 @@ struct PoEntry* u32_add_trans_comment(struct PoEntry* entry, struct PoEntry* add_ref_comment(struct PoEntry* entry, const char* comment); int load_file(struct PoEntry** entries, size_t* entries_size, size_t* entries_count, const char* filename, long* lineno, - long* col); + long* col, char* error); int save_file(const struct PoEntry* entries, const size_t msgid_count, const char* filename); int parse_po_line(const char* line, struct PoEntry** entries, diff --git a/poe.c b/poe.c @@ -21,6 +21,43 @@ extern const char* errors[]; extern const char* prompt_dirty; extern const char* program_name; +int print_error(const int code, const char* msg, ...); +int version(); +int usage(); +void format_filename(char* result, size_t result_size, const char* format, + const struct DrawState* state); +void format_msgs(char* result, size_t result_size, const char* format, + const struct DrawState* state); +void quit_callback(struct DrawState* state, struct tb_event* ev); +struct BufferLine* load_info(struct DrawState* state); +struct BufferLine* load_msgstr(struct DrawState* state); +void save_msgstr(struct DrawState* state); +void cancel_msgstr(struct DrawState* state); +void move_up(struct DrawState* state); +void move_down(struct DrawState* state); +void move_start(struct DrawState* state); +void move_left(struct DrawState* state); +void move_right(struct DrawState* state); +void move_end(struct DrawState* state); +void move_list_up(struct DrawState* state); +void move_list_down(struct DrawState* state); +void move_list_start(struct DrawState* state); +void move_list_end(struct DrawState* state); +void move_list_page_up(struct DrawState* state); +void move_list_page_down(struct DrawState* state); +void next_plural(struct DrawState* state); +void prev_plural(struct DrawState* state); +void toggle_fuzzy(struct DrawState* state); +size_t display_length(const struct DrawState* state, const size_t max_index); +size_t input_length(const struct DrawState* state, const size_t max_index); +void insert_char(struct DrawState* state, uint32_t ch); +void erase_to_start(struct DrawState* state); +void erase_to_end(struct DrawState* state); +struct DrawState* insert_line(struct DrawState* state); +struct DrawState* join_lines(struct DrawState* state, size_t first_line); +void handle_editbox_key_event(struct tb_event* ev, struct DrawState* state); +void handle_key_event(struct tb_event* ev, struct DrawState* state); + int print_error(const int code, const char* msg, ...) { @@ -108,32 +145,6 @@ quit_callback(struct DrawState* state, struct tb_event* ev) } } -struct BufferLine* load_info(struct DrawState* state); -struct BufferLine* load_msgstr(struct DrawState* state); -void save_msgstr(struct DrawState* state); -void move_up(struct DrawState* state); -void move_down(struct DrawState* state); -void move_start(struct DrawState* state); -void move_left(struct DrawState* state); -void move_right(struct DrawState* state); -void move_end(struct DrawState* state); -void move_list_up(struct DrawState* state); -void move_list_down(struct DrawState* state); -void move_list_start(struct DrawState* state); -void move_list_end(struct DrawState* state); -void move_list_page_up(struct DrawState* state); -void move_list_page_down(struct DrawState* state); -void next_plural(struct DrawState* state); -void prev_plural(struct DrawState* state); -void toggle_fuzzy(struct DrawState* state); -size_t display_length(const struct DrawState* state, const size_t max_index); -size_t input_length(const struct DrawState* state, const size_t max_index); -void insert_char(struct DrawState* state, uint32_t ch); -void erase_to_start(struct DrawState* state); -void erase_to_end(struct DrawState* state); -struct DrawState* insert_line(struct DrawState* state); -struct DrawState* join_lines(struct DrawState* state, size_t first_line); - struct BufferLine* load_info(struct DrawState* state) { @@ -936,7 +947,10 @@ handle_editbox_key_event(struct tb_event* ev, struct DrawState* state) } else if (state->input_row > 0) if (!join_lines(state, state->input_row-1)) + { strcpy(state->error, errors[ERR_CANT_ALLOC]); + state->running = 0; + } } else if (ev->key == TB_KEY_CTRL_K) erase_to_end(state); @@ -972,7 +986,10 @@ handle_editbox_key_event(struct tb_event* ev, struct DrawState* state) } else if (state->input_row < state->input_rows_count-1) if (!join_lines(state, state->input_row)) + { strcpy(state->error, errors[ERR_CANT_ALLOC]); + state->running = 0; + } } else if (ev->key == TB_KEY_END || ev->key == TB_KEY_CTRL_E) @@ -980,7 +997,10 @@ handle_editbox_key_event(struct tb_event* ev, struct DrawState* state) else if (ev->key == TB_KEY_ENTER) { if (!insert_line(state)) + { strcpy(state->error, errors[ERR_CANT_ALLOC]); + state->running = 0; + } } else if (ev->key == TB_KEY_ESC) { @@ -1120,12 +1140,15 @@ handle_key_event(struct tb_event* ev, struct DrawState* state) { case SAVE_ERR_CANT_ALLOC: strcpy(state->error, errors[ERR_CANT_ALLOC]); + state->running = 0; break; case SAVE_ERR_CANT_OPEN_FILE: strcpy(state->error, errors[ERR_CANT_SAVE]); + state->running = 0; break; case SAVE_ERR_CANT_MOVE_FILE: strcpy(state->error, strerror(errno)); + state->running = 0; break; case SAVE_ERR_NONE: default: @@ -1159,7 +1182,10 @@ handle_key_event(struct tb_event* ev, struct DrawState* state) state->error[0] = 0; } else + { strcpy(state->error, errors[ERR_CANT_ALLOC]); + state->running = 0; + } } } else if (ev->key == TB_KEY_F1 @@ -1216,7 +1242,8 @@ main(int argc, char** argv) long lineno = 1; long col = 1; int result = load_file(&state.entries, &state.msgid_size, - &state.msgid_count, filename, &lineno, &col); + &state.msgid_count, filename, &lineno, &col, + error); switch (result) { case LOAD_ERR_CANT_ALLOC: @@ -1235,72 +1262,17 @@ main(int argc, char** argv) return print_error(result, "%s:%ld:%ld: Syntax error", filename, lineno, col); case LOAD_ERR_NONE: + if (error[0] != 0) + return print_error(1, error); break; default: return print_error(1, "Unknown error (%d)", result); } - /* - *printf("state.msgid_count = %ld\n", state.msgid_count); - *for (size_t i = 0; i < state.msgid_count; i++) - *{ - * if (state.entries && state.entries[i].msgid) - * { - * char msgid[MAXBUFLINE*6]; - * *msgid = 0; - * unicode_string_to_u8(msgid, state.entries[i].msgid); - * printf("msgid #%ld=\"%s\" (%ld comment lines)\n", i, - * msgid, - * state.entries[i].comment_lines); - * for (size_t c = 0; c < state.entries[i].comment_lines; c++) - * { - * char comment[MAXCOMMENTLINE*6]; - * unicode_string_to_u8(comment, - * state.entries[i].comments[c]); - * size_t len = u32_strlen(state.entries[i].comments[c]); - * printf("\t(len=%ld) \"%s\"\n", len, comment); - * } - * printf("\t => msgstr_count = %d\n", state.entries[i].msgstr_count); - * for (size_t ms = 0; ms < state.entries[i].msgstr_count; ms++) - * { - * char u8_ms[MAXMSG*6]; - * *u8_ms = 0; - * unicode_string_to_u8(u8_ms, - * *(state.entries[i].msgstr + ms)); - * printf("\t=> \"%s\"\n", u8_ms); - * } - * } - *} - *return 0; - */ - tb_init(); error[0] = 0; - state.error = error; - state.filename = filename; - state.input_buffer = NULL; - state.input_column = 0; - state.input_first_shown_column = 0; - state.input_first_shown_row = 0; - state.input_rows_count = 0; - state.input_display_column = 0; - state.saved_column = -1; - state.info_buffer = NULL; - state.info_first_shown_column = 0; - state.info_first_shown_row = 0; - state.info_rows_count = 0; - state.prompt = prompt; - state.prompt_callback = NULL; - state.running = 1; - state.dirty = 0; - state.in_prompt = 0; - state.show_help = 0; - state.show_edit = 0; - state.edit_info_focused = 0; - state.msgid_number = state.msgid_count > 0 ? 1 : 0; - state.msgstr_index = 0; - state.first_shown_msgid = state.msgid_number; + init_drawstate(&state, error, filename, prompt); while (state.running) { @@ -1323,6 +1295,8 @@ main(int argc, char** argv) tb_shutdown(); if (state.error && state.error[0]) return print_error(1, state.error); + + free_drawstate(&state); return 0; }