чување 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:
| M | draw.c | | | 75 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- |
| M | draw.h | | | 3 | +++ |
| M | po.c | | | 11 | +++++++---- |
| M | po.h | | | 2 | +- |
| M | poe.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;
}