line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# Copyright (C) 1999-2002, 2011 Matevz Tadel. |
2
|
|
|
|
|
|
|
# Released under Perl License. |
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
# Parses a configuration file defining command line options and |
5
|
|
|
|
|
|
|
# default values for global variables. |
6
|
|
|
|
|
|
|
# |
7
|
|
|
|
|
|
|
# Default values are evaled ... so be careful. |
8
|
|
|
|
|
|
|
# Legal to return \@ or \% ... but read Getopt::Long for what it means and |
9
|
|
|
|
|
|
|
# how such cases are treated. |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
package Getopt::FileConfig; |
12
|
|
|
|
|
|
|
|
13
|
1
|
|
|
1
|
|
2430
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
51
|
|
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
our $VERSION = "1.0001"; |
16
|
|
|
|
|
|
|
|
17
|
1
|
|
|
1
|
|
1306
|
use Getopt::Long qw(GetOptionsFromArray); |
|
1
|
|
|
|
|
16843
|
|
|
1
|
|
|
|
|
8
|
|
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
sub new |
20
|
|
|
|
|
|
|
{ |
21
|
2
|
|
|
2
|
1
|
56
|
my $proto = shift; |
22
|
2
|
|
33
|
|
|
10
|
my $class = ref($proto) || $proto; |
23
|
2
|
|
|
|
|
8
|
my $S = {@_}; |
24
|
2
|
|
|
|
|
4
|
bless($S, $class); |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
# -defcfg, -cfgbase, -useenv, -verbose, -hash |
27
|
|
|
|
|
|
|
# pass defcfg as string or arr-ref ... it *WILL* become aref |
28
|
2
|
50
|
|
|
|
9
|
if (defined $S->{-defcfg}) |
29
|
|
|
|
|
|
|
{ |
30
|
2
|
50
|
|
|
|
13
|
$S->{-defcfg} = [ $S->{-defcfg} ] unless ref $S->{-defcfg} eq "ARRAY"; |
31
|
|
|
|
|
|
|
} |
32
|
|
|
|
|
|
|
else |
33
|
|
|
|
|
|
|
{ |
34
|
0
|
|
|
|
|
0
|
$S->{-defcfg} = []; |
35
|
|
|
|
|
|
|
} |
36
|
2
|
|
|
|
|
3
|
my $cfgbase; |
37
|
2
|
50
|
|
|
|
5
|
if (defined $S->{-cfgbase}) |
38
|
|
|
|
|
|
|
{ |
39
|
0
|
|
|
|
|
0
|
$cfgbase = $S->{-cfgbase}; |
40
|
|
|
|
|
|
|
} |
41
|
|
|
|
|
|
|
else |
42
|
|
|
|
|
|
|
{ |
43
|
2
|
|
|
|
|
14
|
$0 =~ m!([^/]+?)(?:\.[^.]*)?$!; |
44
|
2
|
|
|
|
|
4
|
$cfgbase = $1; |
45
|
|
|
|
|
|
|
} |
46
|
2
|
|
|
|
|
7
|
$S->{ProgName} = $cfgbase; |
47
|
2
|
|
|
|
|
3
|
push @{$S->{-defcfg}}, "$ENV{PWD}/${cfgbase}.rc", |
|
2
|
|
|
|
|
18
|
|
48
|
|
|
|
|
|
|
"$ENV{PWD}/.${cfgbase}.rc", |
49
|
|
|
|
|
|
|
"$ENV{HOME}/cfg/${cfgbase}.rc", |
50
|
|
|
|
|
|
|
"$ENV{HOME}/.${cfgbase}.rc"; |
51
|
2
|
|
|
|
|
5
|
$S->{PostFoos} = []; |
52
|
|
|
|
|
|
|
|
53
|
2
|
|
|
|
|
5
|
return $S; |
54
|
|
|
|
|
|
|
} |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
sub add_post_foo |
57
|
|
|
|
|
|
|
{ |
58
|
0
|
|
|
0
|
1
|
0
|
my ($S, $foo) = @_; |
59
|
0
|
|
|
|
|
0
|
push @{$S->{PostFoos}}, $foo; |
|
0
|
|
|
|
|
0
|
|
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
sub parse() |
63
|
|
|
|
|
|
|
{ |
64
|
|
|
|
|
|
|
# Parses options from an array-ref and populates the appropriate |
65
|
|
|
|
|
|
|
# namepsaces or a hash, if it was given with -hash option to ctor. |
66
|
|
|
|
|
|
|
# |
67
|
|
|
|
|
|
|
# Args: |
68
|
|
|
|
|
|
|
# $aref -- array of command-line options; if nothing is passed, |
69
|
|
|
|
|
|
|
# @ARGV is going to be used. |
70
|
|
|
|
|
|
|
|
71
|
2
|
|
|
2
|
1
|
21
|
my $S = shift; |
72
|
2
|
|
|
|
|
3
|
my $aref = shift; |
73
|
2
|
50
|
|
|
|
5
|
$aref = \@ARGV unless defined $aref; |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
# First let's find the config file. |
76
|
2
|
50
|
33
|
|
|
3
|
if ($#{$aref} > 0 && $aref->[0] eq "-cfg") |
|
2
|
|
|
|
|
12
|
|
77
|
|
|
|
|
|
|
{ |
78
|
0
|
|
|
|
|
0
|
shift @$aref; $S->{Config} = shift @$aref; |
|
0
|
|
|
|
|
0
|
|
79
|
0
|
0
|
|
|
|
0
|
die "Getopt::FileConfig::parse: config file '$S->{Config}' not readable." |
80
|
|
|
|
|
|
|
unless -r $S->{Config}; |
81
|
|
|
|
|
|
|
} |
82
|
|
|
|
|
|
|
else |
83
|
|
|
|
|
|
|
{ |
84
|
2
|
|
|
|
|
3
|
for my $c (@{$S->{-defcfg}}) |
|
2
|
|
|
|
|
5
|
|
85
|
|
|
|
|
|
|
{ |
86
|
2
|
50
|
|
|
|
34
|
if (-r $c) |
87
|
|
|
|
|
|
|
{ |
88
|
2
|
|
|
|
|
4
|
$S->{Config} = $c; |
89
|
2
|
|
|
|
|
4
|
last; |
90
|
|
|
|
|
|
|
} |
91
|
|
|
|
|
|
|
} |
92
|
2
|
50
|
|
|
|
7
|
die "Getopt::FileConfig::parse: config file not found." |
93
|
|
|
|
|
|
|
unless defined $S->{Config}; |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
2
|
|
|
|
|
4
|
$S->{CmdlOpts} = []; |
97
|
2
|
|
|
|
|
6
|
$S->{Vars} = []; |
98
|
|
|
|
|
|
|
|
99
|
2
|
50
|
|
|
|
7
|
print "Using config $S->{Config} ...\n" if $S->{-verbose}; |
100
|
2
|
50
|
33
|
|
|
17
|
print "Using environment overrides of defaults ...\n" |
101
|
|
|
|
|
|
|
if $S->{-useenv} and $S->{-verbose}; |
102
|
|
|
|
|
|
|
|
103
|
2
|
|
|
|
|
75
|
open CFG, $S->{Config}; |
104
|
2
|
|
|
|
|
32
|
while () |
105
|
|
|
|
|
|
|
{ |
106
|
18
|
100
|
66
|
|
|
104
|
next if /^#/ || /^\s/; |
107
|
8
|
|
|
|
|
12
|
chomp; |
108
|
8
|
|
|
|
|
30
|
my ($conf, $type, $context, $var, $def) = split(' ',$_,5); |
109
|
8
|
|
|
|
|
10
|
my ($varref, $symref); |
110
|
|
|
|
|
|
|
# Env overrides? |
111
|
8
|
50
|
33
|
|
|
27
|
if($S->{-useenv} && defined $ENV{$var}) { |
112
|
0
|
|
|
|
|
0
|
$def = $ENV{$var}; |
113
|
|
|
|
|
|
|
} |
114
|
|
|
|
|
|
|
# Set default value |
115
|
8
|
100
|
|
|
|
16
|
if ($S->{-hash}) |
116
|
|
|
|
|
|
|
{ |
117
|
4
|
100
|
66
|
|
|
18
|
if ($context eq 'main' or $context eq ".") |
118
|
|
|
|
|
|
|
{ |
119
|
3
|
|
|
|
|
153
|
$S->{-hash}{$var} = eval $def; |
120
|
3
|
100
|
|
|
|
16
|
$varref = ref ($S->{-hash}{$var}) ? |
121
|
|
|
|
|
|
|
$S->{-hash}{$var} : \$S->{-hash}{$var}; |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
else |
124
|
|
|
|
|
|
|
{ |
125
|
1
|
|
|
|
|
30
|
$S->{-hash}{$context}{$var} = eval $def; |
126
|
1
|
50
|
|
|
|
8
|
$varref = ref ($S->{-hash}{$context}{$var}) ? |
127
|
|
|
|
|
|
|
$S->{-hash}{$context}{$var} : \$S->{-hash}{$context}{$var}; |
128
|
|
|
|
|
|
|
} |
129
|
4
|
|
|
|
|
5
|
$symref = 0; # not used for hashes |
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
else |
132
|
|
|
|
|
|
|
{ |
133
|
1
|
|
|
1
|
|
1119
|
no strict "refs"; |
|
1
|
|
|
|
|
9
|
|
|
1
|
|
|
|
|
912
|
|
134
|
|
|
|
|
|
|
|
135
|
4
|
100
|
|
|
|
9
|
$context = "main" if $context eq "."; |
136
|
4
|
|
|
|
|
8
|
$symref = "${context}::$var"; |
137
|
4
|
|
|
|
|
221
|
${$symref} = eval $def; |
|
4
|
|
|
|
|
17
|
|
138
|
4
|
100
|
|
|
|
9
|
$varref = ref ${$symref} ? ${$symref} : \${$symref}; |
|
4
|
|
|
|
|
10
|
|
|
3
|
|
|
|
|
7
|
|
|
1
|
|
|
|
|
3
|
|
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
# Store some details |
141
|
8
|
|
|
|
|
10
|
push @{$S->{Vars}}, [$varref, $symref, $context, $var, $def]; |
|
8
|
|
|
|
|
26
|
|
142
|
|
|
|
|
|
|
# voodoo for Getopt |
143
|
8
|
50
|
33
|
|
|
37
|
if ($type ne 'x' and $type ne 'exclude') |
144
|
|
|
|
|
|
|
{ |
145
|
8
|
50
|
33
|
|
|
30
|
$type='' if $type eq 'b' or $type eq 'bool'; |
146
|
8
|
|
|
|
|
8
|
push @{$S->{CmdlOpts}}, "$conf$type", $varref; |
|
8
|
|
|
|
|
40
|
|
147
|
|
|
|
|
|
|
} |
148
|
|
|
|
|
|
|
} |
149
|
2
|
|
|
|
|
4
|
GetOptionsFromArray($aref, @{$S->{CmdlOpts}}); |
|
2
|
|
|
|
|
11
|
|
150
|
2
|
|
|
|
|
1311
|
for my $f (@{$S->{PostFoos}}) |
|
2
|
|
|
|
|
28
|
|
151
|
|
|
|
|
|
|
{ |
152
|
0
|
0
|
|
|
|
|
if ($S->{-hash}) |
153
|
|
|
|
|
|
|
{ |
154
|
0
|
|
|
|
|
|
&$f($S->{-hash}); |
155
|
|
|
|
|
|
|
} |
156
|
|
|
|
|
|
|
else |
157
|
|
|
|
|
|
|
{ |
158
|
0
|
|
|
|
|
|
&$f(); |
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
} |
161
|
|
|
|
|
|
|
} |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
sub parse_string() |
164
|
|
|
|
|
|
|
{ |
165
|
|
|
|
|
|
|
# Splits string argument into an array, then calls parse with this |
166
|
|
|
|
|
|
|
# array. |
167
|
|
|
|
|
|
|
|
168
|
0
|
|
|
0
|
1
|
|
my ($S, $str) = @_; |
169
|
0
|
|
|
|
|
|
my @a = split(' ', $str); |
170
|
|
|
|
|
|
|
# rejoin what was unjustfully split (' and "). what a pain ... do it stupidly |
171
|
|
|
|
|
|
|
# also strips them off after a match is found |
172
|
0
|
|
|
|
|
|
my ($n, $np, $inm) = (0, -1, 0); |
173
|
0
|
|
|
|
|
|
while ($n <= $#a) |
174
|
|
|
|
|
|
|
{ |
175
|
0
|
0
|
0
|
|
|
|
if ($inm and $a[$n]=~m/$inm$/) |
|
|
0
|
0
|
|
|
|
|
176
|
|
|
|
|
|
|
{ |
177
|
0
|
|
|
|
|
|
my $subst = join(' ', @a[$np, $n]); |
178
|
0
|
|
|
|
|
|
substr $subst,0,1,''; substr $subst,-1,1,''; |
|
0
|
|
|
|
|
|
|
179
|
0
|
|
|
|
|
|
splice @a, $np, $n-$np+1, $subst; |
180
|
0
|
|
|
|
|
|
$n = $np+1; $np = -1; $inm = 0; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
181
|
0
|
|
|
|
|
|
redo; |
182
|
|
|
|
|
|
|
} |
183
|
|
|
|
|
|
|
elsif(not $inm and $a[$n]=~m/^([\'\"])/) |
184
|
|
|
|
|
|
|
{ |
185
|
0
|
|
|
|
|
|
$np = $n; $inm = $1; |
|
0
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
} |
187
|
0
|
|
|
|
|
|
$n++; |
188
|
|
|
|
|
|
|
} |
189
|
0
|
|
|
|
|
|
$S->parse(@a); |
190
|
|
|
|
|
|
|
} |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
########################################################################## |
194
|
|
|
|
|
|
|
# Non-OO helper functions. |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
sub assert_presence_of_keys |
197
|
|
|
|
|
|
|
{ |
198
|
|
|
|
|
|
|
# Asserts keys are in hash ... otherwise assign defaults. |
199
|
|
|
|
|
|
|
# Args: |
200
|
|
|
|
|
|
|
# hash-ref - to be checked; |
201
|
|
|
|
|
|
|
# defaults in 'key' => 'default-value' format. |
202
|
|
|
|
|
|
|
# Default value can be '' -> then the function will die if this |
203
|
|
|
|
|
|
|
# key is not existing (it can be undefined). |
204
|
|
|
|
|
|
|
|
205
|
0
|
|
|
0
|
0
|
|
my $h = shift; |
206
|
0
|
0
|
|
|
|
|
die "pook_href: this not a hashref" unless ref $h eq "HASH"; |
207
|
0
|
|
|
|
|
|
my $d = {@_}; |
208
|
0
|
|
|
|
|
|
for my $k (keys %$d) |
209
|
|
|
|
|
|
|
{ |
210
|
0
|
0
|
|
|
|
|
if ($d->{$k} eq '') |
211
|
|
|
|
|
|
|
{ |
212
|
0
|
0
|
|
|
|
|
die "required key $k missing from given hash" unless exists $h->{$k}; |
213
|
0
|
|
|
|
|
|
next; |
214
|
|
|
|
|
|
|
} |
215
|
0
|
0
|
|
|
|
|
$h->{$k} = $d->{$k} unless exists $h->{$k}; |
216
|
|
|
|
|
|
|
} |
217
|
|
|
|
|
|
|
} |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
1; |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
################################################################################ |
223
|
|
|
|
|
|
|
# |
224
|
|
|
|
|
|
|
# DOCUMENTATION |
225
|
|
|
|
|
|
|
# |
226
|
|
|
|
|
|
|
################################################################################ |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
=head1 NAME |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
Getopt::FileConfig - Perl module for parsing configuration files |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
=head1 SYNOPSIS |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
use Getopt::FileConfig; |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
# Default processing ... search for cfg file in the following locations: |
237
|
|
|
|
|
|
|
# ./$base.rc ./.$base.rc, ~/cfg/$base.rc and ~/.$base.rc |
238
|
|
|
|
|
|
|
# where $base is 'basename $0 .any-suffix'. |
239
|
|
|
|
|
|
|
$cfg = new Getopt::FileConfig(); |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
# Specify default cfg file |
242
|
|
|
|
|
|
|
$cfg = new Getopt::FileConfig(-defcfg=>"$ENV{XX_RUN_CONTROL}/globals.rc"); |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
# To override cfg file defaults from environment |
245
|
|
|
|
|
|
|
$cfg = new Getopt::FileConfig(-useenv=>1); |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
# To dump values into a hash instead into 'true' vars: |
248
|
|
|
|
|
|
|
$config = {}; |
249
|
|
|
|
|
|
|
$cfg = new Getopt::FileConfig(-hash=>$config); |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
# Do the work: set-up vars with defaults, patch with cmdl opts |
252
|
|
|
|
|
|
|
$cfg->parse(); # parses @ARGV |
253
|
|
|
|
|
|
|
$cfg->parse(\@my_array); # parses any array |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
=head1 DESCRIPTION |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
Getopt::FileConfig is a module for processing of configuration files which |
259
|
|
|
|
|
|
|
define some variables to be exported into the callers |
260
|
|
|
|
|
|
|
namespace(s). These variables can be optionally overriden from |
261
|
|
|
|
|
|
|
environment variables and unconditionally from command line |
262
|
|
|
|
|
|
|
arguments. C is used for the last part. |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
NOTE: Defaults are set for all variables first. Only then the command |
265
|
|
|
|
|
|
|
line options are applied. |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
The idea is that you don't really want to declare globals inside your |
268
|
|
|
|
|
|
|
perl scripts and even less to provide them some default values that are |
269
|
|
|
|
|
|
|
of limited usefulness. Instead you define them in a config file. |
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
The file is line based, each line has the form: |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
Lines that match C^#/> or C^\s*$/> are skipped. |
276
|
|
|
|
|
|
|
The namespace can be specified as . and it stands for main. |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
Eg (for my mkmenu script that generates ssh menus for windowmaker): |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
# Login name |
281
|
|
|
|
|
|
|
name =s main NAME "matevz" |
282
|
|
|
|
|
|
|
group =s main GROUP "f9base" |
283
|
|
|
|
|
|
|
# Terminal to spawn (think `$TERM -e ssh ...`) |
284
|
|
|
|
|
|
|
term =s main TERM "rxvt" |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
Then you can run it as C<'mkmenu -name root'>. |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
Read the C for explanation of the second |
289
|
|
|
|
|
|
|
parameter. For void argument specification (which means bool), use |
290
|
|
|
|
|
|
|
C<'b'> or C<'bool'>. To suppress passing of this variable to |
291
|
|
|
|
|
|
|
C use C<'x'> or C<'exclude'>. |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
=head1 SYNTAX |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
=over 4 |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
=item $cfg = new Getopt::FileConfig() |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
Will create new Getopt::FileConfig objects. Options can be set on |
301
|
|
|
|
|
|
|
construction time using the hash syntax C<< -option => value >> or |
302
|
|
|
|
|
|
|
later by assigning to a data member as in C<< $cfg->{-option = value} |
303
|
|
|
|
|
|
|
>>. This is the list of options: |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
=over 4 |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
=item -cfgbase |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
Changes the prefix used to search for configuration files. By default, the |
310
|
|
|
|
|
|
|
$cfgbase is extracted from $0: |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
$0 =~ m!([^/]+?)(?:\.[^.]*)?$!; |
313
|
|
|
|
|
|
|
$cfgbase = $1; |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
which is good, as you can use symlinks to the same executable to get different |
316
|
|
|
|
|
|
|
default values. Locations searched by default are: |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
$ENV{PWD}/${cfgbase}.rc, |
319
|
|
|
|
|
|
|
$ENV{PWD}/.${cfgbase}.rc, |
320
|
|
|
|
|
|
|
$ENV{HOME}/cfg/${cfgbase}.rc, |
321
|
|
|
|
|
|
|
$ENV{HOME}/.${cfgbase}.rc; |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
$cfgbase that is used is stored into $cfg->{ProgName}. |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
=item -defcfg |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
Specifies the default location of the configuration file. Can be an |
328
|
|
|
|
|
|
|
array reference to specify several locations to search the file |
329
|
|
|
|
|
|
|
for. Some are predefined, but the ones given here are considered |
330
|
|
|
|
|
|
|
first. See L for details. The file list is |
331
|
|
|
|
|
|
|
created on construction time so be careful if you modify the list by |
332
|
|
|
|
|
|
|
hand. |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
=item -useenv |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
If set to non zero values of environment variables will take |
337
|
|
|
|
|
|
|
precedence over config file defaults. Command line options are still |
338
|
|
|
|
|
|
|
more potent. See L. |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
=item -hash |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
If set to a hash reference the variables will be exported into it. See |
343
|
|
|
|
|
|
|
L. |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
=item -verbose |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
If set to non zero Getopt::FileConfig will dump a moderate amount of info |
348
|
|
|
|
|
|
|
during C. |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
=back |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
=item add_post_foo() |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
Adds to the list of functions that are called after the |
355
|
|
|
|
|
|
|
setting of the variables and patching from command line. Useful when |
356
|
|
|
|
|
|
|
you need to create some compound variables. If C<-hash> is set, the |
357
|
|
|
|
|
|
|
hash reference is passed to these functions as the only argument. |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
=item parse() |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
Does all the job: selects config file to be used, reads it, sets the |
362
|
|
|
|
|
|
|
default values and the calls GetOptions. After that the post functions |
363
|
|
|
|
|
|
|
are invoked. If nothing as passes, @ARGV is used. |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
=item parse_string() |
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
Splits string into an array and calls C, pretending that this |
368
|
|
|
|
|
|
|
string was the actual command line. |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
I used this option to recreate certain variables (for job control and |
371
|
|
|
|
|
|
|
dbase insertion) from list of commands that were submitting jobs into |
372
|
|
|
|
|
|
|
the queuing system. |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
=back |
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
=head1 BUILT-IN CONFIG FILE RULES |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
If you dont specify the default cfg file, Getopt::FileConfig searches for it |
381
|
|
|
|
|
|
|
in the following locations: |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
$base = `basename $0 .pl`; # can be set with -cfgbase=>'foo' |
384
|
|
|
|
|
|
|
`pwd`/${base}.rc |
385
|
|
|
|
|
|
|
`pwd`/.${base}.rc |
386
|
|
|
|
|
|
|
~/cfg/${base}.rc |
387
|
|
|
|
|
|
|
~/.${base}.rc |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
If you do specify the C<-defcfg> it is prepended to the above |
390
|
|
|
|
|
|
|
list. The first found file is used. You can obtain it from |
391
|
|
|
|
|
|
|
C<< $cfg->{Config} >>. Also, the program name can be obtained from |
392
|
|
|
|
|
|
|
C<< $cfg->{ProgName} >>. |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
Will add additional variables enabling a user to fully specify the |
395
|
|
|
|
|
|
|
format of these locations when typical use-cases are gathered (perhaps |
396
|
|
|
|
|
|
|
/etc/... ?). |
397
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
By creating symlinks to a master script you can have several |
399
|
|
|
|
|
|
|
config files for the same script and get different default behaviour. |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
If C<$ARGV[0]> of the script using Getopt::FileConfig is C<-cfg>, then |
402
|
|
|
|
|
|
|
C<$ARGV[1]> is used as a configuration file and no other locations are |
403
|
|
|
|
|
|
|
scanned. |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
Getopt::FileConfig::parse() dies if it can't find any of these files. It |
406
|
|
|
|
|
|
|
should croak. |
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
=head1 DEFAULT VALUES |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
So far all default values are eval-ed prior to assignment. Which means |
412
|
|
|
|
|
|
|
you can use C<[]> or C<{}> or C to get array/hash/closure |
413
|
|
|
|
|
|
|
reference as a default value. Getopt::Long treats such variables |
414
|
|
|
|
|
|
|
differently ... so read its manual to learn more. But, BEWARE, the |
415
|
|
|
|
|
|
|
command line option arguments are NOT eval-ed. Bug Johan Vromans for |
416
|
|
|
|
|
|
|
this option and then I'll do my part. Then would also add the eval |
417
|
|
|
|
|
|
|
control on per-variable base into the config file. |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
You can as well instantiate an object ... decide for yourself ... it |
420
|
|
|
|
|
|
|
doesn't sound like such a great idea to me. C isn't too |
421
|
|
|
|
|
|
|
keen of the idea either, so make sure to suppress passing an obj ref |
422
|
|
|
|
|
|
|
to it. |
423
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
One of the more obscene uses of this feature is to write in the config file: |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
remap =s main REMAP do "$ENV{HOME}/.domain.remaps" |
427
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
where the file .domain.remaps is, eg: |
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
{ |
431
|
|
|
|
|
|
|
"some.domain:other.domain" => { |
432
|
|
|
|
|
|
|
"/u/atlas/matevz" => "/home/matevz", |
433
|
|
|
|
|
|
|
"/opt/agnes" => "/opt" |
434
|
|
|
|
|
|
|
} |
435
|
|
|
|
|
|
|
"foo.domain:some.domain" => { |
436
|
|
|
|
|
|
|
"/afs/cern.ch/user/m/matevz" => "/u/atlas/matevz" |
437
|
|
|
|
|
|
|
} |
438
|
|
|
|
|
|
|
} |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
This will make C<$REMAP> a hash ref to the above struct. |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
Of course you are not limited to a single statement ... but then use |
443
|
|
|
|
|
|
|
C<;s> and know your eval. Don't use newlines or you'll confuse the |
444
|
|
|
|
|
|
|
parser. If you're annoyed by that you/I can fix the parser to grog a |
445
|
|
|
|
|
|
|
trailing C<\> as a continuation symbol. |
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
=head1 ENVIRONMENT OVERRIDES |
449
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
If C<< $cfg->{-useenv} >> is true, then the defaults are taken from the |
451
|
|
|
|
|
|
|
environment. The names of perl and environment variable must be the |
452
|
|
|
|
|
|
|
same AND the env-var must be set (ie: C must |
453
|
|
|
|
|
|
|
be true). The values of env vars are eval-ed, too. So take care. |
454
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
This means you're asking for trouble if several variables in different |
456
|
|
|
|
|
|
|
namespaces have the same names. Or maybe not, if you know what you are |
457
|
|
|
|
|
|
|
doing. |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
Probably should set some additional flags that would mean do-not-eval |
460
|
|
|
|
|
|
|
and never-override-from environment. Probably with some prefixes to |
461
|
|
|
|
|
|
|
the default value or to the type of a command line option (like |
462
|
|
|
|
|
|
|
C<{xs}=s>). |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
=head1 MULTIPLE CONFIG FILES |
466
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
You're free to invoke C several times. As in: |
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
# db options |
470
|
|
|
|
|
|
|
$o = new Getopt::FileConfig(-defcfg=>"$ENV{PRODDIR}/cfg/db.rc", -useenv=>1); |
471
|
|
|
|
|
|
|
$o->parse(); |
472
|
|
|
|
|
|
|
# Tape options |
473
|
|
|
|
|
|
|
$to = new Getopt::FileConfig(-defcfg=>"$ENV{PRODDIR}/cfg/tape_${OCEAN}.rc"); |
474
|
|
|
|
|
|
|
$to->parse(); |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
When invoking the command make sure to use -- between options intended |
477
|
|
|
|
|
|
|
for different config file parsers. |
478
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
=head1 PARSING INTO A HASHREF |
481
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
By setting C<< $cfg->{-hash} = >> you can redirect |
483
|
|
|
|
|
|
|
parsing into this hash (instead of namespace globals). A non-main |
484
|
|
|
|
|
|
|
namespace name induces an additional level of hashing. |
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
Example: |
487
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
Having a config file pcm.rc |
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
simple =s . SIMPLE "blak" |
491
|
|
|
|
|
|
|
aref =s . AREF [] |
492
|
|
|
|
|
|
|
href =s Kazaan HREF {} |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
and perl script pcm.pl |
495
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
#!/usr/bin/perl |
497
|
|
|
|
|
|
|
use Getopt::FileConfig; |
498
|
|
|
|
|
|
|
use Data::Dumper; |
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
$XX = {}; |
501
|
|
|
|
|
|
|
my $cfg = new Getopt::FileConfig(-hash=>$XX); |
502
|
|
|
|
|
|
|
$cfg->parse(); |
503
|
|
|
|
|
|
|
print Dumper($XX); |
504
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
The result of running |
506
|
|
|
|
|
|
|
C is: |
507
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
$VAR1 = { |
509
|
|
|
|
|
|
|
'AREF' => [ |
510
|
|
|
|
|
|
|
'pepe', |
511
|
|
|
|
|
|
|
'lojz' |
512
|
|
|
|
|
|
|
], |
513
|
|
|
|
|
|
|
'Kazaan' => { |
514
|
|
|
|
|
|
|
'HREF' => { |
515
|
|
|
|
|
|
|
'drek' => 'shit', |
516
|
|
|
|
|
|
|
'joska' => 'boob' |
517
|
|
|
|
|
|
|
} |
518
|
|
|
|
|
|
|
}, |
519
|
|
|
|
|
|
|
'SIMPLE' => 'blak' |
520
|
|
|
|
|
|
|
}; |
521
|
|
|
|
|
|
|
|
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
=head1 AUTHOR |
524
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
Matevz Tadel |