]> git.donarmstrong.com Git - perltidy.git/commitdiff
added several -gal defaults and -gaxl=s
authorSteve Hancock <perltidy@users.sourceforge.net>
Wed, 22 Dec 2021 23:38:41 +0000 (15:38 -0800)
committerSteve Hancock <perltidy@users.sourceforge.net>
Wed, 22 Dec 2021 23:38:41 +0000 (15:38 -0800)
14 files changed:
CHANGES.md
bin/perltidy
docs/BugLog.html
docs/ChangeLog.html
docs/Tidy.html
docs/perltidy.html
lib/Perl/Tidy.pm
lib/Perl/Tidy/Formatter.pm
lib/Perl/Tidy/Tokenizer.pm
t/snippets/expect/git77.def
t/snippets/expect/git77.git77
t/snippets/git77.in
t/snippets/packing_list.txt
t/snippets25.t

index f8d392fd31f29f87c7a4afaca0f7c85706415b50..820e32794e5c8e25a6856d4f4d7ebb7f502ea4f5 100644 (file)
@@ -5,6 +5,11 @@
     - A new flag -gal=s, --grep-alias-list=s, has been added as suggested in
       git #77.  This allows code blocks passed to list operator functions to
       be formatted in the same way as a code block passed to grep, map, or sort.
+      By default, the following list operators in List::Util are included:
+
+        all any first none notall reduce reductions
+
+      They can be changed with the flag -gaxl=s, -grep-alias-exclusion-list=s
 
     - A new flag -xlp has been added which can be set to avoid most of the
       limitations of the -lp flag regarding side comments, blank lines, and
index 0370ffe8887707b4922c3249ce2abb72e970d3c1..c96d7a4ac7098ec22b1509dc2f62a5b91f0dad1b 100755 (executable)
@@ -392,13 +392,28 @@ You do not need to include any sub aliases in these lists. Just include keyword
 
 =item B<-gal=s>,   B<--grep-alias-list=s>
 
-This flag causes a code block following a specified word to be formatted as if it followed the keyword 'grep'.  The string B<s> contains one or more such alias words, separated by spaces or commas.
+This flag causes a code block following a specified word to be formatted as if it followed the keyword 'grep' (or 'map' or 'sort').  The string B<s> contains one or more such alias words, separated by spaces or commas.
 
-This allows code block arguments to external list operator functions to be formatted in the same way as code blocks which follow the perl builtin keywords 'grep', 'map', and 'sort'.  Perltidy tries to keep code blocks for these functions intact, and does not automatically break after the closing brace since a list may follow.
+This allows code block arguments to external list operator functions to be formatted in the same way as code blocks which follow the perl builtin keywords 'grep', 'map', and 'sort'.  By 'list operator' is meant a function which is invoked in the form
 
-For example, the functions 'any' and 'all' in module List::Util can be given formatting like 'grep' with
+      word {BLOCK} @list
 
-        perltidy -gal='any all'
+Perltidy tries to keep code blocks for these functions intact, since they are usually short, and does not automatically break after the closing brace since a list may follow. It also does some special handling of continuation indentation.
+
+For example, the code block arguments to functions 'My_grep' and 'My_map' can be given formatting like 'grep' with
+
+        perltidy -gal='My_grep My_map'
+
+By default, the following list operators in List::Util are automatically included, and any operators listed in B<--grep-alias-list> are added to this list:
+
+      all any first none notall reduce reductions
+
+The next parameter can be used to remove words from this default list.
+
+=item B<-gaxl=s>,   B<--grep-alias-exclusion-list=s>
+
+The B<-gaxl=s> flag provides a method for removing any of the default list operators given above
+by listing them in the string B<s>.  To remove all of the default operators use B<-gaxl='*'>.
 
 =back
 
index 6d51aad9aa2af3067b0bf6082017a9e38cdb173a..75fa28c5dc5cee2e6192044dd25ccbb0142c1611 100644 (file)
@@ -12,6 +12,7 @@
 
 
 <ul id="index">
+  <li><a href="#Issues-fixed-after-release-20211029">Issues fixed after release 20211029</a></li>
   <li><a href="#Issues-fixed-after-release-20210625">Issues fixed after release 20210625</a></li>
   <li><a href="#Issues-fixed-after-release-20210402">Issues fixed after release 20210402</a></li>
   <li><a href="#Issues-fixed-after-release-20210111">Issues fixed after release 20210111</a></li>
   <li><a href="#Open-Issues">Open Issues</a></li>
 </ul>
 
