Hello community, here is the log from the commit of package convmv for openSUSE:Factory checked in at Mon Jul 27 23:19:10 CEST 2009. -------- --- convmv/convmv.changes 2008-01-31 23:50:07.000000000 +0100 +++ convmv/convmv.changes 2009-07-27 17:37:01.000000000 +0200 @@ -1,0 +2,6 @@ +Mon Jul 27 17:34:23 CEST 2009 - tiwai@suse.de + +- updated to version 1.14: + see Changes file for details + +------------------------------------------------------------------- calling whatdependson for head-i586 Old: ---- convmv-1.12.tar.bz2 New: ---- convmv-1.14.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ convmv.spec ++++++ --- /var/tmp/diff_new_pack.reFuja/_old 2009-07-27 23:18:22.000000000 +0200 +++ /var/tmp/diff_new_pack.reFuja/_new 2009-07-27 23:18:22.000000000 +0200 @@ -1,5 +1,5 @@ # -# spec file for package convmv (Version 1.12) +# spec file for package convmv (Version 1.14) # # Copyright (c) 2009 SUSE LINUX Products GmbH, Nuernberg, Germany. # @@ -22,8 +22,8 @@ License: GPL v2 or later Group: Productivity/File utilities AutoReqProv: on -Version: 1.12 -Release: 46 +Version: 1.14 +Release: 1 Url: http://j3e.de/linux/convmv/ Source: http://j3e.de/linux/convmv/%{name}-%{version}.tar.bz2 BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -76,7 +76,7 @@ %files %defattr(-, root, root) -%doc GPL2 Changes VERSION MD5sums +%doc GPL2 Changes CREDITS TODO VERSION %{_bindir}/* %{_mandir}/man1/* ++++++ convmv-1.12.tar.bz2 -> convmv-1.14.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/convmv-1.12/CREDITS new/convmv-1.14/CREDITS --- old/convmv-1.12/CREDITS 2004-02-01 00:13:17.000000000 +0100 +++ new/convmv-1.14/CREDITS 2008-01-24 21:12:03.000000000 +0100 @@ -5,3 +5,4 @@ Mike FABIAN Philipp JOCHAM Kuang-che Wu +Hansjörg MAURER diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/convmv-1.12/Changes new/convmv-1.14/Changes --- old/convmv-1.12/Changes 2008-01-23 18:55:56.000000000 +0100 +++ new/convmv-1.14/Changes 2008-12-11 22:59:53.000000000 +0100 @@ -1,3 +1,17 @@ +1.14 +- this release is once more dedicated to Perl::Encode. There is no way to do a check for valid UTF-8 which works with all Perl releases from 5.8.0 up to 5.10.0. We now have to test which code works in our Perl's Encode version and then decide which code path to go. + +1.13 +- move non fatal Perl bug checks into the help screen output +- fix Perl warnings when wrong/unknown charset is used +- run check for some essential Encode functionality at every startup +- add --fixdouble option to only fix files that are double-UTF-8 encoded +- add --parsable option to allow convmv output parsable suggestions for external tools to to something with it +- add --preserve-mtimes option to restore mtimes of parent directories +- allow an argv to be a symlink +- don't checksum deleted files in tar ball and use sha256 now +- allow skippig of certain test suite tests, useful for OS X to skip NFC/NFD related stuff, for example "make test SKIPTESTS=nfd-test,someothertest" will skip that test(s) + 1.12 - now work with Perl 5.10 using an eval block - GPL v2 and v3 now diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/convmv-1.12/MD5sums new/convmv-1.14/MD5sums --- old/convmv-1.12/MD5sums 2008-01-23 18:58:13.000000000 +0100 +++ new/convmv-1.14/MD5sums 1970-01-01 01:00:00.000000000 +0100 @@ -1,19 +0,0 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -2559b77cb012f1a3b7bcae81eddf0f31 ./Changes -e7335cf8e03119c353aa45efdc49b94b ./convmv -8bed1a74d53b68c1bce15d32309bdb52 ./CREDITS -e0dc2bf8cde8e56d69cef5d30c702da3 ./GPL2 -0a83f741ea9a5492a403b0287cea7375 ./Makefile -7d862266a4794aee21f731946a82d4bb ./testsuite.tar -2001efa90039013edb43ba1b6b784bd5 ./TODO -81d99f84fe599419c14b271f7dfc262e ./VERSION -d41d8cd98f00b204e9800998ecf8427e ./.MD5sums ------BEGIN PGP SIGNATURE----- -Version: GnuPG v2.0.8 (GNU/Linux) - -iEYEARECAAYFAkeXgDUACgkQdoo0s+hIejmofgCg7X8B4pwlHtuGqAfeKX1m4BhX -pN4An2YK1L9tfOaIUeJThQAi60jlBwDZ -=AtEk ------END PGP SIGNATURE----- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/convmv-1.12/Makefile new/convmv-1.14/Makefile --- old/convmv-1.12/Makefile 2006-06-27 16:38:01.000000000 +0200 +++ new/convmv-1.14/Makefile 2008-11-29 14:49:38.000000000 +0100 @@ -1,6 +1,9 @@ DESTDIR= PREFIX=/usr/local MANDIR=$(PREFIX)/share/man +TAR=tar +FIND=find +SED=sed all: manpage @@ -14,21 +17,21 @@ pod2man --section 1 --center=" " convmv | gzip > convmv.1.gz clean: - rm -f convmv.1.gz convmv-*.tar.gz MD5sums .files .name + rm -f convmv.1.gz convmv-*.tar.gz MD5sums SHA256sums .files .name rm -rf suite test: - test -d suite || tar -xf testsuite.tar + test -d suite || $(TAR) xf testsuite.tar cd suite ; ./dotests.sh dist: clean - sed -n "2,2p" convmv |sed "s/.*convmv \([^ ]*\).*/\1/" > VERSION - md5sum `find . -name "*" -type f` |gpg --clearsign >.MD5sums - mv .MD5sums MD5sums + $(SED) -n "2,2p" convmv |$(SED) "s/.*convmv \([^ ]*\).*/\1/" > VERSION + $(FIND) . -name "*" ! -name ".*" -type f -print | xargs sha256sum | gpg --clearsign > .SHA256sums + mv .SHA256sums SHA256sums ls > .files echo convmv-`cat VERSION` >.name mkdir `cat .name` mv `cat .files` `cat .name` - tar -cv * |gzip > `cat .name`.tar.gz + $(TAR) cvf - * |gzip > `cat .name`.tar.gz mv `cat .name`/* . rmdir `cat .name` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/convmv-1.12/SHA256sums new/convmv-1.14/SHA256sums --- old/convmv-1.12/SHA256sums 1970-01-01 01:00:00.000000000 +0100 +++ new/convmv-1.14/SHA256sums 2008-12-12 01:38:47.000000000 +0100 @@ -0,0 +1,18 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA1 + +f4f57466afa9a51ea85eca7b08e8ad0ab679a9a8e9e05d42e620ea12f98e44a6 ./Changes +c8dcb65e389bf4a0960fbb1caaa4808f8da28a9cdbf62f131235e82d04d28516 ./CREDITS +a2a9cfa48ba7f7453edf1c43bb8bb1aef5fcd1b87dde11420edceee2e2528db0 ./GPL2 +10f96f4cf2f61333c289f603cedd4c0f5e523d2da05486d9bea670f3877d8592 ./Makefile +31a04f0b0584237d6f81fab7e77b0d43e307230102f09db947e20b2a3103a108 ./testsuite.tar +6cd57b452e9e2be5a9ca992831f96e4a8317c1bc37171f237094d8dc0a6e0d27 ./TODO +b28d3e4bc89658ab4c8d768f013ddf92a3612e20edf922a81d177f1bd8c35b25 ./VERSION +53e30ee37a975d466c34f3a3bead8bcdd32baa75a527e32282fbb81a70254e04 ./convmv +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v2.0.9 (GNU/Linux) + +iEYEARECAAYFAklBspcACgkQdoo0s+hIejlHwgCcCAzv8wB2TPklGlcNSCS7z8zy +hVgAoIKa2LGBSepDfGZuKZoRj5Y1Msz4 +=/mPW +-----END PGP SIGNATURE----- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/convmv-1.12/TODO new/convmv-1.14/TODO --- old/convmv-1.12/TODO 2008-01-22 13:54:03.000000000 +0100 +++ new/convmv-1.14/TODO 2008-11-10 15:09:55.000000000 +0100 @@ -7,11 +7,8 @@ - --null option for "find -print0 | xargs convmv --null" usage - map illegal ntfs characters away: " / \ * ? < > | : - map "most" strange chracters to ASCII equivalences -- parsable column mode \0..\0..\0\0 terminated - keep/restore old ctime - difficult to do! No Perl module, not even a ctime option in standard "touch" command :-| -- add option for a parsable mode, writing in null byte separated columns what to do with which files. This is to allow people more easily to write gui frontends for convmv. Feedback for this option is very welcome - any other suggestions? diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/convmv-1.12/VERSION new/convmv-1.14/VERSION --- old/convmv-1.12/VERSION 2008-01-23 18:58:11.000000000 +0100 +++ new/convmv-1.14/VERSION 2008-12-12 01:38:39.000000000 +0100 @@ -1 +1 @@ -1.12 +1.14 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/convmv-1.12/convmv new/convmv-1.14/convmv --- old/convmv-1.12/convmv 2008-01-23 18:55:19.000000000 +0100 +++ new/convmv-1.14/convmv 2008-12-12 01:38:34.000000000 +0100 @@ -1,5 +1,5 @@ #!/usr/bin/perl -# convmv 1.12 - converts filenames from one encoding to another +# convmv 1.14 - converts filenames from one encoding to another # Copyright © 2003-2008 Bjoern JACKE <bjoern@j3e.de> # # This program comes with ABSOLUTELY NO WARRANTY; it may be copied or modified @@ -83,13 +83,35 @@ C<--nosmart> will also force conversion to UTF-8 for such files, which might result in "double encoded UTF-8" (see section below). +=item B<--fixdouble> + +using the C<--fixdouble> option convmv does only convert files which will still +be UTF-8 encoded after conversion. That's useful for fixing double-encoded +UTF-8 files. All files which are not UTF-8 or will not result in UTF-8 after +conversion will not be touched. Also see chapter "How to undo double UTF-8 ..." +below. + =item B<--notest> Needed to actually rename the files. By default convmv will just print what it wants to do. =item B<--parsable> -This is not implemented yet. + +This is an advanced option that people who want to write a GUI front end will +find useful (some others maybe, too). It will convmv make print out what it +would do in an easy parsable way. The first column contains the action or some +kind of information, the second column mostly contains the file that is to be +modified and if appropriate the third column contains the modified value. Each +column is separated by \0\n (nullbyte newline). Each row (one action) is +separated by \0\0\n (nullbyte nullbyte newline). + +=item B<--preserve-mtimes> + +modifying filenames usually causes the parent directory's mtime being updated. +This option allows to reset the mtime to the old value. If your filesystem +supports sub-second resolution the sub-second part of the atime and mtime +will be lost as Perl does not yet support that. =item B<--replace> @@ -191,14 +213,16 @@ example the file names already were UTF-8 encoded and you accidently did another conversion from some charset to UTF-8. You can simply undo that by converting that the other way round. The from-charset has to be UTF-8 and the -to-charset has to be the from-charset you previously accidently used. You -should check to get the correct results by doing the conversion without -C<--notest> before, also the C<--qfrom> option might be helpful, because the -double utf-8 file names might screw up your terminal if they are being -printed - they often contain control sequences which do funny things with your -terminal window. If you are not sure about the charset which was accidently -converted from, using C<--qfrom> is a good way to fiddle out the required -encoding without destroying the file names finally. +to-charset has to be the from-charset you previously accidently used. If you +use the C<--fixdouble> option convmv will make sure that only files will be +processed that will still be UTF-8 encoded after conversion and it will leave +non-UTF-8 files untouched. You should check to get the correct results by doing +the conversion without C<--notest> before, also the C<--qfrom> option might be +helpful, because the double utf-8 file names might screw up your terminal if +they are being printed - they often contain control sequences which do funny +things with your terminal window. If you are not sure about the charset which +was accidently converted from, using C<--qfrom> is a good way to fiddle out the +required encoding without destroying the file names finally. =head2 How to repair Samba files @@ -272,6 +296,8 @@ 'lower'=>\$opt_lower, 'dotlessi'=>\$opt_dotlessi, 'parsable'=>\$opt_parsable, + 'fixdouble'=>\$opt_fixdouble, + 'preserve-mtimes'=>\$opt_mtimes, ) or exit 1; use File::Compare; $errors_occurred=0; @@ -279,14 +305,24 @@ $maxfilenamelength=255; # $maxpathlength=4096; # this might be used somehow, somewhere? +%dir_time_hash=(); +my $this_is_valid_utf8; + +# delimiter and final delimiter for parsable mode: +$del = "\0\n"; +$fin_del = "\0\0\n"; + &listvalidencodings and exit 0 if ($opt_list); &printusage and exit 1 if (!@ARGV or $opt_help); &check_for_broken_perl_release(); -if ($opt_parsable and ($opt_notest or $opt_exec or $opt_i)) { - die "--parsable mode cannot be used with --notest, --exec or -i\n"; +if ($opt_parsable) { + if ($opt_notest or $opt_exec or $opt_i) { + die "--parsable mode cannot be used with --notest, --exec or -i\n"; + } } + if ($opt_unescape) { die "No charset conversion when unescaping!\n" if ($opt_f or $opt_t); $checkenc=\&unescape_checkenc; @@ -298,9 +334,17 @@ $get_newname=\&upperlower_get_newname; $opt_f="ascii" unless ($opt_f); } else { - $opt_f=Encode::resolve_alias($opt_f) or die "wrong/unknown \"from\" encoding!\n"; - $opt_t=Encode::resolve_alias($opt_t) or die "wrong/unknown \"to\" encoding!\n"; - $checkenc=\&char_checkenc; + if (not ($opt_f and $opt_f=Encode::resolve_alias($opt_f))) { + die "wrong/unknown \"from\" encoding!\n"; + } + if (not ($opt_t and $opt_t=Encode::resolve_alias($opt_t))) { + die "wrong/unknown \"to\" encoding!\n"; + } + if ($opt_fixdouble) { + $checkenc=\&fixdouble_checkenc; + } else { + $checkenc=\&char_checkenc; + } $get_newname=\&char_get_newname; } $to_is_utf8 = lc($opt_t) =~ m/^utf-?8/; @@ -311,6 +355,7 @@ } else { $from_print=\&dummy; } + if ($opt_qto) { $to_print=\&to_ascii; } else { @@ -327,6 +372,10 @@ $norm=\&dummy; } +if ($opt_fixdouble) { + die "--fixdouble requires UTF-8 as source and non-UTF-8 as target charset\n" unless ($from_is_utf8 and $opt_t and not $to_is_utf8); +} + $opt_lowmem=1 if ($opt_exec); $pwd=cwd(); @@ -334,55 +383,73 @@ undef @ARGV; for (@args) { - die "file or directory not found: $_\n" unless (-e); + die "file or directory not found: $_\n" unless (-e or -l); +} + +if ($opt_parsable) { + $outerr=NUL; +} else { + $outerr=STDERR; } ## do {print ord($_)."_" for (split(//,$_));print "\n"; } for (@args); # debug print -print STDERR "Starting a dry run without changes...\n" unless ($opt_notest); +print $outerr "Starting a dry run without changes...\n" unless ($opt_notest); if ($opt_r) { - find({wanted=>\&scan,bydepth=>1,no_chdir=>1}, @args); - if (not $errors_occurred and $warnings_occurred) { - $errors_occurred=1 if (not &print_ask ("WARNINGS occurred. Do you really want to continue?",1)); - } - die "To prevent damage to your files, we won't continue.\nFirst fix this or correct options!\n" if ($errors_occurred); - unless ($opt_exec) { find({wanted=>\&process_symlink_targets,bydepth=>1,no_chdir=>1}, @args); } - find({wanted=>\&process_main,bydepth=>1,no_chdir=>1}, @args); + $myfind=\&find; } else { - for (@args) { &scan; } - if (not $errors_occurred and $warnings_occurred) { - $errors_occurred=1 if (not &print_ask ("WARNINGS occurred. Do you really want to continue?",1)); - } - die "To prevent damage to your files, we won't continue.\nFirst fix errors or correct options!\n" if ($errors_occurred); - unless ($opt_exec) { for (@args) { &process_symlink_targets; } } - for (@args) { &process_main; } + $myfind=\&find0depth; +} + +&$myfind({wanted=>\&scan,bydepth=>1,no_chdir=>1}, @args); +if (not $errors_occurred and $warnings_occurred) { + $errors_occurred=1 if (not &print_ask ("WARNINGS occurred. Do you really want to continue?",1)); +} + +die "To prevent damage to your files, we won't continue.\nFirst fix this or correct options!\n" if ($errors_occurred); +unless ($opt_exec) { + &$myfind({wanted=>\&process_symlink_targets,bydepth=>1,no_chdir=>1}, @args); +} +&$myfind({wanted=>\&process_main,bydepth=>1,no_chdir=>1}, @args); + +# check for unintentionally left files +for (keys %dir_time_hash) { + print $outerr "error: left in %dir_time_hash: $_\n"; } if ($opt_notest) { - print STDERR "Ready!\n", + print $outerr "Ready!\n", } else { - print STDERR "No changes to your files done. Use --notest to finally rename the files.\n"; + print $outerr "No changes to your files done. Use --notest to finally rename the files.\n"; } ##### ## subs ### +# find-like function but without any depth search for not recursive mode: +sub find0depth() { + my $opts = shift; + for (@_) { + $$opts{'wanted'}($_); + } +} + # scan for real files and check charset first: sub scan { - $arg=$_; + $arg = $_; &get_dir_base_change; if (-l $arg) { # print "link: $arg in $dir\n"; if (not defined(&$checkenc($arg))) { $errors_occurred=1 }; } elsif (-d $arg) { # print "dir: $arg in $dir\n"; - $inod_fullname{(stat $arg)[1]}=$dir.$arg if (!$opt_lowmem); + $inod_fullname{(stat $arg)[1]}=$dir."/".$arg if (!$opt_lowmem); if (not defined(&$checkenc($arg))) { $errors_occurred=1 }; } elsif (-f $arg) { # print "file: $arg in $dir\n"; - $inod_fullname{(stat $arg)[1]}=$dir.$arg if (!$opt_lowmem); + $inod_fullname{(stat $arg)[1]}=$dir."/".$arg if (!$opt_lowmem); if (not defined(&$checkenc($arg))) { $errors_occurred=1 }; } chdir $pwd; @@ -399,15 +466,19 @@ if ( $inod_fullname{(stat $oldlink)[1]} or $opt_lowmem) { # = if (symlink target scanned before) #print is_utf8($oldlink) ? 1 : 0; #print is_utf8($newname) ? 1 : 0; - print "symlink \"".&$from_print($File::Find::name)."\": \""; - print &$from_print($oldlink)."\" >> \""; + print $outerr "symlink \"".&$from_print($File::Find::name)."\": \""; + print $outerr "".&$from_print($oldlink)."\" >> \""; &print_ask (&$to_print($newname)."\"",$opt_i) or return; + &save_parent_mtime($dir) if ($opt_mtimes); if ($opt_notest) { unlink $arg; symlink ($newname, $arg); + } elsif ($opt_parsable) { + print "unlink".$del.$File::Find::name.$fin_del; + print "symlink".$del.$newname.$del.$File::Find::name.$fin_del; } } else { - print STDERR "link target \"",&$from_print($oldlink),"\" of \"",&$from_print($dir.$arg),"\" not in subtree, left untouched!\n"; + print $outerr "link target \"",&$from_print($oldlink),"\" of \"",&$from_print($dir."/".$arg),"\" not in subtree, left untouched!\n"; } } # else { print "no need to convert link target: $oldlink to $newname\n"; } } @@ -438,24 +509,41 @@ &renameit($arg,$newname); } } + &restore_times_if_any($dir,$arg,$newname) if ($opt_mtimes); + chdir $pwd; } sub char_get_newname { -# retuns undef on error and string otherwise. +# returns undef on error and string otherwise. my $oldfile=shift; my $newname; + my $lets_die = 0; if (!$from_is_utf8 and $to_is_utf8 and !$opt_nosmart and &looks_like_utf8($oldfile)) { - print STDERR "Skipping, already UTF-8: ",&$from_print($dir.$oldfile),"\n"; + if ($opt_parsable) { + print "іnfomsg".$del."skipalreadyutf8".$del.$dir."/".$oldfile.$fin_del; + } else { + print $outerr "Skipping, already UTF-8: ",&$from_print($dir."/".$oldfile),"\n"; + } return $oldfile; } else { + if ($opt_fixdouble and not looks_like_utf8($oldfile)) { + # this is legacy encoding which we ignore in fixdouble mode + return $oldfile; + } if ($from_is_utf8 and ! $to_is_utf8) { # from_to can't convert from NFD to non-UTF-8! $newname=encode_utf8(NFC(decode_utf8($oldfile))); } else { $newname=$oldfile; } - from_to($newname, $opt_f, $opt_t, Encode::FB_QUIET) or die "SHOULD NOT HAPPEN HERE: conversion error, so suitable charset used?: \"$oldfile\"\nTo prevent damage to your files, we won't continue. First fix this!\n"; + from_to($newname, $opt_f, $opt_t, Encode::FB_QUIET) or $lets_die = 1; + if ($opt_fixdouble and not looks_like_utf8($newname)) { + return $oldfile; + } + if ($lets_die) { + die "SHOULD NOT HAPPEN HERE: conversion error, no suitable charset used?: \"$oldfile\"\nTo prevent damage to your files, we won't continue. First fix this!\n"; + } $newname=&$norm(decode_utf8($newname)) if ($to_is_utf8); return $newname; } @@ -464,7 +552,7 @@ sub get_dir_base_change() { $arg =~ s/\/*$//; - $dir=dirname($arg)."/"; + $dir=dirname($arg); $arg=basename($arg); chdir $dir; } @@ -483,39 +571,85 @@ } else { #print is_utf8($oldfile) ? 1 : 0; #print is_utf8($newname) ? 1 : 0; - &print_ask ("mv \"". &$from_print($dir.$oldfile)."\"\t\"".&$from_print($dir).&$to_print($newname)."\"",$opt_i) or return; + &print_ask ("mv \"". &$from_print($dir."/".$oldfile)."\"\t\"".&$from_print($dir)."/".&$to_print($newname)."\"",$opt_i) or return; } + &save_parent_mtime($dir) if ($opt_mtimes); if (-e $newname and !$opt_exec) { if ($opt_replace and !&compare($oldfile,$newname)) { if ($opt_notest) { - unlink $newname or print STDERR "Error: $!\n"; - rename ($oldfile, $newname) or print STDERR "Error: $!\n"; + unlink $newname or print $outerr "Error: $!\n"; + rename ($oldfile, $newname) or print $outerr "Error: $!\n"; + } elsif ($opt_parsable) { + print "unlink".$del.$dir."/".$oldfile.$fin_del; + print "rename".$del.$dir."/".$oldfile.$del.$dir."/".$newname.$fin_del; } } else { - print STDERR &$to_print($newname)," exists and differs or --replace option missing - skipped\n"; + if ($opt_parsable) { + print "errormsg".$del."fileexists".$del.$newname.$fin_del; + } else { + print $outerr "".&$to_print($newname)," exists and differs or --replace option missing - skipped\n"; + } } } else { if ($opt_notest) { if ($opt_exec) { system($cmd); } else { - rename ($oldfile, $newname) or print STDERR "Error: $!\n"; + rename ($oldfile, $newname) or print $outerr "Error: $!\n"; } + } elsif ($opt_parsable) { + print "rename".$del.$dir."/".$oldfile.$del.$dir."/".$newname.$fin_del; } } } +sub save_parent_mtime() { + my $dir=shift; + return if (exists $dir_time_hash{$dir}); + #print $outerr "Putting $dir in %dir_time_hash\n"; + @{$dir_time_hash{$dir}}=(stat("."))[8..10]; +} + +sub restore_times_if_any() { + my $dir=shift; + my $old=shift; + my $new=shift; + if ($dir eq ".") { + $dir = ""; + } else { + $dir .= "/"; + } + $dir .= $old; + ## print $outerr "Trying to delete $dir now $new from %dir_time_hash\n"; # debug print + if (exists $dir_time_hash{$dir}) { + if ($opt_notest) { + utime ${$dir_time_hash{$dir}}[0], ${$dir_time_hash{$dir}}[1], $new or print $outerr "Could not run utime() on $new: $!\n"; + } elsif ($opt_parsable) { + print "utime".$del.$dir.$del.${$dir_time_hash{$dir}}[0].$del.${$dir_time_hash{$dir}}[1].$del.${$dir_time_hash{$dir}}[2].$fin_del; + } + delete $dir_time_hash{$dir}; + } +} + sub listvalidencodings() { print "$_\n" for (Encode->encodings(":all")); return 1; } +sub fixdouble_checkenc() { + return 1; +} + sub char_checkenc() { my $oldfile=shift; my $new=$oldfile; if ($from_is_utf8) { - if (! &this_is_valid_utf8($new)) { - print STDERR "this file was not validly encoded in UTF-8: \"". &$from_print($dir.$oldfile) ."\"\n"; + if (! &$this_is_valid_utf8($new)) { + if ($opt_parsable) { + print "errormsg".$del."filenotutf8".$del.$oldfile.$fin_del; + } else { + print $outerr "this file was not validly encoded in UTF-8: \"". &$from_print($dir."/".$oldfile) ."\"\n"; + } return undef; } } else { @@ -524,7 +658,11 @@ # be "smart-skipped" if to_enc is utf-8 and not produce no error here. } elsif (! from_to($new,$opt_f, "utf8", Encode::FB_QUIET) ) { - print STDERR "this file was not validly encoded in $opt_f: \"". &$from_print($dir.$oldfile) ."\"\n"; + if ($opt_parsable) { + print "errormsg".$del."fileencodedinvalid".$del.$dir."/".$oldfile.$fin_del; + } else { + print $outerr "this file was not validly encoded in $opt_f: \"". &$from_print($dir."/".$oldfile) ."\"\n"; + } return undef; } } @@ -539,10 +677,14 @@ } ## print "$oldfile|$utf8oldfile|$new|$filenamelength\n"; if (! $filenamelength) { - print STDERR "$opt_t doesn't cover all needed characters for: \"". &$from_print($dir.$oldfile) ."\"\n"; + if ($opt_parsable) { + print "errormsg".$del."charsetdoesntcoverneededcharacters".$del.$dir."/".$oldfile.$fin_del; + } else { + print $outerr "$opt_t doesn't cover all needed characters for: \"". &$from_print($dir."/".$oldfile) ."\"\n"; + } return undef; } elsif ($filenamelength > $maxfilenamelength) { - print STDERR &$from_print($dir.$oldfile).": resulting filename is $filenamelength bytes long (max: $maxfilenamelength)\n"; + print $outerr "".&$from_print($dir."/".$oldfile).": resulting filename is $filenamelength bytes long (max: $maxfilenamelength)\n"; return undef; } &posix_check($new); @@ -550,8 +692,9 @@ } sub printusage { + &check_for_perl_bugs; print <<END; -convmv 1.12 - converts filenames from one encoding to another +convmv 1.14 - converts filenames from one encoding to another Copyright (C) 2003-2008 Bjoern JACKE <bjoern\@j3e.de> This program comes with ABSOLUTELY NO WARRANTY; it may be copied or modified @@ -584,14 +727,23 @@ sub looks_like_utf8() { my $string = shift; - if ($string =~ m/[^[:ascii:]]/ and &this_is_valid_utf8($string)) { + if ($string =~ m/[^[:ascii:]]/ and &$this_is_valid_utf8($string)) { return 1; } else { return undef; } } -sub this_is_valid_utf8() { +sub this_is_valid_utf8_decode { + my $string = shift; + if (not defined(decode_utf8($string))) { + return undef; + } else { + return 1; + } +} + +sub this_is_valid_utf8_decode_CROAK() { my $string = shift; # until 1.08 I used to use decode_utf8() but see perl bug #37757 (perl 5.8.7/8) #if (not defined(decode_utf8($string)) ) { @@ -608,9 +760,9 @@ # see perl bug #49830. convmv 1.10 and Perl 5.10 will again only work with # --nosmart. # - #okay now perluniintro suggests to do this: + # okay, now perluniintro suggests to do this: - eval { decode_utf8($string, Encode::FB_CROAK); }; + eval 'decode_utf8($string, Encode::FB_CROAK);'; if ($@) { return undef; } else { @@ -630,6 +782,9 @@ } sub print_ask() { # takes 2 arguments, string and askornot + if ($opt_parsable) { + return 1; + } my $a=""; print shift; my $ask = shift; @@ -651,7 +806,11 @@ &posix_check(&unescape_get_newname($name)); return 1; } else { - print STDERR "\"",&$from_print($name),"\" not ASCII - this does not seem to be an escaped filename.\n"; + if ($opt_parsable) { + print "errormsg".$del."notanescapedfile".$del.$name.$fin_del; + } else { + print $outerr "\"",&$from_print($name),"\" not ASCII - this does not seem to be an escaped filename.\n"; + } return undef; } } @@ -680,7 +839,7 @@ my $oldname = shift; my $name=$oldname; if (! from_to($name, $opt_f, "utf8", Encode::FB_QUIET)) { # should also leave NFD as it is ... - print STDERR "\"",&$from_print($oldname),"\" not encoded in $opt_f ? Supply the correct encoding via -f option!\n"; + print $outerr "\"",&$from_print($oldname),"\" not encoded in $opt_f ? Supply the correct encoding via -f option!\n"; return undef; } _utf8_on($name); # Unicode in Perl can be a real pain ... @@ -690,7 +849,11 @@ $name =~ s/ı/I/g; $name =~ s/i/İ/g; } - # we do not want to upper ß to SS ! Let's substitute it with NUL+DWSLQH (NUL may not be part of filename) and get it back after uc() + # we do not want to upper ß to SS ! Let's substitute it with + # NUL+DWSLQH (NUL may not be part of filename) and get it back after uc(). + # Unicode 5.1(draft) news: Uppercasing U+00DF (ß) LATIN SMALL LETTER SHARP S + # to the new U+1E9E LATIN CAPITAL LETTER SHARP S. + # but until now I don't see use for this in filenames ... $name =~ s/ß/\000DWSLQH/g; $name = uc($name); $name =~ s/\000DWSLQH/ß/g; @@ -707,7 +870,7 @@ # the problems that arise with this letter are endless ... # $name =~ s/i\314\207/i/g if ($from_is_utf8); if (! from_to($name, "utf8", $opt_f, Encode::FB_QUIET)) { - print STDERR $opt_upper?"Upper":"Lower","case of \"",&$from_print($oldname),"\" not possible in $opt_f ! Maybe supply different encoding via -f option.\n"; + print $outerr $opt_upper?"Upper":"Lower","case of \"",&$from_print($oldname),"\" not possible in $opt_f ! Maybe supply different encoding via -f option.\n"; return undef; } return $name; @@ -716,7 +879,7 @@ sub posix_check() { my $name=shift; if ($name =~ m/[\000\/]/) { - print STDERR "WARNING: new filename \"",&$to_print($name),"\" contains characters, which are not POSIX filesystem conform! This may result in data loss.\n"; + print $outerr "WARNING: new filename \"",&$to_print($name),"\" contains characters, which are not POSIX filesystem conform! This may result in data loss.\n"; $warnings_occurred=1; } } @@ -731,10 +894,52 @@ } sub check_for_broken_perl_release() { + # Check that most basic Perl Encode features we use work reliably + # and decide which code path we use for &this_is_valid_utf8(): + my $test = ""."\366"; + my $error = ""; + + if (not defined(decode_utf8($test))) { + $this_is_valid_utf8=\&this_is_valid_utf8_decode; + return 0; + } + $error .= "decode_utf8(\$test) check failed\n"; + + eval 'decode_utf8($test, Encode::FB_CROAK);'; + if (not $@) { + $error .= "eval 'decode_utf8(\$non-utf8, Encode::FB_CROAK);'; check failed.\n"; + } else { + $test = ""."ö"; + eval 'decode_utf8($test, Encode::FB_CROAK);'; + if ($@) { + $error .= "eval 'decode_utf8(\$utf8, Encode::FB_CROAK);'; check failed.\n"; + } else { + $this_is_valid_utf8=\&this_is_valid_utf8_decode_CROAK; + return 0; + } + } + print "Your Perl release is too broken to make convmv work reliably:\n",$error; + exit 1; +} + +sub check_for_perl_bugs() { + # Check for certain Perl fleas that we more or less have to work around: # until 1.08 I used to use decode_utf8() but see perl bug #37757 (perl 5.8.7/8) #if (not defined(decode_utf8($string)) ) my $bugs = ""; my $test = "\366"; + + my $u8test = NFD(""."ö"); # "". is intended as only so we have _utf8_off set + # otherwise from_to doesn't convert the $data to + # something else. + # print "DEBUG: string is UTF-8 flagged: ",is_utf8($u8test) ? "yes" : "no","\n"; + eval "from_to($u8test, 'utf8', 'iso-8859-1');"; + if ($u8test ne "\366") { + # Perl::Encode guys think that conversion from decomposed UTF-8 + # to any other charset does not have to be supported by from_to. + # Why, when NFC or NFD this is both perfectly valid UTF-8? + $bugs .= "#22111 "; + } if (decode_utf8($test)) { $bugs .= "#37757 "; # Convmv 1.08 and below would not work here! Files old/convmv-1.12/testsuite.tar and new/convmv-1.14/testsuite.tar differ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Remember to have fun... -- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org