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 536996 - Missing noop i18n macro equivalent to C_
Missing noop i18n macro equivalent to C_
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: general
unspecified
Other Linux
: Normal enhancement
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2008-06-06 15:49 UTC by Claude Paroz
Modified: 2008-07-18 18:14 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
[PATCH] Add NC_ as noop variant of C_. Bug #536996. (2.32 KB, patch)
2008-06-10 18:02 UTC, Christian Persch
needs-work Details | Review
patch (5.23 KB, patch)
2008-07-08 19:25 UTC, Christian Persch
committed Details | Review

Description Claude Paroz 2008-06-06 15:49:20 UTC
The new C_ macro is useful to take advantage of new msgctxt functionality of gettext.
However, there's no noop equivalent for this, thus it is difficult to replace code like this (from gnome-panel/panel-properties-dialog.c):

static OrientationComboItem orientation_items [] = {
	{ N_("Orientation|Top"),    PANEL_ORIENTATION_TOP    },
	{ N_("Orientation|Bottom"), PANEL_ORIENTATION_BOTTOM },
	{ N_("Orientation|Left"),   PANEL_ORIENTATION_LEFT   },
	{ N_("Orientation|Right"),  PANEL_ORIENTATION_RIGHT  }
};
...

gtk_list_store_set (model, &iter,
		COLUMN_TEXT, Q_(orientation_items [i].name),
		COLUMN_ITEM, &(orientation_items [i]),
		-1);
Comment 1 Christian Persch 2008-06-10 18:02:48 UTC
Created attachment 112495 [details] [review]
[PATCH] Add NC_ as noop variant of C_. Bug #536996.

 docs/reference/glib/glib-sections.txt |    1 +
 docs/reference/glib/tmpl/i18n.sgml    |   28 ++++++++++++++++++++++++++++
 glib/gi18n-lib.h                      |    1 +
 glib/gi18n.h                          |    1 +
 4 files changed, 31 insertions(+), 0 deletions(-)
Comment 2 Matthias Clasen 2008-06-10 23:10:04 UTC
That doesn't really look right to me. There is not much point in defining
an NC_ macro that is identical to N_. zShouldn't the macro do

#define NC_(Context, Message) (Context "\004" Message)

?

Then you can either get the translation by using Q_(string) or
manual g_dpgettext (NULL, string, 0), and there is no need to repeat the 
context in two places in the code.
Comment 3 Christian Persch 2008-06-11 00:38:44 UTC
It's not identical to N_. The proposed NC_ is to N_ as C_ is to _; that is it takes 2 arguments instead of just one.

Using your #define for NC_, you will still need to put the context in two places in the code since you need its strlen + 1 as the offset in g_dpgettext.

The point of the no-op NC_ is to annotate the string with context for extraction by intltool, but IMHO the C code should just see the plain string. You want to use it like this:

static const char *some_strings[] = {
  NC_("my context", "thing 0"),
  NC_("my context", "thing 1"),
  ...
};

g_print ("The thing is: %s", pgettext ("my context", some_strings[i]));

i.e. the eventual call to actually translate the string might not involve a string literal for the 2nd argument.

Also with my proposed definition of NC_, the Context string ends up only once in the actual binary, within the pgettext call, instead of N times prepended to the individual NC_-marked strings.
Comment 4 Matthias Clasen 2008-06-11 01:08:17 UTC
g_dpgettext can handle 0 for the offset, no need for strlen.

Your example keeps using pgettext(), which is not readily available. We should find a solution that allows to get the translation with functions that are available in glib and glibc. 
Comment 5 Christian Persch 2008-06-11 12:52:20 UTC
g_dpgettext only handles 0 offset correctly with '|' separator, not with \004.

I'd like a NC_ variant that doesn't put the context N times into the binary...

pgettext exists since gettext 0.15 which is already 2 years old. However if you're concerned about other platforms not supporting it, we could just move our own copy of it from gtk/gtkbuilderparser.c into glib under a different name...
Comment 6 Matthias Clasen 2008-06-11 14:51:12 UTC
[mclasen@localhost glib]$ nm -D /lib/libc.so.6  | grep gettext
004523d0 T __dcgettext
00452420 T __dgettext
004523d0 W dcgettext
00453bc0 W dcngettext
00452420 W dgettext
00453c10 W dngettext
00452450 W gettext
00453c50 W ngettext

pgettext only 'exists' in the form of the header /usr/share/gettext/gettext.h
Comment 7 Christian Persch 2008-06-11 16:12:21 UTC
You're right; I should've read the gettext docs more closely. 

So I think a solution should have the following characteristics:
- NC_ should not put the context string into the programme together with the mssage ID, to avoid it occurring N times in the binary if it's repeated (like e.g. in gtk's paper names strings)
- when actually translating the NC_ marked string later, it should allow non-string-literals for either the context and/or the message strings

So how about "#define NC_(Context, String) (String)" as in my previous patch, plus moving the dpgettext function from gtkbuilderparser.c to glib and documenting that you should use that to eventually translate the NC_ marked strings?
Comment 8 Matthias Clasen 2008-06-11 18:07:46 UTC
> So how about "#define NC_(Context, String) (String)" as in my previous patch,
> plus moving the dpgettext function from gtkbuilderparser.c to glib and
> documenting that you should use that to eventually translate the NC_ marked
> strings?

Sounds like a plan. The one problem is that there is already a g_dpgettext() in gi18n.h, so the obvious name is taken
Comment 9 Matthias Clasen 2008-06-11 18:09:43 UTC
Oh, also: g_dpgettext (NULL, Context "\004" Msgid, 0) _should_ work, since the initial dgettext call would find the translation. the msgidoffset is only relevant in the fallback case.
Comment 10 Behdad Esfahbod 2008-06-11 19:02:09 UTC
While you are at it, both of you should also check bug 503071.  Thanks.
Comment 11 Christian Persch 2008-07-08 19:25:14 UTC
Created attachment 114209 [details] [review]
patch

Unfortunately I couldn't think of a better name than g_dpgettext2 ...
Comment 12 Matthias Clasen 2008-07-17 02:04:29 UTC
The docs for NC_ should have a paragraph talking about necessary xgettext arguments, similar to what we have for Q_ and C_.


+ * This uses g_dgettext() internally.  See that functions for differences
+ * with dgettext() proper.
+ *

Should probably be "See that function "

Might also be nice to add a sentence about the similarity and differences to g_dpgettext and about the fact that g_dpgettext2 is useful in situations where
you want to keep the message context separate from the message id. Could point to the example in the NC_() docs.

With those changes, and with adding the new symbol to glib.symbols and the new apis to glib-sections.txt, it is good to go in.
Comment 13 Matthias Clasen 2008-07-18 18:14:44 UTC
In retrospect, it would have been better to only have the g_dpgettext2
variant and avoid g_dpgettext. Too late now...


        Bug 536996 – Missing noop i18n macro equivalent to C_

        * glib/glib.symbols:
        * glib/gstrfuncs.[hc]: Add g_dpgettext2() which is a
        variant of g_dpgettext() taking context and id as separate
        arguments.

        * glib/gi18n-lib.h:
        * glib/gi18n.h: Add an NC_() macro that is to C_() as N_()
        is to _().