+<h1 id="Issues-fixed-after-release-20211029">Issues fixed after release 20211029</h1>
+
+<dl>
+
+<dt id="Fix-tokenization-issue-c109"><b>Fix tokenization issue c109</b></dt>
+<dd>
+
+<p>Automated random testing produced an error tokenizing the following code fragment:</p>
+
+<pre><code>    s s(..)(.)sss
+    ;</code></pre>
+
+<p>This is equivalent to &#39;s/(..)(.)//s&#39; with &#39;s&#39; as the delimiter instead of &#39;/&#39;. It was tokenized correctly except when the final &#39;s&#39; was followed by a newline, as in the example. When the delimiter is a letter rather than a punctuation character, perltidy exercises some seldom-used code which had an off-by-one loop limit. This has been fixed.</p>
+
+<p>12 Nov 2021.</p>
+
+</dd>
+<dt id="Fix-tokenization-of-issue-c106"><b>Fix tokenization of $$^, issue c106</b></dt>
+<dd>
+
+<p>Automated random testing produced an error tokenizing the following fragment:</p>
+
+<pre><code>   my$seed=$$^$^T;</code></pre>
+
+<p>The first ^ should have been tokenized as the bitwise xor operator but was not. This is fixed with this update.</p>
+
+<p>8 Nov 2021</p>
+
+</dd>
+<dt id="Fix-coding-error-issue-c104"><b>Fix coding error, issue c104</b></dt>
+<dd>
+
+<p>Automated random testing produced an error with something like the following input line taken from an obfuscated perl script:</p>
+
+<pre><code>    open(IN, $ 0);</code></pre>
+
+<p>The &#39;0&#39; was missing in the output:</p>
+
+<pre><code>    open( IN, $ );</code></pre>
+
+<p>The tokenization was correct, but a line of code in the formatter which removes the space between the &#39;$&#39; and the &#39;0&#39; should have used a &#39;defined&#39; when doing a check:</p>
+
+<pre><code>    $token .= $word if ($word);             # OLD: error</code></pre>
+
+<p>This if test fails on &#39;0&#39;. The corrected line is</p>
+
+<pre><code>    $token .= $word if ( defined($word) );  # NEW: fixes c104</code></pre>
+
+<p>This fixes the problem and gives the correct formatted result</p>
+
+<pre><code>    open( IN, $0 );</code></pre>
+
+<p>8 Nov 2021.</p>
+
+</dd>
+<dt id="Fix-undefined-variable-reference-c102"><b>Fix undefined variable reference, c102</b></dt>
+<dd>
+
+<p>Random testing produced an undefined variable reference for the following input</p>
+
+<pre><code>    make_sorter ( sort_sha =&gt; sub {sha512 ( $_} );
+    make_sorter ( sort_ids =&gt; sub {/^ID:(\d+)/} );</code></pre>
+
+<p>when formatted with the following input parameters:</p>
+
+<pre><code>    --space-function-paren
+    --maximum-line-length=26
+    --noadd-newlines</code></pre>
+
+<p>Notice that the input script has a peculiar syntax error - the last two closing tokens of the first line are transposed. (Ironically, this snippet is taken from code which accompanied the book Perl Best Practices). The perltidy tokenizer caught the syntax error, but the formatter touched an undefined variable while attempting to do the formatting. It would be possible to just skip formatting for errors like this, but it can sometimes help finding bugs to see an attempted formatting. So the formatter coding has been corrected to avoid the undefined variable reference.</p>
+
+<p>This fixes issue c102.</p>
+
+<p>5 Nov 2021.</p>
+
+</dd>
+<dt id="Some-blocks-with-side-comments-exceed-line-length"><b>Some blocks with side comments exceed line length</b></dt>
+<dd>
+
+<p>In some rare cases, one-line blocks with side comments were exceeding the line length limit. These usually had a semicolon between the closing block brace and the side comment. For example:</p>
+
+<pre><code>        my $size
+            = do { local $^W; -f $local &amp;&amp; -s _ }; # no ALLO if sending data from a pipe</code></pre>
+
+<p>This update breaks the one-line block in an attempt to keep the total length below the line length limit. The result on the above is:</p>
+
+<pre><code>        my $size = do {
+            local $^W;
+            -f $local &amp;&amp; -s _;
+        };    # no ALLO if sending data from a pipe</code></pre>
+
+<p>Note that this break can be prevented by including the flag --ignore-side-comment-lengths or -iscl.</p>
+
+<p>3 Nov 2021.</p>
+
+</dd>
+</dl>
+
 <h1 id="Issues-fixed-after-release-20210625">Issues fixed after release 20210625</h1>
 
 <dl>
 
 <pre><code>   do $roff ( &amp;verify($tpage) );</code></pre>
 
-<p>20 Oct 2021.</p>
+<p>20 Oct 2021, 72e4bb1.</p>
 
 </dd>
 <dt id="Fix-c091-incorrect-closing-side-comment"><b>Fix c091, incorrect closing side comment</b></dt>
 
 <p>An error was discovered and corrected in the behavior of the --closing-side-comment (-csc) flag when only subs were being marked with the setting -cscl=&#39;sub&#39;. The problem was that in rare cases a closing paren could be marked with &#39;## end&#39;. The cause of the problem is that the pattern matching regex which was generated for this case happens to match an empty string, and it could happen that certain parens had empty strings as block names. This was fixed in two ways. First, the regex was fixed so that it cannot match an empty string. Second, a test for an empty string was added.</p>
 
-<p>20 Oct 2021.</p>
+<p>20 Oct 2021, aa1a019.</p>
 
 </dd>
 <dt id="Issue-c089-improve-vertical-alignment-for-lists-without-parens"><b>Issue c089, improve vertical alignment for lists without parens</b></dt>
index d1efa2fbdfe6a8d98d00135ff79ba9266c6b2a73..d1831c491b82f703a15e8e7f036cdb9affeb5017 100644 (file)
@@ -1,5 +1,31 @@
 <h1>Perltidy Change Log</h1>
 
+<h2>2021 10 29.03</h2>
+
+<pre><code>- A new flag -gal=s, --grep-alias-list=s, has been added as suggested in
+  git #77.  This allows code blocks passed to list operator functions to
+  be formatted in the same way as a code block passed to grep, map, or sort.
+  By default, the following list operators in List::Util are included:
+
+    all any first none notall pairfirst pairgrep pairmap reduce reductions
+
+  They can be changed with the flag -gaxl=s, -grep-alias-exclusion-list=s
+
+- A new flag -xlp has been added which can be set to avoid most of the
+  limitations of the -lp flag regarding side comments, blank lines, and
+  code blocks.  This is off by default to avoid changing existing coding,
+  so this flag has to be set to turn this feature on.  [Documentation still
+  needs to be written].  It will be included in the next release to CPAN,
+  but some details regarding how it handles very long lines may change before
+  the final release to CPAN.  This fixes issues git #64 and git #74.
+
+- The coding for the -lp flag has been rewritten to avoid some problems
+  and limitations.  The new coding allows the -lp indentation style to
+  mix smoothly with the standard indentation in a single file.  Some problems
+  where -lp and -xci flags were not working well together have been fixed, such
+  as happened in issue rt140025.
+</code></pre>
+
 <h2>2021 10 29</h2>
 
 <pre><code>- No significant bugs have been found since the last release, but several
   previous release due to optimizations made with the help of NYTProf.
 
 - This version of perltidy was stress-tested for many cpu hours with
-  random input parameters. No instabilities,  internal fault checks, 
+  random input parameters. No instabilities,  internal fault checks,
   undefined variable references or other irregularities were seen.
 
 - Numerous minor fixes have been made, mostly very rare formatting instabilities
index d3b573ee421717935c1a567fa492b34982359a8b..1a355110b54663433956ecfbf90fa3ac35ee2bdb 100644 (file)
 
 <h1 id="VERSION">VERSION</h1>
 
-<p>This man page documents Perl::Tidy version 20211029</p>
+<p>This man page documents Perl::Tidy version 20211029.03</p>
 
 <h1 id="LICENSE">LICENSE</h1>
 
index 4ee2f5d98dfd66a6cdc0e732b0b23712ceb3addc..1fcf5f00aa0a5b220eb9d76d77f2bae615ca1ba2 100644 (file)
 
 <p>Note that several other parameters accept a list of keywords, including &#39;sub&#39; (see <a href="#Specifying-Block-Types">&quot;Specifying Block Types&quot;</a>). You do not need to include any sub aliases in these lists. Just include keyword &#39;sub&#39; if you wish, and all aliases are automatically included.</p>
 
+</dd>
+<dt id="gal-s---grep-alias-list-s"><b>-gal=s</b>, <b>--grep-alias-list=s</b></dt>
+<dd>
+
+<p>This flag causes a code block following a specified word to be formatted as if it followed the keyword &#39;grep&#39; (or &#39;map&#39; or &#39;sort&#39;). The string <b>s</b> contains one or more such alias words, separated by spaces or commas.</p>
+
+<p>This allows code block arguments to external list operator functions to be formatted in the same way as code blocks which follow the perl builtin keywords &#39;grep&#39;, &#39;map&#39;, and &#39;sort&#39;. By &#39;list operator&#39; is meant a function which is invoked in the form</p>
+
+<pre><code>      word {BLOCK} @list</code></pre>
+
+<p>Perltidy tries to keep code blocks for these functions intact, since they are usually short, and does not automatically break after the closing brace since a list may follow. It also does some special handling of continuation indentation.</p>
+
+<p>For example, the code block arguments to functions &#39;My_grep&#39; and &#39;My_map&#39; can be given formatting like &#39;grep&#39; with</p>
+
+<pre><code>        perltidy -gal=&#39;My_grep My_map&#39;</code></pre>
+
+<p>By default, the following list operators in List::Util are automatically included, and any operators listed in <b>--grep-alias-list</b> are added to this list:</p>
+
+<pre><code>      all any first none notall pairfirst pairgrep pairmap reduce reductions</code></pre>
+
+<p>The next parameter can be used to remove words from this default list.</p>
+
+</dd>
+<dt id="gaxl-s---grep-alias-exclusion-list-s"><b>-gaxl=s</b>, <b>--grep-alias-exclusion-list=s</b></dt>
+<dd>
+
+<p>The <b>-gaxl=s</b> flag provides a method for removing any of the default list operators given above by listing them in the string <b>s</b>. To remove all of the default operators use <b>-gaxl=&#39;*&#39;</b>.</p>
+
 </dd>
 </dl>
 
 
 <h1 id="VERSION">VERSION</h1>
 
-<p>This man page documents perltidy version 20211029</p>
+<p>This man page documents perltidy version 20211029.03</p>
 
 <h1 id="BUG-REPORTS">BUG REPORTS</h1>
 
index f4a90e43ab984ecfe8ad0e8949cfadeceec0fda8..fdfe79c36ca9c3b3b3d984b6572b8ee2ac28afb3 100644 (file)
@@ -2257,6 +2257,7 @@ sub generate_options {
     $add_option->( 'assert-untidy',                'asu',  '!' );
     $add_option->( 'sub-alias-list',               'sal',  '=s' );
     $add_option->( 'grep-alias-list',              'gal',  '=s' );
+    $add_option->( 'grep-alias-exclusion-list',    'gaxl', '=s' );
 
     ########################################
     $category = 2;    # Code indentation control
@@ -3205,6 +3206,66 @@ EOM
         $rexpansion, $roption_category, $roption_range );
 } ## end of _process_command_line
 
