File Coverage

blib/lib/Perl/Tidy.pm
Criterion Covered Total %
statement 1239 1995 62.1
branch 394 936 42.0
condition 80 235 34.0
subroutine 74 108 68.5
pod 0 49 0.0
total 1787 3323 53.7


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