#! /usr/bin/perl # load_txi_modules: Load Texinfo modules for embedding Perl. # # Copyright 2010-2026 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, # or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # Trimmed down texi2any.pl that is used to load the modules when # Perl code is directly called from C and no Perl script is run. use 5.006; use strict; use warnings; # Through rules in Makefile.am, directory paths set through configure are # substituted directly in strings in the code, for example # $datadir = '/usr/share'; # We always use these strings as byte string, therefore we explicitly # set no utf8 to be sure that strings in code will never be considered as # character strings by Perl. no utf8; # check that autovivification do not happen incorrectly. #no autovivification qw(fetch delete exists store strict); # for file names portability use File::Spec; # for dirname and fileparse use File::Basename; my ($real_command_name, $command_directory, $command_suffix); my $datadir; # This big BEGIN block deals with finding modules and # some dependencies that we ship # * in source or # * installed or # * installed relative to the script BEGIN { ($real_command_name, $command_directory, $command_suffix) = fileparse($0, '.pl'); my $updir = File::Spec->updir(); # These are substituted by the Makefile to create "load_txi_modules". my $libdir = '/usr/lib64'; my $converter_libdir; if ('/usr/share' eq '@' .'datadir@' or defined($ENV{'TEXINFO_DEV_SOURCE'}) and $ENV{'TEXINFO_DEV_SOURCE'} ne '0') { # use installed path for datadir, even if uninstalled. datadir, # however, is only used for some directories. if ('/usr/share' eq '@' .'datadir@') { my $fallback_prefix = File::Spec->rootdir() . join('/', ('usr', 'local')); $datadir = "$fallback_prefix/share"; } else { $datadir = '/usr/share'; } # Use uninstalled modules # To find Texinfo::ModulePath if (defined($ENV{'t2a_builddir'})) { unshift @INC, join('/', ($ENV{'t2a_builddir'}, 'perl')); } else { unshift @INC, $command_directory; } require Texinfo::ModulePath; Texinfo::ModulePath::init(undef, undef, undef, 'updirs' => 1); } else { # Look for modules in their installed locations. $datadir = '/usr/share'; my $converter = 'texi2any'; my $modules_dir = join('/', ($datadir, $converter)); # look for package data in the installed location. $converter_libdir = join('/', ($libdir, $converter)); # try to make package relocatable, will only work if # standard relative paths are used if (! -f join('/', ($modules_dir, 'Texinfo', 'Parser.pm')) and -f join('/', ($command_directory, $updir, 'share', $converter, 'Texinfo', 'Parser.pm'))) { $datadir = join('/', ($command_directory, $updir, 'share')); $modules_dir = join('/', ($datadir, $converter)); $converter_libdir = join('/', ($command_directory, $updir, 'lib', $converter)); } unshift @INC, $modules_dir; require Texinfo::ModulePath; Texinfo::ModulePath::init($modules_dir, $converter_libdir, $datadir, 'installed' => 1); } } # end BEGIN BEGIN { # important to load early to set XS embedded before loading any # package with XS modules use Texinfo::XSLoader; Texinfo::XSLoader::set_XS_embedded(); my $enable_xs = 'no'; if ($enable_xs eq 'no') { die ("Cannot have XS disabled and embedding Perl\n"); } } use Locale::Messages; use Texinfo::Common; use Texinfo::Config; use Texinfo::Report; # Not a basic module, but contains the initialization of C data use Texinfo::Document; # Paths and file names #my $curdir = File::Spec->curdir(); #my $updir = File::Spec->updir(); my $sysconfdir; my $converter; my $fallback_prefix = File::Spec->rootdir() . join('/', ('usr', 'local')); # The @ delimited strings are substituted by the Makefile to create # "load_txi_modules". if ('/etc' ne '@' . 'sysconfdir@') { $sysconfdir = '/etc'; } else { $sysconfdir = "$fallback_prefix/etc"; } if ('texi2any' ne '@' . 'CONVERTER@') { $converter = 'texi2any'; } else { $converter = 'texi2any'; } # initial setup of messages internalisation framework # work-around in case libintl-perl do not do it itself # see http://www.gnu.org/software/gettext/manual/html_node/The-LANGUAGE-variable.html#The-LANGUAGE-variable if ((defined($ENV{"LC_ALL"}) and $ENV{"LC_ALL"} =~ /^(C|POSIX)$/) or (defined($ENV{"LANG"}) and $ENV{"LANG"} =~ /^(C|POSIX)$/)) { delete $ENV{"LANGUAGE"} if defined($ENV{"LANGUAGE"}); } #my $messages_textdomain = 'texinfo'; my $messages_textdomain = 'texinfo'; $messages_textdomain = 'texinfo' if ($messages_textdomain eq '@'.'PACKAGE@'); my $strings_textdomain = 'texinfo' . '_document'; $strings_textdomain = 'texinfo_document' if ($strings_textdomain eq '@'.'PACKAGE@' . '_document'); # we want a reliable way to switch locale, so we don't use the system # gettext. Locale::Messages->select_package('gettext_pp'); # Note: this uses installed or fallback directory messages when # the program is uninstalled Locale::Messages::bindtextdomain($messages_textdomain, join('/', ($datadir, 'locale'))); # Set initial configuration # We use the configured version for version. If not set we search in # configure.ac. # We do not fallback on a Texinfo module version to be able to # verify that there is no mismatch. # Version set in configure.ac and substituted in Makefile my $configured_version = '7.3'; if ($configured_version eq '@' . 'PACKAGE_VERSION@') { # if not configured/substituted, search for the version in configure.ac if (open(CONFIGURE, "< " . join('/', ($Texinfo::ModulePath::t2a_srcdir, 'configure.ac')))) { while () { if (/^AC_INIT\(\[[^\]]+\]\s*,\s*\[([^\]]+)\]\s*[,\)]/) { # add +nc to distinguish from configured and, in general, installed. # If called from build directory with TEXINFO_DEV_SOURCE=1, however # there will not be +nc as the $configured_version is set. $configured_version = "$1+nc"; last; } } close(CONFIGURE); } } if (!defined($configured_version)) { die "Cannot determine the texi2any version; aborting.\n"; } # Compare the version of this file with the version of the modules # it is using. If they are different, don't go any further. This # can happen if multiple versions are installed under a # different names, e.g. with the --program-suffix option to 'configure'. # The version in Common.pm is checked because that file has been present # since Texinfo 5.0 (the first release with texi2any in Perl). if ($configured_version ne $Texinfo::Common::VERSION and $configured_version ne $Texinfo::Common::VERSION."+nc") { warn "This is load_txi_modules $configured_version but modules ". "for texi2any $Texinfo::Common::VERSION found!\n"; die "Your installation of Texinfo is broken; aborting.\n"; } # Compare the version of the code embedding Perl passed on the # command-line with the version of the modules it is using. # If the version on the command-line cannot be read or # the versions are different, don't go any further. if ($#ARGV != 0 or !defined($ARGV[0]) or $ARGV[0] eq '') { die "$0: Unexpected command-line argument\n"; } my $caller_version = $ARGV[0]; if ($caller_version ne $Texinfo::Common::VERSION and $caller_version ne $Texinfo::Common::VERSION."+nc") { warn "The caller version is $caller_version but modules ". "for texi2any $Texinfo::Common::VERSION found!\n"; die "Your installation of Texinfo is broken; aborting.\n"; } my $configured_package = 'texinfo'; $configured_package = 'texinfo' if ($configured_package eq '@' . 'PACKAGE@'); my $configured_name = 'GNU Texinfo'; $configured_name = 'GNU Texinfo' if ($configured_name eq '@' .'PACKAGE_NAME@'); my $configured_name_version = "$configured_name $configured_version"; my $configured_url = 'https://www.gnu.org/software/texinfo/'; $configured_url = 'https://www.gnu.org/software/texinfo/' if ($configured_url eq '@' .'PACKAGE_URL@'); my $configured_information = { 'PACKAGE_VERSION' => $configured_version, 'PACKAGE' => $configured_package, 'PACKAGE_NAME' => $configured_name, 'PACKAGE_AND_VERSION' => $configured_name_version, 'PACKAGE_URL' => $configured_url, }; # set configure information as constants foreach my $configured_variable (keys(%$configured_information)) { Texinfo::Common::set_build_constant($configured_variable, $configured_information->{$configured_variable}); # set also with _CONFIG prepended, as in C code. Texinfo::Common::set_build_constant($configured_variable.'_CONFIG', $configured_information->{$configured_variable}); } # next three modules are basic and used in call_perl_function.c use Texinfo::Translations; use Texinfo::Convert::NodeNameNormalization; use Texinfo::Indices; if ($Texinfo::ModulePath::texinfo_uninstalled) { my $locales_dir = join('/', ($Texinfo::ModulePath::t2a_builddir, 'LocaleData')); if (-d $locales_dir) { Texinfo::Translations::configure($locales_dir, $strings_textdomain); } else { warn "Locales dir for document strings not found\n"; } } else { my $locales_dir = join('/', ($datadir, 'locale')); Texinfo::Translations::configure($locales_dir, $strings_textdomain); } # useful modules the user can always assume to have. use Texinfo::ManipulateTree; use Texinfo::Convert::Texinfo; use Texinfo::Convert::Utils; #print STDERR "$0 has run\n"; 1;