my %essential_whitespace_filter_r1;
my %essential_whitespace_filter_l2;
my %essential_whitespace_filter_r2;
+ my %is_type_with_space_before_bareword;
BEGIN {
@q = qw( h Z );
@essential_whitespace_filter_l2{@q} = (1) x scalar(@q);
+ # Keep a space between certain types and any bareword:
+ # Q: keep a space between a quote and a bareword to prevent the
+ # bareword from becoming a quote modifier.
+ # &: do not remove space between an '&' and a bare word because
+ # it may turn into a function evaluation, like here
+ # between '&' and 'O_ACCMODE', producing a syntax error [File.pm]
+ # $opts{rdonly} = (($opts{mode} & O_ACCMODE) == O_RDONLY);
+ # +-: binary plus and minus would get converted into unary
+ # plus and minus on next pass through the tokenizer. This can
+ # lead to blinkers: cases b660 b670 b780 b781 b787 b788 b790
+ @q = qw( Q & + - );
+ @is_type_with_space_before_bareword{@q} = (1) x scalar(@q);
+
}
sub is_essential_whitespace {
# $a = - III;
|| $tokenl_is_dash && $typer =~ /^[wC]$/
- # keep a space between a quote and a bareword to prevent the
- # bareword from becoming a quote modifier.
- || $typel eq 'Q'
+ # keep space between types Q & + - and a bareword
+ || $is_type_with_space_before_bareword{$typel}
# keep a space between a token ending in '$' and any word;
# this caused trouble: "die @$ if $@"
|| $typel eq 'i' && $tokenl =~ /\$$/
- # do not remove space between an '&' and a bare word because
- # it may turn into a function evaluation, like here
- # between '&' and 'O_ACCMODE', producing a syntax error [File.pm]
- # $opts{rdonly} = (($opts{mode} & O_ACCMODE) == O_RDONLY);
- || $typel eq '&'
-
# don't combine $$ or $# with any alphanumeric
# (testfile mangle.t with --mangle)
|| $tokenl =~ /^\$[\$\#]$/
$left_bond_strength{p} = $left_bond_strength{'+'};
$left_bond_strength{m} = $left_bond_strength{'-'};
+ # And make right strength of unary plus and minus very high.
+ # Fixes cases b670 b790
+ $right_bond_strength{p} = NO_BREAK;
+ $right_bond_strength{m} = NO_BREAK;
+
# breaking BEFORE these is just ok:
@q = qw# >> << #;
@right_bond_strength{@q} = (STRONG) x scalar(@q);
# rules generate any needed blank lines.
my $kgb_keep = $rOpts_keep_old_blank_lines;
- # Then delete lines requested by the keyword-group logic if
- # allowed
+ # Then delete lines requested by the keyword-group logic if
+ # allowed
if ( $kgb_keep == 1
&& defined( $rwant_blank_line_after->{$i} )
&& $rwant_blank_line_after->{$i} == 2 )
# as '}') which forms a one-line block, this break might
# get undone.
- # And do not do this at an equals if the user wants breaks
- # before an equals (blinker cases b434 b903)
- unless ($type eq '=' && $want_break_before{$type}) {
+ # And do not do this at an equals if the user wants
+ # breaks before an equals (blinker cases b434 b903)
+ unless ( $type eq '=' && $want_break_before{$type} ) {
$want_previous_breakpoint = $i;
}
} ## end if ( $next_nonblank_type...)
|| $rOpts_comma_arrow_breakpoints == 2
)
- # and we made some breakpoints between the opening and closing
+ # and we made breakpoints between the opening and closing
&& ( $breakpoint_undo_stack[$current_depth] <
get_forced_breakpoint_undo_count() )
=over 4
+=item B<Keep space between binary plus or minus and a bareword>
+
+This update makes a space between a binary + or - and a bareword
+an essential whitespace. Otherwise, they may be converted into unary
++ or - on the next pass, which can lead to blinking states.
+Fixes cases b660 b670 b780 b781 b787 b788 b790.
+
+13 Feb 2021.
+
+=item B<Prevent breaks after unary plus and minus>
+
+Some alternating states were produced when extremely maximum line lengths
+forced a break after a unary plus or minus. Fixes cases b670 b790.
+
+13 Feb 2021.
+
=item B<Add line length test for the -vtc=2 option>
Random testing produced a number of cases of blinking states which were caused
b654 b655 b656 b657 b761 b762 b763 b764 b765 b766 b767 b768 b769 b862 b904 b905
b906 b907 b913 b914 b915 b916 b917 b918 b919
-13 Feb 2021.
+13 Feb 2021, f79a4f1.
=item B<Define left side bond strengths for unary plus and minus>