File Coverage

blib/lib/Perl/Tidy.pm
Criterion Covered Total %
statement 1544 2514 61.4
branch 451 1134 39.7
condition 117 351 33.3
subroutine 83 124 66.9
pod 0 60 0.0
total 2195 4183 52.4


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