Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Perl Misc (http://www.velocityreviews.com/forums/f67-perl-misc.html)
-   -   Getting 'system' to Process Win32 Paths Correctly (http://www.velocityreviews.com/forums/t893293-getting-system-to-process-win32-paths-correctly.html)

Jim Keenan 07-14-2005 01:38 PM

Getting 'system' to Process Win32 Paths Correctly
 
I wish to supply a user with a Perl distribution which includes a
command-line utility and whose test suite tests the output of that
utility. The test suite's call to that utility looks like this:

ok(! system("$^X -I$cwd/blib/lib $cwd/blib/script/utility"),
"able to call command-line utility");

where $^X is the name used to execute the current copy of Perl and $cwd
holds the name of the directory from which the test suite is called,
i.e., the directory holding Makefile.PL.

This works fine on my Unix-style system and fine on Win32 *provided*
that $cwd contains no wordspaces. So if the value of $cwd is
"C:/temp/other", the 'system' call correctly expands $cwd and the test
runs as intended.

However, if the value of $cwd is "C:/Documents and
Settings/localuser/My Documents", then the only part of the path that
get substituted is "C:/Documents". The "and" in "Documents and
Settings" is treated by perl as the program to be run, which causes an
error.

I've looked at the documentation for modules such as Cwd and File::Spec
and I don't see a workaround. So, ...

Can anyone suggest how to get 'system' to correctly interpret a
variable which holds a Win32 path which may contain wordspaces?

Thank you very much.
Jim Keenan


Paul Lalli 07-14-2005 01:51 PM

Re: Getting 'system' to Process Win32 Paths Correctly
 
Jim Keenan wrote:
> I wish to supply a user with a Perl distribution which includes a
> command-line utility and whose test suite tests the output of that
> utility. The test suite's call to that utility looks like this:
>
> ok(! system("$^X -I$cwd/blib/lib $cwd/blib/script/utility"),
> "able to call command-line utility");
>
> where $^X is the name used to execute the current copy of Perl and $cwd
> holds the name of the directory from which the test suite is called,
> i.e., the directory holding Makefile.PL.
>
> This works fine on my Unix-style system and fine on Win32 *provided*
> that $cwd contains no wordspaces. So if the value of $cwd is
> "C:/temp/other", the 'system' call correctly expands $cwd and the test
> runs as intended.


I don't think this has anything to do with system(), so much as it has
to do with standard command line processing. If there are spaces in a
command line, they're taking to be argument-separators. If you want
them to mean actual spaces, you have to escape them - either by
prepending them with a backslash, or by enclosing the entire argument
in quotes:

ok(! system(qq|^X -I"$cwd/blib/lib" "$cwd/blib/script/utility"|),
"able to call command-line utility"

Paul Lalli


A. Sinan Unur 07-14-2005 02:01 PM

Re: Getting 'system' to Process Win32 Paths Correctly
 
"Jim Keenan" <jkeen_via_google@yahoo.com> wrote in
news:1121348311.256832.140110@f14g2000cwb.googlegr oups.com:

> I wish to supply a user with a Perl distribution which includes a
> command-line utility and whose test suite tests the output of that
> utility. The test suite's call to that utility looks like this:
>
> ok(! system("$^X -I$cwd/blib/lib $cwd/blib/script/utility"),
> "able to call command-line utility");
>


....

> However, if the value of $cwd is "C:/Documents and
> Settings/localuser/My Documents", then the only part of the path that
> get substituted is "C:/Documents".


The easy way is to wrap the file name in quotation marks:

system("$^X -Iqq{$cwd/blib/lib} qq{$cwd/blib/script/utility}");

On the other hand, for better portability, I would construct the
individual paths using File::Spec::catfile anyway.

By the way, there is a difference between calling system as above versus

system($^X, -I$cwd/blib/lib, $cwd/blib/script/utility);

D:\Home\asu1\UseNet\clpmisc> cat ttt.pl
#!/usr/bin/perl

use strict;
use warnings;

my $appdata = $ENV{APPDATA};

system "perl t2.pl $appdata";
system 'perl', 't2.pl', $appdata;
__END__

D:\Home\asu1\UseNet\clpmisc> cat t2.pl
#!/usr/bin/perl

use strict;
use warnings;

print "$_\n" for @ARGV;

__END__

D:\Home\asu1\UseNet\clpmisc> ttt
C:\Documents
and
Settings\asu1\Application
Data
C:\Documents and Settings\asu1\Application Data

Read

perldoc -f system

Sinan

--
A. Sinan Unur <1usa@llenroc.ude.invalid>
(reverse each component and remove .invalid for email address)

comp.lang.perl.misc guidelines on the WWW:
http://mail.augustmail.com/~tadmc/cl...uidelines.html

A. Sinan Unur 07-14-2005 02:05 PM

Re: Getting 'system' to Process Win32 Paths Correctly
 
"Paul Lalli" <mritty@gmail.com> wrote in
news:1121349105.502877.106680@g44g2000cwa.googlegr oups.com:

> Jim Keenan wrote:
>> I wish to supply a user with a Perl distribution which includes a
>> command-line utility and whose test suite tests the output of that
>> utility. The test suite's call to that utility looks like this:
>>
>> ok(! system("$^X -I$cwd/blib/lib $cwd/blib/script/utility"),
>> "able to call command-line utility");
>>
>> where $^X is the name used to execute the current copy of Perl and
>> $cwd holds the name of the directory from which the test suite is
>> called, i.e., the directory holding Makefile.PL.
>>
>> This works fine on my Unix-style system and fine on Win32 *provided*
>> that $cwd contains no wordspaces. So if the value of $cwd is
>> "C:/temp/other", the 'system' call correctly expands $cwd and the
>> test runs as intended.

>
> I don't think this has anything to do with system(),


Indeed it does. There is a difference between passing a single scalar
string versus a list to system.

Sinan

--
A. Sinan Unur <1usa@llenroc.ude.invalid>
(reverse each component and remove .invalid for email address)

comp.lang.perl.misc guidelines on the WWW:
http://mail.augustmail.com/~tadmc/cl...uidelines.html

Paul Lalli 07-14-2005 02:33 PM

Re: Getting 'system' to Process Win32 Paths Correctly
 
A. Sinan Unur wrote:
> "Paul Lalli" <mritty@gmail.com> wrote in
> news:1121349105.502877.106680@g44g2000cwa.googlegr oups.com:
>
> > Jim Keenan wrote:
> >> I wish to supply a user with a Perl distribution which includes a
> >> command-line utility and whose test suite tests the output of that
> >> utility. The test suite's call to that utility looks like this:
> >>
> >> ok(! system("$^X -I$cwd/blib/lib $cwd/blib/script/utility"),
> >> "able to call command-line utility");
> >>
> >> where $^X is the name used to execute the current copy of Perl and
> >> $cwd holds the name of the directory from which the test suite is
> >> called, i.e., the directory holding Makefile.PL.
> >>
> >> This works fine on my Unix-style system and fine on Win32 *provided*
> >> that $cwd contains no wordspaces. So if the value of $cwd is
> >> "C:/temp/other", the 'system' call correctly expands $cwd and the
> >> test runs as intended.

> >
> > I don't think this has anything to do with system(),

>
> Indeed it does. There is a difference between passing a single scalar
> string versus a list to system.


Hrm. Good point. Trying to see if I understand perldoc -f system
correctly... so if a single string is passed, system lets the shell
parse the string into program + arguments, but if a list of more than
item is passed, system executes the first element, specifying the
remainder as arguments?

Good to keep in mind. Thanks for the reminder.

Paul Lalli


A. Sinan Unur 07-14-2005 02:48 PM

Re: Getting 'system' to Process Win32 Paths Correctly
 
"A. Sinan Unur" <1usa@llenroc.ude.invalid> wrote in
news:Xns969366015F405asu1cornelledu@127.0.0.1:

> "Jim Keenan" <jkeen_via_google@yahoo.com> wrote in
> news:1121348311.256832.140110@f14g2000cwb.googlegr oups.com:
>
>> I wish to supply a user with a Perl distribution which includes a
>> command-line utility and whose test suite tests the output of that
>> utility. The test suite's call to that utility looks like this:
>>
>> ok(! system("$^X -I$cwd/blib/lib $cwd/blib/script/utility"),
>> "able to call command-line utility");
>>

>
> ...
>
>> However, if the value of $cwd is "C:/Documents and
>> Settings/localuser/My Documents", then the only part of the path that
>> get substituted is "C:/Documents".

>
> The easy way is to wrap the file name in quotation marks:
>
> system("$^X -Iqq{$cwd/blib/lib} qq{$cwd/blib/script/utility}");


And, this, of course, is wrong. The correct version would have been:

system(qq{$^X -I"$cwd/blib/lib" "$cwd/blib/script/utility"});

My other comments regarding passing a list to system, and using
File::Spec::catfile to construct paths still apply, though.

Sinan
--
A. Sinan Unur <1usa@llenroc.ude.invalid>
(reverse each component and remove .invalid for email address)

comp.lang.perl.misc guidelines on the WWW:
http://mail.augustmail.com/~tadmc/cl...uidelines.html

Jim Keenan 07-14-2005 05:39 PM

Re: Getting 'system' to Process Win32 Paths Correctly
 
A. Sinan Unur wrote:
> The correct version would have been:
>
> system(qq{$^X -I"$cwd/blib/lib" "$cwd/blib/script/utility"});
>
>


Thanks, Sinan, this DWIMmed. A note for further reference: To pare
the original question down to its essence, I omitted options that the
command-line utility would normally call. When I tested the real code,
I had to add them back in. The quoting that worked for them went like
this:

ok(! system(qq{$^X -I"$cwd/blib/lib" "$cwd/blib/script/utility" -Icn
XYZ::ABC}),
"able to call utility");

Note that the option flags and arguments are not placed within the
quotation marks, but are still within the scope of the 'qq{}'.

Jim Keenan


Brian McCauley 07-15-2005 04:56 PM

Re: Getting 'system' to Process Win32 Paths Correctly
 
A. Sinan Unur wrote:

> "Paul Lalli" <mritty@gmail.com> wrote in
> news:1121349105.502877.106680@g44g2000cwa.googlegr oups.com:
>>
>>I don't think this has anything to do with system(),

>
> Indeed it does. There is a difference between passing a single scalar
> string versus a list to system.


Except this is Win32 - where there isn't a difference.

system(LIST) effectively joins the list with spaces and the CLI splits
it again (in all the wrong places).


A. Sinan Unur 07-16-2005 12:35 PM

Re: Getting 'system' to Process Win32 Paths Correctly
 
Brian McCauley <nobull@mail.com> wrote in news:db8pri$f8g$1
@redhat2.bham.ac.uk:

> A. Sinan Unur wrote:
>
>> "Paul Lalli" <mritty@gmail.com> wrote in
>> news:1121349105.502877.106680@g44g2000cwa.googlegr oups.com:
> >>
>>>I don't think this has anything to do with system(),

>>
>> Indeed it does. There is a difference between passing a single scalar
>> string versus a list to system.

>
> Except this is Win32 - where there isn't a difference.
>
> system(LIST) effectively joins the list with spaces and the CLI splits
> it again (in all the wrong places).


I am not sure if you noticed my earlier example. Here is another one of
system(SCALAR) versus system(LIST). There clearly is a difference.

D:\Home\asu1\UseNet\clpmisc> cat hello.c
#include <stdio.h>

int main(int argc, char *argv[]) {
int i;
for(i = 0; i < argc; ++i) {
printf("%s\n", argv[i]);
}
}

D:\Home\asu1\UseNet\clpmisc> cl hello.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for
80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

hello.c
Microsoft (R) Incremental Linker Version 7.10.3077
Copyright (C) Microsoft Corporation. All rights reserved.

/out:hello.exe
hello.obj

D:\Home\asu1\UseNet\clpmisc> cat ttt.pl
#!/usr/bin/perl

use strict;
use warnings;

system "hello A. Sinan Unur ---";
system 'hello', 'A. Sinan Unur', '---';

D:\Home\asu1\UseNet\clpmisc> ttt.pl
hello
A.
Sinan
Unur
---
hello
A. Sinan Unur
---

Sinan
--
A. Sinan Unur <1usa@llenroc.ude.invalid>
(reverse each component and remove .invalid for email address)

comp.lang.perl.misc guidelines on the WWW:
http://mail.augustmail.com/~tadmc/cl...uidelines.html


All times are GMT. The time now is 03:30 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.