File Coverage

blib/lib/Perl/Tidy.pm
Criterion Covered Total %
statement 1286 2084 61.7
branch 405 966 41.9
condition 85 249 34.1
subroutine 70 107 65.4
pod 0 51 0.0
total 1846 3457 53.4


line stmt bran cond sub pod time code
1             #
2             ###########################################################
3             #
4             # perltidy - a perl script indenter and formatter
5             #
6             # Copyright (c) 2000-2023 by Steve Hancock
7             # Distributed under the GPL license agreement; see file COPYING
8             #
9             # This program is free software; you can redistribute it and/or modify
10             # it under the terms of the GNU General Public License as published by
11             # the Free Software Foundation; either version 2 of the License, or
12             # (at your option) any later version.
13             #
14             # This program is distributed in the hope that it will be useful,
15             # but WITHOUT ANY WARRANTY; without even the implied warranty of
16             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17             # GNU General Public License for more details.
18             #
19             # You should have received a copy of the GNU General Public License along
20             # with this program; if not, write to the Free Software Foundation, Inc.,
21             # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22             #
23             # For brief instructions, try 'perltidy -h'.
24             # For more complete documentation, try 'man perltidy'
25             # or visit http://perltidy.sourceforge.net
26             #
27             # This script is an example of the default style. It was formatted with:
28             #
29             # perltidy Tidy.pm
30             #
31             # Code Contributions: See ChangeLog.html for a complete history.
32             # Michael Cartmell supplied code for adaptation to VMS and helped with
33             # v-strings.
34             # Hugh S. Myers supplied sub streamhandle and the supporting code to
35             # create a Perl::Tidy module which can operate on strings, arrays, etc.
36             # Yves Orton supplied coding to help detect Windows versions.
37             # Axel Rose supplied a patch for MacPerl.
38             # Sebastien Aperghis-Tramoni supplied a patch for the defined or operator.
39             # Dan Tyrell contributed a patch for binary I/O.
40             # Ueli Hugenschmidt contributed a patch for -fpsc
41             # Sam Kington supplied a patch to identify the initial indentation of
42             # entabbed code.
43             # jonathan swartz supplied patches for:
44             # * .../ pattern, which looks upwards from directory
45             # * --notidy, to be used in directories where we want to avoid
46             # accidentally tidying
47             # * prefilter and postfilter
48             # * iterations option
49             #
50             # Many others have supplied key ideas, suggestions, and bug reports;
51             # see the CHANGES file.
52             #
53             ############################################################
54              
55             package Perl::Tidy;
56              
57             # perlver reports minimum version needed is 5.8.0
58             # 5.004 needed for IO::File
59             # 5.008 needed for wide characters
60 39     39   2299620 use 5.008;
  39         494  
61 39     39   212 use warnings;
  39         78  
  39         1293  
62 39     39   300 use strict;
  39         126  
  39         1201  
63 39     39   275 use Exporter;
  39         109  
  39         1861  
64 39     39   229 use Carp;
  39         63  
  39         2335  
65 39     39   20258 use English qw( -no_match_vars );
  39         154378  
  39         224  
66 39     39   13937 use Digest::MD5 qw(md5_hex);
  39         82  
  39         2305  
67 39     39   16672 use Perl::Tidy::Debugger;
  39         102  
  39         1230  
68 39     39   16576 use Perl::Tidy::Diagnostics;
  39         98  
  39         1164  
69 39     39   18405 use Perl::Tidy::FileWriter;
  39         122  
  39         1241  
70 39     39   210262 use Perl::Tidy::Formatter;
  39         176  
  39         1957  
71 39     39   32317 use Perl::Tidy::HtmlWriter;
  39         161  
  39         1677  
72 39     39   20397 use Perl::Tidy::IOScalar;
  39         159  
  39         1207  
73 39     39   16729 use Perl::Tidy::IOScalarArray;
  39         118  
  39         1186  
74 39     39   17721 use Perl::Tidy::IndentationItem;
  39         126  
  39         1243  
75 39     39   19085 use Perl::Tidy::Logger;
  39         115  
  39         1250  
76 39     39   77702 use Perl::Tidy::Tokenizer;
  39         138  
  39         1951  
77 39     39   54542 use Perl::Tidy::VerticalAligner;
  39         141  
  39         2026  
78             local $OUTPUT_AUTOFLUSH = 1;
79              
80             # DEVEL_MODE can be turned on for extra checking during development
81 39     39   366 use constant DEVEL_MODE => 0;
  39         82  
  39         2316  
82 39     39   292 use constant DIAGNOSTICS => 0;
  39         120  
  39         1883  
83 39     39   261 use constant EMPTY_STRING => q{};
  39         111  
  39         1823  
84 39     39   235 use constant SPACE => q{ };
  39         99  
  39         3266  
85              
86 39         4209 use vars qw{
87             $VERSION
88             @ISA
89             @EXPORT
90 39     39   305 };
  39         102  
91              
92             @ISA = qw( Exporter );
93             @EXPORT = qw( &perltidy );
94              
95 39     39   332 use Cwd;
  39         105  
  39         2790  
96 39     39   27497 use Encode ();
  39         415569  
  39         1093  
97 39     39   19361 use Encode::Guess;
  39         140016  
  39         180  
98 39     39   22673 use IO::File;
  39         332548  
  39         4763  
99 39     39   348 use File::Basename;
  39         94  
  39         2609  
100 39     39   22469 use File::Copy;
  39         104401  
  39         3061  
101 39     39   29111 use File::Temp qw(tempfile);
  39         345733  
  39         2780  
