5 # Author: Jarkko Hietaniemi <Jarkko.Hietaniemi@hut.fi>
6 # Helsinki University of Technology, Finland
8 # Acks: Guy Decoux <decoux@moulon.inra.fr> understood
9 # overloading magic much deeper than I and told
10 # how to cut the size of this code by more than half.
11 # (my first version did overload all of lt gt eq le ge cmp)
13 # Purpose: compare 8-bit scalar data according to the current locale
15 # Requirements: Perl5 POSIX::setlocale() and POSIX::strxfrm()
17 # Exports: setlocale 1)
23 # setlocale(&LC_COLLATE, 'locale-of-your-choice'); # 4)
24 # $s1 = new Collate "scalar_data_1";
25 # $s2 = new Collate "scalar_data_2";
27 # now you can compare $s1 and $s2: $s1 le $s2
28 # to extract the data itself, you need to deref: $$s1
31 # 1) this uses POSIX::setlocale
32 # 2) the basic collation conversion is done by strxfrm() which
33 # terminates at NUL characters being a decent C routine.
34 # collate_xfrm handles embedded NUL characters gracefully.
35 # 3) due to cmp and overload magic, lt le eq ge gt work also
36 # 4) the available locales depend on your operating system;
37 # try whether "locale -a" shows them or the more direct
38 # approach "ls /usr/lib/nls/loc" or "ls /usr/lib/nls".
39 # The locale names are probably something like
40 # 'xx_XX.(ISO)?8859-N'.
42 # Updated: 19940913 1341 GMT
46 use POSIX qw(strxfrm LC_COLLATE);
51 @EXPORT = qw(collate_xfrm setlocale LC_COLLATE);
59 sub new { my $new = $_[1]; bless \$new }
62 my ($category, $locale) = @_[0,1];
64 POSIX::setlocale($category, $locale) if (defined $category);
66 $LOCALE = $locale || $ENV{'LC_COLLATE'} || $ENV{'LC_ALL'} || '';
72 $C->{$LOCALE}->{$s} = collate_xfrm($s)
73 unless (defined $C->{$LOCALE}->{$s}); # cache when met
82 for (split(/(\000+)/, $s)) {
83 $x .= (/^\000/) ? $_ : strxfrm("$_\000");
90 &C($_[0]) cmp &C($_[1]);
95 &I18N::Collate::setlocale();
97 1; # keep require happy