]> git.donarmstrong.com Git - perltidy.git/commitdiff
reorgainze sub check_options, part 1
authorSteve Hancock <perltidy@users.sourceforge.net>
Fri, 3 Feb 2023 17:53:05 +0000 (09:53 -0800)
committerSteve Hancock <perltidy@users.sourceforge.net>
Fri, 3 Feb 2023 17:53:05 +0000 (09:53 -0800)
lib/Perl/Tidy/Formatter.pm

index e15b8da3dc66bf0f097559f08e0e534022ca7c83..d666c73a22fd132c9f9aacc3c1d6214cfcaf9d64 100644 (file)
@@ -1336,6 +1336,7 @@ sub check_options {
     make_keyword_group_list_pattern();
 
     prepare_cuddled_block_types();
+
     if ( $rOpts->{'dump-cuddled-block-list'} ) {
         dump_cuddled_block_list(*STDOUT);
         Exit(0);
@@ -1500,71 +1501,7 @@ EOM
         @space_after_keyword{@q} = (1) x scalar(@q);
     }
 
-    # implement user break preferences
-    my $break_after = sub {
-        my @toks = @_;
-        foreach my $tok (@toks) {
-            if ( $tok eq '?' ) { $tok = ':' }    # patch to coordinate ?/:
-            if ( $tok eq ',' ) { $controlled_comma_style = 1 }
-            my $lbs = $left_bond_strength{$tok};
-            my $rbs = $right_bond_strength{$tok};
-            if ( defined($lbs) && defined($rbs) && $lbs < $rbs ) {
-                ( $right_bond_strength{$tok}, $left_bond_strength{$tok} ) =
-                  ( $lbs, $rbs );
-            }
-        }
-        return;
-    };
-
-    my $break_before = sub {
-        my @toks = @_;
-        foreach my $tok (@toks) {
-            if ( $tok eq ',' ) { $controlled_comma_style = 1 }
-            my $lbs = $left_bond_strength{$tok};
-            my $rbs = $right_bond_strength{$tok};
-            if ( defined($lbs) && defined($rbs) && $rbs < $lbs ) {
-                ( $right_bond_strength{$tok}, $left_bond_strength{$tok} ) =
-                  ( $lbs, $rbs );
-            }
-        }
-        return;
-    };
-
-    $break_after->(@all_operators) if ( $rOpts->{'break-after-all-operators'} );
-    $break_before->(@all_operators)
-      if ( $rOpts->{'break-before-all-operators'} );
-
-    $break_after->( split_words( $rOpts->{'want-break-after'} ) );
-    $break_before->( split_words( $rOpts->{'want-break-before'} ) );
-
-    # make note if breaks are before certain key types
-    %want_break_before = ();
-    foreach my $tok ( @all_operators, ',' ) {
-        $want_break_before{$tok} =
-          $left_bond_strength{$tok} < $right_bond_strength{$tok};
-    }
-
-    # Coordinate ?/: breaks, which must be similar
-    # The small strength 0.01 which is added is 1% of the strength of one
-    # indentation level and seems to work okay.
-    if ( !$want_break_before{':'} ) {
-        $want_break_before{'?'}   = $want_break_before{':'};
-        $right_bond_strength{'?'} = $right_bond_strength{':'} + 0.01;
-        $left_bond_strength{'?'}  = NO_BREAK;
-    }
-
-    # Only make a hash entry for the next parameters if values are defined.
-    # That allows a quick check to be made later.
-    %break_before_container_types = ();
-    for ( $rOpts->{'break-before-hash-brace'} ) {
-        $break_before_container_types{'{'} = $_ if $_ && $_ > 0;
-    }
-    for ( $rOpts->{'break-before-square-bracket'} ) {
-        $break_before_container_types{'['} = $_ if $_ && $_ > 0;
-    }
-    for ( $rOpts->{'break-before-paren'} ) {
-        $break_before_container_types{'('} = $_ if $_ && $_ > 0;
-    }
+    initialize_token_break_preferences();
 
     #--------------------------------------------------------------
     # The combination -lp -iob -vmll -bbx=2 can be unstable (b1266)
@@ -1831,305 +1768,68 @@ EOM
     $controlled_comma_style ||= $keep_break_before_type{','};
     $controlled_comma_style ||= $keep_break_after_type{','};
 
-    #------------------------------------------------------------
-    # Make global vars for frequently used options for efficiency
-    #------------------------------------------------------------
+    initialize_global_option_vars();
+    initialize_line_length_vars();
+    initialize_trailing_comma_rules();    # after 'initialize_line_length_vars'
+    initialize_weld_nested_exclusion_rules();
+    initialize_weld_fat_comma_rules();
 
-    $rOpts_add_newlines        = $rOpts->{'add-newlines'};
-    $rOpts_add_trailing_commas = $rOpts->{'add-trailing-commas'};
-    $rOpts_add_whitespace      = $rOpts->{'add-whitespace'};
-    $rOpts_blank_lines_after_opening_block =
-      $rOpts->{'blank-lines-after-opening-block'};
-    $rOpts_block_brace_tightness = $rOpts->{'block-brace-tightness'};
-    $rOpts_block_brace_vertical_tightness =
-      $rOpts->{'block-brace-vertical-tightness'};
-    $rOpts_brace_follower_vertical_tightness =
-      $rOpts->{'brace-follower-vertical-tightness'};
-    $rOpts_break_after_labels = $rOpts->{'break-after-labels'};
-    $rOpts_break_at_old_attribute_breakpoints =
-      $rOpts->{'break-at-old-attribute-breakpoints'};
-    $rOpts_break_at_old_comma_breakpoints =
-      $rOpts->{'break-at-old-comma-breakpoints'};
-    $rOpts_break_at_old_keyword_breakpoints =
-      $rOpts->{'break-at-old-keyword-breakpoints'};
-    $rOpts_break_at_old_logical_breakpoints =
-      $rOpts->{'break-at-old-logical-breakpoints'};
-    $rOpts_break_at_old_semicolon_breakpoints =
-      $rOpts->{'break-at-old-semicolon-breakpoints'};
-    $rOpts_break_at_old_ternary_breakpoints =
-      $rOpts->{'break-at-old-ternary-breakpoints'};
-    $rOpts_break_open_compact_parens = $rOpts->{'break-open-compact-parens'};
-    $rOpts_closing_side_comments     = $rOpts->{'closing-side-comments'};
-    $rOpts_closing_side_comment_else_flag =
-      $rOpts->{'closing-side-comment-else-flag'};
-    $rOpts_closing_side_comment_maximum_text =
-      $rOpts->{'closing-side-comment-maximum-text'};
-    $rOpts_comma_arrow_breakpoints  = $rOpts->{'comma-arrow-breakpoints'};
-    $rOpts_continuation_indentation = $rOpts->{'continuation-indentation'};
-    $rOpts_cuddled_paren_brace      = $rOpts->{'cuddled-paren-brace'};
-    $rOpts_delete_closing_side_comments =
-      $rOpts->{'delete-closing-side-comments'};
-    $rOpts_delete_old_whitespace = $rOpts->{'delete-old-whitespace'};
-    $rOpts_extended_continuation_indentation =
-      $rOpts->{'extended-continuation-indentation'};
-    $rOpts_delete_side_comments   = $rOpts->{'delete-side-comments'};
-    $rOpts_delete_trailing_commas = $rOpts->{'delete-trailing-commas'};
-    $rOpts_delete_weld_interfering_commas =
-      $rOpts->{'delete-weld-interfering-commas'};
-    $rOpts_format_skipping   = $rOpts->{'format-skipping'};
-    $rOpts_freeze_whitespace = $rOpts->{'freeze-whitespace'};
-    $rOpts_function_paren_vertical_alignment =
-      $rOpts->{'function-paren-vertical-alignment'};
-    $rOpts_fuzzy_line_length      = $rOpts->{'fuzzy-line-length'};
-    $rOpts_ignore_old_breakpoints = $rOpts->{'ignore-old-breakpoints'};
-    $rOpts_ignore_side_comment_lengths =
-      $rOpts->{'ignore-side-comment-lengths'};
-    $rOpts_indent_closing_brace     = $rOpts->{'indent-closing-brace'};
-    $rOpts_indent_columns           = $rOpts->{'indent-columns'};
-    $rOpts_indent_only              = $rOpts->{'indent-only'};
-    $rOpts_keep_interior_semicolons = $rOpts->{'keep-interior-semicolons'};
-    $rOpts_line_up_parentheses      = $rOpts->{'line-up-parentheses'};
-    $rOpts_extended_line_up_parentheses =
-      $rOpts->{'extended-line-up-parentheses'};
-    $rOpts_logical_padding = $rOpts->{'logical-padding'};
-    $rOpts_maximum_consecutive_blank_lines =
-      $rOpts->{'maximum-consecutive-blank-lines'};
-    $rOpts_maximum_fields_per_table  = $rOpts->{'maximum-fields-per-table'};
-    $rOpts_maximum_line_length       = $rOpts->{'maximum-line-length'};
-    $rOpts_one_line_block_semicolons = $rOpts->{'one-line-block-semicolons'};
-    $rOpts_opening_brace_always_on_right =
-      $rOpts->{'opening-brace-always-on-right'};
-    $rOpts_outdent_keywords      = $rOpts->{'outdent-keywords'};
-    $rOpts_outdent_labels        = $rOpts->{'outdent-labels'};
-    $rOpts_outdent_long_comments = $rOpts->{'outdent-long-comments'};
-    $rOpts_outdent_long_quotes   = $rOpts->{'outdent-long-quotes'};
-    $rOpts_outdent_static_block_comments =
-      $rOpts->{'outdent-static-block-comments'};
-    $rOpts_recombine = $rOpts->{'recombine'};
-    $rOpts_short_concatenation_item_length =
-      $rOpts->{'short-concatenation-item-length'};
-    $rOpts_space_prototype_paren     = $rOpts->{'space-prototype-paren'};
-    $rOpts_stack_closing_block_brace = $rOpts->{'stack-closing-block-brace'};
-    $rOpts_static_block_comments     = $rOpts->{'static-block-comments'};
-    $rOpts_tee_block_comments        = $rOpts->{'tee-block-comments'};
-    $rOpts_tee_pod                   = $rOpts->{'tee-pod'};
-    $rOpts_tee_side_comments         = $rOpts->{'tee-side-comments'};
-    $rOpts_valign_code               = $rOpts->{'valign-code'};
-    $rOpts_valign_side_comments      = $rOpts->{'valign-side-comments'};
-    $rOpts_variable_maximum_line_length =
-      $rOpts->{'variable-maximum-line-length'};
+    %line_up_parentheses_control_hash    = ();
+    $line_up_parentheses_control_is_lxpl = 1;
+    my $lpxl = $rOpts->{'line-up-parentheses-exclusion-list'};
+    my $lpil = $rOpts->{'line-up-parentheses-inclusion-list'};
+    if ( $lpxl && $lpil ) {
+        Warn( <<EOM );
+You entered values for both -lpxl=s and -lpil=s; the -lpil list will be ignored
+EOM
+    }
+    if ($lpxl) {
+        $line_up_parentheses_control_is_lxpl = 1;
+        initialize_line_up_parentheses_control_hash(
+            $rOpts->{'line-up-parentheses-exclusion-list'}, 'lpxl' );
+    }
+    elsif ($lpil) {
+        $line_up_parentheses_control_is_lxpl = 0;
+        initialize_line_up_parentheses_control_hash(
+            $rOpts->{'line-up-parentheses-inclusion-list'}, 'lpil' );
+    }
 
-    # Note that both opening and closing tokens can access the opening
-    # and closing flags of their container types.
-    %opening_vertical_tightness = (
-        '(' => $rOpts->{'paren-vertical-tightness'},
-        '{' => $rOpts->{'brace-vertical-tightness'},
-        '[' => $rOpts->{'square-bracket-vertical-tightness'},
-        ')' => $rOpts->{'paren-vertical-tightness'},
-        '}' => $rOpts->{'brace-vertical-tightness'},
-        ']' => $rOpts->{'square-bracket-vertical-tightness'},
-    );
+    return;
+} ## end sub check_options
 
