File Coverage

blib/lib/Perl/Tidy.pm
Criterion Covered Total %
statement 1570 2531 62.0
branch 457 1134 40.3
condition 118 351 33.6
subroutine 83 126 65.8
pod 0 62 0.0
total 2228 4204 53.0


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