| 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 |