102              
103             BEGIN {
104              
105             # Release version is the approximate YYYYMMDD of the release.
106             # Development version is (Last Release).(Development Number)
107              
108             # To make the number continually increasing, the Development Number is a 2
109             # digit number starting at 01 after a release. It is continually bumped
110             # along at significant points during development. If it ever reaches 99
111             # then the Release version must be bumped, and it is probably past time for
112             # a release anyway.
113              
114 39     39   38795 $VERSION = '20230909';
115             } ## end BEGIN
116              
117       0     sub DESTROY {
118              
119             # required to avoid call to AUTOLOAD in some versions of perl
120             }
121              
122             sub AUTOLOAD {
123              
124             # Catch any undefined sub calls so that we are sure to get
125             # some diagnostic information. This sub should never be called
126             # except for a programming error.
127 0     0   0 our $AUTOLOAD;
128 0 0       0 return if ( $AUTOLOAD =~ /\bDESTROY$/ );
129 0         0 my ( $pkg, $fname, $lno ) = caller();
130 0         0 print {*STDERR} <<EOM;
  0         0  
131             ======================================================================
132             Unexpected call to Autoload looking for sub $AUTOLOAD
133             Called from package: '$pkg'
134             Called from File '$fname' at line '$lno'
135             This error is probably due to a recent programming change
136             ======================================================================
137             EOM
138 0         0 exit 1;
139             } ## end sub AUTOLOAD
140              
141             sub streamhandle {
142              
143             # given filename and mode (r or w), create an object which:
144             # has a 'getline' method if mode='r', and
145             # has a 'print' method if mode='w'.
146             # The objects also need a 'close' method.
147             #
148             # How the object is made:
149             #
150             # if $filename is: Make object using:
151             # ---------------- -----------------
152             # '-' (STDIN if mode = 'r', STDOUT if mode='w')
153             # string IO::File
154             # ARRAY ref Perl::Tidy::IOScalarArray (formerly IO::ScalarArray)
155             # STRING ref Perl::Tidy::IOScalar (formerly IO::Scalar)
156             # object object
157             # (check for 'print' method for 'w' mode)
158             # (check for 'getline' method for 'r' mode)
159              
160             # An optional flag $is_encoded_data may be given, as follows:
161              
162             # Case 1. Any non-empty string: encoded data is being transferred, set
163             # encoding to be utf8 for files and for stdin.
164              
165             # Case 2. Not given, or an empty string: unencoded binary data is being
166             # transferred, set binary mode for files and for stdin.
167              
168             # NOTE: sub slurp_stream is now preferred for reading.
169              
170 549     549 0 1897 my ( $filename, $mode, $is_encoded_data ) = @_;
171              
172 549         1549 my $ref = ref($filename);
173 549         1398 my $New;
174             my $fh;
175              
176             # handle a reference
177 549 50       1635 if ($ref) {
178 549 50       2710 if ( $ref eq 'ARRAY' ) {
    50          
179 0     0   0 $New = sub { Perl::Tidy::IOScalarArray->new( $filename, $mode ) };
  0         0  
180             }
181             elsif ( $ref eq 'SCALAR' ) {
182 549     549   2895 $New = sub { Perl::Tidy::IOScalar->new( $filename, $mode ) };
  549         4928  
183             }
184             else {
185              
186             # Accept an object with a getline method for reading. Note:
187             # IO::File is built-in and does not respond to the defined
188             # operator. If this causes trouble, the check can be
189             # skipped and we can just let it crash if there is no
190             # getline.
191 0 0       0 if ( $mode =~ /[rR]/ ) {
192              
193             # RT#97159; part 1 of 2: updated to use 'can'
194             ##if ( $ref eq 'IO::File' || defined &{ $ref . "::getline" } ) {
195 0 0       0 if ( $ref->can('getline') ) {
196 0     0   0 $New = sub { $filename };
  0         0  
197             }
198             else {
199 0     0   0 $New = sub { undef };
  0         0  
200 0         0 confess <<EOM;
201             ------------------------------------------------------------------------
202             No 'getline' method is defined for object of class '$ref'
203             Please check your call to Perl::Tidy::perltidy. Trace follows.
204             ------------------------------------------------------------------------
205             EOM
206             }
207             }
208              
209             # Accept an object with a print method for writing.
210             # See note above about IO::File
211 0 0       0 if ( $mode =~ /[wW]/ ) {
212              
213             # RT#97159; part 2 of 2: updated to use 'can'
214             ##if ( $ref eq 'IO::File' || defined &{ $ref . "::print" } ) {
215 0 0       0 if ( $ref->can('print') ) {
216 0     0   0 $New = sub { $filename };
  0         0  
217             }
218             else {
219 0     0   0 $New = sub { undef };
  0         0  
220 0         0 confess <<EOM;
221             ------------------------------------------------------------------------
222             No 'print' method is defined for object of class '$ref'
223             Please check your call to Perl::Tidy::perltidy. Trace follows.
224             ------------------------------------------------------------------------
225             EOM
226             }
227             }
228             }
229             }
230              
231             # handle a string
232             else {
233 0 0       0 if ( $filename eq '-' ) {
234 0 0   0   0 $New = sub { $mode eq 'w' ? *STDOUT : *STDIN }
235 0         0 }
236             else {
237 0     0   0 $New = sub { IO::File->new( $filename, $mode ) };
  0         0  
238             }
239             }
240 549         1873 $fh = $New->( $filename, $mode );
241 549 50       2054 if ( !$fh ) {
242              
243 0         0 Warn("Couldn't open file:$filename in mode:$mode : $OS_ERROR\n");
244              
245             }
246             else {
247              
248             # Case 1: handle encoded data
249 549 50       1539 if ($is_encoded_data) {
250 0 0       0 if ( ref($fh) eq 'IO::File' ) {
    0          
251             ## binmode object call not available in older perl versions
252             ## $fh->binmode(":raw:encoding(UTF-8)");
253 0         0 binmode $fh, ":raw:encoding(UTF-8)";
254             }
255             elsif ( $filename eq '-' ) {
256 0         0 binmode STDOUT, ":raw:encoding(UTF-8)";
257             }
258             else {
259             # shouldn't happen
260             }
261             }
262              
263             # Case 2: handle unencoded data
264             else {
265 549 50       3375 if ( ref($fh) eq 'IO::File' ) { binmode $fh }
  0 50       0  
266 0         0 elsif ( $filename eq '-' ) { binmode STDOUT }
267             else { } # shouldn't happen
268             }
269             }
270              
271 549   33     3779 return $fh, ( $ref or $filename );
272             } ## end sub streamhandle
273              
274             sub slurp_stream {
275              
276 1110     1110 0 3254 my ($filename) = @_;
277              
278             # Read the text in $filename and
279             # return:
280             # undef if read error, or
281             # $rinput_string = ref to string of text
282              
283             # if $filename is: Read
284             # ---------------- -----------------
285             # ARRAY ref array ref
286             # SCALAR ref string ref
287             # object ref object with 'getline' method (exit if no 'getline')
288             # '-' STDIN
289             # string file named $filename
290              
291             # Note that any decoding from utf8 must be done by the caller
292              
293 1110         3395 my $ref = ref($filename);
294 1110         2391 my $rinput_string;
295              
296             # handle a reference
297 1110 100       3744 if ($ref) {
298 1107 100       5616 if ( $ref eq 'ARRAY' ) {
    50          
299 2         9 my $buf = join EMPTY_STRING, @{$filename};
  2         14  
300 2         7 $rinput_string = \$buf;
301             }
302             elsif ( $ref eq 'SCALAR' ) {
303 1105         2655 $rinput_string = $filename;
304             }
305             else {
306 0 0       0 if ( $ref->can('getline') ) {
307 0         0 my $buf = EMPTY_STRING;
308 0         0 while ( defined( my $line = $filename->getline() ) ) {
309 0         0 $buf .= $line;
310             }
311 0         0 $rinput_string = \$buf;
312             }
313             else {
314 0         0 confess <<EOM;
315             ------------------------------------------------------------------------
316             No 'getline' method is defined for object of class '$ref'
317             Please check your call to Perl::Tidy::perltidy. Trace follows.
318             ------------------------------------------------------------------------
319             EOM
320             }
321             }
322             }
323              
324             # handle a string
325             else {
326 3 50       16 if ( $filename eq '-' ) {
327 0         0 local $INPUT_RECORD_SEPARATOR = undef;
328 0         0 my $buf = <>;
329 0         0 $rinput_string = \$buf;
330             }
331             else {
332 3 50       174 if ( open( my $fh, '<', $filename ) ) {
333 3         35 local $INPUT_RECORD_SEPARATOR = undef;
334 3         113 my $buf = <$fh>;
335 3 50       63 $fh->close() or Warn("Cannot close $filename\n");
336 3         92 $rinput_string = \$buf;
337             }
338             else {
339 0         0 Warn("Cannot open $filename: $OS_ERROR\n");
340 0         0 return;
341             }
342             }
343             }
344              
345 1110         3030 return $rinput_string;
346             } ## end sub slurp_stream
347              
348             { ## begin closure for sub catfile
349              
350             my $missing_file_spec;
351              
352             BEGIN {
353 39     39   222 $missing_file_spec = !eval { require File::Spec; 1 };
  39         326  
  39         20100  
354             }
355              
356             sub catfile {
357              
358             # concatenate a path and file basename
359             # returns undef in case of error
360              
361 0     0 0 0 my @parts = @_;
362              
363             # use File::Spec if we can
364 0 0       0 if ( !$missing_file_spec ) {
365 0         0 return File::Spec->catfile(@parts);
366             }
367              
368             # Perl 5.004 systems may not have File::Spec so we'll make
369             # a simple try. We assume File::Basename is available.
370             # return if not successful.
371 0         0 my $name = pop @parts;
372 0         0 my $path = join '/', @parts;
373 0         0 my $test_file = $path . $name;
374 0         0 my ( $test_name, $test_path ) = fileparse($test_file);
375 0 0       0 return $test_file if ( $test_name eq $name );
376 0 0       0 return if ( $OSNAME eq 'VMS' );
377              
378             # this should work at least for Windows and Unix:
379 0         0 $test_file = $path . '/' . $name;
380 0         0 ( $test_name, $test_path ) = fileparse($test_file);
381 0 0       0 return $test_file if ( $test_name eq $name );
382 0         0 return;
383             } ## end sub catfile
384             } ## end closure for sub catfile
385              
386             # Here is a map of the flow of data from the input source to the output
387             # line sink:
388             #
389             # -->Tokenizer-->Formatter-->VerticalAligner-->FileWriter-->
390             # input groups output
391             # lines tokens lines of lines lines
392             # lines
393             #
394             # The names correspond to the package names responsible for the unit processes.
395             #
396             # The overall process is controlled by the "main" package.
397             #
398             # Tokenizer analyzes a line and breaks it into tokens, peeking ahead
399             # if necessary. A token is any section of the input line which should be
400             # manipulated as a single entity during formatting. For example, a single
401             # ',' character is a token, and so is an entire side comment. It handles
402             # the complexities of Perl syntax, such as distinguishing between '<<' as
403             # a shift operator and as a here-document, or distinguishing between '/'
404             # as a divide symbol and as a pattern delimiter.
405             #
406             # Formatter inserts and deletes whitespace between tokens, and breaks
407             # sequences of tokens at appropriate points as output lines. It bases its
408             # decisions on the default rules as modified by any command-line options.
409             #
410             # VerticalAligner collects groups of lines together and tries to line up
411             # certain tokens, such as '=>', '#', and '=' by adding whitespace.
412             #
413             # FileWriter simply writes lines to the output stream.
414             #
415             # The Logger package, not shown, records significant events and warning
416             # messages. It writes a .LOG file, which may be saved with a
417             # '-log' or a '-g' flag.
418              
419             { #<<< (this side comment avoids excessive indentation in a closure)
420              
421             my $Warn_count;
422             my $fh_stderr;
423             my $loaded_unicode_gcstring;
424             my $rstatus;
425              
426             # Bump Warn_count only: it is essential to bump the count on all warnings, even
427             # if no message goes out, so that the correct exit status is set.
428 0     0 0 0 sub Warn_count_bump { $Warn_count++; return }
  0         0  
429              
430             # Output Warn message only
431 0     0 0 0 sub Warn_msg { my $msg = shift; $fh_stderr->print($msg); return }
  0         0  
  0         0  
432              
433             # Output Warn message and bump Warn count
434 0     0 0 0 sub Warn { my $msg = shift; $fh_stderr->print($msg); $Warn_count++; return }
  0         0  
  0         0  
  0         0  
435              
436             sub is_char_mode {
437              
438 559     559 0 1765 my ($string) = @_;
439              
440             # Returns:
441             # true if $string is in Perl's internal character mode
442             # (also called the 'upgraded form', or UTF8=1)
443             # false if $string is in Perl's internal byte mode
444              
445             # This function isolates the call to Perl's internal function
446             # utf8::is_utf8() which is true for strings represented in an 'upgraded
447             # form'. It is available after Perl version 5.8.
448             # See https://perldoc.perl.org/Encode.
449             # See also comments in Carp.pm and other modules using this function
450              
451 559 100       2806 return 1 if ( utf8::is_utf8($string) );
452 557         5936 return;
453             } ## end sub is_char_mode
454              
455             my $md5_hex = sub {
456             my ($buf) = @_;
457              
458             # Evaluate the MD5 sum for a string
459             # Patch for [rt.cpan.org #88020]
460             # Use utf8::encode since md5_hex() only operates on bytes.
461             # my $digest = md5_hex( utf8::encode($sink_buffer) );
462              
463             # Note added 20180114: the above patch did not work correctly. I'm not
464             # sure why. But switching to the method recommended in the Perl 5
465             # documentation for Encode worked. According to this we can either use
466             # $octets = encode_utf8($string) or equivalently
467             # $octets = encode("utf8",$string)
468             # and then calculate the checksum. So:
469             my $octets = Encode::encode( "utf8", $buf );
470             my $digest = md5_hex($octets);
471             return $digest;
472             };
473              
474 0         0 BEGIN {
475              
476             # Array index names for $self.
477             # Do not combine with other BEGIN blocks (c101).
478 39     39   190908 my $i = 0;
479             use constant {
480 39         10506 _actual_output_extension_ => $i++,
481             _debugfile_stream_ => $i++,
482             _decoded_input_as_ => $i++,
483             _destination_stream_ => $i++,
484             _diagnostics_object_ => $i++,
485             _display_name_ => $i++,
486             _file_extension_separator_ => $i++,
487             _fileroot_ => $i++,
488             _is_encoded_data_ => $i++,
489             _length_function_ => $i++,
490             _line_separator_default_ => $i++,
491             _line_separator_ => $i++,
492             _line_tidy_begin_ => $i++,
493             _line_tidy_end_ => $i++,
494             _logger_object_ => $i++,
495             _output_file_ => $i++,
496             _postfilter_ => $i++,
497             _prefilter_ => $i++,
498             _rOpts_ => $i++,
499             _saw_pbp_ => $i++,
500             _tabsize_ => $i++,
501             _teefile_stream_ => $i++,
502             _user_formatter_ => $i++,
503             _input_copied_verbatim_ => $i++,
504             _input_output_difference_ => $i++,
505 39     39   457 };
  39         130  
506             } ## end BEGIN
507              
508             sub perltidy {
509              
510 559     559 0 615206 my %input_hash = @_;
511              
512 559         7476 my %defaults = (
513             argv => undef,
514             destination => undef,
515             formatter => undef,
516             logfile => undef,
517             errorfile => undef,
518             teefile => undef,
519             debugfile => undef,
520             perltidyrc => undef,
521             source => undef,
522             stderr => undef,
523             dump_options => undef,
524             dump_options_type => undef,
525             dump_getopt_flags => undef,
526             dump_options_category => undef,
527             dump_options_range => undef,
528             dump_abbreviations => undef,
529             prefilter => undef,
530             postfilter => undef,
531             );
532              
533             # Status information which can be returned for diagnostic purposes.
534             # NOTE: This is intended only for testing and subject to change.
535              
536             # List of "key => value" hash entries:
537              
538             # Some relevant user input parameters for convenience:
539             # opt_format => value of --format: 'tidy', 'html', or 'user'
540             # opt_encoding => value of -enc flag: 'utf8', 'none', or 'guess'
541             # opt_encode_output => value of -eos flag: 'eos' or 'neos'
542             # opt_max_iterations => value of --iterations=n
543              
544             # file_count => number of files processed in this call
545              
546             # If multiple files are processed, then the following values will be for
547             # the last file only:
548              
549             # input_name => name of the input stream
550             # output_name => name of the output stream
551              
552             # The following two variables refer to Perl's two internal string modes,
553             # and have the values 0 for 'byte' mode and 1 for 'char' mode:
554             # char_mode_source => true if source is in 'char' mode. Will be false
555             # unless we received a source string ref with utf8::is_utf8() set.
556             # char_mode_used => true if text processed by perltidy in 'char' mode.
557             # Normally true for text identified as utf8, otherwise false.
558              
559             # This tells if Unicode::GCString was used
560             # gcs_used => true if -gcs and Unicode::GCString found & used
561              
562             # These variables tell what utf8 decoding/encoding was done:
563             # input_decoded_as => non-blank if perltidy decoded the source text
564             # output_encoded_as => non-blank if perltidy encoded before return
565              
566             # These variables are related to iterations and convergence testing:
567             # iteration_count => number of iterations done
568             # ( can be from 1 to opt_max_iterations )
569             # converged => true if stopped on convergence
570             # ( can only happen if opt_max_iterations > 1 )
571             # blinking => true if stopped on blinking states
572             # ( i.e., unstable formatting, should not happen )
573              
574 559         10352 $rstatus = {
575              
576             file_count => 0,
577             opt_format => EMPTY_STRING,
578             opt_encoding => EMPTY_STRING,
579             opt_encode_output => EMPTY_STRING,
580             opt_max_iterations => EMPTY_STRING,
581              
582             input_name => EMPTY_STRING,
583             output_name => EMPTY_STRING,
584             char_mode_source => 0,
585             char_mode_used => 0,
586             input_decoded_as => EMPTY_STRING,
587             output_encoded_as => EMPTY_STRING,
588             gcs_used => 0,
589             iteration_count => 0,
590             converged => 0,
591             blinking => 0,
592             };
593              
594             # Fix for issue git #57
595 559         1504 $Warn_count = 0;
596              
597             # don't overwrite callers ARGV
598             # Localization of @ARGV could be avoided by calling GetOptionsFromArray
599             # instead of GetOptions, but that is not available before perl 5.10
600 559         2070 local @ARGV = @ARGV;
601 559         1574 local *STDERR = *STDERR;
602              
603 559 50       2564 if ( my @bad_keys = grep { !exists $defaults{$_} } keys %input_hash ) {
  3321         8567  
604 0         0 local $LIST_SEPARATOR = ')(';
605 0         0 my @good_keys = sort keys %defaults;
606 0         0 @bad_keys = sort @bad_keys;
607 0         0 confess <<EOM;
608             ------------------------------------------------------------------------
609             Unknown perltidy parameter : (@bad_keys)
610             perltidy only understands : (@good_keys)
611             ------------------------------------------------------------------------
612              
613             EOM
614             }
615              
616             my $get_hash_ref = sub {
617 2795     2795   4994 my ($key) = @_;
618 2795         4376 my $hash_ref = $input_hash{$key};
619 2795 50       5169 if ( defined($hash_ref) ) {
620 0 0       0 if ( ref($hash_ref) ne 'HASH' ) {
621 0         0 my $what = ref($hash_ref);
622 0 0       0 my $but_is =
623             $what ? "but is ref to $what" : "but is not a reference";
624 0         0 croak <<EOM;
625             ------------------------------------------------------------------------
626             error in call to perltidy:
627             -$key must be reference to HASH $but_is
628             ------------------------------------------------------------------------
629             EOM
630             }
631             }
632 2795         4609 return $hash_ref;
633 559         3949 };
634              
635 559         6240 %input_hash = ( %defaults, %input_hash );
636 559         2250 my $argv = $input_hash{'argv'};
637 559         1371 my $destination_stream = $input_hash{'destination'};
638 559         1328 my $errorfile_stream = $input_hash{'errorfile'};
639 559         1307 my $logfile_stream = $input_hash{'logfile'};
640 559         1215 my $teefile_stream = $input_hash{'teefile'};
641 559         1271 my $debugfile_stream = $input_hash{'debugfile'};
642 559         1304 my $perltidyrc_stream = $input_hash{'perltidyrc'};
643 559         1218 my $source_stream = $input_hash{'source'};
644 559         1104 my $stderr_stream = $input_hash{'stderr'};
645 559         1093 my $user_formatter = $input_hash{'formatter'};
646 559         1063 my $prefilter = $input_hash{'prefilter'};
647 559         1146 my $postfilter = $input_hash{'postfilter'};
648              
649 559 100       1796 if ($stderr_stream) {
650 543         2656 ( $fh_stderr, my $stderr_file ) =
651             Perl::Tidy::streamhandle( $stderr_stream, 'w' );
652 543 50       2705 if ( !$fh_stderr ) {
653 0         0 croak <<EOM;
654             ------------------------------------------------------------------------
655             Unable to redirect STDERR to $stderr_stream
656             Please check value of -stderr in call to perltidy
657             ------------------------------------------------------------------------
658             EOM
659             }
660             }
661             else {
662 16         69 $fh_stderr = *STDERR;
663             }
664              
665 559         1261 my $self = [];
666 559         1579 bless $self, __PACKAGE__;
667              
668             sub Exit {
669 0     0 0 0 my $flag = shift;
670 0 0       0 if ($flag) { goto ERROR_EXIT }
  0         0  
671 0         0 else { goto NORMAL_EXIT }
672 0         0 croak "unexpectd return to Exit";
673             } ## end sub Exit
674              
675             sub Die {
676 0     0 0 0 my $msg = shift;
677 0         0 Warn($msg);
678 0         0 Exit(1);
679 0         0 croak "unexpected return to Die";
680             } ## end sub Die
681              
682             sub Fault {
683 0     0 0 0 my ($msg) = @_;
684              
685             # This routine is called for errors that really should not occur
686             # except if there has been a bug introduced by a recent program change.
687             # Please add comments at calls to Fault to explain why the call
688             # should not occur, and where to look to fix it.
689 0         0 my ( $package0, $filename0, $line0, $subroutine0 ) = caller(0);
690 0         0 my ( $package1, $filename1, $line1, $subroutine1 ) = caller(1);
691 0         0 my ( $package2, $filename2, $line2, $subroutine2 ) = caller(2);
692 0         0 my $pkg = __PACKAGE__;
693              
694 0         0 my $input_stream_name = $rstatus->{'input_name'};
695 0 0       0 $input_stream_name = '(unknown)' unless ($input_stream_name);
696 0         0 Die(<<EOM);
697             ==============================================================================
698             While operating on input stream with name: '$input_stream_name'
699             A fault was detected at line $line0 of sub '$subroutine1'
700             in file '$filename1'
701             which was called from line $line1 of sub '$subroutine2'
702             Message: '$msg'
703             This is probably an error introduced by a recent programming change.
704             $pkg reports VERSION='$VERSION'.
705             ==============================================================================
706             EOM
707              
708             # This return is to keep Perl-Critic from complaining.
709 0         0 return;
710             } ## end sub Fault
711              
712             # extract various dump parameters
713 559         1301 my $dump_options_type = $input_hash{'dump_options_type'};
714 559         1695 my $dump_options = $get_hash_ref->('dump_options');
715 559         1563 my $dump_getopt_flags = $get_hash_ref->('dump_getopt_flags');
716 559         1570 my $dump_options_category = $get_hash_ref->('dump_options_category');
717 559         1394 my $dump_abbreviations = $get_hash_ref->('dump_abbreviations');
718 559         1511 my $dump_options_range = $get_hash_ref->('dump_options_range');
719              
720             # validate dump_options_type
721 559 50       1944 if ( defined($dump_options) ) {
722 0 0       0 if ( !defined($dump_options_type) ) {
723 0         0 $dump_options_type = 'perltidyrc';
724             }
725 0 0 0     0 if ( $dump_options_type ne 'perltidyrc'
726             && $dump_options_type ne 'full' )
727             {
728 0         0 croak <<EOM;
729             ------------------------------------------------------------------------
730             Please check value of -dump_options_type in call to perltidy;
731             saw: '$dump_options_type'
732             expecting: 'perltidyrc' or 'full'
733             ------------------------------------------------------------------------
734             EOM
735              
736             }
737             }
738             else {
739 559         1231 $dump_options_type = EMPTY_STRING;
740             }
741              
742 559 50       1784 if ($user_formatter) {
743              
744             # if the user defines a formatter, there is no output stream,
745             # but we need a null stream to keep coding simple
746 0         0 $destination_stream = \my $tmp;
747             }
748              
749             # see if ARGV is overridden
750 559 50       1880 if ( defined($argv) ) {
751              
752 559         1509 my $rargv = ref $argv;
753 559 50       1967 if ( $rargv eq 'SCALAR' ) { $argv = ${$argv}; $rargv = undef }
  0         0  
  0         0  
  0         0  
754              
755             # ref to ARRAY
756 559 50       1620 if ($rargv) {
757 0 0       0 if ( $rargv eq 'ARRAY' ) {
758 0         0 @ARGV = @{$argv};
  0         0  
759             }
760             else {
761 0         0 croak <<EOM;
762             ------------------------------------------------------------------------
763             Please check value of -argv in call to perltidy;
764             it must be a string or ref to ARRAY but is: $rargv
765             ------------------------------------------------------------------------
766             EOM
767             }
768             }
769              
770             # string
771             else {
772 559         2501 my ( $rargv_str, $msg ) = parse_args($argv);
773 559 50       1979 if ($msg) {
774 0         0 Die(<<EOM);
775             Error parsing this string passed to to perltidy with 'argv':
776             $msg
777             EOM
778             }
779 559         1283 @ARGV = @{$rargv_str};
  559         2034  
780             }
781             }
782              
783             # These string refs will hold any warnings and error messages to be written
784             # to the logfile object when it eventually gets created.
785 559         1110 my $rpending_complaint;
786 559         1263 ${$rpending_complaint} = EMPTY_STRING;
  559         1283  
787              
788 559         1051 my $rpending_logfile_message;
789 559         999 ${$rpending_logfile_message} = EMPTY_STRING;
  559         1197  
790              
791 559         2663 my ( $is_Windows, $Windows_type ) = look_for_Windows($rpending_complaint);
792              
793             # VMS file names are restricted to a 40.40 format, so we append _tdy
794             # instead of .tdy, etc. (but see also sub check_vms_filename)
795 559         1413 my $dot;
796             my $dot_pattern;
797 559 50       2177 if ( $OSNAME eq 'VMS' ) {
798 0         0 $dot = '_';
799 0         0 $dot_pattern = '_';
800             }
801             else {
802 559         1213 $dot = '.';
803 559         1177 $dot_pattern = '\.'; # must escape for use in regex
804             }
805 559         1794 $self->[_file_extension_separator_] = $dot;
806              
807             #-------------------------
808             # get command line options
809             #-------------------------
810 559         2595 my ( $rOpts, $config_file, $rraw_options, $roption_string,
811             $rexpansion, $roption_category, $roption_range )
812             = process_command_line(
813             $perltidyrc_stream, $is_Windows, $Windows_type,
814             $rpending_complaint, $dump_options_type,
815             );
816              
817             # Only filenames should remain in @ARGV
818 559         2492 my @Arg_files = @ARGV;
819              
820 559         3122 $self->[_rOpts_] = $rOpts;
821              
822             my $saw_pbp =
823 559 100       1796 grep { $_ eq '-pbp' || $_ eq '-perl-best-practices' } @{$rraw_options};
  564         3361  
  559         2186  
824 559         1978 $self->[_saw_pbp_] = $saw_pbp;
825              
826             #------------------------------------
827             # Handle requests to dump information
828             #------------------------------------
829              
830             # return or exit immediately after all dumps
831 559         1642 my $quit_now = 0;
832              
833             # Getopt parameters and their flags
834 559 50       2654 if ( defined($dump_getopt_flags) ) {
835 0         0 $quit_now = 1;
836 0         0 foreach my $op ( @{$roption_string} ) {
  0         0  
837 0         0 my $opt = $op;
838 0         0 my $flag = EMPTY_STRING;
839              
840             # Examples:
841             # some-option=s
842             # some-option=i
843             # some-option:i
844             # some-option!
845 0 0       0 if ( $opt =~ /(.*)(!|=.*|:.*)$/ ) {
846 0         0 $opt = $1;
847 0         0 $flag = $2;
848             }
849 0         0 $dump_getopt_flags->{$opt} = $flag;
850             }
851             }
852              
853 559 50       2487 if ( defined($dump_options_category) ) {
854 0         0 $quit_now = 1;
855 0         0 %{$dump_options_category} = %{$roption_category};
  0         0  
  0         0  
856             }
857              
858 559 50       2528 if ( defined($dump_options_range) ) {
859 0         0 $quit_now = 1;
860 0         0 %{$dump_options_range} = %{$roption_range};
  0         0  
  0         0  
861             }
862              
863 559 50       2358 if ( defined($dump_abbreviations) ) {
864 0         0 $quit_now = 1;
865 0         0 %{$dump_abbreviations} = %{$rexpansion};
  0         0  
  0         0  
866             }
867              
868 559 50       2257 if ( defined($dump_options) ) {
869 0         0 $quit_now = 1;
870 0         0 %{$dump_options} = %{$rOpts};
  0         0  
  0         0  
871             }
872              
873 559 50       2077 Exit(0) if ($quit_now);
874              
875             # make printable string of options for this run as possible diagnostic
876 559         3224 my $readable_options = readable_options( $rOpts, $roption_string );
877              
878             # dump from command line
879 559 50       4372 if ( $rOpts->{'dump-options'} ) {
880 0         0 print {*STDOUT} $readable_options;
  0         0  
881 0         0 Exit(0);
882             }
883              
884             # --dump-block-summary requires one filename in the arg list.
885             # This is a safety precaution in case a user accidentally adds -dbs to the
886             # command line parameters and is expecting formatted output to stdout.
887             # Another precaution, added elsewhere, is to ignore -dbs in a .perltidyrc
888 559         1934 my $num_files = @Arg_files;
889 559 50 33     3456 if ( $rOpts->{'dump-block-summary'} && $num_files != 1 ) {
890 0         0 Die(<<EOM);
891             --dump-block-summary expects 1 filename in the arg list but saw $num_files filenames
892             EOM
893             }
894              
895             #----------------------------------------
896             # check parameters and their interactions
897             #----------------------------------------
898 559         4749 $self->check_options( $is_Windows, $Windows_type, $rpending_complaint,
899             $num_files );
900              
901 559 50       2522 if ($user_formatter) {
902 0         0 $rOpts->{'format'} = 'user';
903             }
904              
905             # there must be one entry here for every possible format
906 559         3924 my %default_file_extension = (
907             tidy => 'tdy',
908             html => 'html',
909             user => EMPTY_STRING,
910             );
911              
912 559         2486 $rstatus->{'opt_format'} = $rOpts->{'format'};
913 559         1903 $rstatus->{'opt_max_iterations'} = $rOpts->{'iterations'};
914             $rstatus->{'opt_encode_output'} =
915 559 50       2691 $rOpts->{'encode-output-strings'} ? 'eos' : 'neos';
916              
917             # be sure we have a valid output format
918 559 50       2844 if ( !exists $default_file_extension{ $rOpts->{'format'} } ) {
919             my $formats = join SPACE,
920 0         0 sort map { "'" . $_ . "'" } keys %default_file_extension;
  0         0  
921 0         0 my $fmt = $rOpts->{'format'};
922 0         0 Die("-format='$fmt' but must be one of: $formats\n");
923             }
924              
925             my $output_extension =
926             $self->make_file_extension( $rOpts->{'output-file-extension'},
927 559         4553 $default_file_extension{ $rOpts->{'format'} } );
928              
929             # get parameters associated with the -b option
930 559         3682 my ( $in_place_modify, $backup_extension, $delete_backup ) =
931             $self->check_in_place_modify( $source_stream, $destination_stream );
932              
933 559         5098 Perl::Tidy::Formatter::check_options($rOpts);
934 559         4118 Perl::Tidy::Tokenizer::check_options($rOpts);
935 559         5340 Perl::Tidy::VerticalAligner::check_options($rOpts);
936 559 100       2441 if ( $rOpts->{'format'} eq 'html' ) {
937 1         8 Perl::Tidy::HtmlWriter->check_options($rOpts);
938             }
939              
940             # make the pattern of file extensions that we shouldn't touch
941 559         2593 my $forbidden_file_extensions = "(($dot_pattern)(LOG|DEBUG|ERR|TEE)";
942 559 50       2067 if ($output_extension) {
943 559         1641 my $ext = quotemeta($output_extension);
944 559         1717 $forbidden_file_extensions .= "|$ext";
945             }
946 559 50 33     2427 if ( $in_place_modify && $backup_extension ) {
947 0         0 my $ext = quotemeta($backup_extension);
948 0         0 $forbidden_file_extensions .= "|$ext";
949             }
950 559         1338 $forbidden_file_extensions .= ')$';
951              
952             # Create a diagnostics object if requested;
953             # This is only useful for code development
954 559         1183 my $diagnostics_object = undef;
955 559         1050 if (DIAGNOSTICS) {
956             $diagnostics_object = Perl::Tidy::Diagnostics->new();
957             }
958              
959             # no filenames should be given if input is from an array
960 559 50       2023 if ($source_stream) {
961 559 50       2171 if ( @Arg_files > 0 ) {
962 0         0 Die(
963             "You may not specify any filenames when a source array is given\n"
964             );
965             }
966              
967             # we'll stuff the source array into Arg_files
968 559         1638 unshift( @Arg_files, $source_stream );
969              
970             # No special treatment for source stream which is a filename.
971             # This will enable checks for binary files and other bad stuff.
972 559 100       2231 $source_stream = undef unless ref($source_stream);
973             }
974              
975             # use stdin by default if no source array and no args
976             else {
977 0 0       0 unshift( @Arg_files, '-' ) unless @Arg_files;
978             }
979              
980             # Flag for loading module Unicode::GCString for evaluating text width:
981             # undef = ok to use but not yet loaded
982             # 0 = do not use; failed to load or not wanted
983             # 1 = successfully loaded and ok to use
984             # The module is not actually loaded unless/until it is needed
985 559 50       2154 if ( !$rOpts->{'use-unicode-gcstring'} ) {
986 559         1283 $loaded_unicode_gcstring = 0;
987             }
988              
989             # Remove duplicate filenames. Otherwise, for example if the user entered
990             # perltidy -b myfile.pl myfile.pl
991             # the backup version of the original would be lost.
992 559 50       2296 if ( @Arg_files > 1 ) {
993 0         0 my %seen = ();
994 0         0 @Arg_files = grep { !$seen{$_}++ } @Arg_files;
  0         0  
995             }
996              
997             # If requested, process in order of increasing file size
998             # This can significantly reduce perl's virtual memory usage during testing.
999 559 0 33     2264 if ( @Arg_files > 1 && $rOpts->{'file-size-order'} ) {
1000             @Arg_files =
1001 0         0 map { $_->[0] }
1002 0         0 sort { $a->[1] <=> $b->[1] }
1003 0 0       0 map { [ $_, -e $_ ? -s $_ : 0 ] } @Arg_files;
  0         0  
1004             }
1005              
1006 559         3053 my $logfile_header = make_logfile_header( $rOpts, $config_file,
1007             $rraw_options, $Windows_type, $readable_options, );
1008              
1009             # Store some values needed by lower level routines
1010 559         1706 $self->[_diagnostics_object_] = $diagnostics_object;
1011 559         1535 $self->[_postfilter_] = $postfilter;
1012 559         1399 $self->[_prefilter_] = $prefilter;
1013 559         1372 $self->[_user_formatter_] = $user_formatter;
1014              
1015             #--------------------------
1016             # loop to process all files
1017             #--------------------------
1018 559         4361 $self->process_all_files(
1019              
1020             \%input_hash,
1021             \@Arg_files,
1022              
1023             # filename stuff...
1024             $source_stream,
1025             $output_extension,
1026             $forbidden_file_extensions,
1027             $in_place_modify,
1028             $backup_extension,
1029             $delete_backup,
1030              
1031             # logfile stuff...
1032             $logfile_header,
1033             $rpending_complaint,
1034             $rpending_logfile_message,
1035              
1036             );
1037              
1038             #-----
1039             # Exit
1040             #-----
1041              
1042             # Fix for RT #130297: return a true value if anything was written to the
1043             # standard error output, even non-fatal warning messages, otherwise return
1044             # false.
1045              
1046             # These exit codes are returned:
1047             # 0 = perltidy ran to completion with no errors
1048             # 1 = perltidy could not run to completion due to errors
1049             # 2 = perltidy ran to completion with error messages
1050              
1051             # Note that if perltidy is run with multiple files, any single file with
1052             # errors or warnings will write a line like
1053             # '## Please see file testing.t.ERR'
1054             # to standard output for each file with errors, so the flag will be true,
1055             # even if only some of the multiple files may have had errors.
1056              
1057 559 50       2154 NORMAL_EXIT:
1058             my $ret = $Warn_count ? 2 : 0;
1059 559 50       434948 return wantarray ? ( $ret, $rstatus ) : $ret;
1060              
1061 0 0       0 ERROR_EXIT:
1062             return wantarray ? ( 1, $rstatus ) : 1;
1063              
1064             } ## end sub perltidy
1065              
1066             sub make_file_extension {
1067              
1068             # Make a file extension, adding any leading '.' if necessary.
1069             # (the '.' may actually be an '_' under VMS).
1070 561     561 0 3121 my ( $self, $extension, $default ) = @_;
1071              
1072             # '$extension' is the first choice (usually a user entry)
1073             # '$default' is a backup extension
1074              
1075 561 50       2810 $extension = EMPTY_STRING unless defined($extension);
1076 561         6794 $extension =~ s/^\s+//;
1077 561         1527 $extension =~ s/\s+$//;
1078              
1079             # Use default extension if nothing remains of the first choice
1080             #
1081 561 50       2724 if ( length($extension) == 0 ) {
1082 561         1457 $extension = $default;
1083 561 50       2112 $extension = EMPTY_STRING unless defined($extension);
1084 561         2205 $extension =~ s/^\s+//;
1085 561         2299 $extension =~ s/\s+$//;
1086             }
1087              
1088             # Only extensions with these leading characters get a '.'
1089             # This rule gives the user some freedom.
1090 561 50       3235 if ( $extension =~ /^[a-zA-Z0-9]/ ) {
1091 561         1797 my $dot = $self->[_file_extension_separator_];
1092 561         1898 $extension = $dot . $extension;
1093             }
1094 561         2182 return $extension;
1095             } ## end sub make_file_extension
1096              
1097             sub check_in_place_modify {
1098              
1099 559     559 0 2140 my ( $self, $source_stream, $destination_stream ) = @_;
1100              
1101             # get parameters associated with the -b option
1102 559         1537 my $rOpts = $self->[_rOpts_];
1103              
1104             # check for -b option;
1105             # silently ignore unless beautify mode
1106             my $in_place_modify = $rOpts->{'backup-and-modify-in-place'}
1107 559   66     2360 && $rOpts->{'format'} eq 'tidy';
1108              
1109 559         1425 my ( $backup_extension, $delete_backup );
1110              
1111             # Turn off -b with warnings in case of conflicts with other options.
1112             # NOTE: Do this silently, without warnings, if there is a source or
1113             # destination stream, or standard output is used. This is because the -b
1114             # flag may have been in a .perltidyrc file and warnings break
1115             # Test::NoWarnings. See email discussion with Merijn Brand 26 Feb 2014.
1116 559 100       2194 if ($in_place_modify) {
1117 2 0 33     16 if ( $rOpts->{'standard-output'}
      33        
      33        
      0        
1118             || $destination_stream
1119             || ref $source_stream
1120             || $rOpts->{'outfile'}
1121             || defined( $rOpts->{'output-path'} ) )
1122             {
1123 2         6 $in_place_modify = 0;
1124             }
1125             }
1126              
1127 559 50       2266 if ($in_place_modify) {
1128              
1129             # If the backup extension contains a / character then the backup should
1130             # be deleted when the -b option is used. On older versions of
1131             # perltidy this will generate an error message due to an illegal
1132             # file name.
1133             #
1134             # A backup file will still be generated but will be deleted
1135             # at the end. If -bext='/' then this extension will be
1136             # the default 'bak'. Otherwise it will be whatever characters
1137             # remains after all '/' characters are removed. For example:
1138             # -bext extension slashes
1139             # '/' bak 1
1140             # '/delete' delete 1
1141             # 'delete/' delete 1
1142             # '/dev/null' devnull 2 (Currently not allowed)
1143 0         0 my $bext = $rOpts->{'backup-file-extension'};
1144 0         0 $delete_backup = ( $rOpts->{'backup-file-extension'} =~ s/\///g );
1145              
1146             # At present only one forward slash is allowed. In the future multiple
1147             # slashes may be allowed to allow for other options
1148 0 0       0 if ( $delete_backup > 1 ) {
1149 0         0 Die("-bext=$bext contains more than one '/'\n");
1150             }
1151              
1152             $backup_extension =
1153 0         0 $self->make_file_extension( $rOpts->{'backup-file-extension'},
1154             'bak' );
1155             }
1156              
1157 559         1871 my $backup_method = $rOpts->{'backup-method'};
1158 559 50 33     5000 if ( defined($backup_method)
      33        
1159             && $backup_method ne 'copy'
1160             && $backup_method ne 'move' )
1161             {
1162 0         0 Die(
1163             "Unexpected --backup-method='$backup_method'; must be one of: 'move', 'copy'\n"
1164             );
1165             }
1166              
1167 559         2256 return ( $in_place_modify, $backup_extension, $delete_backup );
1168             } ## end sub check_in_place_modify
1169              
1170             sub backup_method_copy {
1171              
1172 0     0 0 0 my ( $self, $input_file, $routput_string, $backup_extension,
1173             $delete_backup )
1174             = @_;
1175              
1176             # Handle the -b (--backup-and-modify-in-place) option with -bm='copy':
1177             # - First copy $input file to $backup_name.
1178             # - Then open input file and rewrite with contents of $routput_string
1179             # - Then delete the backup if requested
1180              
1181             # NOTES:
1182             # - Die immediately on any error.
1183             # - $routput_string is a SCALAR ref
1184              
1185 0         0 my $backup_file = $input_file . $backup_extension;
1186              
1187 0 0       0 if ( !-f $input_file ) {
1188              
1189             # no real file to backup ..
1190             # This shouldn't happen because of numerous preliminary checks
1191 0         0 Die(
1192             "problem with -b backing up input file '$input_file': not a file\n"
1193             );
1194             }
1195              
1196 0 0       0 if ( -f $backup_file ) {
1197 0 0       0 unlink($backup_file)
1198             or Die(
1199             "unable to remove previous '$backup_file' for -b option; check permissions: $OS_ERROR\n"
1200             );
1201             }
1202              
1203             # Copy input file to backup
1204 0 0       0 File::Copy::copy( $input_file, $backup_file )
1205             or Die("File::Copy failed trying to backup source: $OS_ERROR");
1206              
1207             # set permissions of the backup file to match the input file
1208 0         0 my @input_file_stat = stat($input_file);
1209 0         0 my $in_place_modify = 1;
1210 0         0 $self->set_output_file_permissions( $backup_file, \@input_file_stat,
1211             $in_place_modify );
1212              
1213             # set the modification time of the copy to the original value (rt#145999)
1214 0         0 my ( $read_time, $write_time ) = @input_file_stat[ 8, 9 ];
1215 0 0       0 if ( defined($write_time) ) {
1216 0 0       0 utime( $read_time, $write_time, $backup_file )
1217             || Warn("error setting times for backup file '$backup_file'\n");
1218             }
1219              
1220             # Open the original input file for writing ... opening with ">" will
1221             # truncate the existing data.
1222 0 0       0 open( my $fout, ">", $input_file )
1223             || Die(
1224             "problem re-opening $input_file for write for -b option; check file and directory permissions: $OS_ERROR\n"
1225             );
1226              
1227 0 0       0 if ( $self->[_is_encoded_data_] ) {
1228 0         0 binmode $fout, ":raw:encoding(UTF-8)";
1229             }
1230              
1231             # Now copy the formatted output to it..
1232             # output must be SCALAR ref..
1233 0 0       0 if ( ref($routput_string) eq 'SCALAR' ) {
1234 0 0       0 $fout->print( ${$routput_string} )
  0         0  
1235             or Die("cannot print to '$input_file' with -b option: $OS_ERROR\n");
1236             }
1237              
1238             # Error if anything else ...
1239             else {
1240 0         0 my $ref = ref($routput_string);
1241 0         0 Die(<<EOM);
1242             Programming error: unable to print to '$input_file' with -b option:
1243             unexpected ref type '$ref'; expecting 'ARRAY' or 'SCALAR'
1244             EOM
1245             }
1246              
1247 0 0       0 $fout->close()
1248             or Die("cannot close '$input_file' with -b option: $OS_ERROR\n");
1249              
1250             # Set permissions of the output file to match the input file. This is
1251             # necessary even if the inode remains unchanged because suid/sgid bits may
1252             # have been reset.
1253 0         0 $self->set_output_file_permissions( $input_file, \@input_file_stat,
1254             $in_place_modify );
1255              
1256             # Keep original modification time if no change (rt#145999)
1257 0 0 0     0 if ( !$self->[_input_output_difference_] && defined($write_time) ) {
1258 0 0       0 utime( $read_time, $write_time, $input_file )
1259             || Warn("error setting times for '$input_file'\n");
1260             }
1261              
1262             #---------------------------------------------------------
1263             # remove the original file for in-place modify as follows:
1264             # $delete_backup=0 never
1265             # $delete_backup=1 only if no errors
1266             # $delete_backup>1 always : NOT ALLOWED, too risky
1267             #---------------------------------------------------------
1268 0 0 0     0 if ( $delete_backup && -f $backup_file ) {
1269              
1270             # Currently, $delete_backup may only be 1. But if a future update
1271             # allows a value > 1, then reduce it to 1 if there were warnings.
1272 0 0 0     0 if ( $delete_backup > 1
1273             && $self->[_logger_object_]->get_warning_count() )
1274             {
1275 0         0 $delete_backup = 1;
1276             }
1277              
1278             # As an added safety precaution, do not delete the source file
1279             # if its size has dropped from positive to zero, since this
1280             # could indicate a disaster of some kind, including a hardware
1281             # failure. Actually, this could happen if you had a file of
1282             # all comments (or pod) and deleted everything with -dac (-dap)
1283             # for some reason.
1284 0 0 0     0 if ( !-s $input_file && -s $backup_file && $delete_backup == 1 ) {
      0        
1285 0         0 Warn(
1286             "output file '$input_file' missing or zero length; original '$backup_file' not deleted\n"
1287             );
1288             }
1289             else {
1290 0 0       0 unlink($backup_file)
1291             or Die(
1292             "unable to remove backup file '$backup_file' for -b option; check permissions: $OS_ERROR\n"
1293             );
1294             }
1295             }
1296              
1297             # Verify that inode is unchanged during development
1298 0         0 if (DEVEL_MODE) {
1299             my @output_file_stat = stat($input_file);
1300             my $inode_input = $input_file_stat[1];
1301             my $inode_output = $output_file_stat[1];
1302             if ( $inode_input != $inode_output ) {
1303             Fault(<<EOM);
1304             inode changed with -bm=copy for file '$input_file': inode_input=$inode_input inode_output=$inode_output
1305             EOM
1306             }
1307             }
1308              
1309 0         0 return;
1310             } ## end sub backup_method_copy
1311              
1312             sub backup_method_move {
1313              
1314 0     0 0 0 my ( $self, $input_file, $routput_string, $backup_extension,
1315             $delete_backup )
1316             = @_;
1317              
1318             # Handle the -b (--backup-and-modify-in-place) option with -bm='move':
1319             # - First move $input file to $backup_name.
1320             # - Then copy $routput_string to $input_file.
1321             # - Then delete the backup if requested
1322              
1323             # NOTES:
1324             # - Die immediately on any error.
1325             # - $routput_string is a SCALAR ref
1326             # - $input_file permissions will be set by sub set_output_file_permissions
1327              
1328 0         0 my $backup_name = $input_file . $backup_extension;
1329              
1330 0 0       0 if ( !-f $input_file ) {
1331              
1332             # oh, oh, no real file to backup ..
1333             # shouldn't happen because of numerous preliminary checks
1334 0         0 Die(
1335             "problem with -b backing up input file '$input_file': not a file\n"
1336             );
1337             }
1338 0 0       0 if ( -f $backup_name ) {
1339 0 0       0 unlink($backup_name)
1340             or Die(
1341             "unable to remove previous '$backup_name' for -b option; check permissions: $OS_ERROR\n"
1342             );
1343             }
1344              
1345 0         0 my @input_file_stat = stat($input_file);
1346              
1347             # backup the input file
1348             # we use copy for symlinks, move for regular files
1349 0 0       0 if ( -l $input_file ) {
1350 0 0       0 File::Copy::copy( $input_file, $backup_name )
1351             or Die("File::Copy failed trying to backup source: $OS_ERROR");
1352             }
1353             else {
1354 0 0       0 rename( $input_file, $backup_name )
1355             or Die(
1356             "problem renaming $input_file to $backup_name for -b option: $OS_ERROR\n"
1357             );
1358             }
1359              
1360             # Open a file with the original input file name for writing ...
1361 0         0 my $is_encoded_data = $self->[_is_encoded_data_];
1362 0         0 my ( $fout, $iname ) =
1363             Perl::Tidy::streamhandle( $input_file, 'w', $is_encoded_data );
1364 0 0       0 if ( !$fout ) {
1365 0         0 Die(
1366             "problem re-opening $input_file for write for -b option; check file and directory permissions: $OS_ERROR\n"
1367             );
1368             }
1369              
1370             # Now copy the formatted output to it..
1371             # output must be SCALAR ref..
1372 0 0       0 if ( ref($routput_string) eq 'SCALAR' ) {
1373 0 0       0 $fout->print( ${$routput_string} )
  0         0  
1374             or Die("cannot print to '$input_file' with -b option: $OS_ERROR\n");
1375             }
1376              
1377             # Error if anything else ...
1378             else {
1379 0         0 my $ref = ref($routput_string);
1380 0         0 Die(<<EOM);
1381             Programming error: unable to print to '$input_file' with -b option:
1382             unexpected ref type '$ref'; expecting 'ARRAY' or 'SCALAR'
1383             EOM
1384             }
1385              
1386 0 0       0 $fout->close()
1387             or Die("cannot close '$input_file' with -b option: $OS_ERROR\n");
1388              
1389             # set permissions of the output file to match the input file
1390 0         0 my $in_place_modify = 1;
1391 0         0 $self->set_output_file_permissions( $input_file, \@input_file_stat,
1392             $in_place_modify );
1393              
1394             # Keep original modification time if no change (rt#145999)
1395 0         0 my ( $read_time, $write_time ) = @input_file_stat[ 8, 9 ];
1396 0 0 0     0 if ( !$self->[_input_output_difference_] && defined($write_time) ) {
1397 0 0       0 utime( $read_time, $write_time, $input_file )
1398             || Warn("error setting times for '$input_file'\n");
1399             }
1400              
1401             #---------------------------------------------------------
1402             # remove the original file for in-place modify as follows:
1403             # $delete_backup=0 never
1404             # $delete_backup=1 only if no errors
1405             # $delete_backup>1 always : NOT ALLOWED, too risky
1406             #---------------------------------------------------------
1407 0 0 0     0 if ( $delete_backup && -f $backup_name ) {
1408              
1409             # Currently, $delete_backup may only be 1. But if a future update
1410             # allows a value > 1, then reduce it to 1 if there were warnings.
1411 0 0 0     0 if ( $delete_backup > 1
1412             && $self->[_logger_object_]->get_warning_count() )
1413             {
1414 0         0 $delete_backup = 1;
1415             }
1416              
1417             # As an added safety precaution, do not delete the source file
1418             # if its size has dropped from positive to zero, since this
1419             # could indicate a disaster of some kind, including a hardware
1420             # failure. Actually, this could happen if you had a file of
1421             # all comments (or pod) and deleted everything with -dac (-dap)
1422             # for some reason.
1423 0 0 0     0 if ( !-s $input_file && -s $backup_name && $delete_backup == 1 ) {
      0        
1424 0         0 Warn(
1425             "output file '$input_file' missing or zero length; original '$backup_name' not deleted\n"
1426             );
1427             }
1428             else {
1429 0 0       0 unlink($backup_name)
1430             or Die(
1431             "unable to remove previous '$backup_name' for -b option; check permissions: $OS_ERROR\n"
1432             );
1433             }
1434             }
1435              
1436 0         0 return;
1437              
1438             } ## end sub backup_method_move
1439              
1440             sub set_output_file_permissions {
1441              
1442 2     2 0 9 my ( $self, $output_file, $rinput_file_stat, $in_place_modify ) = @_;
1443              
1444             # Given:
1445             # $output_file = the file whose permissions we will set
1446             # $rinput_file_stat = the result of stat($input_file)
1447             # $in_place_modify = true if --backup-and-modify-in-place is set
1448              
1449 2         5 my ( $mode_i, $uid_i, $gid_i ) = @{$rinput_file_stat}[ 2, 4, 5 ];
  2         6  
1450 2         26 my ( $uid_o, $gid_o ) = ( stat($output_file) )[ 4, 5 ];
1451 2         9 my $input_file_permissions = $mode_i & oct(7777);
1452 2         4 my $output_file_permissions = $input_file_permissions;
1453              
1454             #rt128477: avoid inconsistent owner/group and suid/sgid
1455 2 50 33     9 if ( $uid_i != $uid_o || $gid_i != $gid_o ) {
1456              
1457             # try to change owner and group to match input file if
1458             # in -b mode. Note: chown returns number of files
1459             # successfully changed.
1460 2 50 33     10 if ( $in_place_modify
1461             && chown( $uid_i, $gid_i, $output_file ) )
1462             {
1463             # owner/group successfully changed
1464             }
1465             else {
1466              
1467             # owner or group differ: do not copy suid and sgid
1468 2         8 $output_file_permissions = $mode_i & oct(777);
1469 2 50       7 if ( $input_file_permissions != $output_file_permissions ) {
1470 0         0 Warn(
1471             "Unable to copy setuid and/or setgid bits for output file '$output_file'\n"
1472             );
1473             }
1474             }
1475             }
1476              
1477             # Mark the output file for rw unless we are in -b mode.
1478             # Explanation: perltidy does not unlink existing output
1479             # files before writing to them, for safety. If a
1480             # designated output file exists and is not writable,
1481             # perltidy will halt. This can prevent a data loss if a
1482             # user accidentally enters "perltidy infile -o
1483             # important_ro_file", or "perltidy infile -st
1484             # >important_ro_file". But it also means that perltidy can
1485             # get locked out of rerunning unless it marks its own
1486             # output files writable. The alternative, of always
1487             # unlinking the designated output file, is less safe and
1488             # not always possible, except in -b mode, where there is an
1489             # assumption that a previous backup can be unlinked even if
1490             # not writable.
1491 2 50       5 if ( !$in_place_modify ) {
1492 2         6 $output_file_permissions |= oct(600);
1493             }
1494              
1495 2 50       40 if ( !chmod( $output_file_permissions, $output_file ) ) {
1496              
1497             # couldn't change file permissions
1498 0         0 my $operm = sprintf "%04o", $output_file_permissions;
1499 0         0 Warn(
1500             "Unable to set permissions for output file '$output_file' to $operm\n"
1501             );
1502             }
1503 2         15 return;
1504             } ## end sub set_output_file_permissions
1505              
1506             sub get_decoded_string_buffer {
1507 559     559 0 2042 my ( $self, $input_file, $display_name, $rpending_logfile_message ) = @_;
1508              
1509             # Decode the input buffer if necessary or requested
1510              
1511             # Given:
1512             # $input_file = the input file or stream
1513             # $display_name = its name to use in error messages
1514              
1515             # Set $self->[_line_separator_], and
1516              
1517             # Return:
1518             # $rinput_string = ref to input string, decoded from utf8 if necessary
1519             # $is_encoded_data = true if $buf is decoded from utf8
1520             # $decoded_input_as = true if perltidy decoded input buf
1521             # $encoding_log_message = messages for log file,
1522             # $length_function = function to use for measuring string width
1523              
1524             # Return nothing on any error; this is a signal to skip this file
1525              
1526 559         1506 my $rOpts = $self->[_rOpts_];
1527              
1528 559         2076 my $rinput_string = slurp_stream($input_file);
1529 559 50       2617 return unless ( defined($rinput_string) );
1530              
1531 559         3075 $rinput_string = $self->set_line_separator($rinput_string);
1532              
1533 559         1436 my $encoding_in = EMPTY_STRING;
1534 559         1527 my $rOpts_character_encoding = $rOpts->{'character-encoding'};
1535 559         1163 my $encoding_log_message;
1536 559         1487 my $decoded_input_as = EMPTY_STRING;
1537 559         1785 $rstatus->{'char_mode_source'} = 0;
1538              
1539             # Case 1: If Perl is already in a character-oriented mode for this
1540             # string rather than a byte-oriented mode. Normally, this happens if
1541             # the caller has decoded a utf8 string before calling perltidy. But it
1542             # could also happen if the user has done some unusual manipulations of
1543             # the source. In any case, we will not attempt to decode it because
1544             # that could result in an output string in a different mode.
1545 559 100 33     1200 if ( is_char_mode( ${$rinput_string} ) ) {
  559 50       2838  
    100          
1546 2         6 $encoding_in = "utf8";
1547 2         8 $rstatus->{'char_mode_source'} = 1;
1548             }
1549              
1550             # Case 2. No input stream encoding requested. This is appropriate
1551             # for single-byte encodings like ascii, latin-1, etc
1552             elsif ( !$rOpts_character_encoding
1553             || $rOpts_character_encoding eq 'none' )
1554             {
1555              
1556             # nothing to do
1557             }
1558              
1559             # Case 3. guess input stream encoding if requested
1560             elsif ( lc($rOpts_character_encoding) eq 'guess' ) {
1561              
1562             # The guessing strategy is simple: use Encode::Guess to guess
1563             # an encoding. If and only if the guess is utf8, try decoding and
1564             # use it if successful. Otherwise, we proceed assuming the
1565             # characters are encoded as single bytes (same as if 'none' had
1566             # been specified as the encoding).
1567              
1568             # In testing I have found that including additional guess 'suspect'
1569             # encodings sometimes works but can sometimes lead to disaster by
1570             # using an incorrect decoding.
1571              
1572 548         1346 my $decoder;
1573 548 100       1090 if ( ${$rinput_string} =~ /[^[:ascii:]]/ ) {
  548         3642  
1574 2         8 $decoder = guess_encoding( ${$rinput_string}, 'utf8' );
  2         17  
1575             }
1576 548 50 66     4025 if ( $decoder && ref($decoder) ) {
1577 0         0 $encoding_in = $decoder->name;
1578 0 0 0     0 if ( $encoding_in ne 'UTF-8' && $encoding_in ne 'utf8' ) {
1579 0         0 $encoding_in = EMPTY_STRING;
1580 0         0 $encoding_log_message .= <<EOM;
1581             Guessed encoding '$encoding_in' is not utf8; no encoding will be used
1582             EOM
1583             }
1584             else {
1585              
1586 0         0 my $buf;
1587 0 0       0 if ( !eval { $buf = $decoder->decode( ${$rinput_string} ); 1 } )
  0         0  
  0         0  
  0         0  
1588             {
1589              
1590 0         0 $encoding_log_message .= <<EOM;
1591             Guessed encoding '$encoding_in' but decoding was unsuccessful; no encoding is used
1592             EOM
1593              
1594             # Note that a guess failed, but keep going
1595             # This warning can eventually be removed
1596 0         0 Warn(
1597             "file: $display_name: bad guess to decode source as $encoding_in\n"
1598             );
1599 0         0 $encoding_in = EMPTY_STRING;
1600             }
1601             else {
1602 0         0 $encoding_log_message .= <<EOM;
1603             Guessed encoding '$encoding_in' successfully decoded
1604             EOM
1605 0         0 $decoded_input_as = $encoding_in;
1606 0         0 $rinput_string = \$buf;
1607             }
1608             }
1609             }
1610             else {
1611 548         1802 $encoding_log_message .= <<EOM;
1612             Does not look like utf8 encoded text so processing as raw bytes
1613             EOM
1614             }
1615             }
1616              
1617             # Case 4. Decode with a specific encoding
1618             else {
1619 9         23 $encoding_in = $rOpts_character_encoding;
1620 9         20 my $buf;
1621 9 50       22 if (
1622             !eval {
1623 9         17 $buf = Encode::decode( $encoding_in, ${$rinput_string},
  9         72  
1624             Encode::FB_CROAK | Encode::LEAVE_SRC );
1625 9         758 1;
1626             }
1627             )
1628             {
1629              
1630             # Quit if we cannot decode by the requested encoding;
1631             # Something is not right.
1632 0         0 Warn(
1633             "skipping file: $display_name: Unable to decode source as $encoding_in\n"
1634             );
1635              
1636             # return nothing on error
1637 0         0 return;
1638             }
1639             else {
1640 9         43 $encoding_log_message .= <<EOM;
1641             Specified encoding '$encoding_in' successfully decoded
1642             EOM
1643 9         22 $decoded_input_as = $encoding_in;
1644 9         25 $rinput_string = \$buf;
1645             }
1646             }
1647              
1648             # Set the encoding to be used for all further i/o: If we have
1649             # decoded the data with any format, then we must continue to
1650             # read and write it as encoded data, and we will normalize these
1651             # operations with utf8. If we have not decoded the data, then
1652             # we must not treat it as encoded data.
1653 559 100       2229 my $is_encoded_data = $encoding_in ? 'utf8' : EMPTY_STRING;
1654 559         1607 $self->[_is_encoded_data_] = $is_encoded_data;
1655              
1656             # Delete any Byte Order Mark (BOM), which can cause trouble
1657 559 100       1926 if ($is_encoded_data) {
1658 11         20 ${$rinput_string} =~ s/^\x{FEFF}//;
  11         56  
1659             }
1660              
1661 559         1649 $rstatus->{'input_name'} = $display_name;
1662 559         1748 $rstatus->{'opt_encoding'} = $rOpts_character_encoding;
1663 559 100       2040 $rstatus->{'char_mode_used'} = $encoding_in ? 1 : 0;
1664 559         1609 $rstatus->{'input_decoded_as'} = $decoded_input_as;
1665              
1666             # Define the function to determine the display width of character
1667             # strings
1668 559         1237 my $length_function;
1669 559 100       1931 if ($is_encoded_data) {
1670              
1671             # Try to load Unicode::GCString for defining text display width, if
1672             # requested, when the first encoded file is encountered
1673 11 50       51 if ( !defined($loaded_unicode_gcstring) ) {
1674 0 0       0 if ( eval { require Unicode::GCString; 1 } ) {
  0         0  
  0         0  
1675 0         0 $loaded_unicode_gcstring = 1;
1676             }
1677             else {
1678 0         0 $loaded_unicode_gcstring = 0;
1679 0 0       0 if ( $rOpts->{'use-unicode-gcstring'} ) {
1680 0         0 Warn(<<EOM);
1681             ----------------------
1682             Unable to load Unicode::GCString: $EVAL_ERROR
1683             Processing continues but some vertical alignment may be poor
1684             To prevent this warning message, you can either:
1685             - install module Unicode::GCString, or
1686             - remove '--use-unicode-gcstring' or '-gcs' from your perltidyrc or command line
1687             ----------------------
1688             EOM
1689             }
1690             }
1691             }
1692 11 50       65 if ($loaded_unicode_gcstring) {
1693             $length_function = sub {
1694 0     0   0 return Unicode::GCString->new( $_[0] )->columns;
1695 0         0 };
1696 0         0 $encoding_log_message .= <<EOM;
1697             Using 'Unicode::GCString' to measure horizontal character widths
1698             EOM
1699 0         0 $rstatus->{'gcs_used'} = 1;
1700             }
1701             }
1702             return (
1703 559         3243 $rinput_string,
1704             $is_encoded_data,
1705             $decoded_input_as,
1706             $encoding_log_message,
1707             $length_function,
1708              
1709             );
1710             } ## end sub get_decoded_string_buffer
1711              
1712             { #<<<
1713              
1714             my $LF;
1715             my $CR;
1716             my $CRLF;
1717              
1718             BEGIN {
1719 39     39   267 $LF = chr(10);
1720 39         146 $CR = chr(13);
1721 39         381817 $CRLF = $CR . $LF;
1722             }
1723              
1724             sub get_line_separator_default {
1725              
1726 559     559 0 2079 my ( $rOpts, $input_file ) = @_;
1727              
1728             # Get the line separator that will apply unless overridden by a
1729             # --preserve-line-endings flag for a specific file
1730              
1731 559         1661 my $line_separator_default = "\n";
1732              
1733 559         1768 my $ole = $rOpts->{'output-line-ending'};
1734 559 100       2349 if ($ole) {
1735 4         37 my %endings = (
1736             dos => $CRLF,
1737             win => $CRLF,
1738             mac => $CR,
1739             unix => $LF,
1740             );
1741              
1742 4         20 $line_separator_default = $endings{ lc $ole };
1743              
1744 4 50       17 if ( !$line_separator_default ) {
1745 0         0 my $str = join SPACE, keys %endings;
1746 0         0 Die(<<EOM);
1747             Unrecognized line ending '$ole'; expecting one of: $str
1748             EOM
1749             }
1750              
1751             # Check for conflict with -ple
1752 4 50       19 if ( $rOpts->{'preserve-line-endings'} ) {
1753 0         0 Warn("Ignoring -ple; conflicts with -ole\n");
1754 0         0 $rOpts->{'preserve-line-endings'} = undef;
1755             }
1756             }
1757              
1758 559         1912 return $line_separator_default;
1759              
1760             } ## end sub get_line_separator_default
1761              
1762             sub set_line_separator {
1763              
1764 559     559 0 1833 my ( $self, $rinput_string ) = @_;
1765              
1766             # Set the (output) line separator as requested or necessary
1767              
1768 559         1520 my $rOpts = $self->[_rOpts_];
1769              
1770             # Start with the default (output) line separator
1771 559         1410 my $line_separator = $self->[_line_separator_default_];
1772              
1773             # First try to find the line separator of the input stream
1774 559         1163 my $input_line_separator;
1775              
1776             # Limit the search to a reasonable number of characters, in case we
1777             # have a weird file
1778 559         1161 my $str = substr( ${$rinput_string}, 0, 1024 );
  559         2908  
1779 559 100       2096 if ($str) {
1780              
1781 556 50       10025 if ( $str =~ m/(($CR|$LF)+)/ ) {
1782              
1783 556         2220 my $test = $1;
1784              
1785             # dos
1786 556 100       8335 if ( $test =~ /^($CRLF)+\z/ ) {
    50          
    50          
1787 4         19 $input_line_separator = $CRLF;
1788             }
1789              
1790             # mac
1791             elsif ( $test =~ /^($CR)+\z/ ) {
1792 0         0 $input_line_separator = $CR;
1793             }
1794              
1795             # unix
1796             elsif ( $test =~ /^($LF)+\z/ ) {
1797 552         2101 $input_line_separator = $LF;
1798             }
1799              
1800             # unknown
1801             else { }
1802             }
1803              
1804             # no ending seen
1805             else { }
1806             }
1807              
1808             # Now change the line separator if requested
1809 559 100       2327 if ( defined($input_line_separator) ) {
1810              
1811 556 50       2214 if ( $rOpts->{'preserve-line-endings'} ) {
1812 0         0 $line_separator = $input_line_separator;
1813             }
1814              
1815             # patch to read raw mac files under unix, dos
1816 556 50 66     2891 if ( $input_line_separator ne "\n" && $input_line_separator eq $CR ) {
1817              
1818             # if this file is currently a single line ..
1819 0         0 my @lines = split /^/, ${$rinput_string};
  0         0  
1820 0 0       0 if ( @lines == 1 ) {
1821              
1822             # and becomes multiple lines with the change ..
1823 0         0 @lines = map { $_ . "\n" } split /$CR/, ${$rinput_string};
  0         0  
  0         0  
1824 0 0       0 if ( @lines > 1 ) {
1825              
1826             # then make the change
1827 0         0 my $buf = join EMPTY_STRING, @lines;
1828 0         0 $rinput_string = \$buf;
1829             }
1830             }
1831             }
1832             }
1833              
1834 559         1553 $self->[_line_separator_] = $line_separator;
1835 559         1778 return $rinput_string;
1836             } ## end sub set_line_separator
1837             }
1838              
1839             sub process_all_files {
1840              
1841             my (
1842              
1843 559     559 0 2986 $self,
1844             $rinput_hash,
1845             $rfiles,
1846              
1847             $source_stream,
1848             $output_extension,
1849             $forbidden_file_extensions,
1850             $in_place_modify,
1851             $backup_extension,
1852             $delete_backup,
1853              
1854             $logfile_header,
1855             $rpending_complaint,
1856             $rpending_logfile_message,
1857              
1858             ) = @_;
1859              
1860             # This routine is the main loop to process all files.
1861             # Total formatting is done with these layers of subroutines:
1862             # perltidy - main routine; checks run parameters
1863             # *process_all_files - main loop to process all files; *THIS LAYER
1864             # process_filter_layer - do any pre and post processing;
1865             # process_iteration_layer - handle any iterations on formatting
1866             # process_single_case - solves one formatting problem
1867              
1868 559         1699 my $rOpts = $self->[_rOpts_];
1869 559         1588 my $dot = $self->[_file_extension_separator_];
1870 559         1463 my $diagnostics_object = $self->[_diagnostics_object_];
1871              
1872 559         1889 my $destination_stream = $rinput_hash->{'destination'};
1873 559         1532 my $errorfile_stream = $rinput_hash->{'errorfile'};
1874 559         1545 my $logfile_stream = $rinput_hash->{'logfile'};
1875 559         1479 my $teefile_stream = $rinput_hash->{'teefile'};
1876 559         1587 my $debugfile_stream = $rinput_hash->{'debugfile'};
1877 559         1468 my $stderr_stream = $rinput_hash->{'stderr'};
1878              
1879 559         1096 my $number_of_files = @{$rfiles};
  559         1386  
1880 559         1342 while ( my $input_file = shift @{$rfiles} ) {
  1118         4676  
1881              
1882 559         2081 my $fileroot;
1883             my @input_file_stat;
1884 559         0 my $display_name;
1885              
1886             #--------------------------
1887             # prepare this input stream
1888             #--------------------------
1889 559 100       1748 if ($source_stream) {
    50          
1890 556         1381 $fileroot = "perltidy";
1891 556         1300 $display_name = "<source_stream>";
1892              
1893             # If the source is from an array or string, then .LOG output
1894             # is only possible if a logfile stream is specified. This prevents
1895             # unexpected perltidy.LOG files. If the stream is not defined
1896             # then we will capture it in a string ref but it will not be
1897             # accessible. Previously by Perl::Tidy::DevNull (fix c255);
1898 556 100       2028 if ( !defined($logfile_stream) ) {
1899 555         1350 $logfile_stream = \my $tmp;
1900              
1901             # Likewise for .TEE and .DEBUG output
1902             }
1903 556 100       1792 if ( !defined($teefile_stream) ) {
1904 555         1348 $teefile_stream = \my $tmp;
1905             }
1906 556 100       2048 if ( !defined($debugfile_stream) ) {
1907 554         1408 $debugfile_stream = \my $tmp;
1908             }
1909             }
1910             elsif ( $input_file eq '-' ) { # '-' indicates input from STDIN
1911 0         0 $fileroot = "perltidy"; # root name to use for .ERR, .LOG, etc
1912 0         0 $display_name = "<stdin>";
1913 0         0 $in_place_modify = 0;
1914             }
1915             else {
1916 3         9 $fileroot = $input_file;
1917 3         6 $display_name = $input_file;
1918 3 50       142 if ( !-e $input_file ) {
1919              
1920             # file doesn't exist - check for a file glob
1921 0 0       0 if ( $input_file =~ /([\?\*\[\{])/ ) {
1922              
1923             # Windows shell may not remove quotes, so do it
1924 0         0 my $ifile = $input_file;
1925 0 0       0 if ( $ifile =~ /^\'(.+)\'$/ ) { $ifile = $1 }
  0         0  
1926 0 0       0 if ( $ifile =~ /^\"(.+)\"$/ ) { $ifile = $1 }
  0         0  
1927 0         0 my $pattern = fileglob_to_re($ifile);
1928 0         0 my $dh;
1929 0 0       0 if ( opendir( $dh, './' ) ) {
1930             my @files =
1931 0 0       0 grep { /$pattern/ && !-d } readdir($dh);
  0         0  
1932 0         0 closedir($dh);
1933 0 0       0 next unless (@files);
1934 0         0 unshift @{$rfiles}, @files;
  0         0  
1935 0         0 next;
1936             }
1937             }
1938 0         0 Warn("skipping file: '$input_file': no matches found\n");
1939 0         0 next;
1940             }
1941              
1942 3 50       48 if ( !-f $input_file ) {
1943 0         0 Warn("skipping file: $input_file: not a regular file\n");
1944 0         0 next;
1945             }
1946              
1947             # As a safety precaution, skip zero length files.
1948             # If for example a source file got clobbered somehow,
1949             # the old .tdy or .bak files might still exist so we
1950             # shouldn't overwrite them with zero length files.
1951 3 50       58 if ( !-s $input_file ) {
1952 0         0 Warn("skipping file: $input_file: Zero size\n");
1953 0         0 next;
1954             }
1955              
1956             # And avoid formatting extremely large files. Since perltidy reads
1957             # files into memory, trying to process an extremely large file
1958             # could cause system problems.
1959 3         57 my $size_in_mb = ( -s $input_file ) / ( 1024 * 1024 );
1960 3 50       24 if ( $size_in_mb > $rOpts->{'maximum-file-size-mb'} ) {
1961 0         0 $size_in_mb = sprintf( "%0.1f", $size_in_mb );
1962 0         0 Warn(
1963             "skipping file: $input_file: size $size_in_mb MB exceeds limit $rOpts->{'maximum-file-size-mb'}; use -mfs=i to change\n"
1964             );
1965 0         0 next;
1966             }
1967              
1968 3 0 33     357 if ( !-T $input_file && !$rOpts->{'force-read-binary'} ) {
1969 0         0 Warn("skipping file: $input_file: Non-text (override with -f)\n"
1970             );
1971 0         0 next;
1972             }
1973              
1974             # Input file must be writable for -b -bm='copy'. We must catch
1975             # this early to prevent encountering trouble after unlinking the
1976             # previous backup.
1977 3 50 33     24 if ( $in_place_modify && !-w $input_file ) {
1978 0         0 my $backup_method = $rOpts->{'backup-method'};
1979 0 0 0     0 if ( defined($backup_method) && $backup_method eq 'copy' ) {
1980 0         0 Warn
1981             "skipping file '$input_file' for -b option: file reported as non-writable\n";
1982 0         0 next;
1983             }
1984             }
1985              
1986             # we should have a valid filename now
1987 3         9 $fileroot = $input_file;
1988 3         62 @input_file_stat = stat($input_file);
1989              
1990 3 50       28 if ( $OSNAME eq 'VMS' ) {
1991 0         0 ( $fileroot, $dot ) = check_vms_filename($fileroot);
1992 0         0 $self->[_file_extension_separator_] = $dot;
1993             }
1994              
1995             # add option to change path here
1996 3 50       16 if ( defined( $rOpts->{'output-path'} ) ) {
1997              
1998 0         0 my ( $base, $old_path ) = fileparse($fileroot);
1999 0         0 my $new_path = $rOpts->{'output-path'};
2000 0 0       0 if ( !-d $new_path ) {
2001 0 0       0 mkdir( $new_path, 0777 )
2002             or
2003             Die("unable to create directory $new_path: $OS_ERROR\n");
2004             }
2005 0         0 my $path = $new_path;
2006 0         0 $fileroot = catfile( $path, $base );
2007 0 0       0 if ( !$fileroot ) {
2008 0         0 Die(<<EOM);
2009             ------------------------------------------------------------------------
2010             Problem combining $new_path and $base to make a filename; check -opath
2011             ------------------------------------------------------------------------
2012             EOM
2013             }
2014             }
2015             }
2016              
2017             # Skip files with same extension as the output files because
2018             # this can lead to a messy situation with files like
2019             # script.tdy.tdy.tdy ... or worse problems ... when you
2020             # rerun perltidy over and over with wildcard input.
2021 559 50 33     2583 if (
      66        
2022             !$source_stream
2023             && ( $input_file =~ /$forbidden_file_extensions/
2024             || $input_file eq 'DIAGNOSTICS' )
2025             )
2026             {
2027 0         0 Warn("skipping file: $input_file: wrong extension\n");
2028 0         0 next;
2029             }
2030              
2031             # copy source to a string buffer, decoding from utf8 if necessary
2032             my (
2033 559         3589 $rinput_string,
2034             $is_encoded_data,
2035             $decoded_input_as,
2036             $encoding_log_message,
2037             $length_function,
2038              
2039             ) = $self->get_decoded_string_buffer( $input_file, $display_name,
2040             $rpending_logfile_message );
2041              
2042             # Skip this file on any error
2043 559 50       2125 next if ( !defined($rinput_string) );
2044              
2045             # Register this file name with the Diagnostics package, if any.
2046 559 50       1913 $diagnostics_object->set_input_file($input_file)
2047             if $diagnostics_object;
2048              
2049             # The (possibly decoded) input is now in string ref $rinput_string.
2050             # Now prepare the output stream and error logger.
2051              
2052             #--------------------------
2053             # prepare the output stream
2054             #--------------------------
2055 559         1099 my $output_file;
2056 559         1286 my $output_name = EMPTY_STRING;
2057 559         1067 my $actual_output_extension;
2058              
2059 559 50       3522 if ( $rOpts->{'outfile'} ) {
    100          
    50          
    0          
    0          
2060              
2061 0 0       0 if ( $number_of_files <= 1 ) {
2062              
2063 0 0       0 if ( $rOpts->{'standard-output'} ) {
2064 0         0 my $saw_pbp = $self->[_saw_pbp_];
2065 0         0 my $msg = "You may not use -o and -st together";
2066 0 0       0 $msg .= " (-pbp contains -st; see manual)" if ($saw_pbp);
2067 0         0 Die("$msg\n");
2068             }
2069              
2070 0 0       0 if ($destination_stream) {
2071 0         0 Die(
2072             "You may not specify a destination array and -o together\n"
2073             );
2074             }
2075              
2076 0 0       0 if ( defined( $rOpts->{'output-path'} ) ) {
2077 0         0 Die("You may not specify -o and -opath together\n");
2078             }
2079              
2080 0 0       0 if ( defined( $rOpts->{'output-file-extension'} ) ) {
2081 0         0 Die("You may not specify -o and -oext together\n");
2082             }
2083              
2084 0         0 $output_file = $rOpts->{outfile};
2085 0         0 $output_name = $output_file;
2086              
2087             # make sure user gives a file name after -o
2088 0 0       0 if ( $output_file =~ /^-/ ) {
2089 0         0 Die("You must specify a valid filename after -o\n");
2090             }
2091              
2092             # do not overwrite input file with -o
2093 0 0 0     0 if ( @input_file_stat && ( $output_file eq $input_file ) ) {
2094 0         0 Die("Use 'perltidy -b $input_file' to modify in-place\n");
2095             }
2096             }
2097             else {
2098 0         0 Die("You may not use -o with more than one input file\n");
2099             }
2100             }
2101             elsif ( $rOpts->{'standard-output'} ) {
2102 1 50       6 if ($destination_stream) {
2103 0         0 my $saw_pbp = $self->[_saw_pbp_];
2104 0         0 my $msg =
2105             "You may not specify a destination array and -st together\n";
2106 0 0       0 $msg .= " (-pbp contains -st; see manual)" if ($saw_pbp);
2107 0         0 Die("$msg\n");
2108             }
2109 1         5 $output_file = '-';
2110 1         4 $output_name = "<stdout>";
2111              
2112 1 50       7 if ( $number_of_files <= 1 ) {
2113             }
2114             else {
2115 0         0 Die("You may not use -st with more than one input file\n");
2116             }
2117             }
2118             elsif ($destination_stream) {
2119              
2120 558         1304 $output_file = $destination_stream;
2121 558         1423 $output_name = "<destination_stream>";
2122             }
2123             elsif ($source_stream) { # source but no destination goes to stdout
2124 0         0 $output_file = '-';
2125 0         0 $output_name = "<stdout>";
2126             }
2127             elsif ( $input_file eq '-' ) {
2128 0         0 $output_file = '-';
2129 0         0 $output_name = "<stdout>";
2130             }
2131             else {
2132 0 0       0 if ($in_place_modify) {
2133 0         0 $output_name = $display_name;
2134             }
2135             else {
2136 0         0 $actual_output_extension = $output_extension;
2137 0         0 $output_file = $fileroot . $output_extension;
2138 0         0 $output_name = $output_file;
2139             }
2140             }
2141              
2142 559         1624 $rstatus->{'file_count'} += 1;
2143 559         1547 $rstatus->{'output_name'} = $output_name;
2144 559         1496 $rstatus->{'iteration_count'} = 0;
2145 559         1427 $rstatus->{'converged'} = 0;
2146              
2147             #------------------------------------------
2148             # initialize the error logger for this file
2149             #------------------------------------------
2150 559         1964 my $warning_file = $fileroot . $dot . "ERR";
2151 559 100       1884 if ($errorfile_stream) { $warning_file = $errorfile_stream }
  543         1306  
2152 559         1664 my $log_file = $fileroot . $dot . "LOG";
2153 559 100       1730 if ($logfile_stream) { $log_file = $logfile_stream }
  556         1251  
2154              
2155             # The logger object handles warning messages, logfile messages,
2156             # and can supply basic run information to lower level routines.
2157 559         5270 my $logger_object = Perl::Tidy::Logger->new(
2158             rOpts => $rOpts,
2159             log_file => $log_file,
2160             warning_file => $warning_file,
2161             fh_stderr => $fh_stderr,
2162             display_name => $display_name,
2163             is_encoded_data => $is_encoded_data,
2164             );
2165 559         4138 $logger_object->write_logfile_entry($logfile_header);
2166 559 100       3150 $logger_object->write_logfile_entry($encoding_log_message)
2167             if $encoding_log_message;
2168              
2169             # Now we can add any pending messages to the log
2170 559 50       2114 if ( ${$rpending_logfile_message} ) {
  559         3349  
2171 0         0 $logger_object->write_logfile_entry( ${$rpending_logfile_message} );
  0         0  
2172             }
2173 559 50       1327 if ( ${$rpending_complaint} ) {
  559         2079  
2174 0         0 $logger_object->complain( ${$rpending_complaint} );
  0         0  
2175             }
2176              
2177             # additional parameters needed by lower level routines
2178 559         1828 $self->[_actual_output_extension_] = $actual_output_extension;
2179 559         1433 $self->[_debugfile_stream_] = $debugfile_stream;
2180 559         1379 $self->[_decoded_input_as_] = $decoded_input_as;
2181 559         1417 $self->[_destination_stream_] = $destination_stream;
2182 559         1325 $self->[_display_name_] = $display_name;
2183 559         1339 $self->[_fileroot_] = $fileroot;
2184 559         1209 $self->[_is_encoded_data_] = $is_encoded_data;
2185 559         1296 $self->[_length_function_] = $length_function;
2186 559         1226 $self->[_logger_object_] = $logger_object;
2187 559         1174 $self->[_output_file_] = $output_file;
2188 559         1171 $self->[_teefile_stream_] = $teefile_stream;
2189 559         1287 $self->[_input_copied_verbatim_] = 0;
2190 559         1529 $self->[_input_output_difference_] = 1; ## updated later if -b used
2191              
2192             #--------------------
2193             # process this buffer
2194             #--------------------
2195 559         3026 my $routput_string = $self->process_filter_layer($rinput_string);
2196              
2197             #------------------------------------------------
2198             # send the tidied output to its final destination
2199             #------------------------------------------------
2200 559 100 66     3807 if ( $rOpts->{'format'} eq 'tidy' && defined($routput_string) ) {
2201              
2202 558         3394 $self->write_tidy_output(
2203              
2204             $routput_string,
2205              
2206             \@input_file_stat,
2207             $in_place_modify,
2208             $input_file,
2209             $backup_extension,
2210             $delete_backup,
2211             );
2212             }
2213              
2214             $logger_object->finish()
2215 559 50       4108 if $logger_object;
2216             } ## end of main loop to process all files
2217              
2218 559         2356 return;
2219             } ## end sub process_all_files
2220              
2221             sub write_tidy_output {
2222              
2223             # Write tidied output in '$routput_string' to its final destination
2224              
2225             my (
2226 558     558 0 2473 $self,
2227              
2228             $routput_string,
2229              
2230             $rinput_file_stat,
2231             $in_place_modify,
2232             $input_file,
2233             $backup_extension,
2234             $delete_backup,
2235             ) = @_;
2236              
2237 558         1493 my $rOpts = $self->[_rOpts_];
2238 558         1341 my $is_encoded_data = $self->[_is_encoded_data_];
2239 558         1413 my $output_file = $self->[_output_file_];
2240              
2241             # There are three main output paths:
2242              
2243             #-------------------------------------------------------------------------
2244             # PATH 1: $output_file is not defined: --backup and modify in-place option
2245             #-------------------------------------------------------------------------
2246 558 50       2926 if ($in_place_modify) {
    100          
2247              
2248             # For -b option, leave the file unchanged if a severe error caused
2249             # formatting to be skipped. Otherwise we will overwrite any backup.
2250 0 0       0 if ( !$self->[_input_copied_verbatim_] ) {
2251              
2252 0         0 my $backup_method = $rOpts->{'backup-method'};
2253              
2254             #-------------------------------------------------------------
2255             # PATH 1a: -bm='copy': uses newer version in which original is
2256             # copied to the backup and rewritten; see git #103.
2257             #-------------------------------------------------------------
2258 0 0 0     0 if ( defined($backup_method) && $backup_method eq 'copy' ) {
2259 0         0 $self->backup_method_copy(
2260             $input_file, $routput_string,
2261             $backup_extension, $delete_backup
2262             );
2263             }
2264              
2265             #-------------------------------------------------------------
2266             # PATH 1b: -bm='move': uses older version, where original is
2267             # moved to the backup and formatted output goes to a new file.
2268             #-------------------------------------------------------------
2269             else {
2270 0         0 $self->backup_method_move(
2271             $input_file, $routput_string,
2272             $backup_extension, $delete_backup
2273             );
2274             }
2275             }
2276             }
2277              
2278             #--------------------------------------------------------------------------
2279             # PATH 2: $output_file is a reference (=destination_stream): send output to
2280             # a destination stream ref received from an external perl program. We use
2281             # a sub to do this because the encoding rules are a bit tricky.
2282             #--------------------------------------------------------------------------
2283             elsif ( ref($output_file) ) {
2284 553         2785 $self->copy_buffer_to_external_ref( $routput_string, $output_file );
2285             }
2286              
2287             #--------------------------------------------------------------------------
2288             # PATH 3: $output_file is named file or '-'; send output to the file system
2289             #--------------------------------------------------------------------------
2290             else {
2291              
2292             #--------------------------
2293             # PATH 3a: output to STDOUT
2294             #--------------------------
2295 5 100       25 if ( $output_file eq '-' ) {
2296 1         8 my $fh = *STDOUT;
2297 1 50       3 if ($is_encoded_data) { binmode $fh, ":raw:encoding(UTF-8)" }
  1         91  
2298 0         0 else { binmode $fh }
2299 1         1359 $fh->print( ${$routput_string} );
  1         16  
2300             }
2301              
2302             #--------------------------------
2303             # PATH 3b: output to a named file
2304             #--------------------------------
2305             else {
2306 4 50       590 if ( open( my $fh, '>', $output_file ) ) {
2307 4 100   4   28 if ($is_encoded_data) { binmode $fh, ":raw:encoding(UTF-8)" }
  3         217  
  4         2231  
  4         48  
  4         39  
2308 1         7 else { binmode $fh }
2309 4         4422 $fh->print( ${$routput_string} );
  4         58  
2310 4 50       102 $fh->close() or Die("Cannot close '$output_file': $OS_ERROR\n");
2311             }
2312             else {
2313 0         0 Die("Cannot open $output_file to write: $OS_ERROR\n");
2314             }
2315              
2316             # set output file ownership and permissions if appropriate
2317 4 50 33     940 if ( $output_file && -f $output_file && !-l $output_file ) {
      33        
2318 4 100       12 if ( @{$rinput_file_stat} ) {
  4         25  
2319             $self->set_output_file_permissions( $output_file,
2320 2         5 \@{$rinput_file_stat}, $in_place_modify );
  2         16  
2321             }
2322             }
2323             }
2324              
2325             # Save diagnostic info
2326 5 100       48 if ($is_encoded_data) {
2327 4         22 $rstatus->{'output_encoded_as'} = 'UTF-8';
2328             }
2329             }
2330              
2331 558         1399 return;
2332              
2333             } ## end sub write_tidied_output
2334              
2335             sub process_filter_layer {
2336              
2337 559     559 0 1843 my ( $self, $rinput_string ) = @_;
2338              
2339             # This is the filter layer of processing.
2340             # Do all requested formatting on the string ref '$rinput_string', including
2341             # any pre- and post-processing with filters.
2342             # Returns:
2343             # $routput_string = ref to tidied output if in 'tidy' mode
2344             # (nothing) if not in 'tidy' mode [these modes handle output separately]
2345              
2346             # Total formatting is done with these layers of subroutines:
2347             # perltidy - main routine; checks run parameters
2348             # process_all_files - main loop to process all files;
2349             # *process_filter_layer - do any pre and post processing; *THIS LAYER
2350             # process_iteration_layer - handle any iterations on formatting
2351             # process_single_case - solves one formatting problem
2352              
2353             # Data Flow in this layer:
2354             # $rinput_string
2355             # -> optional prefilter operations
2356             # -> [ formatting by sub process_iteration_layer ]
2357             # -> return if not in 'tidy' mode
2358             # -> optional postfilter operations
2359             # -> $routput_string
2360              
2361             # What is done based on format type:
2362             # utf8 decoding is done for all format types
2363             # prefiltering is applied to all format types
2364             # - because it may be needed to get through the tokenizer
2365             # postfiltering is only done for format='tidy'
2366             # - not appropriate for html text, which has already been output
2367             # encoding of decoded output is only done for format='tidy'
2368             # - because html does its own encoding; user formatter does what it wants
2369              
2370             # Be sure the string we received is defined
2371 559 50       2059 if ( !defined($rinput_string) ) {
2372 0         0 Fault("bad call: the source string ref \$rinput_string is undefined\n");
2373             }
2374 559 50       2615 if ( ref($rinput_string) ne 'SCALAR' ) {
2375 0         0 Fault("bad call: the source string ref is not SCALAR\n");
2376             }
2377              
2378 559         1512 my $rOpts = $self->[_rOpts_];
2379 559         1343 my $is_encoded_data = $self->[_is_encoded_data_];
2380 559         1333 my $logger_object = $self->[_logger_object_];
2381              
2382             # vars for --line-range-tidy filter, if needed
2383 559         3087 my @input_lines_pre;
2384             my @input_lines_post;
2385              
2386             # vars for checking assertions, if needed
2387 559         0 my $digest_input;
2388 559         0 my $saved_input_buf;
2389              
2390             # var for checking --noadd-terminal-newline
2391 559         0 my $chomp_terminal_newline;
2392              
2393             # Setup post-filter vars; these apply to 'tidy' mode only
2394 559 100       2009 if ( $rOpts->{'format'} eq 'tidy' ) {
2395              
2396             #---------------------------------------------------------------------
2397             # for --line-range-tidy, clip '$rinput_string' to a limited line range
2398             #---------------------------------------------------------------------
2399 558         1346 my $line_tidy_begin = $self->[_line_tidy_begin_];
2400 558 100       1939 if ($line_tidy_begin) {
2401              
2402 1         3 my @input_lines = split /^/, ${$rinput_string};
  1         5  
2403              
2404 1         4 my $num = @input_lines;
2405 1 50       6 if ( $line_tidy_begin > $num ) {
2406 0         0 Die(<<EOM);
2407             #--line-range-tidy=n1:n2 has n1=$line_tidy_begin which exceeds max line number of $num
2408             EOM
2409             }
2410             else {
2411 1         3 my $line_tidy_end = $self->[_line_tidy_end_];
2412 1 50 33     6 if ( !defined($line_tidy_end) || $line_tidy_end > $num ) {
2413 0         0 $line_tidy_end = $num;
2414             }
2415 1         8 my $input_string = join EMPTY_STRING,
2416             @input_lines[ $line_tidy_begin - 1 .. $line_tidy_end - 1 ];
2417 1         3 $rinput_string = \$input_string;
2418              
2419 1         6 @input_lines_pre = @input_lines[ 0 .. $line_tidy_begin - 2 ];
2420 1         6 @input_lines_post = @input_lines[ $line_tidy_end .. $num - 1 ];
2421             }
2422             }
2423              
2424             #------------------------------------------
2425             # evaluate MD5 sum of input file, if needed
2426             #------------------------------------------
2427 558 100 33     5371 if ( $rOpts->{'assert-tidy'}
      66        
2428             || $rOpts->{'assert-untidy'}
2429             || $rOpts->{'backup-and-modify-in-place'} )
2430             {
2431 2         4 $digest_input = $md5_hex->( ${$rinput_string} );
  2         8  
2432 2         4 $saved_input_buf = ${$rinput_string};
  2         4  
2433             }
2434              
2435             # When -noadd-terminal-newline is set, and the input does not
2436             # have a newline, then we remove the final newline of the output
2437             $chomp_terminal_newline = !$rOpts->{'add-terminal-newline'}
2438 558   66     2570 && substr( ${$rinput_string}, -1, 1 ) !~ /\n/;
2439              
2440             }
2441              
2442             #-----------------------------------------------------------------------
2443             # Apply any prefilter. The prefilter is a code reference that will be
2444             # applied to the source before tokenizing. Note that we are doing this
2445             # for all format types ('tidy', 'html', 'user') because it may be needed
2446             # to avoid tokenization errors.
2447             #-----------------------------------------------------------------------
2448 559         1473 my $prefilter = $self->[_prefilter_];
2449 559 100       1955 if ($prefilter) {
2450 1         2 my $input_string = $prefilter->( ${$rinput_string} );
  1         7  
2451 1         52 $rinput_string = \$input_string;
2452             }
2453              
2454             #-------------------------------------------
2455             # Format contents of string '$rinput_string'
2456             #-------------------------------------------
2457 559         2715 my $routput_string = $self->process_iteration_layer($rinput_string);
2458              
2459             #-------------------------------
2460             # All done if not in 'tidy' mode
2461             #-------------------------------
2462 559 100       2628 if ( $rOpts->{'format'} ne 'tidy' ) {
2463 1         4 return;
2464             }
2465              
2466             #---------------------
2467             # apply any postfilter
2468             #---------------------
2469 558         1423 my $postfilter = $self->[_postfilter_];
2470 558 100       1961 if ($postfilter) {
2471 1         3 my $output_string = $postfilter->( ${$routput_string} );
  1         8  
2472 1         24 $routput_string = \$output_string;
2473             }
2474              
2475 558 100       2153 if ( defined($digest_input) ) {
2476 2         4 my $digest_output = $md5_hex->( ${$routput_string} );
  2         10  
2477 2         6 $self->[_input_output_difference_] = $digest_output ne $digest_input;
2478             }
2479              
2480             #-----------------------------------------------------
2481             # check for changes if requested by 'assert-...' flags
2482             #-----------------------------------------------------
2483 558 50       2235 if ( $rOpts->{'assert-tidy'} ) {
2484 0 0       0 if ( $self->[_input_output_difference_] ) {
2485 0         0 my $diff_msg =
2486             compare_string_buffers( \$saved_input_buf, $routput_string );
2487 0         0 $logger_object->warning(<<EOM);
2488             assertion failure: '--assert-tidy' is set but output differs from input
2489             EOM
2490 0         0 $logger_object->interrupt_logfile();
2491 0         0 $logger_object->warning( $diff_msg . "\n" );
2492 0         0 $logger_object->resume_logfile();
2493             }
2494             }
2495              
2496 558 50       2180 if ( $rOpts->{'assert-untidy'} ) {
2497 0 0       0 if ( !$self->[_input_output_difference_] ) {
2498 0         0 $logger_object->warning(
2499             "assertion failure: '--assert-untidy' is set but output equals input\n"
2500             );
2501             }
2502             }
2503              
2504             #----------------------------------------
2505             # do --line-range-tidy line recombination
2506             #----------------------------------------
2507 558 100 66     3674 if ( @input_lines_pre || @input_lines_post ) {
2508 1         5 my $str_pre = join EMPTY_STRING, @input_lines_pre;
2509 1         5 my $str_post = join EMPTY_STRING, @input_lines_post;
2510 1         3 my $output_string = $str_pre . ${$routput_string} . $str_post;
  1         4  
2511 1         4 $routput_string = \$output_string;
2512             }
2513              
2514             #-------------------------------------------------------------
2515             # handle --preserve-line-endings or -output-line-endings flags
2516             #-------------------------------------------------------------
2517             # The native line separator has been used in all intermediate
2518             # iterations and filter operations until here so that string
2519             # operations work ok.
2520 558 50       2589 if ( $self->[_line_separator_] ne "\n" ) {
2521 0         0 my $line_separator = $self->[_line_separator_];
2522 0         0 my @output_lines = split /^/, ${$routput_string};
  0         0  
2523 0         0 foreach my $line (@output_lines) {
2524 0         0 chomp $line;
2525 0         0 $line .= $line_separator;
2526             }
2527 0         0 my $output_string = join EMPTY_STRING, @output_lines;
2528 0         0 $routput_string = \$output_string;
2529             }
2530              
2531             #-----------------------------------------
2532             # handle a '--noadd-terminal-newline' flag
2533             #-----------------------------------------
2534 558 100       1853 if ($chomp_terminal_newline) {
2535 1         2 chomp ${$routput_string};
  1         3  
2536             }
2537              
2538 558         2337 return $routput_string;
2539             }
2540              
2541             sub process_iteration_layer {
2542              
2543 559     559 0 1934 my ( $self, $rinput_string ) = @_;
2544              
2545             # This is the iteration layer of processing.
2546             # Do all formatting, iterating if requested, on the source string $buf.
2547             # Output depends on format type:
2548             # For 'tidy' formatting, output goes to sink object
2549             # For 'html' formatting, output goes to the ultimate destination
2550             # For 'user' formatting, user formatter handles output
2551              
2552             # Total formatting is done with these layers of subroutines:
2553             # perltidy - main routine; checks run parameters
2554             # process_all_files - main loop to process all files;
2555             # process_filter_layer - do any pre and post processing
2556             # *process_iteration_layer - do any iterations on formatting; *THIS LAYER
2557             # process_single_case - solves one formatting problem
2558              
2559             # Data Flow in this layer:
2560             # $rinput_string -> [ loop over iterations ] -> $routput_string
2561              
2562 559         1629 my $diagnostics_object = $self->[_diagnostics_object_];
2563 559         1423 my $display_name = $self->[_display_name_];
2564 559         1321 my $fileroot = $self->[_fileroot_];
2565 559         1352 my $is_encoded_data = $self->[_is_encoded_data_];
2566 559         1357 my $length_function = $self->[_length_function_];
2567 559         1383 my $logger_object = $self->[_logger_object_];
2568 559         1388 my $rOpts = $self->[_rOpts_];
2569 559         1361 my $tabsize = $self->[_tabsize_];
2570 559         1212 my $user_formatter = $self->[_user_formatter_];
2571              
2572             # make a debugger object if requested
2573 559         1188 my $debugger_object;
2574 559 100       2219 if ( $rOpts->{DEBUG} ) {
2575 2   33     9 my $debug_file = $self->[_debugfile_stream_]
2576             || $fileroot . $self->make_file_extension('DEBUG');
2577 2         18 $debugger_object =
2578             Perl::Tidy::Debugger->new( $debug_file, $is_encoded_data );
2579             }
2580              
2581             # make a tee file handle if requested
2582 559         1697 my $fh_tee;
2583             my $tee_file;
2584 559 50 66     5485 if ( $rOpts->{'tee-pod'}
      33        
2585             || $rOpts->{'tee-block-comments'}
2586             || $rOpts->{'tee-side-comments'} )
2587             {
2588 1   33     3 $tee_file = $self->[_teefile_stream_]
2589             || $fileroot . $self->make_file_extension('TEE');
2590 1         5 ( $fh_tee, my $tee_filename ) =
2591             Perl::Tidy::streamhandle( $tee_file, 'w', $is_encoded_data );
2592 1 50       4 if ( !$fh_tee ) {
2593 0         0 Warn("couldn't open TEE file $tee_file: $OS_ERROR\n");
2594             }
2595             }
2596              
2597             # vars for iterations and convergence test
2598 559         1459 my $max_iterations = 1;
2599 559         1281 my $convergence_log_message;
2600             my %saw_md5;
2601              
2602             # Only 'tidy' formatting can use multiple iterations
2603 559 100       2200 if ( $rOpts->{'format'} eq 'tidy' ) {
2604              
2605             # check iteration count and quietly fix if necessary:
2606             # - iterations option only applies to code beautification mode
2607             # - the convergence check should stop most runs on iteration 2, and
2608             # virtually all on iteration 3. But we'll allow up to 6.
2609 558         1403 $max_iterations = $rOpts->{'iterations'};
2610 558 50 33     3361 if ( !defined($max_iterations)
2611             || $max_iterations <= 0 )
2612             {
2613 0         0 $max_iterations = 1;
2614             }
2615              
2616 558 50       2248 if ( $max_iterations > 6 ) {
2617 0         0 $max_iterations = 6;
2618             }
2619              
2620             # get starting MD5 sum for convergence test
2621 558 100       1985 if ( $max_iterations > 1 ) {
2622 3         11 my $digest = $md5_hex->( ${$rinput_string} );
  3         17  
2623 3         13 $saw_md5{$digest} = 0;
2624             }
2625             }
2626              
2627             # save objects to allow redirecting output during iterations
2628 559         1274 my $logger_object_final = $logger_object;
2629 559         1336 my $iteration_of_formatter_convergence;
2630             my $routput_string;
2631              
2632             #---------------------
2633             # Loop over iterations
2634             #---------------------
2635 559         2164 foreach my $iter ( 1 .. $max_iterations ) {
2636              
2637 561         1602 $rstatus->{'iteration_count'} += 1;
2638              
2639             # create a string to capture the output
2640 561         1348 my $sink_buffer = EMPTY_STRING;
2641 561         1453 $routput_string = \$sink_buffer;
2642              
2643             # Save logger, debugger and tee output only on pass 1 because:
2644             # (1) line number references must be to the starting
2645             # source, not an intermediate result, and
2646             # (2) we need to know if there are errors so we can stop the
2647             # iterations early if necessary.
2648             # (3) the tee option only works on first pass if comments are also
2649             # being deleted.
2650 561 100       2363 if ( $iter > 1 ) {
2651              
2652 2 50       10 $debugger_object->close_debug_file()
2653             if ($debugger_object);
2654              
2655 2 0 33     11 if ( $fh_tee
      33        
      0        
2656             && $fh_tee->can('close')
2657             && !ref($tee_file)
2658             && $tee_file ne '-' )
2659             {
2660 0 0       0 $fh_tee->close()
2661             or Warn("couldn't close TEE file $tee_file: $OS_ERROR\n");
2662             }
2663              
2664 2         4 $debugger_object = undef;
2665 2         4 $logger_object = undef;
2666 2         5 $fh_tee = undef;
2667             }
2668              
2669             #---------------------------------
2670             # create a formatter for this file
2671             #---------------------------------
2672              
2673 561         1451 my $formatter;
2674              
2675 561 50       3874 if ($user_formatter) {
    100          
    50          
2676 0         0 $formatter = $user_formatter;
2677             }
2678             elsif ( $rOpts->{'format'} eq 'html' ) {
2679              
2680             my $html_toc_extension =
2681 1         6 $self->make_file_extension( $rOpts->{'html-toc-extension'},
2682             'toc' );
2683              
2684             my $html_src_extension =
2685 1         7 $self->make_file_extension( $rOpts->{'html-src-extension'},
2686             'src' );
2687              
2688 1         12 $formatter = Perl::Tidy::HtmlWriter->new(
2689             input_file => $fileroot,
2690             html_file => $self->[_output_file_],
2691             extension => $self->[_actual_output_extension_],
2692             html_toc_extension => $html_toc_extension,
2693             html_src_extension => $html_src_extension,
2694             );
2695             }
2696             elsif ( $rOpts->{'format'} eq 'tidy' ) {
2697 560         4750 $formatter = Perl::Tidy::Formatter->new(
2698             logger_object => $logger_object,
2699             diagnostics_object => $diagnostics_object,
2700             sink_object => $routput_string,
2701             length_function => $length_function,
2702             is_encoded_data => $is_encoded_data,
2703             fh_tee => $fh_tee,
2704             );
2705             }
2706             else {
2707 0         0 Die("I don't know how to do -format=$rOpts->{'format'}\n");
2708             }
2709              
2710 561 50       2862 if ( !$formatter ) {
2711 0         0 Die("Unable to continue with $rOpts->{'format'} formatting\n");
2712             }
2713              
2714             #-----------------------------------
2715             # create the tokenizer for this file
2716             #-----------------------------------
2717             my $tokenizer = Perl::Tidy::Tokenizer->new(
2718             source_object => $rinput_string,
2719             logger_object => $logger_object,
2720             debugger_object => $debugger_object,
2721             diagnostics_object => $diagnostics_object,
2722             tabsize => $tabsize,
2723             rOpts => $rOpts,
2724              
2725             starting_level => $rOpts->{'starting-indentation-level'},
2726             indent_columns => $rOpts->{'indent-columns'},
2727             look_for_hash_bang => $rOpts->{'look-for-hash-bang'},
2728             look_for_autoloader => $rOpts->{'look-for-autoloader'},
2729             look_for_selfloader => $rOpts->{'look-for-selfloader'},
2730             trim_qw => $rOpts->{'trim-qw'},
2731             extended_syntax => $rOpts->{'extended-syntax'},
2732              
2733             continuation_indentation => $rOpts->{'continuation-indentation'},
2734 561         6981 outdent_labels => $rOpts->{'outdent-labels'},
2735             );
2736              
2737             #---------------------------------
2738             # do processing for this iteration
2739             #---------------------------------
2740 561         4327 $self->process_single_case( $tokenizer, $formatter );
2741              
2742             #--------------
2743             # report errors
2744             #--------------
2745              
2746             # see if the formatter is converged
2747 561 50 66     2669 if ( $max_iterations > 1
      66        
2748             && !defined($iteration_of_formatter_convergence)
2749             && $formatter->can('get_convergence_check') )
2750             {
2751 5 100       29 if ( $formatter->get_convergence_check() ) {
2752 3         8 $iteration_of_formatter_convergence = $iter;
2753 3         17 $rstatus->{'converged'} = 1;
2754             }
2755             }
2756              
2757             # line source for next iteration (if any) comes from the current
2758             # temporary output buffer
2759 561 100       5580 if ( $iter < $max_iterations ) {
2760              
2761 4         13 $rinput_string = \$sink_buffer;
2762              
2763             # stop iterations if errors or converged
2764 4         12 my $stop_now = $self->[_input_copied_verbatim_];
2765 4   33     46 $stop_now ||= $tokenizer->get_unexpected_error_count();
2766 4         10 my $stopping_on_error = $stop_now;
2767 4 50       17 if ($stop_now) {
2768 0         0 $convergence_log_message = <<EOM;
2769             Stopping iterations because of severe errors.
2770             EOM
2771             }
2772              
2773             # or do convergence test
2774             else {
2775              
2776             # stop if the formatter has converged
2777 4   66     28 $stop_now ||= defined($iteration_of_formatter_convergence);
2778              
2779 4         52 my $digest = $md5_hex->($sink_buffer);
2780 4 100       29 if ( !defined( $saw_md5{$digest} ) ) {
2781 3         19 $saw_md5{$digest} = $iter;
2782             }
2783             else {
2784              
2785             # Deja vu, stop iterating
2786 1         3 $stop_now = 1;
2787 1         4 my $iterm = $iter - 1;
2788 1 50       5 if ( $saw_md5{$digest} != $iterm ) {
2789              
2790             # Blinking (oscillating) between two or more stable
2791             # end states. This is unlikely to occur with normal
2792             # parameters, but it can occur in stress testing
2793             # with extreme parameter values, such as very short
2794             # maximum line lengths. We want to catch and fix
2795             # them when they happen.
2796 0         0 $rstatus->{'blinking'} = 1;
2797 0         0 $convergence_log_message = <<EOM;
2798             BLINKER. Output for iteration $iter same as for $saw_md5{$digest}.
2799             EOM
2800 0   0     0 $stopping_on_error ||= $convergence_log_message;
2801             DEVEL_MODE
2802 0         0 && print {*STDERR} $convergence_log_message;
2803 0 0       0 $diagnostics_object->write_diagnostics(
2804             $convergence_log_message)
2805             if $diagnostics_object;
2806              
2807             # Uncomment to search for blinking states
2808             # Warn( "$display_name: blinking; iter $iter same as for $saw_md5{$digest}\n" );
2809              
2810             }
2811             else {
2812 1         6 $convergence_log_message = <<EOM;
2813             Converged. Output for iteration $iter same as for iter $iterm.
2814             EOM
2815 1 50 33     6 $diagnostics_object->write_diagnostics(
2816             $convergence_log_message)
2817             if $diagnostics_object && $iterm > 2;
2818 1         5 $rstatus->{'converged'} = 1;
2819             }
2820             }
2821             }
2822              
2823 4 100       35 if ($stop_now) {
2824              
2825 2         6 if (DEVEL_MODE) {
2826              
2827             if ( defined($iteration_of_formatter_convergence) ) {
2828              
2829             # This message cannot appear unless the formatter
2830             # convergence test above is temporarily skipped for
2831             # testing.
2832             if ( $iteration_of_formatter_convergence < $iter - 1 ) {
2833             print {*STDERR}
2834             "STRANGE Early conv in $display_name: Stopping on it=$iter, converged in formatter on $iteration_of_formatter_convergence\n";
2835             }
2836             }
2837             elsif ( !$stopping_on_error ) {
2838             print {*STDERR}
2839             "STRANGE no conv in $display_name: stopping on it=$iter, but not converged in formatter\n";
2840             }
2841             else {
2842             ## looks ok
2843             }
2844             }
2845              
2846             # we are stopping the iterations early;
2847 2         13 last;
2848             }
2849             } ## end if ( $iter < $max_iterations)
2850             } ## end loop over iterations for one source file
2851              
2852             $debugger_object->close_debug_file()
2853 559 100       2907 if $debugger_object;
2854              
2855 559 0 66     2485 if ( $fh_tee
      33        
      33        
2856             && $fh_tee->can('close')
2857             && !ref($tee_file)
2858             && $tee_file ne '-' )
2859             {
2860 0 0       0 $fh_tee->close()
2861             or Warn("couldn't close TEE file $tee_file: $OS_ERROR\n");
2862             }
2863              
2864             # leave logger object open for additional messages
2865 559         1440 $logger_object = $logger_object_final;
2866 559 100       1916 $logger_object->write_logfile_entry($convergence_log_message)
2867             if $convergence_log_message;
2868              
2869 559         2831 return $routput_string;
2870              
2871             } ## end sub process_iteration_layer
2872              
2873             sub process_single_case {
2874              
2875             # run the formatter on a single defined case
2876 561     561 0 1967 my ( $self, $tokenizer, $formatter ) = @_;
2877              
2878             # Total formatting is done with these layers of subroutines:
2879             # perltidy - main routine; checks run parameters
2880             # process_all_files - main loop to process all files;
2881             # process_filter_layer - do any pre and post processing;
2882             # process_iteration_layer - do any iterations on formatting
2883             # *process_single_case - solve one formatting problem; *THIS LAYER
2884              
2885 561         3387 while ( my $line = $tokenizer->get_line() ) {
2886 7660         28699 $formatter->write_line($line);
2887             }
2888              
2889             # user-defined formatters are possible, and may not have a
2890             # sub 'finish_formatting', so we have to check
2891 561 50       7701 if ( $formatter->can('finish_formatting') ) {
2892 561         3118 my $severe_error = $tokenizer->report_tokenization_errors();
2893 561         3131 my $verbatim = $formatter->finish_formatting($severe_error);
2894 561         1869 $self->[_input_copied_verbatim_] = $verbatim;
2895             }
2896              
2897 561         1573 return;
2898             } ## end sub process_single_case
2899              
2900             sub copy_buffer_to_external_ref {
2901              
2902 553     553 0 1865 my ( $self, $routput, $destination_stream ) = @_;
2903              
2904             # Copy $routput to the final $destination_stream,
2905             # encoding if the flag $encode_destination_buffer is true.
2906              
2907             # Data Flow:
2908             # $destination_buffer -> [ encode? ] -> $destination_stream
2909              
2910 553         1582 my $destination_buffer = EMPTY_STRING;
2911 553 50       3101 if ( ref($routput) eq 'ARRAY' ) {
    50          
2912 0         0 $destination_buffer = join EMPTY_STRING, @{$routput};
  0         0  
2913             }
2914             elsif ( ref($routput) eq 'SCALAR' ) {
2915 553         1002 $destination_buffer = ${$routput};
  553         2612  
2916             }
2917             else {
2918 0         0 Fatal(
2919             "'copy_buffer_to_external_ref' expecting ref to ARRAY or SCALAR\n");
2920             }
2921              
2922 553         2129 $rstatus->{'output_encoded_as'} = EMPTY_STRING;
2923 553         1534 my $ref_destination_stream = ref($destination_stream);
2924              
2925             # Encode output? Strings and arrays use special encoding rules; see:
2926             # https://github.com/perltidy/perltidy/blob/master/docs/eos_flag.md
2927 553         1124 my $encode_destination_buffer;
2928 553 50 66     2770 if ( $ref_destination_stream eq 'SCALAR'
    0          
2929             || $ref_destination_stream eq 'ARRAY' )
2930             {
2931 553         1520 my $rOpts = $self->[_rOpts_];
2932             $encode_destination_buffer =
2933 553   66     3343 $rOpts->{'encode-output-strings'} && $self->[_decoded_input_as_];
2934             }
2935              
2936             # An object with a print method will use file encoding rules
2937             elsif ( $ref_destination_stream->can('print') ) {
2938 0         0 $encode_destination_buffer = $self->[_is_encoded_data_];
2939             }
2940             else {
2941 0         0 confess <<EOM;
2942             ------------------------------------------------------------------------
2943             No 'print' method is defined for object of class '$ref_destination_stream'
2944             Please check your call to Perl::Tidy::perltidy. Trace follows.
2945             ------------------------------------------------------------------------
2946             EOM
2947             }
2948              
2949 553 100       2089 if ($encode_destination_buffer) {
2950 6         15 my $encoded_buffer;
2951 6 50       12 if (
2952             !eval {
2953 6         35 $encoded_buffer =
2954             Encode::encode( "UTF-8", $destination_buffer,
2955             Encode::FB_CROAK | Encode::LEAVE_SRC );
2956 6         947 1;
2957             }
2958             )
2959             {
2960              
2961 0         0 Warn(
2962             "Error attempting to encode output string ref; encoding not done\n"
2963             );
2964             }
2965             else {
2966 6         16 $destination_buffer = $encoded_buffer;
2967 6         23 $rstatus->{'output_encoded_as'} = 'UTF-8';
2968             }
2969             }
2970              
2971             # Send data for SCALAR, ARRAY & OBJ refs to its final destination
2972 553 100       1987 if ( $ref_destination_stream eq 'SCALAR' ) {
    50          
2973 550         1151 ${$destination_stream} = $destination_buffer;
  550         1491  
2974             }
2975             elsif ( defined($destination_buffer) ) {
2976 3         44 my @lines = split /^/, $destination_buffer;
2977 3 50       17 if ( $ref_destination_stream eq 'ARRAY' ) {
2978 3         9 @{$destination_stream} = @lines;
  3         18  
2979             }
2980              
2981             # destination stream must be an object with print method
2982             else {
2983 0         0 foreach my $line (@lines) {
2984 0         0 $destination_stream->print($line);
2985             }
2986 0 0       0 if ( $ref_destination_stream->can('close') ) {
2987 0         0 $destination_stream->close();
2988             }
2989             }
2990             }
2991             else {
2992              
2993             # Empty destination buffer not going to a string ... could
2994             # happen for example if user deleted all pod or comments
2995             }
2996 553         1537 return;
2997             } ## end sub copy_buffer_to_external_ref
2998              
2999             } ## end of closure for sub perltidy
3000              
3001             sub line_diff {
3002              
3003             # Given two strings, return
3004             # $diff_marker = a string with carat (^) symbols indicating differences
3005             # $pos1 = character position of first difference; pos1=-1 if no difference
3006              
3007             # Form exclusive or of the strings, which has null characters where strings
3008             # have same common characters so non-null characters indicate character
3009             # differences.
3010 0     0 0 0 my ( $s1, $s2 ) = @_;
3011 0         0 my $diff_marker = EMPTY_STRING;
3012 0         0 my $pos = -1;
3013 0         0 my $pos1 = $pos;
3014 0 0 0     0 if ( defined($s1) && defined($s2) ) {
3015 0         0 my $count = 0;
3016 0         0 my $mask = $s1 ^ $s2;
3017              
3018 0         0 while ( $mask =~ /[^\0]/g ) {
3019 0         0 $count++;
3020 0         0 my $pos_last = $pos;
3021 0         0 $pos = $LAST_MATCH_START[0];
3022 0 0       0 if ( $count == 1 ) { $pos1 = $pos; }
  0         0  
3023 0         0 $diff_marker .= SPACE x ( $pos - $pos_last - 1 ) . '^';
3024              
3025             # we could continue to mark all differences, but there is no point
3026 0         0 last;
3027             }
3028             }
3029 0 0       0 return wantarray ? ( $diff_marker, $pos1 ) : $diff_marker;
3030             } ## end sub line_diff
3031              
3032             sub compare_string_buffers {
3033              
3034             # Compare input and output string buffers and return a brief text
3035             # description of the first difference.
3036 0     0 0 0 my ( $rbufi, $rbufo ) = @_;
3037              
3038 0 0       0 my $leni = defined($rbufi) ? length( ${$rbufi} ) : 0;
  0         0  
3039 0 0       0 my $leno = defined($rbufo) ? length( ${$rbufo} ) : 0;
  0         0  
3040 0         0 my $msg =
3041             "Input file length is $leni chars\nOutput file length is $leno chars\n";
3042 0 0 0     0 return $msg unless $leni && $leno;
3043 0         0 my @aryi = split /^/, ${$rbufi};
  0         0  
3044 0         0 my @aryo = split /^/, ${$rbufo};
  0         0  
3045 0         0 my ( $linei, $lineo );
3046 0         0 my ( $counti, $counto ) = ( 0, 0 );
3047 0         0 my ( $last_nonblank_line, $last_nonblank_count ) = ( EMPTY_STRING, 0 );
3048             my $truncate = sub {
3049 0     0   0 my ( $str, $lenmax ) = @_;
3050 0 0       0 if ( length($str) > $lenmax ) {
3051 0         0 $str = substr( $str, 0, $lenmax ) . "...";
3052             }
3053 0         0 return $str;
3054 0         0 };
3055 0         0 while (1) {
3056 0 0       0 if ($linei) {
3057 0         0 $last_nonblank_line = $linei;
3058 0         0 $last_nonblank_count = $counti;
3059             }
3060 0         0 $linei = shift @aryi;
3061 0         0 $lineo = shift @aryo;
3062              
3063             # compare chomp'ed lines
3064 0 0       0 if ( defined($linei) ) { $counti++; chomp $linei }
  0         0  
  0         0  
3065 0 0       0 if ( defined($lineo) ) { $counto++; chomp $lineo }
  0         0  
  0         0  
3066              
3067             # see if one or both ended before a difference
3068 0 0 0     0 last unless ( defined($linei) && defined($lineo) );
3069              
3070 0 0       0 next if ( $linei eq $lineo );
3071              
3072             # lines differ ...
3073 0         0 my ( $line_diff, $pos1 ) = line_diff( $linei, $lineo );
3074 0         0 my $reason = "Files first differ at character $pos1 of line $counti";
3075              
3076 0         0 my ( $leading_ws_i, $leading_ws_o ) = ( EMPTY_STRING, EMPTY_STRING );
3077 0 0       0 if ( $linei =~ /^(\s+)/ ) { $leading_ws_i = $1; }
  0         0  
3078 0 0       0 if ( $lineo =~ /^(\s+)/ ) { $leading_ws_o = $1; }
  0         0  
3079 0 0       0 if ( $leading_ws_i ne $leading_ws_o ) {
3080 0         0 $reason .= "; leading whitespace differs";
3081 0 0       0 if ( $leading_ws_i =~ /\t/ ) {
3082 0         0 $reason .= "; input has tab char";
3083             }
3084             }
3085             else {
3086 0         0 my ( $trailing_ws_i, $trailing_ws_o ) =
3087             ( EMPTY_STRING, EMPTY_STRING );
3088 0 0       0 if ( $linei =~ /(\s+)$/ ) { $trailing_ws_i = $1; }
  0         0  
3089 0 0       0 if ( $lineo =~ /(\s+)$/ ) { $trailing_ws_o = $1; }
  0         0  
3090 0 0       0 if ( $trailing_ws_i ne $trailing_ws_o ) {
3091 0         0 $reason .= "; trailing whitespace differs";
3092             }
3093             }
3094 0         0 $msg .= $reason . "\n";
3095              
3096             # limit string display length
3097 0 0       0 if ( $pos1 > 60 ) {
3098 0         0 my $drop = $pos1 - 40;
3099 0         0 $linei = "..." . substr( $linei, $drop );
3100 0         0 $lineo = "..." . substr( $lineo, $drop );
3101 0         0 $line_diff = SPACE x 3 . substr( $line_diff, $drop );
3102             }
3103 0         0 $linei = $truncate->( $linei, 72 );
3104 0         0 $lineo = $truncate->( $lineo, 72 );
3105 0         0 $last_nonblank_line = $truncate->( $last_nonblank_line, 72 );
3106              
3107 0 0       0 if ($last_nonblank_line) {
3108 0         0 $msg .= <<EOM;
3109             $last_nonblank_count:$last_nonblank_line
3110             EOM
3111             }
3112 0         0 $line_diff = SPACE x ( 2 + length($counto) ) . $line_diff;
3113 0         0 $msg .= <<EOM;
3114             <$counti:$linei
3115             >$counto:$lineo
3116             $line_diff
3117             EOM
3118 0         0 return $msg;
3119             } ## end while
3120              
3121             # no line differences found, but one file may have fewer lines
3122 0 0       0 if ( $counti > $counto ) {
    0          
3123 0         0 $msg .= <<EOM;
3124             Files initially match file but output file has fewer lines
3125             EOM
3126             }
3127             elsif ( $counti < $counto ) {
3128 0         0 $msg .= <<EOM;
3129             Files initially match file but input file has fewer lines
3130             EOM
3131             }
3132             else {
3133 0         0 $msg .= <<EOM;
3134             Text in lines of file match but checksums differ. Perhaps line endings differ.
3135             EOM
3136             }
3137 0         0 return $msg;
3138             } ## end sub compare_string_buffers
3139              
3140             sub fileglob_to_re {
3141              
3142             # modified (corrected) from version in find2perl
3143 0     0 0 0 my $x = shift;
3144 0         0 $x =~ s/([.\/^\$()])/\\$1/g; # escape special characters
3145 0         0 $x =~ s/\*/.*/g; # '*' -> '.*'
3146 0         0 $x =~ s/\?/./g; # '?' -> '.'
3147 0         0 return "^$x\\z"; # match whole word
3148             } ## end sub fileglob_to_re
3149              
3150             sub make_logfile_header {
3151 559     559 0 2386 my ( $rOpts, $config_file, $rraw_options, $Windows_type, $readable_options )
3152             = @_;
3153              
3154             # Note: the punctuation variable '$]' is not in older versions of
3155             # English.pm so leave it as is to avoid failing installation tests.
3156 559         5022 my $msg =
3157             "perltidy version $VERSION log file on a $OSNAME system, OLD_PERL_VERSION=$]\n";
3158 559 50       1843 if ($Windows_type) {
3159 0         0 $msg .= "Windows type is $Windows_type\n";
3160             }
3161 559         1296 my $options_string = join( SPACE, @{$rraw_options} );
  559         2039  
3162              
3163 559 100       2176 if ($config_file) {
3164 551         2592 $msg .= "Found Configuration File >>> $config_file \n";
3165             }
3166 559         1758 $msg .= "Configuration and command line parameters for this run:\n";
3167 559         1643 $msg .= "$options_string\n";
3168              
3169 559 100 66     4031 if ( $rOpts->{'DEBUG'} || $rOpts->{'show-options'} ) {
3170 2         17 $rOpts->{'logfile'} = 1; # force logfile to be saved
3171 2         8 $msg .= "Final parameter set for this run\n";
3172 2         7 $msg .= "------------------------------------\n";
3173              
3174 2         22 $msg .= $readable_options;
3175              
3176 2         28 $msg .= "------------------------------------\n";
3177             }
3178 559         1694 $msg .= "To find error messages search for 'WARNING' with your editor\n";
3179 559         2042 return $msg;
3180             } ## end sub make_logfile_header
3181              
3182             sub generate_options {
3183              
3184             ######################################################################
3185             # Generate and return references to:
3186             # @option_string - the list of options to be passed to Getopt::Long
3187             # @defaults - the list of default options
3188             # %expansion - a hash showing how all abbreviations are expanded
3189             # %category - a hash giving the general category of each option
3190             # %option_range - a hash giving the valid ranges of certain options
3191              
3192             # Note: a few options are not documented in the man page and usage
3193             # message. This is because these are depricated, experimental or debug
3194             # options and may or may not be retained in future versions:
3195              
3196             # These undocumented flags are accepted but not used:
3197             # --check-syntax
3198             # --fuzzy-line-length
3199             #
3200             # These undocumented flags are for debugging:
3201             # --recombine # used to debug line breaks
3202             # --short-concatenation-item-length # used to break a '.' chain
3203             #
3204             ######################################################################
3205              
3206             # here is a summary of the Getopt codes:
3207             # <none> does not take an argument
3208             # =s takes a mandatory string
3209             # :s takes an optional string (DO NOT USE - filenames will get eaten up)
3210             # =i takes a mandatory integer
3211             # :i takes an optional integer (NOT RECOMMENDED - can cause trouble)
3212             # ! does not take an argument and may be negated
3213             # i.e., -foo and -nofoo are allowed
3214             # a double dash signals the end of the options list
3215             #
3216             #-----------------------------------------------
3217             # Define the option string passed to GetOptions.
3218             #-----------------------------------------------
3219              
3220 557     557 0 1491 my @option_string = ();
3221 557         1403 my %expansion = ();
3222 557         1186 my %option_category = ();
3223 557         1227 my %option_range = ();
3224 557         1399 my $rexpansion = \%expansion;
3225              
3226             # names of categories in manual
3227             # leading integers will allow sorting
3228 557         3278 my @category_name = (
3229             '0. I/O control',
3230             '1. Basic formatting options',
3231             '2. Code indentation control',
3232             '3. Whitespace control',
3233             '4. Comment controls',
3234             '5. Linebreak controls',
3235             '6. Controlling list formatting',
3236             '7. Retaining or ignoring existing line breaks',
3237             '8. Blank line control',
3238             '9. Other controls',
3239             '10. HTML options',
3240             '11. pod2html options',
3241             '12. Controlling HTML properties',
3242             '13. Debugging',
3243             );
3244              
3245             # These options are parsed directly by perltidy:
3246             # help h
3247             # version v
3248             # However, they are included in the option set so that they will
3249             # be seen in the options dump.
3250              
3251             # These long option names have no abbreviations or are treated specially
3252 557         2269 @option_string = qw(
3253             html!
3254             noprofile
3255             no-profile
3256             npro
3257             recombine!
3258             notidy
3259             );
3260              
3261 557         1172 my $category = 13; # Debugging
3262 557         1638 foreach (@option_string) {
3263 3342         4833 my $opt = $_; # must avoid changing the actual flag
3264 3342         8263 $opt =~ s/!$//;
3265 3342         9233 $option_category{$opt} = $category_name[$category];
3266             }
3267              
3268 557         2285 $category = 11; # HTML
3269 557         2189 $option_category{html} = $category_name[$category];
3270              
3271             # routine to install and check options
3272             my $add_option = sub {
3273 138136     138136   248432 my ( $long_name, $short_name, $flag ) = @_;
3274 138136         261895 push @option_string, $long_name . $flag;
3275 138136         290488 $option_category{$long_name} = $category_name[$category];
3276 138136 50       220128 if ($short_name) {
3277 138136 50       232102 if ( $expansion{$short_name} ) {
3278 0         0 my $existing_name = $expansion{$short_name}[0];
3279 0         0 Die(
3280             "redefining abbreviation $short_name for $long_name; already used for $existing_name\n"
3281             );
3282             }
3283 138136         294243 $expansion{$short_name} = [$long_name];
3284 138136 100       240524 if ( $flag eq '!' ) {
3285 70739         101101 my $nshort_name = 'n' . $short_name;
3286 70739         115376 my $nolong_name = 'no' . $long_name;
3287 70739 50       122525 if ( $expansion{$nshort_name} ) {
3288 0         0 my $existing_name = $expansion{$nshort_name}[0];
3289 0         0 Die(
3290             "attempting to redefine abbreviation $nshort_name for $nolong_name; already used for $existing_name\n"
3291             );
3292             }
3293 70739         155454 $expansion{$nshort_name} = [$nolong_name];
3294             }
3295             }
3296 138136         189359 return;
3297 557         4786 };
3298              
3299             # Install long option names which have a simple abbreviation.
3300             # Options with code '!' get standard negation ('no' for long names,
3301             # 'n' for abbreviations). Categories follow the manual.
3302              
3303             ###########################
3304 557         1453 $category = 0; # I/O_Control
3305             ###########################
3306 557         2288 $add_option->( 'backup-and-modify-in-place', 'b', '!' );
3307 557         2109 $add_option->( 'backup-file-extension', 'bext', '=s' );
3308 557         2733 $add_option->( 'backup-method', 'bm', '=s' );
3309 557         3254 $add_option->( 'character-encoding', 'enc', '=s' );
3310 557         3262 $add_option->( 'force-read-binary', 'f', '!' );
3311 557         3257 $add_option->( 'format', 'fmt', '=s' );
3312 557         3210 $add_option->( 'iterations', 'it', '=i' );
3313 557         3543 $add_option->( 'logfile', 'log', '!' );
3314 557         3262 $add_option->( 'logfile-gap', 'g', ':i' );
3315 557         3131 $add_option->( 'outfile', 'o', '=s' );
3316 557         3096 $add_option->( 'output-file-extension', 'oext', '=s' );
3317 557         3693 $add_option->( 'output-path', 'opath', '=s' );
3318 557         3136 $add_option->( 'profile', 'pro', '=s' );
3319 557         3020 $add_option->( 'quiet', 'q', '!' );
3320 557         3004 $add_option->( 'standard-error-output', 'se', '!' );
3321 557         3163 $add_option->( 'standard-output', 'st', '!' );
3322 557         3294 $add_option->( 'use-unicode-gcstring', 'gcs', '!' );
3323 557         3039 $add_option->( 'warning-output', 'w', '!' );
3324 557         4342 $add_option->( 'add-terminal-newline', 'atnl', '!' );
3325 557         3307 $add_option->( 'line-range-tidy', 'lrt', '=s' );
3326              
3327             # options which are both toggle switches and values moved here
3328             # to hide from tidyview (which does not show category 0 flags):
3329             # -ole moved here from category 1
3330             # -sil moved here from category 2
3331 557         2971 $add_option->( 'output-line-ending', 'ole', '=s' );
3332 557         3292 $add_option->( 'starting-indentation-level', 'sil', '=i' );
3333              
3334             ########################################
3335 557         2037 $category = 1; # Basic formatting options
3336             ########################################
3337 557         3009 $add_option->( 'check-syntax', 'syn', '!' );
3338 557         3267 $add_option->( 'entab-leading-whitespace', 'et', '=i' );
3339 557         2690 $add_option->( 'indent-columns', 'i', '=i' );
3340 557         3008 $add_option->( 'maximum-line-length', 'l', '=i' );
3341 557         2977 $add_option->( 'variable-maximum-line-length', 'vmll', '!' );
3342 557         2999 $add_option->( 'whitespace-cycle', 'wc', '=i' );
3343 557         2764 $add_option->( 'perl-syntax-check-flags', 'pscf', '=s' );
3344 557         3017 $add_option->( 'preserve-line-endings', 'ple', '!' );
3345 557         3202 $add_option->( 'tabs', 't', '!' );
3346 557         3194 $add_option->( 'default-tabsize', 'dt', '=i' );
3347 557         2841 $add_option->( 'extended-syntax', 'xs', '!' );
3348 557         3445 $add_option->( 'assert-tidy', 'ast', '!' );
3349 557         3403 $add_option->( 'assert-untidy', 'asu', '!' );
3350 557         3315 $add_option->( 'encode-output-strings', 'eos', '!' );
3351 557         3083 $add_option->( 'sub-alias-list', 'sal', '=s' );
3352 557         2534 $add_option->( 'grep-alias-list', 'gal', '=s' );
3353 557         2710 $add_option->( 'grep-alias-exclusion-list', 'gaxl', '=s' );
3354 557         2915 $add_option->( 'use-feature', 'uf', '=s' );
3355              
3356             ########################################
3357 557         1916 $category = 2; # Code indentation control
3358             ########################################
3359 557         2863 $add_option->( 'continuation-indentation', 'ci', '=i' );
3360 557         2624 $add_option->( 'extended-continuation-indentation', 'xci', '!' );
3361 557         2936 $add_option->( 'line-up-parentheses', 'lp', '!' );
3362 557         2958 $add_option->( 'extended-line-up-parentheses', 'xlp', '!' );
3363 557         3181 $add_option->( 'line-up-parentheses-exclusion-list', 'lpxl', '=s' );
3364 557         3355 $add_option->( 'line-up-parentheses-inclusion-list', 'lpil', '=s' );
3365 557         2634 $add_option->( 'outdent-keyword-list', 'okwl', '=s' );
3366 557         3094 $add_option->( 'outdent-keywords', 'okw', '!' );
3367 557         3235 $add_option->( 'outdent-labels', 'ola', '!' );
3368 557         3129 $add_option->( 'outdent-long-quotes', 'olq', '!' );
3369 557         3186 $add_option->( 'indent-closing-brace', 'icb', '!' );
3370 557         3339 $add_option->( 'closing-token-indentation', 'cti', '=i' );
3371 557         3167 $add_option->( 'closing-paren-indentation', 'cpi', '=i' );
3372 557         3243 $add_option->( 'closing-brace-indentation', 'cbi', '=i' );
3373 557         3051 $add_option->( 'closing-square-bracket-indentation', 'csbi', '=i' );
3374 557         3114 $add_option->( 'brace-left-and-indent', 'bli', '!' );
3375 557         3073 $add_option->( 'brace-left-and-indent-list', 'blil', '=s' );
3376 557         2996 $add_option->( 'brace-left-and-indent-exclusion-list', 'blixl', '=s' );
3377              
3378             ########################################
3379 557         1772 $category = 3; # Whitespace control
3380             ########################################
3381 557         2899 $add_option->( 'add-trailing-commas', 'atc', '!' );
3382 557         2695 $add_option->( 'add-semicolons', 'asc', '!' );
3383 557         3030 $add_option->( 'add-whitespace', 'aws', '!' );
3384 557         3094 $add_option->( 'block-brace-tightness', 'bbt', '=i' );
3385 557         2954 $add_option->( 'brace-tightness', 'bt', '=i' );
3386 557         2990 $add_option->( 'delete-old-whitespace', 'dws', '!' );
3387 557         3122 $add_option->( 'delete-repeated-commas', 'drc', '!' );
3388 557         3035 $add_option->( 'delete-trailing-commas', 'dtc', '!' );
3389 557         2899 $add_option->( 'delete-weld-interfering-commas', 'dwic', '!' );
3390 557         3047 $add_option->( 'delete-semicolons', 'dsm', '!' );
3391 557         2870 $add_option->( 'function-paren-vertical-alignment', 'fpva', '!' );
3392 557         3161 $add_option->( 'keyword-paren-inner-tightness', 'kpit', '=i' );
3393 557         2830 $add_option->( 'keyword-paren-inner-tightness-list', 'kpitl', '=s' );
3394 557         3040 $add_option->( 'logical-padding', 'lop', '!' );
3395 557         3060 $add_option->( 'nospace-after-keyword', 'nsak', '=s' );
3396 557         2996 $add_option->( 'nowant-left-space', 'nwls', '=s' );
3397 557         2881 $add_option->( 'nowant-right-space', 'nwrs', '=s' );
3398 557         3016 $add_option->( 'paren-tightness', 'pt', '=i' );
3399 557         2969 $add_option->( 'space-after-keyword', 'sak', '=s' );
3400 557         2950 $add_option->( 'space-for-semicolon', 'sfs', '!' );
3401 557         3284 $add_option->( 'space-function-paren', 'sfp', '!' );
3402 557         3222 $add_option->( 'space-keyword-paren', 'skp', '!' );
3403 557         3257 $add_option->( 'space-terminal-semicolon', 'sts', '!' );
3404 557         3077 $add_option->( 'square-bracket-tightness', 'sbt', '=i' );
3405 557         3013 $add_option->( 'square-bracket-vertical-tightness', 'sbvt', '=i' );
3406 557         3283 $add_option->( 'square-bracket-vertical-tightness-closing', 'sbvtc', '=i' );
3407 557         3190 $add_option->( 'tight-secret-operators', 'tso', '!' );
3408 557         3049 $add_option->( 'trim-qw', 'tqw', '!' );
3409 557         3033 $add_option->( 'trim-pod', 'trp', '!' );
3410 557         3301 $add_option->( 'want-left-space', 'wls', '=s' );
3411 557         2747 $add_option->( 'want-right-space', 'wrs', '=s' );
3412 557         3169 $add_option->( 'want-trailing-commas', 'wtc', '=s' );
3413 557         3052 $add_option->( 'space-prototype-paren', 'spp', '=i' );
3414 557         2873 $add_option->( 'valign-code', 'vc', '!' );
3415 557         3122 $add_option->( 'valign-block-comments', 'vbc', '!' );
3416 557         2978 $add_option->( 'valign-side-comments', 'vsc', '!' );
3417 557         2950 $add_option->( 'valign-exclusion-list', 'vxl', '=s' );
3418 557         2942 $add_option->( 'valign-inclusion-list', 'vil', '=s' );
3419 557         2861 $add_option->( 'valign-if-unless', 'viu', '!' );
3420 557         3250 $add_option->( 'extended-block-tightness', 'xbt', '!' );
3421 557         3145 $add_option->( 'extended-block-tightness-list', 'xbtl', '=s' );
3422              
3423             ########################################
3424 557         1897 $category = 4; # Comment controls
3425             ########################################
3426 557         2911 $add_option->( 'closing-side-comment-else-flag', 'csce', '=i' );
3427 557         2790 $add_option->( 'closing-side-comment-interval', 'csci', '=i' );
3428 557         2598 $add_option->( 'closing-side-comment-list', 'cscl', '=s' );
3429 557         3173 $add_option->( 'closing-side-comment-maximum-text', 'csct', '=i' );
3430 557         3044 $add_option->( 'closing-side-comment-prefix', 'cscp', '=s' );
3431 557         2907 $add_option->( 'closing-side-comment-warnings', 'cscw', '!' );
3432 557         3170 $add_option->( 'closing-side-comments', 'csc', '!' );
3433 557         3294 $add_option->( 'closing-side-comments-balanced', 'cscb', '!' );
3434 557         2895 $add_option->( 'code-skipping', 'cs', '!' );
3435 557         3037 $add_option->( 'code-skipping-begin', 'csb', '=s' );
3436 557         3002 $add_option->( 'code-skipping-end', 'cse', '=s' );
3437 557         2970 $add_option->( 'format-skipping', 'fs', '!' );
3438 557         3077 $add_option->( 'format-skipping-begin', 'fsb', '=s' );
3439 557         2681 $add_option->( 'format-skipping-end', 'fse', '=s' );
3440 557         2742 $add_option->( 'hanging-side-comments', 'hsc', '!' );
3441 557         2976 $add_option->( 'indent-block-comments', 'ibc', '!' );
3442 557         3243 $add_option->( 'indent-spaced-block-comments', 'isbc', '!' );
3443 557         3258 $add_option->( 'fixed-position-side-comment', 'fpsc', '=i' );
3444 557         2717 $add_option->( 'minimum-space-to-comment', 'msc', '=i' );
3445 557         3063 $add_option->( 'non-indenting-braces', 'nib', '!' );
3446 557         3047 $add_option->( 'non-indenting-brace-prefix', 'nibp', '=s' );
3447 557         3025 $add_option->( 'outdent-long-comments', 'olc', '!' );
3448 557         3141 $add_option->( 'outdent-static-block-comments', 'osbc', '!' );
3449 557         3574 $add_option->( 'static-block-comment-prefix', 'sbcp', '=s' );
3450 557         2979 $add_option->( 'static-block-comments', 'sbc', '!' );
3451 557         3443 $add_option->( 'static-side-comment-prefix', 'sscp', '=s' );
3452 557         3084 $add_option->( 'static-side-comments', 'ssc', '!' );
3453 557         3251 $add_option->( 'ignore-side-comment-lengths', 'iscl', '!' );
3454 557         3078 $add_option->( 'ignore-perlcritic-comments', 'ipc', '!' );
3455              
3456             ########################################
3457 557         1795 $category = 5; # Linebreak controls
3458             ########################################
3459 557         3061 $add_option->( 'add-newlines', 'anl', '!' );
3460 557         2827 $add_option->( 'block-brace-vertical-tightness', 'bbvt', '=i' );
3461 557         2530 $add_option->( 'block-brace-vertical-tightness-list', 'bbvtl', '=s' );
3462 557         2940 $add_option->( 'brace-follower-vertical-tightness', 'bfvt', '=i' );
3463 557         3139 $add_option->( 'brace-vertical-tightness', 'bvt', '=i' );
3464 557         2947 $add_option->( 'brace-vertical-tightness-closing', 'bvtc', '=i' );
3465 557         2910 $add_option->( 'cuddled-else', 'ce', '!' );
3466 557         3034 $add_option->( 'cuddled-block-list', 'cbl', '=s' );
3467 557         2859 $add_option->( 'cuddled-block-list-exclusive', 'cblx', '!' );
3468 557         3282 $add_option->( 'cuddled-break-option', 'cbo', '=i' );
3469 557         2996 $add_option->( 'cuddled-paren-brace', 'cpb', '!' );
3470 557         3190 $add_option->( 'delete-old-newlines', 'dnl', '!' );
3471 557         3023 $add_option->( 'opening-brace-always-on-right', 'bar', '!' );
3472 557         3040 $add_option->( 'opening-brace-on-new-line', 'bl', '!' );
3473 557         3241 $add_option->( 'opening-hash-brace-right', 'ohbr', '!' );
3474 557         3209 $add_option->( 'opening-paren-right', 'opr', '!' );
3475 557         2992 $add_option->( 'opening-square-bracket-right', 'osbr', '!' );
3476 557         3078 $add_option->( 'opening-anonymous-sub-brace-on-new-line', 'asbl', '!' );
3477 557         3133 $add_option->( 'opening-sub-brace-on-new-line', 'sbl', '!' );
3478 557         2984 $add_option->( 'paren-vertical-tightness', 'pvt', '=i' );
3479 557         2879 $add_option->( 'paren-vertical-tightness-closing', 'pvtc', '=i' );
3480 557         2909 $add_option->( 'weld-nested-containers', 'wn', '!' );
3481 557         2986 $add_option->( 'weld-nested-exclusion-list', 'wnxl', '=s' );
3482 557         2960 $add_option->( 'weld-fat-comma', 'wfc', '!' );
3483 557         2870 $add_option->( 'space-backslash-quote', 'sbq', '=i' );
3484 557         3070 $add_option->( 'stack-closing-block-brace', 'scbb', '!' );
3485 557         3662 $add_option->( 'stack-closing-hash-brace', 'schb', '!' );
3486 557         3206 $add_option->( 'stack-closing-paren', 'scp', '!' );
3487 557         3204 $add_option->( 'stack-closing-square-bracket', 'scsb', '!' );
3488 557         3234 $add_option->( 'stack-opening-hash-brace', 'sohb', '!' );
3489 557         3084 $add_option->( 'stack-opening-paren', 'sop', '!' );
3490 557         3020 $add_option->( 'stack-opening-square-bracket', 'sosb', '!' );
3491 557         3079 $add_option->( 'vertical-tightness', 'vt', '=i' );
3492 557         3149 $add_option->( 'vertical-tightness-closing', 'vtc', '=i' );
3493 557         3218 $add_option->( 'want-break-after', 'wba', '=s' );
3494 557         2908 $add_option->( 'want-break-before', 'wbb', '=s' );
3495 557         3006 $add_option->( 'break-after-all-operators', 'baao', '!' );
3496 557         3330 $add_option->( 'break-before-all-operators', 'bbao', '!' );
3497 557         3301 $add_option->( 'keep-interior-semicolons', 'kis', '!' );
3498 557         2911 $add_option->( 'one-line-block-semicolons', 'olbs', '=i' );
3499 557         3041 $add_option->( 'one-line-block-nesting', 'olbn', '=i' );
3500 557         2905 $add_option->( 'one-line-block-exclusion-list', 'olbxl', '=s' );
3501 557         3712 $add_option->( 'break-before-hash-brace', 'bbhb', '=i' );
3502 557         2896 $add_option->( 'break-before-hash-brace-and-indent', 'bbhbi', '=i' );
3503 557         2910 $add_option->( 'break-before-square-bracket', 'bbsb', '=i' );
3504 557         2947 $add_option->( 'break-before-square-bracket-and-indent', 'bbsbi', '=i' );
3505 557         3106 $add_option->( 'break-before-paren', 'bbp', '=i' );
3506 557         3097 $add_option->( 'break-before-paren-and-indent', 'bbpi', '=i' );
3507 557         3198 $add_option->( 'brace-left-list', 'bll', '=s' );
3508 557         3021 $add_option->( 'brace-left-exclusion-list', 'blxl', '=s' );
3509 557         2952 $add_option->( 'break-after-labels', 'bal', '=i' );
3510              
3511             # This was an experiment mentioned in git #78, originally named -bopl. I
3512             # expanded it to also open logical blocks, based on git discussion #100,
3513             # and renamed it -bocp. It works, but will remain commented out due to
3514             # apparent lack of interest.
3515             # $add_option->( 'break-open-compact-parens', 'bocp', '=s' );
3516              
3517             ########################################
3518 557         1796 $category = 6; # Controlling list formatting
3519             ########################################
3520 557         2868 $add_option->( 'break-at-old-comma-breakpoints', 'boc', '!' );
3521 557         2638 $add_option->( 'comma-arrow-breakpoints', 'cab', '=i' );
3522 557         2673 $add_option->( 'maximum-fields-per-table', 'mft', '=i' );
3523              
3524             ########################################
3525 557         1690 $category = 7; # Retaining or ignoring existing line breaks
3526             ########################################
3527 557         2770 $add_option->( 'break-at-old-keyword-breakpoints', 'bok', '!' );
3528 557         2806 $add_option->( 'break-at-old-logical-breakpoints', 'bol', '!' );
3529 557         2862 $add_option->( 'break-at-old-method-breakpoints', 'bom', '!' );
3530 557         3305 $add_option->( 'break-at-old-semicolon-breakpoints', 'bos', '!' );
3531 557         3056 $add_option->( 'break-at-old-ternary-breakpoints', 'bot', '!' );
3532 557         2952 $add_option->( 'break-at-old-attribute-breakpoints', 'boa', '!' );
3533 557         2977 $add_option->( 'keep-old-breakpoints-before', 'kbb', '=s' );
3534 557         2904 $add_option->( 'keep-old-breakpoints-after', 'kba', '=s' );
3535 557         3063 $add_option->( 'ignore-old-breakpoints', 'iob', '!' );
3536              
3537             ########################################
3538 557         1942 $category = 8; # Blank line control
3539             ########################################
3540 557         3263 $add_option->( 'blanks-before-blocks', 'bbb', '!' );
3541 557         3115 $add_option->( 'blanks-before-comments', 'bbc', '!' );
3542 557         3280 $add_option->( 'blank-lines-before-subs', 'blbs', '=i' );
3543 557         3254 $add_option->( 'blank-lines-before-packages', 'blbp', '=i' );
3544 557         3026 $add_option->( 'long-block-line-count', 'lbl', '=i' );
3545 557         2965 $add_option->( 'maximum-consecutive-blank-lines', 'mbl', '=i' );
3546 557         3023 $add_option->( 'keep-old-blank-lines', 'kbl', '=i' );
3547              
3548 557         2909 $add_option->( 'keyword-group-blanks-list', 'kgbl', '=s' );
3549 557         3000 $add_option->( 'keyword-group-blanks-size', 'kgbs', '=s' );
3550 557         2960 $add_option->( 'keyword-group-blanks-repeat-count', 'kgbr', '=i' );
3551 557         2984 $add_option->( 'keyword-group-blanks-before', 'kgbb', '=i' );
3552 557         2895 $add_option->( 'keyword-group-blanks-after', 'kgba', '=i' );
3553 557         3216 $add_option->( 'keyword-group-blanks-inside', 'kgbi', '!' );
3554 557         3463 $add_option->( 'keyword-group-blanks-delete', 'kgbd', '!' );
3555              
3556 557         3081 $add_option->( 'blank-lines-after-opening-block', 'blao', '=i' );
3557 557         2898 $add_option->( 'blank-lines-before-closing-block', 'blbc', '=i' );
3558 557         3246 $add_option->( 'blank-lines-after-opening-block-list', 'blaol', '=s' );
3559 557         2986 $add_option->( 'blank-lines-before-closing-block-list', 'blbcl', '=s' );
3560              
3561             ########################################
3562 557         2113 $category = 9; # Other controls
3563             ########################################
3564 557         2817 $add_option->( 'warn-missing-else', 'wme', '!' );
3565 557         2775 $add_option->( 'add-missing-else', 'ame', '!' );
3566 557         2871 $add_option->( 'add-missing-else-comment', 'amec', '=s' );
3567 557         2894 $add_option->( 'delete-block-comments', 'dbc', '!' );
3568 557         3354 $add_option->( 'delete-closing-side-comments', 'dcsc', '!' );
3569 557         3051 $add_option->( 'delete-pod', 'dp', '!' );
3570 557         3249 $add_option->( 'delete-side-comments', 'dsc', '!' );
3571 557         3070 $add_option->( 'tee-block-comments', 'tbc', '!' );
3572 557         3207 $add_option->( 'tee-pod', 'tp', '!' );
3573 557         3072 $add_option->( 'tee-side-comments', 'tsc', '!' );
3574 557         3256 $add_option->( 'look-for-autoloader', 'lal', '!' );
3575 557         3318 $add_option->( 'look-for-hash-bang', 'x', '!' );
3576 557         3532 $add_option->( 'look-for-selfloader', 'lsl', '!' );
3577 557         3260 $add_option->( 'pass-version-line', 'pvl', '!' );
3578              
3579             ########################################
3580 557         2131 $category = 13; # Debugging
3581             ########################################
3582 557         3358 $add_option->( 'DEBUG', 'D', '!' );
3583 557         2850 $add_option->( 'dump-block-summary', 'dbs', '!' );
3584 557         2799 $add_option->( 'dump-block-minimum-lines', 'dbl', '=i' );
3585 557         2919 $add_option->( 'dump-block-types', 'dbt', '=s' );
3586 557         3191 $add_option->( 'dump-cuddled-block-list', 'dcbl', '!' );
3587 557         3263 $add_option->( 'dump-defaults', 'ddf', '!' );
3588 557         3172 $add_option->( 'dump-long-names', 'dln', '!' );
3589 557         4695 $add_option->( 'dump-options', 'dop', '!' );
3590 557         3209 $add_option->( 'dump-profile', 'dpro', '!' );
3591 557         3272 $add_option->( 'dump-short-names', 'dsn', '!' );
3592 557         3146 $add_option->( 'dump-token-types', 'dtt', '!' );
3593 557         3062 $add_option->( 'dump-want-left-space', 'dwls', '!' );
3594 557         3054 $add_option->( 'dump-want-right-space', 'dwrs', '!' );
3595 557         3049 $add_option->( 'experimental', 'exp', '=s' );
3596 557         2855 $add_option->( 'fuzzy-line-length', 'fll', '!' );
3597 557         3132 $add_option->( 'help', 'h', EMPTY_STRING );
3598 557         3525 $add_option->( 'short-concatenation-item-length', 'scl', '=i' );
3599 557         2757 $add_option->( 'show-options', 'opt', '!' );
3600 557         3522 $add_option->( 'timestamp', 'ts', '!' );
3601 557         3047 $add_option->( 'version', 'v', EMPTY_STRING );
3602 557         2912 $add_option->( 'memoize', 'mem', '!' );
3603 557         3400 $add_option->( 'file-size-order', 'fso', '!' );
3604 557         3248 $add_option->( 'maximum-file-size-mb', 'maxfs', '=i' );
3605 557         3020 $add_option->( 'maximum-level-errors', 'maxle', '=i' );
3606 557         2954 $add_option->( 'maximum-unexpected-errors', 'maxue', '=i' );
3607              
3608             #---------------------------------------------------------------------
3609              
3610             # The Perl::Tidy::HtmlWriter will add its own options to the string
3611 557         7773 Perl::Tidy::HtmlWriter->make_getopt_long_names( \@option_string );
3612              
3613             ########################################
3614             # Set categories 10, 11, 12
3615             ########################################
3616             # Based on their known order
3617 557         1446 $category = 12; # HTML properties
3618 557         2003 foreach my $opt (@option_string) {
3619 185481         248442 my $long_name = $opt;
3620 185481         564448 $long_name =~ s/(!|=.*|:.*)$//;
3621 185481 100       411465 if ( !defined( $option_category{$long_name} ) ) {
3622 44003 100       88107 if ( $long_name =~ /^html-linked/ ) {
    100          
3623 557         1673 $category = 10; # HTML options
3624             }
3625             elsif ( $long_name =~ /^pod2html/ ) {
3626 557         1500 $category = 11; # Pod2html
3627             }
3628             else {
3629 42889         54368 $category = 12; # HTML properties
3630             }
3631 44003         111831 $option_category{$long_name} = $category_name[$category];
3632             }
3633             }
3634              
3635             #---------------------------------------
3636             # Assign valid ranges to certain options
3637             #---------------------------------------
3638             # In the future, these may be used to make preliminary checks
3639             # hash keys are long names
3640             # If key or value is undefined:
3641             # strings may have any value
3642             # integer ranges are >=0
3643             # If value is defined:
3644             # value is [qw(any valid words)] for strings
3645             # value is [min, max] for integers
3646             # if min is undefined, there is no lower limit
3647             # if max is undefined, there is no upper limit
3648             # Parameters not listed here have defaults
3649             %option_range = (
3650 557         19136 'format' => [ 'tidy', 'html', 'user' ],
3651             'output-line-ending' => [ 'dos', 'win', 'mac', 'unix' ],
3652             'space-backslash-quote' => [ 0, 2 ],
3653             'block-brace-tightness' => [ 0, 2 ],
3654             'keyword-paren-inner-tightness' => [ 0, 2 ],
3655             'brace-tightness' => [ 0, 2 ],
3656             'paren-tightness' => [ 0, 2 ],
3657             'square-bracket-tightness' => [ 0, 2 ],
3658              
3659             'block-brace-vertical-tightness' => [ 0, 2 ],
3660             'brace-follower-vertical-tightness' => [ 0, 2 ],
3661             'brace-vertical-tightness' => [ 0, 2 ],
3662             'brace-vertical-tightness-closing' => [ 0, 2 ],
3663             'paren-vertical-tightness' => [ 0, 2 ],
3664             'paren-vertical-tightness-closing' => [ 0, 2 ],
3665             'square-bracket-vertical-tightness' => [ 0, 2 ],
3666             'square-bracket-vertical-tightness-closing' => [ 0, 2 ],
3667             'vertical-tightness' => [ 0, 2 ],
3668             'vertical-tightness-closing' => [ 0, 2 ],
3669              
3670             'closing-brace-indentation' => [ 0, 3 ],
3671             'closing-paren-indentation' => [ 0, 3 ],
3672             'closing-square-bracket-indentation' => [ 0, 3 ],
3673             'closing-token-indentation' => [ 0, 3 ],
3674              
3675             'closing-side-comment-else-flag' => [ 0, 2 ],
3676             'comma-arrow-breakpoints' => [ 0, 5 ],
3677              
3678             'keyword-group-blanks-before' => [ 0, 2 ],
3679             'keyword-group-blanks-after' => [ 0, 2 ],
3680              
3681             'space-prototype-paren' => [ 0, 2 ],
3682             'break-after-labels' => [ 0, 2 ],
3683             );
3684              
3685             # Note: we could actually allow negative ci if someone really wants it:
3686             # $option_range{'continuation-indentation'} = [ undef, undef ];
3687              
3688             #------------------------------------------------------------------
3689             # DEFAULTS: Assign default values to the above options here, except
3690             # for 'outfile' and 'help'.
3691             # These settings should approximate the perlstyle(1) suggestions.
3692             #------------------------------------------------------------------
3693 557         11877 my @defaults = qw(
3694             add-newlines
3695             add-terminal-newline
3696             add-semicolons
3697             add-whitespace
3698             blanks-before-blocks
3699             blanks-before-comments
3700             blank-lines-before-subs=1
3701             blank-lines-before-packages=1
3702              
3703             keyword-group-blanks-size=5
3704             keyword-group-blanks-repeat-count=0
3705             keyword-group-blanks-before=1
3706             keyword-group-blanks-after=1
3707             nokeyword-group-blanks-inside
3708             nokeyword-group-blanks-delete
3709              
3710             block-brace-tightness=0
3711             block-brace-vertical-tightness=0
3712             brace-follower-vertical-tightness=1
3713             brace-tightness=1
3714             brace-vertical-tightness-closing=0
3715             brace-vertical-tightness=0
3716             break-after-labels=0
3717             break-at-old-logical-breakpoints
3718             break-at-old-ternary-breakpoints
3719             break-at-old-attribute-breakpoints
3720             break-at-old-keyword-breakpoints
3721             break-before-hash-brace=0
3722             break-before-hash-brace-and-indent=0
3723             break-before-square-bracket=0
3724             break-before-square-bracket-and-indent=0
3725             break-before-paren=0
3726             break-before-paren-and-indent=0
3727             comma-arrow-breakpoints=5
3728             nocheck-syntax
3729             character-encoding=guess
3730             closing-side-comment-interval=6
3731             closing-side-comment-maximum-text=20
3732             closing-side-comment-else-flag=0
3733             closing-side-comments-balanced
3734             closing-paren-indentation=0
3735             closing-brace-indentation=0
3736             closing-square-bracket-indentation=0
3737             continuation-indentation=2
3738             noextended-continuation-indentation
3739             cuddled-break-option=1
3740             delete-old-newlines
3741             delete-semicolons
3742             dump-block-minimum-lines=20
3743             dump-block-types=sub
3744             extended-syntax
3745             encode-output-strings
3746             function-paren-vertical-alignment
3747             fuzzy-line-length
3748             hanging-side-comments
3749             indent-block-comments
3750             indent-columns=4
3751             iterations=1
3752             keep-old-blank-lines=1
3753             keyword-paren-inner-tightness=1
3754             logical-padding
3755             long-block-line-count=8
3756             look-for-autoloader
3757             look-for-selfloader
3758             maximum-consecutive-blank-lines=1
3759             maximum-fields-per-table=0
3760             maximum-line-length=80
3761             maximum-file-size-mb=10
3762             maximum-level-errors=1
3763             maximum-unexpected-errors=0
3764             memoize
3765             minimum-space-to-comment=4
3766             nobrace-left-and-indent
3767             nocuddled-else
3768             nodelete-old-whitespace
3769             nohtml
3770             nologfile
3771             non-indenting-braces
3772             noquiet
3773             noshow-options
3774             nostatic-side-comments
3775             notabs
3776             nowarning-output
3777             one-line-block-semicolons=1
3778             one-line-block-nesting=0
3779             outdent-labels
3780             outdent-long-quotes
3781             outdent-long-comments
3782             paren-tightness=1
3783             paren-vertical-tightness-closing=0
3784             paren-vertical-tightness=0
3785             pass-version-line
3786             noweld-nested-containers
3787             recombine
3788             nouse-unicode-gcstring
3789             valign-code
3790             valign-block-comments
3791             valign-side-comments
3792             short-concatenation-item-length=8
3793             space-for-semicolon
3794             space-backslash-quote=1
3795             space-prototype-paren=1
3796             square-bracket-tightness=1
3797             square-bracket-vertical-tightness-closing=0
3798             square-bracket-vertical-tightness=0
3799             static-block-comments
3800             timestamp
3801             trim-qw
3802             format=tidy
3803             backup-method=copy
3804             backup-file-extension=bak
3805             code-skipping
3806             format-skipping
3807             default-tabsize=8
3808              
3809             pod2html
3810             html-table-of-contents
3811             html-entities
3812             );
3813              
3814             #-----------------------------------------------------------------------
3815             # Define abbreviations which will be expanded into the above primitives.
3816             # These may be defined recursively.
3817             #-----------------------------------------------------------------------
3818 557         164243 %expansion = (
3819             %expansion,
3820             'freeze-newlines' => [qw(noadd-newlines nodelete-old-newlines)],
3821             'fnl' => [qw(freeze-newlines)],
3822             'freeze-whitespace' => [qw(noadd-whitespace nodelete-old-whitespace)],
3823             'fws' => [qw(freeze-whitespace)],
3824             'freeze-blank-lines' =>
3825             [qw(maximum-consecutive-blank-lines=0 keep-old-blank-lines=2)],
3826             'fbl' => [qw(freeze-blank-lines)],
3827             'indent-only' => [qw(freeze-newlines freeze-whitespace)],
3828             'outdent-long-lines' => [qw(outdent-long-quotes outdent-long-comments)],
3829             'nooutdent-long-lines' =>
3830             [qw(nooutdent-long-quotes nooutdent-long-comments)],
3831             'oll' => [qw(outdent-long-lines)],
3832             'noll' => [qw(nooutdent-long-lines)],
3833             'io' => [qw(indent-only)],
3834             'delete-all-comments' =>
3835             [qw(delete-block-comments delete-side-comments delete-pod)],
3836             'nodelete-all-comments' =>
3837             [qw(nodelete-block-comments nodelete-side-comments nodelete-pod)],
3838             'dac' => [qw(delete-all-comments)],
3839             'ndac' => [qw(nodelete-all-comments)],
3840             'gnu' => [qw(gnu-style)],
3841             'pbp' => [qw(perl-best-practices)],
3842             'tee-all-comments' =>
3843             [qw(tee-block-comments tee-side-comments tee-pod)],
3844             'notee-all-comments' =>
3845             [qw(notee-block-comments notee-side-comments notee-pod)],
3846             'tac' => [qw(tee-all-comments)],
3847             'ntac' => [qw(notee-all-comments)],
3848             'html' => [qw(format=html)],
3849             'nhtml' => [qw(format=tidy)],
3850             'tidy' => [qw(format=tidy)],
3851              
3852             'brace-left' => [qw(opening-brace-on-new-line)],
3853              
3854             # -cb is now a synonym for -ce
3855             'cb' => [qw(cuddled-else)],
3856             'cuddled-blocks' => [qw(cuddled-else)],
3857              
3858             'utf8' => [qw(character-encoding=utf8)],
3859             'UTF8' => [qw(character-encoding=utf8)],
3860             'guess' => [qw(character-encoding=guess)],
3861              
3862             'swallow-optional-blank-lines' => [qw(kbl=0)],
3863             'noswallow-optional-blank-lines' => [qw(kbl=1)],
3864             'sob' => [qw(kbl=0)],
3865             'nsob' => [qw(kbl=1)],
3866              
3867             'break-after-comma-arrows' => [qw(cab=0)],
3868             'nobreak-after-comma-arrows' => [qw(cab=1)],
3869             'baa' => [qw(cab=0)],
3870             'nbaa' => [qw(cab=1)],
3871              
3872             'blanks-before-subs' => [qw(blbs=1 blbp=1)],
3873             'bbs' => [qw(blbs=1 blbp=1)],
3874             'noblanks-before-subs' => [qw(blbs=0 blbp=0)],
3875             'nbbs' => [qw(blbs=0 blbp=0)],
3876              
3877             'keyword-group-blanks' => [qw(kgbb=2 kgbi kgba=2)],
3878             'kgb' => [qw(kgbb=2 kgbi kgba=2)],
3879             'nokeyword-group-blanks' => [qw(kgbb=1 nkgbi kgba=1)],
3880             'nkgb' => [qw(kgbb=1 nkgbi kgba=1)],
3881              
3882             'break-at-old-trinary-breakpoints' => [qw(bot)],
3883              
3884             'cti=0' => [qw(cpi=0 cbi=0 csbi=0)],
3885             'cti=1' => [qw(cpi=1 cbi=1 csbi=1)],
3886             'cti=2' => [qw(cpi=2 cbi=2 csbi=2)],
3887             'icp' => [qw(cpi=2 cbi=2 csbi=2)],
3888             'nicp' => [qw(cpi=0 cbi=0 csbi=0)],
3889              
3890             'closing-token-indentation=0' => [qw(cpi=0 cbi=0 csbi=0)],
3891             'closing-token-indentation=1' => [qw(cpi=1 cbi=1 csbi=1)],
3892             'closing-token-indentation=2' => [qw(cpi=2 cbi=2 csbi=2)],
3893             'indent-closing-paren' => [qw(cpi=2 cbi=2 csbi=2)],
3894             'noindent-closing-paren' => [qw(cpi=0 cbi=0 csbi=0)],
3895              
3896             'vt=0' => [qw(pvt=0 bvt=0 sbvt=0)],
3897             'vt=1' => [qw(pvt=1 bvt=1 sbvt=1)],
3898             'vt=2' => [qw(pvt=2 bvt=2 sbvt=2)],
3899              
3900             'vertical-tightness=0' => [qw(pvt=0 bvt=0 sbvt=0)],
3901             'vertical-tightness=1' => [qw(pvt=1 bvt=1 sbvt=1)],
3902             'vertical-tightness=2' => [qw(pvt=2 bvt=2 sbvt=2)],
3903              
3904             'vtc=0' => [qw(pvtc=0 bvtc=0 sbvtc=0)],
3905             'vtc=1' => [qw(pvtc=1 bvtc=1 sbvtc=1)],
3906             'vtc=2' => [qw(pvtc=2 bvtc=2 sbvtc=2)],
3907              
3908             'vertical-tightness-closing=0' => [qw(pvtc=0 bvtc=0 sbvtc=0)],
3909             'vertical-tightness-closing=1' => [qw(pvtc=1 bvtc=1 sbvtc=1)],
3910             'vertical-tightness-closing=2' => [qw(pvtc=2 bvtc=2 sbvtc=2)],
3911              
3912             'otr' => [qw(opr ohbr osbr)],
3913             'opening-token-right' => [qw(opr ohbr osbr)],
3914             'notr' => [qw(nopr nohbr nosbr)],
3915             'noopening-token-right' => [qw(nopr nohbr nosbr)],
3916              
3917             'sot' => [qw(sop sohb sosb)],
3918             'nsot' => [qw(nsop nsohb nsosb)],
3919             'stack-opening-tokens' => [qw(sop sohb sosb)],
3920             'nostack-opening-tokens' => [qw(nsop nsohb nsosb)],
3921              
3922             'sct' => [qw(scp schb scsb)],
3923             'stack-closing-tokens' => [qw(scp schb scsb)],
3924             'nsct' => [qw(nscp nschb nscsb)],
3925             'nostack-closing-tokens' => [qw(nscp nschb nscsb)],
3926              
3927             'sac' => [qw(sot sct)],
3928             'nsac' => [qw(nsot nsct)],
3929             'stack-all-containers' => [qw(sot sct)],
3930             'nostack-all-containers' => [qw(nsot nsct)],
3931              
3932             'act=0' => [qw(pt=0 sbt=0 bt=0 bbt=0)],
3933             'act=1' => [qw(pt=1 sbt=1 bt=1 bbt=1)],
3934             'act=2' => [qw(pt=2 sbt=2 bt=2 bbt=2)],
3935             'all-containers-tightness=0' => [qw(pt=0 sbt=0 bt=0 bbt=0)],
3936             'all-containers-tightness=1' => [qw(pt=1 sbt=1 bt=1 bbt=1)],
3937             'all-containers-tightness=2' => [qw(pt=2 sbt=2 bt=2 bbt=2)],
3938              
3939             'stack-opening-block-brace' => [qw(bbvt=2 bbvtl=*)],
3940             'sobb' => [qw(bbvt=2 bbvtl=*)],
3941             'nostack-opening-block-brace' => [qw(bbvt=0)],
3942             'nsobb' => [qw(bbvt=0)],
3943              
3944             'converge' => [qw(it=4)],
3945             'noconverge' => [qw(it=1)],
3946             'conv' => [qw(it=4)],
3947             'nconv' => [qw(it=1)],
3948              
3949             'valign' => [qw(vc vsc vbc)],
3950             'novalign' => [qw(nvc nvsc nvbc)],
3951              
3952             # NOTE: This is a possible future shortcut. But it will remain
3953             # deactivated until the -lpxl flag is no longer experimental.
3954             # 'line-up-function-parentheses' => [ qw(lp), q#lpxl=[ { F(2# ],
3955             # 'lfp' => [qw(line-up-function-parentheses)],
3956              
3957             # 'mangle' originally deleted pod and comments, but to keep it
3958             # reversible, it no longer does. But if you really want to
3959             # delete them, just use:
3960             # -mangle -dac
3961              
3962             # An interesting use for 'mangle' is to do this:
3963             # perltidy -mangle myfile.pl -st | perltidy -o myfile.pl.new
3964             # which will form as many one-line blocks as possible
3965              
3966             'mangle' => [
3967             qw(
3968             keep-old-blank-lines=0
3969             delete-old-newlines
3970             delete-old-whitespace
3971             delete-semicolons
3972             indent-columns=0
3973             maximum-consecutive-blank-lines=0
3974             maximum-line-length=100000
3975             noadd-newlines
3976             noadd-semicolons
3977             noadd-whitespace
3978             noblanks-before-blocks
3979             blank-lines-before-subs=0
3980             blank-lines-before-packages=0
3981             notabs
3982             )
3983             ],
3984              
3985             # 'extrude' originally deleted pod and comments, but to keep it
3986             # reversible, it no longer does. But if you really want to
3987             # delete them, just use
3988             # extrude -dac
3989             #
3990             # An interesting use for 'extrude' is to do this:
3991             # perltidy -extrude myfile.pl -st | perltidy -o myfile.pl.new
3992             # which will break up all one-line blocks.
3993             'extrude' => [
3994             qw(
3995             ci=0
3996             delete-old-newlines
3997             delete-old-whitespace
3998             delete-semicolons
3999             indent-columns=0
4000             maximum-consecutive-blank-lines=0
4001             maximum-line-length=1
4002             noadd-semicolons
4003             noadd-whitespace
4004             noblanks-before-blocks
4005             blank-lines-before-subs=0
4006             blank-lines-before-packages=0
4007             nofuzzy-line-length
4008             notabs
4009             norecombine
4010             )
4011             ],
4012              
4013             # this style tries to follow the GNU Coding Standards (which do
4014             # not really apply to perl but which are followed by some perl
4015             # programmers).
4016             'gnu-style' => [
4017             qw(
4018             lp bl noll pt=2 bt=2 sbt=2 cpi=1 csbi=1 cbi=1
4019             )
4020             ],
4021              
4022             # Style suggested in Damian Conway's Perl Best Practices
4023             'perl-best-practices' => [
4024             qw(l=78 i=4 ci=4 st se vt=2 cti=0 pt=1 bt=1 sbt=1 bbt=1 nsfs nolq),
4025             q(wbb=% + - * / x != == >= <= =~ !~ < > | & = **= += *= &= <<= &&= -= /= |= >>= ||= //= .= %= ^= x=)
4026             ],
4027              
4028             # Additional styles can be added here
4029             );
4030              
4031 557         18647 Perl::Tidy::HtmlWriter->make_abbreviated_names( \%expansion );
4032              
4033             # Uncomment next line to dump all expansions for debugging:
4034             # dump_short_names(\%expansion);
4035             return (
4036 557         10229 \@option_string, \@defaults, \%expansion,
4037             \%option_category, \%option_range
4038             );
4039              
4040             } ## end sub generate_options
4041              
4042             # Memoize process_command_line. Given same @ARGV passed in, return same
4043             # values and same @ARGV back.
4044             # This patch was supplied by Jonathan Swartz Nov 2012 and significantly speeds
4045             # up masontidy (https://metacpan.org/module/masontidy)
4046              
4047             my %process_command_line_cache;
4048              
4049             sub process_command_line {
4050              
4051 559     559 0 2015 my @q = @_;
4052             my (
4053 559         2074 $perltidyrc_stream, $is_Windows, $Windows_type,
4054             $rpending_complaint, $dump_options_type
4055             ) = @q;
4056              
4057 559   66     2369 my $use_cache = !defined($perltidyrc_stream) && !$dump_options_type;
4058 559 100       1707 if ($use_cache) {
4059 7         28 my $cache_key = join( chr(28), @ARGV );
4060 7 100       39 if ( my $result = $process_command_line_cache{$cache_key} ) {
4061 2         7 my ( $argv, @retvals ) = @{$result};
  2         8  
4062 2         7 @ARGV = @{$argv};
  2         6  
4063 2         11 return @retvals;
4064             }
4065             else {
4066 5         19 my @retvals = _process_command_line(@q);
4067             $process_command_line_cache{$cache_key} = [ \@ARGV, @retvals ]
4068 5 50       43 if $retvals[0]->{'memoize'};
4069 5         43 return @retvals;
4070             }
4071             }
4072             else {
4073 552         2100 return _process_command_line(@q);
4074             }
4075             } ## end sub process_command_line
4076              
4077             # (note the underscore here)
4078             sub _process_command_line {
4079              
4080             my (
4081 557     557   1937 $perltidyrc_stream, $is_Windows, $Windows_type,
4082             $rpending_complaint, $dump_options_type
4083             ) = @_;
4084              
4085 39     39   438 use Getopt::Long;
  39         114  
  39         594  
4086              
4087             # Save any current Getopt::Long configuration
4088             # and set to Getopt::Long defaults. Use eval to avoid
4089             # breaking old versions of Perl without these routines.
4090             # Previous configuration is reset at the exit of this routine.
4091 557         1106 my $glc;
4092 557 50       1300 if ( eval { $glc = Getopt::Long::Configure(); 1 } ) {
  557         3625  
  557         11957  
4093 557         1255 my $ok = eval { Getopt::Long::ConfigDefaults(); 1 };
  557         2986  
  557         12239  
4094 557 50 50     2962 if ( !$ok && DEVEL_MODE ) {
4095 0         0 Fault("Failed call to Getopt::Long::ConfigDefaults: $EVAL_ERROR\n");
4096             }
4097             }
4098 0         0 else { $glc = undef }
4099              
4100             my (
4101 557         2449 $roption_string, $rdefaults, $rexpansion,
4102             $roption_category, $roption_range
4103             ) = generate_options();
4104              
4105             #--------------------------------------------------------------
4106             # set the defaults by passing the above list through GetOptions
4107             #--------------------------------------------------------------
4108 557         1901 my %Opts = ();
4109             {
4110 557         1210 local @ARGV = ();
  557         1799  
4111              
4112             # do not load the defaults if we are just dumping perltidyrc
4113 557 50       2353 if ( $dump_options_type ne 'perltidyrc' ) {
4114 557         1173 for my $i ( @{$rdefaults} ) { push @ARGV, "--" . $i }
  557         1781  
  64055         116870  
4115             }
4116 557 50       3028 if ( !GetOptions( \%Opts, @{$roption_string} ) ) {
  557         7305  
4117 0         0 Die(
4118             "Programming Bug reported by 'GetOptions': error in setting default options"
4119             );
4120             }
4121             }
4122              
4123 557         66681718 my @raw_options = ();
4124 557         2952 my $config_file = EMPTY_STRING;
4125 557         1736 my $saw_ignore_profile = 0;
4126 557         1740 my $saw_dump_profile = 0;
4127              
4128             #--------------------------------------------------------------
4129             # Take a first look at the command-line parameters. Do as many
4130             # immediate dumps as possible, which can avoid confusion if the
4131             # perltidyrc file has an error.
4132             #--------------------------------------------------------------
4133 557         3035 foreach my $i (@ARGV) {
4134              
4135 21         59 $i =~ s/^--/-/;
4136 21 100       387 if ( $i =~ /^-(npro|noprofile|no-profile)$/ ) {
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
4137 6         26 $saw_ignore_profile = 1;
4138             }
4139              
4140             # note: this must come before -pro and -profile, below:
4141             elsif ( $i =~ /^-(dump-profile|dpro)$/ ) {
4142 0         0 $saw_dump_profile = 1;
4143             }
4144             elsif ( $i =~ /^-(pro|profile)=(.+)/ ) {
4145 0 0       0 if ($config_file) {
4146 0         0 Warn(
4147             "Only one -pro=filename allowed, using '$2' instead of '$config_file'\n"
4148             );
4149             }
4150 0         0 $config_file = $2;
4151              
4152             # resolve <dir>/.../<file>, meaning look upwards from directory
4153 0 0       0 if ( defined($config_file) ) {
4154 0 0       0 if ( my ( $start_dir, $search_file ) =
4155             ( $config_file =~ m{^(.*)\.\.\./(.*)$} ) )
4156             {
4157 0 0       0 $start_dir = '.' if !$start_dir;
4158 0         0 $start_dir = Cwd::realpath($start_dir);
4159 0 0       0 if ( my $found_file =
4160             find_file_upwards( $start_dir, $search_file ) )
4161             {
4162 0         0 $config_file = $found_file;
4163             }
4164             }
4165             }
4166 0 0       0 if ( !-e $config_file ) {
4167 0         0 Warn(
4168             "cannot find file given with -pro=$config_file: $OS_ERROR\n"
4169             );
4170 0         0 $config_file = EMPTY_STRING;
4171             }
4172             }
4173             elsif ( $i =~ /^-(pro|profile)=?$/ ) {
4174 0         0 Die("usage: -pro=filename or --profile=filename, no spaces\n");
4175             }
4176             elsif ( $i =~ /^-(?: help | [ h \? ] )$/xi ) {
4177 0         0 usage();
4178 0         0 Exit(0);
4179             }
4180             elsif ( $i =~ /^-(version|v)$/ ) {
4181 0         0 show_version();
4182 0         0 Exit(0);
4183             }
4184             elsif ( $i =~ /^-(dump-defaults|ddf)$/ ) {
4185 0         0 dump_defaults( @{$rdefaults} );
  0         0  
4186 0         0 Exit(0);
4187             }
4188             elsif ( $i =~ /^-(dump-long-names|dln)$/ ) {
4189 0         0 dump_long_names( @{$roption_string} );
  0         0  
4190 0         0 Exit(0);
4191             }
4192             elsif ( $i =~ /^-(dump-short-names|dsn)$/ ) {
4193 0         0 dump_short_names($rexpansion);
4194 0         0 Exit(0);
4195             }
4196             elsif ( $i =~ /^-(dump-token-types|dtt)$/ ) {
4197 0         0 Perl::Tidy::Tokenizer->dump_token_types(*STDOUT);
4198 0         0 Exit(0);
4199             }
4200             else {
4201             ## no more special cases
4202             }
4203             }
4204              
4205 557 50 33     3498 if ( $saw_dump_profile && $saw_ignore_profile ) {
4206 0         0 Warn("No profile to dump because of -npro\n");
4207 0         0 Exit(1);
4208             }
4209              
4210             #----------------------------------------
4211             # read any .perltidyrc configuration file
4212             #----------------------------------------
4213 557 100       2853 if ( !$saw_ignore_profile ) {
4214              
4215             # resolve possible conflict between $perltidyrc_stream passed
4216             # as call parameter to perltidy and -pro=filename on command
4217             # line.
4218 551 50       11828 if ($perltidyrc_stream) {
4219 551 50       2559 if ($config_file) {
4220 0         0 Warn(<<EOM);
4221             Conflict: a perltidyrc configuration file was specified both as this
4222             perltidy call parameter: $perltidyrc_stream
4223             and with this -profile=$config_file.
4224             Using -profile=$config_file.
4225             EOM
4226             }
4227             else {
4228 551         1504 $config_file = $perltidyrc_stream;
4229             }
4230             }
4231              
4232             # look for a config file if we don't have one yet
4233 551         1547 my $rconfig_file_chatter;
4234 551         1745 ${$rconfig_file_chatter} = EMPTY_STRING;
  551         2291  
4235 551 50       2775 $config_file =
4236             find_config_file( $is_Windows, $Windows_type, $rconfig_file_chatter,
4237             $rpending_complaint )
4238             unless $config_file;
4239              
4240             # open any config file
4241 551         1474 my $rconfig_string;
4242 551 50       2338 if ($config_file) {
4243 551         3280 $rconfig_string = slurp_stream($config_file);
4244 551 50       3294 if ( !defined($rconfig_string) ) {
4245 0         0 ${$rconfig_file_chatter} .=
  0         0  
4246             "# $config_file exists but cannot be opened\n";
4247             }
4248             }
4249              
4250 551 50       2540 if ($saw_dump_profile) {
4251 0         0 dump_config_file( $rconfig_string, $config_file,
4252             $rconfig_file_chatter );
4253 0         0 Exit(0);
4254             }
4255              
4256 551 50       2830 if ( defined($rconfig_string) ) {
4257              
4258 551         3564 my ( $rconfig_list, $death_message ) =
4259             read_config_file( $rconfig_string, $config_file, $rexpansion );
4260 551 50       2258 Die($death_message) if ($death_message);
4261              
4262             # process any .perltidyrc parameters right now so we can
4263             # localize errors
4264 551 100       1289 if ( @{$rconfig_list} ) {
  551         2829  
4265 218         600 local @ARGV = @{$rconfig_list};
  218         1056  
4266              
4267 218         1635 expand_command_abbreviations( $rexpansion, \@raw_options,
4268             $config_file );
4269              
4270 218 50       775 if ( !GetOptions( \%Opts, @{$roption_string} ) ) {
  218         3140  
4271 0         0 Die(
4272             "Error in this config file: $config_file \nUse -npro to ignore this file, -h for help'\n"
4273             );
4274             }
4275              
4276             # Anything left in this local @ARGV is an error and must be
4277             # invalid bare words from the configuration file. We cannot
4278             # check this earlier because bare words may have been valid
4279             # values for parameters. We had to wait for GetOptions to have
4280             # a look at @ARGV.
4281 218 50       4970080 if (@ARGV) {
4282 0         0 my $count = @ARGV;
4283 0         0 my $str = "\'" . pop(@ARGV) . "\'";
4284 0         0 while ( my $param = pop(@ARGV) ) {
4285 0 0       0 if ( length($str) < 70 ) {
4286 0         0 $str .= ", '$param'";
4287             }
4288             else {
4289 0         0 $str .= ", ...";
4290 0         0 last;
4291             }
4292             }
4293 0         0 Die(<<EOM);
4294             There are $count unrecognized values in the configuration file '$config_file':
4295             $str
4296             Use leading dashes for parameters. Use -npro to ignore this file.
4297             EOM
4298             }
4299              
4300             # Undo any options which cause premature exit. They are not
4301             # appropriate for a config file, and it could be hard to
4302             # diagnose the cause of the premature exit.
4303 218         1396 foreach (
4304             qw{
4305             dump-cuddled-block-list
4306             dump-defaults
4307             dump-long-names
4308             dump-options
4309             dump-profile
4310             dump-short-names
4311             dump-token-types
4312             dump-want-left-space
4313             dump-want-right-space
4314             dump-block-summary
4315             help
4316             stylesheet
4317             version
4318             }
4319             )
4320             {
4321              
4322 2834 50       7469 if ( defined( $Opts{$_} ) ) {
4323 0         0 delete $Opts{$_};
4324 0         0 Warn("ignoring --$_ in config file: $config_file\n");
4325             }
4326             }
4327             }
4328             }
4329             }
4330              
4331             #----------------------------------------
4332             # now process the command line parameters
4333             #----------------------------------------
4334 557         4178 expand_command_abbreviations( $rexpansion, \@raw_options, $config_file );
4335              
4336 557     0   9475 local $SIG{'__WARN__'} = sub { Warn( $_[0] ) };
  0         0  
4337 557 50       2301 if ( !GetOptions( \%Opts, @{$roption_string} ) ) {
  557         6429  
4338 0         0 Die("Error on command line; for help try 'perltidy -h'\n");
4339             }
4340              
4341             # reset Getopt::Long configuration back to its previous value
4342 557 50       10270092 if ( defined($glc) ) {
4343 557         2587 my $ok = eval { Getopt::Long::Configure($glc); 1 };
  557         3838  
  557         17963  
4344 557 50 50     4002 if ( !$ok && DEVEL_MODE ) {
4345 0         0 Fault("Could not reset Getopt::Long configuration: $EVAL_ERROR\n");
4346             }
4347             }
4348              
4349 557         19682 return ( \%Opts, $config_file, \@raw_options, $roption_string,
4350             $rexpansion, $roption_category, $roption_range );
4351             } ## end sub _process_command_line
4352              
4353             sub make_grep_alias_string {
4354 559     559 0 2035 my ($rOpts) = @_;
4355              
4356             # Defaults: list operators in List::Util
4357             # Possible future additions: pairfirst pairgrep pairmap
4358 559         2858 my $default_string = join SPACE, qw(
4359             all
4360             any
4361             first
4362             none
4363             notall
4364             reduce
4365             reductions
4366             );
4367              
4368             # make a hash of any excluded words
4369 559         1375 my %is_excluded_word;
4370 559         1888 my $exclude_string = $rOpts->{'grep-alias-exclusion-list'};
4371 559 50       2432 if ($exclude_string) {
4372 0         0 $exclude_string =~ s/,/ /g; # allow commas
4373 0         0 $exclude_string =~ s/^\s+//;
4374 0         0 $exclude_string =~ s/\s+$//;
4375 0         0 my @q = split /\s+/, $exclude_string;
4376 0         0 @is_excluded_word{@q} = (1) x scalar(@q);
4377             }
4378              
4379             # The special option -gaxl='*' removes all defaults
4380 559 50       2435 if ( $is_excluded_word{'*'} ) { $default_string = EMPTY_STRING }
  0         0  
4381              
4382             # combine the defaults and any input list
4383 559         1679 my $input_string = $rOpts->{'grep-alias-list'};
4384 559 100       2187 if ($input_string) { $input_string .= SPACE . $default_string }
  3         16  
4385 556         1368 else { $input_string = $default_string }
4386              
4387             # Now make the final list of unique grep alias words
4388 559         2345 $input_string =~ s/,/ /g; # allow commas
4389 559         2089 $input_string =~ s/^\s+//;
4390 559         3122 $input_string =~ s/\s+$//;
4391 559         4767 my @word_list = split /\s+/, $input_string;
4392 559         2298 my @filtered_word_list;
4393             my %seen;
4394              
4395 559         2197 foreach my $word (@word_list) {
4396 3929 50       7531 if ($word) {
4397 3929 50       11639 if ( $word !~ /^\w[\w\d]*$/ ) {
4398 0         0 Warn(
4399             "unexpected word in --grep-alias-list: '$word' - ignoring\n"
4400             );
4401             }
4402 3929 50 66     13994 if ( !$seen{$word} && !$is_excluded_word{$word} ) {
4403 3915         11398 $seen{$word}++;
4404 3915         7881 push @filtered_word_list, $word;
4405             }
4406             }
4407             }
4408 559         5007 my $joined_words = join SPACE, @filtered_word_list;
4409 559         2022 $rOpts->{'grep-alias-list'} = $joined_words;
4410 559         2610 return;
4411             } ## end sub make_grep_alias_string
4412              
4413             sub cleanup_word_list {
4414 3     3 0 13 my ( $rOpts, $option_name, $rforced_words ) = @_;
4415              
4416             # Clean up the list of words in a user option to simplify use by
4417             # later routines (delete repeats, replace commas with single space,
4418             # remove non-words)
4419              
4420             # Given:
4421             # $rOpts - the global option hash
4422             # $option_name - hash key of this option
4423             # $rforced_words - ref to list of any words to be added
4424              
4425             # Returns:
4426             # \%seen - hash of the final list of words
4427              
4428 3         10 my %seen;
4429             my @input_list;
4430              
4431 3         9 my $input_string = $rOpts->{$option_name};
4432 3 50 33     28 if ( defined($input_string) && length($input_string) ) {
4433 3         16 $input_string =~ s/,/ /g; # allow commas
4434 3         11 $input_string =~ s/^\s+//;
4435 3         20 $input_string =~ s/\s+$//;
4436 3         31 @input_list = split /\s+/, $input_string;
4437             }
4438              
4439 3 50       14 if ($rforced_words) {
4440 3         14 push @input_list, @{$rforced_words};
  3         10  
4441             }
4442              
4443 3         8 my @filtered_word_list;
4444 3         14 foreach my $word (@input_list) {
4445 11 50       27 if ($word) {
4446              
4447             # look for obviously bad words
4448 11 50 33     64 if ( $word =~ /^\d/ || $word !~ /^\w[\w\d]*$/ ) {
4449 0         0 Warn("unexpected '$option_name' word '$word' - ignoring\n");
4450             }
4451 11 50       33 if ( !$seen{$word} ) {
4452 11         36 $seen{$word}++;
4453 11         27 push @filtered_word_list, $word;
4454             }
4455             }
4456             }
4457 3         36 $rOpts->{$option_name} = join SPACE, @filtered_word_list;
4458 3         15 return \%seen;
4459             } ## end sub cleanup_word_list
4460              
4461             sub check_options {
4462              
4463 559     559 0 2902 my ( $self, $is_Windows, $Windows_type, $rpending_complaint, $num_files ) =
4464             @_;
4465              
4466             # $num_files = number of files to be processed, for error checks
4467              
4468 559         1996 my $rOpts = $self->[_rOpts_];
4469              
4470             #------------------------------------------------------------
4471             # check and handle any interactions among the basic options..
4472             #------------------------------------------------------------
4473              
4474             # Since perltidy only encodes in utf8, problems can occur if we let it
4475             # decode anything else. See discussions for issue git #83.
4476 559         1900 my $encoding = $rOpts->{'character-encoding'};
4477 559 50       4973 if ( $encoding !~ /^\s*(?:guess|none|utf8|utf-8)\s*$/i ) {
4478 0         0 Die(<<EOM);
4479             --character-encoding = '$encoding' is not allowed; the options are: 'none', 'guess', 'utf8'
4480             EOM
4481             }
4482              
4483             # Since -vt, -vtc, and -cti are abbreviations, but under
4484             # msdos, an unquoted input parameter like vtc=1 will be
4485             # seen as 2 parameters, vtc and 1, so the abbreviations
4486             # won't be seen. Therefore, we will catch them here if
4487             # they get through.
4488              
4489 559 50       2883 if ( defined $rOpts->{'vertical-tightness'} ) {
4490 0         0 my $vt = $rOpts->{'vertical-tightness'};
4491 0         0 $rOpts->{'paren-vertical-tightness'} = $vt;
4492 0         0 $rOpts->{'square-bracket-vertical-tightness'} = $vt;
4493 0         0 $rOpts->{'brace-vertical-tightness'} = $vt;
4494             }
4495              
4496 559 100       2543 if ( defined $rOpts->{'vertical-tightness-closing'} ) {
4497 1         3 my $vtc = $rOpts->{'vertical-tightness-closing'};
4498 1         3 $rOpts->{'paren-vertical-tightness-closing'} = $vtc;
4499 1         3 $rOpts->{'square-bracket-vertical-tightness-closing'} = $vtc;
4500 1         3 $rOpts->{'brace-vertical-tightness-closing'} = $vtc;
4501             }
4502              
4503 559 50       2545 if ( defined $rOpts->{'closing-token-indentation'} ) {
4504 0         0 my $cti = $rOpts->{'closing-token-indentation'};
4505 0         0 $rOpts->{'closing-square-bracket-indentation'} = $cti;
4506 0         0 $rOpts->{'closing-brace-indentation'} = $cti;
4507 0         0 $rOpts->{'closing-paren-indentation'} = $cti;
4508             }
4509              
4510             # Syntax checking is no longer supported due to concerns about executing
4511             # code in BEGIN blocks. The flag is still accepted for backwards
4512             # compatibility but is ignored if set.
4513 559         1888 $rOpts->{'check-syntax'} = 0;
4514              
4515             my $check_blank_count = sub {
4516 2236     2236   5219 my ( $key, $abbrev ) = @_;
4517 2236 100       5876 if ( $rOpts->{$key} ) {
4518 1094 50       3602 if ( $rOpts->{$key} < 0 ) {
4519 0         0 $rOpts->{$key} = 0;
4520 0         0 Warn("negative value of $abbrev, setting 0\n");
4521             }
4522 1094 50       3472 if ( $rOpts->{$key} > 100 ) {
4523 0         0 Warn("unreasonably large value of $abbrev, reducing\n");
4524 0         0 $rOpts->{$key} = 100;
4525             }
4526             }
4527 2236         3645 return;
4528 559         4495 };
4529              
4530             # check for reasonable number of blank lines and fix to avoid problems
4531 559         2719 $check_blank_count->( 'blank-lines-before-subs', '-blbs' );
4532 559         2131 $check_blank_count->( 'blank-lines-before-packages', '-blbp' );
4533 559         3044 $check_blank_count->( 'blank-lines-after-block-opening', '-blao' );
4534 559         2632 $check_blank_count->( 'blank-lines-before-block-closing', '-blbc' );
4535              
4536             # setting a non-negative logfile gap causes logfile to be saved
4537 559 100 66     4228 if ( defined( $rOpts->{'logfile-gap'} ) && $rOpts->{'logfile-gap'} >= 0 ) {
4538 1         3 $rOpts->{'logfile'} = 1;
4539             }
4540              
4541             # set short-cut flag when only indentation is to be done.
4542             # Note that the user may or may not have already set the
4543             # indent-only flag.
4544 559 50 100     2754 if ( !$rOpts->{'add-whitespace'}
      66        
      33        
4545             && !$rOpts->{'delete-old-whitespace'}
4546             && !$rOpts->{'add-newlines'}
4547             && !$rOpts->{'delete-old-newlines'} )
4548             {
4549 3         13 $rOpts->{'indent-only'} = 1;
4550             }
4551              
4552             # -isbc implies -ibc
4553 559 100       2556 if ( $rOpts->{'indent-spaced-block-comments'} ) {
4554 5         15 $rOpts->{'indent-block-comments'} = 1;
4555             }
4556              
4557             # -bar cannot be used with -bl or -bli; arbitrarily keep -bar
4558 559 100       2513 if ( $rOpts->{'opening-brace-always-on-right'} ) {
4559              
4560 3 50       15 if ( $rOpts->{'opening-brace-on-new-line'} ) {
4561 0         0 Warn(<<EOM);
4562             Conflict: you specified both 'opening-brace-always-on-right' (-bar) and
4563             'opening-brace-on-new-line' (-bl). Ignoring -bl.
4564             EOM
4565 0         0 $rOpts->{'opening-brace-on-new-line'} = 0;
4566             }
4567 3 50       12 if ( $rOpts->{'brace-left-and-indent'} ) {
4568 0         0 Warn(<<EOM);
4569             Conflict: you specified both 'opening-brace-always-on-right' (-bar) and
4570             '--brace-left-and-indent' (-bli). Ignoring -bli.
4571             EOM
4572 0         0 $rOpts->{'brace-left-and-indent'} = 0;
4573             }
4574             }
4575              
4576             # it simplifies things if -bl is 0 rather than undefined
4577 559 100       2510 if ( !defined( $rOpts->{'opening-brace-on-new-line'} ) ) {
4578 537         1885 $rOpts->{'opening-brace-on-new-line'} = 0;
4579             }
4580              
4581 559 100       2516 if ( $rOpts->{'entab-leading-whitespace'} ) {
4582 2 50       12 if ( $rOpts->{'entab-leading-whitespace'} < 0 ) {
4583 0         0 Warn("-et=n must use a positive integer; ignoring -et\n");
4584 0         0 $rOpts->{'entab-leading-whitespace'} = undef;
4585             }
4586              
4587             # entab leading whitespace has priority over the older 'tabs' option
4588 2 100       9 if ( $rOpts->{'tabs'} ) {
4589              
4590             # The following warning could be added but would annoy a lot of
4591             # users who have a perltidyrc with both -t and -et=n. So instead
4592             # there is a note in the manual that -et overrides -t.
4593             ##Warn("-tabs and -et=n conflict; ignoring -tabs\n");
4594 1         5 $rOpts->{'tabs'} = 0;
4595             }
4596             }
4597              
4598             # set a default tabsize to be used in guessing the starting indentation
4599             # level if and only if this run does not use tabs and the old code does
4600             # use tabs
4601 559 50       2231 if ( $rOpts->{'default-tabsize'} ) {
4602 559 50       2529 if ( $rOpts->{'default-tabsize'} < 0 ) {
4603 0         0 Warn("negative value of -dt, setting 0\n");
4604 0         0 $rOpts->{'default-tabsize'} = 0;
4605             }
4606 559 50       2768 if ( $rOpts->{'default-tabsize'} > 20 ) {
4607 0         0 Warn("unreasonably large value of -dt, reducing\n");
4608 0         0 $rOpts->{'default-tabsize'} = 20;
4609             }
4610             }
4611             else {
4612 0         0 $rOpts->{'default-tabsize'} = 8;
4613             }
4614              
4615             # Check and clean up any sub-alias-list
4616 559 100 66     3311 if ( defined( $rOpts->{'sub-alias-list'} )
4617             && length( $rOpts->{'sub-alias-list'} ) )
4618             {
4619 3         9 my @forced_words;
4620              
4621             # include 'sub' for convenience if this option is used
4622 3         11 push @forced_words, 'sub';
4623              
4624 3         18 cleanup_word_list( $rOpts, 'sub-alias-list', \@forced_words );
4625             }
4626              
4627 559         4102 make_grep_alias_string($rOpts);
4628              
4629             # Turn on fuzzy-line-length unless this is an extrude run, as determined
4630             # by the -i and -ci settings. Otherwise blinkers can form (case b935).
4631             # This is an undocumented parameter used only for stress-testing when
4632             # --extrude is set.
4633 559 100       2762 if ( !$rOpts->{'fuzzy-line-length'} ) {
4634 6 50 33     50 if ( $rOpts->{'maximum-line-length'} != 1
4635             || $rOpts->{'continuation-indentation'} != 0 )
4636             {
4637 0         0 $rOpts->{'fuzzy-line-length'} = 1;
4638             }
4639             }
4640              
4641             # Large values of -scl can cause convergence problems, issue c167
4642 559 50       2792 if ( $rOpts->{'short-concatenation-item-length'} > 12 ) {
4643 0         0 $rOpts->{'short-concatenation-item-length'} = 12;
4644             }
4645              
4646             # The freeze-whitespace option is currently a derived option which has its
4647             # own key
4648             $rOpts->{'freeze-whitespace'} = !$rOpts->{'add-whitespace'}
4649 559   100     3249 && !$rOpts->{'delete-old-whitespace'};
4650              
4651             # Turn off certain options if whitespace is frozen
4652             # Note: vertical alignment will be automatically shut off
4653 559 100       2445 if ( $rOpts->{'freeze-whitespace'} ) {
4654 3         11 $rOpts->{'logical-padding'} = 0;
4655             }
4656              
4657             # Define $tabsize, the number of spaces per tab for use in
4658             # guessing the indentation of source lines with leading tabs.
4659             # Assume same as for this run if tabs are used, otherwise assume
4660             # a default value, typically 8
4661             $self->[_tabsize_] =
4662             $rOpts->{'entab-leading-whitespace'}
4663             ? $rOpts->{'entab-leading-whitespace'}
4664             : $rOpts->{'tabs'} ? $rOpts->{'indent-columns'}
4665 559 50       4324 : $rOpts->{'default-tabsize'};
    100          
4666              
4667             # Define the default line ending, before any -ple option is applied
4668 559         3307 $self->[_line_separator_default_] = get_line_separator_default($rOpts);
4669              
4670 559         1807 $self->[_line_tidy_begin_] = undef;
4671 559         1536 $self->[_line_tidy_end_] = undef;
4672 559         1820 my $line_range_tidy = $rOpts->{'line-range-tidy'};
4673 559 100       2402 if ($line_range_tidy) {
4674              
4675 1 50       5 if ( $num_files > 1 ) {
4676 0         0 Die(<<EOM);
4677             --line-range-tidy expects no more than 1 filename in the arg list but saw $num_files filenames
4678             EOM
4679             }
4680              
4681 1         6 $line_range_tidy =~ s/\s+//g;
4682 1 50       9 if ( $line_range_tidy =~ /^(\d+):(\d+)?$/ ) {
4683 1         5 my $n1 = $1;
4684 1         5 my $n2 = $2;
4685 1 50       8 if ( $n1 < 1 ) {
4686 0         0 Die(<<EOM);
4687             --line-range-tidy=n1:n2 expects starting line number n1>=1 but n1=$n1
4688             EOM
4689             }
4690 1 50 33     11 if ( defined($n2) && $n2 < $n1 ) {
4691 0         0 Die(<<EOM);
4692             --line-range-tidy=n1:n2 expects ending line number n2>=n1 but n1=$n1 and n2=$n2
4693             EOM
4694             }
4695 1         4 $self->[_line_tidy_begin_] = $n1;
4696 1         4 $self->[_line_tidy_end_] = $n2;
4697             }
4698             else {
4699 0         0 Die(
4700             "unrecognized 'line-range-tidy'; expecting format '-lrt=n1:n2'\n"
4701             );
4702             }
4703             }
4704              
4705 559         5160 return;
4706             } ## end sub check_options
4707              
4708             sub find_file_upwards {
4709 0     0 0 0 my ( $search_dir, $search_file ) = @_;
4710              
4711 0         0 $search_dir =~ s{/+$}{};
4712 0         0 $search_file =~ s{^/+}{};
4713              
4714 0         0 while (1) {
4715 0         0 my $try_path = "$search_dir/$search_file";
4716 0 0       0 if ( -f $try_path ) {
    0          
4717 0         0 return $try_path;
4718             }
4719             elsif ( $search_dir eq '/' ) {
4720 0         0 return;
4721             }
4722             else {
4723 0         0 $search_dir = dirname($search_dir);
4724             }
4725             }
4726              
4727             # This return is for Perl-Critic.
4728             # We shouldn't get out of the while loop without a return
4729 0         0 return;
4730             } ## end sub find_file_upwards
4731              
4732             sub expand_command_abbreviations {
4733              
4734             # go through @ARGV and expand any abbreviations
4735              
4736 775     775 0 2793 my ( $rexpansion, $rraw_options, $config_file ) = @_;
4737              
4738             # set a pass limit to prevent an infinite loop;
4739             # 10 should be plenty, but it may be increased to allow deeply
4740             # nested expansions.
4741 775         2075 my $max_passes = 10;
4742              
4743             # keep looping until all expansions have been converted into actual
4744             # dash parameters..
4745 775         3456 foreach my $pass_count ( 0 .. $max_passes ) {
4746 1102         2388 my @new_argv = ();
4747 1102         2383 my $abbrev_count = 0;
4748              
4749             # loop over each item in @ARGV..
4750 1102         2950 foreach my $word (@ARGV) {
4751              
4752             # convert any leading 'no-' to just 'no'
4753 2566 100       5692 if ( $word =~ /^(-[-]?no)-(.*)/ ) { $word = $1 . $2 }
  5         17  
4754              
4755             # if it is a dash flag (instead of a file name)..
4756 2566 50       8263 if ( $word =~ /^-[-]?([\w\-]+)(.*)/ ) {
4757              
4758 2566         4760 my $abr = $1;
4759 2566         4824 my $flags = $2;
4760              
4761             # save the raw input for debug output in case of circular refs
4762 2566 100       5111 if ( $pass_count == 0 ) {
4763 558         946 push( @{$rraw_options}, $word );
  558         1282  
4764             }
4765              
4766             # recombine abbreviation and flag, if necessary,
4767             # to allow abbreviations with arguments such as '-vt=1'
4768 2566 100       7369 if ( $rexpansion->{ $abr . $flags } ) {
4769 471         865 $abr = $abr . $flags;
4770 471         894 $flags = EMPTY_STRING;
4771             }
4772              
4773             # if we see this dash item in the expansion hash..
4774 2566 100       6243 if ( $rexpansion->{$abr} ) {
4775 949         1382 $abbrev_count++;
4776              
4777             # stuff all of the words that it expands to into the
4778             # new arg list for the next pass
4779 949         1398 foreach my $abbrev ( @{ $rexpansion->{$abr} } ) {
  949         2436  
4780 1452 50       2794 next unless $abbrev; # for safety; shouldn't happen
4781 1452         4397 push( @new_argv, '--' . $abbrev . $flags );
4782             }
4783             }
4784              
4785             # not in expansion hash, must be actual long name
4786             else {
4787 1617         3352 push( @new_argv, $word );
4788             }
4789             }
4790              
4791             # not a dash item, so just save it for the next pass
4792             else {
4793 0         0 push( @new_argv, $word );
4794             }
4795             } ## end of this pass
4796              
4797             # update parameter list @ARGV to the new one
4798 1102         3304 @ARGV = @new_argv;
4799 1102 100       4024 last if ( !$abbrev_count );
4800              
4801             # make sure we are not in an infinite loop
4802 327 50       1354 if ( $pass_count == $max_passes ) {
4803 0         0 local $LIST_SEPARATOR = ')(';
4804 0         0 Warn(<<EOM);
4805             I'm tired. We seem to be in an infinite loop trying to expand aliases.
4806             Here are the raw options;
4807             (rraw_options)
4808             EOM
4809 0         0 my $num = @new_argv;
4810 0 0       0 if ( $num < 50 ) {
4811 0         0 Warn(<<EOM);
4812             After $max_passes passes here is ARGV
4813             (@new_argv)
4814             EOM
4815             }
4816             else {
4817 0         0 Warn(<<EOM);
4818             After $max_passes passes ARGV has $num entries
4819             EOM
4820             }
4821              
4822 0 0       0 if ($config_file) {
4823 0         0 Die(<<"DIE");
4824             Please check your configuration file $config_file for circular-references.
4825             To deactivate it, use -npro.
4826             DIE
4827             }
4828             else {
4829 0         0 Die(<<'DIE');
4830             Program bug - circular-references in the %expansion hash, probably due to
4831             a recent program change.
4832             DIE
4833             }
4834             } ## end of check for circular references
4835             } ## end of loop over all passes
4836 775         2240 return;
4837             } ## end sub expand_command_abbreviations
4838              
4839             # Debug routine -- this will dump the expansion hash
4840             sub dump_short_names {
4841 0     0 0 0 my $rexpansion = shift;
4842 0         0 print {*STDOUT} <<EOM;
  0         0  
4843             List of short names. This list shows how all abbreviations are
4844             translated into other abbreviations and, eventually, into long names.
4845             New abbreviations may be defined in a .perltidyrc file.
4846             For a list of all long names, use perltidy --dump-long-names (-dln).
4847             --------------------------------------------------------------------------
4848             EOM
4849 0         0 foreach my $abbrev ( sort keys %{$rexpansion} ) {
  0         0  
4850 0         0 my @list = @{ $rexpansion->{$abbrev} };
  0         0  
4851 0         0 print {*STDOUT} "$abbrev --> @list\n";
  0         0  
4852             }
4853 0         0 return;
4854             } ## end sub dump_short_names
4855              
4856             sub check_vms_filename {
4857              
4858             # given a valid filename (the perltidy input file)
4859             # create a modified filename and separator character
4860             # suitable for VMS.
4861             #
4862             # Contributed by Michael Cartmell
4863             #
4864 0     0 0 0 my $filename = shift;
4865 0         0 my ( $base, $path ) = fileparse($filename);
4866              
4867             # remove explicit ; version
4868 0 0       0 $base =~ s/;-?\d*$//
4869              
4870             # remove explicit . version ie two dots in filename NB ^ escapes a dot
4871             or $base =~ s{( # begin capture $1
4872             (?:^|[^^])\. # match a dot not preceded by a caret
4873             (?: # followed by nothing
4874             | # or
4875             .*[^^] # anything ending in a non caret
4876             )
4877             ) # end capture $1
4878             \.-?\d*$ # match . version number
4879             }{$1}x;
4880              
4881             # normalize filename, if there are no unescaped dots then append one
4882 0 0       0 $base .= '.' unless $base =~ /(?:^|[^^])\./;
4883              
4884             # if we don't already have an extension then we just append the extension
4885 0 0       0 my $separator = ( $base =~ /\.$/ ) ? EMPTY_STRING : "_";
4886 0         0 return ( $path . $base, $separator );
4887             } ## end sub check_vms_filename
4888              
4889             sub Win_OS_Type {
4890              
4891             # TODO: are these more standard names?
4892             # Win32s Win95 Win98 WinMe WinNT3.51 WinNT4 Win2000 WinXP/.Net Win2003
4893              
4894             # Returns a string that determines what MS OS we are on.
4895             # Returns win32s,95,98,Me,NT3.51,NT4,2000,XP/.Net,Win2003
4896             # Returns blank string if not an MS system.
4897             # Original code contributed by: Yves Orton
4898             # We need to know this to decide where to look for config files
4899              
4900 0     0 0 0 my $rpending_complaint = shift;
4901 0         0 my $os = EMPTY_STRING;
4902 0 0       0 return $os unless $OSNAME =~ /win32|dos/i; # is it a MS box?
4903              
4904             # Systems built from Perl source may not have Win32.pm
4905             # But probably have Win32::GetOSVersion() anyway so the
4906             # following line is not 'required':
4907             # return $os unless eval('require Win32');
4908              
4909             # Use the standard API call to determine the version
4910 0         0 my ( $undef, $major, $minor, $build, $id );
4911 0         0 my $ok = eval {
4912 0         0 ( $undef, $major, $minor, $build, $id ) = Win32::GetOSVersion();
4913 0         0 1;
4914             };
4915 0 0 0     0 if ( !$ok && DEVEL_MODE ) {
4916 0         0 Fault("Could not cal Win32::GetOSVersion(): $EVAL_ERROR\n");
4917             }
4918              
4919             #
4920             # NAME ID MAJOR MINOR
4921             # Windows NT 4 2 4 0
4922             # Windows 2000 2 5 0
4923             # Windows XP 2 5 1
4924             # Windows Server 2003 2 5 2
4925              
4926 0 0       0 return "win32s" unless $id; # If id==0 then its a win32s box.
4927             $os = { # Magic numbers from MSDN
4928             # documentation of GetOSVersion
4929             1 => {
4930             0 => "95",
4931             10 => "98",
4932             90 => "Me",
4933             },
4934             2 => {
4935             0 => "2000", # or NT 4, see below
4936             1 => "XP/.Net",
4937             2 => "Win2003",
4938             51 => "NT3.51",
4939             }
4940 0         0 }->{$id}->{$minor};
4941              
4942             # If $os is undefined, the above code is out of date. Suggested updates
4943             # are welcome.
4944 0 0       0 if ( !defined($os) ) {
4945 0         0 $os = EMPTY_STRING;
4946              
4947             # Deactivated this message 20180322 because it was needlessly
4948             # causing some test scripts to fail. Need help from someone
4949             # with expertise in Windows to decide what is possible with windows.
4950 0         0 ${$rpending_complaint} .= <<EOS if (0);
4951             Error trying to discover Win_OS_Type: $id:$major:$minor Has no name of record!
4952             We won't be able to look for a system-wide config file.
4953             EOS
4954             }
4955              
4956             # Unfortunately the logic used for the various versions isn't so clever..
4957             # so we have to handle an outside case.
4958 0 0 0     0 return ( $os eq "2000" && $major != 5 ) ? "NT4" : $os;
4959             } ## end sub Win_OS_Type
4960              
4961             sub look_for_Windows {
4962              
4963             # determine Windows sub-type and location of
4964             # system-wide configuration files
4965 559     559 0 1396 my $rpending_complaint = shift;
4966 559         5543 my $is_Windows = ( $OSNAME =~ /win32|dos/i );
4967 559         1272 my $Windows_type;
4968 559 50       1902 $Windows_type = Win_OS_Type($rpending_complaint) if $is_Windows;
4969 559         1969 return ( $is_Windows, $Windows_type );
4970             } ## end sub look_for_Windows
4971              
4972             sub find_config_file {
4973              
4974             # look for a .perltidyrc configuration file
4975             # For Windows also look for a file named perltidy.ini
4976 0     0 0 0 my ( $is_Windows, $Windows_type, $rconfig_file_chatter,
4977             $rpending_complaint )
4978             = @_;
4979              
4980 0         0 ${$rconfig_file_chatter} .= "# Config file search...system reported as:";
  0         0  
4981 0 0       0 if ($is_Windows) {
4982 0         0 ${$rconfig_file_chatter} .= "Windows $Windows_type\n";
  0         0  
4983             }
4984             else {
4985 0         0 ${$rconfig_file_chatter} .= " $OSNAME\n";
  0         0  
4986             }
4987              
4988             # sub to check file existence and record all tests
4989             my $exists_config_file = sub {
4990 0     0   0 my $config_file = shift;
4991 0 0       0 return 0 unless $config_file;
4992 0         0 ${$rconfig_file_chatter} .= "# Testing: $config_file\n";
  0         0  
4993 0         0 return -f $config_file;
4994 0         0 };
4995              
4996             # Sub to search upward for config file
4997             my $resolve_config_file = sub {
4998              
4999             # resolve <dir>/.../<file>, meaning look upwards from directory
5000 0     0   0 my $config_file = shift;
5001 0 0       0 if ($config_file) {
5002 0 0       0 if ( my ( $start_dir, $search_file ) =
5003             ( $config_file =~ m{^(.*)\.\.\./(.*)$} ) )
5004             {
5005 0         0 ${$rconfig_file_chatter} .=
  0         0  
5006             "# Searching Upward: $config_file\n";
5007 0 0       0 $start_dir = '.' if !$start_dir;
5008 0         0 $start_dir = Cwd::realpath($start_dir);
5009 0 0       0 if ( my $found_file =
5010             find_file_upwards( $start_dir, $search_file ) )
5011             {
5012 0         0 $config_file = $found_file;
5013 0         0 ${$rconfig_file_chatter} .= "# Found: $config_file\n";
  0         0  
5014             }
5015             }
5016             }
5017 0         0 return $config_file;
5018 0         0 };
5019              
5020 0         0 my $config_file;
5021              
5022             # look in current directory first
5023 0         0 $config_file = ".perltidyrc";
5024 0 0       0 return $config_file if $exists_config_file->($config_file);
5025 0 0       0 if ($is_Windows) {
5026 0         0 $config_file = "perltidy.ini";
5027 0 0       0 return $config_file if $exists_config_file->($config_file);
5028             }
5029              
5030             # Default environment vars.
5031 0         0 my @envs = qw(PERLTIDY HOME);
5032              
5033             # Check the NT/2k/XP locations, first a local machine def, then a
5034             # network def
5035 0 0       0 push @envs, qw(USERPROFILE HOMESHARE) if $OSNAME =~ /win32/i;
5036              
5037             # Now go through the environment ...
5038 0         0 foreach my $var (@envs) {
5039 0         0 ${$rconfig_file_chatter} .= "# Examining: \$ENV{$var}";
  0         0  
5040 0 0       0 if ( defined( $ENV{$var} ) ) {
5041 0         0 ${$rconfig_file_chatter} .= " = $ENV{$var}\n";
  0         0  
5042              
5043             # test ENV{ PERLTIDY } as file:
5044 0 0       0 if ( $var eq 'PERLTIDY' ) {
5045 0         0 $config_file = "$ENV{$var}";
5046 0         0 $config_file = $resolve_config_file->($config_file);
5047 0 0       0 return $config_file if $exists_config_file->($config_file);
5048             }
5049              
5050             # test ENV as directory:
5051 0         0 $config_file = catfile( $ENV{$var}, ".perltidyrc" );
5052 0         0 $config_file = $resolve_config_file->($config_file);
5053 0 0       0 return $config_file if $exists_config_file->($config_file);
5054              
5055 0 0       0 if ($is_Windows) {
5056 0         0 $config_file = catfile( $ENV{$var}, "perltidy.ini" );
5057 0         0 $config_file = $resolve_config_file->($config_file);
5058 0 0       0 return $config_file if $exists_config_file->($config_file);
5059             }
5060             }
5061             else {
5062 0         0 ${$rconfig_file_chatter} .= "\n";
  0         0  
5063             }
5064             }
5065              
5066             # then look for a system-wide definition
5067             # where to look varies with OS
5068 0 0       0 if ($is_Windows) {
    0          
    0          
    0          
5069              
5070 0 0       0 if ($Windows_type) {
5071 0         0 my ( $os, $system, $allusers ) =
5072             Win_Config_Locs( $rpending_complaint, $Windows_type );
5073              
5074             # Check All Users directory, if there is one.
5075             # i.e. C:\Documents and Settings\User\perltidy.ini
5076 0 0       0 if ($allusers) {
5077              
5078 0         0 $config_file = catfile( $allusers, ".perltidyrc" );
5079 0 0       0 return $config_file if $exists_config_file->($config_file);
5080              
5081 0         0 $config_file = catfile( $allusers, "perltidy.ini" );
5082 0 0       0 return $config_file if $exists_config_file->($config_file);
5083             }
5084              
5085             # Check system directory.
5086             # retain old code in case someone has been able to create
5087             # a file with a leading period.
5088 0         0 $config_file = catfile( $system, ".perltidyrc" );
5089 0 0       0 return $config_file if $exists_config_file->($config_file);
5090              
5091 0         0 $config_file = catfile( $system, "perltidy.ini" );
5092 0 0       0 return $config_file if $exists_config_file->($config_file);
5093             }
5094             }
5095              
5096             # Place to add customization code for other systems
5097             elsif ( $OSNAME eq 'OS2' ) {
5098             }
5099             elsif ( $OSNAME eq 'MacOS' ) {
5100             }
5101             elsif ( $OSNAME eq 'VMS' ) {
5102             }
5103              
5104             # Assume some kind of Unix
5105             else {
5106              
5107 0         0 $config_file = "/usr/local/etc/perltidyrc";
5108 0 0       0 return $config_file if $exists_config_file->($config_file);
5109              
5110 0         0 $config_file = "/etc/perltidyrc";
5111 0 0       0 return $config_file if $exists_config_file->($config_file);
5112             }
5113              
5114             # Couldn't find a config file
5115 0         0 return;
5116             } ## end sub find_config_file
5117              
5118             sub Win_Config_Locs {
5119              
5120             # In scalar context returns the OS name (95 98 ME NT3.51 NT4 2000 XP),
5121             # or undef if its not a win32 OS. In list context returns OS, System
5122             # Directory, and All Users Directory. All Users will be empty on a
5123             # 9x/Me box. Contributed by: Yves Orton.
5124              
5125 0     0 0 0 my ( $rpending_complaint, $os ) = @_;
5126 0 0       0 if ( !$os ) { $os = Win_OS_Type(); }
  0         0  
5127              
5128 0 0       0 return unless $os;
5129              
5130 0         0 my $system = EMPTY_STRING;
5131 0         0 my $allusers = EMPTY_STRING;
5132              
5133 0 0       0 if ( $os =~ /9[58]|Me/ ) {
    0          
5134 0         0 $system = "C:/Windows";
5135             }
5136             elsif ( $os =~ /NT|XP|200?/ ) {
5137 0 0       0 $system = ( $os =~ /XP/ ) ? "C:/Windows/" : "C:/WinNT/";
5138 0 0       0 $allusers =
5139             ( $os =~ /NT/ )
5140             ? "C:/WinNT/profiles/All Users/"
5141             : "C:/Documents and Settings/All Users/";
5142             }
5143             else {
5144              
5145             # This currently would only happen on a win32s computer. I don't have
5146             # one to test, so I am unsure how to proceed. Suggestions welcome!
5147 0         0 ${$rpending_complaint} .=
  0         0  
5148             "I dont know a sensible place to look for config files on an $os system.\n";
5149 0         0 return;
5150             }
5151 0 0       0 return wantarray ? ( $os, $system, $allusers ) : $os;
5152             } ## end sub Win_Config_Locs
5153              
5154             sub dump_config_file {
5155 0     0 0 0 my ( $rconfig_string, $config_file, $rconfig_file_chatter ) = @_;
5156 0         0 print {*STDOUT} "${$rconfig_file_chatter}";
  0         0  
  0         0  
5157 0 0       0 if ($rconfig_string) {
5158 0         0 my @lines = split /^/, ${$rconfig_string};
  0         0  
5159 0         0 print {*STDOUT} "# Dump of file: '$config_file'\n";
  0         0  
5160 0         0 while ( defined( my $line = shift @lines ) ) { print {*STDOUT} $line }
  0         0  
  0         0  
5161             }
5162             else {
5163 0         0 print {*STDOUT} "# ...no config file found\n";
  0         0  
5164             }
5165 0         0 return;
5166             } ## end sub dump_config_file
5167              
5168             sub read_config_file {
5169              
5170 551     551 0 2629 my ( $rconfig_string, $config_file, $rexpansion ) = @_;
5171 551         1593 my @config_list = ();
5172              
5173             # file is bad if non-empty $death_message is returned
5174 551         1520 my $death_message = EMPTY_STRING;
5175              
5176 551         1376 my $name = undef;
5177 551         1684 my $line_no;
5178             my $opening_brace_line;
5179 551         1254 my @lines = split /^/, ${$rconfig_string};
  551         3884  
5180 551         2825 while ( defined( my $line = shift @lines ) ) {
5181 431         966 $line_no++;
5182 431         1107 chomp $line;
5183 431         1474 ( $line, $death_message ) =
5184             strip_comment( $line, $config_file, $line_no );
5185 431 50       1339 last if ($death_message);
5186 431 100       1282 next unless $line;
5187 397         3143 $line =~ s/^\s*(.*?)\s*$/$1/; # trim both ends
5188 397 50       1395 next unless $line;
5189              
5190 397         1004 my $body = $line;
5191              
5192             # Look for complete or partial abbreviation definition of the form
5193             # name { body } or name { or name { body
5194             # See rules in perltidy's perldoc page
5195             # Section: Other Controls - Creating a new abbreviation
5196 397 50       2451 if ( $line =~ /^((\w+)\s*\{)(.*)?$/ ) {
    50          
    50          
5197 0         0 ( $name, $body ) = ( $2, $3 );
5198              
5199             # Cannot start new abbreviation unless old abbreviation is complete
5200 0 0       0 last if ($opening_brace_line);
5201              
5202 0 0 0     0 $opening_brace_line = $line_no unless ( $body && $body =~ s/\}$// );
5203              
5204             # handle a new alias definition
5205 0 0       0 if ( $rexpansion->{$name} ) {
5206 0         0 local $LIST_SEPARATOR = ')(';
5207 0         0 my @names = sort keys %{$rexpansion};
  0         0  
5208 0         0 $death_message =
5209             "Here is a list of all installed aliases\n(@names)\n"
5210             . "Attempting to redefine alias ($name) in config file $config_file line $INPUT_LINE_NUMBER\n";
5211 0         0 last;
5212             }
5213 0         0 $rexpansion->{$name} = [];
5214             }
5215              
5216             # leading opening braces not allowed
5217             elsif ( $line =~ /^{/ ) {
5218 0         0 $opening_brace_line = undef;
5219 0         0 $death_message =
5220             "Unexpected '{' at line $line_no in config file '$config_file'\n";
5221 0         0 last;
5222             }
5223              
5224             # Look for abbreviation closing: body } or }
5225             elsif ( $line =~ /^(.*)?\}$/ ) {
5226 0         0 $body = $1;
5227 0 0       0 if ($opening_brace_line) {
5228 0         0 $opening_brace_line = undef;
5229             }
5230             else {
5231 0         0 $death_message =
5232             "Unexpected '}' at line $line_no in config file '$config_file'\n";
5233 0         0 last;
5234             }
5235             }
5236             else {
5237             ## done
5238             }
5239              
5240             # Now store any parameters
5241 397 50       1162 if ($body) {
5242              
5243 397         1395 my ( $rbody_parts, $msg ) = parse_args($body);
5244 397 50       1376 if ($msg) {
5245 0         0 $death_message = <<EOM;
5246             Error reading file '$config_file' at line number $line_no.
5247             $msg
5248             Please fix this line or use -npro to avoid reading this file
5249             EOM
5250 0         0 last;
5251             }
5252              
5253 397 50       1146 if ($name) {
5254              
5255             # remove leading dashes if this is an alias
5256 0         0 foreach ( @{$rbody_parts} ) { s/^\-+//; }
  0         0  
  0         0  
5257 0         0 push @{ $rexpansion->{$name} }, @{$rbody_parts};
  0         0  
  0         0  
5258             }
5259             else {
5260 397         721 push( @config_list, @{$rbody_parts} );
  397         3091  
5261             }
5262             }
5263             }
5264              
5265 551 50       2325 if ($opening_brace_line) {
5266 0         0 $death_message =
5267             "Didn't see a '}' to match the '{' at line $opening_brace_line in config file '$config_file'\n";
5268             }
5269 551         2549 return ( \@config_list, $death_message );
5270             } ## end sub read_config_file
5271              
5272             sub strip_comment {
5273              
5274             # Strip any comment from a command line
5275 431     431 0 1290 my ( $instr, $config_file, $line_no ) = @_;
5276 431         870 my $msg = EMPTY_STRING;
5277              
5278             # check for full-line comment
5279 431 100       1660 if ( $instr =~ /^\s*#/ ) {
5280 29         129 return ( EMPTY_STRING, $msg );
5281             }
5282              
5283             # nothing to do if no comments
5284 402 100       1433 if ( $instr !~ /#/ ) {
5285 373         1196 return ( $instr, $msg );
5286             }
5287              
5288             # handle case of no quotes
5289 29 100       117 if ( $instr !~ /['"]/ ) {
5290              
5291             # We now require a space before the # of a side comment
5292             # this allows something like:
5293             # -sbcp=#
5294             # Otherwise, it would have to be quoted:
5295             # -sbcp='#'
5296 16         61 $instr =~ s/\s+\#.*$//;
5297 16         45 return ( $instr, $msg );
5298             }
5299              
5300             # handle comments and quotes
5301 13         33 my $outstr = EMPTY_STRING;
5302 13         40 my $quote_char = EMPTY_STRING;
5303 13         29 while (1) {
5304              
5305             # looking for ending quote character
5306 357 100       486 if ($quote_char) {
5307 64 100       291 if ( $instr =~ /\G($quote_char)/gc ) {
    50          
5308 12         48 $quote_char = EMPTY_STRING;
5309 12         30 $outstr .= $1;
5310             }
5311             elsif ( $instr =~ /\G(.)/gc ) {
5312 52         112 $outstr .= $1;
5313             }
5314              
5315             # error..we reached the end without seeing the ending quote char
5316             else {
5317 0         0 $msg = <<EOM;
5318             Error reading file $config_file at line number $line_no.
5319             Did not see ending quote character <$quote_char> in this text:
5320             $instr
5321             Please fix this line or use -npro to avoid reading this file
5322             EOM
5323 0         0 last;
5324             }
5325             }
5326              
5327             # accumulating characters and looking for start of a quoted string
5328             else {
5329 293 100       797 if ( $instr =~ /\G([\"\'])/gc ) {
    100          
    100          
5330 12         45 $outstr .= $1;
5331 12         30 $quote_char = $1;
5332             }
5333              
5334             # Note: not yet enforcing the space-before-hash rule for side
5335             # comments if the parameter is quoted.
5336             elsif ( $instr =~ /\G#/gc ) {
5337 8         31 last;
5338             }
5339             elsif ( $instr =~ /\G(.)/gc ) {
5340 268         472 $outstr .= $1;
5341             }
5342             else {
5343 5         14 last;
5344             }
5345             }
5346             }
5347 13         70 return ( $outstr, $msg );
5348             } ## end sub strip_comment
5349              
5350             sub parse_args {
5351              
5352             # Parse a command string containing multiple string with possible
5353             # quotes, into individual commands. It might look like this, for example:
5354             #
5355             # -wba=" + - " -some-thing -wbb='. && ||'
5356             #
5357             # There is no need, at present, to handle escaped quote characters.
5358             # (They are not perltidy tokens, so needn't be in strings).
5359              
5360 956     956 0 2437 my ($body) = @_;
5361 956         2226 my @body_parts = ();
5362 956         2031 my $quote_char = EMPTY_STRING;
5363 956         1839 my $part = EMPTY_STRING;
5364 956         1851 my $msg = EMPTY_STRING;
5365              
5366             # Check for external call with undefined $body - added to fix
5367             # github issue Perl-Tidy-Sweetened issue #23
5368 956 50       2954 if ( !defined($body) ) { $body = EMPTY_STRING }
  0         0  
5369              
5370 956         1874 while (1) {
5371              
5372             # looking for ending quote character
5373 5641 100       8769 if ($quote_char) {
5374 615 100       2190 if ( $body =~ /\G($quote_char)/gc ) {
    50          
5375 71         213 $quote_char = EMPTY_STRING;
5376             }
5377             elsif ( $body =~ /\G(.)/gc ) {
5378 544         974 $part .= $1;
5379             }
5380              
5381             # error..we reached the end without seeing the ending quote char
5382             else {
5383 0 0       0 if ( length($part) ) { push @body_parts, $part; }
  0         0  
5384 0         0 $msg = <<EOM;
5385             Did not see ending quote character <$quote_char> in this text:
5386             $body
5387             EOM
5388 0         0 last;
5389             }
5390             }
5391              
5392             # accumulating characters and looking for start of a quoted string
5393             else {
5394 5026 100       16475 if ( $body =~ /\G([\"\'])/gc ) {
    100          
    100          
5395 71         304 $quote_char = $1;
5396             }
5397             elsif ( $body =~ /\G(\s+)/gc ) {
5398 155 50       749 if ( length($part) ) { push @body_parts, $part; }
  155         511  
5399 155         297 $part = EMPTY_STRING;
5400             }
5401             elsif ( $body =~ /\G(.)/gc ) {
5402 3844         6435 $part .= $1;
5403             }
5404             else {
5405 956 100       3422 if ( length($part) ) { push @body_parts, $part; }
  409         1211  
5406 956         1888 last;
5407             }
5408             }
5409             }
5410 956         3748 return ( \@body_parts, $msg );
5411             } ## end sub parse_args
5412              
5413             sub dump_long_names {
5414              
5415 0     0 0 0 my @names = @_;
5416 0         0 print {*STDOUT} <<EOM;
  0         0  
5417             # Command line long names (passed to GetOptions)
5418             #--------------------------------------------------
5419             # here is a summary of the Getopt codes:
5420             # <none> does not take an argument
5421             # =s takes a mandatory string
5422             # :s takes an optional string
5423             # =i takes a mandatory integer
5424             # :i takes an optional integer
5425             # ! does not take an argument and may be negated
5426             # i.e., -foo and -nofoo are allowed
5427             # a double dash signals the end of the options list
5428             #
5429             #--------------------------------------------------
5430             EOM
5431              
5432 0         0 foreach my $name ( sort @names ) { print {*STDOUT} "$name\n" }
  0         0  
  0         0  
5433 0         0 return;
5434             } ## end sub dump_long_names
5435              
5436             sub dump_defaults {
5437 0     0 0 0 my @defaults = @_;
5438 0         0 print {*STDOUT} "Default command line options:\n";
  0         0  
5439 0         0 foreach my $line ( sort @defaults ) { print {*STDOUT} "$line\n" }
  0         0  
  0         0  
5440 0         0 return;
5441             } ## end sub dump_defaults
5442              
5443             sub readable_options {
5444              
5445             # return options for this run as a string which could be
5446             # put in a perltidyrc file
5447 559     559 0 2021 my ( $rOpts, $roption_string ) = @_;
5448 559         1352 my %Getopt_flags;
5449 559         1577 my $rGetopt_flags = \%Getopt_flags;
5450 559         1844 my $readable_options = "# Final parameter set for this run.\n";
5451 559         1780 $readable_options .=
5452             "# See utility 'perltidyrc_dump.pl' for nicer formatting.\n";
5453 559         1440 foreach my $opt ( @{$roption_string} ) {
  559         2018  
5454 186147         231111 my $flag = EMPTY_STRING;
5455 186147 100       538385 if ( $opt =~ /(.*)(!|=.*)$/ ) {
5456 178797         319443 $opt = $1;
5457 178797         234661 $flag = $2;
5458             }
5459 186147 100       359027 if ( defined( $rOpts->{$opt} ) ) {
5460 64598         128250 $rGetopt_flags->{$opt} = $flag;
5461             }
5462             }
5463 559         3290 foreach my $key ( sort keys %{$rOpts} ) {
  559         58950  
5464 64605         100647 my $flag = $rGetopt_flags->{$key};
5465 64605         91677 my $value = $rOpts->{$key};
5466 64605         79751 my $prefix = '--';
5467 64605         75816 my $suffix = EMPTY_STRING;
5468 64605 100       100828 if ($flag) {
5469 64350 100       136423 if ( $flag =~ /^=/ ) {
    50          
5470 32406 100       72040 if ( $value !~ /^\d+$/ ) { $value = '"' . $value . '"' }
  2874         6079  
5471 32406         46586 $suffix = "=" . $value;
5472             }
5473             elsif ( $flag =~ /^!/ ) {
5474 31944 100       55705 $prefix .= "no" unless ($value);
5475             }
5476             else {
5477              
5478             # shouldn't happen
5479 0         0 $readable_options .=
5480             "# ERROR in dump_options: unrecognized flag $flag for $key\n";
5481             }
5482             }
5483 64605         127693 $readable_options .= $prefix . $key . $suffix . "\n";
5484             }
5485 559         24604 return $readable_options;
5486             } ## end sub readable_options
5487              
5488             sub show_version {
5489 0     0 0 0 print {*STDOUT} <<"EOM";
  0         0  
5490             This is perltidy, v$VERSION
5491              
5492             Copyright 2000-2023, Steve Hancock
5493              
5494             Perltidy is free software and may be copied under the terms of the GNU
5495             General Public License, which is included in the distribution files.
5496              
5497             Complete documentation for perltidy can be found using 'man perltidy'
5498             or on the internet at http://perltidy.sourceforge.net.
5499             EOM
5500 0         0 return;
5501             } ## end sub show_version
5502              
5503             sub usage {
5504              
5505 0     0 0 0 print {*STDOUT} <<EOF;
  0         0  
5506             This is perltidy version $VERSION, a perl script indenter. Usage:
5507              
5508             perltidy [ options ] file1 file2 file3 ...
5509             (output goes to file1.tdy, file2.tdy, file3.tdy, ...)
5510             perltidy [ options ] file1 -o outfile
5511             perltidy [ options ] file1 -st >outfile
5512             perltidy [ options ] <infile >outfile
5513              
5514             Options have short and long forms. Short forms are shown; see
5515             man pages for long forms. Note: '=s' indicates a required string,
5516             and '=n' indicates a required integer.
5517              
5518             I/O control
5519             -h show this help
5520             -o=file name of the output file (only if single input file)
5521             -oext=s change output extension from 'tdy' to s
5522             -opath=path change path to be 'path' for output files
5523             -b backup original to .bak and modify file in-place
5524             -bext=s change default backup extension from 'bak' to s
5525             -q deactivate error messages (for running under editor)
5526             -w include non-critical warning messages in the .ERR error output
5527             -log save .LOG file, which has useful diagnostics
5528             -f force perltidy to read a binary file
5529             -g like -log but writes more detailed .LOG file, for debugging scripts
5530             -opt write the set of options actually used to a .LOG file
5531             -npro ignore .perltidyrc configuration command file
5532             -pro=file read configuration commands from file instead of .perltidyrc
5533             -st send output to standard output, STDOUT
5534             -se send all error output to standard error output, STDERR
5535             -v display version number to standard output and quit
5536              
5537             Basic Options:
5538             -i=n use n columns per indentation level (default n=4)
5539             -t tabs: use one tab character per indentation level, not recommended
5540             -nt no tabs: use n spaces per indentation level (default)
5541             -et=n entab leading whitespace n spaces per tab; not recommended
5542             -io "indent only": just do indentation, no other formatting.
5543             -sil=n set starting indentation level to n; use if auto detection fails
5544             -ole=s specify output line ending (s=dos or win, mac, unix)
5545             -ple keep output line endings same as input (input must be filename)
5546              
5547             Whitespace Control
5548             -fws freeze whitespace; this disables all whitespace changes
5549             and disables the following switches:
5550             -bt=n sets brace tightness, n= (0 = loose, 1=default, 2 = tight)
5551             -bbt same as -bt but for code block braces; same as -bt if not given
5552             -bbvt block braces vertically tight; use with -bl or -bli
5553             -bbvtl=s make -bbvt to apply to selected list of block types
5554             -pt=n paren tightness (n=0, 1 or 2)
5555             -sbt=n square bracket tightness (n=0, 1, or 2)
5556             -bvt=n brace vertical tightness,
5557             n=(0=open, 1=close unless multiple steps on a line, 2=always close)
5558             -pvt=n paren vertical tightness (see -bvt for n)
5559             -sbvt=n square bracket vertical tightness (see -bvt for n)
5560             -bvtc=n closing brace vertical tightness:
5561             n=(0=open, 1=sometimes close, 2=always close)
5562             -pvtc=n closing paren vertical tightness, see -bvtc for n.
5563             -sbvtc=n closing square bracket vertical tightness, see -bvtc for n.
5564             -ci=n sets continuation indentation=n, default is n=2 spaces
5565             -lp line up parentheses, brackets, and non-BLOCK braces
5566             -sfs add space before semicolon in for( ; ; )
5567             -aws allow perltidy to add whitespace (default)
5568             -dws delete all old non-essential whitespace
5569             -icb indent closing brace of a code block
5570             -cti=n closing indentation of paren, square bracket, or non-block brace:
5571             n=0 none, =1 align with opening, =2 one full indentation level
5572             -icp equivalent to -cti=2
5573             -wls=s want space left of tokens in string; i.e. -nwls='+ - * /'
5574             -wrs=s want space right of tokens in string;
5575             -sts put space before terminal semicolon of a statement
5576             -sak=s put space between keywords given in s and '(';
5577             -nsak=s no space between keywords in s and '('; i.e. -nsak='my our local'
5578              
5579             Line Break Control
5580             -fnl freeze newlines; this disables all line break changes
5581             and disables the following switches:
5582             -anl add newlines; ok to introduce new line breaks
5583             -bbs add blank line before subs and packages
5584             -bbc add blank line before block comments
5585             -bbb add blank line between major blocks
5586             -kbl=n keep old blank lines? 0=no, 1=some, 2=all
5587             -mbl=n maximum consecutive blank lines to output (default=1)
5588             -ce cuddled else; use this style: '} else {'
5589             -cb cuddled blocks (other than 'if-elsif-else')
5590             -cbl=s list of blocks to cuddled, default 'try-catch-finally'
5591             -dnl delete old newlines (default)
5592             -l=n maximum line length; default n=80
5593             -bl opening brace on new line
5594             -sbl opening sub brace on new line. value of -bl is used if not given.
5595             -bli opening brace on new line and indented
5596             -bar opening brace always on right, even for long clauses
5597             -vt=n vertical tightness (requires -lp); n controls break after opening
5598             token: 0=never 1=no break if next line balanced 2=no break
5599             -vtc=n vertical tightness of closing container; n controls if closing
5600             token starts new line: 0=always 1=not unless list 1=never
5601             -wba=s want break after tokens in string; i.e. wba=': .'
5602             -wbb=s want break before tokens in string
5603             -wn weld nested: combines opening and closing tokens when both are adjacent
5604             -wnxl=s weld nested exclusion list: provides some control over the types of
5605             containers which can be welded
5606              
5607             Following Old Breakpoints
5608             -kis keep interior semicolons. Allows multiple statements per line.
5609             -boc break at old comma breaks: turns off all automatic list formatting
5610             -bol break at old logical breakpoints: or, and, ||, && (default)
5611             -bom break at old method call breakpoints: ->
5612             -bok break at old list keyword breakpoints such as map, sort (default)
5613             -bot break at old conditional (ternary ?:) operator breakpoints (default)
5614             -boa break at old attribute breakpoints
5615             -cab=n break at commas after a comma-arrow (=>):
5616             n=0 break at all commas after =>
5617             n=1 stable: break unless this breaks an existing one-line container
5618             n=2 break only if a one-line container cannot be formed
5619             n=3 do not treat commas after => specially at all
5620              
5621             Comment controls
5622             -ibc indent block comments (default)
5623             -isbc indent spaced block comments; may indent unless no leading space
5624             -msc=n minimum desired spaces to side comment, default 4
5625             -fpsc=n fix position for side comments; default 0;
5626             -csc add or update closing side comments after closing BLOCK brace
5627             -dcsc delete closing side comments created by a -csc command
5628             -cscp=s change closing side comment prefix to be other than '## end'
5629             -cscl=s change closing side comment to apply to selected list of blocks
5630             -csci=n minimum number of lines needed to apply a -csc tag, default n=6
5631             -csct=n maximum number of columns of appended text, default n=20
5632             -cscw causes warning if old side comment is overwritten with -csc
5633              
5634             -sbc use 'static block comments' identified by leading '##' (default)
5635             -sbcp=s change static block comment identifier to be other than '##'
5636             -osbc outdent static block comments
5637              
5638             -ssc use 'static side comments' identified by leading '##' (default)
5639             -sscp=s change static side comment identifier to be other than '##'
5640              
5641             Delete selected text
5642             -dac delete all comments AND pod
5643             -dbc delete block comments
5644             -dsc delete side comments
5645             -dp delete pod
5646              
5647             Send selected text to a '.TEE' file
5648             -tac tee all comments AND pod
5649             -tbc tee block comments
5650             -tsc tee side comments
5651             -tp tee pod
5652              
5653             Outdenting
5654             -olq outdent long quoted strings (default)
5655             -olc outdent a long block comment line
5656             -ola outdent statement labels
5657             -okw outdent control keywords (redo, next, last, goto, return)
5658             -okwl=s specify alternative keywords for -okw command
5659              
5660             Other controls
5661             -mft=n maximum fields per table; default n=0 (no limit)
5662             -x do not format lines before hash-bang line (i.e., for VMS)
5663             -asc allows perltidy to add a ';' when missing (default)
5664             -dsm allows perltidy to delete an unnecessary ';' (default)
5665              
5666             Combinations of other parameters
5667             -gnu attempt to follow GNU Coding Standards as applied to perl
5668             -mangle remove as many newlines as possible (but keep comments and pods)
5669             -extrude insert as many newlines as possible
5670              
5671             Dump and die, debugging
5672             -dop dump options used in this run to standard output and quit
5673             -ddf dump default options to standard output and quit
5674             -dsn dump all option short names to standard output and quit
5675             -dln dump option long names to standard output and quit
5676             -dpro dump whatever configuration file is in effect to standard output
5677             -dtt dump all token types to standard output and quit
5678              
5679             HTML
5680             -html write an html file (see 'man perl2web' for many options)
5681             Note: when -html is used, no indentation or formatting are done.
5682             Hint: try perltidy -html -css=mystyle.css filename.pl
5683             and edit mystyle.css to change the appearance of filename.html.
5684             -nnn gives line numbers
5685             -pre only writes out <pre>..</pre> code section
5686             -toc places a table of contents to subs at the top (default)
5687             -pod passes pod text through pod2html (default)
5688             -frm write html as a frame (3 files)
5689             -text=s extra extension for table of contents if -frm, default='toc'
5690             -sext=s extra extension for file content if -frm, default='src'
5691              
5692             A prefix of "n" negates short form toggle switches, and a prefix of "no"
5693             negates the long forms. For example, -nasc means don't add missing
5694             semicolons.
5695              
5696             If you are unable to see this entire text, try "perltidy -h | more"
5697             For more detailed information, and additional options, try "man perltidy",
5698             or go to the perltidy home page at http://perltidy.sourceforge.net
5699             EOF
5700              
5701 0         0 return;
5702             } ## end sub usage
5703              
5704             1;