@@ -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,19 @@ 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
1083+ if @{$pxs -> {line }} && $pxs -> {line }[0] !~ / \S / ;
1084+
1085+ # Process a C-preprocessor line. Note that any non-CPP lines
1086+ # starting with '#' will already have been filtered out by
1087+ # fetch_para().
10781088 #
1079- # Also, keep track of #if/#else/#endif nesting.
1089+ # If its a #if or similar, then recursively process each branch
1090+ # as a separate cpp_scope object until the matching #endif is
1091+ # reached.
10801092
1081- while (@{ $pxs -> { line }} && $pxs -> {line }[0] =~ / ^#/ ) {
1093+ if ( $pxs -> {line }[0] =~ / ^#/ ) {
10821094 my $node = ExtUtils::ParseXS::Node::global_cpp_line-> new();
10831095 $node -> parse($pxs );
10841096 push @{$self -> {kids }}, $node ;
@@ -1105,7 +1117,7 @@ sub parse {
11051117 # other branches of the same conditional.
11061118
11071119 while (1) {
1108- # Parse the branch in new scope
1120+ # For each iteration, parse the next branch in a new scope
11091121 my $scope = ExtUtils::ParseXS::Node::cpp_scope-> new(
11101122 {type => ' if' });
11111123 $scope -> parse($pxs )
@@ -1141,12 +1153,9 @@ sub parse {
11411153 # any more branches to process of current if?
11421154 last if $last -> {is_endif };
11431155 } # while 1
1144- } # while /^#/
1145-
1146- # skip blank lines
1147- shift @{$pxs -> {line }} while @{$pxs -> {line }} && $pxs -> {line }[0] !~ / \S / ;
11481156
1149- next PARAGRAPH unless @{ $pxs -> {line } };
1157+ next ;
1158+ }
11501159
11511160 # die if the next line is indented: all file-scoped things (CPP,
11521161 # keywords, XSUB starts) are supposed to start on column 1
@@ -1189,20 +1198,17 @@ sub parse {
11891198 $pxs -> {file_SCOPE_enabled } = 0;
11901199
11911200 # Process file-scoped keywords
1192-
1193- # ----------------------------------------------------------------
1194- # Process file-scoped keywords
1195- # ----------------------------------------------------------------
1196-
11971201 #
11981202 # This loop repeatedly: skips any blank lines and then calls
11991203 # the relevant Node::FOO::parse() method if it finds any of the
12001204 # file-scoped keywords in the passed pattern.
12011205 #
1202- # Note due to the looping within parse_keywords() rather than
1206+ # Note: due to the looping within parse_keywords() rather than
12031207 # 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.
1208+ # gets the 'start at column 1' check above enforced.
1209+ # This is a bug, maintained for backwards compatibility: see the
1210+ # comments below referring to SCOPE for other bits of code needed
1211+ # to enforce this compatibility.
12061212
12071213 $self -> parse_keywords(
12081214 $pxs ,
@@ -1212,19 +1218,20 @@ sub parse {
12121218 . " |VERSIONCHECK|INCLUDE|INCLUDE_COMMAND|SCOPE|TYPEMAP" ,
12131219 $keywords_flag_MODULE ,
12141220 );
1221+ # XXX we could have an 'or next' here if not for SCOPE backcompat
1222+ # and also delete the following 'skip blank line' and 'next unless
1223+ # @line' lines
12151224
12161225 # skip blank lines
12171226 shift @{$pxs -> {line }} while @{$pxs -> {line }} && $pxs -> {line }[0] !~ / \S / ;
12181227
1219- next PARAGRAPH unless @{ $pxs -> {line } };
1228+ next unless @{$pxs -> {line }};
12201229
1221- # ----------------------------------------------------------------
1222- # Parse and code-emit an XSUB
1223- # ----------------------------------------------------------------
1230+ # Parse an XSUB
12241231
12251232 my $xsub = ExtUtils::ParseXS::Node::xsub-> new();
12261233 $xsub -> parse($pxs )
1227- or next PARAGRAPH ;
1234+ or next ;
12281235 push @{$self -> {kids }}, $xsub ;
12291236
12301237 # Check for a duplicate function definition in this scope
@@ -1238,13 +1245,14 @@ sub parse {
12381245 $self -> {seen_xsubs }{$name } = 1;
12391246 }
12401247
1241-
1242-
1248+ # xsub->parse() should have consumed all the remaining
1249+ # lines in the current paragraph.
12431250 die " Internal error: unexpectedly not at EOF\n "
12441251 if @{$pxs -> {line }};
12451252
12461253 $pxs -> {seen_an_XSUB } = 1; # encountered at least one XSUB
1247- } # END 'PARAGRAPH' 'while' loop
1254+
1255+ } # END main 'while' loop
12481256
12491257 1;
12501258}
0 commit comments