Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
848c3b7
Bump ExtUtils::ParseXS to 3.61
iabyn Oct 8, 2025
c45207c
ParseXS: refactor: add stub top-level node
iabyn Oct 8, 2025
38eb7ac
ParseXS: refactor: add Node::preamble
iabyn Oct 10, 2025
e05aac7
ParseXS: refactor: add Node::C_part
iabyn Oct 10, 2025
1c98325
ParseXS: refactor: add Node::postamble
iabyn Oct 10, 2025
201fc0c
ParseXS: refactor: add Node::global_cpp_line
iabyn Oct 10, 2025
51357f9
ParseXS: refactor: simplify double-negative regex
iabyn Oct 10, 2025
c153926
ParseXS: refactor: add Node::BOOT
iabyn Oct 12, 2025
30c7d5a
ParseXS: refactor: regularise BOOT processing
iabyn Oct 13, 2025
863754e
ParseXS: refactor: add Node::FALLBACK
iabyn Oct 13, 2025
8f8270f
ParseXS: refactor: add Node::REQUIRE
iabyn Oct 13, 2025
583011c
ParseXS: refactor: store current pkg in Node::xsub
iabyn Oct 20, 2025
3bb9e34
ParseXS: refactor: add Node::include etc
iabyn Oct 13, 2025
e65af0e
ParseXS: refactor: remove residual FOO_handler
iabyn Oct 13, 2025
9724016
ParseXS: refactor: remove check_keyword() method
iabyn Oct 14, 2025
b449039
ParseXS: add Node::as_concise method
iabyn Oct 18, 2025
552401e
ParseXS: refactor: add Node::cpp_scope
iabyn Oct 14, 2025
a78e434
ParseXS: refactor: use Node::cpp_scope for INCLUDE
iabyn Oct 15, 2025
7add86a
ParseXS: refactor: rm push_parse_stack, PopFile
iabyn Oct 15, 2025
9753f41
ParseXS: refactor: INCLUDE: save state locally
iabyn Oct 17, 2025
eb87763
ParseXS: refactor: global_cpp_line: parse CPP line
iabyn Oct 18, 2025
df8d3d7
ParseXS: fix #elif processing
iabyn Oct 18, 2025
21967f3
ParseXS: add more #if/#endif tests
iabyn Oct 21, 2025
a085cc8
ParseXS: refactor: reimplement #if processing
iabyn Oct 18, 2025
0881551
ParseXS: refactor: remove parser stack
iabyn Oct 20, 2025
7164235
ParseXS: refactor: move main parsing into XS_file
iabyn Oct 23, 2025
7436cf5
ParseXS: refactor: add Node::pre_boot
iabyn Oct 23, 2025
4aa0301
ParseXS: refactor: add Node::boot_xsub
iabyn Oct 23, 2025
6b82848
ParseXS: refactor: tidy Node::boot_xsub::parse()
iabyn Oct 23, 2025
39cf145
ParseXS: refactor: move some code
iabyn Oct 23, 2025
be71c4d
ParseXS: emit package overload registrations later
iabyn Oct 24, 2025
bcc6c05
ParseXS: refactor: add as_boot_code() methods
iabyn Oct 24, 2025
ae7ba09
ParseXS: refactor: inline and rm standard_XS_defs
iabyn Oct 24, 2025
7ab37e8
ParseXS: refactor: don't use $_ for C part of file
iabyn Oct 24, 2025
3194b77
ParseXS: refactor: remove $ExtUtils::ParseXS::END
iabyn Oct 24, 2025
88aa069
ParseXS: refactor: remove stray $_
iabyn Oct 24, 2025
75ea6d6
ParseXS: spot MODULE line syntax errors
iabyn Oct 25, 2025
7eb5946
ParseXS: refactor: add Node::MODULE
iabyn Oct 25, 2025
4eb804f
ParseXS: spot TYPEMAP: line syntax errors
iabyn Oct 25, 2025
85b283f
ParseXS: refactor: add Node::TYPEMAP
iabyn Oct 25, 2025
970d027
ParseXS: refactor: inline _maybe_skip_pod()
iabyn Oct 25, 2025
51348ed
ParseXS: refactor: move a chomp()
iabyn Oct 26, 2025
ce0f3aa
ParseXS: refactor: chomp TYPEMAP lines
iabyn Oct 26, 2025
52e57a2
ParseXS: fix POD on last line
iabyn Oct 26, 2025
35e3dda
ParseXS: refactor: fetch_para(): remove POD loop
iabyn Oct 26, 2025
990b981
ParseXS: refactor: fetch_para(): invert if
iabyn Oct 26, 2025
b84438e
ParseXS: refactor: fetch_para(): reindent
iabyn Oct 26, 2025
40f3830
ParseXS: process line continuations after POD
iabyn Oct 26, 2025
cb2593c
ParseXS: process line continuations after TYPEMAP
iabyn Oct 26, 2025
9d970e5
ParseXS: refactor: fetch_para(): add more comments
iabyn Oct 27, 2025
db33547
ParseXS: refactor: fetch_para(): simplify logic
iabyn Oct 27, 2025
7d4b810
ParseXS: refactor: fetch_para: update description
iabyn Oct 27, 2025
20d2937
ParseXS: refactor: fix comments re die if indented
iabyn Oct 28, 2025
64d7e86
ParseXS: refactor: simplify main loop
iabyn Oct 27, 2025
e93d277
ParseXS: refactor: rationalise parse-fail action
iabyn Oct 28, 2025
1324bc4
ParseXS: refactor: update POD and comments
iabyn Oct 29, 2025
d88ca93
ParseXS: refactor: add Node::Q method
iabyn Oct 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 0 additions & 113 deletions dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm
Original file line number Diff line number Diff line change
Expand Up @@ -883,67 +883,6 @@ sub push_parse_stack {
}


