~strahinja/poe

4c25f8d688c5b4955263ce6924b38b9a2633332d — Страхиња Радић 6 months ago 8378b97 v1.6.0
Add MATCH_MSGSTR_ENDING, PLURAL_STRING, -V

Signed-off-by: Страхиња Радић <contact@strahinja.org>
8 files changed, 84 insertions(+), 11 deletions(-)

M .gitignore
M TODO
A TODO.done
M config.def.h
M po.c
M poe.1.in
M poe.c
M util.c
M .gitignore => .gitignore +1 -0
@@ 11,6 11,7 @@
*.o
*.swp
*.did
cscope.out
nohup.out
*.err
*.gz

M TODO => TODO +4 -4
@@ 1,11 1,11 @@
TODO
====

[ ] Add config.h options:
	[ ] Enable/disable automatic addition of dot
	[ ] Enable/disable automatic addition of Plural-Forms
[x] Add config.h options:
	[x] Enable/disable automatic addition of dot
	[x] Enable/disable automatic addition of Plural-Forms

[ ] Automatic addition of Plural-Forms (configured as a literal in config.h)
[x] Automatic addition of Plural-Forms (configured as a literal in config.h)

[ ] Replace strn* -> strc*: like str[^n]*, but with configurable string
    ending character (for msgstr, which has multiple lines delimited

A TODO.done => TODO.done +5 -0
@@ 0,0 1,5 @@
Done todos
==========

[x] Replace "Unknown key (H for help)" with "Unknown key" where H is not
    applicable as help character

M config.def.h => config.def.h +9 -0
@@ 9,6 9,15 @@
static const char* backup_suffix = "~";
#endif /* PO_C_GLOBALS */

/* Correct the ending of msgstr to match msgid if ' ', '.' or '\\n' */
#define MATCH_MSGSTR_ENDING

/* Uncomment to insert this after Plural-Forms: in the first msgstr (only if
 * Plural-Forms isn't already present)
 * The plural string given here is for Serbian; adjust to match your language */
/*#define PLURAL_STRING "nplurals=3; plural=(n%10==1 && n%100!=11 ?" \
	" 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"*/

#define SAVE_WRAP_WIDTH	  70
#define WRAP_FIRST_MSGSTR 0
#define WARN_COUNT_DOTS	  0

M po.c => po.c +25 -0
@@ 409,7 409,9 @@ load_file(struct DrawState* dstate, long* lineno, long* col)
	struct PoEntry* entry	 = NULL;
	struct PoEntry* current	 = NULL;
	ParseState pstate	 = PS_NONE;
#ifndef PLURAL_STRING
	int has_plural_msgid	 = 0;
#endif

	dstate->msgid_size = 0;
	if (!newchunk)


@@ 441,8 443,10 @@ load_file(struct DrawState* dstate, long* lineno, long* col)
		result = parse_po_line(input_line, dstate, &entry, &pstate, col,
			&msgstr_index);

#ifndef PLURAL_STRING
		if (entry && entry->msgid_plural)
			has_plural_msgid = 1;
#endif

		if (result == PARSE_ERR_NONE)
		{


@@ 476,8 480,10 @@ load_file(struct DrawState* dstate, long* lineno, long* col)
		else if (entry->comment_lines > 0)
			/* obsolete entry */
			entry->obsolete = 1;
#ifndef PLURAL_STRING
		if (has_plural_msgid && !dstate->entries->plural_forms)
			strcpy(dstate->error, errors[ERR_NO_PLURAL_FORMS]);
#endif
	}

	/* file has < PO_DETECTION_LINES */


@@ 768,6 774,9 @@ save_obsolete_check:
		{
			const uint32_t* pumsgstr = *current->msgstr;
			int seen_generator	 = 0;
#ifdef PLURAL_STRING
			int seen_plural_forms	 = 0;
#endif
			char now[MAXDATEBUF];
			time_t t	  = time(NULL);
			struct tm* now_tm = localtime(&t);


@@ 812,10 821,26 @@ save_obsolete_check:
						"\"X-Generator: poe %s\\n\"\n",
						VERSION);
				}
#ifdef PLURAL_STRING
				else if (first_entry
					&& starts_with(u8_msgstr,
						"Plural-Forms: "))
				{
					seen_plural_forms = 1;
					fprintf(output,
						"\"Plural-Forms: %s\\n\"\n",
						PLURAL_STRING);
				}
