# Perltidy Change Log
-## 2023 07 01.03
+## 2023 07 01.04
- Add parameters -wme, or --warn-missing-else, and -ame,
or --add-missing else. The parameter -wme tells perltidy to issue
=head2 Missing Else Blocks
-One defensive programming technique is to require every B<if-elsif-> chain be
-terminated with an B<else> block, even if it is not strictly required,
+One defensive programming technique is to require that every B<if-elsif->
+chain be terminated with an B<else> block, even though it is not required,
to insure that there are no holes in the logic.
-For example, consider the following snippet from an actual program:
+For example, consider the following snippet:
if ( $level == 3 ) { $val = $global{'section'} }
elsif ( $level == 2 ) { $val = $global{'chapter'} }
What if the variable B<$level> is neither 2 nor 3? Maybe the original
-programmer knew that this was okay, but a new programmer might not be sure
-sure.
+programmer knew that this was okay, but a new programmer might be unsure.
Perltidy has always written this information in its B<LOG> file (search for
B<No else block>). But a problem is that you have to turn on the log file and
=item B<-wme>, B<--warn-missing-else>
-This flag tells perltidy to issue a warning if a program is missing a terminal B<else> block.
+This flag tells perltidy to issue a warning if a program is missing a terminal B<else> block. The default is not to issue such warnings.
=item B<-ame>, B<--add-missing-else>
-This flag tells perltidy to output an empty else block wherever a program is missing a terminal B<else> block.
+This flag tells perltidy to output an empty else block wherever a program is
+missing a terminal B<else> block. To get a warning when this is done you can
+also set B<-wme>. The default is not to add missing else blocks.
=item B<-amec=s>, B<--add-missing-else-comment=s>
For example, on the above example we get
- # perltidy -ame
+ # perltidy -ame -wme
if ( $level == 3 ) { $val = $global{'section'} }
elsif ( $level == 2 ) { $val = $global{'chapter'} }
else {
##FIXME - added with perltidy -ame
}
-The comment should be changed appropriately after the code is inspected. For
-example, we might decide that it fine as is:
+Any B<##FIXME> comments should be changed appropriately after the code is
+inspected. For example, we might decide that it fine as is, and just leave
+a note for the next programmer:
if ( $level == 3 ) { $val = $global{'section'} }
elsif ( $level == 2 ) { $val = $global{'chapter'} }
else {
- # ok - ignore other level values are safely ignored
+ # ok - other $level values can be safely ignored
}
-Or maybe it is a potential problem:
+Or maybe it should never happen:
if ( $level == 3 ) { $val = $global{'section'} }
elsif ( $level == 2 ) { $val = $global{'chapter'} }
Note that this operation cannot be undone, so be careful to inspect the new
code carefully.
-
=head2 Retaining or Ignoring Existing Line Breaks
Several additional parameters are available for controlling the extent
=head1 VERSION
-This man page documents perltidy version 20230701.03
+This man page documents perltidy version 20230701.04
=head1 BUG REPORTS
<h1>Perltidy Change Log</h1>
+<h2>2023 07 01.04</h2>
+
+<pre><code>- Add parameters -wme, or --warn-missing-else, and -ame,
+ or --add-missing else. The parameter -wme tells perltidy to issue
+ a warning to the error output if an if-elsif-elsif-... chain does
+ not end in an else block. The parameter -ame tells perltidy to
+ insert an else block at the end of such a chain if there is none.
+
+ For example, given the following snippet:
+
+ if ( $level == 3 ) { $val = $global{'section'} }
+ elsif ( $level == 2 ) { $val = $global{'chapter'} }
+
+ # perltidy -ame
+ if ( $level == 3 ) { $val = $global{'section'} }
+ elsif ( $level == 2 ) { $val = $global{'chapter'} }
+ else {
+ ##FIXME - added with perltidy -ame
+ }
+
+ The resulting code should be carefully reviewed, and the comment should
+ be updated as appropriate. The comment can be changed with parameter
+ -amec=s, where 's' is the comment in the else block. The man pages
+ have more details.
+
+- The syntax of the parameter --use-feature=class, or -uf=class, which
+ new in the previous release, has been changed slightly for clarity.
+ The default behavior, which occurs if this flag is not entered, is
+ to automatically try to handle both old and new uses of the keywords
+ 'class', 'method', 'field', and 'ADJUST'.
+ To force these keywords to only follow the -use feature 'class' syntax,
+ enter --use-feature=class.
+ To force perltidy to ignore the -use feature 'class' syntax, enter
+ --use-feature=noclass.
+
+- Issue git #122. Added parameter -lrt=n1:n2, or --line-range-tidy=n1:n2
+ to limit tidy operations to a limited line range. Line numbers start
+ with 1. The man pages have details.
+
+- Some fairly rare instances of incorrect spacing have been fixed. The
+ problem was that the tokenizer being overly conservative in marking
+ terms as possible filehandles. This cause the space after the possible
+ filehandle to be frozen to its input value in order not to introduce
+ an error in case Perl had to guess. The problem was fixed by having the
+ tokenizer look ahead for operators which can eliminate the uncertainty.
+ To illustrate, in the following line the term ``$d`` was previouly
+ marked as a possible file handle, so no space was added after it.
+
+ print $d== 1 ? " [ON]\n" : $d ? " [$d]\n" : "\n";
+
+ In the current version, the next token is seen to be an equality, so
+ ``$d`` is marked as an ordinary identifier and normal spacing rules
+ can apply:
+
+ print $d == 1 ? " [ON]\n" : $d ? " [$d]\n" : "\n";
+
+- This version runs 7 to 10 percent faster than the previous release on
+ large files, depending on options and file type.
+</code></pre>
+
<h2>2023 07 01</h2>
<pre><code>- Issue git #121. Added parameters -xbt, or --extended-block-tightness,
<h1 id="VERSION">VERSION</h1>
-<p>This man page documents Perl::Tidy version 20230701</p>
+<p>This man page documents Perl::Tidy version 20230701.04</p>
<h1 id="LICENSE">LICENSE</h1>
<li><a href="#Whitespace-Control">Whitespace Control</a></li>
<li><a href="#Comment-Controls">Comment Controls</a></li>
<li><a href="#Skipping-Selected-Sections-of-Code">Skipping Selected Sections of Code</a></li>
+ <li><a href="#Formatting-a-Limited-Range-of-Lines">Formatting a Limited Range of Lines</a></li>
<li><a href="#Line-Break-Control">Line Break Control</a></li>
<li><a href="#Controlling-Breaks-at-Braces-Parens-and-Square-Brackets">Controlling Breaks at Braces, Parens, and Square Brackets</a></li>
<li><a href="#Welding">Welding</a></li>
<li><a href="#Breaking-Before-or-After-Operators">Breaking Before or After Operators</a></li>
<li><a href="#Controlling-List-Formatting">Controlling List Formatting</a></li>
<li><a href="#Adding-and-Deleting-Commas">Adding and Deleting Commas</a></li>
+ <li><a href="#Missing-Else-Blocks">Missing Else Blocks</a></li>
<li><a href="#Retaining-or-Ignoring-Existing-Line-Breaks">Retaining or Ignoring Existing Line Breaks</a></li>
<li><a href="#Blank-Line-Control">Blank Line Control</a></li>
<li><a href="#Styles">Styles</a></li>
&& ( $a->{'title'} eq $b->{'title'} )
&& ( $a->{'href'} eq $b->{'href'} ) );</code></pre>
-<p>Note that this is considered to be a different operation from "vertical alignment" because space at just one line is being adjusted, whereas in "vertical alignment" the spaces at all lines are being adjusted. So it sort of a local version of vertical alignment.</p>
+<p>Note that this is considered to be a different operation from "vertical alignment" because space at just one line is being adjusted, whereas in "vertical alignment" the spaces at all lines are being adjusted. So it is sort of a local version of vertical alignment.</p>
<p>Here is an example involving a ternary operator:</p>
</dd>
</dl>
+<h2 id="Formatting-a-Limited-Range-of-Lines">Formatting a Limited Range of Lines</h2>
+
+<p>A command <b>--line-range-tidy=n1:n2</b> is available to process just a selected range of lines of an input stream with perltidy. This command is mainly of interest for programming interactive code editors. When it is used, the entire input stream is read but just the selected range of lines of the input file are processed by the perltidy tokenizer and formatter, and then the stream is reassembled for output. The selected lines need to contain a complete statement or balanced container. Otherwise, a syntax error will occur and the code will not be tidied. There are a couple of limitations on the use of this command: (1) it may not be applied to multiple files, and (2) it only applies to code tidying and not, for example, html formatting.</p>
+
+<dl>
+
+<dt id="lrt-n1:n2---line-range-tidy-n1:n2"><b>-lrt=n1:n2</b>, <b>--line-range-tidy=n1:n2</b></dt>
+<dd>
+
+<p>The range of lines is specified by integers <b>n1</b> and <b>n2</b>, where <b>n1</b> is the first line number to be formatted (start counting with 1) and <b>n2</b> is the last line number to be formatted. If <b>n2</b> is not given, or exceeds the actual number of lines, then formatting continues to the end of the file.</p>
+
+<p>Examples:</p>
+
+<pre><code> -line-range-tidy=43:109 # tidy lines 43 through 109
+ -line-range-tidy=' 43 : 109' # tidy lines 43 through 109 (spaces ok in quotes)
+ -line-range-tidy=1: # tidy all lines
+ -line-range-tidy=0:90 # ERROR (n1 must be >= 1)</code></pre>
+
+</dd>
+</dl>
+
<h2 id="Line-Break-Control">Line Break Control</h2>
<p>The parameters in this and the next sections control breaks after non-blank lines of code. Blank lines are controlled separately by parameters in the section <a href="#Blank-Line-Control">"Blank Line Control"</a>.</p>
<p>One limitation is that any line length limit still applies and can cause long welded sections to be broken into multiple lines.</p>
-<p>Another limitation is that an opening symbol which delimits quoted text cannot be included in a welded pair. This is because quote delimiters are treated specially in perltidy.</p>
-
-<p>Finally, the stacking of containers defined by this flag have priority over any other container stacking flags. This is because any welding is done first.</p>
+<p>Also, the stacking of containers defined by this flag have priority over any other container stacking flags. This is because any welding is done first.</p>
</dd>
<dt id="wfc---weld-fat-comma"><b>-wfc</b>, <b>--weld-fat-comma </b></dt>
</dd>
</dl>
+<h2 id="Missing-Else-Blocks">Missing Else Blocks</h2>
+
+<p>One defensive programming technique is to require that every <b>if-elsif-</b> chain be terminated with an <b>else</b> block, even though it is not required, to insure that there are no holes in the logic.</p>
+
+<p>For example, consider the following snippet:</p>
+
+<pre><code> if ( $level == 3 ) { $val = $global{'section'} }
+ elsif ( $level == 2 ) { $val = $global{'chapter'} }</code></pre>
+
+<p>What if the variable <b>$level</b> is neither 2 nor 3? Maybe the original programmer knew that this was okay, but a new programmer might be unsure.</p>
+
+<p>Perltidy has always written this information in its <b>LOG</b> file (search for <b>No else block</b>). But a problem is that you have to turn on the log file and look for it. The parameters in this section can either issue a warning if an <b>else</b> is missing, or even insert an empty <b>else</b> block where one is missing, or both.</p>
+
+<dl>
+
+<dt id="wme---warn-missing-else"><b>-wme</b>, <b>--warn-missing-else</b></dt>
+<dd>
+
+<p>This flag tells perltidy to issue a warning if a program is missing a terminal <b>else</b> block. The default is not to issue such warnings.</p>
+
+</dd>
+<dt id="ame---add-missing-else"><b>-ame</b>, <b>--add-missing-else</b></dt>
+<dd>
+
+<p>This flag tells perltidy to output an empty else block wherever a program is missing a terminal <b>else</b> block. To get a warning when this is done you can also set <b>-wme</b>. The default is not to add missing else blocks.</p>
+
+</dd>
+<dt id="amec-s---add-missing-else-comment-s"><b>-amec=s</b>, <b>--add-missing-else-comment=s</b></dt>
+<dd>
+
+<p>This string is an optional side comment which will be placed within a new empty else block. The default is:</p>
+
+<pre><code> -amec='##FIXME - added with perltidy -ame'</code></pre>
+
+</dd>
+</dl>
+
+<p>For example, on the above example we get</p>
+
+<pre><code> # perltidy -ame -wme
+ if ( $level == 3 ) { $val = $global{'section'} }
+ elsif ( $level == 2 ) { $val = $global{'chapter'} }
+ else {
+ ##FIXME - added with perltidy -ame
+ }</code></pre>
+
+<p>Any <b>##FIXME</b> comments should be changed appropriately after the code is inspected. For example, we might decide that it fine as is, and just leave a note for the next programmer:</p>
+
+<pre><code> if ( $level == 3 ) { $val = $global{'section'} }
+ elsif ( $level == 2 ) { $val = $global{'chapter'} }
+ else {
+ # ok - other $level values can be safely ignored
+ }</code></pre>
+
+<p>Or maybe it should never happen:</p>
+
+<pre><code> if ( $level == 3 ) { $val = $global{'section'} }
+ elsif ( $level == 2 ) { $val = $global{'chapter'} }
+ else {
+ die("unexpected value of level=$level\n);
+ }</code></pre>
+
+<p>Note that this operation cannot be undone, so be careful to inspect the new code carefully.</p>
+
<h2 id="Retaining-or-Ignoring-Existing-Line-Breaks">Retaining or Ignoring Existing Line Breaks</h2>
<p>Several additional parameters are available for controlling the extent to which line breaks in the input script influence the output script. In most cases, the default parameter values are set so that, if a choice is possible, the output style follows the input style. For example, if a short logical container is broken in the input script, then the default behavior is for it to remain broken in the output script.</p>
<dt id="uf-s---use-feature-s"><b>-uf=s</b>, <b>--use-feature=s</b></dt>
<dd>
-<p>This flag tells perltidy to allow the syntax associated a pragma in string <b>s</b>. Currently only the recognized values for the string are <b>s='class'</b> or string <b>s=' '</b>. The default is <b>--use-feature='class'</b>. This enables perltidy to recognized the special words <b>class</b>, <b>method</b>, <b>field</b>, and <b>ADJUST</b>. If this causes a conflict with other uses of these words, the default can be turned off with <b>--use-feature=' '</b>.</p>
+<p>This flag tells perltidy to allow or disallow the syntax associated a pragma in string <b>s</b>. The current possible settings are:</p>
+
+<ul>
+
+<li><p><b>--use-feature='class'</b>. This tells perltidy to recognized the special words <b>class</b>, <b>method</b>, <b>field</b>, and <b>ADJUST</b> as defined for this feature.</p>
+
+</li>
+<li><p><b>--use-feature='noclass'</b>. This tells perltidy <b>not</b> to treat words <b>class</b>, <b>method</b>, <b>field</b>, <b>ADJUST</b> specially.</p>
+
+</li>
+<li><p><b>Neither of these</b> (<b>--use-feature</b> not defined). This is the DEFAULT and recommended setting. In this case perltidy will try to automatically handle both the newer --use-feature 'class' syntax as well as some conflicting uses of some of these special words by exisiting modules.</p>
+
+</li>
+</ul>
+
+<p>Note that this parameter is independent of any <b>use feature</b> control lines within a script. Perltidy does not look for or read such control lines. This is because perltidy must be able to work on small chunks of code sent from an editor, so it cannot assume that such lines will be within the lines being formatted.</p>
</dd>
</dl>
<h1 id="VERSION">VERSION</h1>
-<p>This man page documents perltidy version 20230701</p>
+<p>This man page documents perltidy version 20230701.04</p>
<h1 id="BUG-REPORTS">BUG REPORTS</h1>
# then the Release version must be bumped, and it is probably past time for
# a release anyway.
- $VERSION = '20230701.03';
+ $VERSION = '20230701.04';
} ## end BEGIN
sub DESTROY {
=head1 VERSION
-This man page documents Perl::Tidy version 20230701.03
+This man page documents Perl::Tidy version 20230701.04
=head1 LICENSE
use strict;
use warnings;
use English qw( -no_match_vars );
-our $VERSION = '20230701.03';
+our $VERSION = '20230701.04';
use constant EMPTY_STRING => q{};
use constant SPACE => q{ };
use strict;
use warnings;
use English qw( -no_match_vars );
-our $VERSION = '20230701.03';
+our $VERSION = '20230701.04';
use constant EMPTY_STRING => q{};
package Perl::Tidy::FileWriter;
use strict;
use warnings;
-our $VERSION = '20230701.03';
+our $VERSION = '20230701.04';
use constant DEVEL_MODE => 0;
use constant EMPTY_STRING => q{};
use Carp;
use English qw( -no_match_vars );
use List::Util qw( min max first ); # min, max first are in Perl 5.8
-our $VERSION = '20230701.03';
+our $VERSION = '20230701.04';
# The Tokenizer will be loaded with the Formatter
##use Perl::Tidy::Tokenizer; # for is_keyword()
package Perl::Tidy::HtmlWriter;
use strict;
use warnings;
-our $VERSION = '20230701.03';
+our $VERSION = '20230701.04';
use English qw( -no_match_vars );
use File::Basename;
use strict;
use warnings;
use Carp;
-our $VERSION = '20230701.03';
+our $VERSION = '20230701.04';
use constant DEVEL_MODE => 0;
use constant EMPTY_STRING => q{};
use strict;
use warnings;
use Carp;
-our $VERSION = '20230701.03';
+our $VERSION = '20230701.04';
use constant DEVEL_MODE => 0;
package Perl::Tidy::IndentationItem;
use strict;
use warnings;
-our $VERSION = '20230701.03';
+our $VERSION = '20230701.04';
BEGIN {
package Perl::Tidy::Logger;
use strict;
use warnings;
-our $VERSION = '20230701.03';
+our $VERSION = '20230701.04';
use English qw( -no_match_vars );
use constant DEVEL_MODE => 0;
use warnings;
use English qw( -no_match_vars );
-our $VERSION = '20230701.03';
+our $VERSION = '20230701.04';
use Carp;
use warnings;
use Carp;
use English qw( -no_match_vars );
-our $VERSION = '20230701.03';
+our $VERSION = '20230701.04';
use Perl::Tidy::VerticalAligner::Alignment;
use Perl::Tidy::VerticalAligner::Line;
{ #<<< A non-indenting brace
-our $VERSION = '20230701.03';
+our $VERSION = '20230701.04';
sub new {
my ( $class, $rarg ) = @_;
use strict;
use warnings;
use English qw( -no_match_vars );
-our $VERSION = '20230701.03';
+our $VERSION = '20230701.04';
sub AUTOLOAD {