I made a patch for GNU gettext and the Japanese translation of messages.
To build the gnuplot for it, it is need to add compile options "-D_GNU_GETTEXT_ -DLOCALEDIR=/usr/local/share/locale -lintl"
and to copy the message file po/ja.gmo to $LOCALEDIR/ja/LC_MESSAGES/gnuplot.mo and
po/ja-utf8.gmo to $LOCALEDIR/ja_JP.UTF-8/LC_MESSAGES/gnuplot.mo.
I tested it only on Solaris 9 (with GNU gettext), so I don't know whether it may work on other platform.
a patch for GNU gettext and Japanese message file.
I worry that the patch touches many lines of code, and would require everyone working on the code to learn a new idiom for printing messages.
# diffstat gettext-1.diff
...
91 files changed, 1395 insertions(+), 1207 deletions(-)
I am wondering if it is possible to reach exactly the same goal by a slightly different path.
Instead of a thousand changes from
int_error(c_token, "internal error : df_readline returned %d ", j);
to
int_error(c_token, _("internal error : df_readline returned %d"), j);
it is possible instead rename int_error() to be real_int_error(), and define a macro
#define int_error(c_token, format, args...) \ real_int_error(c_token, _(format), args)
A similar macro would replace int_warn().
That way the original source code would remain unchanged except for inclusion of the new macro definition into util.h. That would be much easier to maintain, and easy to configure in or out if necessary.
The main difficulty I see is that the syntax I show above is specific to gcc.
ISO C (1999) supports a similar macro variant
#define int_error(c_token, format, __VA_ARGS__)
The C99 form is more difficult to work with, but in principle is more portable.
Up until now we have tried to avoid C99-specific code in gnuplot. But snprintf() has crept in, and the cvs source tree uses C99 structure initializers. So maybe it is not so bad to add a __VA_ARGS__ construct, at least as a configurable option.
Unfortunately, I strongly suspect neither of these options will work on Solaris 9. Unless maybe you are using a gcc port?
> #define int_error(c_token, format, args...) \ > real_int_error(c_token, _(format), args)
>
> A similar macro would replace int_warn().
It is a good solution for the compilation of gnuplot, but not for
xgettext, which picks up the messages of the form _(STRING) from
sources to *.po.
Off course, it can be done by hand, but it is difficult to
maintain the PO file in the way.
I think it should work for the translation also, because it is a macro rather than a subroutine. Expansion of the macro produces a line _in the source_ that looks like real_int_error( c_token, _(STRING), args).
In other words, you teach the C pre-processor (cpp) how to do exactly the same edits that your patch does by hand.
It is possible that you would have to modify the script that collects strings for translation so that it explicitly runs cpp first. I am not sure about that. That is, instead of collecting strings directly from
file.c
you would run the preprocessor:
cpp file.c file_trans.c
Now the file_trans.c contains a version of the original source code with all the macros expanded, so you can generate the *.po files from it.
> you would run the preprocessor:
> cpp file.c file_trans.c
> Now the file_trans.c contains a version of the original source code with
> all the macros expanded, so you can generate the *.po files from it.
It is a solution for _(), but not for N_(), which is only for xgettext.
And we sometimes want to see the original source file for translations of
messages. xgettext picks up each message with the line number and the
filename (ex. see gnuplot.pot), But in the way using cpp, we only obtain line
numbers for the file passed through cpp, and the file may not be appropriate
to read.
N_() macro is used for the string substituted to a variable "char *". If it is not "const char *",
we may replace N_() with _() directly, and if "const char*", we may also replace to
remove "const". If we don't use N_(), we can achieve your proposal.
I think there may remain 2 problems.
1) Though we remove _() in (graph|int|os)_(error|warn)(), there are many _() for substituted
string or in fprintf() and fputs(). Do you admit them ?
2) Since gnuplot.pot is template po file for every translators made by xgettext, the line
number included in the file should be for the original source file, not for "file_trans.c".
Not to use cpp, I think I have to make the pot file by 3 steps:
[a] pick up _() part for original sources,
[b] pick up (graph|int|os)_(error|warn)() and translate them to po file format,
[c] merge [a] and [b].
In this way, we don't need cpp and we can keep to use N_().
I will write the script for [b], make a new patch file., and send it again.
Maybe the --keyword=... option to xgettext may be of any help. If I understand the info file correctly, --keyword=int_error:2 should put all error strings into the .po file. No need for a cpp run, then.
Juergen
Thank you for your advice, Juergen. Certainly,
xgettext -kint_error:2 -kint_warn:2 -kgraph_error:1 -k_ -kN_
works well. This is a better solution than my plan [a-c].
I will remake my patch.
I made a new patch. I used xgettext with option:
-L C -k_ -kN_ -kint_error:2 -kint_warn:2 -kos_error:2 -kgraph_error:1 \ -kaxis_checked_extend_empty_range:2 -kAMIGA_ERROR:1 -kIfErrOut:3 -kcheck:1
for AMIGA_ERROR in term/amiga.trm, IfErrOut in term/unixpc.trm, and check in term/gpr.trm.
I don't use a mechanism int_error/real_int_error and modify int_error() directly to avoid
the macro with variable number of arguments.
a patch for GNU gettext and Japanese message file. no.2
add patch for qt terminal