#endif
				else
					fprintf(output, "\"%s\"\n", u8_msgstr);
				free(u8_msgstr);
			}
#ifdef PLURAL_STRING
			if (first_entry && !seen_plural_forms)
				fprintf(output, "\"Plural-Forms: %s\\n\"\n",
					PLURAL_STRING);
#endif
			if (first_entry && !seen_generator)
				fprintf(output, "\"X-Generator: poe %s\\n\"\n",
					VERSION);

M poe.1.in => poe.1.in +12 -6
@@ 33,6 33,10 @@ poe \- .po file editor
.YS
.
.SY poe
.OP "\-V \fR|\fP \-\-full\-version"
.YS
.
.SY poe
.OP "\-v \fR|\fP \-\-version"
.YS
.


@@ 177,14 181,16 @@ has some rudimentary checks of the translated messages built in. First, when
saving changes in the edit box, if the msgid has a newline character
(\fC\\n\fR), a dot (\fC.\fR) or a space (\fC\~\fR) at the end, and the
corresponding msgstr doesn't, msgstr being saved will have its ending character
made to match the one from the msgid.
made to match the one from the msgid. This feature can be disabled by commenting
out the \fCMATCH_MSGSTR_ENDING\fR feature flag.
.
.PP
Second, if the numbers of newline characters (\fC\\n\fR) in msgid and msgstr
don't match, msgstr will be shown in a different color on the main screen. If
the number of newlines was intended, you can simply ignore this warning.
Otherwise, it can be useful to detect unwanted discrepancies in formatting
between the original message and the translation.
Second, if the numbers of newline characters (\fC\\n\fR), or, additionally, dots
when \fCWARN_COUNT_DOTS\fR is set, in msgid and msgstr don't match, msgstr will
be shown in a different color on the main screen. If the number of newlines was
intended, you can simply ignore this warning.  Otherwise, it can be useful to
detect unwanted discrepancies in formatting between the original message and the
translation.
.
.SH AUTHOR
.

M poe.c => poe.c +26 -1
@@ 2065,7 2065,8 @@ main(int argc, char** argv)

	if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))
	{
		printf("Usage: %s [-h|--help] [-v|--version] [filename.po]\n",
		printf("Usage: %s [-h|--help] [-v|--version] "
			"[-V|--full-version] [filename.po]\n",
			program_name);
		return 0;
	}


@@ 2074,6 2075,30 @@ main(int argc, char** argv)
		printf("%s %s, committed on %s\n", program_name, VERSION, DATE);
		return 0;
	}
	else if (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--full-version"))
	{
		printf("%s %s, committed on %s\n", program_name, VERSION, DATE);
		printf("Features set in config.h:\n");
#ifdef CREATE_BACKUPS
		printf("  CREATE_BACKUPS:\tset\n");
#else
		printf("  CREATE_BACKUPS:\tunset\n");
#endif
#ifdef MATCH_MSGSTR_ENDING
		printf("  MATCH_MSGSTR_ENDING:\tset\n");
#else
		printf("  MATCH_MSGSTR_ENDING:\tunset\n");
#endif
#ifdef PLURAL_STRING
		printf("  PLURAL_STRING:\t\"%s\"\n", PLURAL_STRING);
#else
		printf("  PLURAL_STRING:\tunset\n");
#endif
		printf("  SAVE_WRAP_WIDTH:\t%d\n", SAVE_WRAP_WIDTH);
		printf("  WRAP_FIRST_MSGSTR:\t%d\n", WRAP_FIRST_MSGSTR);
		printf("  WARN_COUNT_DOTS:\t%d\n", WARN_COUNT_DOTS);
		return 0;
	}
	else
	{
		strncpy(filename, argv[1], MAXPATH - 1);

M util.c => util.c +2 -0
@@ 84,6 84,7 @@ u32_match_msgid_ending(const uint32_t* msgid, uint32_t* msgstr, size_t max)
			buf[buf_len]	 = 0;
		}
	}
#ifdef MATCH_MSGSTR_ENDING
	else if (msgid_len > 0
		&& u32_strstr((uint32_t*)L" .", msgid + msgid_len - 1))
	{


@@ 106,6 107,7 @@ u32_match_msgid_ending(const uint32_t* msgid, uint32_t* msgstr, size_t max)
		buf_len--;
		buf[buf_len] = 0;
	}
#endif

	u32_strncpy(msgstr, buf, max);