git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: Jonathan Nieder <jrnieder@gmail.com>
Cc: git@vger.kernel.org, Jeff Epler <jepler@unpythonic.net>
Subject: Re: [PATCH/RFC 0/5] Add internationalization support to Git
Date: Sun, 30 May 2010 16:04:07 +0000	[thread overview]
Message-ID: <AANLkTimI5xGiq_GNF_H2bOLECw0NxOiCPsnRqOS39H32@mail.gmail.com> (raw)
In-Reply-To: <20100530014607.GA27387@progeny.tock>

On Sun, May 30, 2010 at 01:46, Jonathan Nieder <jrnieder@gmail.com> wrote:
> Hi Ævar,

Hi, and thanks for taking the time to review this.

> Ævar Arnfjörð Bjarmason wrote:
>
>>     I made three strings in git-pull.sh translatable as a proof of
>>     concept. One problem that I ran into is that xgettext(1) seems
>>     very particular when picking up translation strings. It accepts
>>     this:
>>
>>         gettext "hello world"; echo
>
> Does ‘gettext -s "hello world"’ work, too?  (Just curious.)

No, that just makes "-s" translatable. Even options that gettext
accepts don't work either, you have to use eval_gettext "\$foo"
instead of gettext -e "\$foo". The xgettext program is quite naïve
like that.

>>     but not this:
> [...]
>>
>>         gettext <<"END";
>> hello world
>> END
>>
>>     Maybe there's a way to make it play nice. But I just used a large
>>     multiline string as a workaround.
>
> Not so nice, but it seems that gettext expects a message id as
> an argument (i.e., it will only replace echo and not cat).

Yes. I mailed the maintainer about this. gettext would need to accept
text on STDIN and xgettext would need to find the messages for it to
work.

In the meantime we could just use multiline strings. It works for the
test suite.

