diff --git a/0001-msgcat-Add-feature-to-use-the-newest-po-file.patch b/0001-msgcat-Add-feature-to-use-the-newest-po-file.patch new file mode 100644 index 0000000..b0fcca1 --- /dev/null +++ b/0001-msgcat-Add-feature-to-use-the-newest-po-file.patch @@ -0,0 +1,399 @@ +From a079538e51c6c6e9855d9e7bde1519eaa59bb94d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Mark=C3=A9ta=20Cal=C3=A1bkov=C3=A1?= + +Date: Thu, 9 Jan 2020 14:40:25 +0100 +Subject: [PATCH 1/2] msgcat: Add feature to use the newest po file. + +When concatenating po files, it is often useful to prefer strings from +the newest file regardless their ordering on the command line. +--- + gettext-tools/src/Makefile.am | 4 +- + gettext-tools/src/message.c | 6 +++ + gettext-tools/src/message.h | 4 ++ + gettext-tools/src/msgcat.c | 10 ++++ + gettext-tools/src/msgl-age.c | 96 +++++++++++++++++++++++++++++++++ + gettext-tools/src/msgl-age.h | 36 +++++++++++++ + gettext-tools/src/msgl-cat.c | 15 ++++++ + gettext-tools/src/msgl-cat.h | 1 + + gettext-tools/src/msgl-header.c | 47 ++++++++++++++++ + gettext-tools/src/msgl-header.h | 6 +++ + 10 files changed, 223 insertions(+), 2 deletions(-) + create mode 100644 gettext-tools/src/msgl-age.c + create mode 100644 gettext-tools/src/msgl-age.h + +Index: gettext-0.21/gettext-tools/src/Makefile.am +=================================================================== +--- gettext-0.21.orig/gettext-tools/src/Makefile.am ++++ gettext-0.21/gettext-tools/src/Makefile.am +@@ -43,7 +43,7 @@ noinst_HEADERS = \ + write-catalog.h write-po.h write-properties.h write-stringtable.h \ + dir-list.h file-list.h po-gram-gen.h po-gram-gen2.h cldr-plural.h \ + cldr-plural-exp.h locating-rule.h its.h search-path.h \ +- msgl-charset.h msgl-equal.h msgl-iconv.h msgl-ascii.h msgl-cat.h msgl-header.h \ ++ msgl-age.h msgl-charset.h msgl-equal.h msgl-iconv.h msgl-ascii.h msgl-cat.h msgl-header.h \ + msgl-english.h msgl-check.h msgl-fsearch.h msgfmt.h msgunfmt.h \ + plural-count.h plural-eval.h plural-distrib.h \ + read-mo.h write-mo.h \ +@@ -174,7 +174,7 @@ FORMAT_SOURCE += \ + libgettextsrc_la_SOURCES = \ + $(COMMON_SOURCE) read-catalog.c \ + write-catalog.c write-properties.c write-stringtable.c write-po.c \ +-msgl-ascii.c msgl-iconv.c msgl-equal.c msgl-cat.c msgl-header.c msgl-english.c \ ++msgl-age.c msgl-ascii.c msgl-iconv.c msgl-equal.c msgl-cat.c msgl-header.c msgl-english.c \ + msgl-check.c file-list.c msgl-charset.c po-time.c plural-exp.c plural-eval.c \ + plural-table.c quote.h sentence.h sentence.c \ + $(FORMAT_SOURCE) \ +Index: gettext-0.21/gettext-tools/src/message.c +=================================================================== +--- gettext-0.21.orig/gettext-tools/src/message.c ++++ gettext-0.21/gettext-tools/src/message.c +@@ -356,6 +356,12 @@ message_list_append (message_list_ty *ml + abort (); + } + ++void ++message_list_append_list (message_list_ty *mlp, message_list_ty *mlp2) ++{ ++ for (int i = 0; i < mlp2->nitems; i++) ++ message_list_append (mlp,mlp2->item[i]); ++} + + void + message_list_prepend (message_list_ty *mlp, message_ty *mp) +Index: gettext-0.21/gettext-tools/src/message.h +=================================================================== +--- gettext-0.21.orig/gettext-tools/src/message.h ++++ gettext-0.21/gettext-tools/src/message.h +@@ -24,6 +24,7 @@ + #include "mem-hash-map.h" + + #include ++#include + + + #ifdef __cplusplus +@@ -269,6 +270,8 @@ extern void + extern void + message_list_append (message_list_ty *mlp, message_ty *mp); + extern void ++ message_list_append_list (message_list_ty *mlp, message_list_ty *mlp2); ++extern void + message_list_prepend (message_list_ty *mlp, message_ty *mp); + extern void + message_list_insert_at (message_list_ty *mlp, size_t n, message_ty *mp); +@@ -350,6 +353,7 @@ struct msgdomain_list_ty + size_t nitems_max; + bool use_hashtable; + const char *encoding; /* canonicalized encoding or NULL if unknown */ ++ time_t msgage; + }; + + extern msgdomain_list_ty * +Index: gettext-0.21/gettext-tools/src/msgcat.c +=================================================================== +--- gettext-0.21.orig/gettext-tools/src/msgcat.c ++++ gettext-0.21/gettext-tools/src/msgcat.c +@@ -88,6 +88,7 @@ static const struct option long_options[ + { "to-code", required_argument, NULL, 't' }, + { "unique", no_argument, NULL, 'u' }, + { "use-first", no_argument, NULL, CHAR_MAX + 1 }, ++ { "use-newest", no_argument, NULL, CHAR_MAX + 9 }, + { "version", no_argument, NULL, 'V' }, + { "width", required_argument, NULL, 'w' }, + { "more-than", required_argument, NULL, '>' }, +@@ -141,6 +142,7 @@ main (int argc, char **argv) + more_than = 0; + less_than = INT_MAX; + use_first = false; ++ use_newest = false; + + while ((optchar = getopt_long (argc, argv, "<:>:D:eEf:Fhino:pPst:uVw:", + long_options, NULL)) != EOF) +@@ -277,6 +279,11 @@ main (int argc, char **argv) + message_print_style_filepos (filepos_comment_none); + break; + ++ case CHAR_MAX + 9: /* --use-newest */ ++ use_newest = true; ++ use_first = true; ++ break; ++ + default: + usage (EXIT_FAILURE); + /* NOTREACHED */ +@@ -428,6 +435,9 @@ Output details:\n")); + --use-first use first available translation for each\n\ + message, don't merge several translations\n")); + printf (_("\ ++ --use-newest use the most up-to-date available translation\n\ ++ for each message, don't merge several translations\n")); ++ printf (_("\ + --lang=CATALOGNAME set 'Language' field in the header entry\n")); + printf (_("\ + --color use colors and other text attributes always\n\ +Index: gettext-0.21/gettext-tools/src/msgl-age.c +=================================================================== +--- /dev/null ++++ gettext-0.21/gettext-tools/src/msgl-age.c +@@ -0,0 +1,96 @@ ++/* Message list header time simple parser. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ Written by Markéta Calábková , 2019. ++ ++ This program is free software: you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ ++ ++#ifdef HAVE_CONFIG_H ++# include "config.h" ++#endif ++ ++#include ++#include ++ ++#include "xalloc.h" ++#include "error.h" ++#include "xerror.h" ++#include "xvasprintf.h" ++ ++#include "msgl-header.h" ++#include ++#include ++#include "gettext.h" ++ ++#include "msgl-age.h" ++ ++#define _(str) gettext (str) ++ ++void ++msgdomain_sort_by_ages (msgdomain_list_ty **mdlps, size_t nfiles) ++{ ++ qsort (mdlps, nfiles, sizeof(msgdomain_list_ty*), msgdomain_compare_ages); ++} ++ ++int ++msgdomain_compare_ages (const void * p1, const void * p2) ++{ ++ if (difftime((*(msgdomain_list_ty **)p2)->msgage, (*(msgdomain_list_ty **)p1)->msgage) > 0) ++ return 1; ++ else ++ return 0; ++} ++ ++void ++msgdomain_read_ages (msgdomain_list_ty *mdlp) ++{ ++ time_t times[mdlp->nitems]; ++ const char * field = "PO-Revision-Date:"; ++ char * where; ++ ++ for (int i = 0; i < mdlp->nitems; i++) ++ { ++ message_list_ty *mlp = mdlp->item[i]->messages; ++ ++ message_list_read_header_field (mlp, field, &where); ++ } ++ struct tm tmptm; ++ char *trail; ++ memset (&tmptm, 0, sizeof(struct tm)); ++ if ((trail = strptime (where, "%Y-%m-%d %H:%M:%S%z", &tmptm)) != NULL) ++ mdlp->msgage = mktime (&tmptm); ++ else if ((trail = strptime (where, "%Y-%m-%d %H:%M:%S", &tmptm)) != NULL) ++ mdlp->msgage = mktime (&tmptm); ++ else if ((trail = strptime (where, "%Y-%m-%d %H:%M%z", &tmptm)) != NULL) ++ mdlp->msgage = mktime (&tmptm); ++ else if ((trail = strptime (where, "%Y-%m-%d %H:%M", &tmptm)) != NULL) ++ mdlp->msgage = mktime (&tmptm); ++ else ++ { ++ /* There is probably no creation date. Assign 0 and throw warning. */ ++ mdlp->msgage = 0; ++ multiline_warning (xasprintf (_("warning: ")), ++ xasprintf (_("\ ++PO-Revision-Date has no or invalid value, assuming it is old.\n\ ++"))); ++ return; ++ } ++ if ((*trail != '\n') && (*trail != '\0')) ++ multiline_warning (xasprintf (_("warning: ")), ++ xasprintf (_("\ ++Unknown trailing characters after PO-Revision-Date, ignoring.\n\ ++"))); ++} ++ ++ ++ +Index: gettext-0.21/gettext-tools/src/msgl-age.h +=================================================================== +--- /dev/null ++++ gettext-0.21/gettext-tools/src/msgl-age.h +@@ -0,0 +1,36 @@ ++/* Message list header time simple parser. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ Written by Markéta Calábková , 2019. ++ ++ This program is free software: you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ ++ ++#ifndef _MSGL_AGE_H ++#define _MSGL_AGE_H ++ ++#include "message.h" ++ ++/* Helper function to compare the ages, needed by qsort. */ ++int ++ msgdomain_compare_ages (const void *, const void *); ++ ++/* Simple function to modify intern ordering of files ++ * such that the newer file comes first. In fact it just calls qsort. */ ++void ++ msgdomain_sort_by_ages (msgdomain_list_ty **, size_t); ++ ++/* Parse dates in PO-Revision-Date: and store them inside the structure. */ ++void ++ msgdomain_read_ages (msgdomain_list_ty *); ++ ++#endif +Index: gettext-0.21/gettext-tools/src/msgl-cat.c +=================================================================== +--- gettext-0.21.orig/gettext-tools/src/msgl-cat.c ++++ gettext-0.21/gettext-tools/src/msgl-cat.c +@@ -37,6 +37,7 @@ + #include "message.h" + #include "read-catalog.h" + #include "po-charset.h" ++#include "msgl-age.h" + #include "msgl-ascii.h" + #include "msgl-equal.h" + #include "msgl-iconv.h" +@@ -57,6 +58,11 @@ int less_than; + If false, merge all available translations into one and fuzzy it. */ + bool use_first; + ++/* If true, sort all the translation according to their age and let ++ use_first finish the job. ++ If false, keep the order of translations. */ ++bool use_newest; ++ + /* If true, merge like msgcomm. + If false, merge like msgcat and msguniq. */ + bool msgcomm_mode = false; +@@ -123,6 +129,15 @@ catenate_msgdomain_list (string_list_ty + for (n = 0; n < nfiles; n++) + mdlps[n] = read_catalog_file (files[n], input_syntax); + ++ /* --use-newest case -- sort messages by time and then let --use-first finish the job */ ++ if (use_newest) ++ { ++ for (n = 0; n < nfiles; n++) ++ msgdomain_read_ages (mdlps[n]); ++ ++ msgdomain_sort_by_ages (mdlps, nfiles); ++ } ++ + /* Determine the canonical name of each input file's encoding. */ + canon_charsets = XNMALLOC (nfiles, const char **); + for (n = 0; n < nfiles; n++) +Index: gettext-0.21/gettext-tools/src/msgl-cat.h +=================================================================== +--- gettext-0.21.orig/gettext-tools/src/msgl-cat.h ++++ gettext-0.21/gettext-tools/src/msgl-cat.h +@@ -37,6 +37,7 @@ extern DLL_VARIABLE int less_than; + /* If true, use the first available translation. + If false, merge all available translations into one and fuzzy it. */ + extern DLL_VARIABLE bool use_first; ++extern DLL_VARIABLE bool use_newest; + + /* If true, merge like msgcomm. + If false, merge like msgcat and msguniq. */ +Index: gettext-0.21/gettext-tools/src/msgl-header.c +=================================================================== +--- gettext-0.21.orig/gettext-tools/src/msgl-header.c ++++ gettext-0.21/gettext-tools/src/msgl-header.c +@@ -222,3 +222,50 @@ message_list_delete_header_field (messag + } + } + } ++ ++void ++message_list_read_header_field (message_list_ty *mlp, ++ const char *field, char **where_ptr) ++{ ++ size_t field_len = strlen (field); ++ size_t j; ++ ++ /* Search the header entry. */ ++ for (j = 0; j < mlp->nitems; j++) ++ if (is_header (mlp->item[j]) && !mlp->item[j]->obsolete) ++ { ++ /* We found the correct message. */ ++ message_ty *mp = mlp->item[j]; ++ ++ /* Tag the header entry. */ ++ const char *header = mp->msgstr; ++ ++ /* Test whether the field occurs in the header entry. */ ++ const char *h; ++ ++ for (h = header; *h != '\0'; ) ++ { ++ if (strncmp (h, field, field_len) == 0) ++ break; ++ /* Jump by lines. */ ++ h = strchr (h, '\n'); ++ if (h == NULL) ++ break; ++ h++; ++ } ++ if (h != NULL && *h != '\0') ++ { ++ /* We found it and it is nonempty. Read the value of the field. */ ++ h += field_len + 1; ++ char *enh = strchr (h, '\n'); ++ if (enh != NULL && *enh != '\0') ++ { ++ *where_ptr = (char *)XNMALLOC (((enh - h) + 1), char); ++ memcpy (*where_ptr, h, enh - h); ++ /* Make the string null-terminated. */ ++ (*where_ptr)[enh-h] = '\0'; ++ } ++ } ++ } ++} ++ +Index: gettext-0.21/gettext-tools/src/msgl-header.h +=================================================================== +--- gettext-0.21.orig/gettext-tools/src/msgl-header.h ++++ gettext-0.21/gettext-tools/src/msgl-header.h +@@ -40,6 +40,12 @@ extern void + message_list_delete_header_field (message_list_ty *mlp, + const char *field); + ++/* Read the given field from the header. ++ The FIELD name ends in a colon. */ ++extern void ++ message_list_read_header_field (message_list_ty *mlp, ++ const char *field, char **where_ptr); ++ + + #ifdef __cplusplus + } diff --git a/0002-msgcat-Merge-headers-when-use-first.patch b/0002-msgcat-Merge-headers-when-use-first.patch new file mode 100644 index 0000000..b40aaa7 --- /dev/null +++ b/0002-msgcat-Merge-headers-when-use-first.patch @@ -0,0 +1,304 @@ +From df4aef6209615bdd44cd45208acfe7367451a8fe Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Mark=C3=A9ta=20Cal=C3=A1bkov=C3=A1?= + +Date: Thu, 9 Jan 2020 14:45:49 +0100 +Subject: [PATCH 2/2] msgcat: Merge headers when --use-first + +Merging headers line by line is especially useful when +one header line is present only in the second file. +For example when Plural-Forms: is present only in the second file, +msgcat could create an invalid output file. +We also return error when Plural-Forms: values do not match. +--- + gettext-tools/src/message.c | 2 - + gettext-tools/src/msgl-cat.c | 5 ++ + gettext-tools/src/msgl-header.c | 155 +++++++++++++++++++++++++++++--- + gettext-tools/src/msgl-header.h | 8 ++ + 4 files changed, 157 insertions(+), 13 deletions(-) + +Index: gettext-0.20.1/gettext-tools/src/message.c +=================================================================== +--- gettext-0.20.1.orig/gettext-tools/src/message.c ++++ gettext-0.20.1/gettext-tools/src/message.c +@@ -411,7 +411,6 @@ message_list_insert_at (message_list_ty + } + + +-#if 0 /* unused */ + void + message_list_delete_nth (message_list_ty *mlp, size_t n) + { +@@ -431,7 +430,6 @@ message_list_delete_nth (message_list_ty + mlp->use_hashtable = false; + } + } +-#endif + + + void +Index: gettext-0.20.1/gettext-tools/src/msgl-cat.c +=================================================================== +--- gettext-0.20.1.orig/gettext-tools/src/msgl-cat.c ++++ gettext-0.20.1/gettext-tools/src/msgl-cat.c +@@ -40,6 +40,7 @@ + #include "msgl-age.h" + #include "msgl-ascii.h" + #include "msgl-equal.h" ++#include "msgl-header.h" + #include "msgl-iconv.h" + #include "xalloc.h" + #include "xmalloca.h" +@@ -286,6 +287,10 @@ catenate_msgdomain_list (string_list_ty + } + } + ++ /* Merge headers, please. */ ++ if (use_first) ++ msgdomain_lists_merge_headers (mdlps, nfiles); ++ + /* Create list of resulting messages, but don't fill it. Only count + the number of translations for each message. + If for a message, there is at least one non-fuzzy, non-empty translation, +Index: gettext-0.20.1/gettext-tools/src/msgl-header.c +=================================================================== +--- gettext-0.20.1.orig/gettext-tools/src/msgl-header.c ++++ gettext-0.20.1/gettext-tools/src/msgl-header.c +@@ -26,9 +26,12 @@ + #include + + #include "xalloc.h" ++#include "xerror.h" ++#include "xvasprintf.h" ++#include "gettext.h" + + #define SIZEOF(a) (sizeof(a) / sizeof(a[0])) +- ++#define _(str) gettext (str) + + /* The known fields in their usual order. */ + static const struct +@@ -50,6 +53,98 @@ known_fields[] = + { "Content-Transfer-Encoding:", sizeof ("Content-Transfer-Encoding:") - 1 } + }; + ++void ++msgdomain_lists_merge_headers (msgdomain_list_ty **mdlps, ++ size_t nfiles) ++{ ++ message_list_list_ty * headers = message_list_list_alloc (); ++ char * plur = "Plural-Forms:"; ++ char * plurals[nfiles]; ++ int plur_index = 0; ++ /* First, find all header entries and cut them to lines. */ ++ for (int n = 0; n < nfiles; n++) ++ { ++ msgdomain_list_ty *mdlp = mdlps[n]; ++ for (size_t k = 0; k < mdlp->nitems; k++) ++ { ++ message_list_ty * chopped = message_list_header_list (mdlp->item[k]->messages); ++ if (chopped) message_list_list_append (headers, chopped); ++ } ++ ++ /* Set plural to NULL by default. */ ++ plurals[n] = NULL; ++ } ++ /* While there are some messages remaining, take the first one. */ ++ while (headers->nitems > 0) ++ { ++ message_ty * field = headers->item[0]->item[0]; ++ /* Let us save plurals for later use. */ ++ if (strcmp(field->msgid, plur) == 0) ++ { ++ plurals[0] = XNMALLOC (field->msgstr_len+1, char); ++ strcpy (plurals[0], field->msgstr); ++ for (int i = 1; i < headers->nitems; i++) ++ { ++ message_ty * mp = message_list_search (headers->item[i], NULL, plur); ++ if (mp!=NULL) ++ { ++ plurals[i] = XNMALLOC (mp->msgstr_len+1, char); ++ strcpy (plurals[i], mp->msgstr); ++ } ++ } ++ } ++ /* Set the header field and delete all the occurences of the field. */ ++ msgdomain_list_set_header_field (mdlps[0], field->msgid, field->msgstr); ++ for (int i = 1; i < headers->nitems; i++) ++ { ++ message_ty * mp = message_list_search (headers->item[i], NULL, field->msgid); ++ if (mp != NULL) ++ { ++ /* If needed, fix line numbering in advance. */ ++ if (mp != headers->item[i]->item[0]) ++ for (int l = mp->pos.line_number - headers->item[i]->item[0]->pos.line_number + 1; l < headers->item[i]->nitems; l++) ++ headers->item[i]->item[l]->pos.line_number--; ++ message_list_delete_nth (headers->item[i], mp->pos.line_number - headers->item[i]->item[0]->pos.line_number); ++ } ++ } ++ message_list_delete_nth (headers->item[0], 0); ++ /* If the first header is empty, start to process next nonempty header. */ ++ while (headers->nitems > 0 && headers->item[0]->nitems == 0) ++ { ++ message_list_free (headers->item[0], 0); ++ for (int i = 0; i < headers->nitems - 1; i++) ++ headers->item[i] = headers->item[i+1]; ++ headers->nitems--; ++ } ++ } ++ ++ /* Some plural manipulation. */ ++ char *res = NULL; ++ char *prevres = NULL; ++ prevres = plurals[0]; ++ /* The prevres is the value currently in the output header, ++ * res is the value just read. So if res == NULL we just ++ * continue, which is correct. */ ++ for (int n = 1; n < nfiles; n++) ++ { ++ res = plurals[n]; ++ if (res != NULL) ++ { ++ if (prevres == NULL) ++ { ++ msgdomain_list_set_header_field (mdlps[0], plur, res); ++ prevres = res; ++ } ++ else if (strcmp (res, prevres) != 0) ++ { ++ multiline_error (xstrdup (""), ++ xasprintf (_("\ ++Input po files have different Plural-Forms. Invalid output file was created. \n\ ++Please, fix the plurals.\n"))); ++ } ++ } ++ } ++} + + void + msgdomain_list_set_header_field (msgdomain_list_ty *mdlp, +@@ -81,8 +176,8 @@ msgdomain_list_set_header_field (msgdoma + { + message_ty *mp = mlp->item[j]; + +- /* Modify the header entry. */ +- const char *header = mp->msgstr; ++ /* Modify the header entry (it does not have to be present). */ ++ const char *header = (mp->msgstr != NULL) ? mp->msgstr : "\0"; + char *new_header = + XNMALLOC (strlen (header) + 1 + + strlen (field) + 1 + strlen (value) + 1 + 1, +@@ -230,14 +325,14 @@ message_list_read_header_field (message_ + size_t field_len = strlen (field); + size_t j; + ++ *where_ptr = NULL; ++ + /* Search the header entry. */ + for (j = 0; j < mlp->nitems; j++) + if (is_header (mlp->item[j]) && !mlp->item[j]->obsolete) + { +- /* We found the correct message. */ ++ /* We found the correct message. */ + message_ty *mp = mlp->item[j]; +- +- /* Tag the header entry. */ + const char *header = mp->msgstr; + + /* Test whether the field occurs in the header entry. */ +@@ -247,7 +342,7 @@ message_list_read_header_field (message_ + { + if (strncmp (h, field, field_len) == 0) + break; +- /* Jump by lines. */ ++ /* Jump by lines. */ + h = strchr (h, '\n'); + if (h == NULL) + break; +@@ -257,15 +352,57 @@ message_list_read_header_field (message_ + { + /* We found it and it is nonempty. Read the value of the field. */ + h += field_len + 1; +- char *enh = strchr (h, '\n'); +- if (enh != NULL && *enh != '\0') ++ char *enh = strchr (h, '\n'); ++ if (enh != NULL && *enh != '\0') + { + *where_ptr = (char *)XNMALLOC (((enh - h) + 1), char); + memcpy (*where_ptr, h, enh - h); +- /* Make the string null-terminated. */ ++ /* Make the string null-terminated. */ + (*where_ptr)[enh-h] = '\0'; +- } ++ } + } + } + } + ++message_list_ty * ++message_list_header_list (message_list_ty *mlp) ++{ ++ size_t j; ++ ++ /* Search the header entry. */ ++ for (j = 0; j < mlp->nitems; j++) ++ if (is_header (mlp->item[j]) && !mlp->item[j]->obsolete) ++ { ++ /* We found the correct message. */ ++ message_ty *mp = mlp->item[j]; ++ const char *h = mp->msgstr; ++ message_list_ty * header = message_list_alloc (false); ++ int ctr = 0; ++ ++ while (*h != '\0') ++ { ++ char *enh = strchr (h, ':'); ++ enh++; ++ char * msgid = (char *)XNMALLOC (((enh - h) + 1), char); ++ memcpy (msgid, h, enh - h); ++ /* Make the string null-terminated. */ ++ (msgid)[enh-h] = '\0'; ++ h = enh + 1; ++ ++ enh = strchr (h, '\n'); ++ if (enh != NULL) ++ { ++ char * msgstr = (char *)XNMALLOC (((enh - h) + 1), char); ++ memcpy (msgstr, h, enh - h); ++ /* Make the string null-terminated. */ ++ msgstr[enh-h] = '\0'; ++ lex_pos_ty pos = {NULL, ctr++}; ++ message_list_append (header, message_alloc (NULL, msgid, NULL, msgstr, enh - h, &pos)); ++ h = enh + 1; ++ } ++ else return NULL; ++ } ++ return header; ++ } ++ return NULL; ++} +Index: gettext-0.20.1/gettext-tools/src/msgl-header.h +=================================================================== +--- gettext-0.20.1.orig/gettext-tools/src/msgl-header.h ++++ gettext-0.20.1/gettext-tools/src/msgl-header.h +@@ -33,6 +33,11 @@ extern "C" { + extern void + msgdomain_list_set_header_field (msgdomain_list_ty *mdlp, + const char *field, const char *value); ++/* Merge headers of po files. ++ */ ++extern void ++ msgdomain_lists_merge_headers (msgdomain_list_ty **mdlps, ++ size_t nfiles); + + /* Remove the given field from the header. + The FIELD name ends in a colon. */ +@@ -46,6 +51,9 @@ extern void + message_list_read_header_field (message_list_ty *mlp, + const char *field, char **where_ptr); + ++/* List all the headers from a po file. */ ++extern message_list_ty * ++ message_list_header_list (message_list_ty *mlp); + + #ifdef __cplusplus + } diff --git a/gettext-0.20.2.tar.xz b/gettext-0.20.2.tar.xz deleted file mode 100644 index e817eb2..0000000 --- a/gettext-0.20.2.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b22b818e644c37f6e3d1643a1943c32c3a9bff726d601e53047d2682019ceaba -size 9514892 diff --git a/gettext-0.20.2.tar.xz.sig b/gettext-0.20.2.tar.xz.sig deleted file mode 100644 index 63bfb21..0000000 --- a/gettext-0.20.2.tar.xz.sig +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN PGP SIGNATURE----- -Version: GnuPG v2 - -iQIcBAABCAAGBQJelYUvAAoJEPW+iyZ8akBtVTkP/R/mGzw/Pacu39DlJlCoUUfi -FO1eSEOzCffCQSSXah6myZqNYQF3HkBJvjfm1u9/FME5dvn1p+r4g3ko06v0a8KH -V6ByKCwdJo06TlsWgizN9idVxkonG5yYXkoJpw7yEksvXYrHieEah/YYhfQVB/N7 -rRB5SQgfpu+Uy51h/istslO6UF1GdbpMwPubyARg2EDWtkX0HQ0N4xq3RAHUz37S -nlbr2j/+D8u0EocQtFeeog5EugYBnLlbtEpunIUKML3QFRf6VDU3ChOeplKuStwS -iJIGlhaX4WGsbW431DAWar8gr8xp5t1OUhtp/FapG6Cdk5D0QerH7RJSFj01RFPq -EfHfTAuJi9oyzpNkAwCD92IaPd3ZRIjr9WkW+Y/QLE7yHXiLVOXRWI1colZBFyUr -gukuQ72g+E6VZYZdCult9UrGA+yc0ppGJhFu9eOaL2e4ScWb54+NuUkxwGNUEdj3 -kxGLofiQKJkvOeSGe6oMl8Rc96lCO1Z8pLwT6aRlj1vMOoIFfehZtFFRvesgpt7G -Jp7GhK2XXxJUqfMT6D2+J0Fp7CPe5buc/ak/x/lgfhI24/YmJuDs/OiiONh+3bPO -VIstn9yrITAbdCvIqaHu6ltB6exCArThtMVovYkaKgBQrGDUh9kgdr7HHen99lTd -QhtpcFSzd+eshh8ELDW+ -=5tvt ------END PGP SIGNATURE----- diff --git a/gettext-0.21.tar.xz b/gettext-0.21.tar.xz new file mode 100644 index 0000000..12eb03d --- /dev/null +++ b/gettext-0.21.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d20fcbb537e02dcf1383197ba05bd0734ef7bf5db06bdb241eb69b7d16b73192 +size 9714352 diff --git a/gettext-0.21.tar.xz.sig b/gettext-0.21.tar.xz.sig new file mode 100644 index 0000000..d3d5372 --- /dev/null +++ b/gettext-0.21.tar.xz.sig @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v2 + +iQIcBAABCAAGBQJfHh9mAAoJEPW+iyZ8akBtIXIQAKGUlp67181VBHA050f8pcxX +QHnQbna51vvUI/5zwO5gOJb/ocVBsrXM0wfBUmnSOVH+vKw2CGOil9QfmhTVEWNN +R4DBiFs3hMefabzdp177vWn6gBWYVZ10hQy/ptx4kaNEFHHaXo+ei0p0nfkpab5D +0cNniOCm35tkK0WeFgPESQeGpmItWXRsSkg+xeZblm1DJ4gbQYqCPgFJSYVZzq6G +PEfyISC1OAll8o0dz8D2nddkiVboBMaurXpuMt7CVCCjiEUWGyWiEdfhxBI/aE+z +bZ7hVCV2dThoFvz3ay90IjisjBhsNGQ9cEEB+hyvCfCX0c93OnAuD35nBvb4RfFK +Be1rFqp0SN7ZkeHp4djdDoze34ui0SHWRpzNjD7Hf/mz3SyxzuY6t7sPL1YObz8i +dlCXJ8uYoG9ZU74eDK9epVb880hOPL6G1NVqX859wS14vPH/IGIC7W+BYPBcYsSJ +InxaD2CU38iBrhNS6s8Y9hXjnTqyWWQ4e1yRl1m76MpSXDDwEUzTv2isyPlSJst6 +341V2TPAesXJzB/ndMcusUM2gK+63cH1VSByLn1FYB+InFxKzyUTP6JNqv3eECV8 +WTLD5RIccp391fuGtbIfccVVucOZhahzCxvouXGjQTmT6t28p72oCvroUySkvgoe +6en2/1+QyIzFLJqLCKBq +=02/q +-----END PGP SIGNATURE----- diff --git a/gettext-csharp.changes b/gettext-csharp.changes index e14e73e..2e3c499 100644 --- a/gettext-csharp.changes +++ b/gettext-csharp.changes @@ -1,3 +1,12 @@ +------------------------------------------------------------------- +Tue Jul 28 10:33:41 UTC 2020 - Christian Vögl + +-Updated to version 0.21 + * Improvements for translators: + When msgfmt writes a MO file, it now does so in such a way that processes + that are currently using an older copy of the MO file will not crash. + + ------------------------------------------------------------------- Mon Dec 9 11:17:04 UTC 2019 - Christian Vögl diff --git a/gettext-csharp.spec b/gettext-csharp.spec index e284e2f..17bf236 100644 --- a/gettext-csharp.spec +++ b/gettext-csharp.spec @@ -28,7 +28,7 @@ BuildRequires: perl-libintl-perl BuildRequires: tcl Requires: mono URL: http://www.gnu.org/software/gettext/ -Version: 0.20.2 +Version: 0.21 Release: 0 Summary: Native Language Support (NLS) for C# License: LGPL-2.1-or-later diff --git a/gettext-java.changes b/gettext-java.changes index da44e5c..8e18ced 100644 --- a/gettext-java.changes +++ b/gettext-java.changes @@ -1,3 +1,15 @@ +------------------------------------------------------------------- +Tue Jul 28 10:20:58 UTC 2020 - Christian Vögl + +- Updated to version 0.21 + - Java: + o xgettext now recognizes format strings in the Formatter syntax. They + are marked as 'java-printf-format' in POT and PO files. + o xgettext now recognizes text blocks as string literals. + - Improvements for translators: + o When msgfmt writes a MO file, it now does so in such a way that processes + that are currently using an older copy of the MO file will not crash. + ------------------------------------------------------------------- Tue Jun 11 13:12:37 UTC 2019 - Christian Vögl diff --git a/gettext-java.spec b/gettext-java.spec index 9f801ae..0d83211 100644 --- a/gettext-java.spec +++ b/gettext-java.spec @@ -17,7 +17,7 @@ Name: gettext-java -Version: 0.20.2 +Version: 0.21 Release: 0 Summary: Java Support for Native Language Support (NLS) License: LGPL-2.1-or-later diff --git a/gettext-runtime-mini.changes b/gettext-runtime-mini.changes index f881bd7..3b01c86 100644 --- a/gettext-runtime-mini.changes +++ b/gettext-runtime-mini.changes @@ -1,3 +1,39 @@ +------------------------------------------------------------------- +Fri Aug 7 07:46:39 UTC 2020 - Marketa Calabkova + +- Add multiple new features (bsc#1165138) +- Add patches: + * 0001-msgcat-Add-feature-to-use-the-newest-po-file.patch + * 0002-msgcat-Merge-headers-when-use-first.patch +- Reintroduce autoreconf call + +------------------------------------------------------------------- +Tue Jul 28 09:33:34 UTC 2020 - Christian Vögl + +- Update to 0.21: + * Programming languages support: + - Shell: + o xgettext now recognizes and ignores 'env' invocations and environment + variable assignments in front of commands. + - Java: + o xgettext now recognizes format strings in the Formatter syntax. They + are marked as 'java-printf-format' in POT and PO files. + o xgettext now recognizes text blocks as string literals. + - JavaScript: + xgettext parses JSX expressions more reliably. + - Ruby: + o xgettext now supports Ruby. + o 'msgfmt -c' now verifies the syntax of translations of Ruby format + strings. + * Improvements for translators: + - When msgfmt writes a MO file, it now does so in such a way that processes + that are currently using an older copy of the MO file will not crash. + + * Libtextstyle: + - Added support for emitting hyperlinks. + - New API for doing formatted output. + - The example programs support the NO_COLOR environment variable. + ------------------------------------------------------------------- Tue Jul 7 12:09:30 UTC 2020 - Christian Vögl diff --git a/gettext-runtime-mini.spec b/gettext-runtime-mini.spec index 7a33f8c..b29b705 100644 --- a/gettext-runtime-mini.spec +++ b/gettext-runtime-mini.spec @@ -20,9 +20,11 @@ %bcond_without mini Name: gettext-runtime-mini -Version: 0.20.2 +Version: 0.21 Release: 0 +BuildRequires: automake BuildRequires: gcc-c++ +BuildRequires: libtool # To get an updated linkdupes.sh (in case there are new dupes), temproarily enable: #BuildRequires: fdupes %if %{without mini} @@ -70,6 +72,9 @@ Patch6: gettext-dont-test-gnulib.patch Patch11: boo941629-unnessary-rpath-on-standard-path.patch # PATCH-FIX-SUSE Bug boo#1106843 Patch13: reproducible.patch +# PATCH-FEATURE bsc#1165138 +Patch14: 0001-msgcat-Add-feature-to-use-the-newest-po-file.patch +Patch15: 0002-msgcat-Merge-headers-when-use-first.patch %description This package contains the intl library as well as tools that ease the @@ -158,9 +163,13 @@ This package provides headers and static libraries for libtextstyle %patch6 -p1 %patch11 -p1 %patch13 -p1 +%patch14 -p1 +%patch15 -p1 %build %define _lto_cflags %{nil} +# expect a couple "You should update your `aclocal.m4' by running aclocal." +autoreconf -fiv #sh autogen.sh export CFLAGS="%{optflags} -pipe -W -Wall -Dgcc_is_lint" export CXXFLAGS="$CFLAGS -Dgcc_is_lint" diff --git a/gettext-runtime.changes b/gettext-runtime.changes index f881bd7..f59d2a0 100644 --- a/gettext-runtime.changes +++ b/gettext-runtime.changes @@ -1,3 +1,39 @@ +------------------------------------------------------------------- +Fri Aug 7 07:46:39 UTC 2020 - Marketa Calabkova + +- Add multiple new features (bsc#1165138) +- Add patches: + * 0001-msgcat-Add-feature-to-use-the-newest-po-file.patch + * 0002-msgcat-Merge-headers-when-use-first.patch +- Reintroduce utoreconf call + +------------------------------------------------------------------- +Tue Jul 28 09:33:34 UTC 2020 - Christian Vögl + +- Update to 0.21: + * Programming languages support: + - Shell: + o xgettext now recognizes and ignores 'env' invocations and environment + variable assignments in front of commands. + - Java: + o xgettext now recognizes format strings in the Formatter syntax. They + are marked as 'java-printf-format' in POT and PO files. + o xgettext now recognizes text blocks as string literals. + - JavaScript: + xgettext parses JSX expressions more reliably. + - Ruby: + o xgettext now supports Ruby. + o 'msgfmt -c' now verifies the syntax of translations of Ruby format + strings. + * Improvements for translators: + - When msgfmt writes a MO file, it now does so in such a way that processes + that are currently using an older copy of the MO file will not crash. + + * Libtextstyle: + - Added support for emitting hyperlinks. + - New API for doing formatted output. + - The example programs support the NO_COLOR environment variable. + ------------------------------------------------------------------- Tue Jul 7 12:09:30 UTC 2020 - Christian Vögl diff --git a/gettext-runtime.spec b/gettext-runtime.spec index 665e0aa..bdc5597 100644 --- a/gettext-runtime.spec +++ b/gettext-runtime.spec @@ -20,12 +20,14 @@ %bcond_with mini Name: gettext-runtime -Version: 0.20.2 +Version: 0.21 Release: 0 BuildRequires: gcc-c++ +BuildRequires: libtool # To get an updated linkdupes.sh (in case there are new dupes), temproarily enable: #BuildRequires: fdupes %if %{without mini} +BuildRequires: automake BuildRequires: glib2-devel BuildRequires: libcroco-devel BuildRequires: libxml2-devel @@ -70,6 +72,9 @@ Patch6: gettext-dont-test-gnulib.patch Patch11: boo941629-unnessary-rpath-on-standard-path.patch # PATCH-FIX-SUSE Bug boo#1106843 Patch13: reproducible.patch +# PATCH-FEATURE bsc#1165138 +Patch14: 0001-msgcat-Add-feature-to-use-the-newest-po-file.patch +Patch15: 0002-msgcat-Merge-headers-when-use-first.patch %description This package contains the intl library as well as tools that ease the @@ -158,9 +163,13 @@ This package provides headers and static libraries for libtextstyle %patch6 -p1 %patch11 -p1 %patch13 -p1 +%patch14 -p1 +%patch15 -p1 %build %define _lto_cflags %{nil} +# expect a couple "You should update your `aclocal.m4' by running aclocal." +autoreconf -fiv #sh autogen.sh export CFLAGS="%{optflags} -pipe -W -Wall -Dgcc_is_lint" export CXXFLAGS="$CFLAGS -Dgcc_is_lint"