sub INCLUDE_handler {
my ExtUtils::ParseXS $self = shift;
$_ = shift;
# the rest of the current line should contain a valid filename

trim_whitespace($_);

$self->death("INCLUDE: filename missing")
unless $_;

$self->death("INCLUDE: output pipe is illegal")
if /^\s*\|/;

# simple minded recursion detector
$self->death("INCLUDE loop detected")
if $self->{IncludedFiles}->{$_};

++$self->{IncludedFiles}->{$_} unless /\|\s*$/;

if (/\|\s*$/ && /^\s*perl\s/) {
Warn( $self, "The INCLUDE directive with a command is discouraged." .
" Use INCLUDE_COMMAND instead! In particular using 'perl'" .
" in an 'INCLUDE: ... |' directive is not guaranteed to pick" .
" up the correct perl. The INCLUDE_COMMAND directive allows" .
" the use of \$^X as the currently running perl, see" .
" 'perldoc perlxs' for details.");
}

$self->push_parse_stack();

$self->{in_fh} = Symbol::gensym();

# open the new file
open($self->{in_fh}, $_) or $self->death("Cannot open '$_': $!");

print Q(<<"EOF");
|
|/* INCLUDE: Including '$_' from '$self->{in_filename}' */
|
EOF

$self->{in_filename} = $_;
$self->{in_pathname} = ( $^O =~ /^mswin/i )
# See CPAN RT #61908: gcc doesn't like
# backslashes on win32?
? qq($self->{dir}/$self->{in_filename})
: File::Spec->catfile($self->{dir}, $self->{in_filename});

# Prime the pump by reading the first
# non-blank line

# skip leading blank lines
while (readline($self->{in_fh})) {
last unless /^\s*$/;
}

$self->{lastline} = $_;
$self->{lastline_no} = $.;
}


# Quote a command-line to be suitable for VMS

