Welcome to the world of software development! "It worked fine for years on 
XYZ.." is 
something I've heard so often with software that contains hidden bugs that were 
never found, 
often because of poor initial design. :-(

"perl -w" and "use warnings;" are your friends!

Here was my first run, with the code just copy/pasted from your mail message:

    D:\test>perl-test
            1 file(s) copied.
            1 file(s) copied.
            1 file(s) copied.
            1 file(s) copied.
            1 file(s) copied.
            1 file(s) copied.
            1 file(s) copied.
    syntax error at test-script.bat line 24, near ";,"
    Execution of test-script.bat aborted due to compilation errors.

    D:\test>

The problem appears to be that you have a spurious comma:
  my $DIR;,
  if ( -d $top ) { ... }

Perl sees this as
    ( (/*NULL EXPRESSION*/) , (/*IF STATEMENT*/) );
which of course, evaluates the left and right parts of the comma operator, and 
uses the left-
side value as the value of the entire expression.. So it evaluates to a null 
expression. And 
Perl is quite happy to do nothing!

Here's the fixed scripts (note that I also did some other cleanup, but it's 
still far from what I'd 
call a "production" script!).. It works just fine now, as show further below:

FILE perl-test.bat:
========================================
    @echo off

    rem ********************
    rem Make the directories
    rem ********************

    if not exist "some dir with spaces" (
        mkdir "some dir with spaces"
    )

    if not exist "some dir with spaces\some subdir with spaces" (
        mkdir "some dir with spaces\some subdir with spaces"
    )

    if not exist "some dir with spaces\some subdir with spaces\even deeper" (
        mkdir "some dir with spaces\some subdir with spaces\even deeper"
    )

    if not exist "some other dir with spaces" (
        mkdir "some other dir with spaces"
    )

    if not exist "some other dir with spaces\monotonous, isn't this" (
        mkdir "some other dir with spaces\monotonous, isn't this"
    )

    if not exist "nospaces" (
        mkdir "nospaces"
    )

    if not exist "nospaces\done!" (
        mkdir "nospaces\done!"
    )

    rem ********************
    rem Make the files
    rem ********************

    if not exist "some filename with spaces.txt" (
        copy NUL "some filename with spaces.txt"
    )

    if not exist "some dir with spaces\some subdir with spaces\another 
file.txt" (
        copy NUL "some dir with spaces\some subdir with spaces\another file.txt"
    )

    if not exist "some dir with spaces\some subdir with spaces\even 
deeper\whee.txt" (
        copy NUL "some dir with spaces\some subdir with spaces\even 
deeper\whee.txt"
    )

    if not exist "some other dir with spaces\more spaces %%and [EMAIL 
PROTECTED] $chars.txt" (
        copy NUL "some other dir with spaces\more spaces %%and [EMAIL 
PROTECTED] $chars.txt"
    )

    if not exist "some other dir with spaces\monotonous, isn't this\woot.txt" (
        copy NUL "some other dir with spaces\monotonous, isn't this\woot.txt"
    )

    if not exist "nospaces\foo.txt" (
        copy NUL "nospaces\foo.txt"
    )

    if not exist "nospaces\done!\bar.txt" (
        copy NUL "nospaces\done!\bar.txt"
    )

    rem ********************
    rem Test the script
    rem ********************

    call test-script.bat
========================================

FILE test-script.bat:
========================================
    @rem = '--*-Perl-*--
    @echo off
    if "%OS%" == "Windows_NT" goto WinNT
    set ORIGPATH9X=%PATH%
    set PATH=%PATH%;D:\Devel\Perl\Perl5\bin
    perl -x -S "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9
    goto endofperl
    :WinNT
    setlocal
    set PATH=%PATH%;D:\Devel\Perl\Perl5\bin
    perl -x -S %0 %*
    if NOT "%COMSPEC%" == "%SystemRoot%\system32\cmd.exe" goto endoffile
    if %errorlevel% == 9009 echo You do not have Perl in your PATH.
    if errorlevel 1 goto script_failed_so_exit_with_non_zero_val 2>nul
    goto endofperlNT
    @rem ';
    #! /usr/bin/perl -w
    #line 19
    use strict;
    use warnings;
    use Data::Dump qw( pp );

    sub dir_walk {
      my ($top, $filefunc, $dirfunc) = @_;
      my $DIR;

      if ( -d $top ) {
        my $file;

        unless (opendir $DIR, $top) {
          warn "Couldn't open directory $top: $!; skipping.\n";
          return;
        }

        my @results;
        while ($file = readdir $DIR) {
          next
            if $file eq '.' || $file eq '..';

          push @results, dir_walk("$top/$file", $filefunc, $dirfunc);
        }

        return $dirfunc->($top, @results);

      } else {
        return $filefunc->($top);
      }
    }

    sub file_func {
      print "file_func:\t" . pp(@_) . "\n";
    }

    sub dir_func {
      print "dir_func:\t" . pp(@_) . "\n";
    }

    sub main {
      dir_walk("d:/test", \&file_func, \&dir_func);
    }

    main();

    __END__
    :endofperlNT
    endlocal
    goto endoffile
    :endofperl9X
    set PATH=%ORIGPATH9X%
    set ORIGPATH9X=
    :endoffile