-    %closing_vertical_tightness = (
-        '(' => $rOpts->{'paren-vertical-tightness-closing'},
-        '{' => $rOpts->{'brace-vertical-tightness-closing'},
-        '[' => $rOpts->{'square-bracket-vertical-tightness-closing'},
-        ')' => $rOpts->{'paren-vertical-tightness-closing'},
-        '}' => $rOpts->{'brace-vertical-tightness-closing'},
-        ']' => $rOpts->{'square-bracket-vertical-tightness-closing'},
-    );
+use constant ALIGN_GREP_ALIASES => 0;
 
-    # assume flag for '>' same as ')' for closing qw quotes
-    %closing_token_indentation = (
-        ')' => $rOpts->{'closing-paren-indentation'},
-        '}' => $rOpts->{'closing-brace-indentation'},
-        ']' => $rOpts->{'closing-square-bracket-indentation'},
-        '>' => $rOpts->{'closing-paren-indentation'},
-    );
+sub initialize_grep_and_friends {
 
-    # flag indicating if any closing tokens are indented
-    $some_closing_token_indentation =
-         $rOpts->{'closing-paren-indentation'}
-      || $rOpts->{'closing-brace-indentation'}
-      || $rOpts->{'closing-square-bracket-indentation'}
-      || $rOpts->{'indent-closing-brace'};
+    # Initialize or re-initialize hashes with 'grep' and grep aliases. This
+    # must be done after each set of options because new grep aliases may be
+    # used.
 
-    %opening_token_right = (
-        '(' => $rOpts->{'opening-paren-right'},
-        '{' => $rOpts->{'opening-hash-brace-right'},
-        '[' => $rOpts->{'opening-square-bracket-right'},
-    );
+    # re-initialize the hashes ... this is critical!
+    %is_sort_map_grep = ();
 
-    %stack_opening_token = (
-        '(' => $rOpts->{'stack-opening-paren'},
-        '{' => $rOpts->{'stack-opening-hash-brace'},
-        '[' => $rOpts->{'stack-opening-square-bracket'},
-    );
+    my @q = qw(sort map grep);
+    @is_sort_map_grep{@q} = (1) x scalar(@q);
 
-    %stack_closing_token = (
-        ')' => $rOpts->{'stack-closing-paren'},
-        '}' => $rOpts->{'stack-closing-hash-brace'},
-        ']' => $rOpts->{'stack-closing-square-bracket'},
-    );
+    my $olbxl = $rOpts->{'one-line-block-exclusion-list'};
+    my %is_olb_exclusion_word;
+    if ( defined($olbxl) ) {
+        my @list = split_words($olbxl);
+        if (@list) {
+            @is_olb_exclusion_word{@list} = (1) x scalar(@list);
+        }
+    }
 
-    # Create a table of maximum line length vs level for later efficient use.
-    # We will make the tables very long to be sure it will not be exceeded.
-    # But we have to choose a fixed length.  A check will be made at the start
-    # of sub 'finish_formatting' to be sure it is not exceeded.  Note, some of
-    # my standard test problems have indentation levels of about 150, so this
-    # should be fairly large.  If the choice of a maximum level ever becomes
-    # an issue then these table values could be returned in a sub with a simple
-    # memoization scheme.
-
-    # Also create a table of the maximum spaces available for text due to the
-    # level only.  If a line has continuation indentation, then that space must
-    # be subtracted from the table value.  This table is used for preliminary
-    # estimates in welding, extended_ci, BBX, and marking short blocks.
-    use constant LEVEL_TABLE_MAX => 1000;
-
-    # The basic scheme:
-    foreach my $level ( 0 .. LEVEL_TABLE_MAX ) {
-        my $indent = $level * $rOpts_indent_columns;
-        $maximum_line_length_at_level[$level] = $rOpts_maximum_line_length;
-        $maximum_text_length_at_level[$level] =
-          $rOpts_maximum_line_length - $indent;
-    }
-
-    # Correct the maximum_text_length table if the -wc=n flag is used
-    $rOpts_whitespace_cycle = $rOpts->{'whitespace-cycle'};
-    if ($rOpts_whitespace_cycle) {
-        if ( $rOpts_whitespace_cycle > 0 ) {
-            foreach my $level ( 0 .. LEVEL_TABLE_MAX ) {
-                my $level_mod = $level % $rOpts_whitespace_cycle;
-                my $indent    = $level_mod * $rOpts_indent_columns;
-                $maximum_text_length_at_level[$level] =
-                  $rOpts_maximum_line_length - $indent;
-            }
-        }
-        else {
-            $rOpts_whitespace_cycle = $rOpts->{'whitespace-cycle'} = 0;
-        }
-    }
-
-    # Correct the tables if the -vmll flag is used.  These values override the
-    # previous values.
-    if ($rOpts_variable_maximum_line_length) {
-        foreach my $level ( 0 .. LEVEL_TABLE_MAX ) {
-            $maximum_text_length_at_level[$level] = $rOpts_maximum_line_length;
-            $maximum_line_length_at_level[$level] =
-              $rOpts_maximum_line_length + $level * $rOpts_indent_columns;
-        }
-    }
-
-    # Define two measures of indentation level, alpha and beta, at which some
-    # formatting features come under stress and need to start shutting down.
-    # Some combination of the two will be used to shut down different
-    # formatting features.
-    # Put a reasonable upper limit on stress level (say 100) in case the
-    # whitespace-cycle variable is used.
-    my $stress_level_limit = min( 100, LEVEL_TABLE_MAX );
-
-    # Find stress_level_alpha, targeted at very short maximum line lengths.
-    $stress_level_alpha = $stress_level_limit + 1;
-    foreach my $level_test ( 0 .. $stress_level_limit ) {
-        my $max_len = $maximum_text_length_at_level[ $level_test + 1 ];
-        my $excess_inside_space =
-          $max_len -
-          $rOpts_continuation_indentation -
-          $rOpts_indent_columns - 8;
-        if ( $excess_inside_space <= 0 ) {
-            $stress_level_alpha = $level_test;
-            last;
-        }
-    }
-
-    # Find stress level beta, a stress level targeted at formatting
-    # at deep levels near the maximum line length.  We start increasing
-    # from zero and stop at the first level which shows no more space.
-
-    # 'const' is a fixed number of spaces for a typical variable.
-    # Cases b1197-b1204 work ok with const=12 but not with const=8
-    my $const = 16;
-    my $denom = max( 1, $rOpts_indent_columns );
-    $stress_level_beta = 0;
-    foreach my $level ( 0 .. $stress_level_limit ) {
-        my $remaining_cycles = max(
-            0,
-            (
-                $maximum_text_length_at_level[$level] -
-                  $rOpts_continuation_indentation - $const
-            ) / $denom
-        );
-        last if ( $remaining_cycles <= 3 );    # 2 does not work
-        $stress_level_beta = $level;
-    }
-
-    # This is a combined level which works well for turning off formatting
-    # features in most cases:
-    $high_stress_level = min( $stress_level_alpha, $stress_level_beta + 2 );
-
-    %trailing_comma_rules = ();
-    initialize_trailing_comma_rules();
-
-    initialize_weld_nested_exclusion_rules();
-    initialize_weld_fat_comma_rules();
-
-    %line_up_parentheses_control_hash    = ();
-    $line_up_parentheses_control_is_lxpl = 1;
-    my $lpxl = $rOpts->{'line-up-parentheses-exclusion-list'};
-    my $lpil = $rOpts->{'line-up-parentheses-inclusion-list'};
-    if ( $lpxl && $lpil ) {
-        Warn( <<EOM );
-You entered values for both -lpxl=s and -lpil=s; the -lpil list will be ignored
-EOM
-    }
-    if ($lpxl) {
-        $line_up_parentheses_control_is_lxpl = 1;
-        initialize_line_up_parentheses_control_hash(
-            $rOpts->{'line-up-parentheses-exclusion-list'}, 'lpxl' );
-    }
-    elsif ($lpil) {
-        $line_up_parentheses_control_is_lxpl = 0;
-        initialize_line_up_parentheses_control_hash(
-            $rOpts->{'line-up-parentheses-inclusion-list'}, 'lpil' );
-    }
-
-    return;
-} ## end sub check_options
-
-use constant ALIGN_GREP_ALIASES => 0;
-
-sub initialize_grep_and_friends {
-
-    # Initialize or re-initialize hashes with 'grep' and grep aliases. This
-    # must be done after each set of options because new grep aliases may be
-    # used.
-
-    # re-initialize the hashes ... this is critical!
-    %is_sort_map_grep = ();
-
-    my @q = qw(sort map grep);
-    @is_sort_map_grep{@q} = (1) x scalar(@q);
-
-    my $olbxl = $rOpts->{'one-line-block-exclusion-list'};
-    my %is_olb_exclusion_word;
-    if ( defined($olbxl) ) {
-        my @list = split_words($olbxl);
-        if (@list) {
-            @is_olb_exclusion_word{@list} = (1) x scalar(@list);
-        }
-    }
-
-    # Make the list of block types which may be re-formed into one line.
-    # They will be modified with the grep-alias-list below and
-    # by sub 'prepare_cuddled_block_types'.
-    # Note that it is essential to always re-initialize the hash here:
-    %want_one_line_block = ();
-    if ( !$is_olb_exclusion_word{'*'} ) {
-        foreach (qw(sort map grep eval)) {
-            if ( !$is_olb_exclusion_word{$_} ) { $want_one_line_block{$_} = 1 }
-        }
-    }
+    # Make the list of block types which may be re-formed into one line.
+    # They will be modified with the grep-alias-list below and
+    # by sub 'prepare_cuddled_block_types'.
+    # Note that it is essential to always re-initialize the hash here:
+    %want_one_line_block = ();
+    if ( !$is_olb_exclusion_word{'*'} ) {
+        foreach (qw(sort map grep eval)) {
+            if ( !$is_olb_exclusion_word{$_} ) { $want_one_line_block{$_} = 1 }
+        }
+    }
 
     # Note that any 'grep-alias-list' string has been preprocessed to be a
     # trimmed, space-separated list.
@@ -2443,6 +2143,76 @@ EOM
     return;
 } ## end sub initialize_line_up_parentheses_control_hash
 
