| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Config::Simple; | 
| 2 |  |  |  |  |  |  |  | 
| 3 |  |  |  |  |  |  | # $Id: Simple.pm,v 3.55 2005/02/10 18:57:16 sherzodr Exp $ | 
| 4 |  |  |  |  |  |  |  | 
| 5 | 9 |  |  | 9 |  | 61353 | use strict; | 
|  | 9 |  |  |  |  | 18 |  | 
|  | 9 |  |  |  |  | 377 |  | 
| 6 |  |  |  |  |  |  | # uncomment the following line while debugging. Otherwise, | 
| 7 |  |  |  |  |  |  | # it's too slow for production environment | 
| 8 |  |  |  |  |  |  | #use diagnostics; | 
| 9 | 9 |  |  | 9 |  | 52 | use Carp; | 
|  | 9 |  |  |  |  | 15 |  | 
|  | 9 |  |  |  |  | 683 |  | 
| 10 | 9 |  |  | 9 |  | 49 | use Fcntl qw(:DEFAULT :flock); | 
|  | 9 |  |  |  |  | 21 |  | 
|  | 9 |  |  |  |  | 5420 |  | 
| 11 | 9 |  |  | 9 |  | 10161 | use Text::ParseWords 'parse_line'; | 
|  | 9 |  |  |  |  | 14797 |  | 
|  | 9 |  |  |  |  | 597 |  | 
| 12 | 9 |  |  | 9 |  | 59 | use vars qw($VERSION $DEFAULTNS $LC $USEQQ $errstr); | 
|  | 9 |  |  |  |  | 18 |  | 
|  | 9 |  |  |  |  | 826 |  | 
| 13 | 9 |  |  | 9 |  | 9332 | use AutoLoader 'AUTOLOAD'; | 
|  | 9 |  |  |  |  | 18167 |  | 
|  | 9 |  |  |  |  | 61 |  | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  |  | 
| 16 |  |  |  |  |  |  | $VERSION   = '4.58'; | 
| 17 |  |  |  |  |  |  | $DEFAULTNS = 'default'; | 
| 18 |  |  |  |  |  |  |  | 
| 19 |  |  |  |  |  |  | sub import { | 
| 20 | 4 |  |  | 4 |  | 544 | my $class = shift; | 
| 21 | 4 |  |  |  |  | 2498 | for ( @_ ) { | 
| 22 | 3 | 50 |  |  |  | 23 | if ( $_ eq '-lc'      ) { $LC = 1;    next; } | 
|  | 0 |  |  |  |  | 0 |  | 
|  | 0 |  |  |  |  | 0 |  | 
| 23 | 3 | 50 |  |  |  | 16 | if ( $_ eq '-strict'  ) { $USEQQ = 1; next; } | 
|  | 3 |  |  |  |  | 7 |  | 
|  | 3 |  |  |  |  | 2362 |  | 
| 24 |  |  |  |  |  |  | } | 
| 25 |  |  |  |  |  |  | } | 
| 26 |  |  |  |  |  |  |  | 
| 27 |  |  |  |  |  |  |  | 
| 28 |  |  |  |  |  |  |  | 
| 29 |  |  |  |  |  |  | # delimiter used by Text::ParseWords::parse_line() | 
| 30 | 165 |  |  | 165 | 0 | 555 | sub READ_DELIM () { return '\s*,\s*' } | 
| 31 |  |  |  |  |  |  | # delimiter used by as_string() | 
| 32 | 69 |  |  | 69 | 0 | 125 | sub WRITE_DELIM() { return ', '      } | 
| 33 |  |  |  |  |  |  | sub DEBUG      () { 0 } | 
| 34 |  |  |  |  |  |  |  | 
| 35 |  |  |  |  |  |  |  | 
| 36 |  |  |  |  |  |  | sub new { | 
| 37 | 12 |  |  | 12 | 1 | 2488 | my $class = shift; | 
| 38 | 12 |  | 33 |  |  | 108 | $class = ref($class) || $class; | 
| 39 |  |  |  |  |  |  |  | 
| 40 | 12 |  |  |  |  | 139 | my $self = { | 
| 41 |  |  |  |  |  |  | _FILE_HANDLE    => undef,   # holds a reference to an opened cfg file | 
| 42 |  |  |  |  |  |  | _FILE_NAME      => undef,   # holds the name of the read configuration file | 
| 43 |  |  |  |  |  |  | _STACK          => [],      # currently not implemented | 
| 44 |  |  |  |  |  |  | _DATA           => {},      # actual key/value pairs are stored in _DATA | 
| 45 |  |  |  |  |  |  | _SYNTAX         => undef,   # holds the syntax of the read cfg file | 
| 46 |  |  |  |  |  |  | _SUB_SYNTAX     => undef,   # holds the sub-syntax (like for simplified ini) | 
| 47 |  |  |  |  |  |  | _ARGS           => {},      # holds all key/values passed to new() | 
| 48 |  |  |  |  |  |  | _OO_INTERFACE   => 1,       # currently not implemented | 
| 49 |  |  |  |  |  |  | _IS_MODIFIED    => 0,       # to prevent writing file back if they were not modified | 
| 50 |  |  |  |  |  |  | }; | 
| 51 | 12 |  |  |  |  | 43 | bless ($self, $class); | 
| 52 | 12 | 100 |  |  |  | 104 | $self->_init(@_) or return; | 
| 53 | 11 |  |  |  |  | 99 | return $self; | 
| 54 |  |  |  |  |  |  | } | 
| 55 |  |  |  |  |  |  |  | 
| 56 |  |  |  |  |  |  |  | 
| 57 |  |  |  |  |  |  |  | 
| 58 |  |  |  |  |  |  |  | 
| 59 |  |  |  |  |  |  | sub DESTROY { | 
| 60 | 12 |  |  | 12 |  | 1249 | my $self = shift; | 
| 61 |  |  |  |  |  |  |  | 
| 62 |  |  |  |  |  |  | # if it was an auto save mode, write the changes | 
| 63 |  |  |  |  |  |  | # back only if the values have been modified. | 
| 64 | 12 | 100 | 66 |  |  | 52 | if ( $self->autosave() && $self->_is_modified() ) { | 
| 65 | 1 |  |  |  |  | 5 | $self->write(); | 
| 66 |  |  |  |  |  |  | } | 
| 67 |  |  |  |  |  |  | } | 
| 68 |  |  |  |  |  |  |  | 
| 69 |  |  |  |  |  |  |  | 
| 70 |  |  |  |  |  |  |  | 
| 71 |  |  |  |  |  |  |  | 
| 72 |  |  |  |  |  |  | # initialize the object | 
| 73 |  |  |  |  |  |  | sub _init { | 
| 74 | 12 |  |  | 12 |  | 74 | my $self = shift; | 
| 75 |  |  |  |  |  |  |  | 
| 76 | 12 | 100 |  |  |  | 133 | if ( @_ == 1 ) { | 
|  |  | 50 |  |  |  |  |  | 
| 77 | 5 |  |  |  |  | 27 | return $self->read($_[0]); | 
| 78 |  |  |  |  |  |  | } elsif ( @_ % 2 ) { | 
| 79 | 0 |  |  |  |  | 0 | croak "new(): Illegal arguments detected"; | 
| 80 |  |  |  |  |  |  | } else { | 
| 81 | 7 |  |  |  |  | 65 | $self->{_ARGS} = { @_ }; | 
| 82 |  |  |  |  |  |  | } | 
| 83 |  |  |  |  |  |  | # if syntax was given, call syntax() | 
| 84 | 7 | 100 |  |  |  | 41 | if ( exists $self->{_ARGS}->{syntax} ) { | 
| 85 | 1 |  |  |  |  | 6 | $self->syntax($self->{_ARGS}->{syntax}); | 
| 86 |  |  |  |  |  |  | } | 
| 87 |  |  |  |  |  |  | # if autosave was set, call autosave | 
| 88 | 7 | 50 |  |  |  | 52 | if ( exists $self->{_ARGS}->{autosave} ) { | 
| 89 | 0 |  |  |  |  | 0 | $self->autosave($self->{_ARGS}->{autosave}); | 
| 90 |  |  |  |  |  |  | } | 
| 91 |  |  |  |  |  |  | # If filename was passed, call read() | 
| 92 | 7 | 100 |  |  |  | 38 | if ( exists ($self->{_ARGS}->{filename}) ) { | 
| 93 | 1 |  |  |  |  | 6 | return $self->read( $self->{_ARGS}->{filename} ); | 
| 94 |  |  |  |  |  |  | } | 
| 95 | 6 |  |  |  |  | 25 | return 1; | 
| 96 |  |  |  |  |  |  | } | 
| 97 |  |  |  |  |  |  |  | 
| 98 |  |  |  |  |  |  |  | 
| 99 |  |  |  |  |  |  |  | 
| 100 |  |  |  |  |  |  | sub _is_modified { | 
| 101 | 21 |  |  | 21 |  | 36 | my ($self, $bool) = @_; | 
| 102 |  |  |  |  |  |  |  | 
| 103 | 21 | 100 |  |  |  | 61 | if ( defined $bool ) { | 
| 104 | 20 |  |  |  |  | 856 | $self->{_IS_MODIFIED} = $bool; | 
| 105 |  |  |  |  |  |  | } | 
| 106 | 21 |  |  |  |  | 66 | return $self->{_IS_MODIFIED}; | 
| 107 |  |  |  |  |  |  | } | 
| 108 |  |  |  |  |  |  |  | 
| 109 |  |  |  |  |  |  |  | 
| 110 |  |  |  |  |  |  |  | 
| 111 |  |  |  |  |  |  | sub autosave { | 
| 112 | 13 |  |  | 13 | 1 | 4557 | my ($self, $bool) = @_; | 
| 113 |  |  |  |  |  |  |  | 
| 114 | 13 | 100 |  |  |  | 56 | if ( defined $bool ) { | 
| 115 | 1 |  |  |  |  | 9 | $self->{_ARGS}->{autosave} = $bool; | 
| 116 |  |  |  |  |  |  | } | 
| 117 | 13 |  |  |  |  | 920 | return $self->{_ARGS}->{autosave}; | 
| 118 |  |  |  |  |  |  | } | 
| 119 |  |  |  |  |  |  |  | 
| 120 |  |  |  |  |  |  |  | 
| 121 |  |  |  |  |  |  | sub syntax { | 
| 122 | 6 |  |  | 6 | 0 | 15 | my ($self, $syntax) = @_; | 
| 123 |  |  |  |  |  |  |  | 
| 124 | 6 | 100 |  |  |  | 21 | if ( defined $syntax ) { | 
| 125 | 1 |  |  |  |  | 2 | $self->{_SYNTAX} = $syntax; | 
| 126 |  |  |  |  |  |  | } | 
| 127 | 6 |  |  |  |  | 28 | return $self->{_SYNTAX}; | 
| 128 |  |  |  |  |  |  | } | 
| 129 |  |  |  |  |  |  |  | 
| 130 |  |  |  |  |  |  |  | 
| 131 |  |  |  |  |  |  | # takes a filename or a file handle and returns a filehandle | 
| 132 |  |  |  |  |  |  | sub _get_fh { | 
| 133 | 21 |  |  | 21 |  | 48 | my ($self, $arg, $mode) = @_; | 
| 134 |  |  |  |  |  |  |  | 
| 135 | 21 | 50 |  |  |  | 62 | unless ( defined $arg ) { | 
| 136 | 0 |  |  |  |  | 0 | croak "_get_fh(): filename is missing"; | 
| 137 |  |  |  |  |  |  | } | 
| 138 | 21 | 100 | 66 |  |  | 535 | if ( ref($arg) && (ref($arg) eq 'GLOB') ) { | 
| 139 | 2 |  |  |  |  | 10 | return ($arg, 0); | 
| 140 |  |  |  |  |  |  | } | 
| 141 | 19 | 50 |  |  |  | 56 | unless ( defined $mode ) { | 
| 142 | 0 |  |  |  |  | 0 | $mode = O_RDONLY; | 
| 143 |  |  |  |  |  |  | } | 
| 144 | 19 | 100 |  |  |  | 999 | unless ( sysopen(FH, $arg, $mode) ) { | 
| 145 | 2 |  |  |  |  | 77 | $self->error("couldn't open $arg: $!"); | 
| 146 | 2 |  |  |  |  | 20 | return undef; | 
| 147 |  |  |  |  |  |  | } | 
| 148 | 17 |  |  |  |  | 106 | return (\*FH, 1); | 
| 149 |  |  |  |  |  |  | } | 
| 150 |  |  |  |  |  |  |  | 
| 151 |  |  |  |  |  |  |  | 
| 152 |  |  |  |  |  |  |  | 
| 153 |  |  |  |  |  |  | sub read { | 
| 154 | 11 |  |  | 11 | 1 | 330 | my ($self, $file) = @_; | 
| 155 |  |  |  |  |  |  |  | 
| 156 |  |  |  |  |  |  | # making sure one object doesn't work on more than one | 
| 157 |  |  |  |  |  |  | # file at a time | 
| 158 | 11 | 50 |  |  |  | 78 | if ( defined $self->{_FILE_HANDLE} ) { | 
| 159 | 0 |  |  |  |  | 0 | croak "Open file handle detected. If you're trying to parse another file, close() it first."; | 
| 160 |  |  |  |  |  |  | } | 
| 161 | 11 | 50 |  |  |  | 45 | unless ( defined $file ) { | 
| 162 | 0 |  |  |  |  | 0 | croak "Usage: OBJ->read(\$file_name)"; | 
| 163 |  |  |  |  |  |  | } | 
| 164 |  |  |  |  |  |  |  | 
| 165 | 11 |  |  |  |  | 36 | $self->{_FILE_NAME}   = $file; | 
| 166 | 11 | 100 |  |  |  | 49 | $self->{_FILE_HANDLE} = $self->_get_fh($file, O_RDONLY) or return undef; | 
| 167 |  |  |  |  |  |  |  | 
| 168 | 9 | 50 |  |  |  | 46 | $self->{_SYNTAX} = $self->guess_syntax(\*FH) or return undef; | 
| 169 |  |  |  |  |  |  |  | 
| 170 |  |  |  |  |  |  | # call respective parsers | 
| 171 |  |  |  |  |  |  |  | 
| 172 | 9 | 100 |  |  |  | 46 | if ( $self->{_SYNTAX} eq 'ini' ) { | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 173 | 7 |  |  |  |  | 33 | $self->{_DATA} = $self->parse_ini_file($file); | 
| 174 |  |  |  |  |  |  | } elsif ( $self->{_SYNTAX} eq 'simple' ) { | 
| 175 | 2 |  |  |  |  | 10 | $self->{_DATA} = $self->parse_cfg_file(\*FH); | 
| 176 |  |  |  |  |  |  | } elsif ( $self->{_SYNTAX} eq 'http' ) { | 
| 177 | 0 |  |  |  |  | 0 | $self->{_DATA} = $self->parse_http_file(\*FH); | 
| 178 |  |  |  |  |  |  | } | 
| 179 |  |  |  |  |  |  |  | 
| 180 | 9 | 50 |  |  |  | 39 | if ( $self->{_DATA} ) { | 
| 181 | 9 |  |  |  |  | 51 | return $self->{_DATA}; | 
| 182 |  |  |  |  |  |  | } | 
| 183 |  |  |  |  |  |  |  | 
| 184 | 0 |  |  |  |  | 0 | die "Something went wrong. No supported configuration file syntax found"; | 
| 185 |  |  |  |  |  |  | } | 
| 186 |  |  |  |  |  |  |  | 
| 187 |  |  |  |  |  |  |  | 
| 188 |  |  |  |  |  |  | sub close { | 
| 189 | 0 |  |  | 0 | 0 | 0 | my $self = shift; | 
| 190 |  |  |  |  |  |  |  | 
| 191 | 0 | 0 |  |  |  | 0 | my $fh = $self->{_FILE_HANDLE} or return; | 
| 192 | 0 | 0 |  |  |  | 0 | unless ( close($fh) ) { | 
| 193 | 0 |  |  |  |  | 0 | $self->error("couldn't close the file: $!"); | 
| 194 | 0 |  |  |  |  | 0 | return undef; | 
| 195 |  |  |  |  |  |  | } | 
| 196 | 0 |  |  |  |  | 0 | return 1; | 
| 197 |  |  |  |  |  |  | } | 
| 198 |  |  |  |  |  |  |  | 
| 199 |  |  |  |  |  |  |  | 
| 200 |  |  |  |  |  |  |  | 
| 201 |  |  |  |  |  |  |  | 
| 202 |  |  |  |  |  |  |  | 
| 203 |  |  |  |  |  |  | # tries to guess the syntax of the configuration file. | 
| 204 |  |  |  |  |  |  | # returns 'ini', 'simple' or 'http'. | 
| 205 |  |  |  |  |  |  | sub guess_syntax { | 
| 206 | 9 |  |  | 9 | 0 | 24 | my ($self, $fh) = @_; | 
| 207 |  |  |  |  |  |  |  | 
| 208 | 9 | 50 |  |  |  | 34 | unless ( defined $fh ) { | 
| 209 | 0 | 0 |  |  |  | 0 | $fh = $self->{_FILE_HANDLE} or die "'_FILE_HANDLE' is not defined"; | 
| 210 |  |  |  |  |  |  | } | 
| 211 | 9 | 50 |  |  |  | 78 | unless ( seek($fh, 0, 0) ) { | 
| 212 | 0 |  |  |  |  | 0 | $self->error("Couldn't seek($fh, 0, 0): $!"); | 
| 213 | 0 |  |  |  |  | 0 | return undef; | 
| 214 |  |  |  |  |  |  | } | 
| 215 |  |  |  |  |  |  |  | 
| 216 |  |  |  |  |  |  | # now we keep reading the file line by line untill we can identify the | 
| 217 |  |  |  |  |  |  | # syntax | 
| 218 | 9 |  |  |  |  | 116 | verbose("Trying to guess the file syntax..."); | 
| 219 | 9 |  |  |  |  | 37 | my ($syntax, $sub_syntax); | 
| 220 | 9 |  |  |  |  | 150 | while ( <$fh> ) { | 
| 221 |  |  |  |  |  |  | # skipping empty lines and comments. They don't tell much anyway | 
| 222 | 36 | 100 |  |  |  | 191 | /^(\n|\#|;)/ and next; | 
| 223 |  |  |  |  |  |  |  | 
| 224 |  |  |  |  |  |  | # If there's no alpha-numeric value in this line, ignore it | 
| 225 | 9 | 50 |  |  |  | 71 | /\w/ or next; | 
| 226 |  |  |  |  |  |  |  | 
| 227 |  |  |  |  |  |  | # trim $/ | 
| 228 | 9 |  |  |  |  | 47 | chomp(); | 
| 229 |  |  |  |  |  |  |  | 
| 230 |  |  |  |  |  |  | # If there's a block, it is an ini syntax | 
| 231 | 9 | 100 |  |  |  | 104 | /^\s*\[\s*[^\]]+\s*\]\s*$/  and $syntax = 'ini', last; | 
| 232 |  |  |  |  |  |  |  | 
| 233 |  |  |  |  |  |  | # If we can read key/value pairs separated by '=', it still | 
| 234 |  |  |  |  |  |  | # is an ini syntax with a default block assumed | 
| 235 | 3 | 100 |  |  |  | 38 | /^\s*[^=]+\s*=\s*.*\s*$/    and $syntax = 'ini', $self->{_SUB_SYNTAX} = 'simple-ini', last; | 
| 236 |  |  |  |  |  |  |  | 
| 237 |  |  |  |  |  |  | # If we can read key/value pairs separated by ':', it is an | 
| 238 |  |  |  |  |  |  | # http syntax | 
| 239 | 2 | 50 |  |  |  | 9 | /^\s*[\w-]+\s*:\s*.*\s*$/   and $syntax = 'http', last; | 
| 240 |  |  |  |  |  |  |  | 
| 241 |  |  |  |  |  |  | # If we can read key/value pairs separated by just whites, | 
| 242 |  |  |  |  |  |  | # it is a simple syntax. | 
| 243 | 2 | 50 |  |  |  | 16 | /^\s*[\w-]+\s+.*$/          and $syntax = 'simple', last; | 
| 244 |  |  |  |  |  |  | } | 
| 245 |  |  |  |  |  |  |  | 
| 246 | 9 | 50 |  |  |  | 37 | if ( $syntax ) { | 
| 247 | 9 |  |  |  |  | 49 | return $syntax; | 
| 248 |  |  |  |  |  |  | } | 
| 249 |  |  |  |  |  |  |  | 
| 250 | 0 |  |  |  |  | 0 | $self->error("Couldn't identify the syntax used"); | 
| 251 | 0 |  |  |  |  | 0 | return undef; | 
| 252 |  |  |  |  |  |  |  | 
| 253 |  |  |  |  |  |  | } | 
| 254 |  |  |  |  |  |  |  | 
| 255 |  |  |  |  |  |  |  | 
| 256 |  |  |  |  |  |  |  | 
| 257 |  |  |  |  |  |  |  | 
| 258 |  |  |  |  |  |  |  | 
| 259 |  |  |  |  |  |  | sub parse_ini_file { | 
| 260 | 8 |  |  | 8 | 0 | 18 | my ($class, $file) = @_; | 
| 261 |  |  |  |  |  |  |  | 
| 262 | 8 | 50 |  |  |  | 42 | my ($fh, $close_fh) = $class->_get_fh($file, O_RDONLY) or return; | 
| 263 | 8 | 50 |  |  |  | 81 | unless(flock($fh, LOCK_SH) ) { | 
| 264 | 0 |  |  |  |  | 0 | $errstr = "couldn't acquire shared lock on $fh: $!"; | 
| 265 | 0 |  |  |  |  | 0 | return undef; | 
| 266 |  |  |  |  |  |  | } | 
| 267 |  |  |  |  |  |  |  | 
| 268 | 8 | 50 |  |  |  | 59 | unless ( seek($fh, 0, 0) ) { | 
| 269 | 0 |  |  |  |  | 0 | $errstr = "couldn't seek to the beginning of the file: $!"; | 
| 270 | 0 |  |  |  |  | 0 | return undef; | 
| 271 |  |  |  |  |  |  | } | 
| 272 |  |  |  |  |  |  |  | 
| 273 | 8 |  |  |  |  | 15 | my $bn = $DEFAULTNS; | 
| 274 | 8 |  |  |  |  | 520 | my %data = (); | 
| 275 | 8 |  |  |  |  | 13 | my $line; | 
| 276 | 8 |  |  |  |  | 94 | while ( defined($line=<$fh>) ) { | 
| 277 |  |  |  |  |  |  | # skipping comments and empty lines: | 
| 278 |  |  |  |  |  |  |  | 
| 279 | 235 | 100 |  |  |  | 906 | $line =~ /^\s*(\n|\#|;)/  and next; | 
| 280 | 172 | 50 |  |  |  | 518 | $line =~ /\S/          or  next; | 
| 281 |  |  |  |  |  |  |  | 
| 282 | 172 |  |  |  |  | 257 | chomp $line; | 
| 283 |  |  |  |  |  |  |  | 
| 284 | 172 |  |  |  |  | 262 | $line =~ s/^\s+//g; | 
| 285 | 172 |  |  |  |  | 280 | $line =~ s/\s+$//g; | 
| 286 |  |  |  |  |  |  |  | 
| 287 |  |  |  |  |  |  | # parsing the block name: | 
| 288 | 172 | 100 |  |  |  | 442 | $line =~ /^\s*\[\s*([^\]]+)\s*\]$/       and $bn = lcase($1), next; | 
| 289 |  |  |  |  |  |  | # parsing key/value pairs | 
| 290 | 142 | 50 |  |  |  | 683 | $line =~ /^\s*([^=]*\w)\s*=\s*(.*)\s*$/  and $data{$bn}->{lcase($1)}=[parse_line(READ_DELIM, 0, $2)], next; | 
| 291 |  |  |  |  |  |  | # if we came this far, the syntax couldn't be validated: | 
| 292 | 0 |  |  |  |  | 0 | $errstr = "syntax error on line $. '$line'"; | 
| 293 | 0 |  |  |  |  | 0 | return undef; | 
| 294 |  |  |  |  |  |  | } | 
| 295 | 8 | 50 |  |  |  | 74 | unless(flock($fh, LOCK_UN) ) { | 
| 296 | 0 |  |  |  |  | 0 | $errstr = "couldn't unlock file: $!"; | 
| 297 | 0 |  |  |  |  | 0 | return undef; | 
| 298 |  |  |  |  |  |  | } | 
| 299 | 8 | 50 |  |  |  | 27 | if ( $close_fh ) { | 
| 300 | 8 |  |  |  |  | 87 | CORE::close($fh); | 
| 301 |  |  |  |  |  |  | } | 
| 302 | 8 |  |  |  |  | 33 | return \%data; | 
| 303 |  |  |  |  |  |  | } | 
| 304 |  |  |  |  |  |  |  | 
| 305 |  |  |  |  |  |  |  | 
| 306 |  |  |  |  |  |  | sub lcase { | 
| 307 | 249 |  |  | 249 | 0 | 8508 | my $str = shift; | 
| 308 | 249 | 50 |  |  |  | 1749 | $LC or return $str; | 
| 309 | 0 |  |  |  |  | 0 | return lc($str); | 
| 310 |  |  |  |  |  |  | } | 
| 311 |  |  |  |  |  |  |  | 
| 312 |  |  |  |  |  |  |  | 
| 313 |  |  |  |  |  |  |  | 
| 314 |  |  |  |  |  |  |  | 
| 315 |  |  |  |  |  |  | sub parse_cfg_file { | 
| 316 | 2 |  |  | 2 | 0 | 4 | my ($class, $file) = @_; | 
| 317 |  |  |  |  |  |  |  | 
| 318 | 2 | 50 |  |  |  | 7 | my ($fh, $close_fh) = $class->_get_fh($file, O_RDONLY) or return; | 
| 319 |  |  |  |  |  |  |  | 
| 320 | 2 | 50 |  |  |  | 32 | unless ( flock($fh, LOCK_SH) ) { | 
| 321 | 0 |  |  |  |  | 0 | $errstr = "couldn't get shared lock on $fh: $!"; | 
| 322 | 0 |  |  |  |  | 0 | return undef; | 
| 323 |  |  |  |  |  |  | } | 
| 324 |  |  |  |  |  |  |  | 
| 325 | 2 | 50 |  |  |  | 14 | unless ( seek($fh, 0, 0) ) { | 
| 326 | 0 |  |  |  |  | 0 | $errstr = "couldn't seek to the start of the file: :$!"; | 
| 327 |  |  |  |  |  |  | } | 
| 328 |  |  |  |  |  |  |  | 
| 329 | 2 |  |  |  |  | 3 | my %data = (); | 
| 330 | 2 |  |  |  |  | 4 | my $line; | 
| 331 | 2 |  |  |  |  | 18 | while ( defined($line=<$fh>) ) { | 
| 332 |  |  |  |  |  |  | # skipping comments and empty lines: | 
| 333 | 31 | 100 |  |  |  | 111 | $line =~ /^(\n|\#)/  and next; | 
| 334 | 23 | 50 |  |  |  | 73 | $line =~ /\S/        or  next; | 
| 335 | 23 |  |  |  |  | 37 | chomp $line; | 
| 336 | 23 |  |  |  |  | 40 | $line =~ s/^\s+//g; | 
| 337 | 23 |  |  |  |  | 53 | $line =~ s/\s+$//g; | 
| 338 |  |  |  |  |  |  | # parsing key/value pairs | 
| 339 | 23 | 50 |  |  |  | 143 | $line =~ /^\s*([\w-]+)\s+(.*)\s*$/ and $data{lcase($1)}=[parse_line(READ_DELIM, 0, $2)], next; | 
| 340 |  |  |  |  |  |  | # if we came this far, the syntax couldn't be validated: | 
| 341 | 0 |  |  |  |  | 0 | $errstr = "syntax error on line $.: '$line'"; | 
| 342 | 0 |  |  |  |  | 0 | return undef; | 
| 343 |  |  |  |  |  |  | } | 
| 344 | 2 | 50 |  |  |  | 23 | unless ( flock($fh, LOCK_UN) ) { | 
| 345 | 0 |  |  |  |  | 0 | $errstr = "couldn't unlock the file: $!"; | 
| 346 | 0 |  |  |  |  | 0 | return undef; | 
| 347 |  |  |  |  |  |  | } | 
| 348 |  |  |  |  |  |  |  | 
| 349 | 2 | 50 |  |  |  | 8 | if ( $close_fh ) { | 
| 350 | 0 |  |  |  |  | 0 | CORE::close($fh); | 
| 351 |  |  |  |  |  |  | } | 
| 352 | 2 |  |  |  |  | 10 | return \%data; | 
| 353 |  |  |  |  |  |  | } | 
| 354 |  |  |  |  |  |  |  | 
| 355 |  |  |  |  |  |  |  | 
| 356 |  |  |  |  |  |  |  | 
| 357 |  |  |  |  |  |  | sub parse_http_file { | 
| 358 | 0 |  |  | 0 | 0 | 0 | my ($class, $file) = @_; | 
| 359 |  |  |  |  |  |  |  | 
| 360 | 0 | 0 |  |  |  | 0 | my ($fh, $close_fh) = $class->_get_fh($file, O_RDONLY) or return; | 
| 361 | 0 | 0 |  |  |  | 0 | unless ( flock($fh, LOCK_SH) ) { | 
| 362 | 0 |  |  |  |  | 0 | $errstr = "couldn't get shared lock on file: $!"; | 
| 363 | 0 |  |  |  |  | 0 | return undef; | 
| 364 |  |  |  |  |  |  | } | 
| 365 |  |  |  |  |  |  |  | 
| 366 | 0 | 0 |  |  |  | 0 | unless( seek($fh, 0, 0) ) { | 
| 367 | 0 |  |  |  |  | 0 | $errstr = "couldn't seek to the start of the file: $!"; | 
| 368 | 0 |  |  |  |  | 0 | return undef; | 
| 369 |  |  |  |  |  |  | } | 
| 370 | 0 |  |  |  |  | 0 | my %data = (); | 
| 371 | 0 |  |  |  |  | 0 | my $line; | 
| 372 | 0 |  |  |  |  | 0 | while ( defined($line= <$fh>) ) { | 
| 373 |  |  |  |  |  |  | # skipping comments and empty lines: | 
| 374 | 0 | 0 |  |  |  | 0 | $line =~ /^(\n|\#)/  and next; | 
| 375 | 0 | 0 |  |  |  | 0 | $line =~ /\S/        or  next; | 
| 376 |  |  |  |  |  |  | # stripping $/: | 
| 377 | 0 |  |  |  |  | 0 | chomp $line; | 
| 378 | 0 |  |  |  |  | 0 | $line =~ s/^\s+//g; | 
| 379 | 0 |  |  |  |  | 0 | $line =~ s/\s+$//g; | 
| 380 |  |  |  |  |  |  | # parsing key/value pairs: | 
| 381 | 0 | 0 |  |  |  | 0 | $line =~ /^\s*([\w-]+)\s*:\s*(.*)$/  and $data{lcase($1)}=[parse_line(READ_DELIM, 0, $2)], next; | 
| 382 |  |  |  |  |  |  | # if we came this far, the syntax couldn't be validated: | 
| 383 | 0 |  |  |  |  | 0 | $errstr = "syntax error on line $.: '$line'"; | 
| 384 | 0 |  |  |  |  | 0 | return undef; | 
| 385 |  |  |  |  |  |  | } | 
| 386 | 0 | 0 |  |  |  | 0 | unless ( flock($fh, LOCK_UN) ) { | 
| 387 | 0 |  |  |  |  | 0 | $errstr = "couldn't unlock file: $!"; | 
| 388 | 0 |  |  |  |  | 0 | return undef; | 
| 389 |  |  |  |  |  |  | } | 
| 390 | 0 | 0 |  |  |  | 0 | if ( $close_fh ) { | 
| 391 | 0 |  |  |  |  | 0 | CORE::close($fh); | 
| 392 |  |  |  |  |  |  | } | 
| 393 | 0 |  |  |  |  | 0 | return \%data; | 
| 394 |  |  |  |  |  |  | } | 
| 395 |  |  |  |  |  |  |  | 
| 396 |  |  |  |  |  |  |  | 
| 397 |  |  |  |  |  |  | sub param { | 
| 398 | 58 |  |  | 58 | 1 | 1927 | my $self = shift; | 
| 399 |  |  |  |  |  |  |  | 
| 400 |  |  |  |  |  |  | # If called with no arguments, return all the | 
| 401 |  |  |  |  |  |  | # possible keys | 
| 402 | 58 | 100 |  |  |  | 142 | unless ( @_ ) { | 
| 403 | 1 |  |  |  |  | 27 | my $vars = $self->vars(); | 
| 404 | 1 |  |  |  |  | 29 | return keys %$vars; | 
| 405 |  |  |  |  |  |  | } | 
| 406 |  |  |  |  |  |  | # if called with a single argument, return the value | 
| 407 |  |  |  |  |  |  | # matching this key | 
| 408 | 57 | 100 |  |  |  | 136 | if ( @_ == 1) { | 
| 409 | 39 |  |  |  |  | 86 | return $self->get_param(@_); | 
| 410 |  |  |  |  |  |  | } | 
| 411 |  |  |  |  |  |  | # if we come this far, we were called with multiple | 
| 412 |  |  |  |  |  |  | # arguments. Go figure! | 
| 413 | 18 |  |  |  |  | 91 | my $args = { | 
| 414 |  |  |  |  |  |  | '-name',   undef, | 
| 415 |  |  |  |  |  |  | '-value',  undef, | 
| 416 |  |  |  |  |  |  | '-values', undef, | 
| 417 |  |  |  |  |  |  | '-block',  undef, | 
| 418 |  |  |  |  |  |  | @_ | 
| 419 |  |  |  |  |  |  | }; | 
| 420 | 18 | 50 | 66 |  |  | 87 | if ( defined $args->{'-name'} && (defined($args->{'-value'}) || defined($args->{'-values'})) ) { | 
|  |  |  | 66 |  |  |  |  | 
| 421 |  |  |  |  |  |  | # OBJ->param(-name=>'..', -value=>'...') syntax: | 
| 422 | 4 |  | 66 |  |  | 30 | return $self->set_param($args->{'-name'}, $args->{'-value'}||$args->{'-values'}); | 
| 423 |  |  |  |  |  |  |  | 
| 424 |  |  |  |  |  |  | } | 
| 425 | 14 | 50 |  |  |  | 44 | if ( defined($args->{'-name'}) ) { | 
| 426 |  |  |  |  |  |  | # OBJ->param(-name=>'...') syntax: | 
| 427 | 0 |  |  |  |  | 0 | return $self->get_param($args->{'-name'}); | 
| 428 |  |  |  |  |  |  |  | 
| 429 |  |  |  |  |  |  | } | 
| 430 | 14 | 100 | 66 |  |  | 54 | if ( defined($args->{'-block'}) && (defined($args->{'-values'}) || defined($args->{'-value'})) ) { | 
|  |  |  | 66 |  |  |  |  | 
| 431 | 1 |  | 33 |  |  | 9 | return $self->set_block($args->{'-block'}, $args->{'-values'}||$args->{'-value'}); | 
| 432 |  |  |  |  |  |  | } | 
| 433 | 13 | 100 |  |  |  | 41 | if ( defined($args->{'-block'}) ) { | 
| 434 | 2 |  |  |  |  | 5 | return $self->get_block($args->{'-block'}); | 
| 435 |  |  |  |  |  |  | } | 
| 436 |  |  |  |  |  |  |  | 
| 437 | 11 | 50 |  |  |  | 543 | if ( @_ % 2 ) { | 
| 438 | 0 |  |  |  |  | 0 | croak "param(): illegal syntax"; | 
| 439 |  |  |  |  |  |  | } | 
| 440 | 11 |  |  |  |  | 17 | my $nset = 0; | 
| 441 | 11 |  |  |  |  | 38 | for ( my $i = 0; $i < @_; $i += 2 ) { | 
| 442 | 11 | 50 |  |  |  | 45 | $self->set_param($_[$i], $_[$i+1]) && $nset++; | 
| 443 |  |  |  |  |  |  | } | 
| 444 | 11 |  |  |  |  | 49 | return $nset; | 
| 445 |  |  |  |  |  |  | } | 
| 446 |  |  |  |  |  |  |  | 
| 447 |  |  |  |  |  |  |  | 
| 448 |  |  |  |  |  |  |  | 
| 449 |  |  |  |  |  |  |  | 
| 450 |  |  |  |  |  |  | sub get_param { | 
| 451 | 39 |  |  | 39 | 0 | 54 | my ($self, $arg) = @_; | 
| 452 |  |  |  |  |  |  |  | 
| 453 | 39 | 50 |  |  |  | 79 | unless ( $arg ) { | 
| 454 | 0 |  |  |  |  | 0 | croak "Usage: OBJ->get_param(\$key)"; | 
| 455 |  |  |  |  |  |  | } | 
| 456 | 39 |  |  |  |  | 77 | $arg = lcase($arg); | 
| 457 | 39 | 50 |  |  |  | 107 | my $syntax = $self->{_SYNTAX} or die "'_SYNTAX' is undefined"; | 
| 458 |  |  |  |  |  |  | # If it was an ini-style, we should first | 
| 459 |  |  |  |  |  |  | # split the argument into its block name and key | 
| 460 |  |  |  |  |  |  | # components: | 
| 461 | 39 |  |  |  |  | 45 | my $rv = undef; | 
| 462 | 39 | 100 |  |  |  | 79 | if ( $syntax eq 'ini' ) { | 
| 463 | 38 |  |  |  |  | 158 | my ($block_name, $key) = $arg =~ m/^([^\.]+)\.(.*)$/; | 
| 464 | 38 | 100 | 66 |  |  | 175 | if ( defined($block_name) && defined($key) ) { | 
| 465 | 37 |  |  |  |  | 89 | $rv = $self->{_DATA}->{$block_name}->{$key}; | 
| 466 |  |  |  |  |  |  | } else { | 
| 467 | 1 |  |  |  |  | 4 | $rv = $self->{_DATA}->{$DEFAULTNS}->{$arg}; | 
| 468 |  |  |  |  |  |  | } | 
| 469 |  |  |  |  |  |  | } else { | 
| 470 | 1 |  |  |  |  | 2 | $rv = $self->{_DATA}->{$arg}; | 
| 471 |  |  |  |  |  |  | } | 
| 472 |  |  |  |  |  |  |  | 
| 473 | 39 | 50 |  |  |  | 115 | defined($rv) or return; | 
| 474 |  |  |  |  |  |  |  | 
| 475 | 39 |  |  |  |  | 91 | for ( my $i=0; $i < @$rv; $i++ ) { | 
| 476 | 43 |  |  |  |  | 142 | $rv->[$i] =~ s/\\n/\n/g; | 
| 477 |  |  |  |  |  |  | } | 
| 478 | 39 | 100 |  |  |  | 675 | return @$rv==1 ? $rv->[0] : (wantarray ? @$rv : $rv); | 
|  |  | 100 |  |  |  |  |  | 
| 479 |  |  |  |  |  |  | } | 
| 480 |  |  |  |  |  |  |  | 
| 481 |  |  |  |  |  |  |  | 
| 482 |  |  |  |  |  |  |  | 
| 483 |  |  |  |  |  |  |  | 
| 484 |  |  |  |  |  |  | sub get_block { | 
| 485 | 3 |  |  | 3 | 1 | 6 | my ($self, $block_name)  = @_; | 
| 486 |  |  |  |  |  |  |  | 
| 487 | 3 | 50 |  |  |  | 7 | unless ( $self->syntax() eq 'ini' ) { | 
| 488 | 0 |  |  |  |  | 0 | croak "get_block() is supported only in 'ini' files"; | 
| 489 |  |  |  |  |  |  | } | 
| 490 | 3 | 100 |  |  |  | 7 | unless ( defined $block_name ) { | 
| 491 | 1 |  |  |  |  | 2 | return keys %{$self->{_DATA}}; | 
|  | 1 |  |  |  |  | 7 |  | 
| 492 |  |  |  |  |  |  | } | 
| 493 | 2 |  |  |  |  | 5 | my $rv = {}; | 
| 494 | 2 |  |  |  |  | 3 | while ( my ($k, $v) = each %{$self->{_DATA}->{$block_name}} ) { | 
|  | 10 |  |  |  |  | 67 |  | 
| 495 | 8 |  |  |  |  | 19 | $v =~ s/\\n/\n/g; | 
| 496 | 8 | 100 |  |  |  | 34 | $rv->{$k} = $v->[1] ? $v : $v->[0]; | 
| 497 |  |  |  |  |  |  | } | 
| 498 | 2 |  |  |  |  | 15 | return $rv; | 
| 499 |  |  |  |  |  |  | } | 
| 500 |  |  |  |  |  |  |  | 
| 501 |  |  |  |  |  |  |  | 
| 502 |  |  |  |  |  |  |  | 
| 503 |  |  |  |  |  |  |  | 
| 504 |  |  |  |  |  |  |  | 
| 505 |  |  |  |  |  |  | sub set_block { | 
| 506 | 1 |  |  | 1 | 1 | 3 | my ($self, $block_name, $values) = @_; | 
| 507 |  |  |  |  |  |  |  | 
| 508 | 1 | 50 |  |  |  | 3 | unless ( $self->syntax() eq 'ini' ) { | 
| 509 | 0 |  |  |  |  | 0 | croak "set_block() is supported only in 'ini' files"; | 
| 510 |  |  |  |  |  |  | } | 
| 511 | 1 |  |  |  |  | 2 | my $processed_values = {}; | 
| 512 | 1 |  |  |  |  | 8 | while ( my ($k, $v) = each %$values ) { | 
| 513 | 4 |  |  |  |  | 11 | $v =~ s/\n/\\n/g; | 
| 514 | 4 | 100 |  |  |  | 16 | $processed_values->{$k} = (ref($v) eq 'ARRAY') ? $v : [$v]; | 
| 515 | 4 |  |  |  |  | 9 | $self->_is_modified(1); | 
| 516 |  |  |  |  |  |  | } | 
| 517 |  |  |  |  |  |  |  | 
| 518 | 1 |  |  |  |  | 3 | $self->{_DATA}->{$block_name} = $processed_values; | 
| 519 | 1 |  |  |  |  | 6 | $self->_is_modified(1); | 
| 520 |  |  |  |  |  |  | } | 
| 521 |  |  |  |  |  |  |  | 
| 522 |  |  |  |  |  |  |  | 
| 523 |  |  |  |  |  |  |  | 
| 524 |  |  |  |  |  |  |  | 
| 525 |  |  |  |  |  |  |  | 
| 526 |  |  |  |  |  |  | sub set_param { | 
| 527 | 15 |  |  | 15 | 0 | 49 | my ($self, $key, $value) = @_; | 
| 528 |  |  |  |  |  |  |  | 
| 529 | 15 | 50 |  |  |  | 51 | my $syntax = $self->{_SYNTAX} or die "'_SYNTAX' is not defined"; | 
| 530 | 15 | 100 |  |  |  | 50 | if ( ref($value) eq 'ARRAY' ) { | 
| 531 | 2 |  |  |  |  | 9 | for (my $i=0; $i < @$value; $i++ ) { | 
| 532 | 4 |  |  |  |  | 13 | $value->[$i] =~ s/\n/\\n/g; | 
| 533 |  |  |  |  |  |  | } | 
| 534 |  |  |  |  |  |  | } else { | 
| 535 | 13 |  |  |  |  | 35 | $value =~ s/\n/\\n/g; | 
| 536 |  |  |  |  |  |  | } | 
| 537 | 15 | 100 |  |  |  | 41 | unless ( ref($value) eq 'ARRAY' ) { | 
| 538 | 13 |  |  |  |  | 31 | $value = [$value]; | 
| 539 |  |  |  |  |  |  | } | 
| 540 | 15 |  |  |  |  | 36 | $key = lcase($key); | 
| 541 |  |  |  |  |  |  | # If it was an ini syntax, we should first split the $key | 
| 542 |  |  |  |  |  |  | # into its block_name and key components | 
| 543 | 15 | 100 |  |  |  | 44 | if ( $syntax eq 'ini' ) { | 
| 544 | 12 |  |  |  |  | 61 | my ($bn, $k) = $key =~ m/^([^\.]+)\.(.*)$/; | 
| 545 | 12 | 100 | 66 |  |  | 68 | if ( $bn && $k ) { | 
| 546 | 11 |  |  |  |  | 28 | $self->_is_modified(1); | 
| 547 | 11 |  |  |  |  | 78 | return $self->{_DATA}->{$bn}->{$k} = $value; | 
| 548 |  |  |  |  |  |  | } | 
| 549 |  |  |  |  |  |  | # most likely the user is assuming default name space then? | 
| 550 |  |  |  |  |  |  | # Let's hope! | 
| 551 | 1 |  |  |  |  | 4 | $self->_is_modified(1); | 
| 552 | 1 |  |  |  |  | 9 | return $self->{_DATA}->{$DEFAULTNS}->{$key} = $value; | 
| 553 |  |  |  |  |  |  | } | 
| 554 | 3 |  |  |  |  | 11 | $self->_is_modified(1); | 
| 555 | 3 |  |  |  |  | 28 | return $self->{_DATA}->{$key} = $value; | 
| 556 |  |  |  |  |  |  | } | 
| 557 |  |  |  |  |  |  |  | 
| 558 |  |  |  |  |  |  |  | 
| 559 |  |  |  |  |  |  |  | 
| 560 |  |  |  |  |  |  |  | 
| 561 |  |  |  |  |  |  |  | 
| 562 |  |  |  |  |  |  |  | 
| 563 |  |  |  |  |  |  |  | 
| 564 |  |  |  |  |  |  |  | 
| 565 |  |  |  |  |  |  | sub write { | 
| 566 | 6 |  |  | 6 | 1 | 51 | my ($self, $file) = @_; | 
| 567 |  |  |  |  |  |  |  | 
| 568 | 6 | 50 | 66 |  |  | 65 | $file ||= $self->{_FILE_NAME} or die "Neither '_FILE_NAME' nor \$filename defined"; | 
| 569 |  |  |  |  |  |  |  | 
| 570 | 6 | 50 |  |  |  | 543 | unless ( sysopen(FH, $file, O_WRONLY|O_CREAT, 0666) ) { | 
| 571 | 0 |  |  |  |  | 0 | $self->error("'$file' couldn't be opened for writing: $!"); | 
| 572 | 0 |  |  |  |  | 0 | return undef; | 
| 573 |  |  |  |  |  |  | } | 
| 574 | 6 | 50 |  |  |  | 67 | unless ( flock(FH, LOCK_EX) ) { | 
| 575 | 0 |  |  |  |  | 0 | $self->error("'$file' couldn't be locked: $!"); | 
| 576 | 0 |  |  |  |  | 0 | return undef; | 
| 577 |  |  |  |  |  |  | } | 
| 578 | 6 | 50 |  |  |  | 594 | unless ( truncate(FH, 0) ) { | 
| 579 | 0 |  |  |  |  | 0 | $self->error("'$file' couldn't be truncated: $!"); | 
| 580 | 0 |  |  |  |  | 0 | return undef; | 
| 581 |  |  |  |  |  |  | } | 
| 582 | 6 |  |  |  |  | 30 | print FH $self->as_string(); | 
| 583 | 6 | 50 |  |  |  | 516 | unless ( CORE::close(FH) ) { | 
| 584 | 0 |  |  |  |  | 0 | $self->error("Couldn't write into '$file': $!"); | 
| 585 | 0 |  |  |  |  | 0 | return undef; | 
| 586 |  |  |  |  |  |  | } | 
| 587 | 6 |  |  |  |  | 175 | return 1; | 
| 588 |  |  |  |  |  |  | } | 
| 589 |  |  |  |  |  |  |  | 
| 590 |  |  |  |  |  |  |  | 
| 591 |  |  |  |  |  |  |  | 
| 592 |  |  |  |  |  |  | sub save { | 
| 593 | 1 |  |  | 1 | 1 | 2 | my $self = shift; | 
| 594 | 1 |  |  |  |  | 4 | return $self->write(@_); | 
| 595 |  |  |  |  |  |  | } | 
| 596 |  |  |  |  |  |  |  | 
| 597 |  |  |  |  |  |  |  | 
| 598 |  |  |  |  |  |  | # generates a writable string | 
| 599 |  |  |  |  |  |  | sub as_string { | 
| 600 | 6 |  |  | 6 | 1 | 11 | my $self = shift; | 
| 601 |  |  |  |  |  |  |  | 
| 602 | 6 | 50 |  |  |  | 31 | my $syntax = $self->{_SYNTAX} or die "'_SYNTAX' is not defined"; | 
| 603 | 6 |  | 100 |  |  | 40 | my $sub_syntax = $self->{_SUB_SYNTAX} || ''; | 
| 604 | 6 |  |  |  |  | 344 | my $currtime = localtime; | 
| 605 | 6 |  |  |  |  | 14 | my $STRING = undef; | 
| 606 | 6 | 100 |  |  |  | 34 | if ( $syntax eq 'ini' ) { | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
| 607 | 4 |  |  |  |  | 14 | $STRING .= "; Config::Simple $VERSION\n"; | 
| 608 | 4 |  |  |  |  | 12 | $STRING .= "; $currtime\n\n"; | 
| 609 | 4 |  |  |  |  | 10 | while ( my ($block_name, $key_values) = each %{$self->{_DATA}} ) { | 
|  | 15 |  |  |  |  | 58 |  | 
| 610 | 11 | 100 |  |  |  | 25 | unless ( $sub_syntax eq 'simple-ini' ) { | 
| 611 | 10 |  |  |  |  | 28 | $STRING .= sprintf("[%s]\n", $block_name); | 
| 612 |  |  |  |  |  |  | } | 
| 613 | 11 |  |  |  |  | 14 | while ( my ($key, $value) = each %{$key_values} ) { | 
|  | 57 |  |  |  |  | 170 |  | 
| 614 | 46 |  |  |  |  | 80 | my $values = join (WRITE_DELIM, map { quote_values($_) } @$value); | 
|  | 52 |  |  |  |  | 85 |  | 
| 615 | 46 |  |  |  |  | 149 | $STRING .= sprintf("%s=%s\n", $key, $values ); | 
| 616 |  |  |  |  |  |  | } | 
| 617 | 11 |  |  |  |  | 23 | $STRING .= "\n"; | 
| 618 |  |  |  |  |  |  | } | 
| 619 |  |  |  |  |  |  | } elsif ( $syntax eq 'http' ) { | 
| 620 | 0 |  |  |  |  | 0 | $STRING .= "# Config::Simple $VERSION\n"; | 
| 621 | 0 |  |  |  |  | 0 | $STRING .= "# $currtime\n\n"; | 
| 622 | 0 |  |  |  |  | 0 | while ( my ($key, $value) = each %{$self->{_DATA}} ) { | 
|  | 0 |  |  |  |  | 0 |  | 
| 623 | 0 |  |  |  |  | 0 | my $values = join (WRITE_DELIM, map { quote_values($_) } @$value); | 
|  | 0 |  |  |  |  | 0 |  | 
| 624 | 0 |  |  |  |  | 0 | $STRING .= sprintf("%s: %s\n", $key, $values); | 
| 625 |  |  |  |  |  |  | } | 
| 626 |  |  |  |  |  |  | } elsif ( $syntax eq 'simple' ) { | 
| 627 | 2 |  |  |  |  | 19 | $STRING .= "# Config::Simple $VERSION\n"; | 
| 628 | 2 |  |  |  |  | 8 | $STRING .= "# $currtime\n\n"; | 
| 629 | 2 |  |  |  |  | 6 | while ( my ($key, $value) = each %{$self->{_DATA}} ) { | 
|  | 25 |  |  |  |  | 91 |  | 
| 630 | 23 |  |  |  |  | 36 | my $values = join (WRITE_DELIM, map { quote_values($_) } @$value); | 
|  | 24 |  |  |  |  | 35 |  | 
| 631 | 23 |  |  |  |  | 66 | $STRING .= sprintf("%s %s\n", $key, $values); | 
| 632 |  |  |  |  |  |  | } | 
| 633 |  |  |  |  |  |  | } | 
| 634 | 6 |  |  |  |  | 15 | $STRING .= "\n"; | 
| 635 | 6 |  |  |  |  | 40 | return $STRING; | 
| 636 |  |  |  |  |  |  | } | 
| 637 |  |  |  |  |  |  |  | 
| 638 |  |  |  |  |  |  |  | 
| 639 |  |  |  |  |  |  |  | 
| 640 |  |  |  |  |  |  |  | 
| 641 |  |  |  |  |  |  |  | 
| 642 |  |  |  |  |  |  | # quotes each value before saving into file | 
| 643 |  |  |  |  |  |  | sub quote_values { | 
| 644 | 76 |  |  | 76 | 0 | 96 | my $string = shift; | 
| 645 |  |  |  |  |  |  |  | 
| 646 | 76 | 50 |  |  |  | 185 | if ( ref($string) ) {   $string = $_[0] } | 
|  | 0 |  |  |  |  | 0 |  | 
| 647 | 76 |  |  |  |  | 114 | $string =~ s/\\/\\\\/g; | 
| 648 |  |  |  |  |  |  |  | 
| 649 | 76 | 100 | 100 |  |  | 302 | if ( $USEQQ && ($string =~ m/\W/) ) { | 
| 650 | 12 |  |  |  |  | 17 | $string =~ s/"/\\"/g; | 
| 651 | 12 |  |  |  |  | 14 | $string =~ s/\n/\\n/g; | 
| 652 | 12 |  |  |  |  | 45 | return sprintf("\"%s\"", $string); | 
| 653 |  |  |  |  |  |  | } | 
| 654 | 64 |  |  |  |  | 211 | return $string; | 
| 655 |  |  |  |  |  |  | } | 
| 656 |  |  |  |  |  |  |  | 
| 657 |  |  |  |  |  |  |  | 
| 658 |  |  |  |  |  |  |  | 
| 659 |  |  |  |  |  |  | # deletes a variable | 
| 660 |  |  |  |  |  |  | sub delete { | 
| 661 | 1 |  |  | 1 | 1 | 2 | my ($self, $key) = @_; | 
| 662 |  |  |  |  |  |  |  | 
| 663 | 1 | 50 |  |  |  | 4 | my $syntax = $self->syntax() or die "No 'syntax' is defined"; | 
| 664 | 1 | 50 |  |  |  | 4 | if ( $syntax eq 'ini' ) { | 
| 665 | 1 |  |  |  |  | 6 | my ($bn, $k) = $key =~ m/([^\.]+)\.(.*)/; | 
| 666 | 1 | 50 | 33 |  |  | 8 | if ( defined($bn) && defined($k) ) { | 
| 667 | 1 |  |  |  |  | 4 | delete $self->{_DATA}->{$bn}->{$k}; | 
| 668 |  |  |  |  |  |  | } else { | 
| 669 | 0 |  |  |  |  | 0 | delete $self->{_DATA}->{$DEFAULTNS}->{$key}; | 
| 670 |  |  |  |  |  |  | } | 
| 671 | 1 |  |  |  |  | 5 | return 1; | 
| 672 |  |  |  |  |  |  | } | 
| 673 | 0 |  |  |  |  | 0 | delete $self->{_DATA}->{$key}; | 
| 674 |  |  |  |  |  |  | } | 
| 675 |  |  |  |  |  |  |  | 
| 676 |  |  |  |  |  |  |  | 
| 677 |  |  |  |  |  |  |  | 
| 678 |  |  |  |  |  |  | # clears the '_DATA' entirely. | 
| 679 |  |  |  |  |  |  | sub clear { | 
| 680 | 0 |  |  | 0 | 1 | 0 | my $self = shift; | 
| 681 | 0 |  |  |  |  | 0 | map { $self->delete($_) } $self->param; | 
|  | 0 |  |  |  |  | 0 |  | 
| 682 |  |  |  |  |  |  | } | 
| 683 |  |  |  |  |  |  |  | 
| 684 |  |  |  |  |  |  |  | 
| 685 |  |  |  |  |  |  |  | 
| 686 |  |  |  |  |  |  |  | 
| 687 |  |  |  |  |  |  | 1; | 
| 688 |  |  |  |  |  |  | __END__; |