Skip to content

Commit 969eb6c

Browse files
committed
ParseXS: refactor: add Node::MODULE
(This commit is part of a series which will extend the AST parse tree from just representing individual XSUBs to representing the whole XS file.) Add a new node type, ExtUtils::ParseXS::Node::MODULE. this (mostly) regularises the treatment of a MODULE line, now handled in the usual way by parse_keywords(), rather than being a special magical snowflake that got its own handling in fetch_para(). This commit also changes one parameter of parse_keywords() from being a boolean to being a bit flag, now that there are now *two* slightly special cases to flag up: MODULE, in addition to NOT_IMPLEMENTED_YET. This commit is supposed to have no changes in behaviour, but there *might* be some edge cases that I haven't thought of.
1 parent 01a94f3 commit 969eb6c

File tree

2 files changed

+81
-41
lines changed

2 files changed

+81
-41
lines changed

dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -508,24 +508,6 @@ sub Q {
508508
}
509509

510510

511-
# Process "MODULE = Foo ..." lines and update global state accordingly
512-
513-
sub _process_module_xs_line {
514-
my ExtUtils::ParseXS $self = shift;
515-
my ($module, $pkg, $prefix) = @_;
516-
517-
($self->{MODULE_cname} = $module) =~ s/\W/_/g;
518-
519-
$self->{PACKAGE_name} = defined($pkg) ? $pkg : '';
520-
$self->{PREFIX_pattern} = quotemeta( defined($prefix) ? $prefix : '' );
521-
522-
($self->{PACKAGE_C_name} = $self->{PACKAGE_name}) =~ tr/:/_/;
523-
524-
$self->{PACKAGE_class} = $self->{PACKAGE_name};
525-
$self->{PACKAGE_class} .= "::" if $self->{PACKAGE_class} ne "";
526-
}
527-
528-
529511
# Skip any embedded POD sections, reading in lines from {in_fh} as necessary.
530512

