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


Reply via email to