+sub make_grep_alias_string {
+    my ($rOpts) = @_;
+
+    # Defaults: list operators in List::Util
+    # Possible future additions:  pairfirst pairgrep pairmap
+    my $default_string = join ' ', qw(
+      all
+      any
+      first
+      none
+      notall
+      reduce
+      reductions
+    );
+
+    # make a hash of any excluded words
+    my %is_excluded_word;
+    my $exclude_string = $rOpts->{'grep-alias-exclusion-list'};
+    if ($exclude_string) {
+        $exclude_string =~ s/,/ /g;    # allow commas
+        $exclude_string =~ s/^\s+//;
+        $exclude_string =~ s/\s+$//;
+        my @q = split /\s+/, $exclude_string;
+        @is_excluded_word{@q} = (1) x scalar(@q);
+    }
+
+    # The special option -gaxl='*' removes all defaults
+    if ( $is_excluded_word{'*'} ) { $default_string = "" }
+
+    # combine the defaults and any input list
+    my $input_string = $rOpts->{'grep-alias-list'};
+    if ($input_string) { $input_string .= " " . $default_string }
+    else               { $input_string = $default_string }
+
+    # Now make the final list of unique grep alias words
+    $input_string =~ s/,/ /g;    # allow commas
+    $input_string =~ s/^\s+//;
+    $input_string =~ s/\s+$//;
+    my @word_list = split /\s+/, $input_string;
+    my @filtered_word_list;
+    my %seen;
+
+    foreach my $word (@word_list) {
+        if ($word) {
+            if ( $word !~ /^\w[\w\d]*$/ ) {
+                Warn(
+                    "unexpected word in --grep-alias-list: '$word' - ignoring\n"
+                );
+            }
+            if ( !$seen{$word} && !$is_excluded_word{$word} ) {
+                $seen{$word}++;
+                push @filtered_word_list, $word;
+            }
+        }
+    }
+    my $joined_words = join ' ', @filtered_word_list;
+    $rOpts->{'grep-alias-list'} = $joined_words;
+    return;
+}
+
 sub check_options {
 
     my ( $rOpts, $is_Windows, $Windows_type, $rpending_complaint ) = @_;
@@ -3376,33 +3437,10 @@ EOM
                 }
             }
         }
