File Coverage

blib/lib/Perl/Tidy.pm
Criterion Covered Total %
statement 1284 2082 61.6
branch 402 962 41.7
condition 85 249 34.1
subroutine 70 107 65.4
pod 0 51 0.0
total 1841 3451 53.3


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