| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Inline::Struct; | 
| 2 |  |  |  |  |  |  |  | 
| 3 | 15 |  |  | 15 |  | 1202056 | use strict; | 
|  | 15 |  |  |  |  | 62 |  | 
|  | 15 |  |  |  |  | 491 |  | 
| 4 | 15 |  |  | 15 |  | 85 | use warnings; | 
|  | 15 |  |  |  |  | 37 |  | 
|  | 15 |  |  |  |  | 446 |  | 
| 5 | 15 |  |  | 15 |  | 118 | use Carp; | 
|  | 15 |  |  |  |  | 31 |  | 
|  | 15 |  |  |  |  | 1225 |  | 
| 6 |  |  |  |  |  |  | require Inline; | 
| 7 |  |  |  |  |  |  | require Inline::Struct::grammar; | 
| 8 | 15 |  |  | 15 |  | 89 | use Data::Dumper; | 
|  | 15 |  |  |  |  | 31 |  | 
|  | 15 |  |  |  |  | 29180 |  | 
| 9 |  |  |  |  |  |  |  | 
| 10 |  |  |  |  |  |  | our $VERSION = '0.28'; | 
| 11 |  |  |  |  |  |  |  | 
| 12 |  |  |  |  |  |  | #============================================================================= | 
| 13 |  |  |  |  |  |  | # Inline::Struct is NOT an ILSM: no register() function | 
| 14 |  |  |  |  |  |  | #============================================================================= | 
| 15 |  |  |  |  |  |  |  | 
| 16 |  |  |  |  |  |  | #============================================================================= | 
| 17 |  |  |  |  |  |  | # parse -- gets all C/C++ struct definitions and binds them to Perl | 
| 18 |  |  |  |  |  |  | #============================================================================= | 
| 19 |  |  |  |  |  |  | sub parse { | 
| 20 | 15 |  |  | 15 | 0 | 2491227 | require Parse::RecDescent; | 
| 21 | 15 |  |  |  |  | 53 | my $o = shift; | 
| 22 | 15 | 50 |  |  |  | 136 | return if $o->{STRUCT}{'.parser'}; | 
| 23 | 15 | 50 |  |  |  | 89 | return unless $o->{STRUCT}{'.any'}; | 
| 24 |  |  |  |  |  |  |  | 
| 25 |  |  |  |  |  |  | # Figure out whether to grab all structs | 
| 26 | 68 |  |  |  |  | 279 | my $nstructs = scalar grep { $_ =~ /^[_a-z][_0-9a-z]*$/i } | 
| 27 | 15 |  |  |  |  | 43 | keys %{$o->{STRUCT}}; | 
|  | 15 |  |  |  |  | 109 |  | 
| 28 | 15 | 100 |  |  |  | 97 | $o->{STRUCT}{'.all'} = 1 | 
| 29 |  |  |  |  |  |  | if $nstructs == 0; | 
| 30 |  |  |  |  |  |  |  | 
| 31 |  |  |  |  |  |  | # Load currently-defined types (stored in $o->{ILSM}{typeconv}) | 
| 32 | 15 |  |  |  |  | 188 | $o->get_maps; | 
| 33 | 15 |  |  |  |  | 2544 | $o->get_types; | 
| 34 |  |  |  |  |  |  |  | 
| 35 |  |  |  |  |  |  | # Parse structs | 
| 36 | 15 |  |  |  |  | 219945 | $::RD_HINT++; | 
| 37 | 15 | 50 |  |  |  | 150 | my $grammar = Inline::Struct::grammar::grammar() | 
| 38 |  |  |  |  |  |  | or croak "Can't find Struct grammar!\n"; | 
| 39 | 15 |  |  |  |  | 172 | my $parser = $o->{STRUCT}{'.parser'} = Parse::RecDescent->new($grammar); | 
| 40 | 15 |  |  |  |  | 1477522 | $parser->{data}{typeconv} = $o->{ILSM}{typeconv}; | 
| 41 | 15 |  |  |  |  | 320 | $parser->code($o->{ILSM}{code}); | 
| 42 | 15 |  |  |  |  | 84005 | $o->{ILSM}{typeconv} = $parser->{data}{typeconv}; | 
| 43 |  |  |  |  |  |  |  | 
| 44 | 15 |  |  |  |  | 71 | $o->{STRUCT}{'.xs'} = ""; | 
| 45 | 15 |  |  |  |  | 122 | $o->{STRUCT}{'.macros'} = < | 
| 46 |  |  |  |  |  |  | #define NEW_INLINE_STRUCT(_IS_targ,_IS_type) INLINE_STRUCT_NEW_##_IS_type(_IS_targ) | 
| 47 |  |  |  |  |  |  | #define INLINE_STRUCT_FIELDS(_IS_type) INLINE_STRUCT_FIELDS_##_IS_type | 
| 48 |  |  |  |  |  |  | #define INLINE_STRUCT_INIT_LIST(_IS_targ,_IS_type) INLINE_STRUCT_INITL_##_IS_type(_IS_targ) | 
| 49 |  |  |  |  |  |  | #define INLINE_STRUCT_ARRAY(_IS_src,_IS_targ,_IS_type) INLINE_STRUCT_ARRAY_##_IS_type(_IS_src,_IS_targ) | 
| 50 |  |  |  |  |  |  | #define INLINE_STRUCT_VALUES(_IS_src,_IS_targ,_IS_type) INLINE_STRUCT_ARRAY_##_IS_type(_IS_src,_IS_targ) | 
| 51 |  |  |  |  |  |  | #define INLINE_STRUCT_HASH(_IS_src,_IS_targ,_IS_type) INLINE_STRUCT_HASH_##_IS_type(_IS_src,_IS_targ) | 
| 52 |  |  |  |  |  |  | #define INLINE_STRUCT_KEYS(_IS_src,_IS_targ,_IS_type) INLINE_STRUCT_KEYS_##_IS_type(_IS_src,_IS_targ) | 
| 53 |  |  |  |  |  |  | END | 
| 54 |  |  |  |  |  |  |  | 
| 55 | 15 |  |  |  |  | 32 | my @struct_list; | 
| 56 | 15 | 100 |  |  |  | 77 | if ($o->{STRUCT}{'.all'}) { | 
| 57 | 10 | 50 |  |  |  | 55 | die "No valid structs found" unless $parser->{data}{structs}; | 
| 58 | 10 |  |  |  |  | 23 | @struct_list = @{$parser->{data}{structs}}; | 
|  | 10 |  |  |  |  | 41 |  | 
| 59 |  |  |  |  |  |  | } | 
| 60 |  |  |  |  |  |  | else { | 
| 61 | 33 |  |  |  |  | 117 | @struct_list = grep { $_ =~ /^[_a-z][_a-z0-9]*$/i } | 
| 62 | 5 |  |  |  |  | 16 | keys %{$o->{STRUCT}} | 
|  | 5 |  |  |  |  | 31 |  | 
| 63 |  |  |  |  |  |  | } | 
| 64 | 15 |  |  |  |  | 71 | for my $struct (@struct_list) { | 
| 65 | 19 | 50 |  |  |  | 89 | unless (defined $parser->{data}{struct}{$struct}) { | 
| 66 | 0 | 0 |  |  |  | 0 | warn "Struct $struct requested but not found" if $^W; | 
| 67 | 0 |  |  |  |  | 0 | next; | 
| 68 |  |  |  |  |  |  | } | 
| 69 | 19 |  |  |  |  | 72 | $o->{STRUCT}{'.bound'}{$struct}++; | 
| 70 | 19 |  |  |  |  | 84 | my $cname = $parser->{data}{struct}{$struct}{cname}; | 
| 71 | 19 |  |  |  |  | 53 | my ($NEW, $FIELDS, $INITL, $HASH, $ARRAY, $KEYS); | 
| 72 |  |  |  |  |  |  |  | 
| 73 |  |  |  |  |  |  | # Set up the initial part of the macros | 
| 74 | 19 |  |  |  |  | 131 | $NEW = < | 
| 75 |  |  |  |  |  |  | #define INLINE_STRUCT_NEW_${struct}(_IS_targ) { \\ | 
| 76 |  |  |  |  |  |  | HV *hv = get_hv("Inline::Struct::${struct}::_map_", 1); \\ | 
| 77 |  |  |  |  |  |  | HV *entry = newHV(); \\ | 
| 78 |  |  |  |  |  |  | SV *entrv = (SV*)newRV((SV*)entry); \\ | 
| 79 |  |  |  |  |  |  | SV *lookup; \\ | 
| 80 |  |  |  |  |  |  | char *key; \\ | 
| 81 |  |  |  |  |  |  | STRLEN klen; \\ | 
| 82 |  |  |  |  |  |  | ENTER; \\ | 
| 83 |  |  |  |  |  |  | SAVETMPS; \\ | 
| 84 |  |  |  |  |  |  | Newz(1564,_IS_targ,1,$cname); \\ | 
| 85 |  |  |  |  |  |  | lookup = newSViv((IV)_IS_targ); \\ | 
| 86 |  |  |  |  |  |  | key = SvPV(lookup, klen); \\ | 
| 87 |  |  |  |  |  |  | sv_2mortal(lookup); \\ | 
| 88 |  |  |  |  |  |  | hv_store(entry, "REFCNT", 6, newSViv(0), 0); \\ | 
| 89 |  |  |  |  |  |  | hv_store(entry, "FREE", 4, newSViv(1), 0); \\ | 
| 90 |  |  |  |  |  |  | hv_store(hv, key, klen, entrv, 0); \\ | 
| 91 |  |  |  |  |  |  | FREETMPS; \\ | 
| 92 |  |  |  |  |  |  | LEAVE; \\ | 
| 93 |  |  |  |  |  |  | } | 
| 94 |  |  |  |  |  |  | END | 
| 95 |  |  |  |  |  |  | $FIELDS = "#define INLINE_STRUCT_FIELDS_$struct " . | 
| 96 | 19 |  |  |  |  | 64 | (scalar @{$parser->{data}{struct}{$struct}{fields}}) . "\n"; | 
|  | 19 |  |  |  |  | 129 |  | 
| 97 | 19 |  |  |  |  | 66 | $INITL = "#define INLINE_STRUCT_INITL_$struct(_IS_targ) {\\\n"; | 
| 98 | 19 |  |  |  |  | 60 | $HASH = < | 
| 99 |  |  |  |  |  |  | #define INLINE_STRUCT_HASH_$struct(_IS_src,_IS_targ) \\ | 
| 100 |  |  |  |  |  |  | hv_clear(_IS_targ); \\ | 
| 101 |  |  |  |  |  |  | END | 
| 102 | 19 |  |  |  |  | 54 | $ARRAY = < | 
| 103 |  |  |  |  |  |  | #define INLINE_STRUCT_ARRAY_$struct(_IS_src,_IS_targ) \\ | 
| 104 |  |  |  |  |  |  | av_clear(_IS_targ); \\ | 
| 105 |  |  |  |  |  |  | END | 
| 106 |  |  |  |  |  |  |  | 
| 107 | 19 |  |  |  |  | 53 | $KEYS = < | 
| 108 |  |  |  |  |  |  | #define INLINE_STRUCT_KEYS_$struct(_IS_src,_IS_targ) \\ | 
| 109 |  |  |  |  |  |  | av_clear(_IS_targ); \\ | 
| 110 |  |  |  |  |  |  | END | 
| 111 |  |  |  |  |  |  |  | 
| 112 | 19 |  |  |  |  | 36 | my $maxi = scalar @{$parser->{data}{struct}{$struct}{fields}}; | 
|  | 19 |  |  |  |  | 53 |  | 
| 113 | 19 | 50 |  |  |  | 86 | next unless $maxi > 0; | 
| 114 |  |  |  |  |  |  |  | 
| 115 | 19 |  |  |  |  | 262 | $o->{STRUCT}{'.xs'} .= < | 
| 116 |  |  |  |  |  |  |  | 
| 117 |  |  |  |  |  |  | MODULE = $o->{API}{module}		PACKAGE = Inline::Struct::$struct | 
| 118 |  |  |  |  |  |  |  | 
| 119 |  |  |  |  |  |  | PROTOTYPES: DISABLE | 
| 120 |  |  |  |  |  |  |  | 
| 121 |  |  |  |  |  |  | $cname * | 
| 122 |  |  |  |  |  |  | new(klass, ...) | 
| 123 |  |  |  |  |  |  | char *klass | 
| 124 |  |  |  |  |  |  | PREINIT: | 
| 125 |  |  |  |  |  |  | int _items = items - 1; | 
| 126 |  |  |  |  |  |  | CODE: | 
| 127 |  |  |  |  |  |  | NEW_INLINE_STRUCT(RETVAL,$struct); | 
| 128 |  |  |  |  |  |  | if (_items == 0) { } | 
| 129 |  |  |  |  |  |  | else { | 
| 130 |  |  |  |  |  |  | INLINE_STRUCT_INIT_LIST(RETVAL,$struct); | 
| 131 |  |  |  |  |  |  | } | 
| 132 |  |  |  |  |  |  | OUTPUT: | 
| 133 |  |  |  |  |  |  | RETVAL | 
| 134 |  |  |  |  |  |  |  | 
| 135 |  |  |  |  |  |  | void | 
| 136 |  |  |  |  |  |  | DESTROY(object) | 
| 137 |  |  |  |  |  |  | $cname *object | 
| 138 |  |  |  |  |  |  | PREINIT: | 
| 139 |  |  |  |  |  |  | HV *map = get_hv("Inline::Struct::${struct}::_map_", 1); | 
| 140 |  |  |  |  |  |  | SV *lookup; | 
| 141 |  |  |  |  |  |  | STRLEN klen; | 
| 142 |  |  |  |  |  |  | char *key; | 
| 143 |  |  |  |  |  |  | CODE: | 
| 144 |  |  |  |  |  |  | ENTER; | 
| 145 |  |  |  |  |  |  | SAVETMPS; | 
| 146 |  |  |  |  |  |  | lookup = newSViv((IV)object); | 
| 147 |  |  |  |  |  |  | key = SvPV(lookup, klen); | 
| 148 |  |  |  |  |  |  | sv_2mortal(lookup); | 
| 149 |  |  |  |  |  |  | if (hv_exists(map, key, klen)) { | 
| 150 |  |  |  |  |  |  | HV *info = (HV*)SvRV(*hv_fetch(map, key, klen, 0)); | 
| 151 |  |  |  |  |  |  | SV *refcnt = *hv_fetch(info, "REFCNT", 6, 0); | 
| 152 |  |  |  |  |  |  | int tofree = SvIV(*hv_fetch(info, "FREE", 4, 0)); | 
| 153 |  |  |  |  |  |  | if (tofree && SvIV(refcnt) == 1) { | 
| 154 |  |  |  |  |  |  | Safefree(object); | 
| 155 |  |  |  |  |  |  | hv_delete(map, key, klen, 0); | 
| 156 |  |  |  |  |  |  | } | 
| 157 |  |  |  |  |  |  | else | 
| 158 |  |  |  |  |  |  | sv_dec(refcnt); | 
| 159 |  |  |  |  |  |  | } | 
| 160 |  |  |  |  |  |  | FREETMPS; | 
| 161 |  |  |  |  |  |  | LEAVE; | 
| 162 |  |  |  |  |  |  |  | 
| 163 |  |  |  |  |  |  | HV * | 
| 164 |  |  |  |  |  |  | _HASH(object) | 
| 165 |  |  |  |  |  |  | $cname *object | 
| 166 |  |  |  |  |  |  | CODE: | 
| 167 |  |  |  |  |  |  | RETVAL = newHV(); | 
| 168 |  |  |  |  |  |  | INLINE_STRUCT_HASH(object, RETVAL, $struct); | 
| 169 |  |  |  |  |  |  | OUTPUT: | 
| 170 |  |  |  |  |  |  | RETVAL | 
| 171 |  |  |  |  |  |  |  | 
| 172 |  |  |  |  |  |  | AV * | 
| 173 |  |  |  |  |  |  | _VALUES(object) | 
| 174 |  |  |  |  |  |  | $cname *object | 
| 175 |  |  |  |  |  |  | CODE: | 
| 176 |  |  |  |  |  |  | RETVAL = newAV(); | 
| 177 |  |  |  |  |  |  | INLINE_STRUCT_VALUES(object, RETVAL, $struct); | 
| 178 |  |  |  |  |  |  | OUTPUT: | 
| 179 |  |  |  |  |  |  | RETVAL | 
| 180 |  |  |  |  |  |  |  | 
| 181 |  |  |  |  |  |  | AV * | 
| 182 |  |  |  |  |  |  | _ARRAY(object) | 
| 183 |  |  |  |  |  |  | $cname *object | 
| 184 |  |  |  |  |  |  | CODE: | 
| 185 |  |  |  |  |  |  | RETVAL = newAV(); | 
| 186 |  |  |  |  |  |  | INLINE_STRUCT_ARRAY(object, RETVAL, $struct); | 
| 187 |  |  |  |  |  |  | OUTPUT: | 
| 188 |  |  |  |  |  |  | RETVAL | 
| 189 |  |  |  |  |  |  |  | 
| 190 |  |  |  |  |  |  | AV * | 
| 191 |  |  |  |  |  |  | _KEYS(object) | 
| 192 |  |  |  |  |  |  | $cname *object | 
| 193 |  |  |  |  |  |  | CODE: | 
| 194 |  |  |  |  |  |  | RETVAL = newAV(); | 
| 195 |  |  |  |  |  |  | INLINE_STRUCT_KEYS(object, RETVAL, $struct); | 
| 196 |  |  |  |  |  |  | OUTPUT: | 
| 197 |  |  |  |  |  |  | RETVAL | 
| 198 |  |  |  |  |  |  |  | 
| 199 |  |  |  |  |  |  | END | 
| 200 |  |  |  |  |  |  |  | 
| 201 | 19 |  |  |  |  | 40 | my $i=1; | 
| 202 | 19 |  |  |  |  | 37 | for my $field (@{$parser->{data}{struct}{$struct}{fields}}) { | 
|  | 19 |  |  |  |  | 66 |  | 
| 203 | 41 |  |  |  |  | 97 | my $flen = length $field; | 
| 204 | 41 |  |  |  |  | 128 | my $type = $parser->{data}{struct}{$struct}{field}{$field}; | 
| 205 | 41 | 100 |  |  |  | 126 | my $q = ($i == 1 ? 'if' : 'else if'); | 
| 206 | 41 |  |  |  |  | 163 | my $t = | 
| 207 |  |  |  |  |  |  | typeconv($o, "_IS_targ->$field", | 
| 208 |  |  |  |  |  |  | "val", | 
| 209 |  |  |  |  |  |  | $type, | 
| 210 |  |  |  |  |  |  | "input_expr", | 
| 211 |  |  |  |  |  |  | 1, | 
| 212 |  |  |  |  |  |  | '_KEYS', | 
| 213 |  |  |  |  |  |  | ); | 
| 214 | 41 |  |  |  |  | 154 | my $s = | 
| 215 |  |  |  |  |  |  | typeconv($o, "_IS_src->$field", | 
| 216 |  |  |  |  |  |  | "tmp", | 
| 217 |  |  |  |  |  |  | $type, | 
| 218 |  |  |  |  |  |  | "output_expr", | 
| 219 |  |  |  |  |  |  | 1, | 
| 220 |  |  |  |  |  |  | '_KEYS', | 
| 221 |  |  |  |  |  |  | ); | 
| 222 | 41 |  |  |  |  | 211 | $INITL .= | 
| 223 |  |  |  |  |  |  | (typeconv($o, "_IS_targ->$field", | 
| 224 |  |  |  |  |  |  | "ST($i)", | 
| 225 |  |  |  |  |  |  | $type, | 
| 226 |  |  |  |  |  |  | "input_expr", | 
| 227 |  |  |  |  |  |  | 1, | 
| 228 |  |  |  |  |  |  | '_KEYS', | 
| 229 |  |  |  |  |  |  | ) . | 
| 230 |  |  |  |  |  |  | "; \\\n"); | 
| 231 | 41 | 100 |  |  |  | 312 | $HASH .= (qq{{\\\n\tSV*tmp=newSViv(0);\\\n$s \\ | 
| 232 |  |  |  |  |  |  | \thv_store(_IS_targ, "$field", $flen, tmp, 0); \\\n}} . | 
| 233 |  |  |  |  |  |  | ($i == $maxi ? "" : "\\") . | 
| 234 |  |  |  |  |  |  | "\n" | 
| 235 |  |  |  |  |  |  | ); | 
| 236 | 41 | 100 |  |  |  | 170 | $ARRAY .= (qq{{\\\n\tSV*tmp=newSViv(0);\\\n$s \\ | 
| 237 |  |  |  |  |  |  | \tav_push(_IS_targ, tmp); \\\n}} . | 
| 238 |  |  |  |  |  |  | ($i == $maxi ? "" : "\\") . | 
| 239 |  |  |  |  |  |  | "\n" | 
| 240 |  |  |  |  |  |  | ); | 
| 241 | 41 | 100 |  |  |  | 154 | $KEYS .= (qq{av_push(_IS_targ, newSVpv("$field", 0));} . | 
| 242 |  |  |  |  |  |  | ($i == $maxi ? "" : "\\") . | 
| 243 |  |  |  |  |  |  | "\n" | 
| 244 |  |  |  |  |  |  | ); | 
| 245 | 41 |  |  |  |  | 108 | my $is_sv = $type =~ /^SV\s*\*$/; | 
| 246 | 41 |  |  |  |  | 141 | $o->{STRUCT}{'.xs'} .= < | 
| 247 |  |  |  |  |  |  | void | 
| 248 |  |  |  |  |  |  | $field(object, ...) | 
| 249 |  |  |  |  |  |  | $cname *object | 
| 250 |  |  |  |  |  |  | PREINIT: | 
| 251 |  |  |  |  |  |  | SV *retval = newSViv(0); | 
| 252 |  |  |  |  |  |  | int mortalise_retval = 0; | 
| 253 |  |  |  |  |  |  | PPCODE: | 
| 254 |  |  |  |  |  |  | ENTER; | 
| 255 |  |  |  |  |  |  | SAVETMPS; | 
| 256 |  |  |  |  |  |  | if (items == 1) { | 
| 257 | 41 |  |  |  |  | 129 | @{[typeconv($o, "object->$field", "retval", $type, "output_expr", undef, $field)]} | 
| 258 |  |  |  |  |  |  | @{[ | 
| 259 |  |  |  |  |  |  | # mortalise if not an SV * | 
| 260 | 41 | 100 |  |  |  | 177 | $is_sv ? '' : 'mortalise_retval = 1;' | 
| 261 |  |  |  |  |  |  | ]} | 
| 262 |  |  |  |  |  |  | } | 
| 263 |  |  |  |  |  |  | else { | 
| 264 |  |  |  |  |  |  | @{[ | 
| 265 | 41 | 100 |  |  |  | 155 | $is_sv ? | 
| 266 |  |  |  |  |  |  | qq{if (object->$field && SvOK(object->$field)) { | 
| 267 |  |  |  |  |  |  | SvREFCNT_dec(object->$field); | 
| 268 |  |  |  |  |  |  | }} : "" | 
| 269 |  |  |  |  |  |  | ]} | 
| 270 | 41 |  |  |  |  | 136 | @{[typeconv($o, "object->$field", "ST(1)", $type, "input_expr", undef, $field)]}; | 
| 271 |  |  |  |  |  |  | @{[ | 
| 272 | 41 | 100 |  |  |  | 186 | $is_sv ? | 
| 273 |  |  |  |  |  |  | qq{if (object->$field && SvOK(object->$field)) { | 
| 274 |  |  |  |  |  |  | SvREFCNT_inc(object->$field); | 
| 275 |  |  |  |  |  |  | }} : "" | 
| 276 |  |  |  |  |  |  | ]} | 
| 277 | 41 |  |  |  |  | 141 | @{[typeconv($o, "object", "retval", "$cname *", "output_expr", undef, $field)]}; | 
| 278 |  |  |  |  |  |  | mortalise_retval = 1; | 
| 279 |  |  |  |  |  |  | } | 
| 280 |  |  |  |  |  |  | FREETMPS; | 
| 281 |  |  |  |  |  |  | LEAVE; | 
| 282 |  |  |  |  |  |  | if (mortalise_retval) sv_2mortal(retval); | 
| 283 |  |  |  |  |  |  | XPUSHs(retval); | 
| 284 |  |  |  |  |  |  |  | 
| 285 |  |  |  |  |  |  | EOF | 
| 286 | 41 |  |  |  |  | 202 | $i++; | 
| 287 |  |  |  |  |  |  | } | 
| 288 | 19 |  |  |  |  | 53 | $INITL .= "}\n"; | 
| 289 |  |  |  |  |  |  |  | 
| 290 | 19 |  |  |  |  | 178 | $o->{STRUCT}{'.macros'} .= < | 
| 291 |  |  |  |  |  |  | $NEW | 
| 292 |  |  |  |  |  |  | $FIELDS | 
| 293 |  |  |  |  |  |  | $INITL | 
| 294 |  |  |  |  |  |  | $HASH | 
| 295 |  |  |  |  |  |  | $ARRAY | 
| 296 |  |  |  |  |  |  | $KEYS | 
| 297 |  |  |  |  |  |  | END | 
| 298 |  |  |  |  |  |  |  | 
| 299 |  |  |  |  |  |  | } | 
| 300 |  |  |  |  |  |  |  | 
| 301 |  |  |  |  |  |  | # Write a typemap file containing typemaps for each thingy | 
| 302 | 15 |  |  |  |  | 86 | write_typemap($o); | 
| 303 |  |  |  |  |  |  | } | 
| 304 |  |  |  |  |  |  |  | 
| 305 |  |  |  |  |  |  | sub write_typemap { | 
| 306 | 15 |  |  | 15 | 0 | 38 | my $o = shift; | 
| 307 | 15 |  |  |  |  | 47 | my $data = $o->{STRUCT}{'.parser'}{data}; | 
| 308 |  |  |  |  |  |  |  | 
| 309 | 15 |  |  |  |  | 110 | my ($TYPEMAP, $INPUT, $OUTPUT); | 
| 310 | 15 |  |  |  |  | 53 | for my $struct (@{$data->{structs}}) { | 
|  | 15 |  |  |  |  | 56 |  | 
| 311 | 19 |  |  |  |  | 60 | my $type = "O_OBJECT_$struct"; | 
| 312 | 1011 |  |  |  |  | 1875 | my @ctypes = grep { $data->{typeconv}{type_kind}{$_} eq $type } | 
| 313 | 19 |  |  |  |  | 76 | keys %{$data->{typeconv}{type_kind}}; | 
|  | 19 |  |  |  |  | 245 |  | 
| 314 | 19 |  |  |  |  | 130 | $TYPEMAP .= join "", map { "$_\t\t$type\n" } @ctypes; | 
|  | 26 |  |  |  |  | 118 |  | 
| 315 | 19 |  |  |  |  | 94 | $INPUT .= $type."\n".$data->{typeconv}{input_expr}{$type}; | 
| 316 | 19 |  |  |  |  | 107 | $OUTPUT .= $type."\n".$data->{typeconv}{output_expr}{$type}; | 
| 317 |  |  |  |  |  |  | } | 
| 318 |  |  |  |  |  |  |  | 
| 319 |  |  |  |  |  |  | $o->mkpath($o->{API}{build_dir}) | 
| 320 | 15 | 50 |  |  |  | 906 | unless -d $o->{API}{build_dir}; | 
| 321 | 15 |  |  |  |  | 51 | my $fh; | 
| 322 | 15 |  |  |  |  | 80 | my $fname = $o->{API}{build_dir}.'/Struct.map'; | 
| 323 | 15 | 50 |  |  |  | 2610 | open $fh, ">$fname" | 
| 324 |  |  |  |  |  |  | or die $!; | 
| 325 | 15 |  |  |  |  | 235 | print $fh < | 
| 326 |  |  |  |  |  |  | TYPEMAP | 
| 327 |  |  |  |  |  |  | $TYPEMAP | 
| 328 |  |  |  |  |  |  | INPUT | 
| 329 |  |  |  |  |  |  | $INPUT | 
| 330 |  |  |  |  |  |  |  | 
| 331 |  |  |  |  |  |  | OUTPUT | 
| 332 |  |  |  |  |  |  | $OUTPUT | 
| 333 |  |  |  |  |  |  | END | 
| 334 |  |  |  |  |  |  |  | 
| 335 | 15 |  |  |  |  | 1385 | close $fh; | 
| 336 | 15 |  |  |  |  | 177 | $o->validate( TYPEMAPS => $fname ); | 
| 337 |  |  |  |  |  |  | } | 
| 338 |  |  |  |  |  |  |  | 
| 339 |  |  |  |  |  |  | sub typeconv { | 
| 340 | 246 |  |  | 246 | 0 | 393 | my $o = shift; | 
| 341 | 246 |  |  |  |  | 357 | my $var = shift; | 
| 342 | 246 |  |  |  |  | 344 | my $arg = shift; | 
| 343 | 246 |  |  |  |  | 334 | my $type = shift; | 
| 344 | 246 |  |  |  |  | 328 | my $dir = shift; | 
| 345 | 246 |  |  |  |  | 325 | my $preproc = shift; | 
| 346 | 246 |  |  |  |  | 336 | my $pname = shift; | 
| 347 | 246 |  |  |  |  | 566 | my $tkind = $o->{ILSM}{typeconv}{type_kind}{$type}; | 
| 348 | 246 | 50 |  |  |  | 535 | die "Error: unknown type '$type'" if !$tkind; | 
| 349 | 246 |  |  |  |  | 637 | my $compile = qq{qq{$o->{ILSM}{typeconv}{$dir}{$tkind}}}; | 
| 350 | 246 |  |  |  |  | 13404 | my $ret = eval $compile; | 
| 351 | 246 | 50 |  |  |  | 956 | die "Error while compiling: >>>$compile<<<\n$@" if $@; | 
| 352 | 246 |  |  |  |  | 456 | chomp $ret; | 
| 353 | 246 | 100 |  |  |  | 546 | $ret =~ s/\n/\\\n/g if $preproc; | 
| 354 | 246 |  |  |  |  | 1015 | return $ret; | 
| 355 |  |  |  |  |  |  | } | 
| 356 |  |  |  |  |  |  |  | 
| 357 |  |  |  |  |  |  | #============================================================================= | 
| 358 |  |  |  |  |  |  | # Return a little info about the structs we bound to. | 
| 359 |  |  |  |  |  |  | #============================================================================= | 
| 360 |  |  |  |  |  |  | sub info { | 
| 361 | 0 |  |  | 0 | 0 |  | my $o = shift; | 
| 362 | 0 |  |  |  |  |  | my $info = ""; | 
| 363 | 0 | 0 |  |  |  |  | parse($o) unless defined $o->{STRUCT}{'.parser'}; | 
| 364 | 0 |  |  |  |  |  | my $data = $o->{STRUCT}{'.parser'}{data}; | 
| 365 | 0 | 0 |  |  |  |  | if (defined $o->{STRUCT}{'.bound'}) { | 
| 366 | 0 |  |  |  |  |  | $info .= "The following structs have been bound to Perl:\n"; | 
| 367 | 0 |  |  |  |  |  | for my $struct (keys %{$o->{STRUCT}{'.bound'}}) { | 
|  | 0 |  |  |  |  |  |  | 
| 368 | 0 |  |  |  |  |  | $info .= "\tstruct $struct {\n"; | 
| 369 | 0 |  |  |  |  |  | for my $field (@{$data->{struct}{$struct}{fields}}) { | 
|  | 0 |  |  |  |  |  |  | 
| 370 | 0 |  |  |  |  |  | my $type = $data->{struct}{$struct}{field}{$field}; | 
| 371 | 0 |  |  |  |  |  | $info .= "\t\t$type $field;\n"; | 
| 372 |  |  |  |  |  |  | } | 
| 373 | 0 |  |  |  |  |  | $info .= "\t};\n"; | 
| 374 |  |  |  |  |  |  | } | 
| 375 |  |  |  |  |  |  | } | 
| 376 |  |  |  |  |  |  | else { | 
| 377 | 0 |  |  |  |  |  | $info .= "No structs were bound to Perl.\n"; | 
| 378 |  |  |  |  |  |  | } | 
| 379 | 0 |  |  |  |  |  | return $info; | 
| 380 |  |  |  |  |  |  | } | 
| 381 |  |  |  |  |  |  |  | 
| 382 |  |  |  |  |  |  | 1; | 
| 383 |  |  |  |  |  |  |  | 
| 384 |  |  |  |  |  |  | __END__ |