+sub initialize_token_break_preferences {
+
+    # implement user break preferences
+    my $break_after = sub {
+        my @toks = @_;
+        foreach my $tok (@toks) {
+            if ( $tok eq '?' ) { $tok = ':' }    # patch to coordinate ?/:
+            if ( $tok eq ',' ) { $controlled_comma_style = 1 }
+            my $lbs = $left_bond_strength{$tok};
+            my $rbs = $right_bond_strength{$tok};
+            if ( defined($lbs) && defined($rbs) && $lbs < $rbs ) {
+                ( $right_bond_strength{$tok}, $left_bond_strength{$tok} ) =
+                  ( $lbs, $rbs );
+            }
+        }
+        return;
+    };
+
+    my $break_before = sub {
+        my @toks = @_;
+        foreach my $tok (@toks) {
+            if ( $tok eq ',' ) { $controlled_comma_style = 1 }
+            my $lbs = $left_bond_strength{$tok};
+            my $rbs = $right_bond_strength{$tok};
+            if ( defined($lbs) && defined($rbs) && $rbs < $lbs ) {
+                ( $right_bond_strength{$tok}, $left_bond_strength{$tok} ) =
+                  ( $lbs, $rbs );
+            }
+        }
+        return;
+    };
+
+    $break_after->(@all_operators) if ( $rOpts->{'break-after-all-operators'} );
+    $break_before->(@all_operators)
+      if ( $rOpts->{'break-before-all-operators'} );
+
+    $break_after->( split_words( $rOpts->{'want-break-after'} ) );
+    $break_before->( split_words( $rOpts->{'want-break-before'} ) );
+
+    # make note if breaks are before certain key types
+    %want_break_before = ();
+    foreach my $tok ( @all_operators, ',' ) {
+        $want_break_before{$tok} =
+          $left_bond_strength{$tok} < $right_bond_strength{$tok};
+    }
+
+    # Coordinate ?/: breaks, which must be similar
+    # The small strength 0.01 which is added is 1% of the strength of one
+    # indentation level and seems to work okay.
+    if ( !$want_break_before{':'} ) {
+        $want_break_before{'?'}   = $want_break_before{':'};
+        $right_bond_strength{'?'} = $right_bond_strength{':'} + 0.01;
+        $left_bond_strength{'?'}  = NO_BREAK;
+    }
+
+    # Only make a hash entry for the next parameters if values are defined.
+    # That allows a quick check to be made later.
+    %break_before_container_types = ();
+    for ( $rOpts->{'break-before-hash-brace'} ) {
+        $break_before_container_types{'{'} = $_ if $_ && $_ > 0;
+    }
+    for ( $rOpts->{'break-before-square-bracket'} ) {
+        $break_before_container_types{'['} = $_ if $_ && $_ > 0;
+    }
+    for ( $rOpts->{'break-before-paren'} ) {
+        $break_before_container_types{'('} = $_ if $_ && $_ > 0;
+    }
+    return;
+} ## end sub initialize_token_break_preferences
+
 use constant DEBUG_KB => 0;
 
 sub initialize_keep_old_breakpoints {
@@ -2534,6 +2304,252 @@ EOM
 
 } ## end sub initialize_keep_old_breakpoints
 
