File Coverage

blib/lib/Parse/Yapp/KeyValue.pm
Criterion Covered Total %
statement 32 33 96.9
branch 3 4 75.0
condition 1 3 33.3
subroutine 7 8 87.5
pod 2 2 100.0
total 45 50 90.0


line stmt bran cond sub pod time code
1             package Parse::Yapp::KeyValue;
2              
3 1     1   30661 use strict;
  1         2  
  1         39  
4 1     1   6 use warnings;
  1         2  
  1         50  
5              
6             our $VERSION = 0.10;
7              
8             =head1 NAME
9              
10             Parse::Yapp::KeyValue - parser for simple key/value pairs
11              
12             =head1 DESCRIPTION
13              
14             parse a string of simple key/value pairs and
15             store the results in a hash reference for easy
16             access. Parse::KeyValue correctly handles
17             escaped quotes as well as escaped backslashes.
18              
19             Parse::KeyValue will parse the following example
20             string:
21              
22             AL=53 AK=54 AB=55 TN="home sweet home" =$
23              
24             into a hashref with the following contents:
25              
26             {
27             '' => '$',
28             'AL' => '53',
29             'TN' => 'home sweet home',
30             'AK' => '54',
31             'AB' => '55'
32             }
33              
34             multiple identical keys are treated as arrays.
35             the string
36              
37             A=1 A=2 A=3
38              
39             will return a hash reference with the following
40             contents:
41              
42             { A => [ 1, 2, 3 ] }
43              
44             tokens without an associated key name will be
45             treated as pairs with an empty string for the
46             key. the string
47              
48             yeah alabama "crimson tide"
49              
50             will return a hash reference with the following
51             contents:
52              
53             { '' => [ 'yeah', 'alabama', 'crimson tide' ] }
54              
55             =head1 SYNOPSIS
56              
57             my $str = 'A=1 K=2 B=3 A=4';
58             my $kv = new Parse::Yapp::KeyValue;
59             my $href = $kv->parse($str);
60              
61             print $href ? Dumper $href : "parse failed\n";
62              
63             =head1 TODO
64              
65             - configurable delimiter
66             - flags to alter behavior in the event of
67             multiple keys (error, overwrite last value,
68             keep first value)
69             - flag to require ALL values be inside an array
70             reference, not just keys with multiple values
71              
72             =cut
73              
74 1     1   572 use Parse::Yapp::KeyValue::Parser;
  1         3  
  1         30  
75 1     1   979 use Parse::Lex;
  1         28907  
  1         304  
76              
77             my @lex =
78             (
79             OP_ASSIGNMENT => '=',
80             KEY => '[A-Za-z0-9]+',
81             TEXT_Q_SINGLE => '\'[^\']+\'',
82             TEXT_Q_DOUBLE => '"[^"]+"',
83             TEXT_NONQUOTED => '[^\'" ]+',
84             );
85              
86             =head1 METHODS
87              
88             =over 4
89              
90             =item new
91              
92             instantiates a new Parse::Yapp::KeyValue object.
93             no arguments are currently accepted.
94              
95             =cut
96              
97             sub new
98             {
99 1     1 1 14 my $proto = shift;
100 1   33     9 my $class = ref $proto || $proto;
101              
102 1         5 return bless {}, $class;
103             }
104              
105             =item parse
106              
107             parses the supplied string and returns a hash
108             reference containing the parsed data. in the
109             even that parsing fails, undef is returned.
110              
111             =cut
112              
113             sub parse
114             {
115 1     1 1 852 my $self = shift;
116 1         2 my $str = shift;
117              
118             # handle escaped quotes and escaped backslashes
119             # this is just wrong, but it's quick and easy
120              
121 1         4 $str =~ s/\\\\/\x01/g;
122 1         3 $str =~ s/\\'/\x02/g;
123 1         3 $str =~ s/\\"/\x03/g;
124              
125 1         20 my $lexer = new Parse::Lex @lex;
126 1         625 $lexer->from($str);
127              
128 1         6294 my $parser = Parse::Yapp::KeyValue::Parser->new;
129 1         10 $parser->YYData->{lexer} = $lexer;
130 1         21 $parser->YYData->{DATA} = {};
131              
132             $parser->YYParse
133             (
134             yylex => sub
135             {
136 26     26   910 $_[0]->YYData->{ERR} = 0;
137 26         172 my $lexer = $_[0]->YYData->{lexer};
138 26 100       170 return ('', undef) if $lexer->eoi;
139 25         152 my $token = $lexer->next;
140 25         1774 return $token->name, $token->text;
141             },
142             yyerror => sub
143             {
144 0     0   0 $_[0]->YYData->{ERR} = 1;
145             }
146 1         21 );
147              
148 1 50       55 return $parser->YYData->{ERR} == 1 ? undef : $parser->YYData->{DATA};
149             }
150              
151             =back
152              
153             =head1 AUTHOR
154              
155             mike eldridge
156              
157             =head1 LICENSE
158              
159             This library is free software; you can redistribute it and/or modify
160             it under the same terms as Perl itself, either Perl version 5.8.8 or,
161             at your option, any later version of Perl 5 you may have available.
162              
163             =cut
164              
165             1;