]> git.donarmstrong.com Git - perltidy.git/commitdiff
reduce max known iterations to converge (b878)
authorSteve Hancock <perltidy@users.sourceforge.net>
Wed, 2 Oct 2024 14:03:46 +0000 (07:03 -0700)
committerSteve Hancock <perltidy@users.sourceforge.net>
Wed, 2 Oct 2024 14:03:46 +0000 (07:03 -0700)
This involved the unusual combination of using -boc on a list with line breaks
both before and after commas. This was a simple fix. The max known number of
iterations to converge is now 3 instead of 5.

lib/Perl/Tidy.pm
lib/Perl/Tidy/Formatter.pm

index 30c835525e66f144b4afdfa2b731df295e73a06e..e2133172461c288b978a72a5ab01f2726bcb0a8c 100644 (file)
@@ -2704,7 +2704,7 @@ EOM
 } ## end sub process_filter_layer
 
 # For safety, set an upper bound on number of iterations before stopping.
-# The average number of iterations is 2. No known cases exceed 5.
+# The average number of iterations is 2. No known cases exceed 3.
 use constant ITERATION_LIMIT => 6;
 
 sub process_iteration_layer {
index e92f0fbcc0d87e4bc4b2898089361c6ba964c0ae..b3c9e57a8ea3a77d0f93ae08fc67f0ed9e5dfee3 100644 (file)
@@ -33224,28 +33224,70 @@ sub copy_old_breakpoints {
 
     # We are formatting a list and have decided to make comma breaks
     # the same as in the input file.
+
+    # If the comma style is under certain controls, and if this is a
+    # comma breakpoint with the comma is at the beginning of the next
+    # line, then we must pass that index instead. This will allow sub
+    # set_forced_breakpoints to check and follow the user settings. This
+    # produces a uniform style and can prevent instability (b1422).
+    #
+    # The flag '$controlled_comma_style' will be set if the user
+    # entered any of -wbb=',' -wba=',' -kbb=',' -kba=','.  It is not
+    # set for the -boc flag, but we will need to treat -boc in the
+    # same way for lists with breaks both before and after commas to
+    # avoid excess iterations.
+
+    my @i_old_breaks;
     for my $i ( $i_first_comma .. $i_last_comma ) {
         if ( $old_breakpoint_to_go[$i] ) {
+            push @i_old_breaks, $i;
+        }
+    }
 
-            # If the comma style is under certain controls, and if this is a
-            # comma breakpoint with the comma is at the beginning of the next
-            # line, then we must pass that index instead. This will allow sub
-            # set_forced_breakpoints to check and follow the user settings. This
-            # produces a uniform style and can prevent instability (b1422).
-            #
-            # The flag '$controlled_comma_style' will be set if the user
-            # entered any of -wbb=',' -wba=',' -kbb=',' -kba=','.  It is not
-            # needed or set for the -boc flag.
-            my $ibreak = $i;
-            if ( $types_to_go[$ibreak] ne ',' && $controlled_comma_style ) {
-                my $index = $inext_to_go[$ibreak];
-                if ( $index > $ibreak && $types_to_go[$index] eq ',' ) {
-                    $ibreak = $index;
-                }
+    # just copy old breakpoints unless $controlled_comma_style or -boc
+    if (   !$controlled_comma_style
+        && !$rOpts_break_at_old_comma_breakpoints )
+    {
+        foreach my $ii (@i_old_breaks) {
+            $self->set_forced_breakpoint($ii);
+        }
+        return;
+    }
+
+    # Scan for commas before and after the old breakpoints...
+    my @i_breaks;
+    my $num_after;
+    my $num_before;
+    foreach my $i (@i_old_breaks) {
+        my $i_break = $i;
+        if ( $types_to_go[$i_break] ne ',' ) {
+            my $index = $inext_to_go[$i_break];
+            if ( $index > $i_break && $types_to_go[$index] eq ',' ) {
+                $i_break = $index;
+                $num_before++;
             }
-            $self->set_forced_breakpoint($ibreak);
+        }
+        else { $num_after++; }
+        push @i_breaks, $i_break;
+    }
+
+    # -boc by itself can use old breaks except when there are mixed
+    # leading and trailing commas. In that case excess iterations
+    # can occur (see b878)
+    if (  !$controlled_comma_style
+        && $rOpts_break_at_old_comma_breakpoints )
+    {
+
+        my $mixed = $num_before && $num_after;
+        if ( !$mixed ) {
+            @i_breaks = @i_old_breaks;
         }
     }
+
+    foreach my $ii (@i_breaks) {
+        $self->set_forced_breakpoint($ii);
+    }
+
     return;
 } ## end sub copy_old_breakpoints