@@ -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