File Coverage

blib/lib/FFI/Platypus/TypeParser/Version0.pm
Criterion Covered Total %
statement 64 68 94.1
branch 35 40 87.5
condition 21 32 65.6
subroutine 8 8 100.0
pod 0 3 0.0
total 128 151 84.7


line stmt bran cond sub pod time code
1             package FFI::Platypus::TypeParser::Version0;
2              
3 47     47   7617 use strict;
  47         104  
  47         2049  
4 47     47   298 use warnings;
  47         202  
  47         3041  
5 47     47   990 use 5.008004;
  47         202  
6 47     47   283 use Carp qw( croak );
  47         133  
  47         4030  
7 47     47   319 use parent qw( FFI::Platypus::TypeParser );
  47         92  
  47         406  
8              
9             # ABSTRACT: FFI Type Parser Version Zero
10             our $VERSION = '2.11'; # VERSION
11              
12              
13             our @CARP_NOT = qw( FFI::Platypus FFI::Platypus::TypeParser );
14              
15             # The type parser is responsible for deciding if something is a legal
16             # alias name. Since this needs to be checked before the type is parsed
17             # it is separate from set_alias below.
18             sub check_alias
19             {
20 194     194 0 443 my($self, $alias) = @_;
21 194 50       913 croak "spaces not allowed in alias" if $alias =~ /\s/;
22 194 50       1095 croak "allowed characters for alias: [A-Za-z0-9_]" if $alias !~ /^[A-Za-z0-9_]+$/;
23             croak "alias \"$alias\" conflicts with existing type"
24             if defined $self->type_map->{$alias}
25 194 50 33     641 || $self->types->{$alias};
26 194         471 return 1;
27             }
28              
29             sub set_alias
30             {
31 194     194 0 511 my($self, $alias, $type) = @_;
32 194         511 $self->types->{$alias} = $type;
33             }
34              
35             # This method takes a string representation of the a type and
36             # returns the internal platypus type representation.
37             sub parse
38             {
39 2001     2001 0 4363 my($self, $name) = @_;
40              
41 2001 100       5298 return $self->types->{$name} if defined $self->types->{$name};
42              
43             # Darmock and Legacy Code at Tanagra
44 1362 100 100     8535 unless($name =~ /-\>/ || $name =~ /^record\s*\([0-9A-Z:a-z_]+\)$/
      100        
45             || $name =~ /^string(_rw|_ro|\s+rw|\s+ro|\s*\([0-9]+\))$/)
46             {
47 1260         2197 my $basic = $name;
48 1260         2261 my $extra = '';
49 1260 100       7530 if($basic =~ s/\s*((\*|\[|\<).*)$//)
50             {
51 351         1247 $extra = " $1";
52             }
53 1260 100       3358 if(defined $self->type_map->{$basic})
54             {
55 1225         2581 my $new_name = $self->type_map->{$basic} . $extra;
56 1225 100       3505 if($new_name ne $name)
57             {
58             # hopefully no recursion here.
59 144         584 return $self->types->{$name} = $self->parse($new_name);
60             }
61             }
62             }
63              
64 1218 100       3437 if($name =~ m/^ \( (.*) \) \s* -\> \s* (.*) \s* $/x)
65             {
66 41         222 my @argument_types = map { $self->parse($_) } map { my $t = $_; $t =~ s/^\s+//; $t =~ s/\s+$//; $t } split /,/, $1;
  36         170  
  36         82  
  36         107  
  36         79  
  36         110  
67 41         164 my $return_type = $self->parse($2);
68 41         195 return $self->types->{$name} = $self->create_type_closure($self->abi, $return_type, @argument_types);
69             }
70              
71 1177 100       2900 if($name =~ /^ string \s* \( ([0-9]+) \) $/x)
72             {
73 11         155 return $self->types->{$name} = $self->create_type_record(
74             0,
75             $1, # size
76             );
77             }
78              
79 1166 100       3161 if($name =~ /^ string ( _rw | _ro | \s+ro | \s+rw | ) $/x)
80             {
81 66 100 66     956 return $self->types->{$name} = $self->create_type_string(
82             defined $1 && $1 =~ /rw/ ? 1 : 0, # rw
83             );
84             }
85              
86 1100 100       2583 if($name =~ /^ record \s* \( ([0-9]+) \) $/x)
87             {
88 6         76 return $self->types->{$name} = $self->create_type_record(
89             0,
90             $1, # size
91             );
92             }
93              
94 1094 100       2412 if($name =~ /^ record \s* \( ([0-9:A-Za-z_]+) \) $/x)
95             {
96 33         44 my $size;
97 33         92 my $classname = $1;
98 33 50 66     257 unless($classname->can('ffi_record_size') || $classname->can('_ffi_record_size'))
99             {
100 0         0 my $pm = "$classname.pm";
101 0         0 $pm =~ s/\//::/g;
102 0         0 require $pm;
103             }
104 33 100       167 if($classname->can('ffi_record_size'))
    50          
105             {
106 2         9 $size = $classname->ffi_record_size;
107             }
108             elsif($classname->can('_ffi_record_size'))
109             {
110 31         76 $size = $classname->_ffi_record_size;
111             }
112             else
113             {
114 0         0 croak "$classname has not ffi_record_size or _ffi_record_size method";
115             }
116 33   66     77 return $self->global_types->{record}->{$classname} ||= $self->create_type_record(
117             0,
118             $size, # size
119             $classname, # record_class
120             );
121             }
122              
123             # array types
124 1061 100       3151 if($name =~ /^([\S]+)\s+ \[ ([0-9]*) \] $/x)
125             {
126 205   100     958 my $size = $2 || '';
127 205   33     669 my $basic = $self->global_types->{basic}->{$1} || croak("unknown ffi/platypus type $name [$size]");
128 205 100       584 if($size)
129             {
130 182         1765 return $self->types->{$name} = $self->create_type_array(
131             $basic->type_code,
132             $size,
133             );
134             }
135             else
136             {
137 23   66     66 return $self->global_types->{array}->{$name} ||= $self->create_type_array(
138             $basic->type_code,
139             0
140             );
141             }
142             }
143              
144             # pointer types
145 856 100       2396 if($name =~ s/\s+\*$//)
146             {
147 80   33     463 return $self->global_types->{ptr}->{$name} || croak("unknown ffi/platypus type $name *");
148             }
149              
150             # basic types
151 776   66     2249 return $self->global_types->{basic}->{$name} || croak("unknown ffi/platypus type $name");
152             }
153              
154             1;
155              
156             __END__