>>     I don't know what to do about
>>     'die gettext' other than define a 'die_gettext' wrapper function
>>     and use `xgettext --keyword=die_gettext'.
>
> Sounds sensible.
>
>> One thing I haven't done is to try to go ahead and make massive
>> changes to the Git source code to make everything translatable.
>
> I am vaguely worried about performance.  Suppose a function does
>
>        for (i = 0; i < 1000000; i++)
>                printf(_("Some interesting label: %s\n"), foo(i));
>
> Will this compile to the equivalent of
>
>        const char *s = _("Some interesting label: %s\n");
>        for (i = 0; i < 1000000; i++)
>                printf(s, foo(i));
>
> Suppose someone decides to make that change by hand (maybe the
> loop is too large for the compiler to notice the potential
> winnings).  Then presumably gcc cannot be able to type-check the
> format any more.  Is there some way around this that avoids
> both speed regressions and loss of type-safety?

Any level of indirection is of course going to be slower, there's no
way around that. I made two test programs to test this out:

test-in-loop.c:

    #include <stdio.h>
    #include <stdlib.h>
    #include <locale.h>
    #include <libintl.h>

    #define _(s) gettext(s)

    int foo(long int x) {
        return x * x;
    }

    int main(void) {
        const char *podir = "/usr/local/share/locale";
        if(!podir) puts("zomg error");
        char *ret = bindtextdomain("git", podir);
        ret = setlocale(LC_MESSAGES, "");
        ret = setlocale(LC_CTYPE, "");
        ret = textdomain("git");

        for (long int i = 0; i < 10000000; i++) {
            printf(_("Some interesting label: %ld\n"), foo(i));
        }

        return 0;
    }

test-outside-loop.c:

    #include <stdio.h>
    #include <stdlib.h>
    #include <locale.h>
    #include <libintl.h>

    #define _(s) gettext(s)

    int foo(long int x) {
        return x * x;
    }

    int main(void) {
        const char *podir = "/usr/local/share/locale";
        if(!podir) puts("zomg error");
        char *ret = bindtextdomain("git", podir);
        ret = setlocale(LC_MESSAGES, "");
        ret = setlocale(LC_CTYPE, "");
        ret = textdomain("git");

        const char *s = _("Some interesting label: %ld\n");
        for (long int i = 0; i < 10000000; i++)
            printf(s, foo(i));

        return 0;
    }

Note that I use 10 million iterations, not 1 million like in your
example.

Here's how they compile:

    $ gcc -std=c99 -o test-in-loop test-in-loop.c ; gcc -std=c99 -o
test-outside-loop test-outside-loop.c
    test-in-loop.c: In function ‘main’:
    test-in-loop.c:21: warning: format ‘%ld’ expects type ‘long int’,
but argument 2 has type ‘int’

I.e. your concerns are valid. GCC won't catch an invalid format
specifier in this case.

And even though gettext tries to make cases like these fast
(http://www.gnu.org/software/hello/manual/gettext/Optimized-gettext.html)
it's still a lot slower than hardcoded English:

    perl -MBenchmark=:all -MData::Dump=dump -E 'cmpthese(10, {
         outside => sub { system "./test-outside-loop >/dev/null" },
         inside =>  sub { system "./test-in-loop >/dev/null" },
    });'

            s/iter  inside outside
    inside    13.4      --    -83%
    outside   2.26    495%      --

> Apologies if this was already answered in the earlier discussion.

What you can do (and this was covered) is to use msgfmt to check that
no translations use different format specifiers. But hopefully cases
where you have messages like these in tight loops and the message
lookup itself is a significant contributor to the program time will be
so rare as to not be an issue.

  reply	other threads:[~2010-05-30 16:04 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-05-29 22:45 [PATCH/RFC 0/5] Add internationalization support to Git Ævar Arnfjörð Bjarmason
2010-05-29 22:45 ` [PATCH 1/5] Add infrastructure for translating Git with gettext Ævar Arnfjörð Bjarmason
2010-05-29 22:45 ` [PATCH 2/5] gitignore: Ignore files generated by gettext Ævar Arnfjörð Bjarmason
2010-05-29 22:45 ` [PATCH 3/5] Makefile: Remove Gettext files on make clean Ævar Arnfjörð Bjarmason
2010-05-29 22:45 ` [PATCH 4/5] gettext: Add a skeleton po/is.po Ævar Arnfjörð Bjarmason
2010-05-29 22:45 ` [PATCH 5/5] Add infrastructure to make shellscripts translatable Ævar Arnfjörð Bjarmason
2010-05-30  1:46 ` [PATCH/RFC 0/5] Add internationalization support to Git Jonathan Nieder
2010-05-30 16:04   ` Ævar Arnfjörð Bjarmason [this message]
2010-05-30 22:23     ` Jonathan Nieder
2010-05-31 12:17       ` Ævar Arnfjörð Bjarmason
2010-05-30 20:54 ` [PATCH/RFC v2 0/6] " Ævar Arnfjörð Bjarmason
2010-05-30 20:54 ` [PATCH/RFC v2 1/6] Add infrastructure for translating Git with gettext Ævar Arnfjörð Bjarmason
2010-06-01 17:01   ` Jakub Narebski
2010-06-01 18:11     ` [PATCH/RCF] autoconf: Check if <libintl.h> exists and set NO_GETTEXT Ævar Arnfjörð Bjarmason
2010-06-01 21:22       ` Jakub Narebski
2010-05-30 20:54 ` [PATCH/RFC v2 2/6] gitignore: Ignore files generated by gettext Ævar Arnfjörð Bjarmason
2010-05-30 20:54 ` [PATCH/RFC v2 3/6] Makefile: Remove Gettext files on make clean Ævar Arnfjörð Bjarmason
2010-05-30 20:54 ` [PATCH/RFC v2 4/6] gettext: Add a Gettext interface for shell scripts Ævar Arnfjörð Bjarmason
2010-05-30 20:54 ` [PATCH/RFC v2 5/6] gettext: Add a Gettext interface for Perl Ævar Arnfjörð Bjarmason
2010-06-01 17:00   ` Jakub Narebski
2010-06-01 19:06     ` Ævar Arnfjörð Bjarmason
2010-06-02 11:47       ` Jakub Narebski
2010-05-30 20:54 ` [PATCH/RFC v2 6/6] gettext: Add a skeleton po/is.po Ævar Arnfjörð Bjarmason
2010-05-30 21:29   ` Jonathan Nieder
2010-05-30 21:39     ` Jonathan Nieder
2010-05-31 14:17     ` Ævar Arnfjörð Bjarmason
2010-06-01 23:39 ` [PATCH/RFC v3 0/7] Add internationalization support to Git Ævar Arnfjörð Bjarmason
2010-06-02  0:11   ` Ævar Arnfjörð Bjarmason
2010-06-02  1:05     ` [PATCH/RFC v4 " Ævar Arnfjörð Bjarmason
2010-06-02  1:05     ` [PATCH/RFC v4 1/7] Add infrastructure for translating Git with gettext Ævar Arnfjörð Bjarmason
2010-06-02  9:12       ` Peter Krefting
2010-06-02  9:29         ` Ævar Arnfjörð Bjarmason
2010-06-02 10:11           ` Peter Krefting
2010-06-02 10:56             ` Ævar Arnfjörð Bjarmason
2010-06-02 11:31               ` Peter Krefting
2010-06-02  1:05     ` [PATCH/RFC v4 2/7] gettext: Add a Gettext interface for shell scripts Ævar Arnfjörð Bjarmason
2010-06-02  1:06     ` [PATCH/RFC v4 3/7] gettext: Add a Gettext interface for Perl Ævar Arnfjörð Bjarmason
2010-06-02  1:06     ` [PATCH/RFC v4 4/7] Makefile: Don't install Gettext .mo files if NO_GETTEXT Ævar Arnfjörð Bjarmason
2010-06-02  1:06     ` [PATCH/RFC v4 5/7] Makefile: Override --keyword= for all languages Ævar Arnfjörð Bjarmason
2010-06-02  1:06     ` [PATCH/RFC v4 6/7] gettext: Sanity tests for Git's Gettext support Ævar Arnfjörð Bjarmason
2010-06-02  1:06     ` [PATCH/RFC v4 7/7] gettext: Add a skeleton po/is.po Ævar Arnfjörð Bjarmason
2010-06-02  6:32     ` [PATCH/RFC v3 0/7] Add internationalization support to Git Johannes Sixt
2010-06-02 22:33     ` [PATCH/RFC v5 0/2] Add infrastructure for translating Git with gettext Ævar Arnfjörð Bjarmason
2010-06-02 22:33     ` [PATCH/RFC v5 1/2] " Ævar Arnfjörð Bjarmason
2010-06-02 22:33     ` [PATCH/RFC v5 2/2] Add initial C, Shell and Perl gettext translations Ævar Arnfjörð Bjarmason
2010-06-01 23:39 ` [PATCH/RFC v3 1/7] Add infrastructure for translating Git with gettext Ævar Arnfjörð Bjarmason
2010-06-01 23:39 ` [PATCH/RFC v3 2/7] gettext: Add a Gettext interface for shell scripts Ævar Arnfjörð Bjarmason
2010-06-02  6:32   ` Johannes Sixt
2010-06-02  8:53     ` Ævar Arnfjörð Bjarmason
2010-06-02  9:38       ` Johannes Sixt
2010-06-01 23:39 ` [PATCH/RFC v3 3/7] gettext: Add a Gettext interface for Perl Ævar Arnfjörð Bjarmason
2010-06-01 23:39 ` [PATCH/RFC v3 4/7] Makefile: Don't install Gettext .mo files if NO_GETTEXT Ævar Arnfjörð Bjarmason
2010-06-01 23:39 ` [PATCH/RFC v3 5/7] Makefile: Override --keyword= for all languages Ævar Arnfjörð Bjarmason
2010-06-01 23:39 ` [PATCH/RFC v3 6/7] gettext: Basic sanity tests for Git's Gettext support Ævar Arnfjörð Bjarmason
2010-06-02  6:32   ` Johannes Sixt
2010-06-01 23:39 ` [PATCH/RFC v3 7/7] gettext: Add a skeleton po/is.po Ævar Arnfjörð Bjarmason

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=AANLkTimI5xGiq_GNF_H2bOLECw0NxOiCPsnRqOS39H32@mail.gmail.com \
    --to=avarab@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=jepler@unpythonic.net \
    --cc=jrnieder@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).