line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package App::PTP::Args; |
2
|
|
|
|
|
|
|
|
3
|
15
|
|
|
15
|
|
68644
|
use 5.022; |
|
15
|
|
|
|
|
97
|
|
4
|
15
|
|
|
15
|
|
72
|
use strict; |
|
15
|
|
|
|
|
33
|
|
|
15
|
|
|
|
|
315
|
|
5
|
15
|
|
|
15
|
|
69
|
use warnings; |
|
15
|
|
|
|
|
25
|
|
|
15
|
|
|
|
|
516
|
|
6
|
|
|
|
|
|
|
|
7
|
15
|
|
|
15
|
|
7197
|
use App::PTP::Commands ':CMD'; |
|
15
|
|
|
|
|
45
|
|
|
15
|
|
|
|
|
3418
|
|
8
|
15
|
|
|
15
|
|
116
|
use App::PTP::Util; |
|
15
|
|
|
|
|
30
|
|
|
15
|
|
|
|
|
408
|
|
9
|
15
|
|
|
|
|
90
|
use Getopt::Long qw(GetOptionsFromArray :config auto_abbrev no_ignore_case |
10
|
15
|
|
|
15
|
|
10547
|
permute auto_version); |
|
15
|
|
|
|
|
178377
|
|
11
|
15
|
|
|
15
|
|
3648
|
use List::Util; |
|
15
|
|
|
|
|
37
|
|
|
15
|
|
|
|
|
797
|
|
12
|
15
|
|
|
15
|
|
7937
|
use Pod::Usage; |
|
15
|
|
|
|
|
725266
|
|
|
15
|
|
|
|
|
2300
|
|
13
|
15
|
|
|
15
|
|
156
|
use Scalar::Util 'looks_like_number'; |
|
15
|
|
|
|
|
39
|
|
|
15
|
|
|
|
|
44347
|
|
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
# Name of files or directory to be processed. This can also contain a reference |
16
|
|
|
|
|
|
|
# to the $stdin_marker variable, to indicate that the standard input needs to be |
17
|
|
|
|
|
|
|
# processed. |
18
|
|
|
|
|
|
|
my @inputs; |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
# The list of actions applied to the input. This is a list of array reference. |
21
|
|
|
|
|
|
|
# Each of these array will contain the name of the command to run, the coderef |
22
|
|
|
|
|
|
|
# for it, and then its arguments if any. |
23
|
|
|
|
|
|
|
my @pipeline; |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
# This hash contains options that are used during the pipeline and that can be |
26
|
|
|
|
|
|
|
# set or un-set for each command. |
27
|
|
|
|
|
|
|
my %modes; |
28
|
|
|
|
|
|
|
# This hash contains options that are global for the whole program. |
29
|
|
|
|
|
|
|
my %options; |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
my $default_input_field = '\s*,\s*|\t'; |
32
|
|
|
|
|
|
|
my $default_output_field = "\t"; |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
# env(foo => default) |
35
|
|
|
|
|
|
|
# Returns the given environment variable or the default value. |
36
|
|
|
|
|
|
|
# Always return the default value if the HARNESS_ACTIVE variable is set (so that |
37
|
|
|
|
|
|
|
# tests are not affected by environment variables). |
38
|
|
|
|
|
|
|
sub env { |
39
|
826
|
|
|
826
|
0
|
1341
|
my ($var, $default) = @_; |
40
|
826
|
50
|
|
|
|
2322
|
return $default if $ENV{HARNESS_ACTIVE}; |
41
|
0
|
|
0
|
|
|
0
|
return $ENV{$var} // $default; |
42
|
|
|
|
|
|
|
} |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
sub get_default_modes { |
45
|
118
|
|
|
118
|
0
|
191
|
my %m; |
46
|
118
|
|
|
|
|
288
|
$m{case_sensitive} = not(env(PTP_DEFAULT_CASE_INSENSITIVE => 0)); |
47
|
118
|
|
|
|
|
259
|
$m{quote_regex} = env(PTP_DEFAULT_QUOTE_REGEX => 0); |
48
|
118
|
|
|
|
|
223
|
$m{global_match} = not(env(PTP_DEFAULT_LOCAL_MATCH => 0)); |
49
|
118
|
|
|
|
|
248
|
$m{comparator} = \"default"; |
50
|
118
|
|
|
|
|
219
|
$m{regex_engine} = env(PTP_DEFAULT_REGEX_ENGINE => 'perl'); |
51
|
118
|
|
|
|
|
239
|
$m{fatal_error} = env(PTP_DEFAULT_FATAL_ERROR => 0); |
52
|
118
|
|
|
|
|
234
|
$m{inverse_match} = env(PTP_DEFAULT_INVERSE_MATCH => 0); |
53
|
118
|
|
|
|
|
239
|
$m{input_field} = $default_input_field; |
54
|
118
|
|
|
|
|
215
|
$m{output_field} = $default_output_field; |
55
|
118
|
|
|
|
|
909
|
return %m; |
56
|
|
|
|
|
|
|
} |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
sub get_default_options { |
59
|
118
|
|
|
118
|
0
|
166
|
my %o; |
60
|
118
|
|
|
|
|
239
|
$o{input_encoding} = 'UTF-8'; |
61
|
118
|
|
|
|
|
207
|
$o{output_encoding} = 'UTF-8'; |
62
|
118
|
|
|
|
|
214
|
$o{input_separator} = '\n'; # This will be interpreted in a regex |
63
|
118
|
|
|
|
|
211
|
$o{output_separator} = "\n"; |
64
|
118
|
|
|
|
|
197
|
$o{preserve_eol} = 0; |
65
|
118
|
|
|
|
|
187
|
$o{fix_final_separator} = 0; |
66
|
118
|
|
|
|
|
181
|
$o{recursive} = 0; |
67
|
118
|
|
|
|
|
197
|
$o{input_filter} = undef; |
68
|
118
|
|
|
|
|
195
|
$o{debug_mode} = 0; |
69
|
118
|
|
|
|
|
203
|
$o{merge} = 0; |
70
|
118
|
|
|
|
|
181
|
$o{in_place} = 0; |
71
|
118
|
|
|
|
|
224
|
$o{output} = undef; |
72
|
118
|
|
|
|
|
183
|
$o{append} = 0; |
73
|
118
|
|
|
|
|
183
|
$o{abort} = 0; |
74
|
118
|
|
|
|
|
205
|
$o{preserve_perl_env} = 0; |
75
|
118
|
|
|
|
|
217
|
$o{use_safe} = env(PTP_DEFAULT_SAFE => 0); |
76
|
118
|
|
|
|
|
986
|
return %o; |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
# Resets all the global variables used for the command line parsing. This is |
80
|
|
|
|
|
|
|
# really useful only in tests. |
81
|
|
|
|
|
|
|
sub reset_global { |
82
|
118
|
|
|
118
|
0
|
233
|
@inputs = (); |
83
|
118
|
|
|
|
|
561
|
@pipeline = (); |
84
|
118
|
|
|
|
|
366
|
%modes = get_default_modes(); |
85
|
118
|
|
|
|
|
351
|
%options = get_default_options(); |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
sub set_output { |
89
|
0
|
|
|
0
|
0
|
0
|
my (undef, $f) = @_; |
90
|
0
|
0
|
|
|
|
0
|
if (defined $options{output}) { |
91
|
0
|
|
|
|
|
0
|
die "Only a single occurence of --output or --append is allowed.\n"; |
92
|
|
|
|
|
|
|
} |
93
|
0
|
|
|
|
|
0
|
$options{output} = $f; |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
sub options_flags {( |
97
|
0
|
|
|
0
|
|
0
|
'help|h' => sub { pod2usage(-exitval => 0, -verbose => 2) }, |
98
|
|
|
|
|
|
|
'debug|d+' => \$options{debug_mode}, |
99
|
|
|
|
|
|
|
'merge|m!' => \$options{merge}, |
100
|
|
|
|
|
|
|
'in-place|i!' => \$options{in_place}, |
101
|
|
|
|
|
|
|
'output|o=s' => \&set_output, |
102
|
0
|
|
|
0
|
|
0
|
'append|a=s' => sub { set_output(@_); $options{append} = 1; }, |
|
0
|
|
|
|
|
0
|
|
103
|
|
|
|
|
|
|
'abort!' => \$options{abort}, |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
'recursive|R|r!' => \$options{recursive}, |
106
|
|
|
|
|
|
|
'input-filter=s' => \$options{input_filter}, |
107
|
|
|
|
|
|
|
'input-encoding|in-encoding=s' => \$options{input_encoding}, |
108
|
|
|
|
|
|
|
'output-encoding|out-encoding=s' => \$options{output_encoding}, |
109
|
|
|
|
|
|
|
'input-separator|in-separator=s' => \$options{input_separator}, |
110
|
|
|
|
|
|
|
'output-separator|out-separator=s' => \$options{output_separator}, |
111
|
|
|
|
|
|
|
'fix-final-separator!' => \$options{fix_final_separator}, |
112
|
0
|
|
|
0
|
|
0
|
'0' => sub { $options{input_separator} = '\000'; |
113
|
0
|
|
|
|
|
0
|
$options{output_separator} = '' }, |
114
|
|
|
|
|
|
|
'preserve-input-separator|eol' => |
115
|
1
|
|
|
1
|
|
4751
|
sub { $options{preserve_eol} = 1; $options{output_separator} = '' }, |
|
1
|
|
|
|
|
6
|
|
116
|
|
|
|
|
|
|
'preserve-perl-env!' => \$options{preserve_perl_env}, |
117
|
36
|
|
|
36
|
|
171466
|
'safe:2' => sub { $options{use_safe} = $_[1] }, |
118
|
119
|
|
|
119
|
0
|
1691
|
)} |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
sub modes_flags {( |
121
|
1
|
|
|
1
|
|
228
|
'case-sensitive|S' => sub { $modes{case_sensitive} = 1 }, |
122
|
3
|
|
|
3
|
|
9908
|
'case-insensitive|I' => sub { $modes{case_sensitive} = 0 }, |
123
|
10
|
|
|
10
|
|
43448
|
'quote-regexp|Q' => sub { $modes{quote_regex} = 1 }, |
124
|
0
|
|
|
0
|
|
0
|
'end-quote-regexp|E' => sub { $modes{quote_regex} = 0 }, |
125
|
1
|
|
|
1
|
|
287
|
'global-match|G' => sub { $modes{global_match} = 1 }, |
126
|
2
|
|
|
2
|
|
9675
|
'local-match|L' => sub { $modes{global_match} = 0 }, |
127
|
1
|
|
|
1
|
|
4606
|
'comparator|C=s' => sub { $modes{comparator} = $_[1] }, |
128
|
|
|
|
|
|
|
'regex-engine|re=s' => |
129
|
0
|
0
|
|
0
|
|
0
|
sub { die "Invalid value for --regex-engine: $_[1]\n" if $_[1] !~ /^\w+$/; |
130
|
0
|
|
|
|
|
0
|
$modes{regex_engine} = $_[1] }, |
131
|
0
|
|
|
0
|
|
0
|
'fatal-error|X' => sub { $modes{fatal_error} = 1 }, |
132
|
0
|
|
|
0
|
|
0
|
'ignore-error' => sub { $modes{fatal_error} = 0 }, # Find a short option? |
133
|
1
|
|
|
1
|
|
5026
|
'inverse-match|V' => sub { $modes{inverse_match} = 1 }, |
134
|
0
|
|
|
0
|
|
0
|
'normal-match|N' => sub { $modes{inverse_match} = 0 }, |
135
|
1
|
|
|
1
|
|
4975
|
'input-field-separator|F=s' => sub { $modes{input_field} = $_[1] }, |
136
|
|
|
|
|
|
|
'output-field-separator|P=s' => \$modes{output_field}, |
137
|
0
|
|
|
0
|
|
0
|
'default' => sub { $modes{input_field} = $default_input_field; |
138
|
0
|
|
|
|
|
0
|
$modes{output_field} = $default_output_field; }, |
139
|
1
|
|
|
1
|
|
5062
|
'bytes' => sub { $modes{input_field} = ''; $modes{output_field} = ''; }, |
|
1
|
|
|
|
|
3
|
|
140
|
1
|
|
|
1
|
|
4709
|
'csv' => sub { $modes{input_field} = '\s*,\s*'; $modes{output_field} = ','; }, |
|
1
|
|
|
|
|
3
|
|
141
|
1
|
|
|
1
|
|
4645
|
'tsv' => sub { $modes{input_field} = '\t'; $modes{output_field} = "\t"; }, |
|
1
|
|
|
|
|
3
|
|
142
|
1
|
|
|
1
|
|
4809
|
'none' => sub { $modes{input_field} = '(?!)' }, |
143
|
119
|
|
|
119
|
0
|
2593
|
)} |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
sub input_flags {( |
146
|
22
|
|
|
22
|
|
32153
|
'<>' => sub { push @inputs, $_[0] }, # Any options not matched otherwise. |
147
|
9
|
|
|
9
|
|
835
|
'' => sub { push @inputs, \$App::PTP::Files::stdin_marker }, # a single '-' |
148
|
119
|
|
|
119
|
0
|
554
|
)} |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
sub is_int { |
151
|
10
|
|
|
10
|
0
|
19
|
my ($str) = @_; |
152
|
10
|
|
33
|
|
|
64
|
return looks_like_number($str) && int($str) == $str; |
153
|
|
|
|
|
|
|
} |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
sub validate_cut_spec { |
156
|
5
|
|
|
5
|
0
|
13
|
my ($spec) = @_; |
157
|
5
|
|
|
|
|
370
|
my @fields = split /\s*,\s*/, $spec; |
158
|
5
|
|
|
|
|
19
|
for my $f (@fields) { |
159
|
10
|
50
|
|
|
|
19
|
die "Fields passed to --cut must all be integers: $f\n" unless is_int($f); |
160
|
10
|
50
|
|
|
|
34
|
$f-- if $f > 0; |
161
|
|
|
|
|
|
|
} |
162
|
5
|
|
|
|
|
22
|
return \@fields; |
163
|
|
|
|
|
|
|
} |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
sub action_flags {( |
166
|
|
|
|
|
|
|
'grep|g=s' => |
167
|
27
|
|
|
27
|
|
39986
|
sub { push @pipeline, ['grep', \&do_grep, {%modes}, $_[1]] }, |
168
|
|
|
|
|
|
|
'substitute|s=s{2}' => |
169
|
38
|
|
|
38
|
|
42502
|
sub { push @pipeline, ['substitute', \&do_substitute, {%modes}, |
170
|
|
|
|
|
|
|
$_[1]] }, |
171
|
|
|
|
|
|
|
# All the do_perl below could have the same sub using "$_[0]" instead of the |
172
|
|
|
|
|
|
|
# manually specified name. |
173
|
|
|
|
|
|
|
'perl|p=s' => |
174
|
18
|
|
|
18
|
|
27214
|
sub { push @pipeline, ['perl', \&do_perl, {%modes}, 'perl', $_[1]] }, |
175
|
|
|
|
|
|
|
'n=s' => |
176
|
19
|
|
|
19
|
|
23151
|
sub { push @pipeline, ['n', \&do_perl, {%modes}, 'n', $_[1]] }, |
177
|
|
|
|
|
|
|
'filter|f=s' => |
178
|
6
|
|
|
6
|
|
10343
|
sub { push @pipeline, ['filter', \&do_perl, {%modes}, 'filter', $_[1]] }, |
179
|
|
|
|
|
|
|
'mark-line|ml=s' => |
180
|
7
|
|
|
7
|
|
6207
|
sub { push @pipeline, ['mark-line', \&do_perl, {%modes}, 'mark-line', |
181
|
|
|
|
|
|
|
$_[1]] }, |
182
|
|
|
|
|
|
|
'execute|e=s' => |
183
|
19
|
|
|
19
|
|
22831
|
sub { push @pipeline, ['execute', \&do_execute, {%modes}, $_[1]] }, |
184
|
|
|
|
|
|
|
'load|l=s' => |
185
|
3
|
|
|
3
|
|
777
|
sub { push @pipeline, ['load', \&do_load, {%modes}, $_[1]] }, |
186
|
4
|
|
|
4
|
|
10054
|
'sort' => sub { push @pipeline, ['sort', \&do_sort, {%modes}] }, |
187
|
|
|
|
|
|
|
'numeric-sort|ns' => |
188
|
1
|
|
|
1
|
|
4656
|
sub { my $opt = {%modes, comparator => \"numeric" }; |
189
|
1
|
|
|
|
|
6
|
push @pipeline, [ 'numeric-sort', \&do_sort, $opt] }, |
190
|
|
|
|
|
|
|
'locale-sort|ls' => |
191
|
1
|
|
|
1
|
|
5047
|
sub { my $opt = {%modes, comparator => \"locale" }; |
192
|
1
|
|
|
|
|
5
|
push @pipeline, [ 'numeric-sort', \&do_sort, $opt] }, |
193
|
|
|
|
|
|
|
'custom-sort|cs=s' => |
194
|
1
|
|
|
1
|
|
4659
|
sub { my $opt = {%modes, comparator => $_[1] }; |
195
|
1
|
|
|
|
|
17
|
push @pipeline, [ 'custom-sort', \&do_sort, $opt] }, |
196
|
|
|
|
|
|
|
'unique|u' => |
197
|
0
|
|
|
0
|
|
0
|
sub { push @pipeline, ['unique', \&do_list_op, {%modes}, |
198
|
|
|
|
|
|
|
\&App::PTP::Util::uniqstr, 0] }, |
199
|
4
|
|
|
4
|
|
19394
|
'head:i' => sub { push @pipeline, ['head', \&do_head, {%modes}, $_[1]] }, |
200
|
4
|
|
|
4
|
|
18998
|
'tail:i' => sub { push @pipeline, ['tail', \&do_tail, {%modes}, $_[1]] }, |
201
|
|
|
|
|
|
|
'reverse|tac' => |
202
|
|
|
|
|
|
|
sub { push @pipeline, |
203
|
0
|
|
|
0
|
|
0
|
['reverse', \&do_list_op, {%modes}, sub {reverse @_ }, 1] }, |
|
0
|
|
|
|
|
0
|
|
204
|
|
|
|
|
|
|
'shuffle' => |
205
|
0
|
|
|
0
|
|
0
|
sub { push @pipeline, ['shuffle', \&do_list_op, {%modes}, |
206
|
|
|
|
|
|
|
\&List::Util::shuffle, 0] }, |
207
|
|
|
|
|
|
|
'delete-marked' => |
208
|
3
|
|
|
3
|
|
722
|
sub { push @pipeline, ['delete-marked', \&do_delete_marked, {%modes}, |
209
|
|
|
|
|
|
|
0] }, |
210
|
|
|
|
|
|
|
'delete-before' => |
211
|
0
|
|
|
0
|
|
0
|
sub { push @pipeline, ['delete-before', \&do_delete_marked, {%modes}, |
212
|
|
|
|
|
|
|
-1] }, |
213
|
|
|
|
|
|
|
'delete-after' => |
214
|
0
|
|
|
0
|
|
0
|
sub { push @pipeline, ['delete-after', \&do_delete_marked, {%modes}, |
215
|
|
|
|
|
|
|
1] }, |
216
|
|
|
|
|
|
|
'delete-at-offset=i' => |
217
|
0
|
|
|
0
|
|
0
|
sub { push @pipeline, ['delete-at-offset', \&do_delete_marked, {%modes}, |
218
|
|
|
|
|
|
|
$_[1]] }, |
219
|
|
|
|
|
|
|
'insert-before=s' => |
220
|
0
|
|
|
0
|
|
0
|
sub { push @pipeline, ['insert-before', \&do_insert_marked, {%modes}, |
221
|
|
|
|
|
|
|
-1, $_[1]] }, |
222
|
|
|
|
|
|
|
'insert-after=s' => |
223
|
3
|
|
|
3
|
|
727
|
sub { push @pipeline, ['insert-after', \&do_insert_marked, {%modes}, |
224
|
|
|
|
|
|
|
0, $_[1]] }, |
225
|
|
|
|
|
|
|
'insert-at-offset=s{2}' => |
226
|
0
|
|
|
0
|
|
0
|
sub { push @pipeline, ['insert-at-offset', \&do_insert_marked, {%modes}, |
227
|
|
|
|
|
|
|
$_[1]] }, |
228
|
|
|
|
|
|
|
'clear-markers' => |
229
|
0
|
|
|
0
|
|
0
|
sub { push @pipeline, ['clear-markers', \&do_set_markers, {%modes}, 0] }, |
230
|
|
|
|
|
|
|
'set-all-markers' => |
231
|
0
|
|
|
0
|
|
0
|
sub { push @pipeline, ['set-all-markers', \&do_set_markers, {%modes}, |
232
|
|
|
|
|
|
|
1] }, |
233
|
5
|
|
|
5
|
|
5949
|
'cut=s' => sub { push @pipeline, ['cut', \&do_cut, {%modes}, |
234
|
|
|
|
|
|
|
validate_cut_spec($_[1])] }, |
235
|
0
|
|
|
0
|
|
0
|
'paste=s' => sub { push @pipeline, ['paste', \&do_paste, {%modes}, $_[1]] }, |
236
|
2
|
|
|
2
|
|
5264
|
'pivot' => sub { push @pipeline, ['pivot', \&do_pivot, {%modes}, 0] }, |
237
|
2
|
|
|
2
|
|
4978
|
'transpose' => sub { push @pipeline, ['transpose', \&do_pivot, {%modes}, 1] }, |
238
|
|
|
|
|
|
|
'number-lines|nl' => |
239
|
0
|
|
|
0
|
|
0
|
sub { push @pipeline, ['number-lines', \&do_number_lines, {%modes}] }, |
240
|
|
|
|
|
|
|
'file-name|fn' => |
241
|
0
|
|
|
0
|
|
0
|
sub { push @pipeline, ['file-name', \&do_file_name, {%modes}, 1] }, |
242
|
|
|
|
|
|
|
'prefix-file-name|pfn' => |
243
|
1
|
|
|
1
|
|
229
|
sub { push @pipeline, ['prefix-file-name', \&do_file_name, {%modes}, 0] }, |
244
|
|
|
|
|
|
|
'line-count|lc' => |
245
|
1
|
|
|
1
|
|
232
|
sub { push @pipeline, ['line-count', \&do_line_count, {%modes}] }, |
246
|
6
|
|
|
6
|
|
1575
|
'tee=s' => sub { push @pipeline, ['tee', \&do_tee, {%modes}, $_[1]] } |
247
|
119
|
|
|
119
|
0
|
5358
|
)} |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
sub all_args { |
250
|
119
|
|
|
119
|
0
|
98994
|
return (options_flags(), modes_flags(), input_flags(), action_flags()); |
251
|
|
|
|
|
|
|
} |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
# parse_command_line(\@args) |
254
|
|
|
|
|
|
|
sub parse_command_line { |
255
|
118
|
|
|
118
|
0
|
240
|
my ($args) = @_; |
256
|
118
|
|
|
|
|
329
|
reset_global(); |
257
|
118
|
50
|
|
|
|
378
|
GetOptionsFromArray($args, all_args()) |
258
|
|
|
|
|
|
|
or pod2usage(-exitval => 2, -verbose => 0); |
259
|
|
|
|
|
|
|
|
260
|
118
|
50
|
|
|
|
47606
|
if ($options{debug_mode} > 1) { |
261
|
|
|
|
|
|
|
# When -d is specified multiple times, we add the marker on the final |
262
|
|
|
|
|
|
|
# output. |
263
|
0
|
|
|
|
|
0
|
push @pipeline, ['show-marker', \&do_perl, {%modes}, 'perl', |
264
|
|
|
|
|
|
|
'pf "%s %s", ($m ? "*" : " "), $_'] |
265
|
|
|
|
|
|
|
} |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
# Because of the way the options are processed, each --replace options |
268
|
|
|
|
|
|
|
# (expecting two arguments) is pushed twice in the pipeline sub (once for each |
269
|
|
|
|
|
|
|
# argument). We're fixing this here. |
270
|
118
|
|
|
|
|
820
|
for my $i (0 .. $#pipeline) { |
271
|
175
|
100
|
|
|
|
668
|
if ($pipeline[$i][0] eq 'substitute') { |
|
|
50
|
|
|
|
|
|
272
|
19
|
|
|
|
|
31
|
push @{$pipeline[$i]}, $pipeline[$i+1]->[3]; |
|
19
|
|
|
|
|
76
|
|
273
|
19
|
|
|
|
|
51
|
$pipeline[$i+1][0] = 'garbage'; |
274
|
|
|
|
|
|
|
} elsif ($pipeline[$i][0] eq 'insert-at-offset') { |
275
|
0
|
|
|
|
|
0
|
my $o = $pipeline[$i]->[3]; |
276
|
0
|
0
|
|
|
|
0
|
if (!ist_int($o)) { |
277
|
0
|
|
|
|
|
0
|
die "The first argument to --insert-at-offset must be an integer: $o\n"; |
278
|
|
|
|
|
|
|
} |
279
|
0
|
|
|
|
|
0
|
push @{$pipeline[$i]}, $pipeline[$i+1]->[3]; |
|
0
|
|
|
|
|
0
|
|
280
|
0
|
|
|
|
|
0
|
$pipeline[$i+1][0] = 'garbage'; |
281
|
|
|
|
|
|
|
} |
282
|
|
|
|
|
|
|
} |
283
|
118
|
|
|
|
|
287
|
@pipeline = grep { $_->[0] ne 'garbage' } @pipeline; |
|
175
|
|
|
|
|
682
|
|
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
# Add any options that were passed after a '--' to the list of inputs. |
286
|
118
|
|
|
|
|
257
|
push @inputs, @$args; |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
# Add the standard input marker to the inputs if no other input were |
289
|
|
|
|
|
|
|
# specified. |
290
|
118
|
100
|
|
|
|
356
|
push @inputs, \$App::PTP::Files::stdin_marker if not @inputs; |
291
|
|
|
|
|
|
|
|
292
|
118
|
0
|
33
|
|
|
317
|
if ($options{in_place} && $options{merge}) { |
293
|
0
|
|
|
|
|
0
|
die "The --in-place and --merge options are incompatible.\n"; |
294
|
|
|
|
|
|
|
} |
295
|
|
|
|
|
|
|
|
296
|
118
|
0
|
33
|
|
|
348
|
if ($options{in_place} && $options{output}) { |
297
|
0
|
0
|
|
|
|
0
|
if ($options{append}) { |
298
|
0
|
|
|
|
|
0
|
die "The --in-place and --append options are incompatible.\n"; |
299
|
|
|
|
|
|
|
} else { |
300
|
0
|
|
|
|
|
0
|
die "The --in-place and --output options are incompatible.\n"; |
301
|
|
|
|
|
|
|
} |
302
|
|
|
|
|
|
|
} |
303
|
|
|
|
|
|
|
|
304
|
118
|
50
|
66
|
|
|
356
|
if (defined $options{input_filter} && !$options{recursive}) { |
305
|
0
|
|
|
|
|
0
|
print "WARNING: The --input-filter option is useless unless --recursive is specified too.\n"; |
306
|
|
|
|
|
|
|
} |
307
|
|
|
|
|
|
|
|
308
|
118
|
|
|
|
|
480
|
return (\@inputs, \@pipeline, \%options); |
309
|
|
|
|
|
|
|
} |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
1; |