1use strict; 2use Test; 3use Config qw(%Config); 4use Cwd qw(cwd); 5use Encode qw(); 6use Win32; 7 8BEGIN { 9 unless (defined &Win32::BuildNumber && Win32::BuildNumber() >= 820 or $] >= 5.008009) { 10 print "1..0 # Skip: Needs ActivePerl 820 or Perl 5.8.9 or later\n"; 11 exit 0; 12 } 13 if ((((Win32::FsType())[1] & 4) == 0) || (Win32::FsType() =~ /^FAT/)) { 14 print "1..0 # Skip: Filesystem doesn't support Unicode\n"; 15 exit 0; 16 } 17 unless ((Win32::GetOSVersion())[1] > 4) { 18 print "1..0 # Skip: Unicode support requires Windows 2000 or later\n"; 19 exit 0; 20 } 21} 22 23my $home = Win32::GetCwd(); 24my $cwd = cwd(); # may be a Cygwin path 25my $dir = "Foo \x{394}\x{419} Bar \x{5E7}\x{645} Baz"; 26my $file = "$dir\\xyzzy \x{394}\x{419} plugh \x{5E7}\x{645}"; 27 28sub cleanup { 29 chdir($home); 30 my $ansi = Win32::GetANSIPathName($file); 31 unlink($ansi) if -f $ansi; 32 $ansi = Win32::GetANSIPathName($dir); 33 rmdir($ansi) if -d $ansi; 34} 35 36cleanup(); 37END { cleanup() } 38 39plan test => 12; 40 41# Create Unicode directory 42Win32::CreateDirectory($dir); 43ok(-d Win32::GetANSIPathName($dir)); 44 45# Create Unicode file 46Win32::CreateFile($file); 47ok(-f Win32::GetANSIPathName($file)); 48 49# readdir() returns ANSI form of Unicode filename 50ok(opendir(my $dh, Win32::GetANSIPathName($dir))); 51while ($_ = readdir($dh)) { 52 next if /^\./; 53 # On Cygwin 1.7 readdir() returns the utf8 representation of the 54 # filename but doesn't turn on the SvUTF8 bit 55 Encode::_utf8_on($_) if $^O eq "cygwin" && $Config{osvers} !~ /^1.5/; 56 ok($file, Win32::GetLongPathName("$dir\\$_")); 57} 58closedir($dh); 59 60# Win32::GetLongPathName() of the absolute path restores the Unicode dir name 61my $full = Win32::GetFullPathName($dir); 62my $long = Win32::GetLongPathName($full); 63 64ok($long, Win32::GetLongPathName($home)."\\$dir"); 65 66# We can Win32::SetCwd() into the Unicode directory 67ok(Win32::SetCwd($dir)); 68 69my $w32dir = Win32::GetCwd(); 70# cwd() also returns a usable ANSI directory name 71my $subdir = cwd(); 72 73# change back to home directory to make sure relative paths 74# in @INC continue to work 75ok(chdir($home)); 76ok(Win32::GetCwd(), $home); 77 78ok(Win32::GetLongPathName($w32dir), $long); 79 80# cwd() on Cygwin returns a mapped path that we need to translate 81# back to a Windows path. Invoking `cygpath` on $subdir doesn't work. 82if ($^O eq "cygwin") { 83 $subdir = Cygwin::posix_to_win_path($subdir, 1); 84} 85$subdir =~ s,/,\\,g; 86ok(Win32::GetLongPathName($subdir), $long); 87 88# We can chdir() into the Unicode directory if we use the ANSI name 89ok(chdir(Win32::GetANSIPathName($dir))); 90ok(Win32::GetLongPathName(Win32::GetCwd()), $long); 91