|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Config::Properties;  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
3
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
98777
 | 
 use strict;  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
235
 | 
    | 
| 
4
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
27
 | 
 use warnings;  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
260
 | 
    | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $VERSION = '1.78';  | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
8
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
3447
 | 
 use IO::Handle;  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36006
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
348
 | 
    | 
| 
9
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
43
 | 
 use Carp;  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
325
 | 
    | 
| 
10
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
29
 | 
 use PerlIO qw();  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
88
 | 
    | 
| 
11
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
3516
 | 
 use Errno qw();  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6813
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
146
 | 
    | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 {  | 
| 
14
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
30
 | 
     no warnings;  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18506
 | 
    | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sub _t_key ($) {  | 
| 
16
 | 
70
 | 
 
 | 
 
 | 
  
70
  
 | 
 
 | 
60
 | 
 	my $k=shift;  | 
| 
17
 | 
70
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
353
 | 
 	defined($k) && length($k)  | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    or croak "invalid property key '$k'";  | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sub _t_value ($) {  | 
| 
22
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
2
 | 
 	my $v=shift;  | 
| 
23
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
 	defined $v  | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    or croak "undef is not a valid value for a property";  | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sub _t_format ($) {  | 
| 
28
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
 	my $f=shift;  | 
| 
29
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 	defined ($f) && $f=~/\%s.*\%s/  | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    or croak "invalid format '%f'";  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sub _t_validator ($) {  | 
| 
34
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
3
 | 
 	my $v=shift;  | 
| 
35
 | 
2
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
16
 | 
 	defined($v) &&  | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    UNIVERSAL::isa($v, 'CODE') or  | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		croak "invalid property validator '$v'";  | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sub _t_file ($) {  | 
| 
41
 | 
14
 | 
 
 | 
 
 | 
  
14
  
 | 
 
 | 
22
 | 
 	my $f=shift;  | 
| 
42
 | 
14
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
36
 | 
 	defined ($f) or  | 
| 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    croak "invalid file '$f'";  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sub _t_order ($) {  | 
| 
47
 | 
9
 | 
 
 | 
 
 | 
  
9
  
 | 
 
 | 
13
 | 
         my $o = shift;  | 
| 
48
 | 
9
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
65
 | 
         $o =~ /^(?:keep|alpha|none)$/ or  | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             croak "invalid order";  | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sub _t_encoding ($) {  | 
| 
53
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
11
 | 
         my $e = shift;  | 
| 
54
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
43
 | 
         $e =~ /^[\w\-]+$/ or  | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             croak "invalid encoding '$e'";  | 
| 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #   new() - Constructor  | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #   The constructor can take one optional argument "$defaultProperties"  | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #   which is an instance of Config::Properties to be used as defaults  | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #   for this object.  | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub new {  | 
| 
65
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
  
1
  
 | 
265
 | 
     my $class = shift;  | 
| 
66
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
     my $defaults;  | 
| 
67
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
30
 | 
     $defaults = shift if @_ & 1;  | 
| 
68
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
     my %opts = @_;  | 
| 
69
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
36
 | 
     $defaults = delete $opts{defaults} unless defined $defaults;  | 
| 
70
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
     my $format = delete $opts{format};  | 
| 
71
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
23
 | 
     $format = '%s=%s' unless defined $format;  | 
| 
72
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
     my $wrap = delete $opts{wrap};  | 
| 
73
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
20
 | 
     $wrap = 1 unless defined $wrap;  | 
| 
74
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     my $order = delete $opts{order};  | 
| 
75
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
19
 | 
     $order = 'keep' unless defined $order;  | 
| 
76
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
     _t_order($order);  | 
| 
77
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
     my $file = delete $opts{file};  | 
| 
78
 | 
8
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
39
 | 
     my $encoding = delete $opts{encoding} || 'latin1';  | 
| 
79
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
     _t_encoding($encoding);  | 
| 
80
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     my $eol_re = delete $opts{eol_re};  | 
| 
81
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
45
 | 
     $eol_re = qr/\r\n|\n|\r/ unless defined $eol_re;  | 
| 
82
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
193
 | 
     my $line_re = qr/^(.*?)(?:$eol_re)/s;  | 
| 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
84
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
32
 | 
     %opts and croak "invalid option(s) '" . join("', '", keys %opts) . "'";  | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
86
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
128
 | 
     if (defined $defaults) {  | 
| 
87
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         if (ref $defaults eq 'HASH') {  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
88
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             my $d = Config::Properties->new;  | 
| 
89
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             while (my ($k, $v) = each %$defaults) {  | 
| 
90
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 $d->setProperty($k, $v);  | 
| 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
92
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $defaults = $d;  | 
| 
93
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         elsif (!$defaults->isa('Config::Properties')) {  | 
| 
95
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             croak die "defaults parameter is not a Config::Properties object or a hash"  | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
99
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
79
 | 
     my $self = { defaults => $defaults,  | 
| 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		 format => $format,  | 
| 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                  wrap => $wrap,  | 
| 
102
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                  order => $order,  | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		 properties => {},  | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		 last_line_number => 0,  | 
| 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		 property_line_numbers => {},  | 
| 
106
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                  file => $file,  | 
| 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                  encoding => $encoding,  | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                  line_re => $line_re };  | 
| 
109
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30
 | 
     bless $self, $class;  | 
| 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
111
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
29
 | 
     if (defined $file) {  | 
| 
112
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         open my $fh, '<', $file or croak "unable to open file '$file': $!";  | 
| 
113
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $self->load($fh);  | 
| 
114
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         close $fh or croak "unable to load file '$file': $!";  | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
116
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
39
 | 
     return $self;  | 
| 
117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # set property only if its going to change the property value.  | 
| 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub changeProperty {  | 
| 
122
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
     my ($self, $key, $new, @defaults) = @_;  | 
| 
123
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _t_key $key;  | 
| 
124
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _t_value $new;  | 
| 
125
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $old=$self->getProperty($key, @defaults);  | 
| 
126
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
     if (!defined $old or $old ne $new) {  | 
| 
127
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	$self->setProperty($key, $new);  | 
| 
128
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	return 1;  | 
| 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
130
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return 0;  | 
| 
131
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub deleteProperty {  | 
| 
134
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
599
 | 
     my ($self, $key, $recurse) = @_;  | 
| 
135
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
     _t_key $key;  | 
| 
136
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
137
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
     if (exists $self->{properties}{$key}) {  | 
| 
138
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
       delete $self->{properties}{$key};  | 
| 
139
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
       delete $self->{property_line_numbers}{$key};  | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
142
 | 
1
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
3
 | 
     $self->{defaults}->deleteProperty($key, 1)  | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	if ($recurse and $self->{defaults});  | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
145
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	setProperty() - Set the value for a specific property  | 
| 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub setProperty {  | 
| 
148
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
  
1
  
 | 
8
 | 
     my ($self, $key, $value)=@_;  | 
| 
149
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1
 | 
     _t_key $key;  | 
| 
150
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
     _t_value $value;  | 
| 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
152
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
     defined(wantarray) and  | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	carp "warning: setProperty doesn't return the old value anymore";  | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
155
 | 
2
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
7
 | 
     $self->{property_line_numbers}{$key} ||= ++$self->{last_line_number};  | 
| 
156
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
     $self->{properties}{$key} = $value;  | 
| 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
158
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
159
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _properties {  | 
| 
160
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
5
 | 
     my $self=shift;  | 
| 
161
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
12
 | 
     if (defined ($self->{defaults})) {  | 
| 
162
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my %p=($self->{defaults}->_properties, %{$self->{properties}});  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
163
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	return %p;  | 
| 
164
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
165
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
     return %{ $self->{properties} }  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
61
 | 
    | 
| 
166
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
167
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #       properties() - return a flated hash with all the properties  | 
| 
169
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub properties {  | 
| 
170
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
2
 | 
     my $self = shift;  | 
| 
171
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
     my %p = $self->_properties;  | 
| 
172
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
     map { $_ => $p{$_} } $self->_sort_keys(keys %p);  | 
| 
 
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
    | 
| 
173
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
174
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
175
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	getProperties() - Return a hashref of all of the properties  | 
| 
178
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
3
 | 
 sub getProperties { return { shift->_properties }; }  | 
| 
179
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
180
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	getFormat() - Return the output format for the properties  | 
| 
182
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
 sub getFormat { shift->{format} }  | 
| 
183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
184
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	setFormat() - Set the output format for the properties  | 
| 
186
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub setFormat {  | 
| 
187
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
     my ($self, $format) = @_;  | 
| 
188
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     defined $format or $format='%s=%s';  | 
| 
189
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _t_format $format;  | 
| 
190
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->{format} = $format;  | 
| 
191
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	format() - Alias for get/setFormat();  | 
| 
194
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub format {  | 
| 
195
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
     my $self = shift;  | 
| 
196
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if (@_) {  | 
| 
197
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	return $self->setFormat(@_)  | 
| 
198
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
199
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->getFormat();  | 
| 
200
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
201
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
202
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
203
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #       setValidator(\&validator) - Set sub to be called to validate  | 
| 
204
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #                property/value pairs.  It is called  | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #                &validator($property, $value, $config) being $config  | 
| 
206
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #                the Config::Properties object.  $property and $key  | 
| 
207
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #                can be modified by the validator via $_[0] and $_[1]  | 
| 
208
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub setValidator {  | 
| 
209
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
  
0
  
 | 
43
 | 
     my ($self, $validator) = @_;  | 
| 
210
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     _t_validator $validator;  | 
| 
211
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
     $self->{validator} = $validator;  | 
| 
212
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
214
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #       getValidator() - Return the current validator sub  | 
| 
216
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
 sub getValidator { shift->{validator} }  | 
| 
217
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
218
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #       validator() - Alias for get/setValidator();  | 
| 
219
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub validator {  | 
| 
220
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
     my $self=shift;  | 
| 
221
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if (@_) {  | 
| 
222
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	return $self->setValidator(@_)  | 
| 
223
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
224
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $self->getValidator  | 
| 
225
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 }  | 
| 
226
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
227
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub setOrder {  | 
| 
228
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
0
  
 | 
3
 | 
     my ($self, $order) = @_;  | 
| 
229
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
     _t_order $order;  | 
| 
230
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
     $self->{order} = $order  | 
| 
231
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
233
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
 sub getOrder { shift->{order} }  | 
| 
234
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub order {  | 
| 
236
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
1588
 | 
     my $self = shift;  | 
| 
237
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     $self->setOrder(@_) if @_;  | 
| 
238
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
     $self->{order};  | 
| 
239
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
241
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	load() - Load the properties from a filehandle  | 
| 
242
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub load {  | 
| 
243
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
  
1
  
 | 
45
 | 
     my ($self, $file) = @_;  | 
| 
244
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
     _t_file $file;  | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # check whether it is a real file handle  | 
| 
247
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     my $fn = do {  | 
| 
248
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
         local $@;  | 
| 
249
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
         eval { fileno($file) }  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
    | 
| 
250
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     };  | 
| 
251
 | 
8
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
41
 | 
     if (defined $fn and $fn >0) {  | 
| 
252
 | 
8
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
88
 | 
         unless (grep /^(?:encoding|utf8)\b/, PerlIO::get_layers($file)) {  | 
| 
253
 | 
7
 | 
  
 50
  
 | 
 
 | 
  
6
  
 | 
 
 | 
190
 | 
             binmode $file, ":encoding($self->{encoding})"  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
    | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
    | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
    | 
| 
254
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 or croak "Unable to set file encoding layer: $!";  | 
| 
255
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
256
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
257
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
55889
 | 
     $self->{properties} = {};  | 
| 
258
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
     $self->{property_line_numbers} = {};  | 
| 
259
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
63
 | 
     my $ln = $file->input_line_number;  | 
| 
260
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
193
 | 
     $self->{last_line_number} = ($ln > 0 ? $ln : 0);  | 
| 
261
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
     $self->{buffer_in} = '';  | 
| 
262
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
     1 while $self->process_line($file);  | 
| 
263
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
     $self->{last_line_number};  | 
| 
264
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
265
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
266
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
267
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #        escape_key(string), escape_value(string), unescape(string) -  | 
| 
268
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #               subroutines to convert escaped characters to their  | 
| 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #               real counterparts back and forward.  | 
| 
270
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
271
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my %esc = ( "\n" => 'n',  | 
| 
272
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    "\r" => 'r',  | 
| 
273
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    "\t" => 't' );  | 
| 
274
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my %unesc = reverse %esc;  | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
276
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub escape_key {  | 
| 
277
 | 
21
 | 
 
 | 
 
 | 
  
21
  
 | 
  
0
  
 | 
57
 | 
     $_[0]=~s{([\t\n\r\\"' =:])}{  | 
| 
278
 | 
14
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
75
 | 
 	"\\".($esc{$1}||$1) }ge;  | 
| 
279
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
     $_[0]=~s{([^\x20-\x7e])}{sprintf "\\u%04x", ord $1}ge;  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
280
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
     $_[0]=~s/^ /\\ /;  | 
| 
281
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
41
 | 
     $_[0]=~s/^([#!])/\\$1/;  | 
| 
282
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35
 | 
     $_[0]=~s/(?
 | 
| 
283
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
284
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
285
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub escape_value {  | 
| 
286
 | 
21
 | 
 
 | 
 
 | 
  
21
  
 | 
  
0
  
 | 
54
 | 
     $_[0]=~s{([\t\n\r\\])}{  | 
| 
287
 | 
13
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
64
 | 
 	"\\".($esc{$1}||$1) }ge;  | 
| 
288
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
42
 | 
     $_[0]=~s{([^\x20-\x7e])}{sprintf "\\u%04x", ord $1}ge;  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
289
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
39
 | 
     $_[0]=~s/^ /\\ /;  | 
| 
290
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
291
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub unescape {  | 
| 
293
 | 
116
 | 
 
 | 
 
 | 
  
116
  
 | 
  
0
  
 | 
285
 | 
     $_[0]=~s/\\([tnr\\"' =:#!])|\\u([\da-fA-F]{4})/  | 
| 
294
 | 
155
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
678
 | 
 	defined $1 ? $unesc{$1}||$1 : chr hex $2 /ge;  | 
| 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
296
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
297
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub read_line {  | 
| 
298
 | 
124
 | 
 
 | 
 
 | 
  
124
  
 | 
  
0
  
 | 
110
 | 
     my ($self, $file) = @_;  | 
| 
299
 | 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
131
 | 
     my $bin = \$self->{buffer_in};  | 
| 
300
 | 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
107
 | 
     my $line_re = $self->{line_re};  | 
| 
301
 | 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
89
 | 
     while (1) {  | 
| 
302
 | 
132
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
973
 | 
         if ($$bin =~ s/$line_re//) {  | 
| 
303
 | 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
113
 | 
             $self->{last_line_number}++;  | 
| 
304
 | 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
334
 | 
             return $1;  | 
| 
305
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
306
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         else {  | 
| 
307
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
243
 | 
             my $bytes = read($file, $$bin, 8192, length $$bin);  | 
| 
308
 | 
13
 | 
  
 50
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
88
 | 
             last unless $bytes or (not defined $bytes and  | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
309
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                    ($! == Errno::EGAIN()       or  | 
| 
310
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                     $! == Errno::EWOULDBLOCK() or  | 
| 
311
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                     $! == Errno::EINTR()));  | 
| 
312
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
313
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
314
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
315
 | 
5
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
11
 | 
     if (length $$bin) {  | 
| 
316
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $self->{last_line_number}++;  | 
| 
317
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $line = $$bin;  | 
| 
318
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $$bin = '';  | 
| 
319
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         return $line  | 
| 
320
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
321
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
     undef;  | 
| 
322
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
323
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
324
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
325
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	process_line() - read and parse a line from the properties file.  | 
| 
326
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
327
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # this is to workaround a bug in perl 5.6.0 related to unicode  | 
| 
328
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my $bomre = eval(q< qr/^\\x{FEFF}/ >) || qr//;  | 
| 
329
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
330
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub process_line {  | 
| 
331
 | 
100
 | 
 
 | 
 
 | 
  
100
  
 | 
  
0
  
 | 
125
 | 
     my ($self, $file) = @_;  | 
| 
332
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
124
 | 
     my $line = $self->read_line($file);  | 
| 
333
 | 
100
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
184
 | 
     defined $line or return undef;  | 
| 
334
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
335
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # remove utf8 byte order mark  | 
| 
336
 | 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
90
 | 
     my $ln = $self->{last_line_number};  | 
| 
337
 | 
95
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
160
 | 
     $line =~ s/$bomre// if $ln < 2;  | 
| 
338
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
339
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # ignore comments  | 
| 
340
 | 
95
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
305
 | 
     $line =~ /^\s*(\#|\!|$)/ and return 1;  | 
| 
341
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
342
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # handle continuation lines  | 
| 
343
 | 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
49
 | 
     my @lines;  | 
| 
344
 | 
59
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
226
 | 
     while ($line =~ /(\\+)$/ and length($1) & 1) {  | 
| 
345
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
82
 | 
 	$line =~ s/\\$//;  | 
| 
346
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35
 | 
 	push @lines, $line;  | 
| 
347
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
41
 | 
 	$line = $self->read_line($file);  | 
| 
348
 | 
24
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
48
 | 
         $line = '' unless defined $line;  | 
| 
349
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
167
 | 
 	$line =~ s/^\s+//;  | 
| 
350
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
351
 | 
59
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
102
 | 
     $line = join('', @lines, $line) if @lines;  | 
| 
352
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
353
 | 
59
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
401
 | 
     my ($key, $value) = $line =~ /^  | 
| 
354
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				  \s*  | 
| 
355
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				  ((?:[^\s:=\\]|\\.)+)  | 
| 
356
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				  \s*  | 
| 
357
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				  [:=\s]  | 
| 
358
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				  \s*  | 
| 
359
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				  (.*)  | 
| 
360
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				  $  | 
| 
361
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				  /x  | 
| 
362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        or $self->fail("invalid property line '$line'");  | 
| 
363
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
364
 | 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
105
 | 
     unescape $key;  | 
| 
365
 | 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
83
 | 
     unescape $value;  | 
| 
366
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
367
 | 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
104
 | 
     $self->validate($key, $value);  | 
| 
368
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
369
 | 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
128
 | 
     $self->{property_line_numbers}{$key} = $ln;  | 
| 
370
 | 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
83
 | 
     $self->{properties}{$key} = $value;  | 
| 
371
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
372
 | 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
160
 | 
     return 1;  | 
| 
373
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
374
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
375
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub validate {  | 
| 
376
 | 
58
 | 
 
 | 
 
 | 
  
58
  
 | 
  
0
  
 | 
52
 | 
     my $self=shift;  | 
| 
377
 | 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
63
 | 
     my $validator = $self->{validator};  | 
| 
378
 | 
58
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
100
 | 
     if (defined $validator) {  | 
| 
379
 | 
11
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
9
 | 
 	&{$validator}(@_, $self) or $self->fail("invalid value '$_[1]' for '$_[0]'");  | 
| 
 
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
    | 
| 
380
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
381
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
382
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
383
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
384
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #       line_number() - number for the last line read from the configuration file  | 
| 
385
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
  
0
  
 | 
21
 | 
 sub line_number { shift->{last_line_number} }  | 
| 
386
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
387
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
388
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #       fail(error) - report errors in the configuration file while reading.  | 
| 
389
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub fail {  | 
| 
390
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
  
0
  
 | 
15
 | 
     my ($self, $error) = @_;  | 
| 
391
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
     die "$error at line ".$self->line_number()."\n";  | 
| 
392
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
393
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
394
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _sort_keys {  | 
| 
395
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
11
 | 
     my $self = shift;  | 
| 
396
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
     my $order = $self->{order};  | 
| 
397
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
16
 | 
     if ($order eq 'keep') {  | 
| 
398
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
         my $sk = $self->{property_line_numbers};  | 
| 
399
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
54
 | 
         no warnings 'uninitialized';  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
859
 | 
    | 
| 
400
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
         return sort { $sk->{$a} <=> $sk->{$b} } @_;  | 
| 
 
 | 
145
 | 
 
 | 
 
 | 
 
 | 
 
 | 
211
 | 
    | 
| 
401
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
402
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
3
 | 
     if ($order eq 'alpha') {  | 
| 
403
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
         return sort @_;  | 
| 
404
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
405
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return @_;  | 
| 
406
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
407
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
408
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	_save() - Utility function that performs the actual saving of  | 
| 
409
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #		the properties file to a filehandle.  | 
| 
410
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _save {  | 
| 
411
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
5
 | 
     my ($self, $file) = @_;  | 
| 
412
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     _t_file $file;  | 
| 
413
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
414
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
     my $wrap;  | 
| 
415
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     if ($self->{wrap}) {  | 
| 
416
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
         eval {  | 
| 
417
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
43
 | 
             no warnings;  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6999
 | 
    | 
| 
418
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2194
 | 
             require Text::Wrap;  | 
| 
419
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3706
 | 
             $wrap=($Text::Wrap::VERSION >= 2001.0929);  | 
| 
420
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         };  | 
| 
421
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
44
 | 
         unless ($wrap) {  | 
| 
422
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             carp "Text::Wrap module is to old, version 2001.0929 or newer required: long lines will not be wrapped"  | 
| 
423
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
424
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
425
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
426
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     local($Text::Wrap::separator)=" \\\n"       if $wrap;  | 
| 
427
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     local($Text::Wrap::unexpand)=undef          if $wrap;  | 
| 
428
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
6
 | 
     local($Text::Wrap::huge)='overflow'         if $wrap;  | 
| 
429
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     local($Text::Wrap::break)=qr/(?
 | 
| 
430
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
431
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
     foreach ($self->_sort_keys(keys %{$self->{properties}})) {  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
    | 
| 
432
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34585
 | 
 	my $key=$_;  | 
| 
433
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
93
 | 
 	my $value=$self->{properties}{$key};  | 
| 
434
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
 	escape_key $key;  | 
| 
435
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
 	escape_value $value;  | 
| 
436
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
437
 | 
21
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
34
 | 
 	if ($wrap) {  | 
| 
438
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
113
 | 
 	    $file->print( Text::Wrap::wrap( "",  | 
| 
439
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					    "    ",  | 
| 
440
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					    sprintf( $self->{'format'},  | 
| 
441
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 						     $key, $value ) ),  | 
| 
442
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			  "\n" );  | 
| 
443
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
444
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	else {  | 
| 
445
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	    $file->print(sprintf( $self->{'format'}, $key, $value ), "\n")  | 
| 
446
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
447
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
448
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
449
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
450
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
451
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	save() - Save the properties to a filehandle with the given header.  | 
| 
452
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub save {  | 
| 
453
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
  
1
  
 | 
375
 | 
     my ($self, $file, $header) = @_;  | 
| 
454
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     _t_file($file);  | 
| 
455
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
456
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     if (defined $header) {  | 
| 
457
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
 	$header=~s/\n/# \n/sg;  | 
| 
458
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
 	print $file "# $header\n#\n";  | 
| 
459
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
460
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
203
 | 
     print $file '# ' . localtime() . "\n\n";  | 
| 
461
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
     $self->_save( $file );  | 
| 
462
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
463
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
464
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub saveToString {  | 
| 
465
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
     my $self = shift;  | 
| 
466
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $str = '';  | 
| 
467
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     open my $fh, '>', \$str  | 
| 
468
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	or die "unable to open string ref as file";  | 
| 
469
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->save($fh, @_);  | 
| 
470
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     close $fh  | 
| 
471
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	or die "unable to write to in memory file";  | 
| 
472
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return $str;  | 
| 
473
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
474
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
475
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _split_to_tree {  | 
| 
476
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
     my ($self, $tree, $re, $start) = @_;  | 
| 
477
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if (defined $self->{defaults}) {  | 
| 
478
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	$self->{defaults}->_split_to_tree($tree, $re, $start);  | 
| 
479
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
480
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     for my $key (keys %{$self->{properties}}) {  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
481
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $ekey = $key;  | 
| 
482
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
483
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         if (defined $start) {  | 
| 
484
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $ekey =~ s/$start// or next;  | 
| 
485
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
486
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
487
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my @parts = split $re, $ekey;  | 
| 
488
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	@parts = '' unless @parts;  | 
| 
489
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my $t = $tree;  | 
| 
490
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	while (@parts) {  | 
| 
491
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	    my $part = shift @parts;  | 
| 
492
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	    my $old = $t->{$part};  | 
| 
493
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
494
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	    if (@parts) {  | 
| 
495
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		if (defined $old) {  | 
| 
496
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		    if (ref $old) {  | 
| 
497
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$t = $old;  | 
| 
498
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		    }  | 
| 
499
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		    else {  | 
| 
500
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$t = $t->{$part} = { '' => $old };  | 
| 
501
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		    }  | 
| 
502
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
503
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		else {  | 
| 
504
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		    $t = $t->{$part} = {};  | 
| 
505
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
506
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
507
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    else {  | 
| 
508
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		my $value = $self->{properties}{$key};  | 
| 
509
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		if (ref $old) {  | 
| 
510
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		    $old->{''} = $value;  | 
| 
511
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
512
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		else {  | 
| 
513
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		    $t->{$part} = $value;  | 
| 
514
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
515
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
516
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
517
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
518
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
519
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
520
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub splitToTree {  | 
| 
521
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
     my ($self, $re, $start) = @_;  | 
| 
522
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $re = qr/\./ unless defined $re;  | 
| 
523
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $re = qr/$re/ unless ref $re;  | 
| 
524
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if (defined $start) {  | 
| 
525
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $start = quotemeta $start;  | 
| 
526
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $start = qr/^$start$re/  | 
| 
527
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
528
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $tree = {};  | 
| 
529
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->_split_to_tree($tree, $re, $start);  | 
| 
530
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $tree;  | 
| 
531
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
532
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
533
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _unsplit_from_tree {  | 
| 
534
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
     my ($self, $method, $tree, $sep, @start) = @_;  | 
| 
535
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $sep = '.' unless defined $sep;  | 
| 
536
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $ref = ref $tree;  | 
| 
537
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if ($ref eq 'HASH') {  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
538
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         for my $key (keys %$tree) {  | 
| 
539
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $self->_unsplit_from_tree($method, $tree->{$key}, $sep,  | 
| 
540
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                @start, ($key ne '' ? $key : ()))  | 
| 
541
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
542
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
543
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif ($ref eq 'ARRAY') {  | 
| 
544
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         for my $key (0..$#$tree) {  | 
| 
545
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $self->_unsplit_from_tree($method, $tree->[$key], $sep, @start, $key)  | 
| 
546
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
547
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
548
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif ($ref) {  | 
| 
549
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         croak "unexpected object '$ref' found inside tree"  | 
| 
550
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
551
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
552
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $self->$method(join($sep, @start), $tree)  | 
| 
553
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
554
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
555
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
556
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
 sub setFromTree { shift->_unsplit_from_tree(setProperty => @_) }  | 
| 
557
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
 sub changeFromTree { shift->_unsplit_from_tree(changeProperty => @_) }  | 
| 
558
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
559
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	store() - Synonym for save()  | 
| 
560
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 *store = \&save;  | 
| 
561
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
562
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	getProperty() - Return the value of a property key. Returns the default  | 
| 
563
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #		for that key (if there is one) if no value exists for that key.  | 
| 
564
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub getProperty {  | 
| 
565
 | 
67
 | 
 
 | 
 
 | 
  
67
  
 | 
  
1
  
 | 
11479
 | 
     my $self = shift;  | 
| 
566
 | 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
69
 | 
     my $key = shift;  | 
| 
567
 | 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
95
 | 
     _t_key $key;  | 
| 
568
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
569
 | 
67
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
134
 | 
     if (exists $self->{properties}{$key}) {  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
570
 | 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
211
 | 
 	return $self->{properties}{$key}  | 
| 
571
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
572
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif (defined $self->{defaults}) {  | 
| 
573
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	return $self->{defaults}->getProperty($key, @_);  | 
| 
574
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
575
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     for (@_) {  | 
| 
576
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	return $_ if defined $_  | 
| 
577
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
578
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     undef  | 
| 
579
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 }  | 
| 
580
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
581
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub requireProperty {  | 
| 
582
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
     my $this = shift;  | 
| 
583
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $prop = $this->getProperty(@_);  | 
| 
584
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     defined $prop  | 
| 
585
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	or die "required property '$_[0]' not found on configuration file\n";  | 
| 
586
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return $prop;  | 
| 
587
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
588
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
589
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _property_line_number {  | 
| 
590
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
     my ($self, $key)=@_;  | 
| 
591
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->{property_line_numbers}{$key}  | 
| 
592
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
593
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
594
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
595
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	propertyName() - Returns an array of the keys of the Properties  | 
| 
596
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub propertyNames {  | 
| 
597
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
  
1
  
 | 
18
 | 
     my $self = shift;  | 
| 
598
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     my %p = $self->_properties;  | 
| 
599
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     $self->_sort_keys(keys %p);  | 
| 
600
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
601
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
602
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
603
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  | 
| 
604
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __END__  |