| package locale; |
| |
| our $VERSION = '1.09'; |
| use Config; |
| |
| $Carp::Internal{ (__PACKAGE__) } = 1; |
| |
| # A separate bit is used for each of the two forms of the pragma, to save |
| # having to look at %^H for the normal case of a plain 'use locale' without an |
| # argument. |
| |
| $locale::hint_bits = 0x4; |
| $locale::partial_hint_bits = 0x10; # If pragma has an argument |
| |
| # The pseudo-category :characters consists of 2 real ones; but it also is |
| # given its own number, -1, because in the complement form it also has the |
| # side effect of "use feature 'unicode_strings'" |
| |
| sub import { |
| shift; # should be 'locale'; not checked |
| |
| $^H{locale} = 0 unless defined $^H{locale}; |
| if (! @_) { # If no parameter, use the plain form that changes all categories |
| $^H |= $locale::hint_bits; |
| |
| } |
| else { |
| my @categories = ( qw(:ctype :collate :messages |
| :numeric :monetary :time) ); |
| for (my $i = 0; $i < @_; $i++) { |
| my $arg = $_[$i]; |
| $complement = $arg =~ s/ : ( ! | not_ ) /:/x; |
| if (! grep { $arg eq $_ } @categories, ":characters") { |
| require Carp; |
| Carp::croak("Unknown parameter '$_[$i]' to 'use locale'"); |
| } |
| |
| if ($complement) { |
| if ($i != 0 || $i < @_ - 1) { |
| require Carp; |
| Carp::croak("Only one argument to 'use locale' allowed" |
| . "if is $complement"); |
| } |
| |
| if ($arg eq ':characters') { |
| push @_, grep { $_ ne ':ctype' && $_ ne ':collate' } |
| @categories; |
| # We add 1 to the category number; This category number |
| # is -1 |
| $^H{locale} |= (1 << 0); |
| } |
| else { |
| push @_, grep { $_ ne $arg } @categories; |
| } |
| next; |
| } |
| elsif ($arg eq ':characters') { |
| push @_, ':ctype', ':collate'; |
| next; |
| } |
| |
| $^H |= $locale::partial_hint_bits; |
| |
| # This form of the pragma overrides the other |
| $^H &= ~$locale::hint_bits; |
| |
| $arg =~ s/^://; |
| |
| eval { require POSIX; import POSIX 'locale_h'; }; |
| |
| # Map our names to the ones defined by POSIX |
| my $LC = "LC_" . uc($arg); |
| |
| my $bit = eval "&POSIX::$LC"; |
| if (defined $bit) { # XXX Should we warn that this category isn't |
| # supported on this platform, or make it |
| # always be the C locale? |
| |
| # Verify our assumption. |
| if (! ($bit >= 0 && $bit < 31)) { |
| require Carp; |
| Carp::croak("Cannot have ':$arg' parameter to 'use locale'" |
| . " on this platform. Use the 'perlbug' utility" |
| . " to report this problem, or send email to" |
| . " 'perlbug\@perl.org'. $LC=$bit"); |
| } |
| |
| # 1 is added so that the pseudo-category :characters, which is |
| # -1, comes out 0. |
| $^H{locale} |= 1 << ($bit + 1); |
| } |
| } |
| } |
| |
| } |
| |
| sub unimport { |
| $^H &= ~($locale::hint_bits|$locale::partial_hint_bits); |
| $^H{locale} = 0; |
| } |
| |
| 1; |