========================================

OUTPUT (doesn't really reformat well to email, but.. you can see it works):
========================================
    D:\test>perl-test
    file_func:      "d:/test/nospaces/done!/bar.txt"
    dir_func:       ("d:/test/nospaces/done!", 1)
    file_func:      "d:/test/nospaces/foo.txt"
    dir_func:       ("d:/test/nospaces", 1, 1)
    file_func:      "d:/test/perl-test.bat"
    file_func:      "d:/test/some dir with spaces/some subdir with 
spaces/another file.txt"
    file_func:      "d:/test/some dir with spaces/some subdir with spaces/even
      deeper/whee.txt"
    dir_func:       (
      "d:/test/some dir with spaces/some subdir with spaces/even deeper",
      1,
    )
    dir_func:       ("d:/test/some dir with spaces/some subdir with spaces", 1, 
1)
    dir_func:       ("d:/test/some dir with spaces", 1)
    file_func:      "d:/test/some filename with spaces.txt"
    file_func:      "d:/test/some other dir with spaces/monotonous, isn't 
this/woot.txt"
    dir_func:       (
      "d:/test/some other dir with spaces/monotonous, isn't this",
      1,
    )
    file_func:      "d:/test/some other dir with spaces/more spaces %and [EMAIL 
PROTECTED]
      \$chars.txt"
    dir_func:       ("d:/test/some other dir with spaces", 1, 1)
    file_func:      "d:/test/test-script.bat"
    dir_func:       ("d:/test", 1, 1, 1, 1, 1, 1)

    D:\test>
========================================

If your scripts still won't work after cleaning up, then check into what your 
build of Perl is 
doing, as I don't think it's the script itself. You might also want to look 
into the File::Find Perl 
module, available on CPAN, in the AS repositories, etc.

Best of luck.
Cas


On 23 Sep 2008 at 14:59, Dennis Daupert wrote:

> 
> Hi List,
> 
> I've worked with Perl on Unix for years, still a beginner on windows.
> 
> I have a script that recursively travels down a file and directory
> tree and captures file stats. Works fine on Solaris.
> 
> The script has a problem when it hits a directory or filename
> containing spaces.
> 
> I'll paste the subroutine code below; I borrowed from Mark Jason
> Dominus' "Higher Order Perl"
> 
> Basically, this is a recursive subroutine. You feed it some directory
> that gets populated into the variable $top (eg, C:\path\to\some dir),
> as well as feed it a couple of callbacks.
> 
> The code below breaks down when it hits the test operator -d and $top
> contains a directory with a space (/some dir/). The test operator
> doesn't seem to recognize the directory-with-space as a directory, so
> the whole if condition is bypassed.
> 
> I've played with such things as putting quotes around the offending
> directory, around the whole path, etc., with no joy. The best he does
> is read the toplevel directory handed to him, but then he stops. I
> need a more robust way of handling this strange filesystem.
> 
> ===========================================
> Here's the code:
> 
> sub dir_walk {
>   my ($top, $filefunc, $dirfunc) = @_;
>   my $DIR;,
> 
>   if ( -d $top ) {  # << FAILS HERE
>     my $file;
>     unless (opendir $DIR, $top) {
>       warn "Couldn't open directory $top: $!; skipping.\n";
>       return;
>     }
> 
>     my @results;
>     while ($file = readdir $DIR) {
>       next if $file eq '.' || $file eq '..';;
>       push @results, dir_walk("$top/$file", $filefunc, $dirfunc);
>     }
> 
>     return $dirfunc->($top, @results);
> 
>   } else {
>     return $filefunc->($top);
>   }
> }
> ===========================================
> 
> best,
> 
>  /dennis
> 
> ------------------------------------------------
> Dennis Daupert, PhD
> Senior Systems Development Professional -- CSC Account
> CSC
> 
> GOS | o: 1.317.298.9499 | [EMAIL PROTECTED] | www.csc.com
> 
> This is a PRIVATE message. If you are not the intended recipient,
> please delete without copying and kindly advise us by e-mail of the
> mistake in delivery. NOTE: Regardless of content, this e-mail shall
> not operate to bind CSC to any order or other contract unless pursuant
> to explicit written agreement or government initiative expressly
> permitting the use of e-mail for such purpose.
> 
> _______________________________________________
> Perl-Win32-Users mailing list
> [email protected]
> To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


_______________________________________________
Perl-Win32-Users mailing list
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to