* Interoperability with automake-1.10.
+* msgmerge has a new option --previous that has the effect of saving the
+ previous msgid of message when making them fuzzy. These previous msgids are
+ stored in the resulting PO file, using a pseudo-comment syntax like this:
+
+ #, fuzzy
+ #| msgid "too many arguments"
+ msgid "too few arguments"
+ msgstr "trop d'arguments"
+
+ The translator then only needs to compare the previous and the current
+ msgid ("too many arguments" and "too few arguments"), and infer which
+ parts of the translation she needs to change.
+
+ msgattrib has a new option --clear-previous that removes these #| lines.
+
* msgmerge is faster now on CPUs with multiple execution units, if compiled
with GCC 4.2 or newer.
+2006-10-03 Bruno Haible <bruno@clisp.org>
+
+ * gettext.texi (PO Files): Document the "previous msgid" syntax.
+ * msgmerge.texi: Document the --previous option.
+ * msgattrib.texi: Document the --clear-previous option.
+
2006-10-03 Bruno Haible <bruno@clisp.org>
* msgcmp.texi: Document --use-fuzzy and --use-untranslated options.
#. @var{extracted-comments}
#: @var{reference}@dots{}
#, @var{flag}@dots{}
+#| msgid @var{previous-untranslated-string}
msgid @var{untranslated-string}
msgstr @var{translated-string}
@end example
because the @code{xgettext} program extracts them from the program's
source code. Comment lines starting with @code{#:} contain references to
the program's source code. Comment lines starting with @code{#,} contain
-flags; more about these below.
+flags; more about these below. Comment lines starting with @code{#|}
+contain the previous untranslated string for which the translator gave
+a translation.
+
All comments, of either kind, are optional.
@kwindex msgid
#. @var{extracted-comments}
#: @var{reference}@dots{}
#, @var{flag}@dots{}
+#| msgctxt @var{previous-context}
+#| msgid @var{previous-untranslated-string}
msgctxt @var{context}
msgid @var{untranslated-string}
msgstr @var{translated-string}
#. @var{extracted-comments}
#: @var{reference}@dots{}
#, @var{flag}@dots{}
+#| msgid @var{previous-untranslated-string-singular}
+#| msgid_plural @var{previous-untranslated-string-plural}
msgid @var{untranslated-string-singular}
msgid_plural @var{untranslated-string-plural}
msgstr[0] @var{translated-string-case-0}
Here also, a @code{msgctxt} context can be specified before @code{msgid},
like above.
+The @var{previous-untranslated-string} is optionally inserted by the
+@code{msgmerge} program, at the same time when it marks a message fuzzy.
+It helps the translator to see which changes were done by the developers
+on the @var{untranslated-string}.
+
It happens that some lines, usually whitespace or comments, follow the
very last entry of a PO file. Such lines are not part of any entry,
and will be dropped when the PO file is processed by the tools, or may
@opindex --clear-obsolete@r{, @code{msgattrib} option}
Set all messages non-obsolete.
+@item --clear-previous
+@opindex --clear-previous@r{, @code{msgattrib} option}
+Remove the ``previous msgid'' (@samp{#|}) comments from all messages.
+
@item --only-file=@var{file}
@opindex --only-file@r{, @code{msgattrib} option}
Limit the attribute changes to entries that are listed in @var{file}.
@opindex --no-fuzzy-matching@r{, @code{msgmerge} option}
Do not use fuzzy matching when an exact match is not found. This may speed
up the operation considerably.
+
+@item --previous
+@opindex --previous@r{, @code{msgmerge} option}
+Keep the previous msgids of translated messages, marked with @samp{#|}, when
+adding the fuzzy marker to such messages.
@end table
@subsection Input file syntax
+2006-10-03 Bruno Haible <bruno@clisp.org>
+
+ * message.h (struct message_ty): New fields prev_msgctxt, prev_msgid,
+ prev_msgid_plural.
+ * message.c (message_alloc): Initialize the prev_msg* fields.
+ (message_free): Free the prev_msg* fields.
+ (message_copy): Copy the prev_msg* fields.
+ * msgl-ascii.c (is_ascii_message): Consider also the prev_msg* fields.
+ * msgl-cat.c (catenate_msgdomain_list): Copy the prev_msg* fields if
+ a message is copied, not merged.
+ * msgl-equal.c (message_equal): Consider also the prev_msg* fields.
+ * msgl-iconv.c (convert_prev_msgid): New function.
+ (iconv_message_list): Call it.
+ iconvable_prev_msgid): New function.
+ (is_message_list_iconvable): Call it.
+
+ * po-lex.c (po_lex_previous): New variable.
+ (lex_start, lex_end): Reset it.
+ (keyword_p): Test it. New return values PREV_MSGID, PREV_MSGID_PLURAL,
+ PREV_MSGCTXT.
+ (po_gram_lex): Recognize #| and #~| syntax. New return value
+ PREV_STRING.
+ * po-gram-gen.y (do_callback_message): Add prev_msgctxt, prev_msgid,
+ prev_msgid_plural arguments.
+ (free_message_intro): New macro.
+ (PREV_MSGCTXT, PREV_MSGID, PREV_MSGID_PLURAL, PREV_STRING): New tokens.
+ (prev, message_intro): New structures.
+ (po_file): Renamed from msgfmt.
+ (message): Pass prev_* fields around. Call free_message_intro.
+ (message_intro, prev): New rules.
+ (msg_intro): Renamed from message_intro.
+ (prev_msg_intro, prev_msgid_pluralform, prev_string_list): New rules.
+ * read-po-abstract.h (struct abstract_po_reader_class_ty): Add
+ prev_msgctxt, prev_msgid, prev_msgid_plural arguments to the
+ 'directive_message' method.
+ (po_callback_message): Add prev_msgctxt, prev_msgid,
+ prev_msgid_plural arguments.
+ * read-po-abstract.c (call_directive_message, po_callback_message): Add
+ prev_msgctxt, prev_msgid, prev_msgid_plural arguments.
+ * read-po.h (struct default_po_reader_class_ty): Add prev_msgctxt,
+ prev_msgid, prev_msgid_plural arguments to the 'add_message' method.
+ (default_directive_message, default_add_message): Add prev_msgctxt,
+ prev_msgid, prev_msgid_plural arguments.
+ * read-po.c (call_add_message, default_directive_message,
+ default_add_message): Add prev_msgctxt, prev_msgid, prev_msgid_plural
+ arguments.
+ * read-properties.c (properties_parse): Update.
+ * read-stringtable.c (stringtable_parse): Update.
+ * xgettext.c (exclude_directive_message): Add prev_msgctxt, prev_msgid,
+ prev_msgid_plural arguments.
+ * x-po.c (extract_add_message): Add prev_msgctxt, prev_msgid,
+ prev_msgid_plural arguments.
+
+ * write-po.c (wrap): Add extra_indent argument.
+ (message_print, message_print_obsolete): Print the prev_msgctxt,
+ prev_msgid, prev_msgid_plural fields. Compute an extra_indent.
+
+ * msgmerge.c (keep_previous): New variable.
+ (long_options): Add --previous option.
+ (main): Handle it.
+ (usage): Document --previous option.
+ (message_merge): Add force_fuzzy argument. Set the new message's
+ prev_msg* fields.
+ (match_domain): Update.
+ * msgattrib.c (REMOVE_PREV): New enum item.
+ (long_options): Add --clear-previous option.
+ (main): Handle it.
+ (usage): Document --clear-previous option.
+ (process_message_list): Handle REMOVE_PREV.
+ * msgfmt.c (msgfmt_add_message): Add prev_msgctxt, prev_msgid,
+ prev_msgid_plural arguments.
+ * gettext-po.c (po_message_prev_msgctxt, po_message_set_prev_msgctxt,
+ po_message_prev_msgid, po_message_set_prev_msgid,
+ po_message_prev_msgid_plural, po_message_set_prev_msgid_plural): New
+ functions.
+
2006-10-03 Bruno Haible <bruno@clisp.org>
* msgmerge.c (definitions_init): Fix initialization of fresh_lock.
/* Public API for GNU gettext PO files.
- Copyright (C) 2003-2005 Free Software Foundation, Inc.
+ Copyright (C) 2003-2006 Free Software Foundation, Inc.
Written by Bruno Haible <bruno@clisp.org>, 2003.
This program is free software; you can redistribute it and/or modify
}
+/* Return the previous context of a message, or NULL for none. */
+
+const char *
+po_message_prev_msgctxt (po_message_t message)
+{
+ message_ty *mp = (message_ty *) message;
+
+ return mp->prev_msgctxt;
+}
+
+
+/* Change the previous context of a message. NULL is allowed. */
+
+void
+po_message_set_prev_msgctxt (po_message_t message, const char *prev_msgctxt)
+{
+ message_ty *mp = (message_ty *) message;
+
+ if (prev_msgctxt != mp->prev_msgctxt)
+ {
+ char *old_prev_msgctxt = (char *) mp->prev_msgctxt;
+
+ mp->prev_msgctxt = (prev_msgctxt != NULL ? xstrdup (prev_msgctxt) : NULL);
+ if (old_prev_msgctxt != NULL)
+ free (old_prev_msgctxt);
+ }
+}
+
+
+/* Return the previous msgid (untranslated English string) of a message, or
+ NULL for none. */
+
+const char *
+po_message_prev_msgid (po_message_t message)
+{
+ message_ty *mp = (message_ty *) message;
+
+ return mp->prev_msgid;
+}
+
+
+/* Change the previous msgid (untranslated English string) of a message.
+ NULL is allowed. */
+
+void
+po_message_set_prev_msgid (po_message_t message, const char *prev_msgid)
+{
+ message_ty *mp = (message_ty *) message;
+
+ if (prev_msgid != mp->prev_msgid)
+ {
+ char *old_prev_msgid = (char *) mp->prev_msgid;
+
+ mp->prev_msgid = (prev_msgid != NULL ? xstrdup (prev_msgid) : NULL);
+ if (old_prev_msgid != NULL)
+ free (old_prev_msgid);
+ }
+}
+
+
+/* Return the previous msgid_plural (untranslated English plural string) of a
+ message, or NULL for none. */
+
+const char *
+po_message_prev_msgid_plural (po_message_t message)
+{
+ message_ty *mp = (message_ty *) message;
+
+ return mp->prev_msgid_plural;
+}
+
+
+/* Change the previous msgid_plural (untranslated English plural string) of a
+ message. NULL is allowed. */
+
+void
+po_message_set_prev_msgid_plural (po_message_t message, const char *prev_msgid_plural)
+{
+ message_ty *mp = (message_ty *) message;
+
+ if (prev_msgid_plural != mp->prev_msgid_plural)
+ {
+ char *old_prev_msgid_plural = (char *) mp->prev_msgid_plural;
+
+ mp->prev_msgid_plural =
+ (prev_msgid_plural != NULL ? xstrdup (prev_msgid_plural) : NULL);
+ if (old_prev_msgid_plural != NULL)
+ free (old_prev_msgid_plural);
+ }
+}
+
+
/* Return true if the message is marked obsolete. */
int
for (i = 0; i < NFORMATS; i++)
mp->is_format[i] = undecided;
mp->do_wrap = undecided;
+ mp->prev_msgctxt = NULL;
+ mp->prev_msgid = NULL;
+ mp->prev_msgid_plural = NULL;
mp->used = 0;
mp->obsolete = false;
return mp;
free ((char *) mp->filepos[j].file_name);
if (mp->filepos != NULL)
free (mp->filepos);
+ if (mp->prev_msgctxt != NULL)
+ free ((char *) mp->prev_msgctxt);
+ if (mp->prev_msgid != NULL)
+ free ((char *) mp->prev_msgid);
+ if (mp->prev_msgid_plural != NULL)
+ free ((char *) mp->prev_msgid_plural);
free (mp);
}
lex_pos_ty *pp = &mp->filepos[j];
message_comment_filepos (result, pp->file_name, pp->line_number);
}
+ result->prev_msgctxt =
+ (mp->prev_msgctxt != NULL ? xstrdup (mp->prev_msgctxt) : NULL);
+ result->prev_msgid =
+ (mp->prev_msgid != NULL ? xstrdup (mp->prev_msgid) : NULL);
+ result->prev_msgid_plural =
+ (mp->prev_msgid_plural != NULL ? xstrdup (mp->prev_msgid_plural) : NULL);
return result;
}
/* Do we want the string to be wrapped in the emitted PO file? */
enum is_wrap do_wrap;
+ /* The prev_msgctxt, prev_msgid and prev_msgid_plural strings appearing
+ before the message, if present. Generated by msgmerge. */
+ const char *prev_msgctxt;
+ const char *prev_msgid;
+ const char *prev_msgid_plural;
+
/* If set the message is obsolete and while writing out it should be
commented out. */
bool obsolete;
SET_FUZZY = 1 << 0,
RESET_FUZZY = 1 << 1,
SET_OBSOLETE = 1 << 2,
- RESET_OBSOLETE = 1 << 3
+ RESET_OBSOLETE = 1 << 3,
+ REMOVE_PREV = 1 << 4
};
static int to_change;
{ "add-location", no_argument, &line_comment, 1 },
{ "clear-fuzzy", no_argument, NULL, CHAR_MAX + 8 },
{ "clear-obsolete", no_argument, NULL, CHAR_MAX + 10 },
+ { "clear-previous", no_argument, NULL, CHAR_MAX + 18 },
{ "directory", required_argument, NULL, 'D' },
{ "escape", no_argument, NULL, 'E' },
{ "force-po", no_argument, &force_po, 1 },
message_print_syntax_stringtable ();
break;
+ case CHAR_MAX + 18: /* --clear-previous */
+ to_change |= REMOVE_PREV;
+ break;
+
default:
usage (EXIT_FAILURE);
/* NOTREACHED */
printf (_("\
--clear-obsolete set all messages non-obsolete\n"));
printf (_("\
+ --clear-previous remove the \"previous msgid\" from all messages\n"));
+ printf (_("\
--only-file=FILE.po manipulate only entries listed in FILE.po\n"));
printf (_("\
--ignore-file=FILE.po manipulate only entries not listed in FILE.po\n"));
mp->obsolete = true;
if (to_change & RESET_OBSOLETE)
mp->obsolete = false;
+ if (to_change & REMOVE_PREV)
+ {
+ mp->prev_msgctxt = NULL;
+ mp->prev_msgid = NULL;
+ mp->prev_msgid_plural = NULL;
+ }
}
}
}
char *msgid_plural,
char *msgstr, size_t msgstr_len,
lex_pos_ty *msgstr_pos,
+ char *prev_msgctxt,
+ char *prev_msgid,
+ char *prev_msgid_plural,
bool force_fuzzy, bool obsolete)
{
/* Check whether already a domain is specified. If not, use default
/* Invoke superclass method. */
default_add_message (this, msgctxt, msgid, msgid_pos, msgid_plural,
- msgstr, msgstr_len, msgstr_pos, force_fuzzy, obsolete);
+ msgstr, msgstr_len, msgstr_pos,
+ prev_msgctxt, prev_msgid, prev_msgid_plural,
+ force_fuzzy, obsolete);
}
/* Message list test for ASCII character set.
- Copyright (C) 2001-2002, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2001-2002, 2005-2006 Free Software Foundation, Inc.
Written by Bruno Haible <haible@clisp.cons.org>, 2001.
This program is free software; you can redistribute it and/or modify
if (mp->msgctxt != NULL && !is_ascii_string (mp->msgctxt))
return false;
+ /* Likewise for the prev_* fields. */
+ if (mp->prev_msgctxt != NULL && !is_ascii_string (mp->prev_msgctxt))
+ return false;
+ if (mp->prev_msgid != NULL && !is_ascii_string (mp->prev_msgid))
+ return false;
+ if (mp->prev_msgid_plural != NULL && !is_ascii_string (mp->prev_msgid_plural))
+ return false;
+
return true;
}
for (i = 0; i < NFORMATS; i++)
tmp->is_format[i] = mp->is_format[i];
tmp->do_wrap = mp->do_wrap;
+ tmp->prev_msgctxt = mp->prev_msgctxt;
+ tmp->prev_msgid = mp->prev_msgid;
+ tmp->prev_msgid_plural = mp->prev_msgid_plural;
tmp->obsolete = mp->obsolete;
}
else if (msgcomm_mode)
tmp->msgstr_len = mp->msgstr_len;
tmp->pos = mp->pos;
tmp->is_fuzzy = mp->is_fuzzy;
+ tmp->prev_msgctxt = mp->prev_msgctxt;
+ tmp->prev_msgid = mp->prev_msgid;
+ tmp->prev_msgid_plural = mp->prev_msgid_plural;
}
if (mp->comment && tmp->comment == NULL)
for (i = 0; i < mp->comment->nitems; i++)
tmp->is_format[i] = no;
if (mp->do_wrap == no)
tmp->do_wrap = no;
+ /* Don't fill tmp->prev_msgid in this case. */
if (!mp->obsolete)
tmp->obsolete = false;
}
/* Message list test for equality.
- Copyright (C) 2001-2002, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2001-2002, 2005-2006 Free Software Foundation, Inc.
Written by Bruno Haible <haible@clisp.cons.org>, 2001.
This program is free software; you can redistribute it and/or modify
if (mp1->is_format[i] != mp2->is_format[i])
return false;
+ if (!(mp1->prev_msgctxt != NULL
+ ? mp2->prev_msgctxt != NULL
+ && strcmp (mp1->prev_msgctxt, mp2->prev_msgctxt) == 0
+ : mp2->prev_msgctxt == NULL))
+ return false;
+
+ if (!(mp1->prev_msgid != NULL
+ ? mp2->prev_msgid != NULL
+ && strcmp (mp1->prev_msgid, mp2->prev_msgid) == 0
+ : mp2->prev_msgid == NULL))
+ return false;
+
+ if (!(mp1->prev_msgid_plural != NULL
+ ? mp2->prev_msgid_plural != NULL
+ && strcmp (mp1->prev_msgid_plural, mp2->prev_msgid_plural) == 0
+ : mp2->prev_msgid_plural == NULL))
+ return false;
+
if (mp1->obsolete != mp2->obsolete)
return false;
slp->item[i] = convert_string (cd, slp->item[i], context);
}
+static void
+convert_prev_msgid (iconv_t cd, message_ty *mp,
+ const struct conversion_context* context)
+{
+ if (mp->prev_msgctxt != NULL)
+ mp->prev_msgctxt = convert_string (cd, mp->prev_msgctxt, context);
+ if (mp->prev_msgid != NULL)
+ mp->prev_msgid = convert_string (cd, mp->prev_msgid, context);
+ if (mp->prev_msgid_plural != NULL)
+ mp->prev_msgid_plural = convert_string (cd, mp->prev_msgid_plural, context);
+}
+
static void
convert_msgid (iconv_t cd, message_ty *mp,
const struct conversion_context* context)
context.message = mp;
convert_string_list (cd, mp->comment, &context);
convert_string_list (cd, mp->comment_dot, &context);
+ convert_prev_msgid (cd, mp, &context);
convert_msgid (cd, mp, &context);
convert_msgstr (cd, mp, &context);
}
return true;
}
+static bool
+iconvable_prev_msgid (iconv_t cd, message_ty *mp)
+{
+ if (mp->prev_msgctxt != NULL)
+ if (!iconvable_string (cd, mp->prev_msgctxt))
+ return false;
+ if (mp->prev_msgid != NULL)
+ if (!iconvable_string (cd, mp->prev_msgid))
+ return false;
+ if (mp->msgid_plural != NULL)
+ if (!iconvable_string (cd, mp->prev_msgid_plural))
+ return false;
+ return true;
+}
+
static bool
iconvable_msgid (iconv_t cd, message_ty *mp)
{
if (!(iconvable_string_list (cd, mp->comment)
&& iconvable_string_list (cd, mp->comment_dot)
+ && iconvable_prev_msgid (cd, mp)
&& iconvable_msgid (cd, mp)
&& iconvable_msgstr (cd, mp)))
return false;
/* Determines whether to use fuzzy matching. */
static bool use_fuzzy_matching = true;
+/* Determines whether to keep old msgids as previous msgids. */
+static bool keep_previous = false;
+
/* List of user-specified compendiums. */
static message_list_list_ty *compendiums;
{ "no-location", no_argument, &line_comment, 0 },
{ "no-wrap", no_argument, NULL, CHAR_MAX + 4 },
{ "output-file", required_argument, NULL, 'o' },
+ { "previous", no_argument, NULL, CHAR_MAX + 7 },
{ "properties-input", no_argument, NULL, 'P' },
{ "properties-output", no_argument, NULL, 'p' },
{ "quiet", no_argument, NULL, 'q' },
message_print_syntax_stringtable ();
break;
+ case CHAR_MAX + 7: /* --previous */
+ keep_previous = true;
+ break;
+
default:
usage (EXIT_FAILURE);
break;
-m, --multi-domain apply ref.pot to each of the domains in def.po\n"));
printf (_("\
-N, --no-fuzzy-matching do not use fuzzy matching\n"));
+ printf (_("\
+ --previous keep previous msgids of translated messages\n"));
printf ("\n");
printf (_("\
Input file syntax:\n"));
static message_ty *
-message_merge (message_ty *def, message_ty *ref)
+message_merge (message_ty *def, message_ty *ref, bool force_fuzzy)
{
const char *msgstr;
size_t msgstr_len;
+ const char *prev_msgctxt;
+ const char *prev_msgid;
+ const char *prev_msgid_plural;
message_ty *result;
size_t j, i;
msgstr = cp;
msgstr_len = strlen (cp) + 1;
+
+ prev_msgctxt = NULL;
+ prev_msgid = NULL;
+ prev_msgid_plural = NULL;
}
else
{
msgstr = def->msgstr;
msgstr_len = def->msgstr_len;
+
+ if (def->is_fuzzy)
+ {
+ prev_msgctxt = def->prev_msgctxt;
+ prev_msgid = def->prev_msgid;
+ prev_msgid_plural = def->prev_msgid_plural;
+ }
+ else
+ {
+ prev_msgctxt = def->msgctxt;
+ prev_msgid = def->msgid;
+ prev_msgid_plural = def->msgid_plural;
+ }
}
result = message_alloc (ref->msgctxt != NULL ? xstrdup (ref->msgctxt) : NULL,
/* The flags are mixed in a special way. Some informations come
from the reference message (such as format/no-format), others
come from the definition file (fuzzy or not). */
- result->is_fuzzy = def->is_fuzzy;
+ result->is_fuzzy = def->is_fuzzy | force_fuzzy;
for (i = 0; i < NFORMATS; i++)
{
result->do_wrap = ref->do_wrap;
+ /* Insert previous msgid, commented out with "#|".
+ Do so only when --previous is specified, for backward compatibility.
+ Since the "previous msgid" represents the original msgid that led to
+ the current msgstr,
+ - we can omit it if the resulting message is not fuzzy,
+ - otherwise, if the corresponding message from the definition file
+ was translated (not fuzzy), we use that message's msgid,
+ - otherwise, we use that message's prev_msgid. */
+ if (keep_previous && result->is_fuzzy)
+ {
+ result->prev_msgctxt = prev_msgctxt;
+ result->prev_msgid = prev_msgid;
+ result->prev_msgid_plural = prev_msgid_plural;
+ }
+
/* Take the file position comments from the reference file, as they
are generated by xgettext. Any in the definition file are old ones
collected by previous runs of xgettext and msgmerge. */
#: comments from the reference, take the # comments from
the definition, take the msgstr from the definition. Add
this merged entry to the output message list. */
- message_ty *mp = message_merge (defmsg, refmsg);
+ message_ty *mp = message_merge (defmsg, refmsg, false);
message_list_append (resultmlp, mp);
#: comments from the reference, take the # comments from
the definition, take the msgstr from the definition. Add
this merged entry to the output message list. */
- mp = message_merge (defmsg, refmsg);
-
- mp->is_fuzzy = true;
+ mp = message_merge (defmsg, refmsg, true);
message_list_append (resultmlp, mp);
/* GNU gettext - internationalization aids
- Copyright (C) 1995-1996, 1998, 2000-2001, 2003, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1995-1996, 1998, 2000-2001, 2003, 2005-2006 Free Software Foundation, Inc.
This file was written by Peter Miller <pmiller@agso.gov.au>
do_callback_message (char *msgctxt,
char *msgid, lex_pos_ty *msgid_pos, char *msgid_plural,
char *msgstr, size_t msgstr_len, lex_pos_ty *msgstr_pos,
+ char *prev_msgctxt,
+ char *prev_msgid, char *prev_msgid_plural,
bool obsolete)
{
/* Test for header entry. Ignore fuzziness of the header entry. */
po_callback_message (msgctxt,
msgid, msgid_pos, msgid_plural,
msgstr, msgstr_len, msgstr_pos,
+ prev_msgctxt, prev_msgid, prev_msgid_plural,
false, obsolete);
}
+#define free_message_intro(value) \
+ if ((value).prev_ctxt != NULL) \
+ free ((value).prev_ctxt); \
+ if ((value).prev_id != NULL) \
+ free ((value).prev_id); \
+ if ((value).prev_id_plural != NULL) \
+ free ((value).prev_id_plural); \
+ if ((value).ctxt != NULL) \
+ free ((value).ctxt);
+
%}
%token COMMENT
%token DOMAIN
%token JUNK
+%token PREV_MSGCTXT
+%token PREV_MSGID
+%token PREV_MSGID_PLURAL
+%token PREV_STRING
%token MSGCTXT
%token MSGID
%token MSGID_PLURAL
struct { string_list_ty stringlist; lex_pos_ty pos; bool obsolete; } stringlist;
struct { long number; lex_pos_ty pos; bool obsolete; } number;
struct { lex_pos_ty pos; bool obsolete; } pos;
+ struct { char *ctxt; char *id; char *id_plural; lex_pos_ty pos; bool obsolete; } prev;
+ struct { char *prev_ctxt; char *prev_id; char *prev_id_plural; char *ctxt; lex_pos_ty pos; bool obsolete; } message_intro;
struct { struct msgstr_def rhs; lex_pos_ty pos; bool obsolete; } rhs;
}
-%type <string> STRING COMMENT NAME message_intro msgid_pluralform
-%type <stringlist> string_list
+%type <string> STRING PREV_STRING COMMENT NAME
+ msg_intro prev_msg_intro msgid_pluralform prev_msgid_pluralform
+%type <stringlist> string_list prev_string_list
%type <number> NUMBER
-%type <pos> DOMAIN MSGCTXT MSGID MSGID_PLURAL MSGSTR '[' ']'
+%type <pos> DOMAIN
+ PREV_MSGCTXT PREV_MSGID PREV_MSGID_PLURAL
+ MSGCTXT MSGID MSGID_PLURAL MSGSTR '[' ']'
+%type <prev> prev
+%type <message_intro> message_intro
%type <rhs> pluralform pluralform_list
%right MSGSTR
%%
-msgfmt
+po_file
: /* empty */
- | msgfmt comment
- | msgfmt domain
- | msgfmt message
- | msgfmt error
+ | po_file comment
+ | po_file domain
+ | po_file message
+ | po_file error
+ ;
+
+
+comment
+ : COMMENT
+ {
+ po_callback_comment_dispatcher ($1.string);
+ }
;
+
domain
: DOMAIN STRING
{
}
;
+
message
: message_intro string_list MSGSTR string_list
{
check_obsolete ($1, $3);
check_obsolete ($1, $4);
if (!$1.obsolete || pass_obsolete_entries)
- do_callback_message ($1.string, string2, &$1.pos, NULL,
+ do_callback_message ($1.ctxt, string2, &$1.pos, NULL,
string4, strlen (string4) + 1, &$3.pos,
+ $1.prev_ctxt,
+ $1.prev_id, $1.prev_id_plural,
$1.obsolete);
else
{
+ free_message_intro ($1);
free (string2);
free (string4);
}
check_obsolete ($1, $3);
check_obsolete ($1, $4);
if (!$1.obsolete || pass_obsolete_entries)
- do_callback_message ($1.string, string2, &$1.pos, $3.string,
+ do_callback_message ($1.ctxt, string2, &$1.pos, $3.string,
$4.rhs.msgstr, $4.rhs.msgstr_len, &$4.pos,
+ $1.prev_ctxt,
+ $1.prev_id, $1.prev_id_plural,
$1.obsolete);
else
{
+ free_message_intro ($1);
free (string2);
free ($3.string);
free ($4.rhs.msgstr);
check_obsolete ($1, $2);
check_obsolete ($1, $3);
po_gram_error_at_line (&$1.pos, _("missing `msgstr[]' section"));
+ free_message_intro ($1);
string_list_destroy (&$2.stringlist);
free ($3.string);
}
check_obsolete ($1, $2);
check_obsolete ($1, $3);
po_gram_error_at_line (&$1.pos, _("missing `msgid_plural' section"));
+ free_message_intro ($1);
string_list_destroy (&$2.stringlist);
free ($3.rhs.msgstr);
}
{
check_obsolete ($1, $2);
po_gram_error_at_line (&$1.pos, _("missing `msgstr' section"));
+ free_message_intro ($1);
string_list_destroy (&$2.stringlist);
}
;
+
message_intro
+ : msg_intro
+ {
+ $$.prev_ctxt = NULL;
+ $$.prev_id = NULL;
+ $$.prev_id_plural = NULL;
+ $$.ctxt = $1.string;
+ $$.pos = $1.pos;
+ $$.obsolete = $1.obsolete;
+ }
+ | prev msg_intro
+ {
+ check_obsolete ($1, $2);
+ $$.prev_ctxt = $1.ctxt;
+ $$.prev_id = $1.id;
+ $$.prev_id_plural = $1.id_plural;
+ $$.ctxt = $2.string;
+ $$.pos = $2.pos;
+ $$.obsolete = $2.obsolete;
+ }
+ ;
+
+
+prev
+ : prev_msg_intro prev_string_list
+ {
+ check_obsolete ($1, $2);
+ $$.ctxt = $1.string;
+ $$.id = string_list_concat_destroy (&$2.stringlist);
+ $$.id_plural = NULL;
+ $$.pos = $1.pos;
+ $$.obsolete = $1.obsolete;
+ }
+ | prev_msg_intro prev_string_list prev_msgid_pluralform
+ {
+ check_obsolete ($1, $2);
+ check_obsolete ($1, $3);
+ $$.ctxt = $1.string;
+ $$.id = string_list_concat_destroy (&$2.stringlist);
+ $$.id_plural = $3.string;
+ $$.pos = $1.pos;
+ $$.obsolete = $1.obsolete;
+ }
+ ;
+
+
+msg_intro
: MSGID
{
$$.string = NULL;
}
;
+prev_msg_intro
+ : PREV_MSGID
+ {
+ $$.string = NULL;
+ $$.pos = $1.pos;
+ $$.obsolete = $1.obsolete;
+ }
+ | PREV_MSGCTXT prev_string_list PREV_MSGID
+ {
+ check_obsolete ($1, $2);
+ check_obsolete ($1, $3);
+ $$.string = string_list_concat_destroy (&$2.stringlist);
+ $$.pos = $3.pos;
+ $$.obsolete = $3.obsolete;
+ }
+ ;
+
+
msgid_pluralform
: MSGID_PLURAL string_list
{
}
;
+prev_msgid_pluralform
+ : PREV_MSGID_PLURAL prev_string_list
+ {
+ check_obsolete ($1, $2);
+ $$.string = string_list_concat_destroy (&$2.stringlist);
+ $$.pos = $1.pos;
+ $$.obsolete = $1.obsolete;
+ }
+ ;
+
+
pluralform_list
: pluralform
{
}
;
+
string_list
: STRING
{
}
;
-comment
- : COMMENT
+prev_string_list
+ : PREV_STRING
{
- po_callback_comment_dispatcher ($1.string);
+ string_list_init (&$$.stringlist);
+ string_list_append (&$$.stringlist, $1.string);
+ $$.pos = $1.pos;
+ $$.obsolete = $1.obsolete;
+ }
+ | prev_string_list PREV_STRING
+ {
+ check_obsolete ($1, $2);
+ $$.stringlist = $1.stringlist;
+ string_list_append (&$$.stringlist, $2.string);
+ $$.pos = $1.pos;
+ $$.obsolete = $1.obsolete;
}
;
static mbfile_t mbf;
unsigned int gram_max_allowed_errors = 20;
static bool po_lex_obsolete;
+static bool po_lex_previous;
static bool pass_comments = false;
bool pass_obsolete_entries = false;
gram_pos_column = 0;
signal_eilseq = true;
po_lex_obsolete = false;
+ po_lex_previous = false;
po_lex_charset_init ();
}
gram_pos_column = 0;
signal_eilseq = false;
po_lex_obsolete = false;
+ po_lex_previous = false;
po_lex_charset_close ();
}
static int
keyword_p (const char *s)
{
- if (!strcmp (s, "domain"))
- return DOMAIN;
- if (!strcmp (s, "msgid"))
- return MSGID;
- if (!strcmp (s, "msgid_plural"))
- return MSGID_PLURAL;
- if (!strcmp (s, "msgstr"))
- return MSGSTR;
- if (!strcmp (s, "msgctxt"))
- return MSGCTXT;
+ if (!po_lex_previous)
+ {
+ if (!strcmp (s, "domain"))
+ return DOMAIN;
+ if (!strcmp (s, "msgid"))
+ return MSGID;
+ if (!strcmp (s, "msgid_plural"))
+ return MSGID_PLURAL;
+ if (!strcmp (s, "msgstr"))
+ return MSGSTR;
+ if (!strcmp (s, "msgctxt"))
+ return MSGCTXT;
+ }
+ else
+ {
+ /* Inside a "#|" context, the keywords have a different meaning. */
+ if (!strcmp (s, "msgid"))
+ return PREV_MSGID;
+ if (!strcmp (s, "msgid_plural"))
+ return PREV_MSGID_PLURAL;
+ if (!strcmp (s, "msgctxt"))
+ return PREV_MSGCTXT;
+ }
po_gram_error_at_line (&gram_pos, _("keyword \"%s\" unknown"), s);
return NAME;
}
{
case '\n':
po_lex_obsolete = false;
+ po_lex_previous = false;
/* Ignore whitespace, not relevant for the grammar. */
break;
characters are expected to be well formed. */
{
po_lex_obsolete = true;
+ /* A pseudo-comment beginning with #~| denotes a previous
+ untranslated string in an obsolete entry. This does not
+ make much sense semantically, and is implemented here
+ for completeness only. */
+ lex_getc (mbc);
+ if (mb_iseq (mbc, '|'))
+ po_lex_previous = true;
+ else
+ lex_ungetc (mbc);
+ break;
+ }
+ if (mb_iseq (mbc, '|'))
+ /* A pseudo-comment beginning with #| is found. This is
+ the previous untranslated string. We discard the "#|"
+ prefix, but change the keywords and string returns
+ accordingly. */
+ {
+ po_lex_previous = true;
break;
}
{
/* We do this in separate loop because collecting large
comments while they get not passed to the upper layers
- is not very effective. */
+ is not very efficient. */
while (!mb_iseof (mbc) && !mb_iseq (mbc, '\n'))
lex_getc (mbc);
po_lex_obsolete = false;
po_gram_lval.string.string = xstrdup (buf);
po_gram_lval.string.pos = gram_pos;
po_gram_lval.string.obsolete = po_lex_obsolete;
- return STRING;
+ return (po_lex_previous ? PREV_STRING : STRING);
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
char *msgid_plural,
char *msgstr, size_t msgstr_len,
lex_pos_ty *msgstr_pos,
+ char *prev_msgctxt,
+ char *prev_msgid,
+ char *prev_msgid_plural,
bool force_fuzzy, bool obsolete)
{
if (pop->methods->directive_message)
pop->methods->directive_message (pop, msgctxt,
msgid, msgid_pos, msgid_plural,
msgstr, msgstr_len, msgstr_pos,
+ prev_msgctxt,
+ prev_msgid,
+ prev_msgid_plural,
force_fuzzy, obsolete);
}
po_callback_message (char *msgctxt,
char *msgid, lex_pos_ty *msgid_pos, char *msgid_plural,
char *msgstr, size_t msgstr_len, lex_pos_ty *msgstr_pos,
+ char *prev_msgctxt,
+ char *prev_msgid,
+ char *prev_msgid_plural,
bool force_fuzzy, bool obsolete)
{
/* assert(callback_arg); */
call_directive_message (callback_arg, msgctxt,
msgid, msgid_pos, msgid_plural,
msgstr, msgstr_len, msgstr_pos,
+ prev_msgctxt, prev_msgid, prev_msgid_plural,
force_fuzzy, obsolete);
}
/* Reading PO files, abstract class.
- Copyright (C) 1995-1996, 1998, 2000-2003, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1995-1996, 1998, 2000-2003, 2005-2006 Free Software Foundation, Inc.
This file was written by Peter Miller <millerp@canb.auug.org.au>
char *msgid_plural,
char *msgstr, size_t msgstr_len,
lex_pos_ty *msgstr_pos,
+ char *prev_msgctxt,
+ char *prev_msgid, char *prev_msgid_plural,
bool force_fuzzy, bool obsolete);
/* What to do with a plain-vanilla comment - the expectation is that
char *msgid_plural,
char *msgstr, size_t msgstr_len,
lex_pos_ty *msgstr_pos,
+ char *prev_msgctxt,
+ char *prev_msgid, char *prev_msgid_plural,
bool force_fuzzy, bool obsolete);
extern void po_callback_comment (const char *s);
extern void po_callback_comment_dot (const char *s);
/* Reading PO files.
- Copyright (C) 1995-1998, 2000-2003, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1995-1998, 2000-2003, 2005-2006 Free Software Foundation, Inc.
This file was written by Peter Miller <millerp@canb.auug.org.au>
This program is free software; you can redistribute it and/or modify
char *msgctxt,
char *msgid, lex_pos_ty *msgid_pos, char *msgid_plural,
char *msgstr, size_t msgstr_len, lex_pos_ty *msgstr_pos,
+ char *prev_msgctxt, char *prev_msgid, char *prev_msgid_plural,
bool force_fuzzy, bool obsolete)
{
default_po_reader_class_ty *methods =
methods->add_message (this, msgctxt,
msgid, msgid_pos, msgid_plural,
msgstr, msgstr_len, msgstr_pos,
+ prev_msgctxt, prev_msgid, prev_msgid_plural,
force_fuzzy, obsolete);
}
char *msgid_plural,
char *msgstr, size_t msgstr_len,
lex_pos_ty *msgstr_pos,
+ char *prev_msgctxt,
+ char *prev_msgid, char *prev_msgid_plural,
bool force_fuzzy, bool obsolete)
{
default_po_reader_ty *this = (default_po_reader_ty *) that;
call_add_message (this, msgctxt, msgid, msgid_pos, msgid_plural,
- msgstr, msgstr_len, msgstr_pos, force_fuzzy, obsolete);
+ msgstr, msgstr_len, msgstr_pos,
+ prev_msgctxt, prev_msgid, prev_msgid_plural,
+ force_fuzzy, obsolete);
/* Prepare for next message. */
default_reset_comment_state (this);
char *msgid_plural,
char *msgstr, size_t msgstr_len,
lex_pos_ty *msgstr_pos,
+ char *prev_msgctxt,
+ char *prev_msgid,
+ char *prev_msgid_plural,
bool force_fuzzy, bool obsolete)
{
message_ty *mp;
}
/* We don't need the just constructed entries' parameter string
(allocated in po-gram-gen.y). */
- free (msgstr);
free (msgid);
+ if (msgid_plural != NULL)
+ free (msgid_plural);
+ free (msgstr);
if (msgctxt != NULL)
free (msgctxt);
+ if (prev_msgctxt != NULL)
+ free (prev_msgctxt);
+ if (prev_msgid != NULL)
+ free (prev_msgid);
+ if (prev_msgid_plural != NULL)
+ free (prev_msgid_plural);
/* Add the accumulated comments to the message. */
default_copy_comment_state (this, mp);
appropriate. */
mp = message_alloc (msgctxt, msgid, msgid_plural, msgstr, msgstr_len,
msgstr_pos);
+ mp->prev_msgctxt = prev_msgctxt;
+ mp->prev_msgid = prev_msgid;
+ mp->prev_msgid_plural = prev_msgid_plural;
mp->obsolete = obsolete;
default_copy_comment_state (this, mp);
if (force_fuzzy)
/* Reading PO files.
- Copyright (C) 1995-1998, 2000-2003, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1995-1998, 2000-2003, 2005-2006 Free Software Foundation, Inc.
This file was written by Bruno Haible <haible@clisp.cons.org>.
This program is free software; you can redistribute it and/or modify
char *msgctxt,
char *msgid, lex_pos_ty *msgid_pos, char *msgid_plural,
char *msgstr, size_t msgstr_len, lex_pos_ty *msgstr_pos,
+ char *prev_msgctxt,
+ char *prev_msgid,
+ char *prev_msgid_plural,
bool force_fuzzy, bool obsolete);
/* How to modify a new message before adding it to the list. */
char *msgid_plural,
char *msgstr, size_t msgstr_len,
lex_pos_ty *msgstr_pos,
+ char *prev_msgctxt,
+ char *prev_msgid,
+ char *prev_msgid_plural,
bool force_fuzzy, bool obsolete);
extern void default_comment (abstract_po_reader_ty *that, const char *s);
extern void default_comment_dot (abstract_po_reader_ty *that, const char *s);
char *msgid_plural,
char *msgstr, size_t msgstr_len,
lex_pos_ty *msgstr_pos,
+ char *prev_msgctxt,
+ char *prev_msgid,
+ char *prev_msgid_plural,
bool force_fuzzy, bool obsolete);
/* Allocate a fresh default_po_reader_ty (or derived class) instance and
po_callback_message (NULL, msgid, &msgid_pos, NULL,
msgstr, strlen (msgstr) + 1, &msgstr_pos,
+ NULL, NULL, NULL,
force_fuzzy, false);
}
}
msgstr_pos = msgid_pos;
po_callback_message (NULL, msgid, &msgid_pos, NULL,
msgstr, strlen (msgstr) + 1, &msgstr_pos,
+ NULL, NULL, NULL,
false, next_is_obsolete);
}
else if (c == '=')
/* A key/value pair. */
po_callback_message (NULL, msgid, &msgid_pos, NULL,
msgstr, strlen (msgstr) + 1, &msgstr_pos,
+ NULL, NULL, NULL,
false, next_is_obsolete);
}
else
static void
-wrap (const message_ty *mp, FILE *fp, const char *line_prefix,
+wrap (const message_ty *mp, FILE *fp, const char *line_prefix, int extra_indent,
const char *name, const char *value, enum is_wrap do_wrap,
const char *charset)
{
See INDENT-S. */
startcol_after_break = (line_prefix ? strlen (line_prefix) : 0);
if (indent)
- startcol_after_break = (startcol_after_break + 8) & ~7;
+ startcol_after_break = (startcol_after_break + extra_indent + 8) & ~7;
startcol_after_break++;
/* The line width. Allow room for the closing quote character. */
{
startcol += strlen (name);
if (indent)
- startcol = (startcol + 8) & ~7;
+ startcol = (startcol + extra_indent + 8) & ~7;
else
startcol++;
}
else
{
if (indent)
- startcol = (startcol + 8) & ~7;
+ startcol = (startcol + extra_indent + 8) & ~7;
}
/* Allow room for the opening quote character. */
startcol++;
if (first_line)
{
fputs (name, fp);
- putc (indent ? '\t' : ' ', fp);
+ if (indent)
+ {
+ if (extra_indent > 0)
+ fwrite (" ", 1, extra_indent, fp);
+ putc ('\t', fp);
+ }
+ else
+ putc (' ', fp);
first_line = false;
}
else
{
if (indent)
- putc ('\t', fp);
+ {
+ if (extra_indent > 0)
+ fwrite (" ", 1, extra_indent, fp);
+ putc ('\t', fp);
+ }
}
/* Print the portion itself, with linebreaks where necessary. */
message_print (const message_ty *mp, FILE *fp, const char *charset,
bool blank_line, bool debug)
{
+ int extra_indent;
+
/* Separate messages with a blank line. Uniforum doesn't like blank
lines, so use an empty comment (unless there already is one). */
if (blank_line && (!uniforum
/* Print flag information in special comment. */
message_print_comment_flags (mp, fp, debug);
+ /* Print the previous msgid. This helps the translator when the msgid has
+ only slightly changed. */
+ if (mp->prev_msgctxt != NULL)
+ wrap (mp, fp, "#| ", 0, "msgctxt", mp->prev_msgctxt, mp->do_wrap, charset);
+ if (mp->prev_msgid != NULL)
+ wrap (mp, fp, "#| ", 0, "msgid", mp->prev_msgid, mp->do_wrap, charset);
+ if (mp->prev_msgid_plural != NULL)
+ wrap (mp, fp, "#| ", 0, "msgid_plural", mp->prev_msgid_plural, mp->do_wrap,
+ charset);
+ extra_indent = (mp->prev_msgctxt != NULL || mp->prev_msgid != NULL
+ || mp->prev_msgid_plural != NULL
+ ? 3
+ : 0);
+
/* Print each of the message components. Wrap them nicely so they
are as readable as possible. If there is no recorded msgstr for
this domain, emit an empty string. */
free (warning_message);
}
if (mp->msgctxt != NULL)
- wrap (mp, fp, NULL, "msgctxt", mp->msgctxt, mp->do_wrap, charset);
- wrap (mp, fp, NULL, "msgid", mp->msgid, mp->do_wrap, charset);
+ wrap (mp, fp, NULL, extra_indent, "msgctxt", mp->msgctxt, mp->do_wrap,
+ charset);
+ wrap (mp, fp, NULL, extra_indent, "msgid", mp->msgid, mp->do_wrap, charset);
if (mp->msgid_plural != NULL)
- wrap (mp, fp, NULL, "msgid_plural", mp->msgid_plural, mp->do_wrap, charset);
+ wrap (mp, fp, NULL, extra_indent, "msgid_plural", mp->msgid_plural,
+ mp->do_wrap, charset);
if (mp->msgid_plural == NULL)
- wrap (mp, fp, NULL, "msgstr", mp->msgstr, mp->do_wrap, charset);
+ wrap (mp, fp, NULL, extra_indent, "msgstr", mp->msgstr, mp->do_wrap,
+ charset);
else
{
char prefix_buf[20];
p += strlen (p) + 1, i++)
{
sprintf (prefix_buf, "msgstr[%u]", i);
- wrap (mp, fp, NULL, prefix_buf, p, mp->do_wrap, charset);
+ wrap (mp, fp, NULL, extra_indent, prefix_buf, p, mp->do_wrap,
+ charset);
}
}
}
message_print_obsolete (const message_ty *mp, FILE *fp, const char *charset,
bool blank_line)
{
+ int extra_indent;
+
/* If msgstr is the empty string we print nothing. */
if (mp->msgstr[0] == '\0')
return;
putc ('\n', fp);
}
+ /* Print the previous msgid. This helps the translator when the msgid has
+ only slightly changed. */
+ if (mp->prev_msgctxt != NULL)
+ wrap (mp, fp, "#~| ", 0, "msgctxt", mp->prev_msgctxt, mp->do_wrap, charset);
+ if (mp->prev_msgid != NULL)
+ wrap (mp, fp, "#~| ", 0, "msgid", mp->prev_msgid, mp->do_wrap, charset);
+ if (mp->prev_msgid_plural != NULL)
+ wrap (mp, fp, "#~| ", 0, "msgid_plural", mp->prev_msgid_plural, mp->do_wrap,
+ charset);
+ extra_indent = (mp->prev_msgctxt != NULL || mp->prev_msgid != NULL
+ || mp->prev_msgid_plural != NULL
+ ? 1
+ : 0);
+
/* Print each of the message components. Wrap them nicely so they
are as readable as possible. */
if (mp->msgctxt != NULL && !is_ascii_string (mp->msgctxt)
free (warning_message);
}
if (mp->msgctxt != NULL)
- wrap (mp, fp, "#~ ", "msgctxt", mp->msgctxt, mp->do_wrap, charset);
- wrap (mp, fp, "#~ ", "msgid", mp->msgid, mp->do_wrap, charset);
- if (mp->msgid_plural != NULL)
- wrap (mp, fp, "#~ ", "msgid_plural", mp->msgid_plural, mp->do_wrap,
+ wrap (mp, fp, "#~ ", extra_indent, "msgctxt", mp->msgctxt, mp->do_wrap,
charset);
+ wrap (mp, fp, "#~ ", extra_indent, "msgid", mp->msgid, mp->do_wrap, charset);
+ if (mp->msgid_plural != NULL)
+ wrap (mp, fp, "#~ ", extra_indent, "msgid_plural", mp->msgid_plural,
+ mp->do_wrap, charset);
if (mp->msgid_plural == NULL)
- wrap (mp, fp, "#~ ", "msgstr", mp->msgstr, mp->do_wrap, charset);
+ wrap (mp, fp, "#~ ", extra_indent, "msgstr", mp->msgstr, mp->do_wrap,
+ charset);
else
{
char prefix_buf[20];
p += strlen (p) + 1, i++)
{
sprintf (prefix_buf, "msgstr[%u]", i);
- wrap (mp, fp, "#~ ", prefix_buf, p, mp->do_wrap, charset);
+ wrap (mp, fp, "#~ ", extra_indent, prefix_buf, p, mp->do_wrap,
+ charset);
}
}
}
/* xgettext PO and JavaProperties backends.
- Copyright (C) 1995-1998, 2000-2003, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1995-1998, 2000-2003, 2005-2006 Free Software Foundation, Inc.
This file was written by Peter Miller <millerp@canb.auug.org.au>
char *msgid_plural,
char *msgstr, size_t msgstr_len,
lex_pos_ty *msgstr_pos,
+ char *prev_msgctxt,
+ char *prev_msgid,
+ char *prev_msgid_plural,
bool force_fuzzy, bool obsolete)
{
/* See whether we shall exclude this message. */
if (msgctxt != NULL)
free (msgctxt);
free (msgid);
+ if (msgid_plural != NULL)
+ free (msgid_plural);
free (msgstr);
+ if (prev_msgctxt != NULL)
+ free (prev_msgctxt);
+ if (prev_msgid != NULL)
+ free (prev_msgid);
+ if (prev_msgid_plural != NULL)
+ free (prev_msgid_plural);
return;
}
/* Invoke superclass method. */
default_add_message (this, msgctxt, msgid, msgid_pos, msgid_plural,
- msgstr, msgstr_len, msgstr_pos, force_fuzzy, obsolete);
+ msgstr, msgstr_len, msgstr_pos,
+ prev_msgctxt, prev_msgid, prev_msgid_plural,
+ force_fuzzy, obsolete);
}
char *msgid_plural,
char *msgstr, size_t msgstr_len,
lex_pos_ty *msgstr_pos,
+ char *prev_msgctxt,
+ char *prev_msgid,
+ char *prev_msgid_plural,
bool force_fuzzy, bool obsolete)
{
message_ty *mp;
+2006-10-03 Bruno Haible <bruno@clisp.org>
+
+ * msgattrib-16: New file.
+ * msgattrib-17: New file.
+ * msgcat-15: New file.
+ * msgcat-16: New file.
+ * msgcmp-4: New file.
+ * msgcomm-26: New file.
+ * msgconv-6: New file.
+ * msgfmt-16: New file.
+ * msgmerge-19: New file.
+ * msguniq-6: New file.
+ * Makefile.am (TESTS): Add them.
+
2006-10-03 Bruno Haible <bruno@clisp.org>
* msgmerge-18: Invoke msgcmp with options --use-fuzzy and
msgattrib-1 msgattrib-2 msgattrib-3 msgattrib-4 msgattrib-5 \
msgattrib-6 msgattrib-7 msgattrib-8 msgattrib-9 msgattrib-10 \
msgattrib-11 msgattrib-12 msgattrib-13 msgattrib-14 msgattrib-15 \
+ msgattrib-16 msgattrib-17 \
msgattrib-properties-1 \
msgcat-1 msgcat-2 msgcat-3 msgcat-4 msgcat-5 msgcat-6 msgcat-7 \
msgcat-8 msgcat-9 msgcat-10 msgcat-11 msgcat-12 msgcat-13 msgcat-14 \
+ msgcat-15 msgcat-16 \
msgcat-properties-1 msgcat-properties-2 \
msgcat-stringtable-1 \
- msgcmp-1 msgcmp-2 msgcmp-3 \
+ msgcmp-1 msgcmp-2 msgcmp-3 msgcmp-4 \
msgcomm-1 msgcomm-2 msgcomm-3 msgcomm-4 msgcomm-5 msgcomm-6 msgcomm-7 \
msgcomm-8 msgcomm-9 msgcomm-10 msgcomm-11 msgcomm-12 msgcomm-13 \
msgcomm-14 msgcomm-15 msgcomm-16 msgcomm-17 msgcomm-18 msgcomm-19 \
msgcomm-20 msgcomm-21 msgcomm-22 msgcomm-23 msgcomm-24 msgcomm-25 \
- msgconv-1 msgconv-2 msgconv-3 msgconv-4 msgconv-5 \
+ msgcomm-26 \
+ msgconv-1 msgconv-2 msgconv-3 msgconv-4 msgconv-5 msgconv-6 \
msgen-1 msgen-2 msgen-3 \
msgexec-1 msgexec-2 msgexec-3 msgexec-4 \
msgfilter-1 msgfilter-2 msgfilter-3 msgfilter-4 \
msgfilter-sr-latin-1 \
msgfmt-1 msgfmt-2 msgfmt-3 msgfmt-4 msgfmt-5 msgfmt-6 msgfmt-7 \
msgfmt-8 msgfmt-9 msgfmt-10 msgfmt-11 msgfmt-12 msgfmt-13 msgfmt-14 \
- msgfmt-15 \
+ msgfmt-15 msgfmt-16 \
msgfmt-properties-1 \
msgfmt-qt-1 msgfmt-qt-2 \
msggrep-1 msggrep-2 msggrep-3 msggrep-4 msggrep-5 msggrep-6 msggrep-7 \
msgmerge-1 msgmerge-2 msgmerge-3 msgmerge-4 msgmerge-5 msgmerge-6 \
msgmerge-7 msgmerge-8 msgmerge-9 msgmerge-10 msgmerge-11 msgmerge-12 \
msgmerge-13 msgmerge-14 msgmerge-15 msgmerge-16 msgmerge-17 \
- msgmerge-18 \
+ msgmerge-18 msgmerge-19 \
msgmerge-compendium-1 msgmerge-compendium-2 msgmerge-compendium-3 \
msgmerge-compendium-4 msgmerge-compendium-5 msgmerge-compendium-6 \
msgmerge-properties-1 msgmerge-properties-2 \
msgunfmt-java-1 \
msgunfmt-properties-1 \
msgunfmt-tcl-1 \
- msguniq-1 msguniq-2 msguniq-3 msguniq-4 msguniq-5 \
+ msguniq-1 msguniq-2 msguniq-3 msguniq-4 msguniq-5 msguniq-6 \
recode-sr-latin-1 recode-sr-latin-2 \
xgettext-1 xgettext-2 xgettext-3 xgettext-4 xgettext-5 xgettext-6 \
xgettext-7 xgettext-8 xgettext-9 \