File Coverage

blib/lib/POSIX/Wide.pm
Criterion Covered Total %
statement 40 44 90.9
branch 2 6 33.3
condition n/a
subroutine 14 15 93.3
pod 5 5 100.0
total 61 70 87.1


line stmt bran cond sub pod time code
1             # Copyright 2009, 2010, 2011, 2014, 2024 Kevin Ryde
2              
3             # This file is part of POSIX-Wide.
4             #
5             # POSIX-Wide is free software; you can redistribute it and/or modify
6             # it under the terms of the GNU General Public License as published by the
7             # Free Software Foundation; either version 3, or (at your option) any later
8             # version.
9             #
10             # POSIX-Wide is distributed in the hope that it will be useful, but
11             # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12             # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13             # for more details.
14             #
15             # You should have received a copy of the GNU General Public License along
16             # with POSIX-Wide. If not, see .
17              
18              
19             # Possible funcs:
20             # asctime()
21             # ctime()
22             # Believe always ascii day/month, or at least that's what glibc gives.
23             #
24             # Different:
25             # strcoll()
26             # strxfrm()
27              
28              
29             package POSIX::Wide;
30 1     1   106491 use 5.008;
  1         5  
31 1     1   7 use strict;
  1         12  
  1         46  
32 1     1   6 use warnings;
  1         2  
  1         57  
33 1     1   570 use POSIX ();
  1         7916  
  1         30  
34 1     1   511 use Encode;
  1         15144  
  1         89  
35 1     1   452 use Encode::Locale; # has 'locale' from its initial 0.01 release
  1         3090  
  1         55  
36              
37             our $VERSION = 12;
38              
39 1     1   6 use Exporter;
  1         1  
  1         64  
40             our @ISA = ('Exporter');
41             our @EXPORT_OK = qw(localeconv perror strerror strftime tzname
42             $ERRNO $EXTENDED_OS_ERROR);
43             # not yet ...
44             # our %EXPORT_TAGS = (all => \@EXPORT_OK);
45              
46 1     1   597 use POSIX::Wide::ERRNO;
  1         3  
  1         45  
47             tie (our $ERRNO, 'POSIX::Wide::ERRNO');
48              
49 1     1   427 use POSIX::Wide::EXTENDED_OS_ERROR;
  1         3  
  1         368  
50             tie (our $EXTENDED_OS_ERROR, 'POSIX::Wide::EXTENDED_OS_ERROR');
51              
52              
53             our @LOCALECONV_STRING_FIELDS = (qw(decimal_point
54             thousands_sep
55             int_curr_symbol
56             currency_symbol
57             mon_decimal_point
58             mon_thousands_sep
59             positive_sign
60             negative_sign));
61              
62             # POSIX.xs of perl 5.10.1 has mon_thousands_sep conditionalized, so allow
63             # for it and maybe other fields to not exist.
64             #
65             # POSIX.xs omits fields which are empty strings "", so for example when
66             # positive_sign is an empty string (which is usual in an English locale)
67             # there's no such field in the POSIX::localeconv() return.
68             #
69             sub localeconv {
70 1     1 1 179084 my $l = POSIX::localeconv();
71 1         4 foreach my $key (@LOCALECONV_STRING_FIELDS) {
72 8 50       385 if (exists $l->{$key}) {
73 8         21 $l->{$key} = _to_wide($l->{$key});
74             }
75             }
76 1         37 return $l;
77             }
78              
79             # STDERR like POSIX/perror.al
80             sub perror {
81 0 0   0 1 0 if (@_) { print STDERR @_,': '; }
  0         0  
82 0         0 print STDERR strerror($!),"\n";
83             }
84              
85             sub strerror {
86 1     1 1 2182 return _to_wide (POSIX::strerror ($_[0]));
87             }
88              
89             # \020-\176 is printable ascii
90             # only basic control chars are allows through to strftime, in particular Esc
91             # is excluded in case the locale is shift-jis etc and it means something
92             sub strftime {
93 14     14 1 18716 (my $fmt = shift) =~ s{(%[\020-\176\t\n\r\f\a]*)}
94 16         382 { _to_wide(POSIX::strftime($1,@_)) }ge;
95 14         466 return $fmt;
96             }
97              
98             sub tzname {
99 1     1 1 1777 return map {_to_wide($_)} POSIX::tzname();
  2         50  
100             }
101              
102             sub _to_wide {
103 35     35   2209 my ($str) = @_;
104 35 50       172 if (utf8::is_utf8($str)) { return $str; }
  0         0  
105              
106             # netbsd langinfo(CODESET) returns "646" meaning ISO-646, ie. ASCII. Must
107             # put that through resolve_alias() to turn it into "ascii".
108             #
109 35         208 return Encode::decode ('locale', $str, Encode::FB_CROAK());
110             }
111              
112             1;
113             __END__