File Coverage

blib/lib/Config/Auto.pm
Criterion Covered Total %
statement 260 286 90.9
branch 160 208 76.9
condition 34 54 62.9
subroutine 27 29 93.1
pod 8 8 100.0
total 489 585 83.5


line stmt bran cond sub pod time code
1             package Config::Auto;
2              
3 9     9   35069 use strict;
  9         20  
  9         339  
4 9     9   52 use warnings;
  9         18  
  9         329  
5              
6 9     9   58 use Carp qw[croak];
  9         15  
  9         653  
7              
8 9     9   52 use vars qw[$VERSION $DisablePerl $Untaint $Debug];
  9         16  
  9         2560  
9              
10             $VERSION = '0.44';
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 1904 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 9     9   51 { no strict 'refs';
  9         20  
  9         36165  
158             for my $meth ( qw[format path source _fh _data _file _score _tmp_fh] ) {
159             *$meth = sub {
160 1820     1820   14493 my $self = shift;
161 1820 100       4089 $self->{$meth} = shift if @_;
162 1820         9274 return $self->{$meth};
163             };
164             }
165             }
166              
167             sub new {
168 78     78 1 118849 my $class = shift;
169 78         317 my %hash = @_;
170 78         267 my $self = bless {}, $class;
171              
172 78 100       326 if( my $format = $hash{'format'} ) {
173              
174             ### invalid format
175 12 50       37 croak "No such format '$format'" unless $Methods{$format};
176              
177 12         34 $self->format( $format );
178             }
179              
180             ### set the other values that could be passed
181 78         205 for my $key ( qw[source path] ) {
182 156 100       805 $self->$key( defined $hash{$key} ? $hash{$key} : '' );
183             }
184              
185 78         322 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 65     65 1 48458 my $self = shift;
201              
202             ### XXX todo: re-implement magic configuration file finding based on $0
203              
204             ### procedural invocation, fix to OO
205 65 100       461 unless( UNIVERSAL::isa( $self, __PACKAGE__ ) ) {
206 32 50       240 $self = __PACKAGE__->new( source => $self, @_ )
207             or croak( "Could not parse '$self' => @_" );
208             }
209              
210 65         239 my $file = $self->file;
211 65 50       169 croak "No config file found!" unless defined $file;
212 65 50       1147 croak "Config file $file not readable!" unless -e $file;
213              
214             ### from Toru Marumoto: Config-Auto return undef if -B $file
215             ### <21d48be50604271656n153e6db6m9b059f57548aaa32@mail.gmail.com>
216             # If a config file "$file" contains multibyte charactors like japanese,
217             # -B returns "true" in old version of perl such as 5.005_003. It seems
218             # there is no problem in perl 5.6x or newer.
219             ### so check -B and only return only if
220 65 100       233 unless( $self->format ) {
221 63 50 33     162 return if $self->file and -B $self->file and $] >= '5.006';
      33        
222              
223 63         197 my $score = $self->score;
224              
225             ### no perl?
226 63 100 66     187 delete $score->{perl} if exists $score->{perl} and $DisablePerl;
227              
228             ### no formats found
229 63 100       421 croak "Unparsable file format!" unless keys %$score;
230              
231             ### Clear winner?
232 62         71 { my @methods = sort { $score->{$b} <=> $score->{$a} } keys %$score;
  62         299  
  45         142  
233 62 100       171 if (@methods > 1) {
234 0         0 croak "File format unclear! " .
235 25 50       69 join ",", map { "$_ => $score->{$_}"} @methods
236             if $score->{ $methods[0] } == $score->{ $methods[1] };
237             }
238 62         176 $self->format( $methods[0] );
239              
240 62         149 $self->_debug( "Using the following format for parsing: " . $self->format );
241             }
242             }
243              
244 64         139 return $Methods{ $self->format }->($self);
245             }
246              
247             =head2 $href = $obj->score;
248              
249             Takes a look at the contents of your configuration data and produces a
250             'score' determining which format it most likely contains.
251              
252             They keys are equal to formats as returned by the C<< Config::Auto->formats >>
253             and their values are a score between 1 and 100. The format with the highest
254             score will be used to parse your configuration data, unless you provided the
255             C option explicitly to the C method.
256              
257             =cut
258              
259             sub score {
260 95     95 1 50850 my $self = shift;
261              
262 95 100       232 return $self->_score if $self->_score;
263              
264 68         207 my $data = $self->data;
265              
266 68 50       280 return { xml => 100 } if $data->[0] =~ /^\s*<\?xml/;
267 68 100       284 return { perl => 100 } if $data->[0] =~ /^#!.*perl/;
268 58         86 my %score;
269              
270 58         133 for (@$data) {
271             ### it's almost definately YAML if the first line matches this
272 292 100 66     763 $score{yaml} += 20 if /(?:\#|%) # a #YAML or %YAML
273             YAML
274             (?::|\s) # a YAML: or YAML[space]
275             /x and $data->[0] eq $_;
276 292 100 66     842 $score{yaml} += 20 if /^---/ and $data->[0] eq $_;
277 292 50       613 $score{yaml} += 10 if /^\s+-\s\w+:\s\w+/;
278              
279             # Easy to comment out foo=bar syntax
280 292 50       664 $score{equal}++ if /^\s*#\s*\w+\s*=/;
281 292 100       629 next if /^\s*#/;
282              
283 242         598 $score{xml}++ for /(<\w+.*?>)/g;
284 242         553 $score{xml}+= 2 for m|()|g;
285 242         727 $score{xml}+= 5 for m|(/>)|g;
286 242 100       788 next unless /\S/;
287              
288 201 100       541 $score{equal}++, $score{ini}++ if m|^.*=.*$|;
289 201 100       524 $score{equal}++, $score{ini}++ if m|^\S+\s+=\s+|;
290 201 100       631 $score{colon}++ if /^[^:]+:[^:=]+/;
291 201 100       522 $score{colon}+=2 if /^\s*\w+\s*:[^:]+$/;
292 201 50       518 $score{colonequal}+= 3 if /^\s*\w+\s*:=[^:]+$/; # Debian foo.
293 201 50       385 $score{perl}+= 10 if /^\s*\$\w+(\{.*?\})*\s*=.*/;
294 201 100       738 $score{space}++ if m|^[^\s:]+\s+\S+$|;
295              
296             # mtab, fstab, etc.
297 201 100       895 $score{space}++ if m|^(\S+)\s+(\S+\s*)+|;
298 201 100       433 $score{bind}+= 5 if /\s*\S+\s*{$/;
299 201 100       593 $score{list}++ if /^[\w\/\-\+]+$/;
300 201 100 66     484 $score{bind}+= 5 if /^\s*}\s*$/ and exists $score{bind};
301 201 50 33     536 $score{irssi}+= 5 if /^\s*};\s*$/ and exists $score{irssi};
302 201 50       852 $score{irssi}+= 10 if /(\s*|^)\w+\s*=\s*{/;
303 201 50       736 $score{perl}++ if /\b([@%\$]\w+)/g;
304 201 100       471 $score{perl}+= 2 if /;\s*$/;
305 201 50       416 $score{perl}+=10 if /(if|for|while|until|unless)\s*\(/;
306 201         575 $score{perl}++ for /([\{\}])/g;
307 201 100       620 $score{equal}++, $score{ini}++ if m|^\s*\w+\s*=.*$|;
308 201 100       604 $score{ini} += 10 if /^\s*\[[\s\w]+\]\s*$/;
309             }
310              
311             # Choose between Win INI format and foo = bar
312 58 100       180 if (exists $score{ini}) {
313 9     9   175 no warnings 'uninitialized';
  9         20  
  9         30424  
314 21 100       77 $score{ini} > $score{equal}
315             ? delete $score{equal}
316             : delete $score{ini};
317             }
318              
319             # Some general sanity checks
320 58 100       144 if (exists $score{perl}) {
321 1 50 33     26 $score{perl} /= 2 unless ("@$data" =~ /;/) > 3 or $#$data < 3;
322 1 50       14 delete $score{perl} unless ("@$data" =~ /;/);
323 1 50       15 delete $score{perl} unless ("@$data" =~ /([\$\@\%]\w+)/);
324             }
325              
326 58 100 100     258 if ( $score{equal} && $score{space} && $score{equal} == $score{space} ) {
      100        
327 1         2 $score{equal}++;
328             }
329              
330 58         158 $self->_score( \%score );
331              
332 58         169 return \%score;
333             }
334              
335             =head2 $aref = $obj->data;
336              
337             Returns an array ref of your configuration data, split by newlines.
338              
339             =cut
340              
341             sub data {
342 89     89 1 1122 my $self = shift;
343 89 100       174 return $self->_data if $self->_data;
344              
345 66         129 my $src = $self->source;
346              
347             ### filehandle
348 66 100       922 if( ref $src ) {
    100          
349 20         266 my @data = <$src>;
350 20         59 $self->_data( \@data );
351              
352 20         147 seek $src, 0, 0; # reset position!
353              
354             ### data
355             } elsif ( $src =~ /\n/ ) {
356 23         224 $self->_data( [ split $/, $src, -1 ] );
357              
358             ### filename
359             } else {
360 23         60 my $fh = $self->fh;
361 23         534 my @data = <$fh>;
362 23         73 $self->_data( \@data );
363              
364 23         158 seek $fh, 0, 0; # reset position!
365             }
366              
367 66         175 return $self->_data;
368             }
369              
370             =head2 $fh = $obj->fh;
371              
372             Returns a filehandle, opened for reading, containing your configuration
373             data. This works even if you provided a plain text string or filename to
374             parse.
375              
376             =cut
377              
378             sub fh {
379 63     63 1 98 my $self = shift;
380 63 100       146 return $self->_fh if $self->_fh;
381              
382 48         107 my $src = $self->source;
383              
384             ### filehandle
385 48 100       188 if( ref $src ) {
    100          
386 12         29 $self->_fh( $src );
387              
388             ### data
389             } elsif ( $src =~ /\n/ ) {
390 12         1082 require IO::String;
391              
392 12         2287 my $fh = IO::String->new;
393 12         558 print $fh $src;
394 12         309 $fh->setpos(0);
395              
396 12         145 $self->_fh( $fh );
397              
398             } else {
399 24         33 my $fh;
400 24         57 my $file = $self->file;
401              
402 24 50       955 if( open $fh, $file ) {
403 24         73 $self->_fh( $fh );
404             } else {
405 0         0 $self->_debug( "Could not open '$file': $!" );
406 0         0 return;
407             }
408             }
409              
410 48         112 return $self->_fh;
411             }
412              
413             =head2 $filename = $obj->file;
414              
415             Returns a filename containing your configuration data. This works even
416             if you provided a plaintext string or filehandle to parse. In that case,
417             a temporary file will be written holding your configuration data.
418              
419             =cut
420              
421             sub file {
422 223     223 1 1331 my $self = shift;
423 223 100       423 return $self->_file if $self->_file;
424              
425 67         148 my $src = $self->source;
426              
427             ### filehandle or datastream, no file attached =/
428             ### so write a temp file
429 67 100 100     487 if( ref $src or $src =~ /\n/ ) {
430              
431             ### require only when needed
432 42         1758 require File::Temp;
433              
434 42         28231 my $tmp = File::Temp->new;
435 42 100       19610 $tmp->print( ref $src ? <$src> : $src );
436 42         694 $tmp->close; # write to disk
437              
438 42         3111 $self->_tmp_fh( $tmp ); # so it won't get destroyed
439 42         157 $self->_file( $tmp->filename );
440              
441 42 100       239 seek $src, 0, 0 if ref $src; # reset position!
442              
443             } else {
444 25 50       74 my $file = $self->_find_file( $src, $self->path ) or return;
445              
446 25         83 $self->_file( $file );
447             }
448              
449 67         154 return $self->_file;
450             }
451              
452             =head2 $str = $obj->as_string;
453              
454             Returns a string representation of your configuration data.
455              
456             =cut
457              
458             sub as_string {
459 14     14 1 26 my $self = shift;
460 14         34 my $data = $self->data;
461              
462 14         315 return join $/, @$data;
463             }
464              
465             sub _find_file {
466 25     25   629 my ($self, $file, $path) = @_;
467              
468              
469             ### moved here so they are only loaded when looking for a file
470             ### all to keep memory usage down.
471 25         41 { require File::Spec::Functions;
  25         8099  
472 25         6745 File::Spec::Functions->import('catfile');
473              
474 25         135 require File::Basename;
475 25         933 File::Basename->import(qw[dirname basename]);
476             }
477              
478 25         1461 my $bindir = dirname($0);
479 25         653 my $whoami = basename($0);
480              
481 25         143 $whoami =~ s/\.(pl|t)$//;
482              
483 25   66     146 my @filenames = $file ||
484             ("${whoami}config", "${whoami}.config",
485             "${whoami}rc", ".${whoami}rc");
486              
487 25         70 my $try;
488 25         83 for my $name (@filenames) {
489              
490 26 100       1015 return $name if -e $name;
491 2 100 66     5 return $try if ( $try = $self->_chkpaths($path, $name) ) and -e $try;
492 1 50       10 return $try if -e ( $try = catfile($bindir, $name) );
493 1 50 33     20 return $try if $ENV{HOME} && -e ( $try = catfile($ENV{HOME}, $name) );
494 1 50       17 return "/etc/$name" if -e "/etc/$name";
495 1 50       27 return "/usr/local/etc/$name"
496             if -e "/usr/local/etc/$name";
497             }
498              
499 0         0 $self->_debug( "Could not find file for '". $self->source ."'" );
500              
501 0         0 return;
502             }
503              
504             sub _chkpaths {
505 2     2   19 my ($self, $paths, $filename) = @_;
506              
507             ### no paths? no point in checking
508 2 50       7 return unless defined $paths;
509              
510 2         2 my $file;
511 2 50       7 for my $path ( ref($paths) eq 'ARRAY' ? @$paths : $paths ) {
512 2 100       51 return $file if -e ($file = catfile($path, $filename));
513             }
514              
515 1         5 return;
516             }
517              
518             sub _eval_perl {
519              
520 6     6   10 my $self = shift;
521 6         14 my $str = $self->as_string;
522              
523 6 50       16 ($str) = $str =~ m/^(.*)$/s if $Untaint;
524              
525 6         437 my $cfg = eval "$str";
526 6 50       22 croak __PACKAGE__ . " couldn't parse perl data: $@" if $@;
527 6         31 return $cfg;
528             }
529              
530             sub _parse_xml {
531 1     1   2 my $self = shift;
532              
533             ### Check if XML::Simple is already loaded
534 1 50       6 unless ( exists $INC{'XML/Simple.pm'} ) {
535             ### make sure we give good diagnostics when XML::Simple is not
536             ### available, but required to parse a config
537 1         2 eval { require XML::Simple; XML::Simple->import; 1 };
  1         433  
  1         13  
  0         0  
538 1 50       21 croak "XML::Simple not available. Can not parse " .
539             $self->as_string . "\nError: $@\n" if $@;
540             }
541              
542 0         0 return XML::Simple::XMLin( $self->as_string );
543             }
544              
545             sub _parse_ini {
546 6     6   12 my $self = shift;
547              
548             ### Check if Config::IniFiles is already loaded
549 6 100       21 unless ( exists $INC{'Config/IniFiles.pm'} ) {
550             ### make sure we give good diagnostics when XML::Simple is not
551             ### available, but required to parse a config
552 1         3 eval { require Config::IniFiles; Config::IniFiles->import; 1 };
  1         1356  
  1         15080  
  1         3  
553 1 50       7 croak "Config::IniFiles not available. Can not parse " .
554             $self->as_string . "\nError: $@\n" if $@;
555             }
556              
557 6         22 tie my %ini, 'Config::IniFiles', ( -file => $self->file );
558 6         9570 return \%ini;
559             }
560              
561             sub _return_list {
562 6     6   10 my $self = shift;
563              
564             ### there shouldn't be any trailing newlines or empty entries here
565 6         8 return [ grep { length } map { chomp; $_ } @{ $self->data } ];
  20         60  
  20         22  
  20         39  
  6         14  
566             }
567              
568             ### Changed to YAML::Any which selects the fastest YAML parser available
569             ### (req YAML 0.67)
570             sub _yaml {
571 6     6   11 my $self = shift;
572 6         880 require YAML::Any;
573              
574 6         1050 return YAML::Any::Load( $self->as_string );
575             }
576              
577 0     0   0 sub _bind_style { croak "BIND8-style config not supported in this release" }
578 0     0   0 sub _irssi_style { croak "irssi-style config not supported in this release" }
579              
580             # BUG: These functions are too similar. How can they be unified?
581              
582             sub _colon_sep {
583 18     18   28 my $self = shift;
584 18         42 my $fh = $self->fh;
585              
586 18         21 my %config;
587 18         25 local $_;
588 18         151 while (<$fh>) {
589 96 100       828 next if /^\s*#/;
590 66 100       313 /^\s*(.*?)\s*:\s*(.*)/ or next;
591 54         137 my ($k, $v) = ($1, $2);
592 54         52 my @v;
593 54 100       198 if ($v =~ /:/) {
    50          
    100          
    50          
594 18         79 @v = split /:/, $v;
595             } elsif ($v =~ /, /) {
596 0         0 @v = split /\s*,\s*/, $v;
597             } elsif ($v =~ / /) {
598 6         21 @v = split /\s+/, $v;
599             } elsif ($v =~ /,/) { # Order is important
600 0         0 @v = split /\s*,\s*/, $v;
601             } else {
602 30         56 @v = $v;
603             }
604 54         151 $self->_check_hash_and_assign(\%config, $k, @v);
605             }
606 18         186 return \%config;
607             }
608              
609             sub _check_hash_and_assign {
610 91     91   115 my $self = shift;
611              
612 91         217 my ($c, $k, @v) = @_;
613 91 100 100     287 if (exists $c->{$k} and !ref $c->{$k}) {
614 6         18 $c->{$k} = [$c->{$k}];
615             }
616              
617 91 100       374 if (grep /=/, @v) { # Bugger, it's really a hash
    100          
618 6         12 for (@v) {
619 6         6 my ($subkey, $subvalue);
620              
621             ### If the array element has an equal sign in it...
622 6 50       25 if (/(.*)=(.*)/) {
623 6         15 ($subkey, $subvalue) = ($1,$2);
624              
625             ###...otherwise, if the array element does not contain an equals sign:
626             } else {
627 0         0 $subkey = $_;
628 0         0 $subvalue = 1;
629             }
630              
631 6 50 33     21 if (exists $c->{$k} and ref $c->{$k} ne "HASH") {
632             # Can we find a hash in here?
633 0         0 my $h=undef;
634 0         0 for (@{$c->{$k}}) {
  0         0  
635 0 0       0 last if ref ($h = $_) eq "hash";
636             }
637 0 0       0 if ($h) { $h->{$subkey} = $subvalue; }
  0         0  
638 0         0 else { push @{$c->{$k}}, { $subkey => $subvalue } }
  0         0  
639             } else {
640 6         46 $c->{$k}{$subkey} = $subvalue;
641             }
642             }
643             } elsif (@v == 1) {
644 42 100       73 if (exists $c->{$k}) {
645 18 100       45 if (ref $c->{$k} eq "HASH") { $c->{$k}{$v[0]} = 1; }
  6         35  
  12         91  
646 12         11 else {push @{$c->{$k}}, @v}
647 24         139 } else { $c->{$k} = $v[0]; }
648             } else {
649 43 50       88 if (exists $c->{$k}) {
650 0 0       0 if (ref $c->{$k} eq "HASH") { $c->{$k}{$_} = 1 for @v }
  0         0  
  0         0  
651 0         0 else {push @{$c->{$k}}, @v }
652             }
653 43         410 else { $c->{$k} = [@v]; }
654             }
655             }
656              
657             { ### only load Text::ParseWords once;
658             my $loaded_tp;
659              
660             sub _equal_sep {
661 8     8   14 my $self = shift;
662 8         22 my $fh = $self->fh;
663              
664 8         54 my %config;
665 8         13 local $_;
666 8         103 while ( <$fh>) {
667 35 100       574 next if /^\s*#/;
668 16 100       130 next unless /^\s*(.*?)\s*=\s*(.*?)\s*$/;
669              
670 15         51 my ($k, $v) = ($1, $2);
671              
672             ### multiple enries, but no shell tokens?
673 15 50 33     161 if ($v=~ /,/ and $v !~ /(["']).*?,.*?\1/) {
    100          
674 0         0 $config{$k} = [ split /\s*,\s*/, $v ];
675             } elsif ($v =~ /\s/) { # XXX: Foo = "Bar baz"
676              
677             ### only load once
678 2 50       2283 require Text::ParseWords unless $loaded_tp++;
679              
680 2         2896 $config{$k} = [ Text::ParseWords::shellwords($v) ];
681              
682             } else {
683 13         85 $config{$k} = $v;
684             }
685             }
686              
687 8         489 return \%config;
688             }
689              
690             sub _space_sep {
691 13     13   27 my $self = shift;
692 13         29 my $fh = $self->fh;
693              
694 13         19 my %config;
695 13         22 local $_;
696 13         103 while (<$fh>) {
697 37 50       279 next if /^\s*#/;
698 37 50       158 next unless /\s*(\S+)\s+(.*)/;
699 37         92 my ($k, $v) = ($1, $2);
700 37         41 my @v;
701              
702             ### multiple enries, but no shell tokens?
703 37 100 100     309 if ($v=~ /,/ and $v !~ /(["']).*?,.*?\1/) {
    100          
704 1         7 @v = split /\s*,\s*/, $v;
705             } elsif ($v =~ /\s/) { # XXX: Foo = "Bar baz"
706              
707             ### only load once
708 18 100       2172 require Text::ParseWords unless $loaded_tp++;
709              
710 18         4082 @v = Text::ParseWords::shellwords($v);
711              
712             } else {
713 18         35 @v = $v;
714             }
715 37         1996 $self->_check_hash_and_assign(\%config, $k, @v);
716             }
717 13         160 return \%config;
718              
719             }
720             }
721             sub _debug {
722 62     62   104 my $self = shift;
723 62 50       138 my $msg = shift or return;
724              
725 62 50       230 Carp::confess( __PACKAGE__ . $msg ) if $Debug;
726             }
727              
728             1;
729              
730              
731             __END__