gettext: Libraries

1 
1 4.10 Preparing Library Sources
1 ==============================
1 
1    When you are preparing a library, not a program, for the use of
1 ‘gettext’, only a few details are different.  Here we assume that the
1 library has a translation domain and a POT file of its own.  (If it uses
1 the translation domain and POT file of the main program, then the
1 previous sections apply without changes.)
1 
1   1. The library code doesn’t call ‘setlocale (LC_ALL, "")’.  It’s the
1      responsibility of the main program to set the locale.  The
1      library’s documentation should mention this fact, so that
1      developers of programs using the library are aware of it.
1 
1   2. The library code doesn’t call ‘textdomain (PACKAGE)’, because it
1      would interfere with the text domain set by the main program.
1 
1   3. The initialization code for a program was
1 
1             setlocale (LC_ALL, "");
1             bindtextdomain (PACKAGE, LOCALEDIR);
1             textdomain (PACKAGE);
1 
1      For a library it is reduced to
1 
1             bindtextdomain (PACKAGE, LOCALEDIR);
1 
1      If your library’s API doesn’t already have an initialization
1      function, you need to create one, containing at least the
1      ‘bindtextdomain’ invocation.  However, you usually don’t need to
1      export and document this initialization function: It is sufficient
1      that all entry points of the library call the initialization
1      function if it hasn’t been called before.  The typical idiom used
1      to achieve this is a static boolean variable that indicates whether
1      the initialization function has been called.  Like this:
1 
1           static bool libfoo_initialized;
1 
1           static void
1           libfoo_initialize (void)
1           {
1             bindtextdomain (PACKAGE, LOCALEDIR);
1             libfoo_initialized = true;
1           }
1 
1           /* This function is part of the exported API.  */
1           struct foo *
1           create_foo (...)
1           {
1             /* Must ensure the initialization is performed.  */
1             if (!libfoo_initialized)
1               libfoo_initialize ();
1             ...
1           }
1 
1           /* This function is part of the exported API.  The argument must be
1              non-NULL and have been created through create_foo().  */
1           int
1           foo_refcount (struct foo *argument)
1           {
1             /* No need to invoke the initialization function here, because
1                create_foo() must already have been called before.  */
1             ...
1           }
1 
1   4. The usual declaration of the ‘_’ macro in each source file was
1 
1           #include <libintl.h>
1           #define _(String) gettext (String)
1 
1      for a program.  For a library, which has its own translation
1      domain, it reads like this:
1 
1           #include <libintl.h>
1           #define _(String) dgettext (PACKAGE, String)
1 
1      In other words, ‘dgettext’ is used instead of ‘gettext’.
1      Similarly, the ‘dngettext’ function should be used in place of the
1      ‘ngettext’ function.
1