From: Bruno Haible Date: Sun, 4 May 2025 14:42:38 +0000 (+0200) Subject: xgettext: Allow ignoring specific files in the POT-Creation-Date computation. X-Git-Tag: v0.25~22 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a6cafd7ae45d19fb4a986475e0298a3e92aab7f8;p=thirdparty%2Fgettext.git xgettext: Allow ignoring specific files in the POT-Creation-Date computation. Reported by Vaclav Slavik at . * autogen.sh (GNULIB_MODULES_TOOLS_FOR_SRC): Add hashkey-string, set. * gettext-tools/src/xgettext.c: Include gl_set.h, gl_xset.h, gl_hash_set.h, hashkey-string.h. (generated_files): New variables. (long_options): New option '--generated'. (main): Initialize generated_files. Handle the option '--generated'. (usage): Document the option '--generated'. (finalize_header): Filter out the generated_files from the file list. * gettext-tools/doc/xgettext.texi: Document the option '--generated'. * gettext-tools/tests/xgettext-git-1: Test the --generated option. * NEWS: Mention the new option. --- diff --git a/NEWS b/NEWS index 5c96e0024..d2a87986d 100644 --- a/NEWS +++ b/NEWS @@ -24,6 +24,10 @@ Version 0.25 - May 2025 strings. - A new example 'hello-modula2' has been added. +# Improvements for maintainers: + * xgettext has a new option '--generated' that customizes the way the + 'POT-Creation-Date' in the POT file is computed. + Version 0.24.1 - May 2025 * Bug fixes: diff --git a/autogen.sh b/autogen.sh index aed04d9a5..b181c523a 100755 --- a/autogen.sh +++ b/autogen.sh @@ -211,6 +211,7 @@ if ! $skip_gnulib; then gocomp-script hash-map hash-set + hashkey-string iconv javacomp javaexec @@ -240,6 +241,7 @@ if ! $skip_gnulib; then readdir relocatable-prog relocatable-script + set setlocale sf-istream sh-filename diff --git a/gettext-tools/doc/xgettext.texi b/gettext-tools/doc/xgettext.texi index 59d593204..8e6dbda7d 100644 --- a/gettext-tools/doc/xgettext.texi +++ b/gettext-tools/doc/xgettext.texi @@ -783,10 +783,21 @@ which the translators can contact you. The default value is empty, which means that translators will be clueless! Don't forget to specify this option. +@item --generated=@var{file} +@opindex --generated@r{, @code{xgettext} option} + +Declares that the given @var{file} is generated +and therefore should not have +an influence on the @samp{POT-Creation-Date} field in the output. + +When you specify this option, +you should also specify one or @code{--reference} options, +to indicate the files from which the given @var{file} was generated. + @item --reference=@var{file} @opindex --reference@r{, @code{xgettext} option} -Declares that the output depends on the contents of the given FILE. +Declares that the output depends on the contents of the given @var{file}. This has an influence on the @samp{POT-Creation-Date} field in the output. By default, @code{xgettext} determines the @samp{POT-Creation-Date} as diff --git a/gettext-tools/src/xgettext.c b/gettext-tools/src/xgettext.c index 255c9a87e..7a217a479 100644 --- a/gettext-tools/src/xgettext.c +++ b/gettext-tools/src/xgettext.c @@ -53,6 +53,10 @@ #include "dir-list.h" #include "file-list.h" #include "str-list.h" +#include "gl_set.h" +#include "gl_xset.h" +#include "gl_hash_set.h" +#include "hashkey-string.h" #include "error-progname.h" #include "progname.h" #include "relocatable.h" @@ -252,6 +256,9 @@ static bool add_itstool_comments = false; /* The file names whose version-controlled modification times shall be considered. */ static string_list_ty files_for_vc_mtime; +/* The file names whose (possibly version-controlled) modification times + shall be ignored. */ +static gl_set_t generated_files; /* Long options. */ static const struct option long_options[] = @@ -274,6 +281,7 @@ static const struct option long_options[] = { "force-po", no_argument, &force_po, 1 }, { "foreign-user", no_argument, NULL, CHAR_MAX + 2 }, { "from-code", required_argument, NULL, CHAR_MAX + 3 }, + { "generated", required_argument, NULL, CHAR_MAX + 24 }, { "help", no_argument, NULL, 'h' }, { "indent", no_argument, NULL, 'i' }, { "its", required_argument, NULL, CHAR_MAX + 20 }, @@ -397,6 +405,9 @@ main (int argc, char *argv[]) /* Set initial value of variables. */ default_domain = MESSAGE_DOMAIN_DEFAULT; string_list_init (&files_for_vc_mtime); + generated_files = + gl_set_create_empty (GL_HASH_SET, + hashkey_string_equals, hashkey_string_hash, NULL); xgettext_global_source_encoding = NULL; init_flag_table_c (); init_flag_table_objc (); @@ -741,6 +752,10 @@ main (int argc, char *argv[]) xgettext_no_git = true; break; + case CHAR_MAX + 24: /* --generated */ + gl_set_add (generated_files, optarg); + break; + default: usage (EXIT_FAILURE); /* NOTREACHED */ @@ -1315,6 +1330,10 @@ Output details:\n")); printf (_("\ --msgid-bugs-address=EMAIL@ADDRESS set report address for msgid bugs\n")); printf (_("\ + --generated=FILE Declares that the given FILE is generated and\n\ + therefore should not have an influence on the\n\ + 'POT-Creation-Date' field in the output.\n")); + printf (_("\ --reference=FILE Declares that the output depends on the contents\n\ of the given FILE. This has an influence on the\n\ 'POT-Creation-Date' field in the output.\n")); @@ -2340,17 +2359,34 @@ finalize_header (msgdomain_list_ty *mdlp) { /* Set the POT-Creation-Date field. */ { + /* First, filter out the generated files. */ + const char **filenames; + size_t nfiles; + { + const char **all_files = files_for_vc_mtime.item; + size_t num_all_files = files_for_vc_mtime.nitems; + filenames = XNMALLOC (num_all_files, const char *); + nfiles = 0; + for (size_t i = 0; i < num_all_files; i++) + { + const char *file = all_files[i]; + if (!gl_set_search (generated_files, file)) + filenames[nfiles++] = file; + } + } + + /* Then, take the maximum of the (possibly version-controlled) modification + times of these files. */ time_t stamp; struct timespec max_of_mtimes; - if (files_for_vc_mtime.nitems > 0 - && max_mtime (&max_of_mtimes, - files_for_vc_mtime.nitems, files_for_vc_mtime.item) - == 0) + if (nfiles > 0 && max_mtime (&max_of_mtimes, nfiles, filenames) == 0) /* Use the maximum of the encountered mtimes. */ stamp = max_of_mtimes.tv_sec; else /* Use the current time. */ time (&stamp); + free (filenames); + char *timestring = po_strftime (&stamp); msgdomain_list_set_header_field (mdlp, "POT-Creation-Date:", timestring); free (timestring); diff --git a/gettext-tools/tests/xgettext-git-1 b/gettext-tools/tests/xgettext-git-1 index c53149809..33f723179 100755 --- a/gettext-tools/tests/xgettext-git-1 +++ b/gettext-tools/tests/xgettext-git-1 @@ -261,3 +261,40 @@ EOF : ${DIFF=diff} ${DIFF} xg-gi-test1-h.ok xg-gi-test1-h.pot || Exit 1 + +# ------------------------------------------------------------------------------ +# Verify that a file specified through --generated is ignored in the +# POT-Creation-Date computation. + +TZ=UTC0 \ +${XGETTEXT} -o xg-gi-test1-i.tmp --no-location \ + --generated='Hadschi Halef Omar/ben/Hadschi Abul Abbas/ibn/Hadschi Dawuhd al Gossarah'/sequence999.c \ + 'Hadschi Halef Omar/ben/Hadschi Abul Abbas/ibn/Hadschi Dawuhd al Gossarah'/sequence{000,999}.c +LC_ALL=C tr -d '\r' < xg-gi-test1-i.tmp > xg-gi-test1-i.pot || Exit 1 + +cat <<\EOF > xg-gi-test1-i.ok +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-05-01 20:51+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "Hello, world!" +msgstr "" +EOF + +: ${DIFF=diff} +${DIFF} xg-gi-test1-i.ok xg-gi-test1-i.pot || Exit 1