531513
sub _maybe_skip_pod {
@@ -677,21 +659,6 @@ sub fetch_para {
677659
@{ $self->{line} } = ();
678660
@{ $self->{line_no} } = ();
679661

680-
if (ExtUtils::ParseXS::Utilities::looks_like_MODULE_line($self->{lastline}))
681-
{
682-
$self->{lastline} =~
683-
/^
684-
MODULE \s* = \s* ([\w:]+)
685-
(?: \s+ PACKAGE \s* = \s* ([\w:]+))?
686-
(?: \s+ PREFIX \s* = \s* (\S+))?
687-
\s*
688-
$/x
689-
or $self->death("Error: unparseable MODULE line: '$self->{lastline}'");
690-
691-
$self->_process_module_xs_line($1, $2, $3);
692-
$self->{lastline} = "";
693-
}
694-
695662
# count how many #ifdef levels we see in this paragraph
696663
# decrementing when we see an endif. if we see an elsif
697664
# or endif without a corresponding #ifdef then we don't

dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS/Node.pm

Lines changed: 81 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,11 @@ shown above.
208208
my $open_brace = '{';
209209
my $close_brace = '}';
210210

211+
# values for parse_keywords() flags
212+
# (Can't assume 'constant.pm' is present yet)
213+
214+
my $keywords_flag_MODULE = 1;
215+
my $keywords_flag_NOT_IMPLEMENTED_YET = 2;
211216

212217
# Utility sub to handle all the boilerplate of declaring a Node subclass,
213218
# including setting up @INC and @FIELDS. Intended to be called from within
@@ -327,6 +332,10 @@ sub parse {
327332
# If $max is defined, it specifies the maximum number of keywords to
328333
# process. This value is typically passed as undef (unlimited) or 1
329334
# (just grab the next keyword).
335+
# $flags can contain $keywords_flag_MODULE or
336+
# keywords_flag_NOT_IMPLEMENTED_YET to indicate to match one of those
337+
# keywords too (whose syntax is slightly different from 'KEY:' and
338+
# so need special handling
330339

331340
sub parse_keywords {
332341
my __PACKAGE__ $self = shift;
@@ -335,24 +344,39 @@ sub parse_keywords {
335344
my $xbody = shift;
336345
my $max = shift; # max number of keywords to process
337346
my $pat = shift;
338-
my $do_notimplemented = shift;
347+
my $flags = shift;
348+
349+
$flags = 0 unless defined $flags;
339350

340351
my $n = 0;
341352
my @kids;
342353
while (@{$pxs->{line}}) {
343354
my $line = shift @{$pxs->{line}};
344355
next unless $line =~ /\S/;
345-
# extract/delete recognised keyword and any following comment
346-
unless ( $line =~ s/^(\s*)($pat)\s*:\s*(?:#.*)?/$1/s
347-
or ( $do_notimplemented
356+
357+
# extract/delete recognised keyword and any following text
358+
my $keyword;
359+
360+
if ( ($flags & $keywords_flag_MODULE)
361+
&& ExtUtils::ParseXS::Utilities::looks_like_MODULE_line($line)
362+
)
363+
{
364+
$keyword = 'MODULE';
365+
}
366+
elsif ( $line =~ s/^(\s*)($pat)\s*:\s*(?:#.*)?/$1/s
367+
or ( ($flags & $keywords_flag_NOT_IMPLEMENTED_YET)
348368
&& $line =~ s/^(\s*)(NOT_IMPLEMENTED_YET)/$1/
349369
)
350-
) {
370+
)
371+
{
372+
$keyword = $2
373+
}
374+
else {
351375
# stop at unrecognised line
352376
unshift @{$pxs->{line}}, $line;
353377
last;
354378
}
355-
my $keyword = $2;
379+
356380
unshift @{$pxs->{line}}, $line;
357381
# create a node for the keyword and parse any lines associated
358382
# with it.
@@ -1167,7 +1191,8 @@ sub parse {
11671191
undef, undef, # xsub and xbody: not needed for non XSUB keywords
11681192
undef, # implies process as many keywords as possible
11691193
"BOOT|REQUIRE|PROTOTYPES|EXPORT_XSUB_SYMBOLS|FALLBACK"
1170-
. "|VERSIONCHECK|INCLUDE|INCLUDE_COMMAND|SCOPE"
1194+
. "|VERSIONCHECK|INCLUDE|INCLUDE_COMMAND|SCOPE",
1195+
$keywords_flag_MODULE,
11711196
);
11721197

11731198
# skip blank lines
@@ -4252,7 +4277,7 @@ sub parse {
42524277
$pxs, $xsub, $xbody,
42534278
1, # match at most one keyword
42544279
"CODE|PPCODE",
4255-
1, # also match NOT_IMPLEMENTED_YET
4280+
$keywords_flag_NOT_IMPLEMENTED_YET,
42564281
);
42574282

42584283
# Didn't find a CODE keyword or similar, so auto-generate a call
@@ -4529,6 +4554,54 @@ sub parse {
45294554
}
45304555

45314556

4557+
# ======================================================================
4558+
4559+
package ExtUtils::ParseXS::Node::MODULE;
4560+
4561+
# Process a MODULE keyword, e.g.
4562+
#
4563+
# MODULE = Foo PACKAGE = Foo::Bar PREFIX = foo_
4564+
4565+
BEGIN { $build_subclass->(-parent => 'oneline',
4566+
'module', # Str
4567+
'package', # Str: may be ''
4568+
'prefix', # Str: may be ''
4569+
)};
4570+
4571+
4572+
sub parse {
4573+
my __PACKAGE__ $self = shift;
4574+
my ExtUtils::ParseXS $pxs = shift;
4575+
4576+
$self->SUPER::parse($pxs); # set file/line_no
4577+
4578+
my $line = $self->{text};
4579+
my ($module, $pkg, $prefix) = $line =~
4580+
/^
4581+
MODULE \s* = \s* ([\w:]+)
4582+
(?: \s+ PACKAGE \s* = \s* ([\w:]+))?
4583+
(?: \s+ PREFIX \s* = \s* (\S+))?
4584+
\s*
4585+
$/x
4586+
or $pxs->death("Error: unparseable MODULE line: '$line'");
4587+
4588+
$self->{module} = $module;
4589+
($pxs->{MODULE_cname} = $module) =~ s/\W/_/g;
4590+
4591+
$self->{package} = $pxs->{PACKAGE_name} = defined($pkg) ? $pkg : '';
4592+
4593+
$self->{prefix} = $prefix = defined($prefix) ? $prefix : '';
4594+
$pxs->{PREFIX_pattern} = quotemeta($prefix);
4595+
4596+
($pxs->{PACKAGE_C_name} = $pxs->{PACKAGE_name}) =~ tr/:/_/;
4597+
4598+
$pxs->{PACKAGE_class} = $pxs->{PACKAGE_name};
4599+
$pxs->{PACKAGE_class} .= "::" if $pxs->{PACKAGE_class} ne "";
4600+
4601+
1;
4602+
}
4603+
4604+
45324605
# ======================================================================
45334606

45344607
package ExtUtils::ParseXS::Node::NOT_IMPLEMENTED_YET;

0 commit comments

Comments
 (0)