Pádraig Brady wrote: > Paul Eggert wrote: >> Ondřej Vašík <ova...@redhat.com> writes: >> >>> as reported in https://bugzilla.redhat.com/show_bug.cgi?id=525134 by >>> Daniel Qarras, ls -l shows iso long format for en_* locales. >> >> I just now read that Bugzilla report, and the diagnosis and the >> patch do not seem correct. The diagnosis says: >> >>> In ls.c (case locale_time_style) is dcgettext (NULL, long_time_format[i], >>> LC_TIME); ... that translates the string, but the translation is THE SAME as >>> the default - as the format is the same for en_* locales. >> >> But that is not what the ls.c source code does. The code does this: >> >> char const *locale_format = >> dcgettext (NULL, long_time_format[i], LC_TIME); >> if (locale_format == long_time_format[i]) >> goto case_long_iso_time_style; >> >> The "==" test returns true when dcgettext returns the msgid (its 2nd >> argument) because it finds no translation. > > Right. We don't have any translations for "en".
This is key. Looking at Makefile.in.in, you can see that the file /usr/share/locale/en/LC_TIME/coreutils.mo is never installed, and neither is .../LC_MESSAGES/coreutils.mo, because coreutils has no po/en.po file. Pre-optimizers might argue that not installing the latter is a good thing, because gettext will then not waste time with the fstat+mmap+close that it normally performs after each successful .mo file open. Not to mention the cost of each subsequent failed message lookup. I try not to pre-optimize, so question whether the Makefile.in.in patch is worthwhile, but from an aesthetics point of view, I prefer not to install the LC_MESSAGES/coreutils.mo file. The core of the patch is this two-line addition: ++ lang=en; for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ ++ test -n "$$lc" && mv -f $(message_mo) $(lc_mo_file); done All of the rest is factoring. I'm leaning towards rewriting it to insert the non-factored equivalent. However, one advantage of using the patch is that it records the context: if we update to a newer gettext that changes the body of that rule, the patch will no longer apply, and that will make bootstrap fail. One alternative that could be used with the 3-line-insertion approach is to record (and always cross-check) a checksum of the rule contents. With this patch, in an en* locale, ls -l now uses the conventional date formats. Here's an incomplete patch. It needs a test and a NEWS entry. Ondřej, can you adjust your test to work (or skip) if there is no en* locale? >From 53c88d531d88e5d4ef393a61758bc3fee4894e48 Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyer...@redhat.com> Date: Sat, 26 Sep 2009 14:59:05 +0200 Subject: [PATCH] ls: use conventional date format in long listing for en* locales * bootstrap.conf: Generate po/en.po with identity translations for the two LC_TIME strings required by ls.c. * configure.ac: Require gettext version 0.17. * po/Makefile.in.in-patch: Patch autopoint-provided file so that it provides the LC_TIME .mo file, but not the LC_MESSAGES one. * po/.gitattributes: Allow space-before-TAB in the patch. --- bootstrap.conf | 41 +++++++++++++++++++++++++++++ configure.ac | 2 +- po/.gitattributes | 1 + po/Makefile.in.in-patch | 65 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 108 insertions(+), 1 deletions(-) create mode 100644 po/.gitattributes create mode 100644 po/Makefile.in.in-patch diff --git a/bootstrap.conf b/bootstrap.conf index 726092c..c2e349d 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -320,10 +320,51 @@ tar - # Automake requires that ChangeLog exist. touch ChangeLog || exit 1 +# The following is to accommodate coreutils' use of LC_TIME. +# Two steps: +# - create a nearly empty po/en.po +# - patch po/Makefile.in.in to do what we want at install-time +# +# The existence of po/en.po ensures that $(localedir)/en/LC_TIME/coreutils.mo +# will be created at install time. That file is required by ls.c's +# dcgettext call, when run in an en* locale. +date=$(date '+%F %H:%M%z') +ver=$(cat .prev-version) +pkg=$(sed -n 's/AC_INIT(\[GNU \(.*\)\],.*/\1/p' configure.ac) + +cat <<EOF > po/en.po +# Copyright 2009 Free Software Foundation, Inc. +# This file is distributed under the same license as the $pkg package. +msgid "" +msgstr "" +"Project-Id-Version: $pkg-$ver\n" +"Report-Msgid-Bugs-To: bug-$...@gnu.org\n" +"POT-Creation-Date: $date\n" +"PO-Revision-Date: $date\n" +"Last-Translator: nobody\n" +"Language-Team: none\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "%b %e %Y" +msgstr "%b %e %Y" + +msgid "%b %e %H:%M" +msgstr "%b %e %H:%M" +EOF + bootstrap_epilogue() { # Change paths in gnulib-tests/gnulib.mk from "../.." to "..". m=gnulib-tests/gnulib.mk sed 's,\.\./\.\.,..,g' $m > $m-t mv -f $m-t $m + + # Patch the autopoint-supplied po/Makefile.in.in to ensure that we + # install en/LC_TIME/coreutils.mo, but not, en/LC_MESSAGES/coreutils.mo. + # Thus, ls -l works properly in en* locales, yet those same locales do not + # incur the albeit-small cost of a translation look-up for each message. + (cd po && patch -p1 -V never --fuzz=0 Makefile.in.in Makefile.in.in-patch) \ + || exit 1 } diff --git a/configure.ac b/configure.ac index fa82b4c..9ad96d4 100644 --- a/configure.ac +++ b/configure.ac @@ -421,7 +421,7 @@ AC_SUBST([CONFIG_STATUS_DEPENDENCIES]) ############################################################################ AM_GNU_GETTEXT([external], [need-formatstring-macros]) -AM_GNU_GETTEXT_VERSION([0.15]) +AM_GNU_GETTEXT_VERSION([0.17]) # For a test of uniq: it uses the $LOCALE_FR envvar. gt_LOCALE_FR diff --git a/po/.gitattributes b/po/.gitattributes new file mode 100644 index 0000000..2336166 --- /dev/null +++ b/po/.gitattributes @@ -0,0 +1 @@ +Makefile.in.in-patch -whitespace diff --git a/po/Makefile.in.in-patch b/po/Makefile.in.in-patch new file mode 100644 index 0000000..5298ee3 --- /dev/null +++ b/po/Makefile.in.in-patch @@ -0,0 +1,65 @@ +--- po/Makefile.in.in.orig 2009-09-26 10:56:43.373721019 +0200 ++++ po/Makefile.in.in 2009-09-26 11:00:12.111846820 +0200 +@@ -218,6 +218,12 @@ install-data: install-da...@use_nls@ + else \ + : ; \ + fi ++ ++lang_dir = $(DESTDIR)$(localedir)/$$lang ++message_mo = $(lang_dir)/LC_MESSAGES/$(DOMAIN).mo ++lc_dir = $(lang_dir)/$$lc ++lc_mo_file = $(lc_dir)/$(DOMAIN).mo ++ + install-data-no: all + install-data-yes: all + $(mkdir_p) $(DESTDIR)$(datadir) +@@ -232,33 +238,35 @@ install-data-yes: all + echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \ + for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ + if test -n "$$lc"; then \ +- if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ +- link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ +- mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ +- mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ +- (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ ++ if (cd $(lang_dir) && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ ++ link=`cd $(lang_dir) && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ ++ mv $(lc_dir) $(lc_dir).old; \ ++ mkdir $(lc_dir); \ ++ (cd $(lc_dir).old && \ + for file in *; do \ + if test -f $$file; then \ +- ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ ++ ln -s ../$$link/$$file $(lc_dir)/$$file; \ + fi; \ + done); \ +- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ ++ rm -f $(lc_dir).old; \ + else \ +- if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ ++ if test -d $(lc_dir); then \ + :; \ + else \ +- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ +- mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ ++ rm -f $(lc_dir); \ ++ mkdir $(lc_dir); \ + fi; \ + fi; \ +- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ +- ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ +- ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ +- cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ +- echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \ ++ rm -f $(lc_mo_file); \ ++ ln -s ../LC_MESSAGES/$(DOMAIN).mo $(lc_mo_file) 2>/dev/null || \ ++ ln $(message_mo) $(lc_mo_file) 2>/dev/null || \ ++ cp -p $(message_mo) $(lc_mo_file); \ ++ echo "installing $$realcat link as $(lc_mo_file)"; \ + fi; \ + done; \ + done ++ lang=en; for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ ++ test -n "$$lc" && mv -f $(message_mo) $(lc_mo_file); done + + install-strip: install -- 1.6.5.rc2.177.ga9dd6