@@ -1056,14 +1056,20 @@ sub parse {
10561056 my __PACKAGE__ $self = shift ;
10571057 my ExtUtils::ParseXS $pxs = shift ;
10581058
1059- # ----------------------------------------------------------------
1060- # Main loop: for each iteration, read in a paragraph's worth of XSUB
1061- # definition or XS/CPP directives into @{ $self->{line} }, then try to
1062- # interpret those lines.
1063- # ----------------------------------------------------------------
1059+ # Main loop: for each iteration, parse the next 'thing' in the current
1060+ # paragraph, such as a C preprocessor directive, a contiguous block of
1061+ # file-scoped keywords, or an XSUB. When the current paragraph runs
1062+ # out, read in another one. XSUBs, TYPEMAP and BOOT will consume
1063+ # all lines until the end of the current paragraph.
1064+ #
1065+ # C preprocessor conditionals such as #if may trigger recursive
1066+ # calls to process each branch until the matching #endif. These may
1067+ # cross paragraph boundaries.
1068+
1069+ while ( ($pxs -> {line } && @{$pxs -> {line }}) || $pxs -> fetch_para())
1070+ {
1071+ next unless @{$pxs -> {line }}; # fetch_para() can return zero lines
10641072
1065- PARAGRAPH:
1066- while ( ($pxs -> {line } && @{$pxs -> {line }}) || $pxs -> fetch_para()) {
10671073 if ( !defined ($self -> {line_no })
10681074 && defined $pxs -> {line_no }[0]
10691075 ) {
@@ -1072,13 +1078,18 @@ sub parse {
10721078 $self -> SUPER::parse($pxs );
10731079 }
10741080
1075- # Process any initial C-preprocessor lines and blank
1076- # lines. Note that any non-CPP lines starting with '#' will
1077- # already have been filtered out by fetch_para().
1081+ # skip blank line
1082+ shift @{$pxs -> {line }}, next if $pxs -> {line }[0] !~ / \S / ;
1083+
1084+ # Process a C-preprocessor line. Note that any non-CPP lines
1085+ # starting with '#' will already have been filtered out by
1086+ # fetch_para().
10781087 #
1079- # Also, keep track of #if/#else/#endif nesting.
1088+ # If its a #if or similar, then recursively process each branch
1089+ # as a separate cpp_scope object until the matching #endif is
1090+ # reached.
10801091
1081- while (@{ $pxs -> { line }} && $pxs -> {line }[0] =~ / ^#/ ) {
1092+ if ( $pxs -> {line }[0] =~ / ^#/ ) {
10821093 my $node = ExtUtils::ParseXS::Node::global_cpp_line-> new();
10831094 $node -> parse($pxs );
10841095 push @{$self -> {kids }}, $node ;
@@ -1105,7 +1116,7 @@ sub parse {
11051116 # other branches of the same conditional.
11061117
11071118 while (1) {
1108- # Parse the branch in new scope
1119+ # For each iteration, parse the next branch in a new scope
11091120 my $scope = ExtUtils::ParseXS::Node::cpp_scope-> new(
11101121 {type => ' if' });
11111122 $scope -> parse($pxs )
@@ -1141,12 +1152,9 @@ sub parse {
11411152 # any more branches to process of current if?
11421153 last if $last -> {is_endif };
11431154 } # while 1
1144- } # while /^#/
1145-
1146- # skip blank lines
1147- shift @{$pxs -> {line }} while @{$pxs -> {line }} && $pxs -> {line }[0] !~ / \S / ;
11481155
1149- next PARAGRAPH unless @{ $pxs -> {line } };
1156+ next ;
1157+ }
11501158
11511159 # die if the next line is indented: all file-scoped things (CPP,
11521160 # keywords, XSUB starts) are supposed to start on column 1
@@ -1189,20 +1197,17 @@ sub parse {
11891197 $pxs -> {file_SCOPE_enabled } = 0;
11901198
11911199 # Process file-scoped keywords
1192-
1193- # ----------------------------------------------------------------
1194- # Process file-scoped keywords
1195- # ----------------------------------------------------------------
1196-
11971200 #
11981201 # This loop repeatedly: skips any blank lines and then calls
11991202 # the relevant Node::FOO::parse() method if it finds any of the
12001203 # file-scoped keywords in the passed pattern.
12011204 #
1202- # Note due to the looping within parse_keywords() rather than
1205+ # Note: due to the looping within parse_keywords() rather than
12031206 # looping here, only the first keyword in a contiguous block
1204- # gets the 'start at column 1' check above enforced. This is
1205- # a bug, maintained for backwards compatibility.
1207+ # gets the 'start at column 1' check above enforced.
1208+ # This is a bug, maintained for backwards compatibility: see the
1209+ # comments below referring to SCOPE for other bits of code needed
1210+ # to enforce this compatibility.
12061211
12071212 $self -> parse_keywords(
12081213 $pxs ,
@@ -1212,19 +1217,20 @@ sub parse {
12121217 . " |VERSIONCHECK|INCLUDE|INCLUDE_COMMAND|SCOPE|TYPEMAP" ,
12131218 $keywords_flag_MODULE ,
12141219 );
1220+ # XXX we could have an 'or next' here if not for SCOPE backcompat
1221+ # and also delete the following 'skip blank line' and 'next unless
1222+ # @line' lines
12151223
12161224 # skip blank lines
12171225 shift @{$pxs -> {line }} while @{$pxs -> {line }} && $pxs -> {line }[0] !~ / \S / ;
12181226
1219- next PARAGRAPH unless @{ $pxs -> {line } };
1227+ next unless @{$pxs -> {line }};
12201228
1221- # ----------------------------------------------------------------
1222- # Parse and code-emit an XSUB
1223- # ----------------------------------------------------------------
1229+ # Parse an XSUB
12241230
12251231 my $xsub = ExtUtils::ParseXS::Node::xsub-> new();
12261232 $xsub -> parse($pxs )
1227- or next PARAGRAPH ;
1233+ or next ;
12281234 push @{$self -> {kids }}, $xsub ;
12291235
12301236 # Check for a duplicate function definition in this scope
@@ -1238,13 +1244,14 @@ sub parse {
12381244 $self -> {seen_xsubs }{$name } = 1;
12391245 }
12401246
1241-
1242-
1247+ # xsub->parse() should have consumed all the remaining
1248+ # lines in the current paragraph.
12431249 die " Internal error: unexpectedly not at EOF\n "
12441250 if @{$pxs -> {line }};
12451251
12461252 $pxs -> {seen_an_XSUB } = 1; # encountered at least one XSUB
1247- } # END 'PARAGRAPH' 'while' loop
1253+
1254+ } # END main 'while' loop
12481255
12491256 1;
12501257}
0 commit comments