-        my $joined_words = join ' ', @filtered_word_list;
         $rOpts->{'sub-alias-list'} = join ' ', @filtered_word_list;
     }
 
-    if ( $rOpts->{'grep-alias-list'} ) {
-        my $grep_alias_string = $rOpts->{'grep-alias-list'};
-        $grep_alias_string =~ s/,/ /g;    # allow commas
-        $grep_alias_string =~ s/^\s+//;
-        $grep_alias_string =~ s/\s+$//;
-        my @grep_alias_list = split /\s+/, $grep_alias_string;
-        my @filtered_word_list;
-        my %seen;
-
-        foreach my $word (@grep_alias_list) {
-            if ($word) {
-                if ( $word !~ /^\w[\w\d]*$/ ) {
-                    Warn("unexpected grep alias '$word' - ignoring\n");
-                }
-                if ( !$seen{$word} ) {
-                    $seen{$word}++;
-                    push @filtered_word_list, $word;
-                }
-            }
-        }
-        my $joined_words = join ' ', @filtered_word_list;
-        $rOpts->{'grep-alias-list'} = join ' ', @filtered_word_list;
-    }
+    make_grep_alias_string($rOpts);
 
     # Turn on fuzzy-line-length unless this is an extrude run, as determined
     # by the -i and -ci settings. Otherwise blinkers can form (case b935)
