diff options
authorSergey Poznyakoff <gray@gnu.org>2021-02-08 09:45:02 +0200
committerSergey Poznyakoff <gray@gnu.org>2021-02-08 09:45:02 +0200
commit634ce0fb0bbc4a2766d03d8845c1b0705daa56ea (patch)
parentba4f63d5773522e768a4bbdc4f7f3df69d83e945 (diff)
Support for the Language header.
* src/po.c (restore_file_name): Try to obtain the language code from the Language header first. If this fails, use Language-Team. * doc/wyslij-po.texi: Document the use of the Language header. * NEWS: Document changes.
3 files changed, 49 insertions, 23 deletions
diff --git a/NEWS b/NEWS
index 2002804..d268d3e 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-Wyslij-po NEWS -- history of user-visible changes. 2021-02-07
+Wyslij-po NEWS -- history of user-visible changes. 2021-02-08
See the end of file for copying conditions.
Please send mailfromd bug reports to <bug-wyslij-po@gnu.org.ua>
@@ -7,6 +7,11 @@ Version 3.2.90 (git)
* Fix parsing of po header fields
+* Use the Language header instead of Language-Team.
+The support for Language-Team and language tables is retained for
+backward compatibility.
* Organizational change: repository moved to git
The repository along with links for cloning can be viewed online at
diff --git a/doc/wyslij-po.texi b/doc/wyslij-po.texi
index 13dcb0a..ee52d38 100644
--- a/doc/wyslij-po.texi
+++ b/doc/wyslij-po.texi
@@ -160,24 +160,26 @@ A canonical @acronym{PO} name consists of the project name and
version, separated by dash, which are followed by a dot, the language
code as per @acronym{ISO} 639, and the suffix @samp{.po}. To determine the
canonical name, @command{wyslij-po} uses the contents of
-@code{Project-Id-Version} and @code{Language-Team} @acronym{PO}
+@code{Project-Id-Version} and @code{Language} @acronym{PO}
headers. The value of @code{Project-Id-Version} supplies the name and
version of the project this file is for, and the value of
-@code{Language-Team} gives the full name of the language served by
-this @acronym{PO}. This full name is then looked up in a @dfn{language
-table} - a special file listing for each language name its @acronym{ISO} 639
-code (@pxref{Langtab}), and the code found is then used. For example,
-if the two headers in question were:
+@code{Language} gives the @acronym{ISO-639} abbreviation of the
+language name@. For example, if the two headers in question were:
Project-Id-Version: cflow 1.2
-Language-Team: Polish
- <translation-team-pl@@lists.sourceforge.net>
+Language: pl
@end example
then the canonical name for that file is @file{cflow-1.2.pl.po}.
+If the @acronym{PO} file lacks the @code{Language} header,
+@command{wyslij-po} analyzes the @code{Language-Team} header. The
+full language name extracted from this header is looked up in a
+@dfn{language table} file to find the corresponding @acronym{ISO-639}
+code (@pxref{Langtab}).
@item Verify the consistency of @acronym{PO} file.
This step ensures that the file corresponds to the latest version of
@@ -701,12 +703,19 @@ sed, GNU sed}) with exactly one parenthesized group.
@cindex language code
To recreate the canonical @acronym{PO} name (@pxref{canonical-name})
for a given translation, @command{wyslij-po} needs to know the
-@dfn{language code} associated with this language. This information cannot
-be obtained from @acronym{PO} file directly. Instead,
-@command{wyslij-po} obtains the full language name
-from the @code{Language-Team} @acronym{PO} header, and then uses this
-value as a look-up key in a set of @dfn{language tables}. If the key is
-found, its value gives the language code.
+@dfn{language code} associated with this language. Normally this
+information is kept in the @code{Language} header of the @acronym{PO}
+file@footnote{The @code{Language} header is present in @acronym{PO}
+files created by @command{gettext} version 0.18 or later.}. If this
+header is not present, @command{wyslij-po} will first obtain the full
+language name from the @code{Language-Team} @acronym{PO} header, and
+then use this value as a look-up key in a set of @dfn{language
+tables}. If the key is found, its value gives the language code.
+ This language code lookup is retained as a fallback mechanism for
+handling old @acronym{PO} files and will be removed in future
+releases. This chapter describes the format of language table files
+used by @command{wyslij-po}.
@cindex language tables, format
The language tables are stored in plain text files. Their format is
diff --git a/src/po.c b/src/po.c
index 5ef6189..088c604 100644
--- a/src/po.c
+++ b/src/po.c
@@ -340,7 +340,6 @@ char *
restore_file_name (const char *file_name, char **pemail)
const char *project_id;
- const char *lang_team;
const char *langcode;
struct mu_wordsplit ws;
char *name;
@@ -357,12 +356,6 @@ restore_file_name (const char *file_name, char **pemail)
mu_error (_("No Project-Id-Version"));
exit (1);
- status = mu_header_sget_value (header, "Language-Team", &lang_team);
- if (status)
- {
- mu_error (_("No Language-Team"));
- exit (1);
- }
status = mu_wordsplit (project_id, &ws, MU_WRDSF_DEFFLAGS);
if (status)
@@ -382,8 +375,27 @@ restore_file_name (const char *file_name, char **pemail)
if (verify_mask & VERIFY_PO_TIME)
verify_times (file_name);
- langcode = parse_language_team (lang_team);
+ status = mu_header_sget_value (header, "Language", &langcode);
+ if (status)
+ {
+ const char *lang_team;
+ if (status != MU_ERR_NOENT)
+ {
+ mu_error (_("Can't get the Language header: %s"),
+ mu_strerror (status));
+ }
+ status = mu_header_sget_value (header, "Language-Team", &lang_team);
+ if (status)
+ {
+ mu_error (_("Can't determine target language: neither Language nor Language-Team header is present in the PO file"));
+ exit (1);
+ }
+ langcode = parse_language_team (lang_team);
+ }
if (mu_asprintf (&name, "%s-%s.%s%s",
ws.ws_wordv[0], ws.ws_wordv[1], langcode, PO_SUF))
mu_alloc_die ();

Return to:

Send suggestions and report system problems to the System administrator.