Skip to content

Commit 0028ecc

Browse files
committed
ParseXS: refactor: fetch_para(): add more comments
Add more code comments to fetch_para(), especially explaining how the "XSUB cuddled by #if/#endif without blank lines" mechanism works
1 parent fbfd5fb commit 0028ecc

File tree

1 file changed

+53
-11
lines changed

1 file changed

+53
-11
lines changed

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

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -608,15 +608,17 @@ sub fetch_para {
608608
@{ $self->{line} } = ();
609609
@{ $self->{line_no} } = ();
610610

611-
# count how many #ifdef levels we see in this paragraph
612-
# decrementing when we see an endif. if we see an elsif
613-
# or endif without a corresponding #ifdef then we don't
614-
# consider it part of this paragraph.
615-
my $if_level = 0;
611+
my $if_level = 0; # current depth of #if/#endif nesting
612+
613+
# Main loop: for each iteration, process the current line,
614+
# then maybe read in the next line and continue. Handle some special
615+
# cases like POD in their own little loop which may read multiple
616+
# lines.
616617

617618
for (;;) {
618619

619-
my $final;
620+
my $final; # if true, end loop after reading in the next line
621+
620622

621623
# Skip an embedded POD section
622624

@@ -629,7 +631,8 @@ sub fetch_para {
629631
goto read_next_line;
630632
}
631633

632-
# if present, extract out a TYPEMAP block as a paragraph
634+
635+
# If present, extract out a TYPEMAP block as a paragraph
633636
if ($self->{lastline} =~ /^TYPEMAP\s*:/) {
634637

635638
# Return what we have already and process this line on the
@@ -660,6 +663,9 @@ sub fetch_para {
660663
goto read_next_line;
661664
}
662665

666+
667+
# Strip code comment lines
668+
663669
if ($self->{lastline} =~ /^\s*#/
664670
# CPP directives:
665671
# ANSI: if ifdef ifndef elif else endif define undef
@@ -683,18 +689,51 @@ sub fetch_para {
683689
goto read_next_line;
684690
}
685691

686-
# A general line: process it
687-
688692

689693
# Blank line followed by char in column 1. Start of next XSUB?
694+
690695
last if $self->{lastline} =~ /^\S/
691696
&& @{ $self->{line} }
692697
&& $self->{line}->[-1] eq "";
693698

694-
# analyse CPP conditionals
699+
700+
# Must be a general line (e.g. file-scoped keyword or CPP directive):
701+
# process it.
702+
703+
# Analyse a CPP conditional line and if appropriate, make this line
704+
# the last line of the current paragraph, or the first line of the
705+
# next paragraph.
706+
695707
if ($self->{lastline}
696708
=~/^#[ \t]*(if|ifn?def|elif|else|endif|elifn?def)\b/)
697709
{
710+
# Allow a CPP conditional to directly precede or follow an XSUB
711+
# without the usual required blank line, e.g.
712+
#
713+
# #if X
714+
# void foo()
715+
# CODE:
716+
# ...
717+
# # if Y
718+
# ...
719+
# # endif
720+
# ...
721+
# #else
722+
# ...
723+
#
724+
# This is achieved by keeping track of CPP conditional nesting, to
725+
# determine whether the conditional (e.g. the #else above) is part
726+
# of the current paragraph, or is paired with something outside it.
727+
# In this example, the #if Y / #endif are internal to the paragraph,
728+
# while the #else is external and therefore indicates the end of the
729+
# current paragraph and so we should stop, even though "\n\n\S"
730+
# hasn't been encountered.
731+
#
732+
# Similarly we stop at the external '#if X', although here it is
733+
# trickier to distinguish internal from external. For #if's, we
734+
# achieve this by stopping if the #if is the first line in the
735+
# putative paragraph; otherwise treat it as internal.
736+
698737
my $type = $1;
699738
if ($type =~ /^if/) { # if, ifdef, ifndef
700739
if (@{$self->{line}}) {
@@ -725,7 +764,10 @@ sub fetch_para {
725764

726765

727766
read_next_line:
728-
# Read next line and continuation lines
767+
# Read next line and any continuation lines into $self->{lastline_no},
768+
# ready for the next iteration, or if $final, to be ready for the next
769+
# call to fetch_para().
770+
729771
last unless defined($self->{lastline} = readline($self->{in_fh}));
730772
$self->{lastline_no} = $.;
731773
my $tmp_line;

0 commit comments

Comments
 (0)