On Wed, Nov 27, 2024 at 04:29:43PM +0200, Eli Zaretskii wrote:
> > From: Gavin Smith <gavinsmith0...@gmail.com>
> > Date: Tue, 26 Nov 2024 18:33:31 +0000
> > 
> > On the two systems you mention (Cygwin64 and Macos-13), in spite of
> > Perl appearing to be new enough, calling gettext does not work.  It
> > is presumed that calling back into Perl would work, though.  Have I
> > understood the issue correctly?
> 
> Can you please explain what you mean by "calling back into Perl"?
> What kind of call is made from the C code of an XS, and what functions
> in Perl does it call?

It is possible to call any Perl function from C code using the Perl C
API and having a Perl interpreter available. It is described here:
 https://perldoc.perl.org/perlcall

The precise code is in tp/Texinfo/XS/main/call_perl_function.c, function
call_translations_translate_string.  There is some code to setup the
Perl stack, convert C to SV * Perl objects and push on the Perl stack:

  PUSHs(sv_2mortal (newSVpv_utf8 (string, 0)));
  PUSHs(sv_2mortal (newSVpv_utf8 (in_lang, 0)));
  PUSHs(sv_2mortal (newSVpv_utf8 (translation_context, 0)));

the call to the Perl function:
  count = call_pv (
    "Texinfo::Translations::translate_string",
    G_SCALAR);

and getting the result from the return of the Perl function:
  result_sv = POPs;
  result_ret = SvPVutf8 (result_sv, len);

> And also, do you have any guesses for why calling gettext from XS
> doesn't work?

My guess is that it is related to the switching of locale using calls to
getenv and searching for an existing locale to use the @documentlanguage,
as it has always been very fragile and prone to fail, both in pure Perl and
in C.  It could also fail because this local switching is done from C
called from Perl, we had trouble with that previously and needed to call
some Perl functions related to threads to make things work, while it
worked well from C only.

>  XS is just C code, 

It is just C code, but as said above, it is possible to call Perl code
from XS.

> and gettext is callable from C, so
> what could be the problem?

There is something going on that makes the C code fail to find the
translated strings, the workaround consist in calling the pure Perl
libintl-perl Gettext implementation from C through the mechanism
explained above to retrieve the translated string.  So, we actually
avoid calling the C gettext to get the output we want.

I think that it would be better to investigate why calling C gettext
from C code does not work, but it requires direct access to the
platforms.

-- 
Pat

Reply via email to