File Coverage

blib/lib/Config/Auto.pm
Criterion Covered Total %
statement 253 279 90.6
branch 154 202 76.2
condition 26 45 57.7
subroutine 27 29 93.1
pod 8 8 100.0
total 468 563 83.1


line stmt bran cond sub pod time code
1             package Config::Auto;
2              
3 6     6   4351 use strict;
  6         11  
  6         291  
4 6     6   34 use warnings;
  6         11  
  6         267  
5              
6 6     6   45 use Carp qw[croak];
  6         8  
  6         653  
7              
8 6     6   43 use vars qw[$VERSION $DisablePerl $Untaint $Debug];
  6         9  
  6         1555  
9              
10             $VERSION = '0.29_02';
11             $DisablePerl = 0;
12             $Untaint = 0;
13             $Debug = 0;
14              
15             =head1 NAME
16              
17             Config::Auto - Magical config file parser
18              
19             =head1 SYNOPSIS
20            
21             use Config::Auto;
22            
23             ### Not very magical at all.
24             $config = Config::Auto::parse("myprogram.conf", format => "colon");
25            
26             ### Considerably more magical.
27             $config = Config::Auto::parse("myprogram.conf");
28            
29             ### Highly magical.
30             $config = Config::Auto::parse();
31            
32             ### Using the OO interface
33             $ca = Config::Auto->new( source => $text );
34             $ca = Config::Auto->new( source => $fh );
35             $ca = Config::Auto->new( source => $filename );
36            
37             $href = $ca->score; # compute the score for various formats
38              
39             $config = $ca->parse; # parse the config
40              
41             $format = $ca->format; # detected (or provided) config format
42             $str = $ca->as_string; # config file stringified
43             $fh = $ca->fh; # config file handle
44             $file = $ca->file; # config filename
45             $aref = $ca->data; # data from your config, split by newlines
46              
47             =cut
48              
49              
50             =head1 DESCRIPTION
51              
52             This module was written after having to write Yet Another Config File Parser
53             for some variety of colon-separated config. I decided "never again".
54              
55             Config::Auto aims to be the most C config parser available, by detecting
56             configuration styles, include paths and even config filenames automagically.
57              
58             See the L section below on implementation details.
59              
60             =cut
61              
62             =head1 ACCESSORS
63              
64             =head2 @formats = Config::Auto->formats
65              
66             Returns a list of supported formats for your config files. These formats
67             are also the keys as used by the C method.
68              
69             C recognizes the following formats:
70              
71             =over 4
72              
73             =item * perl => perl code
74              
75             =item * colon => colon separated (e.g., key:value)
76              
77             =item * space => space separated (e.g., key value)
78              
79             =item * equal => equal separated (e.g., key=value)
80              
81             =item * bind => bind style (not available)
82              
83             =item * irssi => irssi style (not available)
84              
85             =item * xml => xml (via XML::Simple)
86              
87             =item * ini => .ini format (via Config::IniFiles)
88              
89             =item * list => list (e.g., foo bar baz)
90              
91             =item * yaml => yaml (via YAML.pm)
92              
93             =back
94              
95             =cut
96              
97             my %Methods = (
98             perl => \&_eval_perl,
99             colon => \&_colon_sep,
100             space => \&_space_sep,
101             equal => \&_equal_sep,
102             bind => \&_bind_style,
103             irssi => \&_irssi_style,
104             ini => \&_parse_ini,
105             list => \&_return_list,
106             yaml => \&_yaml,
107             xml => \&_parse_xml,
108             );
109              
110 2     2 1 1248 sub formats { return keys %Methods }
111              
112             =head1 METHODS
113              
114             =head2 $obj = Config::Auto->new( [source => $text|$fh|$filename, path => \@paths, format => FORMAT_NAME] );
115              
116             Returns a C object based on your configs source. This can either be:
117              
118             =over 4
119              
120             =item a filehandle
121              
122             Any opened filehandle, or C/C object.
123              
124             =item a plain text string
125              
126             Any plain string containing one or more newlines.
127              
128             =item a filename
129              
130             Any plain string pointing to a file on disk
131              
132             =item nothing
133              
134             A heuristic will be applied to find your config file, based on the name of
135             your script; C<$0>.
136              
137             =back
138              
139             Although C is at its most magical when called with no parameters,
140             its behavior can be controlled explicitly by using one or two arguments.
141              
142             If a filename is passed as the C argument, the same paths are checked,
143             but C will look for a file with the passed name instead of the
144             C<$0>-based names.
145              
146             Supplying the C parameter will add additional directories to the search
147             paths. The current directory is searched first, then the paths specified with
148             the path parameter. C can either be a scalar or a reference to an array
149             of paths to check.
150              
151             The C parameters forces C to interpret the contents of
152             the configuration file in the given format without trying to guess.
153              
154             =cut
155              
156             ### generate accessors
157 6     6   39 { no strict 'refs';
  6         8  
  6         13108  
158             for my $meth ( qw[format path source _fh _data _file _score _tmp_fh] ) {
159             *$meth = sub {
160 1619     1619   10003 my $self = shift;
161 1619 100       3431 $self->{$meth} = shift if @_;
162 1619         7129 return $self->{$meth};
163             };
164             }
165             }
166              
167             sub new {
168 75     75 1 88915 my $class = shift;
169 75         284 my %hash = @_;
170 75         243 my $self = bless {}, $class;
171              
172 75 100       301 if( my $format = $hash{'format'} ) {
173              
174             ### invalid format
175 11 50       34 croak "No such format '$format'" unless $Methods{$format};
176            
177 11         23 $self->format( $format );
178             }
179              
180             ### set the other values that could be passed
181 75         191 for my $key ( qw[source path] ) {
182 150 100       723 $self->$key( defined $hash{$key} ? $hash{$key} : '' );
183             }
184              
185 75         870 return $self;
186             }
187              
188             =head2 $rv = $obj->parse | Config::Auto::parse( [$text|$fh|$filename, path => \@paths, format => FORMAT_NAME] );
189              
190             Parses the source you provided in the C call and returns a data
191             structure representing your configuration file.
192              
193             You can also call it in a procedural context (C), where
194             the first argument is the source, and the following arguments are named. This
195             function is provided for backwards compatiblity with releases prior to 0.29.
196              
197             =cut
198              
199             sub parse {
200 62     62 1 67417 my $self = shift;
201            
202             ### XXX todo: re-implement magic configuration file finding based on $0
203            
204             ### procedural invocation, fix to OO
205 62 100       484 unless( UNIVERSAL::isa( $self, __PACKAGE__ ) ) {
206 31 50       222 $self = __PACKAGE__->new( source => $self, @_ )
207             or croak( "Could not parse '$self' => @_" );
208             }
209              
210             ### from Toru Marumoto: Config-Auto return undef if -B $file
211             ### <21d48be50604271656n153e6db6m9b059f57548aaa32@mail.gmail.com>
212             # If a config file "$file" contains multibyte charactors like japanese,
213             # -B returns "true" in old version of perl such as 5.005_003. It seems
214             # there is no problem in perl 5.6x or newer.
215             ### so check -B and only return only if
216 62 100       214 unless( $self->format ) {
217 61 50 33     178 return if $self->file and -B $self->file and $] >= '5.006';
      33        
218              
219 61         254 my $score = $self->score;
220            
221             ### no perl?
222 61 100 66     218 delete $score->{perl} if exists $score->{perl} and $DisablePerl;
223            
224             ### no formats found
225 61 100       421 croak "Unparsable file format!" unless keys %$score;
226            
227             ### Clear winner?
228 60         78 { my @methods = sort { $score->{$b} <=> $score->{$a} } keys %$score;
  60         327  
  45         172  
229 60 100       217 if (@methods > 1) {
230 0         0 croak "File format unclear! " .
231 24 50       87 join ",", map { "$_ => $score->{$_}"} @methods
232             if $score->{ $methods[0] } == $score->{ $methods[1] };
233             }
234 60         183 $self->format( $methods[0] );
235              
236 60         129 $self->_debug( "Using the following format for parsing: " . $self->format );
237             }
238             }
239              
240 61         140 return $Methods{ $self->format }->($self);
241             }
242              
243             =head2 $href = $obj->score;
244              
245             Takes a look at the contents of your configuration data and produces a
246             'score' determining which format it most likely contains.
247              
248             They keys are equal to formats as returned by the C<< Config::Auto->formats >>
249             and their values are a score between 1 and 100. The format with the highest
250             score will be used to parse your configuration data, unless you provided the
251             C option explicitly to the C method.
252              
253             =cut
254              
255             sub score {
256 93     93 1 44310 my $self = shift;
257              
258 93 100       236 return $self->_score if $self->_score;
259              
260 66         207 my $data = $self->data;
261              
262 66 50       351 return { xml => 100 } if $data->[0] =~ /^\s*<\?xml/;
263 66 100       341 return { perl => 100 } if $data->[0] =~ /^#!.*perl/;
264 56         100 my %score;
265              
266 56         150 for (@$data) {
267             ### it's almost definately YAML if the first line matches this
268 284 100 66     801 $score{yaml} += 20 if /(?:\#|%) # a #YAML or %YAML
269             YAML
270             (?::|\s) # a YAML: or YAML[space]
271             /x and $data->[0] eq $_;
272 284 100 66     688 $score{yaml} += 20 if /^---/ and $data->[0] eq $_;
273 284 50       585 $score{yaml} += 10 if /^\s+-\s\w+:\s\w+/;
274            
275             # Easy to comment out foo=bar syntax
276 284 50       604 $score{equal}++ if /^\s*#\s*\w+\s*=/;
277 284 100       586 next if /^\s*#/;
278              
279 234         608 $score{xml}++ for /(<\w+.*?>)/g;
280 234         515 $score{xml}+= 2 for m|()|g;
281 234         441 $score{xml}+= 5 for m|(/>)|g;
282 234 100       794 next unless /\S/;
283              
284 193 100       563 $score{equal}++, $score{ini}++ if m|^.*=.*$|;
285 193 100       488 $score{equal}++, $score{ini}++ if m|^\S+\s+=\s+|;
286 193 100       769 $score{colon}++ if /^[^:]+:[^:=]+/;
287 193 100       493 $score{colon}+=2 if /^\s*\w+\s*:[^:]+$/;
288 193 50       417 $score{colonequal}+= 3 if /^\s*\w+\s*:=[^:]+$/; # Debian foo.
289 193 50       397 $score{perl}+= 10 if /^\s*\$\w+(\{.*?\})*\s*=.*/;
290 193 100       2896 $score{space}++ if m|^[^\s:]+\s+\S+$|;
291              
292             # mtab, fstab, etc.
293 193 100       845 $score{space}++ if m|^(\S+)\s+(\S+\s*)+|;
294 193 100       480 $score{bind}+= 5 if /\s*\S+\s*{$/;
295 193 100       721 $score{list}++ if /^[\w\/\-\+]+$/;
296 193 100 66     486 $score{bind}+= 5 if /^\s*}\s*$/ and exists $score{bind};
297 193 50 33     467 $score{irssi}+= 5 if /^\s*};\s*$/ and exists $score{irssi};
298 193 50       762 $score{irssi}+= 10 if /(\s*|^)\w+\s*=\s*{/;
299 193 50       710 $score{perl}++ if /\b([@%\$]\w+)/g;
300 193 100       422 $score{perl}+= 2 if /;\s*$/;
301 193 50       514 $score{perl}+=10 if /(if|for|while|until|unless)\s*\(/;
302 193         612 $score{perl}++ for /([\{\}])/g;
303 193 100       952 $score{equal}++, $score{ini}++ if m|^\s*\w+\s*=.*$|;
304 193 100       541 $score{ini} += 10 if /^\s*\[[\s\w]+\]\s*$/;
305             }
306              
307             # Choose between Win INI format and foo = bar
308 56 100       169 if (exists $score{ini}) {
309 6     6   66 no warnings 'uninitialized';
  6         12  
  6         17515  
310 20 100       98 $score{ini} > $score{equal}
311             ? delete $score{equal}
312             : delete $score{ini};
313             }
314              
315             # Some general sanity checks
316 56 100       136 if (exists $score{perl}) {
317 1 50 33     23 $score{perl} /= 2 unless ("@$data" =~ /;/) > 3 or $#$data < 3;
318 1 50       13 delete $score{perl} unless ("@$data" =~ /;/);
319 1 50       14 delete $score{perl} unless ("@$data" =~ /([\$\@\%]\w+)/);
320             }
321              
322 56         206 $self->_score( \%score );
323              
324 56         152 return \%score;
325             }
326              
327             =head2 $aref = $obj->data;
328              
329             Returns an array ref of your configuration data, split by newlines.
330              
331             =cut
332              
333             sub data {
334 87     87 1 978 my $self = shift;
335 87 100       218 return $self->_data if $self->_data;
336            
337 64         196 my $src = $self->source;
338              
339             ### filehandle
340 64 100       915 if( ref $src ) {
    100          
341 20         251 my @data = <$src>;
342 20         75 $self->_data( \@data );
343            
344 20         76 seek $src, 0, 0; # reset position!
345              
346             ### data
347             } elsif ( $src =~ /\n/ ) {
348 23         277 $self->_data( [ split $/, $src, -1 ] );
349            
350             ### filename
351             } else {
352 21         64 my $fh = $self->fh;
353 21         350 my @data = <$fh>;
354 21         71 $self->_data( \@data );
355            
356 21         92 seek $fh, 0, 0; # reset position!
357             }
358            
359 64         180 return $self->_data;
360             }
361              
362             =head2 $fh = $obj->fh;
363              
364             Returns a filehandle, opened for reading, containing your configuration
365             data. This works even if you provided a plain text string or filename to
366             parse.
367              
368             =cut
369              
370             sub fh {
371 58     58 1 87 my $self = shift;
372 58 100       137 return $self->_fh if $self->_fh;
373              
374 45         107 my $src = $self->source;
375              
376             ### filehandle
377 45 100       252 if( ref $src ) {
    100          
378 12         32 $self->_fh( $src );
379              
380             ### data
381             } elsif ( $src =~ /\n/ ) {
382 12         905 require IO::String;
383            
384 12         3289 my $fh = IO::String->new;
385 12         633 print $fh $src;
386 12         375 $fh->setpos(0);
387            
388 12         180 $self->_fh( $fh );
389              
390             } else {
391 21         32 my $fh;
392 21         51 my $file = $self->file;
393            
394 21 50       794 if( open $fh, $file ) {
395 21         72 $self->_fh( $fh );
396             } else {
397 0         0 $self->_debug( "Could not open '$file': $!" );
398 0         0 return;
399             }
400             }
401              
402 45         105 return $self->_fh;
403             }
404              
405             =head2 $filename = $obj->file;
406              
407             Returns a filename containing your configuration data. This works even
408             if you provided a plaintext string or filehandle to parse. In that case,
409             a temporary file will be written holding your configuration data.
410              
411             =cut
412              
413             sub file {
414 151     151 1 804 my $self = shift;
415 151 100       341 return $self->_file if $self->_file;
416              
417 63         190 my $src = $self->source;
418              
419             ### filehandle or datastream, no file attached =/
420             ### so write a temp file
421 63 100 100     474 if( ref $src or $src =~ /\n/ ) {
422              
423             ### require only when needed
424 41         386 require File::Temp;
425            
426 41         410 my $tmp = File::Temp->new;
427 41 100       20548 $tmp->print( ref $src ? <$src> : $src );
428 41         743 $tmp->close; # write to disk
429              
430 41         2306 $self->_tmp_fh( $tmp ); # so it won't get destroyed
431 41         155 $self->_file( $tmp->filename );
432            
433 41 100       213 seek $src, 0, 0 if ref $src; # reset position!
434              
435             } else {
436 22 50       557 my $file = $self->_find_file( $src, $self->path ) or return;
437            
438 22         90 $self->_file( $file );
439             }
440            
441 63         164 return $self->_file;
442             }
443              
444             =head2 $str = $obj->as_string;
445              
446             Returns a string representation of your configuration data.
447              
448             =cut
449              
450             sub as_string {
451 14     14 1 18 my $self = shift;
452 14         34 my $data = $self->data;
453            
454 14         283 return join $/, @$data;
455             }
456              
457             sub _find_file {
458 22     22   531 my ($self, $file, $path) = @_;
459              
460            
461             ### moved here so they are only loaded when looking for a file
462             ### all to keep memory usage down.
463 22         26 { require File::Spec::Functions;
  22         1979  
464 22         14640 File::Spec::Functions->import('catfile');
465            
466 22         143 require File::Basename;
467 22         718 File::Basename->import(qw[dirname basename]);
468             }
469            
470 22         1345 my $bindir = dirname($0);
471 22         600 my $whoami = basename($0);
472              
473 22         142 $whoami =~ s/\.(pl|t)$//;
474            
475 22   66     126 my @filenames = $file ||
476             ("${whoami}config", "${whoami}.config",
477             "${whoami}rc", ".${whoami}rc");
478              
479 22         40 my $try;
480 22         55 for my $name (@filenames) {
481              
482 23 100       673 return $name if -e $name;
483 2 100 66     9 return $try if ( $try = $self->_chkpaths($path, $name) ) and -e $try;
484 1 50       10 return $try if -e ( $try = catfile($bindir, $name) );
485 1 50       19 return $try if -e ( $try = catfile($ENV{HOME}, $name) );
486 1 50       15 return "/etc/$name" if -e "/etc/$name";
487 1 50       21 return "/usr/local/etc/$name"
488             if -e "/usr/local/etc/$name";
489             }
490            
491 0         0 $self->_debug( "Could not find file for '". $self->source ."'" );
492            
493 0         0 return;
494             }
495              
496             sub _chkpaths {
497 2     2   20 my ($self, $paths, $filename) = @_;
498              
499             ### no paths? no point in checking
500 2 50       7 return unless defined $paths;
501              
502 2         3 my $file;
503 2 50       11 for my $path ( ref($paths) eq 'ARRAY' ? @$paths : $paths ) {
504 2 100       54 return $file if -e ($file = catfile($path, $filename));
505             }
506            
507 1         6 return;
508             }
509              
510             sub _eval_perl {
511              
512 6     6   11 my $self = shift;
513 6         12 my $str = $self->as_string;
514            
515 6 50       14 ($str) = $str =~ m/^(.*)$/s if $Untaint;
516            
517 6         418 my $cfg = eval "$str";
518 6 50       25 croak __PACKAGE__ . " couldn't parse perl data: $@" if $@;
519 6         40 return $cfg;
520             }
521              
522             sub _parse_xml {
523 1     1   1 my $self = shift;
524              
525             ### Check if XML::Simple is already loaded
526 1 50       4 unless ( exists $INC{'XML/Simple.pm'} ) {
527             ### make sure we give good diagnostics when XML::Simple is not
528             ### available, but required to parse a config
529 1         2 eval { require XML::Simple; XML::Simple->import; 1 };
  1         428  
  1         10  
  0         0  
530 1 50       15 croak "XML::Simple not available. Can not parse " .
531             $self->as_string . "\nError: $@\n" if $@;
532             }
533            
534 0         0 return XML::Simple::XMLin( $self->as_string );
535             }
536              
537             sub _parse_ini {
538 6     6   16 my $self = shift;
539              
540             ### Check if Config::IniFiles is already loaded
541 6 100       27 unless ( exists $INC{'Config/IniFiles.pm'} ) {
542             ### make sure we give good diagnostics when XML::Simple is not
543             ### available, but required to parse a config
544 1         2 eval { require Config::IniFiles; Config::IniFiles->import; 1 };
  1         736  
  1         9472  
  1         2  
545 1 50       5 croak "Config::IniFiles not available. Can not parse " .
546             $self->as_string . "\nError: $@\n" if $@;
547             }
548            
549 6         34 tie my %ini, 'Config::IniFiles', ( -file => $self->file );
550 6         10598 return \%ini;
551             }
552              
553             sub _return_list {
554 6     6   9 my $self = shift;
555            
556             ### there shouldn't be any trailing newlines or empty entries here
557 6         12 return [ grep { length } map { chomp; $_ } @{ $self->data } ];
  20         64  
  20         25  
  20         32  
  6         15  
558             }
559              
560             ### Changed to YAML::Any which selects the fastest YAML parser available
561             ### (req YAML 0.67)
562             sub _yaml {
563 6     6   8 my $self = shift;
564 6         703 require YAML::Any;
565              
566 6         1171 return YAML::Any::Load( $self->as_string );
567             }
568              
569 0     0   0 sub _bind_style { croak "BIND8-style config not supported in this release" }
570 0     0   0 sub _irssi_style { croak "irssi-style config not supported in this release" }
571              
572             # BUG: These functions are too similar. How can they be unified?
573              
574             sub _colon_sep {
575 18     18   39 my $self = shift;
576 18         57 my $fh = $self->fh;
577            
578 18         40 my %config;
579 18         180 while (<$fh>) {
580 96 100       944 next if /^\s*#/;
581 66 100       418 /^\s*(.*?)\s*:\s*(.*)/ or next;
582 54         165 my ($k, $v) = ($1, $2);
583 54         70 my @v;
584 54 100       260 if ($v =~ /:/) {
    50          
    100          
    50          
585 18         87 @v = split /:/, $v;
586             } elsif ($v =~ /, /) {
587 0         0 @v = split /\s*,\s*/, $v;
588             } elsif ($v =~ / /) {
589 6         29 @v = split /\s+/, $v;
590             } elsif ($v =~ /,/) { # Order is important
591 0         0 @v = split /\s*,\s*/, $v;
592             } else {
593 30         70 @v = $v;
594             }
595 54         162 $self->_check_hash_and_assign(\%config, $k, @v);
596             }
597 18         196 return \%config;
598             }
599              
600             sub _check_hash_and_assign {
601 84     84   122 my $self = shift;
602              
603 84         185 my ($c, $k, @v) = @_;
604 84 100 100     353 if (exists $c->{$k} and !ref $c->{$k}) {
605 6         16 $c->{$k} = [$c->{$k}];
606             }
607              
608 84 100       379 if (grep /=/, @v) { # Bugger, it's really a hash
    100          
609 6         16 for (@v) {
610 6         8 my ($subkey, $subvalue);
611              
612             ### If the array element has an equal sign in it...
613 6 50       37 if (/(.*)=(.*)/) {
614 6         21 ($subkey, $subvalue) = ($1,$2);
615            
616             ###...otherwise, if the array element does not contain an equals sign:
617             } else {
618 0         0 $subkey = $_;
619 0         0 $subvalue = 1;
620             }
621              
622 6 50 33     27 if (exists $c->{$k} and ref $c->{$k} ne "HASH") {
623             # Can we find a hash in here?
624 0         0 my $h=undef;
625 0         0 for (@{$c->{$k}}) {
  0         0  
626 0 0       0 last if ref ($h = $_) eq "hash";
627             }
628 0 0       0 if ($h) { $h->{$subkey} = $subvalue; }
  0         0  
629 0         0 else { push @{$c->{$k}}, { $subkey => $subvalue } }
  0         0  
630             } else {
631 6         63 $c->{$k}{$subkey} = $subvalue;
632             }
633             }
634             } elsif (@v == 1) {
635 42 100       94 if (exists $c->{$k}) {
636 18 100       46 if (ref $c->{$k} eq "HASH") { $c->{$k}{$v[0]} = 1; }
  6         37  
  12         93  
637 12         13 else {push @{$c->{$k}}, @v}
638 24         165 } else { $c->{$k} = $v[0]; }
639             } else {
640 36 100       102 if (exists $c->{$k}) {
641 12 50       43 if (ref $c->{$k} eq "HASH") { $c->{$k}{$_} = 1 for @v }
  0         0  
  12         121  
642 12         71 else {push @{$c->{$k}}, @v }
643             }
644 24         241 else { $c->{$k} = [@v]; }
645             }
646             }
647              
648             { ### only load Text::ParseWords once;
649             my $loaded_tp;
650            
651             sub _equal_sep {
652 6     6   7 my $self = shift;
653 6         9 my $fh = $self->fh;
654            
655 6         7 my %config;
656 6         34 while (<$fh>) {
657 30 100       211 next if /^\s*#/;
658 12 50       47 next unless /^\s*(.*?)\s*=\s*(.*)\s*$/;
659            
660 12         25 my ($k, $v) = ($1, $2);
661 12         8 my @v;
662            
663             ### multiple enries, but no shell tokens?
664 12 50 33     42 if ($v=~ /,/ and $v !~ /(["']).*?,.*?\1/) {
    50          
665 0         0 $config{$k} = [ split /\s*,\s*/, $v ];
666             } elsif ($v =~ /\s/) { # XXX: Foo = "Bar baz"
667            
668             ### only load once
669 0 0       0 require Text::ParseWords unless $loaded_tp++;
670            
671 0         0 $config{$k} = [ Text::ParseWords::shellwords($v) ];
672             } else {
673 12         37 $config{$k} = $v;
674             }
675             }
676            
677 6         41 return \%config;
678             }
679            
680             sub _space_sep {
681 12     12   18 my $self = shift;
682 12         35 my $fh = $self->fh;
683            
684 12         19 my %config;
685 12         110 while (<$fh>) {
686 30 50       310 next if /^\s*#/;
687 30 50       213 next unless /\s*(\S+)\s+(.*)/;
688 30         94 my ($k, $v) = ($1, $2);
689 30         36 my @v;
690            
691             ### multiple enries, but no shell tokens?
692 30 50 66     211 if ($v=~ /,/ and $v !~ /(["']).*?,.*?\1/) {
    100          
693 0         0 @v = split /\s*,\s*/, $v;
694             } elsif ($v =~ /\s/) { # XXX: Foo = "Bar baz"
695            
696             ### only load once
697 12 100       855 require Text::ParseWords unless $loaded_tp++;
698              
699 12         1826 $config{$k} = [ Text::ParseWords::shellwords($v) ];
700             } else {
701 18         39 @v = $v;
702             }
703 30         1359 $self->_check_hash_and_assign(\%config, $k, @v);
704             }
705 12         133 return \%config;
706            
707             }
708             }
709             sub _debug {
710 60     60   87 my $self = shift;
711 60 50       165 my $msg = shift or return;
712            
713 60 50       275 Carp::confess( __PACKAGE__ . $msg ) if $Debug;
714             }
715              
716             1;
717              
718              
719             __END__