Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the ExtUtils-ParseXS CPAN distribution.

Report information
The Basics
Id: 58182
Status: resolved
Priority: 0/
Queue: ExtUtils-ParseXS

People
Owner: Nobody in particular
Requestors: cberry [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 2.2205
Fixed in: (no value)



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
Thank you. Applied in the repository. I think the portability concerns you raise are really with the original INCLUDE, which special-cased using a pipe character. The INCLUDE_COMMAND that Steffen Mueller added is just a more explicit way of doing what people were already doing with pipe and making it easier to execute against $^X correctly.