line
stmt
bran
cond
sub
pod
time
code
1
2
# = HISTORY SECTION =====================================================================
3
4
# ---------------------------------------------------------------------------------------
5
# version | date | author | changes
6
# ---------------------------------------------------------------------------------------
7
# 1.11 |17.04.07| JSTENZEL | renamed fileOptions2prefixes() into _fileOptions2prefixes(),
8
# | | | in order to avoid POD documentation because it is an
9
# | | | internal helper function;
10
# | | JSTENZEL | slight adaptations after complaints of perlcritic;
11
# | | JSTENZEL | added POD hints that GetOptions() is imported from
12
# | | | Getopt::Long and not defined in Getopt::ArgvFile;
13
# | | JSTENZEL | POD: bugfix in GetOptions() calls, %options hash needs to
14
# | | | be passed in as reference;
15
# |21.04.07| JSTENZEL | POD: bugfix in -fileOption example;
16
# 1.10 |05.01.05| JSTENZEL | added options resolveRelativePathes and resolveEnvVars;
17
# 1.09 |19.10.04| JSTENZEL | option -startupFilename now accepts array references both
18
# | | | directly set up and supplied by a callback;
19
# |20.10.04| JSTENZEL | new option -fileOption allows to use a user defined option
20
# | | | instead of an option file prefix like "@" (-options options
21
# | | | instead of @options);
22
# 1.08 |30.04.04| JSTENZEL | new import() switch "justload";
23
# 1.07 |29.04.04| JSTENZEL | import() implemented directly: emulating the old behaviour
24
# | | | of Exporter::import() when necessary, it alternatively
25
# | | | allows to invoke argvFile() via use();
26
# 1.06 |03.05.02| JSTENZEL | the startup filename scheme is now configurable by the
27
# | | | new option "startupFilename";
28
# 1.05 |30.04.02| JSTENZEL | cosmetics: hash access without quotes;
29
# | | JSTENZEL | corrected and improved inline doc;
30
# | | JSTENZEL | using File::Spec::Functions to build filenames,
31
# | | | for improved portability;
32
# | | JSTENZEL | using Cwd::abs_path() to check if files were read already;
33
# | | JSTENZEL | added support for default files in *current* directory;
34
# 1.04 |29.10.00| JSTENZEL | bugfix: options were read twice if both default and home
35
# | | | startup options were read and the script was installed in
36
# | | | the users homedirectory;
37
# 1.03 |25.03.00| JSTENZEL | new parameter "prefix";
38
# | | JSTENZEL | POD in option files is now supported;
39
# | | JSTENZEL | using Test in test suite now;
40
# 1.02 |27.02.00| JSTENZEL | new parameter "array";
41
# | | JSTENZEL | slight POD adaptions;
42
# 1.01 |23.03.99| JSTENZEL | README update only;
43
# 1.00 |16.03.99| JSTENZEL | first CPAN version.
44
# ---------------------------------------------------------------------------------------
45
46
# = POD SECTION =========================================================================
47
48
=head1 NAME
49
50
Getopt::ArgvFile - interpolates script options from files into @ARGV or another array
51
52
=head1 VERSION
53
54
This manual describes version B<1.11>.
55
56
=head1 SYNOPSIS
57
58
One line invocation - option hints are processed while the module is loaded:
59
60
# load module and process option file hints in @ARGV
61
use Getopt::ArgvFile default=>1;
62
63
# load another module to evaluate the options, e.g.:
64
use Getopt::Long;
65
...
66
67
# evaluate options, e.g. this common way:
68
GetOptions(\%options, 'any'); # this function is defined in Getopt::Long
69
70
Or suppress option hint processing when the module is loaded, to
71
perform it later on:
72
73
# load module, do *not* process option file hints
74
use Getopt::ArgvFile justload=>1;
75
76
# load another module to evaluate the options, e.g.:
77
use Getopt::Long;
78
...
79
80
# *now*, solve option file hints
81
Getopt::ArgvFile::argvFile(default=>1);
82
83
# evaluate options, e.g. this common way:
84
GetOptions(\%options, 'any'); # this function is defined in Getopt::Long
85
86
Or use the traditional two step invocation of module loading with
87
I and I option file handling:
88
89
# Load the module and import the &argvFile symbol
90
# - this will *not* process option hints.
91
# Use *this* syntax to do so, *exactly*.
92
use Getopt::ArgvFile qw(argvFile);
93
94
# load another module to evaluate the options, e.g.:
95
use Getopt::Long;
96
...
97
98
# *now*, solve option file hints
99
argvFile(default=>1);
100
101
# evaluate options, e.g. this common way:
102
GetOptions(\%options, 'any'); # this function is defined in Getopt::Long
103
104
105
If options should be processed into another array, this can be done this way:
106
107
# prepare target array
108
my @options=('@options1', '@options2', '@options3');
109
110
...
111
112
# replace file hints by the options stored in the files
113
argvFile(array=>\@options);
114
115
In case you do not like the "@" prefix it is possible to define an option to
116
be used instead:
117
118
# prepare target array
119
my @options=('-options', 'options1', '-options', 'options2');
120
121
...
122
123
# replace file hints by the options stored in the files
124
argvFile(fileOption=>'options', array=>\@options);
125
126
127
=head1 DESCRIPTION
128
129
This module simply interpolates option file hints in @ARGV
130
by the contents of the pointed files. This enables option
131
reading from I instead of or additional to the usual
132
reading from the command line.
133
134
Alternatively, you can process any array instead of @ARGV
135
which is used by default and mentioned mostly in this manual.
136
137
The interpolated @ARGV could be subsequently processed by
138
the usual option handling, e.g. by a Getopt::xxx module.
139
Getopt::ArgvFile does I perform any option handling itself,
140
it only prepares the array @ARGV.
141
142
Option files can significantly simplify the call of a script.
143
Imagine the following:
144
145
=over 4
146
147
=item Breaking command line limits
148
149
A script may offer a lot of options, with possibly a few of them
150
even taking parameters. If these options and their parameters
151
are passed onto the program call directly, the number of characters
152
accepted by your shells command line may be exceeded.
153
154
Perl itself does I limit the number of characters passed to a
155
script by parameters, but the shell or command interpreter often
156
I a limit here. The same problem may occur if you want to
157
store a long call in a system file like crontab.
158
159
If such a limit restricts you, options and parameters may be moved into
160
option files, which will result in a shorter command line call.
161
162
=item Script calls prepared by scripts
163
164
Sometimes a script calls another script. The options passed onto the
165
nested script could depend on variable situations, such as a users
166
input or the detected environment. In such a case, it I be easier
167
to generate an intermediate option file which is then passed to
168
the nested script.
169
170
Or imagine two cron jobs one preparing the other: the first may generate
171
an option file which is then used by the second.
172
173
=item Simple access to typical calling scenarios
174
175
If several options need to be set, but in certain circumstances
176
are always the same, it could become sligthly nerveracking to type
177
them in again and again. With an option file, they can be stored
178
I and recalled easily as often as necessary.
179
180
Further more, option files may be used to group options. Several
181
settings may set up one certain behaviour of the program, while others
182
influence another. Or a certain set of options may be useful in one
183
typical situation, while another one should be used elsewhere. Or there
184
is a common set of options which has to be used in every call,
185
while other options are added depending on the current needs. Or there
186
are a few user groups with different but typical ways to call your script.
187
In all these cases, option files may collect options belonging together,
188
and may be combined by the script users to set up a certain call.
189
In conjunction with the possiblity to I such collections, this is
190
perhaps the most powerful feature provided by this method.
191
192
=item Individual and installationwide default options
193
194
The module allows the programmer to enable user setups of default options;
195
for both individual users or generally I callers of a script.
196
This is especially useful for administrators who can configure the
197
I behaviour of a script by setting up its installationwide
198
startup option file. All script users are free then to completely
199
forget every already configured setup option. And if one of them regularly
200
adds certain options to every call, he could store them in his I
201
startup option file.
202
203
For example, I use this feature to make my scripts both flexible I
204
usable. I have several scripts accessing a database via DBI. The database
205
account parameters as well as the DBI startup settings should not be coded
206
inside the scripts because this is not very flexible, so I implemented
207
them by options. But on the other hand, there should be no need for a normal
208
user to pass all these settings to every script call. My solution for this
209
is to use I option files set up and maintained by an administrator.
210
This is very transparent, most of the users know nothing of these
211
(documented ;-) configuration settings ... and if anything changes, only the
212
option files have to be adapted.
213
214
=back
215
216
=cut
217
218
# PACKAGE SECTION ###############################################
219
220
# declare namespace
221
package Getopt::ArgvFile;
222
223
# declare your revision (and use it to avoid a warning)
224
$VERSION=1.11;
225
$VERSION=$VERSION;
226
227
# force Perl version
228
require 5.003;
229
230
=pod
231
232
=head1 EXPORTS
233
234
No symbol is exported by default, but you may explicitly import
235
the "argvFile()" function I:
236
237
use Getopt::ArgvFile qw(argvFile);
238
239
Please note that this interface is provided for backwards compatibility with
240
versions up to 1.06. By loading the module this way, the traditional import
241
mechanisms take affect and I is not called implicitly>.
242
243
This means that while option file hints are usually processed implicitly when
244
C is loaded, the syntax
245
246
use Getopt::ArgvFile qw(argvFile);
247
248
requires an I call of I to process option files.
249
250
=cut
251
252
# export something (Exporter is not made a base module because we implement import() ourselves,
253
# which *can* call Exporter::import() (if needed for backwards compatibility) - see import())
254
require Exporter;
255
@EXPORT_OK=qw(argvFile);
256
257
# CODE SECTION ##################################################
258
259
# set pragmas
260
8
8
222545
use strict;
8
17
8
316
261
262
# load libraries
263
8
8
45
use Carp;
8
16
8
753
264
8
8
50
use File::Basename;
8
15
8
859
265
8
8
7712
use Text::ParseWords;
8
12565
8
2235
266
8
8
31164
use File::Spec::Functions;
8
8210
8
803
267
8
8
50
use Cwd qw(:DEFAULT abs_path chdir);
8
15
8
18633
268
269
# module variables
270
my $optionPrefixPattern=qr/(-{1,2}|\+)/;
271
272
# METHOD SECTION ################################################
273
274
=pod
275
276
=head1 FUNCTIONS
277
278
There is only one function, I, which does all the work of
279
option file hint processing.
280
281
Please note that with version 1.07 and above C is called
282
I when the module is loaded, except this is done in one of
283
the following ways:
284
285
# the traditional interface - provided for
286
# backwards compatibility - this loads the
287
# module and imports the &argvFile symbol
288
use Getopt::ArgvFile qw(argvFile);
289
290
--
291
292
# option file processing is explicitly suppressed
293
use Getopt::ArgvFile justload=>1;
294
295
Except for the traditional loading, the complete interface of C
296
is available via C, but in the typical C syntax without
297
parantheses.
298
299
# implicit call of argvFile(default=>1, home=>1)
300
use Getopt::ArgvFile default=>1, home=>1;
301
302
See I for further details.
303
304
305
=head2 argvFile()
306
307
Scans the command line parameters (stored in @ARGV or an alternatively
308
passed array) for option file hints (see I below), reads the
309
pointed files and makes their contents part of the source array
310
(@ARGV by default) replacing the hints.
311
312
Because the function was intentionally designed to work on @ARGV
313
and this is still the default behaviour, this manual mostly speaks about
314
@ARGV. Please note that it is possible to process I other array
315
as well.
316
317
B
318
319
An option file hint is simply the filename preceeded by (at least) one
320
"@" character:
321
322
> script -optA argA -optB @optionFile -optC argC
323
324
This will cause argvFile() to scan "optionFile" for options.
325
The element "@optionFile" will be removed from the @ARGV array and
326
will be replaced by the options found.
327
328
Note: you can choose another prefix by using the "prefix" parameter,
329
see below.
330
331
An option file which cannot be found is quietly skipped.
332
333
Well, what is I an option file? It is intended to
334
store I which should be passed to the called
335
script. They can be stored exactly as they would be written in
336
the command line, but may be spread to multiple lines. To make the
337
file more readable, space and comment lines (starting with a "#")
338
are allowed additionally. POD comments are supported as well.
339
For example, the call
340
341
> script -optA argA -optB -optC cArg par1 par2
342
343
could be transformed into
344
345
> script @scriptOptions par1 par2
346
347
where the file "scriptOptions" may look like this:
348
349
# option a
350
-optA argA
351
352
C<>
353
354
=pod
355
option b
356
=cut
357
-optB
358
359
C<>
360
361
# option c
362
-optC cArg
363
364
B
365
366
Option files can be nested. Recursion is avoided globally, that means
367
that every file will be opened only I (the first time argvFile() finds
368
a hint pointing to it). This is the simplest implementation, indeed, but
369
should be suitable. (Unfortunately, there are I.)
370
371
By using this feature, you may combine groups of typical options into
372
a top level option file, e.g.:
373
374
File ab:
375
376
C<>
377
378
# option a
379
-optA argA
380
# option b
381
-optB
382
383
C<>
384
385
File c:
386
387
C<>
388
389
# option c
390
-optC cArg
391
392
C<>
393
394
File abc:
395
396
C<>
397
398
# combine ab and c
399
@ab @c
400
401
If anyone provides these files, a user can use a very short call:
402
403
> script @abc
404
405
and argvFile() will recursively move all the filed program parameters
406
into @ARGV.
407
408
409
B
410
411
Pathes in option files might be relative, as in
412
413
-file ../file @../../configs/nested
414
415
If written with the (prepared) start directory in mind, that will work,
416
but it can fail when it was written relatively to the option file location
417
because by default those pathes will not be resolved when written from
418
an option file.
419
420
Use parameter C to switch to path resolution:
421
422
argvFile(resolveRelativePathes=>1);
423
424
will cause C to expand those pathes, both in standard strings
425
and nested option files.
426
427
With resolveRelativePathes, both pathes
428
will be resolved:
429
430
-file ../file @../../configs/nested
431
432
A path is resolved I it is found in.
433
434
435
B
436
437
Similar to relative pathes, environment variables are handled differently
438
depending if the option is specified at the commandline or from an option
439
file, due to bypassed shell processing. By default, C does
440
not resolve environment variables. But if required it can be commanded
441
to do so via parameter C.
442
443
argvFile(resolveEnvVars=>1);
444
445
B
446
447
By setting several named parameters, you can enable automatic processing
448
of I. There are three of them:
449
450
The I is searched in the installation path
451
of the calling script, the I is searched in the
452
users home (evaluated via environment variable "HOME"), and the
453
I is searched in the current directory.
454
455
By default, all startup option files are expected to be named like
456
the script, preceeded by a dot, but this can be adapted to individual
457
needs if preferred, see below.
458
459
Examples:
460
If a script located in "/path/script" is invoked in directory
461
/the/current/dir by a user "user" whoms "HOME" variable points
462
to "/homes/user", the following happens:
463
464
C<>
465
466
argvFile() # ignores all startup option files;
467
argvFile(default=>1) # searches and expands "/path/.script",
468
# if available (the "default" settings);
469
argvFile(home=>1) # searches and expands "/homes/user/.script",
470
# if available (the "home" settings);
471
argvFile(current=>1) # searches and expands "/the/current/dir/.script",
472
# if available (the "current" settings);
473
argvFile(
474
default => 1,
475
home => 1,
476
current => 1
477
) # tries to handle all startups.
478
479
Any true value will activate the setting it is assigned to.
480
481
In case the ".script" name rule does not meet your needs or does not fit
482
into a certain policy, the expected startup filenames can be set up by
483
an option C. The option value may be a scalar used as
484
the expected filename, or a reference to an array of accepted choices,
485
or a reference to code returning the name - plainly or as a reference to
486
an array of names. Such callback code will be called I and will
487
receive the name of the script.
488
489
# use ".config"
490
argvFile(startupFilename => '.config');
491
492
# use ".config" or "config"
493
argvFile(startupFilename => [qw(.config config)]);
494
495
# emulate the default behaviour,
496
# but use an extra dot postfix
497
my $nameBuilder=sub {join('', '.', basename($_[0]), '.');};
498
argvFile(startupFilename => $nameBuilder);
499
500
# use .(script)rc or .(script)/config
501
my $nameBuilder=sub
502
{
503
my $sname=basename($_[0]);
504
[".${sname}rc", ".${sname}/config"];
505
};
506
argvFile(startupFilename => $nameBuilder);
507
508
Note that the list variants will use the first matching filename in each
509
possible startup-file path. For example if your array is C<['.scriptrc',
510
'.script.config']> and you have both a C<.scriptrc> and a C<.script.config>
511
file in (say) your current directory, only the C<.scriptrc> file will be
512
used, as it is the first found.
513
514
The contents found in a startup file is placed I all explicitly
515
set command line arguments. This enables to overwrite a default setting
516
by an explicit option. If all startup files are read, I startup
517
files can overwrite I files which have preceedence over I
518
ones, so that the I startups are most common. In other words,
519
if the module would not support startup files, you could get the same
520
result with "script @/path/.script @/homes/user/.script @/the/current/dir/.script".
521
522
Note: There is one certain case when overwriting will I work completely
523
because duplicates are sorted out: if all three types of startup files are
524
used and the script is started in the installation directory,
525
the default file will be identical to the current file. The default file is
526
processed, but the current file is skipped as a duplicate later on and will
527
I overwrite settings made caused by the intermediately processed home file.
528
If started in another directory, it I overwrite the home settings.
529
But the alternative seems to be even more confusing: the script would behave
530
differently if just started in its installation path. Because a user might
531
be more aware of configuration editing then of the current path, I choose
532
the current implementation, but this preceedence might become configurable
533
in a future version.
534
535
If there is no I environment variable, the I setting takes no effect
536
to avoid trouble accessing the root directory.
537
538
B
539
540
The function supports multi-level (or so called I) option files.
541
If a filename in an option file hint starts with a "@" again, this complete
542
name is the resolution written back to @ARGV - assuming there will be
543
another utility reading option files.
544
545
Examples:
546
@rfile rfile will be opened, its contents is
547
made part of @ARGV.
548
@@rfile cascade: "@rfile" is written back to
549
@ARGV assuming that there is a subsequent
550
tool called by the script to which this
551
hint will be passed to solve it by an own
552
call of argvFile().
553
554
The number of cascaded hints is unlimited.
555
556
B
557
558
Although the function was designed to process @ARGV, it is possible to
559
process another array as well if you prefer. To do this, simply pass
560
a I to this array by parameter B.
561
562
Examples:
563
argvFile() # processes @ARGV;
564
argvFile(array=>\@options); # processes @options;
565
566
B
567
568
By default, "@" is the prefix used to mark an option file. This can
569
be changed by using the optional parameter B:
570
571
Examples:
572
argvFile(); # use "@";
573
argvFile(prefix=>'~'); # use "~";
574
575
Note that the strings "#", "=", "-" and "+" are reserved and I
576
be chosen here because they are used to start plain or POD comments or
577
are typically option prefixes.
578
579
B
580
581
People not familiar with option files might be confused by file prefixes.
582
This can be avoided by offering an I that can be used instead
583
of a prefix, using the optional parameter B:
584
585
# install a file option
586
# (all lines are equivalent)
587
argvFile(fileOption=>'options');
588
argvFile(fileOption=>'-options');
589
argvFile(fileOption=>'+options');
590
argvFile(fileOption=>'--options');
591
592
The name of the option can be specified with or without the usual option
593
prefixes C<->, C<--> and C<+>.
594
595
Once an option is declared, it I replace a prefix. (Prefixes remain
596
in action as well.)
597
598
# with -options declared to be a file option,
599
# these sequences are equivalent
600
@file
601
-options file
602
603
# five equivalent cascades
604
@@@@file
605
-options @@@file
606
-options -options @@file
607
-options -options -options @file
608
-options -options -options -options file
609
610
Please note that prefixes are attached to the filename with no spaces
611
in between, while the option declared via -fileOption is separated from
612
the filename by whitespace, as for normal options.
613
614
615
=cut
616
sub argvFile
617
{
618
# declare function variables
619
22
22
1
55848
my ($maskString, $i, %rfiles, %startup, %seen)=("\0x07\0x06\0x07");
620
621
# detect the host system (to prepare filename handling)
622
22
273
my $casesensitiveFilenames=$^O!~/^(?:dos|os2|MSWin32)/i;
623
624
# check and get parameters
625
22
50
150
confess('[BUG] Getopt::ArgvFile::argvFile() uses named parameters, please provide name value pairs.') if @_ % 2;
626
22
124
my %switches=@_;
627
628
# perform more parameter checks
629
22
50
33
222
confess('[BUG] The "array" parameter value is no array reference.') if exists $switches{array} and not (ref($switches{array}) and ref($switches{array}) eq 'ARRAY');
66
630
22
50
33
121
confess('[BUG] The "prefix" parameter value is no defined literal.') if exists $switches{prefix} and (not defined $switches{prefix} or ref($switches{prefix}));
66
631
22
50
66
118
confess('[BUG] Invalid "prefix" parameter $switches{"prefix"}.') if exists $switches{prefix} and $switches{prefix}=~/^[-#=+]$/;
632
22
50
100
188
confess('[BUG] The "startupFilename" parameter value is neither a scalar nor array or code reference.') if exists $switches{startupFilename} and ref($switches{startupFilename}) and ref($switches{startupFilename})!~/^(ARRAY|CODE)$/;
66
633
22
50
33
150
confess('[BUG] The "fileOption" parameter value is no defined literal.') if exists $switches{fileOption} and (not defined $switches{fileOption} or ref($switches{fileOption}));
66
634
635
# check if further operations are suppressed (in case of a call via import())
636
{
637
22
37
my ($callerSub)=(caller(1))[3];
22
74
638
22
100
66
1774
return if defined $callerSub and $callerSub eq join('::', __PACKAGE__, 'import')
100
639
and exists $switches{justload};
640
}
641
642
# set array reference
643
21
100
286
my $arrayRef=exists $switches{array} ? $switches{array} : \@ARGV;
644
645
# set prefix
646
21
100
77
my $prefix=exists $switches{prefix} ? $switches{prefix} : '@';
647
648
# set file option
649
21
100
70
my $fileOption=exists $switches{fileOption} ? $switches{fileOption} : '';
650
21
319
$fileOption=~s/^$optionPrefixPattern//;
651
652
# set up startup filename list
653
21
100
1826
my $startupFilenames=exists $switches{startupFilename}
100
100
654
? ref($switches{startupFilename})
655
? ref($switches{startupFilename}) eq 'CODE'
656
? $switches{startupFilename}->($0)
657
: $switches{startupFilename}
658
: [$switches{startupFilename}]
659
: [join('', '.', basename($0))];
660
661
# check callback results
662
21
50
66
409
confess('[BUG] The filenames callback did not return a scalar or an array reference.')
663
if ref($startupFilenames) and ref($startupFilenames) ne 'ARRAY';
664
665
# a callback might have returned a(n undefined) scalar instead of an array reference
666
21
50
144
$startupFilenames=[defined $startupFilenames ? $startupFilenames : ()]
100
667
unless ref($startupFilenames);
668
669
# substitute file options by prefixes, if necessary
670
21
100
67
_fileOptions2prefixes($fileOption, $prefix, $arrayRef) if $fileOption;
671
672
# init startup file paths
673
(
674
21
100
189672
$startup{default}{path},
675
$startup{home}{path},
676
$startup{current}{path},
677
)=(
678
dirname($0),
679
exists $ENV{HOME} ? $ENV{HOME} : 'no HOME variable, sorry',
680
cwd(),
681
);
682
683
# ignore the "home" switch if there is no HOME environment variable, for reasons
684
# of security
685
21
100
544
delete $switches{home} unless exists $ENV{HOME};
686
687
# If startup paths are *identical* (script installed in home directory) and
688
# both startup flags are set, we can delete one of them (to read the options only once).
689
# (Note that we could easily combine this with the subsequent loop, but an extra loop
690
# will make it easy to allow extra configuration for "first seen first processed" /
691
# "fix processing order" preferences (what if the current directory is the default
692
# one, but should overwrite the home settings?).)
693
# Also set the first-found startup files while we're finding them. This makes sure we
694
# only use *one* file per path.
695
21
172
my %startupFiles;
696
21
687
foreach my $type (qw(default home current))
697
{
698
# skip unused settings
699
63
100
404
next unless exists $switches{$type};
700
701
# build filename (use the first existing file built according to the list of choices, if any)
702
19
255
my $cfg=(grep(-e, map {catfile(abs_path($startup{$type}{path}), $_)} @$startupFilenames))[0];
21
2053
703
704
# remove this setting if the associated file
705
# was already seen before (each file should be read once)
706
# - or if there is no such file this call
707
19
50
33
396
delete $switches{$type}, next if not defined $cfg or exists $seen{$cfg};
708
709
# buffer filename for subsequent use - no need to built it twice
710
19
142
$startupFiles{$type}=$cfg;
711
712
# otherwise, note that we saw this file
713
19
273
$seen{$cfg}=1;
714
}
715
716
# Check all possible startup files for usage - be careful to handle
717
# them in the following order (implemented by alphabetical order here!):
718
# FIRST, the DEFAULT startup should be read, THEN the HOME one and finally
719
# the CURRENT one - this way, all startup options are placed before command
720
# line ones, and the CURRENT settings can overwrite the HOME settings which
721
# can overwrite the DEFAULT ones - which are the most common.
722
# Note that to achieve this reading order, we have to build the array
723
# of filenames in reverse order (because we use unshift() for construction).
724
21
83
foreach my $type (qw(current home default))
725
{
726
# let's proceed this file first, if there is anything to do
727
# - this way, command line options can overwrite configuration
728
# settings (we already checked file existence above)
729
63
100
893
unshift @$arrayRef, join('', $prefix, $startupFiles{$type})
730
if exists $switches{$type};
731
}
732
733
# nesting ...
734
21
816
while (grep(/^$prefix/, @$arrayRef))
735
{
736
# declare scope variables
737
38
76
my (%nr, @c, $c);
738
739
# scan the array for option file hints
740
38
100
250
for ($i=0; $i<@$arrayRef; $i++)
278
1452
741
{$nr{$i}=1 if substr($arrayRef->[$i], 0, 1) eq $prefix;}
742
743
38
193
for ($i=0; $i<@$arrayRef; $i++)
744
{
745
278
100
564
if ($nr{$i})
746
{
747
# an option file - handle it
748
749
# remove the option hint
750
54
384
$arrayRef->[$i]=~s/$prefix//;
751
752
# if there is still an option file hint in the name of the file,
753
# this is a cascaded hint - insert it with a special temporary
754
# hint (has to be different from $prefix to avoid a subsequent solution
755
# by this loop)
756
54
100
535
push(@c, $arrayRef->[$i]), next if $arrayRef->[$i]=~s/^$prefix/$maskString/;
757
758
# skip nonexistent or recursively nested files
759
38
50
66
1616
next if !-e $arrayRef->[$i] || -d _ || $rfiles{$casesensitiveFilenames ? $arrayRef->[$i] : lc($arrayRef->[$i])};
50
66
760
761
# store filename to avoid recursion
762
36
50
7480
$rfiles{$casesensitiveFilenames ? $arrayRef->[$i] : lc($arrayRef->[$i])}=1;
763
764
# open file and read its contents
765
36
2111
open(OPT, $arrayRef->[$i]);
766
{
767
# scopy
768
36
82
my ($pod);
36
131
769
770
# handle every line
771
36
802
while ()
772
{
773
# check for POD directives
774
608
100
1499
$pod=1 if /^=\w/;
775
608
100
1979
$pod=0, next if /^=cut/;
776
777
# skip space and comment lines (including POD)
778
592
100
100
6189
next if /^\s*$/ || /^\s*\#/ || $pod;
100
779
780
# remove newlines, leading and trailing spaces
781
200
2087
s/\s*\n?$//; s/^\s*//;
200
708
782
783
# get "shellwords", double backslashes before Dollar characters
784
# as they would get lost otherwise (other backslash removals are welcome!)
785
200
732
s/\\\$/\\\\\$/g;
786
200
979
my (@shellwords)=shellwords($_);
787
788
# replace environment variables, if necessary
789
200
100
18180
if (exists $switches{resolveEnvVars})
790
{
791
# get *quoted* strings
792
11
35
my (@quotedwords)=quotewords('\s+', 1, $_);
793
794
# process all strings
795
11
1508
for (my $i=0; $i<@shellwords; ++$i)
796
{
797
# substitute environment variables, except in single quoted strings
798
31
100
89
unless ($quotedwords[$i]=~/^'.+'$/)
799
{
800
# named variables
801
29
100
73
$shellwords[$i]=~s/(?
7
52
802
803
# symbolic variables
804
29
50
63
$shellwords[$i]=~s/(?
5
39
805
806
# finally, remove the backslashes before Dollar characters we added above
807
29
95
$shellwords[$i]=~s/\\\$/\$/g;
808
}
809
}
810
}
811
812
# resolve relative pathes, if requested
813
200
100
571
if (exists $switches{resolveRelativePathes})
814
{
815
# process all strings
816
10
39
foreach my $string (@shellwords)
817
{
818
# scopy
819
11
16
my @p;
820
# replace as necessary
821
11
100
293
@p=(defined($1) ? $1 : '', $2), $string=~s#^$p[0]$p[1]#join('', $p[0], abs_path(catfile(dirname($arrayRef->[$i]), $p[1])))#e
5
100
1001
822
if $string=~m#^($prefix)?([./]+)/#;
823
}
824
}
825
826
# supply results
827
200
1561
push(@c, @shellwords);
828
}
829
}
830
}
831
else
832
{
833
# a normal option or parameter - handle it
834
224
966
push(@c, $arrayRef->[$i]);
835
}
836
}
837
838
# substitute file options by prefixes, if necessary
839
38
100
161
_fileOptions2prefixes($fileOption, $prefix, \@c) if $fileOption;
840
841
# replace original array by expanded array
842
38
1316
@$arrayRef=@c;
843
}
844
845
# reset hint character in cascaded hints to $prefix
846
21
102
@$arrayRef=map {s/^$maskString/$prefix/; $_} @$arrayRef;
334
879
334
3874
847
}
848
849
850
# allow one line invokation via "use", but make sure to keep backwards compatibility to
851
# the traditional interface inherited from Exporter
852
sub import
853
{
854
# check if the caller intended to import symbols
855
# (till 1.06, import() was inherited from Exporter and the only symbol to import was argvFile())
856
8
100
66
8
144
if (@_==2 and $_[-1] eq "argvFile")
6
16262
857
{goto &Exporter::import;}
858
else
859
{
860
# shift away the module name
861
2
4
shift;
862
863
# invoke argvFile(): now option files are processed while the module is loaded
864
2
32
argvFile(@_);
865
}
866
}
867
868
869
870
# preprocess an array to convert the -fileOption string into a prefix
871
sub _fileOptions2prefixes
872
{
873
# get and check parameters
874
15
15
71
my ($fileOption, $prefix, $arrayRef)=@_;
875
876
# anything to do?
877
15
50
41
if ($fileOption)
878
{
879
# make options a string and replace all file options by a prefix
880
# (to replace the file option and its successor by the prefixed successor)
881
15
117
my $options=join("\x01\x01\x01", @$arrayRef);
882
15
329
$options=~s/($optionPrefixPattern$fileOption\x01+)/$prefix/g;
883
884
# replace original array
885
15
183
@$arrayRef=split(/\x01\x01\x01/, $options);;
886
}
887
}
888
889
890
891
# flag this module was read successfully
892
1;
893
894
# POD TRAILER ####################################################
895
896
=pod
897
898
=head1 ONE LINE INVOCATION
899
900
The traditional two line sequence
901
902
# load the module
903
use Getopt::ArgvFile qw(argvFile);
904
905
...
906
907
# solve option files
908
argvFile(default=>1);
909
910
can be reduced to one line - just pass the parameters of C
911
to C:
912
913
# load module and process option file hints in @ARGV
914
use Getopt::ArgvFile default=>1;
915
916
Please note that in this case option file hints are processed at compile
917
time. This means that if you want to process alternative arrays, these
918
arrays have to be prepared before, usually in a C block.
919
920
In versions 1.07 and above, implicit option file handling is the I
921
and only suppressed for the traditional
922
923
use Getopt::ArgvFile qw(argvFile);
924
925
loading, for reasons of backwards compatibility. A simple loading like
926
927
use Getopt::ArgvFile;
928
929
I process option hints! If you want to suppress this, use the
930
B> switch:
931
932
use Getopt::ArgvFile justload=>1;
933
934
See I for additional informations.
935
936
=head1 NOTES
937
938
If a script calling C with the C switch is
939
invoked using a relative path, it is strongly recommended to
940
perform the call of C in the startup directory
941
because C then uses the I script path as
942
well.
943
944
945
=head1 LIMITS
946
947
If an option file does not exist, argvFile() simply ignores it.
948
No message will be displayed, no special return code will be set.
949
950
=head1 AUTHOR
951
952
Jochen Stenzel Emailto:perl@jochen-stenzel.deE
953
954
=head1 LICENSE
955
956
Copyright (c) 1993-2007 Jochen Stenzel. All rights reserved.
957
958
This program is free software, you can redistribute it and/or modify it
959
under the terms of the Artistic License distributed with Perl version
960
5.003 or (at your option) any later version. Please refer to the
961
Artistic License that came with your Perl distribution for more
962
details.
963
964
=cut