poe

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

чување 9a153076509f87fab625c53e084d2a7e6a96d1f8
родитељ 1ddcefc73d99604370a99398e82f41697068a102
Аутор: Страхиња Радић <contact@strahinja.org>
Датум:   Mon,  5 Jul 2021 15:06:52 +0200

First msgstr is modified on save (PO-Revision-Date and X-Generator); updated TODO

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

Diffstat:
MTODO | 13+++++++------
Mdraw.c | 4+++-
Mpo.c | 43++++++++++++++++++++++++++++++++++++++++++-
Mpoe.1.in | 9++++-----
Mutil.c | 26++++++++++++++++++++++++++
Mutil.h | 9++++++---
измењених датотека: 6, додавања: 88(+), брисања: 16(-)

diff --git a/TODO b/TODO @@ -4,19 +4,20 @@ [x] Line editing with cursor [ ] Previous/next word? - [~] .po file save + [x] .po file save [x] Save all read .po structure - [ ] Edit first msgid's msgstr + [x] Edit first msgid's msgstr (in saved file, not in memory) [ ] Yank/paste (entire current msgstr) + [ ] Copy msgid (only) to msgstr - [ ] Sort by flag/column? + [ ] Search (highlight=/, then navigate with next/prev) - [ ] Text selection? + [ ] Sort by flag/column? - [ ] Search (highlight, then navigate with next/prev) + [/] ~Text selection?~ - No need. - [ ] Multiple page help dialog? + [/] ~Multiple page help dialog?~ - There's already a man page. Legend diff --git a/draw.c b/draw.c @@ -22,7 +22,9 @@ static const char* help[] = { "C-F or PgDn - Go to next page", "G or End - Go to last entry", "f or C-Z - Toggle fuzzy flag", - "q or C-Q - Quit" + "q or C-Q - Quit", + "", + "See the manual (man poe) for full help." }; static const char* editbox_title = "Edit translation"; const char* errors[] = { diff --git a/po.c b/po.c @@ -2,10 +2,12 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <time.h> #include "po.h" #include "draw.h" #include "util.h" +#include "version.h" extern const char* flag_strings[]; @@ -387,6 +389,7 @@ save_file(const struct PoEntry* entries, const size_t msgid_count, backup_filename[len] = '~'; backup_filename[len+1] = 0; + while (current < entries + msgid_count) { if (current->comment_lines > 0) @@ -543,6 +546,22 @@ save_file(const struct PoEntry* entries, const size_t msgid_count, *current->msgstr); if (num_lines > 1) { + int first_entry = current == entries && + !current->msgid; + int seen_generator = 0; + char now[MAXDATEBUF]; + time_t t = time(NULL); + struct tm* now_tm = localtime(&t); + strftime(now, MAXDATEBUF, "%F %H:%M%z", + now_tm); + /* + *if (now_tm) + *{ + * free(now_tm); + * now_tm = NULL; + *} + */ + struct BufferLine* msgstr_split = split(*current->msgstr); struct BufferLine* pmsgstr_split = NULL; @@ -560,11 +579,33 @@ save_file(const struct PoEntry* entries, const size_t msgid_count, pmsgstr_split->text); unicode_string_to_u8(u8_msgstr, pmsgstr_split->text); - if (!(last && len == 0)) + + 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%s\"\n", u8_msgstr, last ? "" : "\\n"); } + if (!seen_generator) + fprintf(output, + "\"X-Generator: poe %s\"\n", + VERSION); for (size_t i = 0; i < num_lines; i++) { pmsgstr_split = msgstr_split + i; diff --git a/poe.1.in b/poe.1.in @@ -109,8 +109,9 @@ _ .sp 1 . .LP -When the info box is focused, arrow keys, C-B/C-F (PgUp/PgDn) and C-A/C-E -(Home/End) keys scroll the info box. +When the info box is focused, arrow keys, \fCC-B\fP/\fCC-F\fP +(\fCPgUp\fP/\fCPgDn\fP) and \fCC-A\fP/\fCC-E\fP (\fCHome\fP/\fCEnd\fP) keys +scroll the info box. . .SH "KNOWN LIMITATIONS" . @@ -124,8 +125,8 @@ library. See .IP "" 4 .UR https://\:github.com/\:nsf/\:termbox .UE -.IP . +.IP for more details. . .IP \(bu @@ -141,9 +142,7 @@ potential data loss under specific circumstances (loss of power during write). . .LP Bugs can be reported using the ticket tracker at: -. .UR https://\:todo.sr.ht/\:~strahinja/\:poe .UE -. .\" vim: set filetype=groff: diff --git a/util.c b/util.c @@ -122,6 +122,19 @@ u32_strlen(const uint32_t* s) return len; } +uint32_t* +u32_strstr(uint32_t* haystack, const uint32_t* needle) +{ + uint32_t* ph = haystack; + while (*ph) + { + if (u32_starts_with(ph, needle)) + return ph; + ph++; + } + return NULL; +} + size_t u32_strncpy(uint32_t* to, const uint32_t* from, size_t max) { @@ -269,6 +282,19 @@ starts_with(const char* s, const char* with) return *with == 0; } +int +u32_starts_with(const uint32_t* s, const uint32_t* with) +{ + while (*s && *s == *with) + { + if (*s != *with) + return 0; + s++; + with++; + } + return *with == 0; +} + void poe_log(const char* msg, ...) { diff --git a/util.h b/util.h @@ -15,16 +15,18 @@ enum { ERR_CANT_MOVE }; -#define MAXBUFLINE 4096 -#define MAXMSG 1024 -#define MAXPATH 1024 +#define MAXBUFLINE 4096 +#define MAXDATEBUF 80 #define MAXFLAGSBUF 3+1 +#define MAXMSG 1024 +#define MAXPATH 1024 size_t u8_string_to_unicode(uint32_t* us, const char* s); char* unicode_string_to_u8(char* s, const uint32_t* us); size_t u32_encode_tabs(uint32_t* s, size_t max); size_t u32_decode_tabs(uint32_t* s, size_t max); size_t u32_strlen(const uint32_t* s); +uint32_t* u32_strstr(uint32_t* haystack, const uint32_t* needle); 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); @@ -34,5 +36,6 @@ size_t u32_line_length(const uint32_t* s); size_t u8_lines_in_string(const char* s); size_t u32_lines_in_string(const uint32_t* s); int starts_with(const char* s, const char* with); +int u32_starts_with(const uint32_t* s, const uint32_t* with); void poe_log(const char* msg, ...);