+sub initialize_global_option_vars {
+
+    #------------------------------------------------------------
+    # Make global vars for frequently used options for efficiency
+    #------------------------------------------------------------
+
+    $rOpts_add_newlines        = $rOpts->{'add-newlines'};
+    $rOpts_add_trailing_commas = $rOpts->{'add-trailing-commas'};
+    $rOpts_add_whitespace      = $rOpts->{'add-whitespace'};
+    $rOpts_blank_lines_after_opening_block =
+      $rOpts->{'blank-lines-after-opening-block'};
+    $rOpts_block_brace_tightness = $rOpts->{'block-brace-tightness'};
+    $rOpts_block_brace_vertical_tightness =
+      $rOpts->{'block-brace-vertical-tightness'};
+    $rOpts_brace_follower_vertical_tightness =
+      $rOpts->{'brace-follower-vertical-tightness'};
+    $rOpts_break_after_labels = $rOpts->{'break-after-labels'};
+    $rOpts_break_at_old_attribute_breakpoints =
+      $rOpts->{'break-at-old-attribute-breakpoints'};
+    $rOpts_break_at_old_comma_breakpoints =
+      $rOpts->{'break-at-old-comma-breakpoints'};
+    $rOpts_break_at_old_keyword_breakpoints =
+      $rOpts->{'break-at-old-keyword-breakpoints'};
+    $rOpts_break_at_old_logical_breakpoints =
+      $rOpts->{'break-at-old-logical-breakpoints'};
+    $rOpts_break_at_old_semicolon_breakpoints =
+      $rOpts->{'break-at-old-semicolon-breakpoints'};
+    $rOpts_break_at_old_ternary_breakpoints =
+      $rOpts->{'break-at-old-ternary-breakpoints'};
+    $rOpts_break_open_compact_parens = $rOpts->{'break-open-compact-parens'};
+    $rOpts_closing_side_comments     = $rOpts->{'closing-side-comments'};
+    $rOpts_closing_side_comment_else_flag =
+      $rOpts->{'closing-side-comment-else-flag'};
+    $rOpts_closing_side_comment_maximum_text =
+      $rOpts->{'closing-side-comment-maximum-text'};
+    $rOpts_comma_arrow_breakpoints  = $rOpts->{'comma-arrow-breakpoints'};
+    $rOpts_continuation_indentation = $rOpts->{'continuation-indentation'};
+    $rOpts_cuddled_paren_brace      = $rOpts->{'cuddled-paren-brace'};
+    $rOpts_delete_closing_side_comments =
+      $rOpts->{'delete-closing-side-comments'};
+    $rOpts_delete_old_whitespace = $rOpts->{'delete-old-whitespace'};
+    $rOpts_extended_continuation_indentation =
+      $rOpts->{'extended-continuation-indentation'};
+    $rOpts_delete_side_comments   = $rOpts->{'delete-side-comments'};
+    $rOpts_delete_trailing_commas = $rOpts->{'delete-trailing-commas'};
+    $rOpts_delete_weld_interfering_commas =
+      $rOpts->{'delete-weld-interfering-commas'};
+    $rOpts_format_skipping   = $rOpts->{'format-skipping'};
+    $rOpts_freeze_whitespace = $rOpts->{'freeze-whitespace'};
+    $rOpts_function_paren_vertical_alignment =
+      $rOpts->{'function-paren-vertical-alignment'};
+    $rOpts_fuzzy_line_length      = $rOpts->{'fuzzy-line-length'};
+    $rOpts_ignore_old_breakpoints = $rOpts->{'ignore-old-breakpoints'};
+    $rOpts_ignore_side_comment_lengths =
+      $rOpts->{'ignore-side-comment-lengths'};
+    $rOpts_indent_closing_brace     = $rOpts->{'indent-closing-brace'};
+    $rOpts_indent_columns           = $rOpts->{'indent-columns'};
+    $rOpts_indent_only              = $rOpts->{'indent-only'};
+    $rOpts_keep_interior_semicolons = $rOpts->{'keep-interior-semicolons'};
+    $rOpts_line_up_parentheses      = $rOpts->{'line-up-parentheses'};
+    $rOpts_extended_line_up_parentheses =
+      $rOpts->{'extended-line-up-parentheses'};
+    $rOpts_logical_padding = $rOpts->{'logical-padding'};
+    $rOpts_maximum_consecutive_blank_lines =
+      $rOpts->{'maximum-consecutive-blank-lines'};
+    $rOpts_maximum_fields_per_table  = $rOpts->{'maximum-fields-per-table'};
+    $rOpts_maximum_line_length       = $rOpts->{'maximum-line-length'};
+    $rOpts_one_line_block_semicolons = $rOpts->{'one-line-block-semicolons'};
+    $rOpts_opening_brace_always_on_right =
+      $rOpts->{'opening-brace-always-on-right'};
+    $rOpts_outdent_keywords      = $rOpts->{'outdent-keywords'};
+    $rOpts_outdent_labels        = $rOpts->{'outdent-labels'};
+    $rOpts_outdent_long_comments = $rOpts->{'outdent-long-comments'};
+    $rOpts_outdent_long_quotes   = $rOpts->{'outdent-long-quotes'};
+    $rOpts_outdent_static_block_comments =
+      $rOpts->{'outdent-static-block-comments'};
+    $rOpts_recombine = $rOpts->{'recombine'};
+    $rOpts_short_concatenation_item_length =
+      $rOpts->{'short-concatenation-item-length'};
+    $rOpts_space_prototype_paren     = $rOpts->{'space-prototype-paren'};
+    $rOpts_stack_closing_block_brace = $rOpts->{'stack-closing-block-brace'};
+    $rOpts_static_block_comments     = $rOpts->{'static-block-comments'};
+    $rOpts_tee_block_comments        = $rOpts->{'tee-block-comments'};
+    $rOpts_tee_pod                   = $rOpts->{'tee-pod'};
+    $rOpts_tee_side_comments         = $rOpts->{'tee-side-comments'};
+    $rOpts_valign_code               = $rOpts->{'valign-code'};
+    $rOpts_valign_side_comments      = $rOpts->{'valign-side-comments'};
+    $rOpts_variable_maximum_line_length =
+      $rOpts->{'variable-maximum-line-length'};
+
+    # Note that both opening and closing tokens can access the opening
+    # and closing flags of their container types.
+    %opening_vertical_tightness = (
+        '(' => $rOpts->{'paren-vertical-tightness'},
+        '{' => $rOpts->{'brace-vertical-tightness'},
+        '[' => $rOpts->{'square-bracket-vertical-tightness'},
+        ')' => $rOpts->{'paren-vertical-tightness'},
+        '}' => $rOpts->{'brace-vertical-tightness'},
+        ']' => $rOpts->{'square-bracket-vertical-tightness'},
+    );
+
+    %closing_vertical_tightness = (
+        '(' => $rOpts->{'paren-vertical-tightness-closing'},
+        '{' => $rOpts->{'brace-vertical-tightness-closing'},
+        '[' => $rOpts->{'square-bracket-vertical-tightness-closing'},
+        ')' => $rOpts->{'paren-vertical-tightness-closing'},
+        '}' => $rOpts->{'brace-vertical-tightness-closing'},
+        ']' => $rOpts->{'square-bracket-vertical-tightness-closing'},
+    );
+
+    # assume flag for '>' same as ')' for closing qw quotes
+    %closing_token_indentation = (
+        ')' => $rOpts->{'closing-paren-indentation'},
+        '}' => $rOpts->{'closing-brace-indentation'},
+        ']' => $rOpts->{'closing-square-bracket-indentation'},
+        '>' => $rOpts->{'closing-paren-indentation'},
+    );
+
+    # flag indicating if any closing tokens are indented
+    $some_closing_token_indentation =
+         $rOpts->{'closing-paren-indentation'}
+      || $rOpts->{'closing-brace-indentation'}
+      || $rOpts->{'closing-square-bracket-indentation'}
+      || $rOpts->{'indent-closing-brace'};
+
+    %opening_token_right = (
+        '(' => $rOpts->{'opening-paren-right'},
+        '{' => $rOpts->{'opening-hash-brace-right'},
+        '[' => $rOpts->{'opening-square-bracket-right'},
+    );
+
+    %stack_opening_token = (
+        '(' => $rOpts->{'stack-opening-paren'},
+        '{' => $rOpts->{'stack-opening-hash-brace'},
+        '[' => $rOpts->{'stack-opening-square-bracket'},
+    );
+
+    %stack_closing_token = (
+        ')' => $rOpts->{'stack-closing-paren'},
+        '}' => $rOpts->{'stack-closing-hash-brace'},
+        ']' => $rOpts->{'stack-closing-square-bracket'},
+    );
+    return;
+} ## end sub initialize_global_option_vars
+
+sub initialize_line_length_vars {
+
+    # Create a table of maximum line length vs level for later efficient use.
+    # We will make the tables very long to be sure it will not be exceeded.
+    # But we have to choose a fixed length.  A check will be made at the start
+    # of sub 'finish_formatting' to be sure it is not exceeded.  Note, some of
+    # my standard test problems have indentation levels of about 150, so this
+    # should be fairly large.  If the choice of a maximum level ever becomes
+    # an issue then these table values could be returned in a sub with a simple
+    # memoization scheme.
+
+    # Also create a table of the maximum spaces available for text due to the
+    # level only.  If a line has continuation indentation, then that space must
+    # be subtracted from the table value.  This table is used for preliminary
+    # estimates in welding, extended_ci, BBX, and marking short blocks.
+    use constant LEVEL_TABLE_MAX => 1000;
+
+    # The basic scheme:
+    foreach my $level ( 0 .. LEVEL_TABLE_MAX ) {
+        my $indent = $level * $rOpts_indent_columns;
+        $maximum_line_length_at_level[$level] = $rOpts_maximum_line_length;
+        $maximum_text_length_at_level[$level] =
+          $rOpts_maximum_line_length - $indent;
+    }
+
+    # Correct the maximum_text_length table if the -wc=n flag is used
+    $rOpts_whitespace_cycle = $rOpts->{'whitespace-cycle'};
+    if ($rOpts_whitespace_cycle) {
+        if ( $rOpts_whitespace_cycle > 0 ) {
+            foreach my $level ( 0 .. LEVEL_TABLE_MAX ) {
+                my $level_mod = $level % $rOpts_whitespace_cycle;
+                my $indent    = $level_mod * $rOpts_indent_columns;
+                $maximum_text_length_at_level[$level] =
+                  $rOpts_maximum_line_length - $indent;
+            }
+        }
+        else {
+            $rOpts_whitespace_cycle = $rOpts->{'whitespace-cycle'} = 0;
+        }
+    }
+
+    # Correct the tables if the -vmll flag is used.  These values override the
+    # previous values.
+    if ($rOpts_variable_maximum_line_length) {
+        foreach my $level ( 0 .. LEVEL_TABLE_MAX ) {
+            $maximum_text_length_at_level[$level] = $rOpts_maximum_line_length;
+            $maximum_line_length_at_level[$level] =
+              $rOpts_maximum_line_length + $level * $rOpts_indent_columns;
+        }
+    }
+
+    # Define two measures of indentation level, alpha and beta, at which some
+    # formatting features come under stress and need to start shutting down.
+    # Some combination of the two will be used to shut down different
+    # formatting features.
+    # Put a reasonable upper limit on stress level (say 100) in case the
+    # whitespace-cycle variable is used.
+    my $stress_level_limit = min( 100, LEVEL_TABLE_MAX );
+
+    # Find stress_level_alpha, targeted at very short maximum line lengths.
+    $stress_level_alpha = $stress_level_limit + 1;
+    foreach my $level_test ( 0 .. $stress_level_limit ) {
+        my $max_len = $maximum_text_length_at_level[ $level_test + 1 ];
+        my $excess_inside_space =
+          $max_len -
+          $rOpts_continuation_indentation -
+          $rOpts_indent_columns - 8;
+        if ( $excess_inside_space <= 0 ) {
+            $stress_level_alpha = $level_test;
+            last;
+        }
+    }
+
+    # Find stress level beta, a stress level targeted at formatting
+    # at deep levels near the maximum line length.  We start increasing
+    # from zero and stop at the first level which shows no more space.
+
+    # 'const' is a fixed number of spaces for a typical variable.
+    # Cases b1197-b1204 work ok with const=12 but not with const=8
+    my $const = 16;
+    my $denom = max( 1, $rOpts_indent_columns );
+    $stress_level_beta = 0;
+    foreach my $level ( 0 .. $stress_level_limit ) {
+        my $remaining_cycles = max(
+            0,
+            (
+                $maximum_text_length_at_level[$level] -
+                  $rOpts_continuation_indentation - $const
+            ) / $denom
+        );
+        last if ( $remaining_cycles <= 3 );    # 2 does not work
+        $stress_level_beta = $level;
+    }
+
+    # This is a combined level which works well for turning off formatting
+    # features in most cases:
+    $high_stress_level = min( $stress_level_alpha, $stress_level_beta + 2 );
+
+    return;
+} ## end sub initialize_line_length_vars
+
 sub initialize_trailing_comma_rules {
 
     # Setup control hash for trailing commas
@@ -2556,8 +2572,12 @@ sub initialize_trailing_comma_rules {
     #        if -atc set will add these
     #        if -dtc set will delete other trailing commas
 
+    #-------------------------------------------------------------------
     # This routine must be called after the alpha and beta stress levels
-    # have been defined.
+    # have been defined in sub 'initialize_line_length_vars'.
+    #-------------------------------------------------------------------
+
+    %trailing_comma_rules = ();
 
     my $rvalid_flags = [qw(0 1 * m b h i)];