Skip to content

Commit

Permalink
Wrap CORE::readdir to provide UTF-8 filenames
Browse files Browse the repository at this point in the history
readdir returns filenames as bytes, but that is
inconvenient. Now, we wrap readdir and decode the
returned filenames so the user is presented with
the UTF-8 filenames they expected.

Thanks for Leon Timmermans for code review

Fixes GH #11
  • Loading branch information
doherty committed Oct 25, 2012
2 parents 7978a07 + 919b24c commit bc37b2a
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 3 deletions.
1 change: 1 addition & 0 deletions Changes
Expand Up @@ -4,6 +4,7 @@ Revision history for Perl module {{$dist->name}}
* Enable unicode_strings (see perldoc feature) [GH #2] * Enable unicode_strings (see perldoc feature) [GH #2]
* Enable unicode_eval (see perldoc feature) [GH #2] * Enable unicode_eval (see perldoc feature) [GH #2]
* Enable fc (see perldoc fc) [GH #2] * Enable fc (see perldoc fc) [GH #2]
* Wrap CORE::readdir to provide UTF-8 filenames [GH #11]


0.007 2012-08-01 0.007 2012-08-01
* Use version.pm for comparing versions in the test suite * Use version.pm for comparing versions in the test suite
Expand Down
Empty file added corpus/みかちゃん
Empty file.
1 change: 1 addition & 0 deletions dist.ini
Expand Up @@ -7,6 +7,7 @@ copyright_year = 2009


[@Author::DOHERTY] [@Author::DOHERTY]
has_version = 0 has_version = 0
disable_tests = Test::Portability


[Conflicts] [Conflicts]
autodie = 2.11 autodie = 2.11
19 changes: 19 additions & 0 deletions lib/utf8/all.pm
Expand Up @@ -51,6 +51,11 @@ sub import {
'feature'->import::into($target, qw{unicode_strings}) if $^V >= v5.11.0; 'feature'->import::into($target, qw{unicode_strings}) if $^V >= v5.11.0;
'feature'->import::into($target, qw{unicode_eval fc}) if $^V >= v5.16.0; 'feature'->import::into($target, qw{unicode_eval fc}) if $^V >= v5.16.0;


{
no strict qw(refs); ## no critic (TestingAndDebugging::ProhibitNoStrict)
*{$target . '::readdir'} = \&_utf8_readdir;
}

# utf8 in @ARGV # utf8 in @ARGV
state $have_encoded_argv = 0; state $have_encoded_argv = 0;
_encode_argv() unless $have_encoded_argv++; _encode_argv() unless $have_encoded_argv++;
Expand All @@ -65,6 +70,20 @@ sub _encode_argv {
return; return;
} }


sub _utf8_readdir(*) { ## no critic (Subroutines::ProhibitSubroutinePrototypes)
my $handle = shift;
if (wantarray) {
my @all_files = CORE::readdir($handle);
$_ = Encode::decode('UTF-8', $_) for @all_files;
return @all_files;
}
else {
my $next_file = CORE::readdir($handle);
$next_file = Encode::decode('UTF-8', $next_file);
return $next_file;
}
}

=head1 INTERACTION WITH AUTODIE =head1 INTERACTION WITH AUTODIE
If you use L<autodie>, which is a great idea, you need to use at least version If you use L<autodie>, which is a great idea, you need to use at least version
Expand Down
41 changes: 38 additions & 3 deletions t/autodie.t
@@ -1,10 +1,45 @@
use strict; use strict;
use warnings; use warnings;
use version 0.77; use version 0.77;
use Test::More tests => 1; use Test::More 0.96;
use Test::Fatal;


if ( eval { require autodie; 1 } ) { if ( eval { require autodie; 1 } ) {
diag "autodie is version $autodie::VERSION, but must be greater than version 2.11" plan skip_all => "autodie is version $autodie::VERSION, but must be greater than version 2.11"
if (version->parse($autodie::VERSION) < version->parse(2.11)); if (version->parse($autodie::VERSION) < version->parse(2.11));
plan tests => 2;
} }
pass; else {
plan skip_all => "autodie is required for these tests";
}
no autodie;

subtest 'autodie first' => sub {
plan tests => 2;
use autodie;
use utf8::all;

opendir my $dh, 'corpus';
my @files = grep { !m{^\.} } readdir $dh;
closedir $dh;

is_deeply \@files, ["\x{307f}\x{304b}\x{3061}\x{3083}\x{3093}", "testfile"];

my $exception = exception { opendir my $no_dh, 'nonexistent' };
like $exception => qr/No such file or directory/;
};

subtest 'autodie last' => sub {
plan tests => 2;
use utf8::all;
use autodie;

opendir my $dh, 'corpus';
my @files = grep { !m{^\.} } readdir $dh;
closedir $dh;

is_deeply \@files, ["\x{307f}\x{304b}\x{3061}\x{3083}\x{3093}", "testfile"];

my $exception = exception { opendir my $no_dh, 'nonexistent' };
like $exception, qr/No such file or directory/;
};
39 changes: 39 additions & 0 deletions t/readdir.t
@@ -0,0 +1,39 @@
use strict;
use warnings;
use Test::More 0.96 tests => 2;

subtest utf8 => sub {
plan tests => 3;

opendir my $dh, 'corpus'
or die "Couldn't open directory 'corpus'";

my @files = grep { $_ ne '.' and $_ ne '..' } readdir $dh;
my @utf8_files;
{
rewinddir $dh;
use utf8::all;
@utf8_files = grep { $_ ne '.' and $_ ne '..' } readdir $dh;
}
closedir $dh;

is_deeply \@utf8_files, ["\x{307f}\x{304b}\x{3061}\x{3083}\x{3093}", "testfile"];
isnt $files[0] => $utf8_files[0];
is $files[1] => $utf8_files[1];
};

subtest context => sub {
plan tests => 1;

opendir my $dh, 'corpus'
or die "Couldn't open directory 'corpus'";

use utf8::all;
my $core = CORE::readdir $dh;
rewinddir $dh;
my $utf8 = readdir $dh;
rewinddir $dh;

is $utf8 => $core;
closedir $dh;
};

0 comments on commit bc37b2a

Please sign in to comment.