From: Steve Hancock Date: Mon, 1 Jan 2024 22:58:24 +0000 (-0800) Subject: split -wcp=s into -wcp=s and -nwcp=s to simplify use X-Git-Tag: 20230912.10~1 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=137eee6c302403c7f7dc0f4b807864bf3960a0d8;p=perltidy.git split -wcp=s into -wcp=s and -nwcp=s to simplify use --- diff --git a/CHANGES.md b/CHANGES.md index a5fb8ff8..fc70b47c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -15,9 +15,9 @@ k:chomp:3:4 k:close:7:4 - - Added --warn-call-parens=s (-wcp=s) option which will warn of paren - uses which do not match a selected style. The manual has details. But - for example, + - Added --warn-call-parens=s (-wcp=s) and --nowarn-call-parens=s (-nwcp=s) + options which will warn of paren uses which do not match a selected + style. The manual has details. But for example, perltidy -wcp='&' somefile.pl diff --git a/bin/perltidy b/bin/perltidy index 0cf249c8..0ee4d26b 100755 --- a/bin/perltidy +++ b/bin/perltidy @@ -5602,97 +5602,95 @@ can be used to skip warning checks for a list of variables. For example, will skip all warnings for variables C<$self> and C<$class>. -=item B +=item B -Perl allows function call arguments to be placed within parentheses, but it is -not generally required. Styles vary, but often the arguments of user-defined -functions are placed within parens, and the arguments of many builtin function -calls are often written without parens. - -The parameter B<--dump-mixed-call-parens>, or B<-dmcp>, can be used to to -make a list of keywords and sub names which have been written both with and -without following parens. This can be useful for checking for a consistent -programming style. For example, +The parameter B<--dump-mixed-call-parens>, or B<-dmcp>, provides information on +the use of call parens within a program. It produces a list of keywords and sub +names which occur both both with and without parens. In other words, with +a mixed style. This might be useful if one is working to standardize the +call style for some particular keyword or function. For example, perltidy -dmcp somefile.pl >output.txt will analyze the text of F, write the results to F, -and then immediately exit. +and then immediately exit (like all B parameters). The output shows a list of operators and the number of times they were used with parens and the number of times without parens. For example, here -is a small section of the output from one program: +is a small section of the output from one file in a past Perl distribution: k:length:17:9 k:open:30:9 k:pop:3:4 -The 'k' indicates a Perl keyword, and the two numbers should the number of -times it was called with parens and the number of times without parens. +The first line shows that the C function occurs 17 times with parens +and 9 times without parens. The 'k' indicates that C is a Perl builtin +keyword. So from this partial output we see that the author had a preference +for parens around the args of C and C, whereas C was about +equally likely to have parens as not. A detailed list list of each occurance of a particular operator use, either -with or without parens, can be made with the parameter B<--want-call-parens=s> -described in the next section. +without or with parens, can be made with the parameters B<--want-call-parens=s> +and B<--nowant-call-parens=s> described in the next section. -=item B +=item B The parameter B<--want-call-parens=s>, or B<-wcp=s>, can be used to to produce -a warning message if the parens, or lack of parens, does not match the desired -style for a particular function. This information can help a programmer to -maintain a certain style. Note that this is a regular parameter, not a -dump, so perltidy will look for a discrepancy from the requested style -while it does its normal formatting. This allows monitoring a file for -the introduction of an unwanted style. Before using this parameter, it -may be helpful to first use B<--dump-mixed-call-parens=s>, described in the -previous section, to get an overview of the existing paren usage in a file. - -The string argument B is a list of functions which perltidy should check. -The function names may builtin keywords or user-defined subs. The names -must be simple words (matching the regex C<\w+>) without a package prefix -or sigil. Perltidy scans the text for the listed function names, -looks for a subsequent opening paren, and warns of any discrepancies with -the request. - -For builtin keywords such as C, which have either a block form or a -trailing modifier form, the block form will be ignored when the file is -scanned since parens are mandetory in that case. - -In the input string, functions which should enclose their arguments in parens -are listed first, separated by spaces or commas. Then, if there are functions -which should not have parens, an exclamation mark, B, should be added -and followed by the list of those functions. Thus, the symbol B divides -the string into two parts, the first part being operators which should have -parens, and the second part being operators which should not have parens. +a warning message if call parens are missing from selected functions. +Likewise, B<--nowant-call-parens=s>, or B<-nwcp=s>, can warn if call parens +exist for selected functions. When either of these parameters are set, +perltidy will will look for a discrepancy from the requested styles while it +does its normal formatting operations. -For example +If a function name is entered in both lists, the entry in B<-wcp> will apply. - perltidy -wcp='open close ! print' somefile.pl - <--parens--|--no parens--> +Before using either of these parameters, it may be helpful to first use +B<--dump-mixed-call-parens=s>, described in the previous section, to get an +overview of the existing paren usage in a file. -means that the builtin functions C and C should have parens around -their call args but C should not. Spaces are okay but only needed to -separate words, so this could also be written +The string arguments B are space-separated lists of the names of the +functions to be checked. The function names may builtin keywords or +user-defined subs. They may not include a package prefix or sigil. - perltidy -wcp='open close!print' somefile.pl +For builtin keywords which have both a block form and a trailing modifier form, +such as C, only the trailing modifier form will be checked because +parens are mandatory for the block form. -or even +To illustrate, - perltidy -wcp='open,close!print' somefile.pl + perltidy -wcp='length open' -nwcp='pop' somefile.pl -Though not necessary, a symbol B<+> may be placed in the string B to end the -scope of a preceding B. So this example could also be written +means that the builtin functions C and C should have parens around +their call args but C should not. If this is run on the example file +discussed in the previous section, the error output will contain lines such as: - perltidy -wcp='open ! print + close' somefile.pl + 2314:open FD_TO_CLOSE: no call parens + 3652:pop (: has call parens + 3783:length $DB: no call parens + ... -If the symbol B<&> is entered instead of a function name, it means all user defined subs not in the list. So for example +In this particular case, the list will contain the 9 entries for C, 9 +entries for C, and 3 entries for C, which were discovered with the +B<-dmcp> parameter in the previous section. - perltidy -wcp='&' +The symbol B<&> may entered instead of a function name to mean all user-defined +subs not explicitely listed. So the compact expression + + perltidy -wcp='&' somefile.pl means that calls to all user-defined subs in the file being processed should have their call arguments enclosed in parens. -When adding or removing parentheses, it is essential to pay attention to -operator precedence issues. +Perltidy does not have the ability to add or delete call parens because it is +difficult to automate, so changes must be done by hand editing. When adding or +removing parentheses, it is essential to pay attention to operator precedence +issues. For example, if the parens in the following statement are +removed, then C<||> must be changed to C: + + open( IN, "<", $infile ) || die("cannot open $infile:$!\n"); + +Otherwise, the C<||> will operate on C<$infile> and not the return value of +C. =item B diff --git a/dev-bin/perltidy_random_setup.pl b/dev-bin/perltidy_random_setup.pl index 12c06c47..8afb7902 100755 --- a/dev-bin/perltidy_random_setup.pl +++ b/dev-bin/perltidy_random_setup.pl @@ -902,7 +902,8 @@ EOM 'space-signature-paren' => [ 0, 2 ], 'break-after-labels' => [ 0, 2 ], - 'want-call-parens' => [ '&', 'open!close' ], + 'want-call-parens' => [ '&', 'open', 'close' ], + 'nowant-call-parens' => [ 'pop', 'open' ], 'want-trailing-commas' => [ '0', '*', 'm', 'b', 'h', 'i', ' ' ], 'one-line-block-exclusion-list' => diff --git a/lib/Perl/Tidy.pm b/lib/Perl/Tidy.pm index 40d4ff18..58d1fade 100644 --- a/lib/Perl/Tidy.pm +++ b/lib/Perl/Tidy.pm @@ -3713,6 +3713,7 @@ sub generate_options { $add_option->( 'warn-variable-types', 'wvt', '=s' ); $add_option->( 'warn-variable-exclusion-list', 'wvxl', '=s' ); $add_option->( 'want-call-parens', 'wcp', '=s' ); + $add_option->( 'nowant-call-parens', 'nwcp', '=s' ); ######################################## $category = 13; # Debugging diff --git a/lib/Perl/Tidy/Formatter.pm b/lib/Perl/Tidy/Formatter.pm index d7bde764..1cdcc5a1 100644 --- a/lib/Perl/Tidy/Formatter.pm +++ b/lib/Perl/Tidy/Formatter.pm @@ -9807,7 +9807,7 @@ sub dump_mixed_call_parens { @mixed_counts; my $output_string = <{$opt}; - return unless $str; - - my $want_parens = 1; - my $err_msg; - while ( - $str =~ m{ - \G( - (\s+) # whitespace - this must come before \W - | (\W) # or single-character, non-whitespace punct - | (\d+) # or sequence of digits - must come before \w - | (\w+) # or words not starting with a digit - ) - }gcx - ) - { - # skip blanks - if ( defined($2) ) { next } - elsif ( defined($3) ) { - if ( $3 eq '!' ) { $want_parens = 0; } - elsif ( $3 eq '+' ) { $want_parens = 1; } - elsif ( $3 eq '*' ) { $call_paren_style{$3} = $want_parens } - elsif ( $3 eq '&' ) { $call_paren_style{$3} = $want_parens } - elsif ( $3 eq ',' ) { next } - else { $err_msg = "Unexpected symbol '$3'"; last } - } - elsif ( defined($4) ) { - $err_msg = "Unexpected digit '$4'"; - last; - } - elsif ( defined($5) ) { - if ( defined( $call_paren_style{$5} ) ) { - Warn("--$opt has multiple entries for '$5', last is used\n"); - } - $call_paren_style{$5} = $want_parens; + my $val = 0; + foreach my $opt_name ( 'nowant-call-parens', 'want-call-parens' ) { + if ( my @q = split_words( $rOpts->{$opt_name} ) ) { + @call_paren_style{@q} = ($val) x scalar(@q); } - else { - ## should never get here - $err_msg = "Unexpected token '$1'"; - last; - } - } - if ($err_msg) { - Perl::Tidy::Die("Error parsing --$opt: $err_msg\n"); + $val++; } return; } ## end sub initialize_call_paren_style @@ -9993,6 +9931,11 @@ EOM if ( length($token_next) > 23 ) { $token_next = substr( $token_next, 0, 20 ) . '...'; } + + # stop before a ':' to allow use of ':' as spreadsheet col separator + my $ii = index( $token_next, ':' ); + if ( $ii >= 0 ) { $token_next = substr( $token_next, 0, $ii ) } + $message .= "$lno:$token $token_next: $note\n"; } $message .= "End scan for --$opt_name\n";