This section explains how to code for proper messages localization by gettext package.
You should keep the surprise/po/${LANG}.po
source files for
message translations up to date. By make -C surprise/po
update-po
you will always update all PO files by examining all
*.c
source files (usually modified when time passes). Please do
this update-po
before starting any message translation.
If you add new file that uses translation macros, you must call
autogen
at first -- because it composes the list of files that
should be indexed. It doesn't do any M4 expansion etc., so if you want
to translate a string, you must write the _("...")
or
N_("...")
directly near the string. The only exceptions are
params.m4
and error.et
files -- autogen is modified to insert
params.c
and error_chket.h
files into POTFILES.in
altough
they don't exist yet. These generated files will contain N_("...")
macro calls generated by M4/com_err.
Then you should edit your file surprise/po/${LANG}.po
where
${LANG}
is the language you are appropriate for. You should always
search for two defects:
Although in classical editor (VIM etc.) the search is pretty easy, you will find more comfort in PO mode implemented in GNU Emacs editor. Please look into Texinfo manual for gettext package for more PO mode information.
When you are starting to implement new language translations, you should
update ALL_LINGUAS
variable in surprise/configure.in
file
accordingly. The surprise/po/${LANG}.po
file header can be by
copying it adapted from its mates.
Although _(variable)
syntax is usually identical to
gettext(variable)
, you should always use _(variable)
syntax in
Surprise project as this macro automatically expands to appropriate
dgettext()
call for libsurprise based code. As a further note I
must declare a specific requirement for _("string")
before
gettext("strings")
as otherwise translatable strings detection may
fail and you will remain with incorrect (incomplete) PO file.
As _(anything)
syntax will result in real function call, you may
not use it in places where executable code is not permitted. Typical
example is plain C global variable or structures defined in
declarations. Such _("string")
usages would result in GCC error
message `initializer element is not constant'. (Please note that C++
supports such code but Surprise project is written for compatibility
reasons in non-++, plain C.) In C you must use N_("string")
code
in these cases - translatable string detection will find this string
correctly although you have to use explicit _(variable)
construct
in ALL places where you want to access such N_(...)
initialized
variables.
Example showing the most effective use of _(...)
vs. N_(...)
directives:
#include "generic.h" /* take care of localization definitions/declarations */ struct x { int num; char *val; }; struct x Global={ 4, N_("foo") }; int main(void) { static struct x Static={ 4, N_("foo") }; struct x Local={ 5, _("bar") }; char *String=_("foobar"); printf("%s,%s,%s,%s\n",_(Global.val),_(Static.val),Local.val,String); return(0); }
Filesystem implementators have to respect dupl_parameter()
and
dupl_parameter_gettext()
accordingly. When they are initially
duplicating parameters from code-declared ones, *_getext
variant
should be used. In the case of possible duplication of already
generated memory-based structures, pure (non-*_gettext
) variant is
appropriate, of course. This paragraph accordingly applies also to
dupl_pars()
and dupl_pars_gettext()
functions.
`text domain' used in the following text corresponds to `.po', `.mo' or `.gmo' files (exact suffix depending on compilation stage). This file contains translation of all messages contained in the program using it, these files are all named according to their language. When this text domain file(s) get out of date, missing translation strings are still displayed but in their original english form.
Whole Surprise is now made as a single text domain named `surprise'. Both libsurprise part and all code of clients use this one text domain. When libsurprise will start to get more third-party clients with separated development from libsurprise, it will be apropriate to split this text domain.
locale_init()
call is appropriate only for use from packages using
text domain `surprise', e.g. Surprise clients. Whole `libsurprise'
does not use actually set default domain, it always accesses its
messages by explicit text domain use. You can use `libsurprise' from
third-party software without any fear about localization - libsurprise
will accept your setlocale(3)
settings and it is not concerned
about the text domain actually in default use.
locale_init()
should be called only from programs where all their
strings are translated in the range of `surprise' text domain. It is
used by Surprise clients to save code size by using convenient default
text domain `surprise'.