localehelper-0.1.7/0000755000000000000000000000000014473105101014150 5ustar00rootroot00000000000000localehelper-0.1.7/.perlcriticrc0000644000000000000000000000322414473105077016653 0ustar00rootroot00000000000000severity = 1 verbose = %f:%l: [%p] %m\n [-CodeLayout::ProhibitParensWithBuiltins] # no, thanks [-CodeLayout::RequireTidyCode] # no, thanks [-Documentation::PodSpelling] [-Documentation::RequirePodAtEnd] [-Documentation::RequirePodSections] # we keep the actual POD in a separate file [-ErrorHandling::RequireCarping] # die is good enough for our purposes [InputOutput::ProhibitBacktickOperators] only_in_void_context = 1 [InputOutput::RequireBriefOpen] lines = 20 [-InputOutput::RequireCheckedClose] [-InputOutput::RequireCheckedOpen] # already covered by RequireCheckedSyscalls [InputOutput::RequireCheckedSyscalls] functions = :builtins [Modules::ProhibitExcessMainComplexity] max_mccabe = 30 [-Modules::RequireVersionVar] # useful only for modules [-RegularExpressions::ProhibitEnumeratedClasses] # we work mostly with ASCII [-RegularExpressions::RequireDotMatchAnything] # we work mostly with single-line strings # reconsider when https://github.com/Perl-Critic/Perl-Critic/issues/551 is fixed [-RegularExpressions::RequireExtendedFormatting] # no, thanks [-RegularExpressions::RequireLineBoundaryMatching] # we work mostly with single-line strings # reconsider when https://github.com/Perl-Critic/Perl-Critic/issues/551 is fixed [-Subroutines::ProhibitSubroutinePrototypes] # no, thanks [-ValuesAndExpressions::ProhibitEmptyQuotes] # no, thanks [-ValuesAndExpressions::ProhibitMagicNumbers] # no, thanks [-ValuesAndExpressions::ProhibitNoisyQuotes] # no, thanks [-ValuesAndExpressions::ProhibitVersionStrings] # we don't care about Perl << 5.6, which doesn't support version strings [-Variables::RequireLocalizedPunctuationVars] allow = %ENV # vim:ft=dosini localehelper-0.1.7/Makefile0000644000000000000000000000361114473105077015625 0ustar00rootroot00000000000000# Copyright © 2018-2021 Jakub Wilk # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the “Software”), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. PERL = perl PREFIX = /usr/local DESTDIR = bindir = $(PREFIX)/bin mandir = $(PREFIX)/share/man .PHONY: all all: ; .PHONY: install install: localehelper install -d $(DESTDIR)$(bindir) perl -MConfig -p -e '$$. == 1 and s/#!.*/$$Config{startperl}/' \ $(<) > $(<).tmp install $(<).tmp $(DESTDIR)$(bindir)/$(<) rm $(<).tmp ifeq "$(wildcard doc/localehelper.1)" "" # run "$(MAKE) -C doc" to build the manpage else install -d $(DESTDIR)$(mandir)/man1/ install -m644 doc/$(<).1 $(DESTDIR)$(mandir)/man1/$(<).1 endif .PHONY: test test: prove --verbose .PHONY: test-installed test-installed: $(or $(shell command -v localehelper;),$(bindir)/localehelper) LOCALEHELPER_COMMANDLINE=localehelper prove --verbose .PHONY: clean clean: rm -f *.tmp .error = GNU make is required # vim:ts=4 sts=4 sw=4 noet localehelper-0.1.7/doc/0000755000000000000000000000000014473105101014715 5ustar00rootroot00000000000000localehelper-0.1.7/doc/LICENSE0000644000000000000000000000207414473105077015741 0ustar00rootroot00000000000000Copyright © 2012-2023 Jakub Wilk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. localehelper-0.1.7/doc/Makefile0000644000000000000000000000361514473105077016376 0ustar00rootroot00000000000000# Copyright © 2013-2022 Jakub Wilk # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the “Software”), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. version = $(shell IFS='()' read _ v _ < changelog && echo $$v) .PHONY: all all: localehelper.1 localehelper.1: manpage.pod changelog perl -p -e 's/L<([a-z_-]+)[(]([0-9]+)[)]>/B<\1>(\2)/g' $(<) \ | pod2man --utf8 -c '' -n LOCALEHELPER -r 'localehelper $(version)' \ > $(@).tmp mv $(@).tmp $(@) .PHONY: check check: check-changelog check-pod check-rst .PHONY: check-changelog check-changelog: changelog dpkg-parsechangelog -l$(<) --all 2>&1 >/dev/null | { ! grep .; } .PHONY: check-pod check-pod: manpage.pod podchecker -warnings -warnings $(<) rst2xml = $(notdir $(shell command -v rst2xml || echo rst2xml.py)) .PHONY: check-rst check-rst: $(rst2xml) --input-encoding=UTF-8 --strict README > /dev/null .PHONY: clean clean: rm -f *.1 *.tmp .error = GNU make is required # vim:ts=4 sts=4 sw=4 noet localehelper-0.1.7/doc/README0000644000000000000000000000114214473105077015607 0ustar00rootroot00000000000000Overview ======== **localehelper** is a helper tool for generating locales and setting `internationalization environment variables`_. .. _internationalization environment variables: https://www.gnu.org/software/gettext/manual/html_node/Setting-the-POSIX-Locale.html Example ------- .. code:: console $ locale -a | grep -c ^es 0 $ localehelper LANG=es_ES.UTF-8 locale mon | xargs -n1 -d ';' enero febrero marzo abril mayo junio julio agosto septiembre octubre noviembre diciembre Prerequisites ============= * Perl ≥ 5.10 .. vim:ft=rst ts=3 sts=3 sw=3 et localehelper-0.1.7/doc/changelog0000644000000000000000000000436514473105077016613 0ustar00rootroot00000000000000localehelper (0.1.7) unstable; urgency=low * Stop using switch statements (deprecated in Perl v5.38). Thanks to Niko Tyni for the bug report. https://bugs.debian.org/1042525 -- Jakub Wilk Mon, 28 Aug 2023 13:51:18 +0200 localehelper (0.1.6) unstable; urgency=low * Improve the build system: + Add checks against BSD make. + Use install(1) to install the executable. + Add “test-installed” target. * Improve documentation: + Rephrase description of the --help option. + Use HTTPS for pubs.opengroup.org. * Improve the test suite: + Fix script shebangs. + Make kill(1) call more portable. -- Jakub Wilk Fri, 20 Dec 2019 15:51:15 +0100 localehelper (0.1.5) unstable; urgency=low * Add Makefile. -- Jakub Wilk Thu, 15 Feb 2018 20:11:49 +0100 localehelper (0.1.4) unstable; urgency=low * Fix encoding normalization code for encodings containing only digits and punctuation characters. * Don't hardcode the Perl interpreter path in script shebang; use “#!/usr/bin/env perl” instead. * Make --help return with exit code 0. * Add a basic test suite. * Use HTTPS URLs when they are available, in documentation and code. -- Jakub Wilk Mon, 05 Oct 2015 23:21:12 +0200 localehelper (0.1.3) unstable; urgency=low * Fix encoding normalization code. * Improve error handling. * Tidy up the code. Thanks, perlcritic. -- Jakub Wilk Fri, 17 Jan 2014 00:36:02 +0100 localehelper (0.1.2) unstable; urgency=low * Improve the manual page: + Work around a pod2man bug: manual page references should be rendered in bold, not in italics. https://bugs.debian.org/280148 + Make the title all uppercase. + Document that TEXTDOMAINDIR environment variable is left untouched. * Disable warnings about use of smartmatch. -- Jakub Wilk Tue, 28 May 2013 18:53:30 +0200 localehelper (0.1.1) unstable; urgency=low * Improve the documentation. * Fix command-line argument parsing. -- Jakub Wilk Mon, 21 Jan 2013 13:02:01 +0100 localehelper (0.1) unstable; urgency=low * Initial release. -- Jakub Wilk Fri, 11 Jan 2013 23:04:08 +0100 localehelper-0.1.7/doc/localehelper.10000644000000000000000000001300614473105101017436 0ustar00rootroot00000000000000.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.43) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "LOCALEHELPER 1" .TH LOCALEHELPER 1 "2023-08-28" "localehelper 0.1.7" "" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" localehelper \- generate locales and set internationalization environment variables .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBlocalehelper\fR [\-x \fIlocale\fR[,\fIlocale\fR...]] [\fIintvar\fR=\fIlocale\fR[,\fIlocale-fallback\fR...]]... [\-\-] \fIcommandline\fR .PP \&\fBlocalehelper\fR {\-h | \-\-help} .SH "DESCRIPTION" .IX Header "DESCRIPTION" .IP "1. Set each internationalization environment variable to \fIlocale\fR (possibly falling back to \fIlocale-fallback\fR)." 4 .IX Item "1. Set each internationalization environment variable to locale (possibly falling back to locale-fallback)." .PD 0 .IP "2. Unset all other internationalization environment variables." 4 .IX Item "2. Unset all other internationalization environment variables." .IP "3. If needed, generate missing locales (in a temporary location)." 4 .IX Item "3. If needed, generate missing locales (in a temporary location)." .IP "4. Run the specified command." 4 .IX Item "4. Run the specified command." .PD .SH "OPTIONS" .IX Header "OPTIONS" .IP "\fB\-x\fR \fIlocale\fR[,\fIlocale\fR...]" 4 .IX Item "-x locale[,locale...]" Make sure these locales are available, even when they are not used in any internationalization environment variable. .IP "\fB\-h\fR, \fB\-\-help\fR" 4 .IX Item "-h, --help" Show help message and exit. .SH "ENVIRONMENT" .IX Header "ENVIRONMENT" The following environment variables can be set or unset by \fBlocalehelper\fR: .IP "\fB\s-1LANG\s0\fR" 4 .IX Item "LANG" fall-back for \fB\s-1LC_\s0\f(BI*\fB\fR variables .IP "\fB\s-1LC_COLLATE\s0\fR" 4 .IX Item "LC_COLLATE" affects regular expression matching and string collation. .IP "\fB\s-1LC_CTYPE\s0\fR" 4 .IX Item "LC_CTYPE" affects regular expression matching, character classification, conversion, case-sensitive comparison, and wide character functions .IP "\fB\s-1LC_MESSAGES\s0\fR" 4 .IX Item "LC_MESSAGES" affects natural-language messages .IP "\fB\s-1LC_MONETARY\s0\fR" 4 .IX Item "LC_MONETARY" affects monetary formatting .IP "\fB\s-1LC_NUMERIC\s0\fR" 4 .IX Item "LC_NUMERIC" affects number formatting .IP "\fB\s-1LC_TIME\s0\fR" 4 .IX Item "LC_TIME" affects time and date formatting .IP "other \fB\s-1LC_\s0\f(BI*\fB\fR" 4 .IX Item "other LC_*" may affect other linguistic and cultural aspects .IP "\fB\s-1LC_ALL\s0\fR" 4 .IX Item "LC_ALL" overrides all \fB\s-1LC_\s0\f(BI*\fB\fR .IP "\fB\s-1LANGUAGE\s0\fR" 4 .IX Item "LANGUAGE" affects natural-language messages .PP The following environment variables may be used by users to announce specific localization requirements to applications, but are left intact by \&\fBlocalehelper\fR: .IP "\fB\s-1NLSPATH\s0\fR" 4 .IX Item "NLSPATH" message catalogue path for \fBcatopen\fR(3) .IP "\fB\s-1TEXTDOMAIN\s0\fR" 4 .IX Item "TEXTDOMAIN" message catalogue domain for \fBgettext\fR(1) .IP "\fB\s-1TEXTDOMAINDIR\s0\fR" 4 .IX Item "TEXTDOMAINDIR" message catalogue directory for \fBgettext\fR(1) .SH "EXAMPLES" .IX Header "EXAMPLES" .Vb 10 \& $ localehelper LANG=es_ES.UTF\-8 locale mon | xargs \-n1 \-d \*(Aq;\*(Aq \& enero \& febrero \& marzo \& abril \& mayo \& junio \& julio \& agosto \& septiembre \& octubre \& noviembre \& diciembre .Ve .SH "SEE ALSO" .IX Header "SEE ALSO" .IP "\(bu" 2 \&\fBlocale\fR(7) .IP "\(bu" 2 \&\s-1POSIX:2004\s0 .IP "\(bu" 2 \&\s-1GNU\s0 gettext manual localehelper-0.1.7/doc/manpage.pod0000644000000000000000000000462514473105077017054 0ustar00rootroot00000000000000=encoding UTF-8 =head1 NAME localehelper - generate locales and set internationalization environment variables =head1 SYNOPSIS B [-x I[,I...]] [I=I[,I...]]... [--] I B {-h | --help} =head1 DESCRIPTION =over =item 1. Set each internationalization environment variable to I (possibly falling back to I). =item 2. Unset all other internationalization environment variables. =item 3. If needed, generate missing locales (in a temporary location). =item 4. Run the specified command. =back =head1 OPTIONS =over =item B<-x> I[,I...] Make sure these locales are available, even when they are not used in any internationalization environment variable. =item B<-h>, B<--help> Show help message and exit. =back =head1 ENVIRONMENT The following environment variables can be set or unset by B: =over =item B fall-back for B> variables =item B affects regular expression matching and string collation. =item B affects regular expression matching, character classification, conversion, case-sensitive comparison, and wide character functions =item B affects natural-language messages =item B affects monetary formatting =item B affects number formatting =item B affects time and date formatting =item other B> may affect other linguistic and cultural aspects =item B overrides all B> =item B affects natural-language messages =back The following environment variables may be used by users to announce specific localization requirements to applications, but are left intact by B: =over =item B message catalogue path for L =item B message catalogue domain for L =item B message catalogue directory for L =back =head1 EXAMPLES $ localehelper LANG=es_ES.UTF-8 locale mon | xargs -n1 -d ';' enero febrero marzo abril mayo junio julio agosto septiembre octubre noviembre diciembre =head1 SEE ALSO =over 2 =item * L =item * L =item * L =back localehelper-0.1.7/localehelper0000755000000000000000000001653614473105077016564 0ustar00rootroot00000000000000#!/usr/bin/env perl # Copyright © 2012-2023 Jakub Wilk # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the “Software”), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. =head1 SYNOPSIS B [-x I[,I...]] [I=I[,I...]]... [--] I =cut # cwd in @INC is harmful: # https://www.nntp.perl.org/group/perl.perl5.porters/2010/08/msg162729.html no lib '.'; use strict; use warnings; use v5.10; use English qw(-no_match_vars); use File::Temp qw(); my $myself = 'localehelper'; my $category_re = qr/(?:LC_[A-Z]+|LANG|LANGUAGE)/; my $locale_with_encoding_re = qr/^([^.@]+)[.]([^.@]+)((?:@.+)?)$/; sub clean_environment($) { my ($regex) = @_; my @keys_to_unset = grep { m/$regex/ } keys %ENV; delete @ENV{@keys_to_unset}; return; } sub update_environment(%) { my %env = @_; @ENV{keys(%env)} = values(%env); return; } sub normalize_encoding($) { # https://sourceware.org/git/?p=glibc.git;a=blob;f=intl/l10nflist.c;h=3d8344be7b9cb65ac2a7764a47aac4af424dcca8;hb=eefa3be8e4c2c721a9f277d8ea2e11180231829f#l313 # https://www.gnu.org/software/libc/manual/html_node/Using-gettextized-software.html local ($_) = @_; s/[^a-zA-Z0-9]+//g; if (m/^[0-9]+/) { return "iso$_"; } else { y/A-Z/a-z/; return $_; } } sub normalize_locale($) { local ($_) = @_; if (my ($prefix, $encoding, $suffix) = m/$locale_with_encoding_re/) { $encoding = normalize_encoding($encoding); return "$prefix.$encoding$suffix"; } return $_; } sub get_all_locales() { if (defined $ENV{LOCPATH}) { my @lst; push @lst, 'C'; push @lst, 'POSIX'; for (glob '/usr/lib/locale/*/') { s{.*/(.*)/}{$1} or die; push @lst, $1; } return @lst; } else { my $lst = qx(locale -a); if ($CHILD_ERROR != 0) { diag('warning: locale(1) failed'); $lst = ''; } return split(/\n/, $lst); } } sub get_encoding_map() { my %encodings = (); for (glob '/usr/share/i18n/charmaps/*') { s{.*/}{}; s/[.]gz$//; my $encoding = $_; my $nencoding = normalize_encoding($_); $encodings{$nencoding} = $encoding; } return \%encodings; } sub show_usage() { open(my $fh, '<', $PROGRAM_NAME) or die "$PROGRAM_NAME: $ERRNO"; my $in_synopsis = 0; while (<$fh>) { chomp; if (m/^=head1\s+SYNOPSIS$/) { $in_synopsis = 1; } elsif (m/^=/) { last if $in_synopsis; } elsif (m/^\S.*/) { if ($in_synopsis) { s/B<(.*?)>/$1/g; s/I(<.*?>)/$1/g; say {*STDERR} "Usage: $_" or die $ERRNO; close($fh) or die "$PROGRAM_NAME: $ERRNO"; return; } } } die; # unreachable statement } sub diag(@) { my (@message) = @_; say {*STDERR} "$myself: ", @message; ## no critic (CheckedSyscalls) return; } my @extra_locales = (); my %env = (); while (scalar(@ARGV) > 0) { $_ = $ARGV[0]; if (m/^($category_re)=(.*)$/) { my ($category, $locale) = ($1, $2); $env{$category} = $locale; shift @ARGV; next; } if ($_ eq '-x') { shift @ARGV; if (not @ARGV) { diag('error: -x requires an argument'); exit 1; } push @extra_locales, split(m/,/, shift @ARGV); next; } if ($_ eq '-h' or $_ eq '--help') { show_usage(); exit 0; } if ($_ eq '--') { shift @ARGV; last; } last; } if (not @ARGV) { exit 0; } clean_environment(qr/^$category_re$/); delete $ENV{LOCPATH}; my $locale_list = qx(locale -a); if ($CHILD_ERROR != 0) { diag('warning: locale(1) failed'); $locale_list = ''; } my %all_locales = map { $_ => 1 } get_all_locales(); my $no_missing_locales = 1; my %locales_to_generate = (); while (my ($category, $locales) = each %env) { next if $category eq 'LANGUAGE'; $locales_to_generate{$locales} = 1; my @nlocales = map { normalize_locale($_) } split(m/,/, $locales); $no_missing_locales &&= grep { exists $all_locales{$_} } @nlocales; } for my $locale (@extra_locales) { $locales_to_generate{$locale} = 1; my $nlocale = normalize_locale($locale); $no_missing_locales &&= exists $all_locales{$nlocale}; } my $missing_locales = not $no_missing_locales; if ($missing_locales) { my %encodings = %{get_encoding_map()}; my $locpath = $ENV{LOCPATH} = File::Temp::tempdir("$myself.XXXXXXXX", CLEANUP => 1, TMPDIR => 1); %all_locales = map { $_ => 1 } get_all_locales(); for my $locales (keys %locales_to_generate) { my @locales = split(m/,/, $locales); for my $locale (@locales) { if (exists $all_locales{$locale}) { last; } if (my ($prefix, $encoding, $suffix) = $locale =~ m/$locale_with_encoding_re/) { my $nencoding = normalize_encoding($encoding); my $nlocale = "$prefix.$nencoding$suffix"; if (exists $all_locales{$nlocale}) { last; } $encoding = $encodings{$nencoding} // $encoding; system('localedef', ## no critic (RequireCheckedSyscalls) '-f', $encoding, '-i', "$prefix$suffix", "$locpath/$nlocale/" ); if ($CHILD_ERROR) { diag("warning: localedef for $locale failed"); next } $all_locales{$nlocale} = 1; last; } else { diag("warning: cannot generate locale $locale"); } } } } while (my ($category, $locales) = each %env) { next if $category eq 'LANGUAGE'; my @locales = split(m/,/, $locales); my @existing_locales = grep { exists $all_locales{$_} or exists $all_locales{normalize_locale($_)} } @locales; if (@existing_locales) { $env{$category} = $existing_locales[0]; } else { local $LIST_SEPARATOR = ', '; diag("error: missing locales @locales"); exit 1; } } update_environment(%env); system { $ARGV[0] } @ARGV; ## no critic (RequireCheckedSyscalls) my $exit_code = ($CHILD_ERROR & 127) ? 1 : ($CHILD_ERROR >> 8); exit($exit_code); # vim:ts=4 sts=4 sw=4 et localehelper-0.1.7/private/0000755000000000000000000000000014473105101015622 5ustar00rootroot00000000000000localehelper-0.1.7/private/run-perlcritic0000755000000000000000000000115514473105077020530 0ustar00rootroot00000000000000#!/bin/sh # Copyright © 2014-2019 Jakub Wilk # SPDX-License-Identifier: MIT set -e -u export LC_ALL=C here=$(dirname "$0") cd "$here/.." perl -n -E 's/^\[-?// and s/\]$// and print' .perlcriticrc \ | sort -c target=$(mktemp -t localehelper.perlcritic.XXXXXX) run_perlcritic() { perlcritic "$@" >> "$target" && return rc=$? [ $rc -eq 2 ] || exit $rc } run_perlcritic "$@" localehelper run_perlcritic "$@" --exclude '::(Modules::RequireEndWithOne|Modules::RequireExplicitPackage)\b' t/*.t rc=0 grep -v ' source OK$' "$target" && rc=1 rm -f "$target" exit $rc # vim:ts=4 sts=4 sw=4 et localehelper-0.1.7/private/update-coverage0000755000000000000000000000023214473105077020634 0ustar00rootroot00000000000000#!/bin/sh set -e -u here=$(dirname "$0") cd "$here/.." export LOCALEHELPER_COMMANDLINE='perl -MDevel::Cover=-silent,1 ./localehelper' prove -v exec cover localehelper-0.1.7/t/0000755000000000000000000000000014473105077014427 5ustar00rootroot00000000000000localehelper-0.1.7/t/basic.t0000755000000000000000000000332214473105077015700 0ustar00rootroot00000000000000#!/usr/bin/env perl # Copyright © 2015-2019 Jakub Wilk # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the “Software”), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. no lib '.'; use strict; use warnings; use v5.10; use English qw(-no_match_vars); use FindBin (); use Test::More tests => 4; my $exe = $ENV{LOCALEHELPER_COMMANDLINE} // "$FindBin::Bin/../localehelper"; my $output = qx($exe LANG=es_ES.UTF-8 locale mon); is($CHILD_ERROR, 0, 'LANG exit code'); is($output, "enero;febrero;marzo;abril;mayo;junio;julio;agosto;septiembre;octubre;noviembre;diciembre\n", 'LANG output'); $output = qx($exe LANG=C LC_CTYPE=es_ES.UTF-8 locale charmap); is($CHILD_ERROR, 0, 'LANG+LC_CTYPE exit code'); is($output, "UTF-8\n", 'LANG+LC_CTYPE charmap'); # vim:ts=4 sts=4 sw=4 et localehelper-0.1.7/t/c.t0000755000000000000000000000311514473105077015041 0ustar00rootroot00000000000000#!/usr/bin/env perl # Copyright © 2015-2019 Jakub Wilk # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the “Software”), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. no lib '.'; use strict; use warnings; use v5.10; use English qw(-no_match_vars); use FindBin (); use Test::More tests => 4; my $exe = $ENV{LOCALEHELPER_COMMANDLINE} // "$FindBin::Bin/../localehelper"; sub t{ my ($locale) = @_; my $output = qx($exe LANG=$locale locale charmap); is($CHILD_ERROR, 0, "$locale => exit code 0"); is($output, "ANSI_X3.4-1968\n", "$locale => charmap is ASCII"); return; } t('C'); t('POSIX'); # vim:ts=4 sts=4 sw=4 et localehelper-0.1.7/t/help.t0000755000000000000000000000321014473105077015543 0ustar00rootroot00000000000000#!/usr/bin/env perl # Copyright © 2015-2019 Jakub Wilk # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the “Software”), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. no lib '.'; use strict; use warnings; use v5.10; use English qw(-no_match_vars); use FindBin (); use Test::More tests => 2; my $exe = $ENV{LOCALEHELPER_COMMANDLINE} // "$FindBin::Bin/../localehelper"; my $output = qx($exe --help 2>&1); $output =~ s/unexpected OP_PADRANGE at .+\n//; # https://bugs.debian.org/789487 is($CHILD_ERROR, 0, 'exit code 0'); is($output, "Usage: localehelper [-x [,...]] [=[,...]]... [--] \n", 'help message'); # vim:ts=4 sts=4 sw=4 et localehelper-0.1.7/t/numeric-encoding.t0000755000000000000000000000306114473105077020045 0ustar00rootroot00000000000000#!/usr/bin/env perl # Copyright © 2015-2019 Jakub Wilk # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the “Software”), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. no lib '.'; use strict; use warnings; use v5.10; use English qw(-no_match_vars); use FindBin (); use Test::More tests => 2; TODO: { local $TODO = q(broken on some systems for unknown reasons); my $exe = $ENV{LOCALEHELPER_COMMANDLINE} // "$FindBin::Bin/../localehelper"; my $output = qx($exe LANG=pl_PL.88592 locale charmap); is($CHILD_ERROR, 0, 'exit code 0'); is($output, "ISO-8859-2\n", 'correct charmap'); } # vim:ts=4 sts=4 sw=4 et localehelper-0.1.7/t/perl-version.t0000755000000000000000000000274714473105077017256 0ustar00rootroot00000000000000#!/usr/bin/env perl # Copyright © 2014-2019 Jakub Wilk # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the “Software”), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. no lib '.'; use strict; use warnings; use v5.10; use Test::More tests => 1; use Perl::MinimumVersion (); use FindBin (); my $exe = "$FindBin::Bin/../localehelper"; my $mv = Perl::MinimumVersion->new($exe); cmp_ok( $mv->minimum_explicit_version, 'ge', $mv->minimum_syntax_version, 'explicit version >= syntax version', ); # vim:ts=4 sts=4 sw=4 et localehelper-0.1.7/t/signal.t0000755000000000000000000000271014473105077016074 0ustar00rootroot00000000000000#!/usr/bin/env perl # Copyright © 2015-2019 Jakub Wilk # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the “Software”), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. no lib '.'; use strict; use warnings; use v5.10; use English qw(-no_match_vars); use FindBin (); use Test::More tests => 1; my $exe = $ENV{LOCALEHELPER_COMMANDLINE} // "$FindBin::Bin/../localehelper"; my $output = qx($exe LANG=es_ES.UTF-8 sh -c 'kill -s ABRT \$\$'); is($CHILD_ERROR, 1 << 8, 'exit code 1'); # vim:ts=4 sts=4 sw=4 et