Subject: | [PATCH] partial portability help for dubious INCLUDE_COMMAND feature |
First of all, I really don't think the INCLUDE_COMMAND feature is a great idea for the
following reasons:
1.) The command must parse under 3 different languages, one of which is always unknown.
The three languages are XS, the C preprocessor, and whatever command shell you're running
on, and you don't know what shell that will be when you write your XS code. The chances of
the average module maintainer getting all of that right all of the time seems slim.
2.) In section 6.10.4, the C standard says,
Show quoted text
---quote---
A preprocessing directive of the form
# line digit-sequence "s-char-sequenceopt" new-line
sets the presumed line number similarly and changes the presumed name of the source
file to be the contents of the character string literal.
---endquote---
The INCLUDE_COMMAND feature violates this because the character string literal it inserts is
not a presumed filename but a command. Any source-level debugger, IDE, or other tool that
tries to use this information to load the relevant "file" (and some of them do), will break.
They may break nicely and continue, or they may crash, hang, or spew confusing error
messages. Putting something in there that is not a filename is wrong.
3.) The feature is anti-portable because it encourages people to generate XS code with
external commands, which are likely to be platform-specific. If the assumption is that
people will use Perl to generate XS code then why not base a new feature on do() rather than
running Perl as an external command?
Since I'm late to the party and often unpersuasive in convincing people not to do crazy
things, the attached patch gets the tests passing on VMS (and still passing on Mac OS X)
without addressing any of the concerns above.
Subject: | 0001-Make-INCLUDE_COMMAND-semi-portable.patch |
From 430186bb3dcd0bdb46f545e30282c67bd0c15e8d Mon Sep 17 00:00:00 2001
From: Craig A. Berry <craigberry@mac.com>
Date: Sun, 6 Jun 2010 17:56:01 -0500
Subject: [PATCH] Make INCLUDE_COMMAND semi-portable.
At the very least, arguments to the command must be quoted on VMS
to preserve case. The double quotes then have to be escaped to
be parseable as a string literal by the C preprocessor for the #line
directive. The result is still dubious, as it is in no way "the
presumed name of the source file" as the C standard says it must
be, but this does get it passing tests.
This change also stops pasting the directory onto the command
since it's a command, not a path, and for the INCLUDE handler,
it properly assembles the path using File::Spec->catfile().
---
lib/ExtUtils/ParseXS.pm | 17 +++++++++++++++--
1 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/lib/ExtUtils/ParseXS.pm b/lib/ExtUtils/ParseXS.pm
index 795145c..9dc0901 100644
--- a/lib/ExtUtils/ParseXS.pm
+++ b/lib/ExtUtils/ParseXS.pm
@@ -1543,7 +1543,7 @@ sub INCLUDE_handler ()
EOF
$filename = $_ ;
- $filepathname = "$dir/$filename";
+ $filepathname = File::Spec->catfile($dir, $filename);
# Prime the pump by reading the first
# non-blank line
@@ -1557,12 +1557,24 @@ EOF
$lastline_no = $. ;
}
+sub QuoteArgs {
+ my $cmd = shift;
+ my @args = split /\s+/, $cmd;
+ $cmd = shift @args;
+ for (@args) {
+ $_ = q(").$_.q(") if !/^\"/ && length($_) > 0;
+ }
+ return join (' ', ($cmd, @args));
+ }
+
sub INCLUDE_COMMAND_handler ()
{
# the rest of the current line should contain a valid command
TrimWhitespace($_) ;
+ $_ = QuoteArgs($_) if $^O eq 'VMS';
+
death("INCLUDE_COMMAND: command missing")
unless $_ ;
@@ -1588,7 +1600,8 @@ sub INCLUDE_COMMAND_handler ()
EOF
$filename = $_ ;
- $filepathname = "$dir/$filename";
+ $filepathname = $filename;
+ $filepathname =~ s/\"/\\"/g;
# Prime the pump by reading the first
# non-blank line
--
1.7.0.3