sub QuoteArgs {
Expand Down Expand Up @@ -980,58 +919,6 @@ sub QuoteArgs {
}


sub INCLUDE_COMMAND_handler {
my ExtUtils::ParseXS $self = shift;
$_ = shift;
# the rest of the current line should contain a valid command

trim_whitespace($_);

$_ = QuoteArgs($_) if $^O eq 'VMS';

$self->death("INCLUDE_COMMAND: command missing")
unless $_;

$self->death("INCLUDE_COMMAND: pipes are illegal")
if /^\s*\|/ or /\|\s*$/;

$self->push_parse_stack( IsPipe => 1 );

$self->{in_fh} = Symbol::gensym();

# If $^X is used in INCLUDE_COMMAND, we know it's supposed to be
# the same perl interpreter as we're currently running
my $X = $self->_safe_quote($^X); # quotes if has spaces
s/^\s*\$\^X/$X/;

# open the new file
open ($self->{in_fh}, "-|", $_)
or $self->death( $self, "Cannot run command '$_' to include its output: $!");

print Q(<<"EOF");
|
|/* INCLUDE_COMMAND: Including output of '$_' from '$self->{in_filename}' */
|
EOF

$self->{in_filename} = $_;
$self->{in_pathname} = $self->{in_filename};
#$self->{in_pathname} =~ s/\"/\\"/g; # Fails? See CPAN RT #53938: MinGW Broken after 2.21
$self->{in_pathname} =~ s/\\/\\\\/g; # Works according to reporter of #53938

# Prime the pump by reading the first
# non-blank line

# skip leading blank lines
while (readline($self->{in_fh})) {
last unless /^\s*$/;
}

$self->{lastline} = $_;
$self->{lastline_no} = $.;
}


# Pop the type => 'file' entry off the top of the @{ $self->{XS_parse_stack} }
# array following the end of processing an INCLUDEd file, and restore the
# former state.
Expand Down
170 changes: 170 additions & 0 deletions dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS/Node.pm
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ExtUtils::ParseXS::Node;
use strict;
use warnings;
use Symbol;

our $VERSION = '3.61';

Expand Down Expand Up @@ -3973,6 +3974,175 @@ sub parse {
}


# ======================================================================

package ExtUtils::ParseXS::Node::include;

# Common base class for the 'INCLUDE' and 'INCLUDE_COMMAND' keywords

BEGIN { $build_subclass->(-parent => 'oneline',
'is_cmd', # Bool: is INCLUDE_COMMAND
'inc_filename', # Str: the file/command to be included
'old_filename', # Str: the previous file
)};


sub parse {
my __PACKAGE__ $self = shift;
my ExtUtils::ParseXS $pxs = shift;

$self->SUPER::parse($pxs); # set file/line_no/text

my $f = $self->{text};
my $is_cmd = $self->{is_cmd};

if ($is_cmd) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the distinct messages there isn't really that much common between the two, it seems to me that it would be cleaner to put most of the specific code in the derived parse() methods.

Perhaps only with # Prime the pump onwards in ...::include::parse

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer to keep them together. It makes it easier to compare and contrast. For example, the two open() variants are now near to each other, as are the "quote/munge the path" variants. It's less likely that in future someone will fix/change one branch without being aware that the other branch needs consideration too.

$f = ExtUtils::ParseXS::QuoteArgs($f) if $^O eq 'VMS';

$pxs->death("INCLUDE_COMMAND: command missing")
unless length $f;

$pxs->death("INCLUDE_COMMAND: pipes are illegal")
if $f =~ /^\s*\|/ or $f =~ /\|\s*$/;
}
else {
$pxs->death("INCLUDE: filename missing")
unless length $f;

$pxs->death("INCLUDE: output pipe is illegal")
if $f =~ /^\s*\|/;

# simple minded recursion detector
$pxs->death("INCLUDE loop detected")
if $pxs->{IncludedFiles}{$f};

++$pxs->{IncludedFiles}->{$f} unless $f =~ /\|\s*$/;

if ($f =~ /\|\s*$/ && $f =~ /^\s*perl\s/) {
$pxs->Warn(
"The INCLUDE directive with a command is discouraged."
. " Use INCLUDE_COMMAND instead! In particular using 'perl'"
. " in an 'INCLUDE: ... |' directive is not guaranteed to pick"
. " up the correct perl. The INCLUDE_COMMAND directive allows"
. " the use of \$^X as the currently running perl, see"
. " 'perldoc perlxs' for details."
);
}
}

$pxs->push_parse_stack($is_cmd ? (IsPipe => 1) : ());

$pxs->{in_fh} = Symbol::gensym();

# Open the new file / pipe

if ($is_cmd) {
# Expand the special token '$^X' into the full path of the
# currently running perl interpreter
my $X = $pxs->_safe_quote($^X); # quotes if has spaces
$f =~ s/^\s*\$\^X/$X/;

open ($pxs->{in_fh}, "-|", $f)
or $pxs->death(
"Cannot run command '$f' to include its output: $!");
}
else {
open($pxs->{in_fh}, $f)
or $pxs->death("Cannot open '$f': $!");
}

$self->{old_filename} = $pxs->{in_filename};
$self->{inc_filename} = $f;
$pxs->{in_filename} = $f;

my $path = $f;
if ($is_cmd) {
#$path =~ s/\"/\\"/g; # Fails? See CPAN RT #53938: MinGW Broken after 2.21
$path =~ s/\\/\\\\/g; # Works according to reporter of #53938
}
else {
$path = ($^O =~ /^mswin/i)
# See CPAN RT #61908: gcc doesn't like
# backslashes on win32?
? "$pxs->{dir}/$path"
: File::Spec->catfile($pxs->{dir}, $path);
}
$pxs->{in_pathname} = $path;

# Prime the pump by reading the first non-blank line

# skip leading blank lines
while (readline($pxs->{in_fh})) {
last unless /^\s*$/;
}

$pxs->{lastline} = $_;
$pxs->{lastline_no} = $.;

1;
}


sub as_code {
my __PACKAGE__ $self = shift;
my ExtUtils::ParseXS $pxs = shift;

my $comment = $self->{is_cmd}
? "INCLUDE_COMMAND: Including output of"
: "INCLUDE: Including";

$comment .= " '$self->{inc_filename}' from '$self->{old_filename}'";

print ExtUtils::ParseXS::Q(<<"EOF");
|
|/* $comment */
|
EOF
}


# ======================================================================

package ExtUtils::ParseXS::Node::INCLUDE;

# Process the 'INCLUDE' keyword. Most processing is actually done by the
# parent 'include' class which handles INCLUDE_COMMAND too.

BEGIN { $build_subclass->(-parent => 'include',
)};


sub parse {
my __PACKAGE__ $self = shift;
my ExtUtils::ParseXS $pxs = shift;

$self->{is_cmd} = 0;
$self->SUPER::parse($pxs); # main parsing done by Node::include
1;
}


# ======================================================================

package ExtUtils::ParseXS::Node::INCLUDE_COMMAND;

# Process the 'INCLUDE_COMMAND' keyword. Most processing is actually done
# by the parent 'include' class which handles INCLUDE too.

BEGIN { $build_subclass->(-parent => 'include',
)};


sub parse {
my __PACKAGE__ $self = shift;
my ExtUtils::ParseXS $pxs = shift;

$self->{is_cmd} = 1;
$self->SUPER::parse($pxs); # main parsing done by Node::include
1;
}


# ======================================================================

package ExtUtils::ParseXS::Node::enable;
Expand Down