File Coverage

inc/YAML/Types.pm
Criterion Covered Total %
statement 30 165 18.1
branch 0 48 0.0
condition 0 5 0.0
subroutine 10 25 40.0
pod n/a
total 40 243 16.4


line stmt bran cond sub pod time code
1             #line 1
2 1     1   4 package YAML::Types;
  1     1   2  
  1         31  
  1         4  
  1         2  
  1         26  
3 1     1   5 use strict; use warnings;
  1     1   1  
  1         48  
  1         6  
  1         2  
  1         7  
4 1     1   5 use YAML::Base; use base 'YAML::Base';
  1         2  
  1         60  
5             use YAML::Node;
6              
7             # XXX These classes and their APIs could still use some refactoring,
8             # but at least they work for now.
9             #-------------------------------------------------------------------------------
10 1     1   5 package YAML::Type::blessed;
  1         2  
  1         132  
11             use YAML::Base; # XXX
12 0     0     sub yaml_dump {
13 0           my $self = shift;
14 0           my ($value) = @_;
15 1     1   6 my ($class, $type) = YAML::Base->node_info($value);
  1         2  
  1         576  
16 0           no strict 'refs';
17 0   0       my $kind = lc($type) . ':';
18             my $tag = ${$class . '::ClassTag'} ||
19 0 0         "!perl/$kind$class";
    0          
20 0           if ($type eq 'REF') {
21 0           YAML::Node->new(
22             {(&YAML::VALUE, ${$_[0]})}, $tag
23             );
24             }
25 0           elsif ($type eq 'SCALAR') {
26 0           $_[1] = $$value;
27             YAML::Node->new($_[1], $tag);
28 0           } else {
29             YAML::Node->new($value, $tag);
30             }
31             }
32              
33             #-------------------------------------------------------------------------------
34             package YAML::Type::undef;
35 0     0     sub yaml_dump {
36             my $self = shift;
37             }
38              
39 0     0     sub yaml_load {
40             my $self = shift;
41             }
42              
43             #-------------------------------------------------------------------------------
44             package YAML::Type::glob;
45 0     0     sub yaml_dump {
46 0           my $self = shift;
47 0           my $ynode = YAML::Node->new({}, '!perl/glob:');
48 0           for my $type (qw(PACKAGE NAME SCALAR ARRAY HASH CODE IO)) {
  0            
49 0 0         my $value = *{$_[0]}{$type};
50 0 0         $value = $$value if $type eq 'SCALAR';
51 0 0         if (defined $value) {
52 0           if ($type eq 'IO') {
53             my @stats = qw(device inode mode links uid gid rdev size
54 0           atime mtime ctime blksize blocks);
55 0           undef $value;
56 0           $value->{stat} = YAML::Node->new({});
  0            
  0            
57 0           map {$value->{stat}{shift @stats} = $_} stat(*{$_[0]});
  0            
58             $value->{fileno} = fileno(*{$_[0]});
59 0           {
  0            
60 0           local $^W;
  0            
61             $value->{tell} = tell(*{$_[0]});
62             }
63 0           }
64             $ynode->{$type} = $value;
65             }
66 0           }
67             return $ynode;
68             }
69              
70 0     0     sub yaml_load {
71 0           my $self = shift;
72 0           my ($node, $class, $loader) = @_;
73 0 0         my ($name, $package);
74 0           if (defined $node->{NAME}) {
75 0           $name = $node->{NAME};
76             delete $node->{NAME};
77             }
78 0           else {
79 0           $loader->warn('YAML_LOAD_WARN_GLOB_NAME');
80             return undef;
81 0 0         }
82 0           if (defined $node->{PACKAGE}) {
83 0           $package = $node->{PACKAGE};
84             delete $node->{PACKAGE};
85             }
86 0           else {
87             $package = 'main';
88 1     1   6 }
  1         2  
  1         296  
89 0 0         no strict 'refs';
90 0           if (exists $node->{SCALAR}) {
  0            
91 0           *{"${package}::$name"} = \$node->{SCALAR};
92             delete $node->{SCALAR};
93 0           }
94 0 0         for my $elem (qw(ARRAY HASH CODE IO)) {
95 0 0         if (exists $node->{$elem}) {
96 0           if ($elem eq 'IO') {
97 0           $loader->warn('YAML_LOAD_WARN_GLOB_IO');
98 0           delete $node->{IO};
99             next;
100 0           }
  0            
101 0           *{"${package}::$name"} = $node->{$elem};
102             delete $node->{$elem};
103             }
104 0           }
105 0           for my $elem (sort keys %$node) {
106             $loader->warn('YAML_LOAD_WARN_BAD_GLOB_ELEM', $elem);
107 0           }
  0            
108             return *{"${package}::$name"};
109             }
110              
111             #-------------------------------------------------------------------------------
112             package YAML::Type::code;
113             my $dummy_warned = 0;
114             my $default = '{ "DUMMY" }';
115 0     0     sub yaml_dump {
116 0           my $self = shift;
117 0           my $code;
118 0           my ($dumpflag, $value) = @_;
119 0           my ($class, $type) = YAML::Base->node_info($value);
120 0 0         my $tag = "!perl/code";
121 0 0         $tag .= ":$class" if defined $class;
122 0           if (not $dumpflag) {
123             $code = $default;
124             }
125 0 0         else {
126 1     1   5 bless $value, "CODE" if $class;
  1         2  
  1         679  
  0            
127 0 0         eval { use B::Deparse };
128 0           return if $@;
129 0           my $deparse = B::Deparse->new();
130 0           eval {
131 0           local $^W = 0;
132             $code = $deparse->coderef2text($value);
133 0 0         };
134 0 0         if ($@) {
135 0           warn YAML::YAML_DUMP_WARN_DEPARSE_FAILED() if $^W;
136             $code = $default;
137 0 0         }
138 0           bless $value, $class if $class;
139 0           chomp $code;
140             $code .= "\n";
141 0           }
142 0           $_[2] = $code;
143             YAML::Node->new($_[2], $tag);
144             }
145              
146 0     0     sub yaml_load {
147 0           my $self = shift;
148 0 0         my ($node, $class, $loader) = @_;
149 0           if ($loader->load_code) {
150 0 0         my $code = eval "package main; sub $node";
151 0           if ($@) {
152 0     0     $loader->warn('YAML_LOAD_WARN_PARSE_CODE', $@);
  0            
153             return sub {};
154             }
155 0 0         else {
156 0           CORE::bless $code, $class if $class;
157             return $code;
158             }
159             }
160 0 0   0     else {
  0            
161 0     0     return CORE::bless sub {}, $class if $class;
  0            
162             return sub {};
163             }
164             }
165              
166             #-------------------------------------------------------------------------------
167             package YAML::Type::ref;
168 0     0     sub yaml_dump {
169 0           my $self = shift;
  0            
170             YAML::Node->new({(&YAML::VALUE, ${$_[0]})}, '!perl/ref')
171             }
172              
173 0     0     sub yaml_load {
174 0           my $self = shift;
175 0 0         my ($node, $class, $loader) = @_;
176             $loader->die('YAML_LOAD_ERR_NO_DEFAULT_VALUE', 'ptr')
177 0           unless exists $node->{&YAML::VALUE};
178             return \$node->{&YAML::VALUE};
179             }
180              
181             #-------------------------------------------------------------------------------
182             package YAML::Type::regexp;
183             # XXX Be sure to handle blessed regexps (if possible)
184 0     0     sub yaml_dump {
185             die "YAML::Type::regexp::yaml_dump not currently implemented";
186             }
187              
188 0           use constant _QR_TYPES => {
189 0           '' => sub { qr{$_[0]} },
190 0           x => sub { qr{$_[0]}x },
191 0           i => sub { qr{$_[0]}i },
192 0           s => sub { qr{$_[0]}s },
193 0           m => sub { qr{$_[0]}m },
194 0           ix => sub { qr{$_[0]}ix },
195 0           sx => sub { qr{$_[0]}sx },
196 0           mx => sub { qr{$_[0]}mx },
197 0           si => sub { qr{$_[0]}si },
198 0           mi => sub { qr{$_[0]}mi },
199 0           ms => sub { qr{$_[0]}sm },
200 0           six => sub { qr{$_[0]}six },
201 0           mix => sub { qr{$_[0]}mix },
202 0           msx => sub { qr{$_[0]}msx },
203 0           msi => sub { qr{$_[0]}msi },
204 1     1   5 msix => sub { qr{$_[0]}msix },
  1         2  
  1         301  
205             };
206 0     0     sub yaml_load {
207 0           my $self = shift;
208 0 0         my ($node, $class) = @_;
209 0           return qr{$node} unless $node =~ /^\(\?([\-xism]*):(.*)\)\z/s;
210 0           my ($flags, $re) = ($1, $2);
211 0   0 0     $flags =~ s/-.*//;
  0            
212 0           my $sub = _QR_TYPES->{$flags} || sub { qr{$_[0]} };
213 0 0         my $qr = &$sub($re);
214 0           bless $qr, $class if length $class;
215             return $qr;
216             }
217              
218             1;
219              
220             __END__