чување b5e9596130f4a5b2eb5b0c64e176f04d04691419
родитељ d1019afbfcd2a3efc2dcf18a03d1d285d28f0d72
Аутор: Страхиња Радић <sr@strahinja.org>
Датум: Thu, 12 Feb 2026 23:15:17 +0100
WIP continue converting, optimizing and fixing old code
Diffstat:
| M | po.c | | | 924 | ++++++++++++++++++++++++++++++++++++++++--------------------------------------- |
| M | po.h | | | 26 | ++++++++++++++++++++------ |
| M | poe.c | | | 16 | ++++++++-------- |
| M | poe.h | | | 2 | +- |
измењених датотека: 4, додавања: 493(+), брисања: 475(-)
diff --git a/po.c b/po.c
@@ -22,6 +22,7 @@ extern const char* flag_strings[];
// TODO: Check ifdef PLURAL_ ...
+extern int cp(const char* from, const char* to);
extern int print_error(const int code, const char* msg, ...);
extern void redraw_status(struct DrawState* state);
@@ -41,26 +42,26 @@ format_flags(char* buffer, const size_t max, const struct PoEntry* entry,
void
init_po_entry(struct PoEntry* entry)
{
- entry->flags = FL_NONE;
- entry->obsolete = 0;
- entry->warning = 0;
- entry->msgid = NULL;
- entry->msgid_size = 0;
- entry->msgid_len = 0;
- entry->msgid_plural = NULL;
- entry->msgid_plural_size = 0;
- entry->msgid_plural_len = 0;
- entry->plural_forms = NULL;
- entry->msgstr = NULL;
- entry->msgstr_count = 0;
- entry->msgstr_size = NULL;
- entry->msgstr_len = NULL;
- entry->comments = NULL;
- entry->comment_lines = 0;
- entry->trans_comments = NULL;
- entry->trans_comment_lines = 0;
- entry->ref_comments = NULL;
- entry->ref_comment_lines = 0;
+ entry->flags = FL_NONE;
+ entry->obsolete = 0;
+ entry->warning = 0;
+ entry->msgid = NULL;
+ entry->msgid_size = 0;
+ entry->msgid_len = 0;
+ entry->msgid_plural = NULL;
+ entry->msgid_plural_size = 0;
+ entry->msgid_plural_len = 0;
+ entry->plural_forms = NULL;
+ entry->msgstr = NULL;
+ entry->msgstr_count = 0;
+ entry->msgstr_size = NULL;
+ entry->msgstr_len = NULL;
+ entry->comments = NULL;
+ entry->comment_lines = 0;
+ entry->extr_comments = NULL;
+ entry->extr_comment_lines = 0;
+ entry->ref_comments = NULL;
+ entry->ref_comment_lines = 0;
}
void
@@ -90,13 +91,13 @@ free_po_entry(struct PoEntry* entry)
free(entry->comments);
}
- if (entry->trans_comments)
+ if (entry->extr_comments)
{
- uint32_t** trans_comment = entry->trans_comments;
- while (trans_comment
- < entry->trans_comments + entry->trans_comment_lines)
- free(*trans_comment++);
- free(entry->trans_comments);
+ uint32_t** extr_comment = entry->extr_comments;
+ while (extr_comment
+ < entry->extr_comments + entry->extr_comment_lines)
+ free(*extr_comment++);
+ free(entry->extr_comments);
}
if (entry->ref_comments)
@@ -157,6 +158,7 @@ set_msgstr(struct PoEntry* entry, const char* msgstr, int msgstr_index,
{
uint32_t umsgstr[MAXMSGLINE];
assert(entry != NULL);
+ umsgstr[0] = 0;
if (msgstr)
u8_string_to_unicode(umsgstr, msgstr, MAXMSGLINE);
return u32_set_msgstr(entry, umsgstr, msgstr_index, append, state);
@@ -290,42 +292,42 @@ u32_set_msgstr(struct PoEntry* entry, const uint32_t* msgstr, int msgstr_index,
}
if (!newmsgstr || !newmsgstr_size || !newmsgstr_len)
{
- free(newmsgstr);
+ /*free(newmsgstr);
free(newmsgstr_len);
- free(newmsgstr_size);
+ free(newmsgstr_size);*/
return NULL;
}
- *(newmsgstr + msgstr_index) = NULL;
+ newmsgstr[msgstr_index] = NULL;
entry->msgstr = newmsgstr;
entry->msgstr_size = newmsgstr_size;
entry->msgstr_len = newmsgstr_len;
}
- if (!*(entry->msgstr + msgstr_index))
+ if (!entry->msgstr[msgstr_index])
{
- *(entry->msgstr_size + msgstr_index) = MSGDELTA;
- *(entry->msgstr_len + msgstr_index) = 0;
- *(entry->msgstr + msgstr_index)
- = calloc(*(entry->msgstr_size + msgstr_index),
+ entry->msgstr_size[msgstr_index] = MSGDELTA;
+ entry->msgstr_len[msgstr_index] = 0;
+ entry->msgstr[msgstr_index]
+ = calloc(entry->msgstr_size[msgstr_index],
sizeof(uint32_t));
}
- else if (*(entry->msgstr_len + msgstr_index) + msgstr_len
- >= *(entry->msgstr_size + msgstr_index))
+ else if (entry->msgstr_len[msgstr_index] + msgstr_len
+ >= entry->msgstr_size[msgstr_index])
{
- *(entry->msgstr_size + msgstr_index) += MSGDELTA;
- *(entry->msgstr + msgstr_index)
- = realloc(*(entry->msgstr + msgstr_index),
- *(entry->msgstr_size + msgstr_index)
+ entry->msgstr_size[msgstr_index] += MSGDELTA;
+ entry->msgstr[msgstr_index]
+ = realloc(entry->msgstr[msgstr_index],
+ entry->msgstr_size[msgstr_index]
* sizeof(uint32_t));
}
- *(entry->msgstr_len + msgstr_index) += msgstr_len;
- if (!*(entry->msgstr + msgstr_index))
+ entry->msgstr_len[msgstr_index] += msgstr_len;
+ if (!entry->msgstr[msgstr_index])
return NULL;
if (append)
- u32_strncat(*(entry->msgstr + msgstr_index), msgstr,
- *(entry->msgstr_size + msgstr_index));
+ u32_strncat(entry->msgstr[msgstr_index], msgstr,
+ entry->msgstr_size[msgstr_index]);
else
- u32_strncpy(*(entry->msgstr + msgstr_index), msgstr,
- *(entry->msgstr_size + msgstr_index));
+ u32_strncpy(entry->msgstr[msgstr_index], msgstr,
+ entry->msgstr_size[msgstr_index]);
return entry;
}
@@ -359,32 +361,32 @@ u32_add_comment(struct PoEntry* entry, const uint32_t* comment)
}
struct PoEntry*
-u32_add_trans_comment(struct PoEntry* entry, const uint32_t* trans_comment)
+u32_add_extr_comment(struct PoEntry* entry, const uint32_t* extr_comment)
{
- uint32_t** trans_comments = NULL;
- uint32_t* new_line = NULL;
- size_t len = 0;
+ uint32_t** extr_comments = NULL;
+ uint32_t* new_line = NULL;
+ size_t len = 0;
if (!entry)
return NULL;
- entry->trans_comment_lines++;
- if (!entry->trans_comments)
- trans_comments
- = calloc(entry->trans_comment_lines, sizeof(uint32_t*));
+ entry->extr_comment_lines++;
+ if (!entry->extr_comments)
+ extr_comments
+ = calloc(entry->extr_comment_lines, sizeof(uint32_t*));
else
- trans_comments = realloc(entry->trans_comments,
- entry->trans_comment_lines * sizeof(uint32_t*));
- if (!trans_comments)
+ extr_comments = realloc(entry->extr_comments,
+ entry->extr_comment_lines * sizeof(uint32_t*));
+ if (!extr_comments)
return NULL;
- entry->trans_comments = trans_comments;
+ entry->extr_comments = extr_comments;
- len = u32_strlen(trans_comment) + 1;
+ len = u32_strlen(extr_comment) + 1;
new_line = calloc(len, sizeof(uint32_t));
if (!new_line)
return NULL;
- entry->trans_comments[entry->trans_comment_lines - 1] = new_line;
- u32_strncpy(new_line, trans_comment, len);
+ entry->extr_comments[entry->extr_comment_lines - 1] = new_line;
+ u32_strncpy(new_line, extr_comment, len);
return entry;
}
@@ -485,8 +487,9 @@ load_file(struct DrawState* dstate, long* lineno, long* col)
if (nulbyte && (nulbyte != eol))
possible_nulbyte = 1;
- parse_po_line(input_line, dstate, &entry, &pstate, col,
- &msgstr_index);
+ if (parse_po_line(input_line, dstate, &entry, &pstate, col,
+ &msgstr_index))
+ return 1;
if (entry && entry->msgid_plural)
has_plural_msgid = 1;
@@ -498,7 +501,6 @@ load_file(struct DrawState* dstate, long* lineno, long* col)
msgid_counter = -1;
else if (msgid_counter != -1)
msgid_counter--;
-
if (msgid_counter == 0)
{
dstate->error = ERR_NOTPO_FILE;
@@ -571,82 +573,77 @@ load_file_alloc_error:
}
int
+save_comment(FILE* output, struct DrawState* state,
+ const struct PoEntry* current)
+{
+ char* u8_comment = NULL;
+ char* temp = NULL;
+ size_t c, len, size;
+
+ assert((output != NULL) && (state != NULL) && (current != NULL));
+ for (c = 0; c < current->comment_lines; c++)
+ {
+ len = u32_strlen(current->comments[c]);
+ size = len * UTF8REPMAX + 1;
+ temp = realloc(u8_comment, size);
+ if (!temp)
+ {
+ state->error = ERR_CANT_ALLOC;
+ return 1;
+ }
+ u8_comment = temp;
+ unicode_string_to_u8(u8_comment, current->comments[c], len);
+ fprintf(output, "#%s%s\n", current->obsolete ? "~ " : "",
+ u8_comment);
+ }
+ free(u8_comment);
+ return 0;
+}
+
+int
save_file(struct DrawState* state)
{
FILE* output = NULL;
const struct PoEntry* current = NULL;
struct stat st;
- char* real_filename = NULL;
- char* backup_filename = NULL;
- ssize_t rfn_len = 0;
- Flags flags;
- int saved_errno;
int result = 0;
+ int saved_errno;
assert(state != NULL);
+
+ state->action = ACT_WRITING;
+ redraw_status(state);
+ errno = 0;
+
current = state->entries;
- if (!(real_filename = calloc(MAXPATH, 1)))
- return SAVE_ERR_CANT_ALLOC;
if (!create_backups)
goto save_skip_backup_copy;
if (!backup_fail && !state->backup_possible)
goto save_skip_backup_copy;
- if (!(backup_filename = calloc(MAXPATH, 1)))
- {
- free(real_filename);
- return SAVE_ERR_CANT_ALLOC;
- }
- if (lstat(state->filename, &st) != -1)
+ if ((unlink(state->backup_filename) < 0) && (errno != ENOENT))
{
- if (S_ISLNK(st.st_mode))
- {
- rfn_len = readlink(state->filename, real_filename,
- MAXPATH);
- if (rfn_len == -1)
- {
- result = SAVE_ERR_CANT_READLINK;
- goto save_loop_entries_done;
- }
- real_filename[rfn_len] = 0;
- if (stat(real_filename, &st) == -1)
- {
- result = SAVE_ERR_CANT_STAT_FILE;
- goto save_loop_entries_done;
- }
- }
- STRLCPY(state->filename, backup_filename, MAXPATH);
- STRLCAT(backup_suffix, backup_filename, MAXPATH);
- if (rename(rfn_len > 0 ? real_filename : state->filename,
- backup_filename)
- == -1)
- {
- result = SAVE_ERR_CANT_MOVE_FILE;
- goto save_loop_entries_done;
- }
- }
- else
- {
- result = SAVE_ERR_CANT_STAT_FILE;
- goto save_loop_entries_done;
+ state->error = ERR_ERRNO_SET;
+ result = 1;
+ goto save_file_cleanup;
}
- if (rfn_len > 0)
+
+ if (cp(state->rfn_len > 0 ? state->real_filename : state->filename,
+ state->backup_filename))
{
- if (unlink(state->filename) == -1)
+ if (backup_fail)
{
- result = SAVE_ERR_CANT_UNLINK;
- goto save_loop_entries_done;
- }
- if (symlink(real_filename, state->filename) == -1)
- {
- result = SAVE_ERR_CANT_SYMLINK;
- goto save_loop_entries_done;
+ state->error = ERR_ERRNO_SET;
+ result = 1;
+ goto save_file_cleanup;
}
+ else
+ errno = 0; /* ignore errors */
}
- chmod(rfn_len > 0 ? real_filename : state->filename, st.st_mode);
save_skip_backup_copy:
- if (!(output = fopen(rfn_len > 0 ? real_filename : state->filename,
+ if (!(output = fopen(state->rfn_len > 0 ? state->real_filename
+ : state->filename,
"wt")))
{
state->error = ERR_ERRNO_SET;
@@ -654,82 +651,108 @@ save_skip_backup_copy:
goto save_file_cleanup;
}
-save_loop_entries_start:
- if (current >= state->entries + state->real_msgid_count)
- goto save_loop_entries_done;
+ if (!create_backups)
+ goto save_skip_backup_symlink;
- if (current->obsolete)
- goto save_flags;
+ if (lstat(state->rfn_len > 0 ? state->real_filename : state->filename,
+ &st)
+ < 0)
+ {
+ state->error = ERR_ERRNO_SET;
+ result = 1;
+ goto save_file_cleanup;
+ }
+
+ if (!backup_fail && !state->backup_possible)
+ goto save_skip_backup_symlink;
-save_comments:
- if (current->comment_lines > 0)
+ if (state->rfn_len > 0)
{
- char* u8_comment = NULL;
- for (size_t c = 0; c < current->comment_lines; c++)
+ if (unlink(state->filename) == -1)
{
- size_t len = u32_strlen(*(current->comments + c));
- size_t size = len * UTF8REPMAX + 1;
- if (!u8_comment)
- {
- u8_comment = malloc(size);
- memset(u8_comment, 0, size);
- }
- else
- u8_comment = realloc(u8_comment, size);
- if (!u8_comment)
- {
- result = SAVE_ERR_CANT_ALLOC;
- goto save_file_alloc_error;
- }
- unicode_string_to_u8(u8_comment,
- *(current->comments + c), len);
- fprintf(output, "#%s%s\n", current->obsolete ? "~" : "",
- u8_comment);
+ state->error = ERR_ERRNO_SET;
+ result = 1;
+ goto save_file_cleanup;
}
- free(u8_comment);
- }
- if (current->trans_comment_lines > 0)
- {
- char* u8_trans_comment = NULL;
- for (size_t tc = 0; tc < current->trans_comment_lines; tc++)
+ if (symlink(state->orig_real_filename, state->filename) == -1)
{
- size_t len
- = u32_strlen(*(current->trans_comments + tc));
- size_t size = len * UTF8REPMAX + 1;
-
- if (!u8_trans_comment)
- {
- u8_trans_comment = malloc(size);
- memset(u8_trans_comment, 0, size);
- }
- else
- u8_trans_comment
- = realloc(u8_trans_comment, size);
- if (!u8_trans_comment)
- {
- result = SAVE_ERR_CANT_ALLOC;
- goto save_file_alloc_error;
- }
- unicode_string_to_u8(u8_trans_comment,
- *(current->trans_comments + tc), len);
- fprintf(output, "#.%s%s\n",
- u8_trans_comment[0] == 0 ? "" : " ",
- u8_trans_comment);
+ state->error = ERR_ERRNO_SET;
+ result = 1;
+ goto save_file_cleanup;
}
- free(u8_trans_comment);
}
+ chmod(state->rfn_len > 0 ? state->real_filename : state->filename,
+ st.st_mode);
+
+save_skip_backup_symlink:
+ /*if (state->rows_count == 1 && state->buffer[0].length == 0)
+ goto save_file_cleanup;*/
+
+ ;
+
+save_loop_entries_start:
+ if (current >= state->entries + state->real_msgid_count)
+ goto save_loop_entries_done;
+
+ if (!current->obsolete && current->comment_lines > 0)
+ if (save_comment(output, state, current))
+ return 1;
+ if (current->extr_comment_lines > 0)
+ if (save_extr_comment(output, state, current))
+ return 1;
if (current->ref_comment_lines > 0)
+ if (save_ref_comment(output, state, current))
+ return 1;
+ if (save_flags(output, state, current))
+ return 1;
+ if (current->obsolete && current->comment_lines > 0)
+ if (save_comment(output, state, current))
+ return 1;
+
+ if (current->obsolete)
{
- for (size_t rc = 0; rc < current->ref_comment_lines; rc++)
- fprintf(output, "#: %s\n",
- *(current->ref_comments + rc));
+ if (current < state->entries + state->real_msgid_count - 1)
+ fprintf(output, "\n");
+ current++;
+ goto save_loop_entries_start;
}
- if (current->obsolete)
- goto save_obsolete_check;
-save_flags:
+ save_msgid(output, state, current);
+ if (current->msgid_plural)
+ if (save_msgid_plural(output, state, current))
+ return 1;
+
+ if (save_msgstrs(output, state, current))
+ return 1;
+
+ if (current < state->entries + state->real_msgid_count - 1)
+ fprintf(output, "\n");
+ current++;
+ goto save_loop_entries_start;
+
+ /*save_file_alloc_error:
+ if (output)
+ fclose(output);
+ return 1;*/
+
+save_loop_entries_done:
+save_file_cleanup:
+ saved_errno = errno;
+ if (output)
+ fclose(output);
+ state->action = ACT_IDLE;
+ errno = saved_errno;
+ return result;
+}
+
+int
+save_flags(FILE* output, struct DrawState* state, const struct PoEntry* current)
+{
+ Flags flags;
+
+ assert((output != NULL) && (state != NULL) && (current != NULL));
flags = current->flags;
- if (current->flags != FL_NONE)
+ if (flags != FL_NONE)
fprintf(output, "#, ");
while (flags != FL_NONE)
{
@@ -756,336 +779,297 @@ save_flags:
}
if (current->flags != FL_NONE)
fprintf(output, "\n");
- if (current->obsolete)
- goto save_comments;
+ return 0;
+}
-save_obsolete_check:
- if (current->obsolete)
+int
+save_msgid(FILE* output, struct DrawState* state, const struct PoEntry* current)
+{
+ const uint32_t* pumsgid = NULL;
+ const uint32_t* old_pumsgid = NULL;
+ char* u8_msgid = NULL;
+ size_t len = 0;
+ size_t num_lines;
+ size_t size;
+
+ assert((output != NULL) && (state != NULL) && (current != NULL));
+ if (!current->msgid)
{
- if (current < state->entries + state->real_msgid_count - 1)
- fprintf(output, "\n");
- current++;
- goto save_loop_entries_start;
+ fprintf(output, "msgid \"\"\n");
+ return 0;
}
+ num_lines = u32_lines_in_string(current->msgid, 1, wrap_width);
- if (current->msgid)
+ if ((num_lines > 1)
+ && (u32_strlen(current->msgid) > SAVE_MULTILINE_TRESHOLD))
{
- size_t num_lines
- = u32_lines_in_string(current->msgid, 1, wrap_width);
-
- if ((num_lines > 1)
- && (u32_strlen(current->msgid)
- > SAVE_MULTILINE_TRESHOLD))
+ pumsgid = current->msgid;
+ fprintf(output, "msgid \"\"\n");
+ while (*pumsgid)
{
- const uint32_t* pumsgid = current->msgid;
-
- fprintf(output, "msgid \"\"\n");
-
- while (*pumsgid)
- {
- size_t len = 0;
- size_t size;
- char* u8_msgid = NULL;
- const uint32_t* old_pumsgid = pumsgid;
+ u8_msgid = NULL;
+ old_pumsgid = pumsgid;
+ len = 0;
- len = u32_next_line(current->msgid, &pumsgid, 1,
- wrap_width);
- if (len == 0)
- continue;
+ len = u32_next_line(current->msgid, &pumsgid, 1,
+ wrap_width);
+ if (len == 0)
+ continue;
- size = len * UTF8REPMAX + 1;
-
- u8_msgid = malloc(size);
- if (!u8_msgid)
- {
- result = SAVE_ERR_CANT_ALLOC;
- goto save_file_alloc_error;
- }
-
- memset(u8_msgid, 0, size);
-
- unicode_string_to_u8(u8_msgid, old_pumsgid, len);
- fprintf(output, "\"%s\"\n", u8_msgid);
- free(u8_msgid);
- }
- }
- else
- {
- size_t size;
- char* u8_msgid = NULL;
+ size = len * UTF8REPMAX + 1;
- size = current->msgid_size * UTF8REPMAX + 1;
u8_msgid = malloc(size);
if (!u8_msgid)
{
- result = SAVE_ERR_CANT_ALLOC;
- goto save_file_alloc_error;
+ state->error = ERR_CANT_ALLOC;
+ return 1;
}
memset(u8_msgid, 0, size);
- unicode_string_to_u8(u8_msgid, current->msgid,
- current->msgid_size);
- fprintf(output, "msgid \"%s\"\n", u8_msgid);
+ unicode_string_to_u8(u8_msgid, old_pumsgid, len);
+ fprintf(output, "\"%s\"\n", u8_msgid);
free(u8_msgid);
}
}
else
- fprintf(output, "msgid \"\"\n");
-
- if (current->msgid_plural)
{
- size_t num_lines = u32_lines_in_string(current->msgid_plural, 1,
- wrap_width);
-
- if ((num_lines > 1)
- && (u32_strlen(current->msgid_plural)
- > SAVE_MULTILINE_TRESHOLD))
+ size = current->msgid_size * UTF8REPMAX + 1;
+ u8_msgid = malloc(size);
+ if (!u8_msgid)
{
- const uint32_t* pumsgid = current->msgid_plural;
-
- fprintf(output, "msgid_plural \"\"\n");
+ state->error = ERR_CANT_ALLOC;
+ return 1;
+ }
- while (*pumsgid)
- {
- size_t len = 0;
- char* u8_msgid = NULL;
- const uint32_t* old_pumsgid = pumsgid;
- size_t size;
-
- len = u32_next_line(current->msgid_plural,
- &pumsgid, 1, wrap_width);
- if (len == 0)
- continue;
-
- size = len * UTF8REPMAX + 1;
- u8_msgid = malloc(size);
- if (!u8_msgid)
- {
- result = SAVE_ERR_CANT_ALLOC;
- goto save_file_alloc_error;
- }
+ memset(u8_msgid, 0, size);
- memset(u8_msgid, 0, size);
+ unicode_string_to_u8(u8_msgid, current->msgid,
+ current->msgid_size);
+ fprintf(output, "msgid \"%s\"\n", u8_msgid);
+ free(u8_msgid);
+ }
+ return 0;
+}
- unicode_string_to_u8(u8_msgid, old_pumsgid, len);
- fprintf(output, "\"%s\"\n", u8_msgid);
- free(u8_msgid);
- }
- }
- else
+int
+save_msgid_plural(FILE* output, struct DrawState* state,
+ const struct PoEntry* current)
+{
+ const uint32_t* old_pumsgid = NULL;
+ const uint32_t* pumsgid = NULL;
+ char* u8_msgid = NULL;
+ size_t len = 0;
+ size_t msgid_plural_len, num_lines, size;
+
+ assert((output != NULL) && (state != NULL) && (current != NULL));
+ num_lines = u32_lines_in_string(current->msgid_plural, 1, wrap_width);
+ if ((num_lines > 1)
+ && (u32_strlen(current->msgid_plural) > SAVE_MULTILINE_TRESHOLD))
+ {
+ pumsgid = current->msgid_plural;
+ fprintf(output, "msgid_plural \"\"\n");
+ while (*pumsgid)
{
- char* u8_msgid = NULL;
- size_t size;
- size_t msgid_plural_len;
-
- size = current->msgid_plural_size * UTF8REPMAX + 1;
+ len = 0;
+ u8_msgid = NULL;
+ old_pumsgid = pumsgid;
+ len = u32_next_line(current->msgid_plural, &pumsgid, 1,
+ wrap_width);
+ if (len == 0)
+ continue;
+
+ size = len * UTF8REPMAX + 1;
u8_msgid = malloc(size);
if (!u8_msgid)
{
- result = SAVE_ERR_CANT_ALLOC;
- goto save_file_alloc_error;
+ state->error = ERR_CANT_ALLOC;
+ return 1;
}
- memset(u8_msgid, 9, size);
+ memset(u8_msgid, 0, size);
- msgid_plural_len = u32_strlen(current->msgid_plural);
- unicode_string_to_u8(u8_msgid, current->msgid_plural,
- msgid_plural_len);
- fprintf(output, "msgid_plural \"%s\"\n", u8_msgid);
+ unicode_string_to_u8(u8_msgid, old_pumsgid, len);
+ fprintf(output, "\"%s\"\n", u8_msgid);
free(u8_msgid);
}
}
+ else
+ {
+ size = current->msgid_plural_size * UTF8REPMAX + 1;
+ u8_msgid = malloc(size);
+ if (!u8_msgid)
+ {
+ state->error = ERR_CANT_ALLOC;
+ return 1;
+ }
+
+ memset(u8_msgid, 9, size);
+
+ msgid_plural_len = u32_strlen(current->msgid_plural);
+ unicode_string_to_u8(u8_msgid, current->msgid_plural,
+ msgid_plural_len);
+ fprintf(output, "msgid_plural \"%s\"\n", u8_msgid);
+ free(u8_msgid);
+ }
+ return 0;
+}
+int
+save_msgstrs(FILE* output, struct DrawState* state,
+ const struct PoEntry* current)
+{
+ const uint32_t* pumsgstr = NULL;
+ const uint32_t* old_pumsgstr = NULL;
+ char now[MAXDATEBUF];
+ char* u8_msgstr = NULL;
+ struct tm* now_tm = NULL;
+ time_t t;
+ ssize_t m, num_lines;
+ size_t len, size, msgstr_len;
+ int i;
+ int seen_generator = 0;
+ int seen_plural_forms = 0;
+ int first_entry;
+
+ assert((output != NULL) && (state != NULL) && (current != NULL));
+ first_entry = (current == state->entries) && !current->msgid;
+ if (!current->msgstr_count)
+ {
+ if (current->msgid_plural)
+ for (i = 0; i < state->nplurals; i++)
+ fprintf(output, "msgstr[%d] \"\"\n", i);
+ else
+ fprintf(output, "msgstr \"\"\n");
+ return 0;
+ }
if (current->msgstr_count == 1)
{
- ssize_t num_lines
- = u32_lines_in_string(*current->msgstr, 1, wrap_width);
- int first_entry
- = (current == state->entries) && !current->msgid;
-
+ t = time(NULL);
+ now_tm = localtime(&t);
+ strftime(now, MAXDATEBUF, "%F %H:%M%z", now_tm);
+ }
+ for (m = 0; m < current->msgstr_count; m++)
+ {
+ num_lines = u32_lines_in_string(current->msgstr[m], 1,
+ wrap_width);
if ((num_lines > 1)
- && (first_entry
- || (u32_strlen(*current->msgstr)
- > (size_t)SAVE_MULTILINE_TRESHOLD)))
+ && (u32_strlen(current->msgstr[m])
+ > SAVE_MULTILINE_TRESHOLD))
{
- const uint32_t* pumsgstr = *current->msgstr;
- int seen_generator = 0;
- int seen_plural_forms = 0;
- char now[MAXDATEBUF];
- time_t t = time(NULL);
- struct tm* now_tm = localtime(&t);
-
- strftime(now, MAXDATEBUF, "%F %H:%M%z", now_tm);
- fprintf(output, "msgstr \"\"\n");
+ pumsgstr = current->msgstr[m];
+ if (current->msgstr_count == 1)
+ fprintf(output, "msgstr \"\"\n");
+ else
+ fprintf(output, "msgstr[%ld] \"\"\n", m);
- while (*pumsgstr)
+ save_msgstrs_pumsgstr_loop:
+ len = 0;
+ old_pumsgstr = pumsgstr;
+ len = u32_next_line(current->msgstr[m], &pumsgstr, 1,
+ wrap_width);
+ if (len == 0)
+ goto save_msgstrs_pumsgstr_done;
+ size = len * UTF8REPMAX + 1;
+ u8_msgstr = malloc(size);
+ if (!u8_msgstr)
{
- size_t len = 0;
- size_t size;
- char* u8_msgstr = NULL;
- const uint32_t* old_pumsgstr = pumsgstr;
-
- len = u32_next_line(*current->msgstr, &pumsgstr,
- 1,
- ((first_entry && wrap_first_msgstr)
- || !first_entry)
- ? wrap_width
- : 0);
-
- if (len == 0)
- continue;
-
- size = len * UTF8REPMAX + 1;
- u8_msgstr = malloc(size);
- if (!u8_msgstr)
- {
- result = SAVE_ERR_CANT_ALLOC;
- goto save_file_alloc_error;
- }
+ state->error = ERR_CANT_ALLOC;
+ return 1;
+ }
+ memset(u8_msgstr, 0, size);
- memset(u8_msgstr, 0, size);
-
- unicode_string_to_u8(u8_msgstr, old_pumsgstr,
- len);
- 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 (first_entry && plural_string
- && starts_with(u8_msgstr,
- "Plural-Forms: "))
- {
- seen_plural_forms = 1;
- fprintf(output,
- "\"Plural-Forms: %s\\n\"\n",
- plural_string);
- }
- else
- fprintf(output, "\"%s\"\n", u8_msgstr);
- free(u8_msgstr);
+ unicode_string_to_u8(u8_msgstr, old_pumsgstr, len);
+ if (first_entry
+ && starts_with(u8_msgstr, "X-Generator: "))
+ {
+ seen_generator = 1;
+ fprintf(output, "\"X-Generator: poe %s\\n\"\n",
+ VERSION);
}
- if (first_entry && plural_string && !seen_plural_forms)
+ else if (first_entry && plural_string
+ && starts_with(u8_msgstr, "Plural-Forms: "))
+ {
+ seen_plural_forms = 1;
fprintf(output, "\"Plural-Forms: %s\\n\"\n",
plural_string);
+ }
+ else
+ fprintf(output, "\"%s\"\n", u8_msgstr);
+ free(u8_msgstr);
+ if (*pumsgstr)
+ goto save_msgstrs_pumsgstr_loop;
+
+ save_msgstrs_pumsgstr_done:
if (first_entry && !seen_generator)
fprintf(output, "\"X-Generator: poe %s\\n\"\n",
VERSION);
+ if (first_entry && plural_string && !seen_plural_forms)
+ fprintf(output, "\"Plural-Forms: %s\\n\"\n",
+ plural_string);
}
- else if (current->msgid_plural
- && (!*current->msgstr || !**current->msgstr))
- for (int i = 0; i < state->nplurals; i++)
- fprintf(output, "msgstr[%d] \"\"\n", i);
else
{
- size_t size = MAXMSGLINE * UTF8REPMAX + 1;
- char u8_msgstr[size];
- size_t msgstr_len;
-
- msgstr_len = u32_strlen(*current->msgstr);
- unicode_string_to_u8(u8_msgstr, *current->msgstr,
- msgstr_len);
- fprintf(output, "msgstr \"%s\"\n", u8_msgstr);
- }
- }
- else if (current->msgstr_count > 0)
- {
- for (ssize_t m = 0; m < current->msgstr_count; m++)
- {
- ssize_t num_lines
- = u32_lines_in_string(*current->msgstr, 1,
- wrap_width);
-
- if ((num_lines > 1)
- && (u32_strlen(*(current->msgstr + m))
- > SAVE_MULTILINE_TRESHOLD))
+ size = MAXMSGLINE * UTF8REPMAX + 1;
+ u8_msgstr = malloc(size);
+ if (!u8_msgstr)
{
- const uint32_t* pumsgstr
- = *(current->msgstr + m);
-
- fprintf(output, "msgstr[%ld] \"\"\n", m);
-
- while (*pumsgstr)
- {
- size_t len = 0;
- size_t size;
- char* u8_msgstr = NULL;
- const uint32_t* old_pumsgstr = pumsgstr;
-
- len = u32_next_line(*(current->msgstr
- + m),
- &pumsgstr, 1, wrap_width);
- if (len == 0)
- continue;
-
- size = len * UTF8REPMAX + 1;
- u8_msgstr = malloc(size);
- if (!u8_msgstr)
- {
- result = SAVE_ERR_CANT_ALLOC;
- goto save_file_alloc_error;
- }
-
- memset(u8_msgstr, 0, size);
-
- unicode_string_to_u8(u8_msgstr,
- old_pumsgstr, len);
- fprintf(output, "\"%s\"\n", u8_msgstr);
- free(u8_msgstr);
- }
+ state->error = ERR_CANT_ALLOC;
+ return 1;
}
+ msgstr_len = u32_strlen(current->msgstr[m]);
+ unicode_string_to_u8(u8_msgstr, current->msgstr[m],
+ msgstr_len);
+ if (current->msgstr_count == 1)
+ fprintf(output, "msgstr \"%s\"\n", u8_msgstr);
else
- {
- size_t size = MAXMSGLINE * UTF8REPMAX + 1;
- char u8_msgstr[size];
- size_t msgstr_len;
- msgstr_len = u32_strlen(*(current->msgstr + m));
- unicode_string_to_u8(u8_msgstr,
- *(current->msgstr + m), msgstr_len);
fprintf(output, "msgstr[%ld] \"%s\"\n", m,
u8_msgstr);
- }
+ free(u8_msgstr);
}
}
- else
- {
- if (current->msgid_plural)
- for (int i = 0; i < state->nplurals; i++)
- fprintf(output, "msgstr[%d] \"\"\n", i);
- else
- fprintf(output, "msgstr \"\"\n");
- }
+ return 0;
+}
- if (current < state->entries + state->real_msgid_count - 1)
- fprintf(output, "\n");
- current++;
- goto save_loop_entries_start;
-save_file_alloc_error:
- if (output)
- fclose(output);
- return 1;
+int
+save_ref_comment(FILE* output, struct DrawState* state,
+ const struct PoEntry* current)
+{
+ size_t rc;
+ assert((output != NULL) && (state != NULL) && (current != NULL));
+ for (rc = 0; rc < current->ref_comment_lines; rc++)
+ fprintf(output, "#: %s\n", current->ref_comments[rc]);
+ return 0;
+}
-save_loop_entries_done:
-save_file_cleanup:
- saved_errno = errno;
- if (output)
- fclose(output);
- free(backup_filename);
- free(real_filename);
- state->action = ACT_IDLE;
- errno = saved_errno;
- return result;
+int
+save_extr_comment(FILE* output, struct DrawState* state,
+ const struct PoEntry* current)
+{
+ char* u8_extr_comment = NULL;
+ char* temp = NULL;
+ size_t tc, len, size;
+
+ assert((output != NULL) && (state != NULL) && (current != NULL));
+ for (tc = 0; tc < current->extr_comment_lines; tc++)
+ {
+ len = u32_strlen(current->extr_comments[tc]);
+ size = len * UTF8REPMAX + 1;
+
+ temp = realloc(u8_extr_comment, size);
+ if (!temp)
+ {
+ state->error = ERR_CANT_ALLOC;
+ return 1;
+ }
+ u8_extr_comment = temp;
+ unicode_string_to_u8(u8_extr_comment,
+ current->extr_comments[tc], len);
+ fprintf(output, "#.%s%s\n", u8_extr_comment[0] == 0 ? "" : " ",
+ u8_extr_comment);
+ }
+ free(u8_extr_comment);
+ return 0;
}
#define INC_COL() \
@@ -1116,17 +1100,17 @@ parse_po_line(const char* line, struct DrawState* dstate,
*token = 0;
ptoken = token;
- if (starts_with(line, "msgid_plural"))
+ if (starts_with(line, "msgid_plural "))
{
- len = strlen("msgid_plural");
+ len = strlen("msgid_plural ");
*pstate &= ~PS_MSGID;
*pstate |= PS_MSGID_PLURAL;
pline += len;
*col += len;
}
- else if (starts_with(line, "msgid"))
+ else if (starts_with(line, "msgid "))
{
- len = strlen("msgid");
+ len = strlen("msgid ");
*pstate |= PS_MSGID;
pline += len;
*col += len;
@@ -1158,9 +1142,9 @@ parse_po_line(const char* line, struct DrawState* dstate,
goto parse_po_cleanup;
}
}
- else if (starts_with(line, "msgstr"))
+ else if (starts_with(line, "msgstr "))
{
- len = strlen("msgstr");
+ len = strlen("msgstr ");
*pstate &= ~PS_MSGID;
*pstate &= ~PS_MSGID_PLURAL;
*pstate |= PS_MSGSTR;
@@ -1227,6 +1211,11 @@ parse_po_line(const char* line, struct DrawState* dstate,
*pstate |= PS_COMMENT_EXTR;
pline++;
INC_COL();
+ while (*pline == ' ' || *pline == '\t')
+ {
+ pline++;
+ INC_COL();
+ }
}
else
{
@@ -1241,6 +1230,11 @@ parse_po_line(const char* line, struct DrawState* dstate,
*pstate |= PS_COMMENT_FLAG;
pline++;
INC_COL();
+ while (*pline == ' ' || *pline == '\t')
+ {
+ pline++;
+ INC_COL();
+ }
}
else
{
@@ -1255,6 +1249,11 @@ parse_po_line(const char* line, struct DrawState* dstate,
*pstate |= PS_COMMENT_REFN;
pline++;
INC_COL();
+ while (*pline == ' ' || *pline == '\t')
+ {
+ pline++;
+ INC_COL();
+ }
}
else
{
@@ -1269,6 +1268,11 @@ parse_po_line(const char* line, struct DrawState* dstate,
*pstate |= PS_COMMENT_OBSO;
pline++;
INC_COL();
+ while (*pline == ' ' || *pline == '\t')
+ {
+ pline++;
+ INC_COL();
+ }
}
else
{
@@ -1279,7 +1283,7 @@ parse_po_line(const char* line, struct DrawState* dstate,
case '\\':
if (*pstate & PS_COMMENT)
{
- pline++;
+ *ptoken++ = *pline++;
INC_COL();
}
else if ((*pstate & PS_STRING) && *(pstate + 1))
@@ -1292,7 +1296,7 @@ parse_po_line(const char* line, struct DrawState* dstate,
case '"':
if (*pstate & PS_COMMENT)
{
- pline++;
+ *ptoken++ = *pline++;
INC_COL();
}
else if (*pstate & PS_STRING)
@@ -1404,7 +1408,7 @@ parse_po_line(const char* line, struct DrawState* dstate,
if (!u32_token)
goto parse_po_line_alloc_error;
u8_string_to_unicode(u32_token, token, len);
- u32_add_trans_comment(*current_entry, u32_token);
+ u32_add_extr_comment(*current_entry, u32_token);
free(u32_token);
}
else if (*pstate & PS_COMMENT_FLAG)
@@ -1466,7 +1470,7 @@ parse_po_line(const char* line, struct DrawState* dstate,
else if (*pstate & PS_COMMENT_TRAN)
u32_add_comment(*current_entry, (uint32_t*)L"");
else if (*pstate & PS_COMMENT_EXTR)
- u32_add_trans_comment(*current_entry, (uint32_t*)L"");
+ u32_add_extr_comment(*current_entry, (uint32_t*)L"");
/* one-line states */
*pstate &= ~PS_COMMENT;
diff --git a/po.h b/po.h
@@ -48,8 +48,8 @@ typedef enum {
PS_NONE = 0,
PS_COMMENT_TRAN = 1, /* "translator-comments" : # */
PS_COMMENT_EXTR = 1 << 1, /* "extracted-comments" : #. */
- PS_COMMENT_FLAG = 1 << 2, /* "flag" : #, */
- PS_COMMENT_REFN = 1 << 3, /* "reference" : #: */
+ PS_COMMENT_REFN = 1 << 2, /* "reference" : #: */
+ PS_COMMENT_FLAG = 1 << 3, /* "flag" : #, */
PS_COMMENT_OBSO = 1 << 4, /* obsolete (undocumented) : #~ */
PS_MSGID = 1 << 5,
PS_MSGID_PLURAL = 1 << 6,
@@ -95,8 +95,8 @@ struct PoEntry {
size_t* msgstr_len;
uint32_t** comments;
size_t comment_lines;
- uint32_t** trans_comments;
- size_t trans_comment_lines;
+ uint32_t** extr_comments;
+ size_t extr_comment_lines;
char** ref_comments;
size_t ref_comment_lines;
};
@@ -122,11 +122,25 @@ struct PoEntry* u32_set_plural_forms(struct PoEntry* entry,
struct PoEntry* u32_set_msgstr(struct PoEntry* entry, const uint32_t* msgstr,
int msgstr_index, int append, struct DrawState* state);
struct PoEntry* u32_add_comment(struct PoEntry* entry, const uint32_t* comment);
-struct PoEntry* u32_add_trans_comment(struct PoEntry* entry,
- const uint32_t* trans_comment);
+struct PoEntry* u32_add_extr_comment(struct PoEntry* entry,
+ const uint32_t* extr_comment);
struct PoEntry* add_ref_comment(struct PoEntry* entry, const char* comment);
int load_file(struct DrawState* state, long* lineno, long* col);
+int save_comment(FILE* output, struct DrawState* state,
+ const struct PoEntry* current);
int save_file(struct DrawState* state);
+int save_flags(FILE* output, struct DrawState* state,
+ const struct PoEntry* current);
+int save_msgid(FILE* output, struct DrawState* state,
+ const struct PoEntry* current);
+int save_msgid_plural(FILE* output, struct DrawState* state,
+ const struct PoEntry* current);
+int save_msgstrs(FILE* output, struct DrawState* state,
+ const struct PoEntry* current);
+int save_ref_comment(FILE* output, struct DrawState* state,
+ const struct PoEntry* current);
+int save_extr_comment(FILE* output, struct DrawState* state,
+ const struct PoEntry* current);
int parse_po_line(const char* line, struct DrawState* dstate,
struct PoEntry** current_entry, ParseState* pstate, long* col,
int* msgstr_index);
diff --git a/poe.c b/poe.c
@@ -57,7 +57,7 @@ cancel_callback(struct DrawState* state, struct tb_event* ev)
#define MAXCOPYBUF 8192
-static int
+int
cp(const char* from, const char* to)
{
struct stat st;
@@ -533,8 +533,8 @@ load_info(struct DrawState* state)
}
if (current->comments)
num_lines += current->comment_lines + 1;
- if (current->trans_comments)
- num_lines += current->trans_comment_lines + 1;
+ if (current->extr_comments)
+ num_lines += current->extr_comment_lines + 1;
if (current->ref_comments)
num_lines += current->ref_comment_lines + 1;
newbuf = calloc(num_lines, sizeof(struct BufferLine));
@@ -647,7 +647,7 @@ load_info(struct DrawState* state)
pnewbuf++;
}
}
- if (current->trans_comments)
+ if (current->extr_comments)
{
newlen = u32_u8_strncpy(pnewbuf->text,
"Translation comments:", MAXBUFLINE);
@@ -657,11 +657,11 @@ load_info(struct DrawState* state)
pnewbuf->fg = colors[C_EDIT_MSGID_HEADING].fg;
pnewbuf->bg = colors[C_EDIT_MSGID_HEADING].bg;
pnewbuf++;
- for (size_t i = 0; i < current->trans_comment_lines; i++)
+ for (size_t i = 0; i < current->extr_comment_lines; i++)
{
- uint32_t* trans_comment = current->trans_comments[i];
- size_t len = u32_strlen(trans_comment);
- newlen = u32_strncpy(pnewbuf->text, trans_comment,
+ uint32_t* extr_comment = current->extr_comments[i];
+ size_t len = u32_strlen(extr_comment);
+ newlen = u32_strncpy(pnewbuf->text, extr_comment,
MIN(len + 1, MAXBUFLINE));
pnewbuf->length = newlen;
if (newlen > state->info_rows_maxlen)
diff --git a/poe.h b/poe.h
@@ -7,7 +7,7 @@ static int cancel_close(struct DrawState* state);
static int cancel_msgstr(struct DrawState* state);
static int cancel_search(struct DrawState* state);
static int copy_msgid_to_input(struct DrawState* state);
-static int cp(const char* from, const char* to);
+int cp(const char* from, const char* to);
//static int create_file(struct DrawState* state);
static char* dirname(char* dir, char* path, const ssize_t dir_size);
static int edit_page_down(struct DrawState* state);