After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 345027 - invalid ngettext calls in src/gnm-plugin.c
invalid ngettext calls in src/gnm-plugin.c
Status: RESOLVED FIXED
Product: Gnumeric
Classification: Applications
Component: General
git master
Other All
: Normal normal
: ---
Assigned To: Jody Goldberg
Jody Goldberg
Depends on:
Blocks:
 
 
Reported: 2006-06-15 16:22 UTC by tokul
Modified: 2006-06-22 22:11 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description tokul 2006-06-15 16:22:59 UTC
Please describe the problem:
src/gnm-plugin.c contains two ngettext calls.

ngettext (N_("User interface with %d action"),
          N_("User interface with %d actions"),
          n_actions)

ngettext (N_("%d function in category \"%s\""),
          N_("Group of %d functions in category \"%s\""),
          n_functions)

I think calls are invalid and normal gettext calls should not be used inside ngettext call.

Steps to reproduce:
intltool does not add ngettext strings to gnumeric.pot


Actual results:


Expected results:
I think correct function calls are

ngettext ("User interface with %d action",
          "User interface with %d actions",
          n_actions)

ngettext ("%d function in category \"%s\"",
          "Group of %d functions in category \"%s\"",
          n_functions)


Does this happen every time?


Other information:
I am not C programmer and I am not sure if proposed changes are correct.
Comment 1 Morten Welinder 2006-06-15 21:11:33 UTC
N_("string") expands to just "string", so no function is actually called.

Can you site a reference for your claim that the N_() markers should
go away?
Comment 2 tokul 2006-06-17 15:48:29 UTC
I don't have a reference. My experience says that you can't use variables and function calls inside gettext calls.

N_("string") expands to translated string. ngettext function won't find msgid of translated string in gnumeric.mo.

HEAD gnumeric.pot has 

----
#: ../src/gnm-plugin.c:407
#, c-format
msgid "User interface with %d action"
msgstr ""

#: ../src/gnm-plugin.c:408
#, c-format
msgid "User interface with %d actions"
msgstr ""
----
They are extracted from N_() calls.

gnumeric.pot does not have
----
#, c-format
msgid "User interface with %d action"
msgid_plural "User interface with %d actions"
msgstr[0] ""
msgstr[1] ""
----

I have posted question about it on gnome-i18n mailing list. Haven't got an answer yet.
Comment 3 Roozbeh Pournader 2006-06-17 18:06:54 UTC
Just confirming tokul's explanation. The way the quoted code is using ngettext would not work as it's supposed to. It will only work for languages using the same exact logic for plurals that English is using.
Comment 4 Andreas J. Guelzow 2006-06-17 21:34:52 UTC
The statement:
"N_("string") expands to translated string. ngettext function won't find msgid
of translated string in gnumeric.mo."
is simply not correct.
N_("string") expands to "string".
_("string") expands to translated string.


Why is 
----
#, c-format
msgid "User interface with %d action"
msgid_plural "User interface with %d actions"
msgstr[0] ""
msgstr[1] ""
----
any better than
----
#: ../src/gnm-plugin.c:407
#, c-format
msgid "User interface with %d action"
msgstr ""

#: ../src/gnm-plugin.c:408
#, c-format
msgid "User interface with %d actions"
msgstr ""
----
?
Comment 5 Andreas J. Guelzow 2006-06-17 21:48:16 UTC
Morten, you will find the reference in "info xgettext" in the description of the option --keyword:

xgettext will extract the first and second string argument from any call to ngettext. So without the N_, the two strings are going to be added to the pot file as Tokul suggests. 

On the other hand I still don't see why using N_ should be wrong, it is just unnecessary.

(Oh yeah: of course this assumes that our po/Makefile.in.in just adds the keywords _ and N_ and does not remove the default list.)
Comment 6 tokul 2006-06-18 05:51:23 UTC
Translation of "%d objects" to Lithuanian

%d is 1
1 objektas

%d is from 2 to 9
2-9 objektai

%d is from 10 to 20
10-20 objektu

%d is 21
21 objektas

%d is from 22 to 29
22-29 objektai

there are 3 different word forms for "object" in Lithuanian and they depend on
%d.  Only some languages have one noun form for %d = 1 and other form for %d >
1.

See
http://www.gnu.org/software/gettext/manual/html_chapter/gettext_10.html#SEC150

If "User interface with %d action" is translated with gettext call to Lithuanian, ngettext call looks up "Vartotojo sąsaja su %d veiksmu" msgid. ngettext can't find msgid "Vartotojo sąsaja su %d veiksmu" in gnumeric.mo and translation is done only with "User interface with %d action" for one action and "User interface with %d actions" for two and more actions.

You are not using ngettext. If you use N_() calls inside ngettext() call, ngettext call is useless, because 
a) ngettext strings are not extracted, 
b) even if translation contains entry with msgid and msgid_plural that I've shown in previous comment, it won't be used, because msgid is modified by N_() call.

I've already made mistake when I used your code to fix plural issues in Dia. See how ngettext is used in gnopernicus (http://cvs.gnome.org/viewcvs/gnopernicus/srcore/srctrl.c?rev=1.100&view=markup) or ekiga (http://cvs.gnome.org/viewcvs/ekiga/src/gui/addressbook.cpp?rev=1.33&view=markup).
Comment 7 Andreas J. Guelzow 2006-06-18 07:30:53 UTC
This makes sense to me. Thanks for the explanation. 
Comment 8 Andreas J. Guelzow 2006-06-18 07:35:46 UTC
I should have been more complete:

Your lithuanian example makes sense to me. Your explanation is not quite correct since N_ does not modify the string! N_ is not a gettext call (or any other function call).

Nevertheless, we should clearly use:

ngettext ("User interface with %d action",
          "User interface with %d actions",
          n_actions)

and make sure that ngettext is used as a keyword in the xgettext invocation (as it is by default unless one clears the default list.)
Comment 9 Danilo Segan 2006-06-19 14:28:32 UTC
The explanation is that you are combining two different things (regular gettext messages, and plural form messages), thus breaking xgettext.  It will work ok in code, but PO files will have incorrect messages.

So, altogether, it will break, since MO files will hold non-plural-form entries, and code will ask for plural-form messages (and they are coded differently in both PO and MO files).

(Just to chip in with an explanation :)
Comment 10 Andreas J. Guelzow 2006-06-22 22:11:30 UTC
fixed in cvs. (Note that the code didn't even work in Candian English.)