1
by Chuck Short
Import upstream version 5.1.30 |
1 |
# -*- cperl -*-
|
2 |
||
1.1.5
by Marc Deslauriers
Import upstream version 5.1.61 |
3 |
# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
|
4 |
#
|
|
5 |
# This program is free software; you can redistribute it and/or modify
|
|
6 |
# it under the terms of the GNU General Public License as published by
|
|
7 |
# the Free Software Foundation; version 2 of the License.
|
|
8 |
#
|
|
9 |
# This program is distributed in the hope that it will be useful,
|
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12 |
# GNU General Public License for more details.
|
|
13 |
#
|
|
14 |
# You should have received a copy of the GNU General Public License
|
|
15 |
# along with this program; if not, write to the Free Software
|
|
16 |
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17 |
||
1
by Chuck Short
Import upstream version 5.1.30 |
18 |
package My::Config::Option; |
19 |
||
20 |
use strict; |
|
21 |
use warnings; |
|
0.1.1
by Norbert Tretkowski
Import upstream version 5.1.32 |
22 |
use Carp; |
1
by Chuck Short
Import upstream version 5.1.30 |
23 |
|
24 |
||
25 |
sub new { |
|
26 |
my ($class, $option_name, $option_value)= @_; |
|
27 |
my $self= bless { name => $option_name, |
|
28 |
value => $option_value |
|
29 |
}, $class; |
|
30 |
return $self; |
|
31 |
}
|
|
32 |
||
33 |
||
34 |
sub name { |
|
35 |
my ($self)= @_; |
|
36 |
return $self->{name}; |
|
37 |
}
|
|
38 |
||
39 |
||
40 |
sub value { |
|
41 |
my ($self)= @_; |
|
42 |
return $self->{value}; |
|
43 |
}
|
|
44 |
||
0.1.1
by Norbert Tretkowski
Import upstream version 5.1.32 |
45 |
sub option { |
46 |
my ($self)= @_; |
|
47 |
my $name= $self->{name}; |
|
48 |
my $value= $self->{value}; |
|
49 |
||
50 |
my $opt= $name; |
|
51 |
$opt= "$name=$value" if ($value); |
|
52 |
$opt= "--$opt" unless ($opt =~ /^--/); |
|
53 |
return $opt; |
|
54 |
}
|
|
1
by Chuck Short
Import upstream version 5.1.30 |
55 |
|
56 |
package My::Config::Group; |
|
57 |
||
58 |
use strict; |
|
59 |
use warnings; |
|
0.1.1
by Norbert Tretkowski
Import upstream version 5.1.32 |
60 |
use Carp; |
1
by Chuck Short
Import upstream version 5.1.30 |
61 |
|
62 |
sub new { |
|
63 |
my ($class, $group_name)= @_; |
|
64 |
my $self= bless { name => $group_name, |
|
65 |
options => [], |
|
66 |
options_by_name => {}, |
|
67 |
}, $class; |
|
68 |
return $self; |
|
69 |
}
|
|
70 |
||
71 |
||
72 |
sub insert { |
|
73 |
my ($self, $option_name, $value, $if_not_exist)= @_; |
|
74 |
my $option= $self->option($option_name); |
|
75 |
if (defined($option) and !$if_not_exist) { |
|
76 |
$option->{value}= $value; |
|
77 |
}
|
|
78 |
else { |
|
79 |
my $option= My::Config::Option->new($option_name, $value); |
|
80 |
# Insert option in list
|
|
81 |
push(@{$self->{options}}, $option); |
|
82 |
# Insert option in hash
|
|
83 |
$self->{options_by_name}->{$option_name}= $option; |
|
84 |
}
|
|
85 |
return $option; |
|
86 |
}
|
|
87 |
||
88 |
sub remove { |
|
89 |
my ($self, $option_name)= @_; |
|
90 |
||
91 |
# Check that option exists
|
|
92 |
my $option= $self->option($option_name); |
|
93 |
||
94 |
return undef unless defined $option; |
|
95 |
||
96 |
# Remove from the hash
|
|
0.1.1
by Norbert Tretkowski
Import upstream version 5.1.32 |
97 |
delete($self->{options_by_name}->{$option_name}) or croak; |
1
by Chuck Short
Import upstream version 5.1.30 |
98 |
|
99 |
# Remove from the array
|
|
100 |
@{$self->{options}}= grep { $_->name ne $option_name } @{$self->{options}}; |
|
101 |
||
102 |
return $option; |
|
103 |
}
|
|
104 |
||
105 |
||
106 |
sub options { |
|
107 |
my ($self)= @_; |
|
108 |
return @{$self->{options}}; |
|
109 |
}
|
|
110 |
||
111 |
||
112 |
sub name { |
|
113 |
my ($self)= @_; |
|
114 |
return $self->{name}; |
|
115 |
}
|
|
116 |
||
0.1.1
by Norbert Tretkowski
Import upstream version 5.1.32 |
117 |
sub suffix { |
118 |
my ($self)= @_; |
|
119 |
# Everything in name from the last .
|
|
120 |
my @parts= split(/\./, $self->{name}); |
|
121 |
my $suffix= pop(@parts); |
|
122 |
return ".$suffix"; |
|
123 |
}
|
|
124 |
||
125 |
sub after { |
|
126 |
my ($self, $prefix)= @_; |
|
127 |
die unless defined $prefix; |
|
128 |
||
129 |
# everything after $prefix
|
|
130 |
my $name= $self->{name}; |
|
131 |
if ($name =~ /^\Q$prefix\E(.*)$/) |
|
132 |
{
|
|
133 |
return $1; |
|
134 |
}
|
|
135 |
die "Failed to extract the value after '$prefix' in $name"; |
|
136 |
}
|
|
137 |
||
138 |
||
139 |
sub split { |
|
140 |
my ($self)= @_; |
|
141 |
# Return an array with name parts
|
|
142 |
return split(/\./, $self->{name}); |
|
143 |
}
|
|
1
by Chuck Short
Import upstream version 5.1.30 |
144 |
|
145 |
#
|
|
146 |
# Return a specific option in the group
|
|
147 |
#
|
|
148 |
sub option { |
|
149 |
my ($self, $option_name)= @_; |
|
150 |
||
151 |
return $self->{options_by_name}->{$option_name}; |
|
152 |
}
|
|
153 |
||
154 |
||
155 |
#
|
|
0.1.1
by Norbert Tretkowski
Import upstream version 5.1.32 |
156 |
# Return value for an option in the group, fail if it does not exist
|
1
by Chuck Short
Import upstream version 5.1.30 |
157 |
#
|
158 |
sub value { |
|
159 |
my ($self, $option_name)= @_; |
|
160 |
my $option= $self->option($option_name); |
|
161 |
||
0.1.1
by Norbert Tretkowski
Import upstream version 5.1.32 |
162 |
croak "No option named '$option_name' in group '$self->{name}'" |
1
by Chuck Short
Import upstream version 5.1.30 |
163 |
if ! defined($option); |
164 |
||
165 |
return $option->value(); |
|
166 |
}
|
|
167 |
||
168 |
||
0.1.1
by Norbert Tretkowski
Import upstream version 5.1.32 |
169 |
#
|
170 |
# Return value for an option if it exist
|
|
171 |
#
|
|
172 |
sub if_exist { |
|
173 |
my ($self, $option_name)= @_; |
|
174 |
my $option= $self->option($option_name); |
|
175 |
||
176 |
return undef if ! defined($option); |
|
177 |
||
178 |
return $option->value(); |
|
179 |
}
|
|
180 |
||
181 |
||
1
by Chuck Short
Import upstream version 5.1.30 |
182 |
package My::Config; |
183 |
||
184 |
use strict; |
|
185 |
use warnings; |
|
0.1.1
by Norbert Tretkowski
Import upstream version 5.1.32 |
186 |
use Carp; |
1
by Chuck Short
Import upstream version 5.1.30 |
187 |
use IO::File; |
188 |
use File::Basename; |
|
189 |
||
190 |
#
|
|
191 |
# Constructor for My::Config
|
|
192 |
# - represents a my.cnf config file
|
|
193 |
#
|
|
194 |
# Array of arrays
|
|
195 |
#
|
|
196 |
sub new { |
|
197 |
my ($class, $path)= @_; |
|
198 |
my $group_name= undef; |
|
199 |
||
200 |
my $self= bless { groups => [] }, $class; |
|
201 |
my $F= IO::File->new($path, "<") |
|
0.1.1
by Norbert Tretkowski
Import upstream version 5.1.32 |
202 |
or croak "Could not open '$path': $!"; |
1
by Chuck Short
Import upstream version 5.1.30 |
203 |
|
204 |
while ( my $line= <$F> ) { |
|
205 |
chomp($line); |
|
1.1.5
by Marc Deslauriers
Import upstream version 5.1.61 |
206 |
# Remove any trailing CR from Windows edited files
|
207 |
$line=~ s/\cM$//; |
|
1
by Chuck Short
Import upstream version 5.1.30 |
208 |
|
209 |
# [group]
|
|
0.1.1
by Norbert Tretkowski
Import upstream version 5.1.32 |
210 |
if ( $line =~ /^\[(.*)\]/ ) { |
1
by Chuck Short
Import upstream version 5.1.30 |
211 |
# New group found
|
212 |
$group_name= $1; |
|
213 |
#print "group: $group_name\n";
|
|
214 |
||
215 |
$self->insert($group_name, undef, undef); |
|
216 |
}
|
|
217 |
||
218 |
# Magic #! comments
|
|
219 |
elsif ( $line =~ /^#\!/) { |
|
220 |
my $magic= $line; |
|
0.1.1
by Norbert Tretkowski
Import upstream version 5.1.32 |
221 |
croak "Found magic comment '$magic' outside of group" |
1
by Chuck Short
Import upstream version 5.1.30 |
222 |
unless $group_name; |
223 |
||
224 |
#print "$magic\n";
|
|
225 |
$self->insert($group_name, $magic, undef); |
|
226 |
}
|
|
227 |
||
228 |
# Comments
|
|
229 |
elsif ( $line =~ /^#/ || $line =~ /^;/) { |
|
230 |
# Skip comment
|
|
231 |
next; |
|
232 |
}
|
|
233 |
||
234 |
# Empty lines
|
|
235 |
elsif ( $line =~ /^$/ ) { |
|
236 |
# Skip empty lines
|
|
237 |
next; |
|
238 |
}
|
|
239 |
||
240 |
# !include <filename>
|
|
241 |
elsif ( $line =~ /^\!include\s*(.*?)\s*$/ ) { |
|
242 |
my $include_file_name= dirname($path)."/".$1; |
|
0.1.1
by Norbert Tretkowski
Import upstream version 5.1.32 |
243 |
|
244 |
# Check that the file exists relative to path of first config file
|
|
245 |
if (! -f $include_file_name){ |
|
246 |
# Try to include file relativ to current dir
|
|
247 |
$include_file_name= $1; |
|
248 |
}
|
|
249 |
croak "The include file '$include_file_name' does not exist" |
|
1
by Chuck Short
Import upstream version 5.1.30 |
250 |
unless -f $include_file_name; |
251 |
||
252 |
$self->append(My::Config->new($include_file_name)); |
|
253 |
}
|
|
254 |
||
255 |
# <option>
|
|
256 |
elsif ( $line =~ /^([\@\w-]+)\s*$/ ) { |
|
257 |
my $option= $1; |
|
258 |
||
0.1.1
by Norbert Tretkowski
Import upstream version 5.1.32 |
259 |
croak "Found option '$option' outside of group" |
1
by Chuck Short
Import upstream version 5.1.30 |
260 |
unless $group_name; |
261 |
||
262 |
#print "$option\n";
|
|
263 |
$self->insert($group_name, $option, undef); |
|
264 |
}
|
|
265 |
||
266 |
# <option>=<value>
|
|
267 |
elsif ( $line =~ /^([\@\w-]+)\s*=\s*(.*?)\s*$/ ) { |
|
268 |
my $option= $1; |
|
269 |
my $value= $2; |
|
270 |
||
0.1.1
by Norbert Tretkowski
Import upstream version 5.1.32 |
271 |
croak "Found option '$option=$value' outside of group" |
1
by Chuck Short
Import upstream version 5.1.30 |
272 |
unless $group_name; |
273 |
||
274 |
#print "$option=$value\n";
|
|
275 |
$self->insert($group_name, $option, $value); |
|
276 |
} else { |
|
0.1.1
by Norbert Tretkowski
Import upstream version 5.1.32 |
277 |
croak "Unexpected line '$line' found in '$path'"; |
1
by Chuck Short
Import upstream version 5.1.30 |
278 |
}
|
279 |
||
280 |
}
|
|
281 |
undef $F; # Close the file |
|
282 |
||
283 |
return $self; |
|
284 |
}
|
|
285 |
||
286 |
#
|
|
287 |
# Insert a new group if it does not already exist
|
|
288 |
# and add option if defined
|
|
289 |
#
|
|
290 |
sub insert { |
|
291 |
my ($self, $group_name, $option, $value, $if_not_exist)= @_; |
|
292 |
my $group; |
|
293 |
||
294 |
# Create empty array for the group if it doesn't exist
|
|
295 |
if ( !$self->group_exists($group_name) ) { |
|
296 |
$group= $self->_group_insert($group_name); |
|
297 |
}
|
|
298 |
else { |
|
299 |
$group= $self->group($group_name); |
|
300 |
}
|
|
301 |
||
302 |
if ( defined $option ) { |
|
303 |
#print "option: $option, value: $value\n";
|
|
304 |
||
305 |
# Add the option to the group
|
|
306 |
$group->insert($option, $value, $if_not_exist); |
|
307 |
}
|
|
0.1.1
by Norbert Tretkowski
Import upstream version 5.1.32 |
308 |
return $group; |
1
by Chuck Short
Import upstream version 5.1.30 |
309 |
}
|
310 |
||
311 |
#
|
|
312 |
# Remove a option, given group and option name
|
|
313 |
#
|
|
314 |
sub remove { |
|
315 |
my ($self, $group_name, $option_name)= @_; |
|
316 |
my $group= $self->group($group_name); |
|
317 |
||
0.1.1
by Norbert Tretkowski
Import upstream version 5.1.32 |
318 |
croak "group '$group_name' does not exist" |
1
by Chuck Short
Import upstream version 5.1.30 |
319 |
unless defined($group); |
320 |
||
321 |
$group->remove($option_name) or |
|
0.1.1
by Norbert Tretkowski
Import upstream version 5.1.32 |
322 |
croak "option '$option_name' does not exist"; |
1
by Chuck Short
Import upstream version 5.1.30 |
323 |
}
|
324 |
||
325 |
||
326 |
||
327 |
#
|
|
328 |
# Check if group with given name exists in config
|
|
329 |
#
|
|
330 |
sub group_exists { |
|
331 |
my ($self, $group_name)= @_; |
|
332 |
||
333 |
foreach my $group ($self->groups()) { |
|
334 |
return 1 if $group->{name} eq $group_name; |
|
335 |
}
|
|
336 |
return 0; |
|
337 |
}
|
|
338 |
||
339 |
||
340 |
#
|
|
341 |
# Insert a new group into config
|
|
342 |
#
|
|
343 |
sub _group_insert { |
|
344 |
my ($self, $group_name)= @_; |
|
0.1.1
by Norbert Tretkowski
Import upstream version 5.1.32 |
345 |
caller eq __PACKAGE__ or croak; |
1
by Chuck Short
Import upstream version 5.1.30 |
346 |
|
347 |
# Check that group does not already exist
|
|
0.1.1
by Norbert Tretkowski
Import upstream version 5.1.32 |
348 |
croak "Group already exists" if $self->group_exists($group_name); |
1
by Chuck Short
Import upstream version 5.1.30 |
349 |
|
350 |
my $group= My::Config::Group->new($group_name); |
|
351 |
push(@{$self->{groups}}, $group); |
|
352 |
return $group; |
|
353 |
}
|
|
354 |
||
355 |
||
356 |
#
|
|
357 |
# Append a configuration to current config
|
|
358 |
#
|
|
359 |
sub append { |
|
360 |
my ($self, $from)= @_; |
|
361 |
||
362 |
foreach my $group ($from->groups()) { |
|
363 |
foreach my $option ($group->options()) { |
|
364 |
$self->insert($group->name(), $option->name(), $option->value()); |
|
365 |
}
|
|
366 |
||
367 |
}
|
|
368 |
}
|
|
369 |
||
370 |
||
371 |
#
|
|
372 |
# Return a list with all the groups in config
|
|
373 |
#
|
|
374 |
sub groups { |
|
375 |
my ($self)= @_; |
|
376 |
return ( @{$self->{groups}} ); |
|
377 |
}
|
|
378 |
||
379 |
||
380 |
#
|
|
381 |
# Return a list of all the groups in config
|
|
382 |
# starting with the given string
|
|
383 |
#
|
|
384 |
sub like { |
|
385 |
my ($self, $prefix)= @_; |
|
386 |
return ( grep ( $_->{name} =~ /^$prefix/, $self->groups()) ); |
|
387 |
}
|
|
388 |
||
389 |
||
390 |
#
|
|
391 |
# Return the first group in config
|
|
392 |
# starting with the given string
|
|
393 |
#
|
|
394 |
sub first_like { |
|
395 |
my ($self, $prefix)= @_; |
|
396 |
return ($self->like($prefix))[0]; |
|
397 |
}
|
|
398 |
||
399 |
||
400 |
#
|
|
401 |
# Return a specific group in the config
|
|
402 |
#
|
|
403 |
sub group { |
|
404 |
my ($self, $group_name)= @_; |
|
405 |
||
406 |
foreach my $group ( $self->groups() ) { |
|
407 |
return $group if $group->{name} eq $group_name; |
|
408 |
}
|
|
409 |
return undef; |
|
410 |
}
|
|
411 |
||
412 |
||
413 |
#
|
|
414 |
# Return a list of all options in a specific group in the config
|
|
415 |
#
|
|
416 |
sub options_in_group { |
|
417 |
my ($self, $group_name)= @_; |
|
418 |
||
419 |
my $group= $self->group($group_name); |
|
420 |
return () unless defined $group; |
|
421 |
return $group->options(); |
|
422 |
}
|
|
423 |
||
424 |
||
425 |
#
|
|
426 |
# Return a value given group and option name
|
|
427 |
#
|
|
428 |
sub value { |
|
429 |
my ($self, $group_name, $option_name)= @_; |
|
430 |
my $group= $self->group($group_name); |
|
431 |
||
0.1.1
by Norbert Tretkowski
Import upstream version 5.1.32 |
432 |
croak "group '$group_name' does not exist" |
1
by Chuck Short
Import upstream version 5.1.30 |
433 |
unless defined($group); |
434 |
||
435 |
my $option= $group->option($option_name); |
|
0.1.1
by Norbert Tretkowski
Import upstream version 5.1.32 |
436 |
croak "option '$option_name' does not exist" |
1
by Chuck Short
Import upstream version 5.1.30 |
437 |
unless defined($option); |
438 |
||
439 |
return $option->value(); |
|
440 |
}
|
|
441 |
||
442 |
||
443 |
#
|
|
444 |
# Check if an option exists
|
|
445 |
#
|
|
446 |
sub exists { |
|
447 |
my ($self, $group_name, $option_name)= @_; |
|
448 |
my $group= $self->group($group_name); |
|
449 |
||
0.1.1
by Norbert Tretkowski
Import upstream version 5.1.32 |
450 |
croak "group '$group_name' does not exist" |
1
by Chuck Short
Import upstream version 5.1.30 |
451 |
unless defined($group); |
452 |
||
453 |
my $option= $group->option($option_name); |
|
454 |
return defined($option); |
|
455 |
}
|
|
456 |
||
457 |
||
458 |
# Overload "to string"-operator with 'stringify'
|
|
459 |
use overload |
|
460 |
'""' => \&stringify; |
|
461 |
||
462 |
#
|
|
463 |
# Return the config as a string in my.cnf file format
|
|
464 |
#
|
|
465 |
sub stringify { |
|
466 |
my ($self)= @_; |
|
467 |
my $res; |
|
468 |
||
469 |
foreach my $group ($self->groups()) { |
|
470 |
$res .= "[$group->{name}]\n"; |
|
471 |
||
472 |
foreach my $option ($group->options()) { |
|
473 |
$res .= $option->name(); |
|
474 |
my $value= $option->value(); |
|
475 |
if (defined $value) { |
|
476 |
$res .= "=$value"; |
|
477 |
}
|
|
478 |
$res .= "\n"; |
|
479 |
}
|
|
480 |
$res .= "\n"; |
|
481 |
}
|
|
482 |
return $res; |
|
483 |
}
|
|
484 |
||
485 |
||
486 |
#
|
|
487 |
# Save the config to named file
|
|
488 |
#
|
|
489 |
sub save { |
|
0.1.1
by Norbert Tretkowski
Import upstream version 5.1.32 |
490 |
my ($self, $path)= @_; |
491 |
my $F= IO::File->new($path, ">") |
|
492 |
or croak "Could not open '$path': $!"; |
|
493 |
print $F $self; |
|
494 |
undef $F; # Close the file |
|
1
by Chuck Short
Import upstream version 5.1.30 |
495 |
}
|
496 |
||
497 |
1; |