xref: /openbsd/gnu/usr.bin/perl/lib/locale.pm (revision d415bd75)
1package locale;
2
3use strict;
4use warnings;
5
6our $VERSION = '1.10';
7use Config;
8
9$Carp::Internal{ (__PACKAGE__) } = 1;
10
11=head1 NAME
12
13locale - Perl pragma to use or avoid POSIX locales for built-in operations
14
15=head1 WARNING
16
17DO NOT USE this pragma in scripts that have multiple
18L<threads|threads> active.  The locale is not local to a single thread.
19Another thread may change the locale at any time, which could cause at a
20minimum that a given thread is operating in a locale it isn't expecting
21to be in.  On some platforms, segfaults can also occur.  The locale
22change need not be explicit; some operations cause perl to change the
23locale itself.  You are vulnerable simply by having done a C<"use
24locale">.
25
26=head1 SYNOPSIS
27
28    @x = sort @y;      # Native-platform/Unicode code point sort order
29    {
30        use locale;
31        @x = sort @y;  # Locale-defined sort order
32    }
33    @x = sort @y;      # Native-platform/Unicode code point sort order
34                       # again
35
36=head1 DESCRIPTION
37
38This pragma tells the compiler to enable (or disable) the use of POSIX
39locales for built-in operations (for example, LC_CTYPE for regular
40expressions, LC_COLLATE for string comparison, and LC_NUMERIC for number
41formatting).  Each "use locale" or "no locale"
42affects statements to the end of the enclosing BLOCK.
43
44See L<perllocale> for more detailed information on how Perl supports
45locales.
46
47On systems that don't have locales, this pragma will cause your operations
48to behave as if in the "C" locale; attempts to change the locale will fail.
49
50=cut
51
52# A separate bit is used for each of the two forms of the pragma, to save
53# having to look at %^H for the normal case of a plain 'use locale' without an
54# argument.
55
56$locale::hint_bits = 0x4;
57$locale::partial_hint_bits = 0x10;  # If pragma has an argument
58
59# The pseudo-category :characters consists of 2 real ones; but it also is
60# given its own number, -1, because in the complement form it also has the
61# side effect of "use feature 'unicode_strings'"
62
63sub import {
64    shift;  # should be 'locale'; not checked
65
66    $^H{locale} = 0 unless defined $^H{locale};
67    if (! @_) { # If no parameter, use the plain form that changes all categories
68        $^H |= $locale::hint_bits;
69
70    }
71    else {
72        my @categories = ( qw(:ctype :collate :messages
73                              :numeric :monetary :time) );
74        for (my $i = 0; $i < @_; $i++) {
75            my $arg = $_[$i];
76            my $complement = $arg =~ s/ : ( ! | not_ ) /:/x;
77            if (! grep { $arg eq $_ } @categories, ":characters") {
78                require Carp;
79                Carp::croak("Unknown parameter '$_[$i]' to 'use locale'");
80            }
81
82            if ($complement) {
83                if ($i != 0 || $i < @_ - 1)  {
84                    require Carp;
85                    Carp::croak("Only one argument to 'use locale' allowed"
86                                . "if is $complement");
87                }
88
89                if ($arg eq ':characters') {
90                    push @_, grep { $_ ne ':ctype' && $_ ne ':collate' }
91                                  @categories;
92                    # We add 1 to the category number;  This category number
93                    # is -1
94                    $^H{locale} |= (1 << 0);
95                }
96                else {
97                    push @_, grep { $_ ne $arg } @categories;
98                }
99                next;
100            }
101            elsif ($arg eq ':characters') {
102                push @_, ':ctype', ':collate';
103                next;
104            }
105
106            $^H |= $locale::partial_hint_bits;
107
108            # This form of the pragma overrides the other
109            $^H &= ~$locale::hint_bits;
110
111            $arg =~ s/^://;
112
113            eval { require POSIX; import POSIX 'locale_h'; };
114
115            # Map our names to the ones defined by POSIX
116            my $LC = "LC_" . uc($arg);
117
118            my $bit = eval "&POSIX::$LC";
119            if (defined $bit) { # XXX Should we warn that this category isn't
120                                # supported on this platform, or make it
121                                # always be the C locale?
122
123                # Verify our assumption.
124                if (! ($bit >= 0 && $bit < 31)) {
125                    require Carp;
126                    Carp::croak("Cannot have ':$arg' parameter to 'use locale'"
127                              . " on this platform.  Use the 'perlbug' utility"
128                              . " to report this problem, or send email to"
129                              . " 'perlbug\@perl.org'.  $LC=$bit");
130                }
131
132                # 1 is added so that the pseudo-category :characters, which is
133                # -1, comes out 0.
134                $^H{locale} |= 1 << ($bit + 1);
135            }
136        }
137    }
138
139}
140
141sub unimport {
142    $^H &= ~($locale::hint_bits|$locale::partial_hint_bits);
143    $^H{locale} = 0;
144}
145
1461;
147