GNOME Bugzilla – Bug 345027
invalid ngettext calls in src/gnm-plugin.c
Last modified: 2006-06-22 22:11:30 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.
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?
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.
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.
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 "" ---- ?
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.)
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).
This makes sense to me. Thanks for the explanation.
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.)
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 :)
fixed in cvs. (Note that the code didn't even work in Candian English.)