index 66e41ee089a38af7733d23d28e6daafec3342981..ebe6466cdacd3d7c5aa363705366bd0dddf3c5c5 100644 (file)
@@ -198,15 +198,10 @@ my (
 
     # Static hashes initialized in a BEGIN block
     %is_assignment,
-    %is_keyword_returning_list,
     %is_if_unless_and_or_last_next_redo_return,
     %is_if_elsif_else_unless_while_until_for_foreach,
     %is_if_unless_while_until_for_foreach,
     %is_last_next_redo_return,
-    %is_sort_map_grep,
-    %is_sort_map_grep_eval,
-    %is_sort_map_grep_eval_do,
-    %block_type_map,
     %is_if_unless,
     %is_and_or,
     %is_chain_operator,
@@ -217,7 +212,6 @@ my (
     %is_opening_token,
     %is_closing_token,
     %is_equal_or_fat_comma,
-    %is_block_with_ci,
     %is_counted_type,
     %is_opening_sequence_token,
     %is_closing_sequence_token,
@@ -234,6 +228,15 @@ my (
     %is_anon_sub_1_brace_follower,
     %is_other_brace_follower,
 
+    # Initialized and re-initialized in sub initialize_grep_and_friends;
+    # These can be modified by grep-alias-list
+    %is_sort_map_grep,
+    %is_sort_map_grep_eval,
+    %is_sort_map_grep_eval_do,
+    %is_block_with_ci,
+    %is_keyword_returning_list,
+    %block_type_map,
+
     # Initialized in sub initialize_whitespace_hashes;
     # Some can be modified according to user parameters.
     %binary_ws_rules,
@@ -549,16 +552,6 @@ BEGIN {
     );
     @is_assignment{@q} = (1) x scalar(@q);
 
-    @q = qw(
-      grep
-      keys
-      map
-      reverse
-      sort
-      split
-    );
-    @is_keyword_returning_list{@q} = (1) x scalar(@q);
-
     @q = qw(is if unless and or err last next redo return);
     @is_if_unless_and_or_last_next_redo_return{@q} = (1) x scalar(@q);
 
@@ -577,17 +570,10 @@ BEGIN {
     @q = qw(last next redo return);
     @is_last_next_redo_return{@q} = (1) x scalar(@q);
 
-    @q = qw(sort map grep);
-    @is_sort_map_grep{@q} = (1) x scalar(@q);
-
-    @q = qw(sort map grep eval);
-    @is_sort_map_grep_eval{@q} = (1) x scalar(@q);
-
-    @q = qw(sort map grep eval do);
-    @is_sort_map_grep_eval_do{@q} = (1) x scalar(@q);
-
     # Map related block names into a common name to allow vertical alignment
-    # used by sub make_alignment_patterns
+    # used by sub make_alignment_patterns. Note: this is normally unchanged,
+    # but it contains 'grep' and can be re-initized in
+    # sub initialize_grep_and_friends in a testing mode.
     %block_type_map = (
         'unless'  => 'if',
         'else'    => 'if',
@@ -675,14 +661,6 @@ BEGIN {
     push @q, ',';
     @is_counted_type{@q} = (1) x scalar(@q);
 
-    # These block types can take ci.  This is used by the -xci option.
-    # Note that the 'sub' in this list is an anonymous sub.  To be more correct
-    # we could remove sub and use ASUB pattern to also handle a
-    # prototype/signature.  But that would slow things down and would probably
-    # never be useful.
-    @q = qw( do sub eval sort map grep );
-    @is_block_with_ci{@q} = (1) x scalar(@q);
-
 }
 
 {    ## begin closure to count instances
@@ -1226,7 +1204,9 @@ sub check_options {
 
     initialize_whitespace_hashes();
     initialize_bond_strength_hashes();
-    install_grep_alias_list( $rOpts->{'grep-alias-list'} );
+
+    # This function must be called early to get hashes with grep initialized
+    initialize_grep_and_friends( $rOpts->{'grep-alias-list'} );
 
     # Make needed regex patterns for matching text.
     # NOTE: sub_matching_patterns must be made first because later patterns use
@@ -1278,6 +1258,8 @@ sub check_options {
 
     # Make initial list of desired one line block types
     # They will be modified by 'prepare_cuddled_block_types'
+    # NOTE: this line must come after is_sort_map_grep_eval is
+    # initialized in sub 'initialize_grep_and_friends'
     %want_one_line_block = %is_sort_map_grep_eval;
 
     prepare_cuddled_block_types();
@@ -1948,21 +1930,74 @@ EOM
     return;
 }
 
-sub install_grep_alias_list {
+use constant ALIGN_GREP_ALIASES => 0;
+
+sub initialize_grep_and_friends {
     my ($str) = @_;
-    return unless ($str);
+
+    # 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 hash ... this is critical!
+    %is_sort_map_grep = ();
+
+    my @q = qw(sort map grep);
+    @is_sort_map_grep{@q} = (1) x scalar(@q);
 
     # Note that any 'grep-alias-list' string has been preprocessed to be a
     # trimmed, space-separated list.
-    my @q = split /\s+/, $str;
-    @{is_sort_map_grep}{@q}          = (1) x scalar(@q);
-    @{is_sort_map_grep_eval}{@q}     = (1) x scalar(@q);
-    @{is_sort_map_grep_eval_do}{@q}  = (1) x scalar(@q);
-    @{is_block_with_ci}{@q}          = (1) x scalar(@q);
-    @{is_keyword_returning_list}{@q} = (1) x scalar(@q);
-    foreach (@q) {
-        $block_type_map{$_} = 'map' unless ( $_ eq 'map' );
+    my @grep_aliases = split /\s+/, $str;
+    @{is_sort_map_grep}{@grep_aliases} = (1) x scalar(@grep_aliases);
+
+    ##@q = qw(sort map grep eval);
+    %is_sort_map_grep_eval = %is_sort_map_grep;
+    $is_sort_map_grep_eval{'eval'} = 1;
+
+    ##@q = qw(sort map grep eval do);
+    %is_sort_map_grep_eval_do = %is_sort_map_grep_eval;
+    $is_sort_map_grep_eval_do{'do'} = 1;
+
+    # These block types can take ci.  This is used by the -xci option.
+    # Note that the 'sub' in this list is an anonymous sub.  To be more correct
+    # we could remove sub and use ASUB pattern to also handle a
+    # prototype/signature.  But that would slow things down and would probably
+    # never be useful.
+    ##@q = qw( do sub eval sort map grep );
+    %is_block_with_ci = %is_sort_map_grep_eval_do;
+    $is_block_with_ci{'sub'} = 1;
+
+    %is_keyword_returning_list = ();
+    @q                         = qw(
+      grep
+      keys
+      map
+      reverse
+      sort
+      split
+    );
+    push @q, @grep_aliases;
+    @is_keyword_returning_list{@q} = (1) x scalar(@q);
+
+    # This code enables vertical alignment of grep aliases for testing.  It has
+    # not been found to be beneficial, so it is off by default.  But it is
+    # useful for precise testing of the grep alias coding.
+    if (ALIGN_GREP_ALIASES) {
+        %block_type_map = (
+            'unless'  => 'if',
+            'else'    => 'if',
+            'elsif'   => 'if',
+            'when'    => 'if',
+            'default' => 'if',
+            'case'    => 'if',
+            'sort'    => 'map',
+            'grep'    => 'map',
+        );
+        foreach (@q) {
+            $block_type_map{$_} = 'map' unless ( $_ eq 'map' );
+        }
     }
+    return;
 }
 
 sub initialize_weld_nested_exclusion_rules {
@@ -2940,6 +2975,11 @@ EOM
 
         my @q;
 
+        # NOTE: This hash is like the global %is_sort_map_grep, but it ignores
+        # grep aliases on purpose, since here we are looking parens, not braces
+        @q = qw(sort grep map);
+        @is_sort_grep_map{@q} = (1) x scalar(@q);
+
         @q = qw(for foreach);
         @is_for_foreach{@q} = (1) x scalar(@q);
 
@@ -3172,7 +3212,7 @@ EOM
                 ## || $typel eq 'Y'
 
                 # must have space between grep and left paren; "grep(" will fail
-                || $is_sort_map_grep{$tokenl}
+                || $is_sort_grep_map{$tokenl}
 
                 # don't stick numbers next to left parens, as in:
                 #use Mail::Internet 1.28 (); (see Entity.pm, Head.pm, Test.pm)
@@ -14429,8 +14469,8 @@ sub terminal_type_i {
     my $block_type = $block_type_to_go[$i];
     if (
         $type_i eq '}'
-        && ( !$block_type
-            || ( $is_sort_map_grep_eval_do{$block_type} ) )
+        && (  !$block_type
+            || $is_sort_map_grep_eval_do{$block_type} )
       )
     {
         $type_i = 'b';
index c354ff235bd3e895d1432e08e2e7b8da8b8c346d..e6decd294129a67e896dd9ea606d4d8174f4eb0f 100644 (file)
@@ -312,15 +312,13 @@ sub check_options {
         }
     }
 
-    # Install any aliases to 'grep'
+    %is_grep_alias = ();
     if ( $rOpts->{'grep-alias-list'} ) {
 
         # Note that 'grep-alias-list' has been preprocessed to be a trimmed,
         # space-separated list
         my @q = split /\s+/, $rOpts->{'grep-alias-list'};
-        @{is_grep_alias}{@q}            = (1) x scalar(@q);
-        @{is_code_block_token}{@q}      = (1) x scalar(@q);
-        @{is_sort_map_grep_eval_do}{@q} = (1) x scalar(@q);
+        @{is_grep_alias}{@q} = (1) x scalar(@q);
     }
 
     $rOpts_code_skipping = $rOpts->{'code-skipping'};
@@ -4969,16 +4967,16 @@ EOM
 
                     # zero continuation flag at terminal BLOCK '}' which
                     # ends a statement.
-                    if ( $routput_block_type->[$i] ) {
+                    my $block_type_i = $routput_block_type->[$i];
+                    if ($block_type_i) {
 
                         # ...These include non-anonymous subs
                         # note: could be sub ::abc { or sub 'abc
-                        if ( $routput_block_type->[$i] =~ m/^sub\s*/gc ) {
+                        if ( $block_type_i =~ m/^sub\s*/gc ) {
 
                          # note: older versions of perl require the /gc modifier
                          # here or else the \G does not work.
-                            if ( $routput_block_type->[$i] =~ /\G('|::|\w)/gc )
-                            {
+                            if ( $block_type_i =~ /\G('|::|\w)/gc ) {
                                 $in_statement_continuation = 0;
                             }
                         }
@@ -4987,27 +4985,21 @@ EOM
 # block prototypes and these: (sort|grep|map|do|eval)
 # /^(\}|\{|BEGIN|END|CHECK|INIT|AUTOLOAD|DESTROY|UNITCHECK|continue|;|if|elsif|else|unless|while|until|for|foreach)$/
                         elsif (
-                            $is_zero_continuation_block_type{
-                                $routput_block_type->[$i]
-                            }
-                          )
+                            $is_zero_continuation_block_type{$block_type_i} )
                         {
                             $in_statement_continuation = 0;
                         }
 
                         # ..but these are not terminal types:
                         #     /^(sort|grep|map|do|eval)$/ )
-                        elsif (
-                            $is_sort_map_grep_eval_do{
-                                $routput_block_type->[$i]
-                            }
-                          )
+                        elsif ($is_sort_map_grep_eval_do{$block_type_i}
+                            || $is_grep_alias{$block_type_i} )
                         {
                         }
 
                         # ..and a block introduced by a label
                         # /^\w+\s*:$/gc ) {
-                        elsif ( $routput_block_type->[$i] =~ /:$/ ) {
+                        elsif ( $block_type_i =~ /:$/ ) {
                             $in_statement_continuation = 0;
                         }
 
@@ -5674,7 +5666,9 @@ sub code_block_type {
 # otherwise, look at previous token.  This must be a code block if
 # it follows any of these:
 # /^(BEGIN|END|CHECK|INIT|AUTOLOAD|DESTROY|UNITCHECK|continue|if|elsif|else|unless|do|while|until|eval|for|foreach|map|grep|sort)$/
-    elsif ( $is_code_block_token{$last_nonblank_token} ) {
+    elsif ($is_code_block_token{$last_nonblank_token}
+        || $is_grep_alias{$last_nonblank_token} )
+    {
 
         # Bug Patch: Note that the opening brace after the 'if' in the following
         # snippet is an anonymous hash ref and not a code block!
index 7505948613815fda4a09b370e57245aadf86cad3..406647637c296a197b143ca25db2ad8c4597d943 100644 (file)
@@ -1,4 +1,5 @@
-    # These should format the same with -gal='Map Grep'
+# These should format about the same with -gal='Map Grep'.
+# NOTE: The braces only align if the internal code flag ALIGN_GREP_ALIASES is set
     return +{
         Map {
             $_->init_arg => $_->get_value($instance)
index a5b982bef6954eb440755a6f5176a5e3b8876187..b806bacd8818f40fdab2f636e4de82696f793a2b 100644 (file)
@@ -1,6 +1,7 @@
-    # These should format the same with -gal='Map Grep'
+# These should format about the same with -gal='Map Grep'.
+# NOTE: The braces only align if the internal code flag ALIGN_GREP_ALIASES is set
     return +{
-        Map  { $_->init_arg => $_->get_value($instance) }
+        Map { $_->init_arg => $_->get_value($instance) }
         Grep { $_->has_value($instance) }
         Grep { defined( $_->init_arg ) } $class->get_all_attributes
     };
index cbff9d57132d2a598c2ef88eaa3ff0e214620602..32ebf0ff620359439546d9026465a35b567ba098 100644 (file)
@@ -1,4 +1,5 @@
-# These should format the same with -gal='Map Grep'
+# These should format about the same with -gal='Map Grep'.
+# NOTE: The braces only align if the internal code flag ALIGN_GREP_ALIASES is set
     return +{
         Map  {
 $_->init_arg => $_->get_value($instance) }
index d944aba828f0767b73a156e8550c9ecaaf14b811..1b67a93163736c051dfb776007eafafaec536fd8 100644 (file)
 ../snippets25.t        xlp1.xlp1
 ../snippets25.t        git74.def
 ../snippets25.t        git74.git74
+../snippets25.t        git77.def
+../snippets25.t        git77.git77
 ../snippets3.t ce_wn1.ce_wn
 ../snippets3.t ce_wn1.def
 ../snippets3.t colin.colin
 ../snippets9.t rt98902.def
 ../snippets9.t rt98902.rt98902
 ../snippets9.t rt99961.def
-../snippets25.t        git77.def
-../snippets25.t        git77.git77
index 8f0b09fd46f8ef6fc61ca392b0fbc2414dfe8f26..2e15c49c70c2a24f216d20385f83a645c391d30c 100644 (file)
@@ -180,7 +180,8 @@ my $test_var =
 ----------
 
         'git77' => <<'----------',
-# These should format the same with -gal='Map Grep'
+# These should format about the same with -gal='Map Grep'.
+# NOTE: The braces only align if the internal code flag ALIGN_GREP_ALIASES is set
     return +{
         Map  {
 $_->init_arg => $_->get_value($instance) }
@@ -666,7 +667,8 @@ my $test_var =
             source => "git77",
             params => "def",
             expect => <<'#14...........',
-    # These should format the same with -gal='Map Grep'
+# These should format about the same with -gal='Map Grep'.
+# NOTE: The braces only align if the internal code flag ALIGN_GREP_ALIASES is set
     return +{
         Map {
             $_->init_arg => $_->get_value($instance)
@@ -689,9 +691,10 @@ my $test_var =
             source => "git77",
             params => "git77",
             expect => <<'#15...........',
-    # These should format the same with -gal='Map Grep'
+# These should format about the same with -gal='Map Grep'.
+# NOTE: The braces only align if the internal code flag ALIGN_GREP_ALIASES is set
     return +{
-        Map  { $_->init_arg => $_->get_value($instance) }
+        Map { $_->init_arg => $_->get_value($instance) }
         Grep { $_->has_value($instance) }
         Grep { defined( $_->init_arg ) } $class->get_all_attributes
     };