File Coverage

blib/lib/CORBA/XS/CVisitor.pm
Criterion Covered Total %
statement 12 270 4.4
branch 0 34 0.0
condition 0 3 0.0
subroutine 4 28 14.2
pod 0 22 0.0
total 16 357 4.4


line stmt bran cond sub pod time code
1            
2             #
3             # Interface Definition Language (OMG IDL CORBA v3.0)
4             #
5            
6             package CORBA::XS::CVisitor;
7            
8 1     1   6 use strict;
  1         2  
  1         35  
9 1     1   3 use warnings;
  1         2  
  1         37  
10            
11             our $VERSION = '0.62';
12            
13 1     1   4 use File::Basename;
  1         2  
  1         122  
14 1     1   870 use POSIX qw(ctime);
  1         7062  
  1         5  
15            
16             sub new {
17 0     0 0   my $proto = shift;
18 0   0       my $class = ref($proto) || $proto;
19 0           my $self = {};
20 0           bless $self, $class;
21 0           my($parser) = @_;
22 0           $self->{srcname} = $parser->YYData->{srcname};
23 0           $self->{srcname_size} = $parser->YYData->{srcname_size};
24 0           $self->{srcname_mtime} = $parser->YYData->{srcname_mtime};
25 0           $self->{symbtab} = $parser->YYData->{symbtab};
26 0           $self->{modules} = [ @{$parser->YYData->{modules}} ];
  0            
27 0           $self->{inc} = {};
28 0           $self->{has_methods} = 0;
29 0           $self->{num_key} = 'num_xs_c';
30 0           return $self;
31             }
32            
33             sub open_stream {
34 0     0 0   my $self = shift;
35 0           my($filename) = @_;
36 0 0         open $self->{out}, '>', $filename
37             or die "can't open $filename ($!).\n";
38 0           $self->{filename} = $filename;
39             }
40            
41             sub _insert_inc {
42 0     0     my $self = shift;
43 0           my($filename) = @_;
44 0           my $FH = $self->{out};
45 0 0         if (! exists $self->{inc}->{$filename}) {
46 0           $self->{inc}->{$filename} = 1;
47 0           $filename = basename($filename, '.idl') . '.h';
48 0           print $FH "#include \"",$filename,"\"\n";
49             }
50             }
51            
52             sub _get_defn {
53 0     0     my $self = shift;
54 0           my($defn) = @_;
55 0 0         if (ref $defn) {
56 0           return $defn;
57             }
58             else {
59 0           return $self->{symbtab}->Lookup($defn);
60             }
61             }
62            
63             #
64             # 3.5 OMG IDL Specification
65             #
66            
67             sub visitSpecification {
68 0     0 0   my $self = shift;
69 0           my($node) = @_;
70 0           my $src_name = basename($self->{srcname}, '.idl');
71 0           $self->open_stream($src_name . '.c');
72 0           my $FH = $self->{out};
73 0           print $FH "/* ex: set ro: */\n";
74 0           print $FH "/* This file was generated (by ",$0,"). DO NOT modify it */\n";
75 0           print $FH "/*\n";
76 0           print $FH " * From file : ",$self->{srcname},", ",$self->{srcname_size}," octets, ",POSIX::ctime($self->{srcname_mtime});
77 0           print $FH " */\n";
78 0           print $FH "\n";
79 0           print $FH "#include \"EXTERN.h\"\n";
80 0           print $FH "#include \"perl.h\"\n";
81 0           print $FH "#include \"XSUB.h\"\n";
82 0           print $FH "\n";
83 0           $self->{newXS} = q{};
84 0           foreach (@{$node->{list_decl}}) {
  0            
85 0           $self->_get_defn($_)->visit($self);
86             }
87 0           print $FH "#ifdef __cplusplus\n";
88 0           print $FH "extern \"C\"\n";
89 0           print $FH "#endif\n";
90 0           print $FH "XS(boot_",$src_name,")\n";
91 0           print $FH "{\n";
92 0           print $FH " dXSARGS;\n";
93 0           print $FH " char* file = __FILE__;\n";
94 0           print $FH "\n";
95 0           print $FH " XS_VERSION_BOOTCHECK ;\n";
96 0           print $FH "\n";
97 0           print $FH $self->{newXS};
98 0           print $FH " XSRETURN_YES;\n";
99 0           print $FH "}\n";
100 0           print $FH "\n";
101 0           print $FH "/* end of file : ",$self->{filename}," */\n";
102 0           print $FH "\n";
103 0           print $FH "/*\n";
104 0           print $FH " * Local variables:\n";
105 0           print $FH " * buffer-read-only: t\n";
106 0           print $FH " * End:\n";
107 0           print $FH " */\n";
108 0           close $FH;
109 0 0         unless ($self->{has_methods}) {
110 0 0         unlink $self->{filename}
111             or die "can't delete $self->{filename} ($!).\n";
112 0           return;
113             }
114            
115 0           my $filename = 'Makefile.PL';
116 0 0         open my $OUT, '>', $filename
117             or die "can't open $filename ($!).\n";
118 0           print $OUT "use ExtUtils::MakeMaker;\n";
119 0           print $OUT "# See lib/ExtUtils/MakeMaker.pm for details of how to influence\n";
120 0           print $OUT "# the contents of the Makefile that is written.\n";
121 0           print $OUT "WriteMakefile(\n";
122 0           print $OUT " 'NAME' => '",$src_name,"',\n";
123 0           print $OUT " 'VERSION_FROM' => '",$src_name,".pm', # finds \$VERSION\n";
124 0           print $OUT " 'PREREQ_PM' => {\n";
125 0           print $OUT " 'Error' => 0,\n";
126 0           print $OUT " 'CORBA::Perl::CORBA' => 0\n";
127 0           print $OUT " },\n";
128 0           print $OUT " 'LIBS' => [''], # e.g., '-lm'\n";
129 0           print $OUT " 'DEFINE' => '', # e.g., '-DHAVE_SOMETHING'\n";
130 0           print $OUT " 'INC' => '', # e.g., '-I/usr/include/other'\n";
131 0           print $OUT " 'MYEXTLIB' => 'cdr_",$src_name,"\$(OBJ_EXT) skel_",$src_name,"\$(OBJ_EXT) corba\$(OBJ_EXT)',\n";
132 0           print $OUT " 'PM' => {\n";
133 0           foreach (@{$self->{modules}}) {
  0            
134 0           print $OUT " '",$_,".pm' => '\$(INST_LIBDIR)/",$_,".pm',\n";
135             }
136 0           print $OUT " '",$src_name,".pm' => '\$(INST_LIBDIR)/",$src_name,".pm'\n";
137 0           print $OUT " },\n";
138 0           print $OUT ");\n";
139 0           close $OUT;
140            
141 0           $filename = 'MANIFEST';
142 0 0         open $OUT, '>', $filename
143             or die "can't open $filename ($!).\n";
144 0           foreach (@{$self->{modules}}) {
  0            
145 0           print $OUT $_,".pm\n";
146 0           print $OUT $_,".h\n";
147             }
148 0           print $OUT $src_name,".pm\n";
149 0           print $OUT $src_name,".c\n";
150 0           print $OUT $src_name,".h\n";
151 0           print $OUT "cdr_",$src_name,".c\n";
152 0           print $OUT "skel_",$src_name,".c\n";
153 0           print $OUT "corba.c\n";
154 0           print $OUT "Changes\n";
155 0           print $OUT "Makefile.PL\n";
156 0           print $OUT "MANIFEST\n";
157 0           print $OUT "test.pl\n";
158 0           close $OUT;
159            
160 0           $filename = 'Changes';
161 0 0         open $OUT, '>', $filename
162             or die "can't open $filename ($!).\n";
163 0           print $OUT "Revision history for Perl extension ",$src_name,".\n";
164 0           print $OUT "\n";
165 0           print $OUT "0.01 ",POSIX::ctime(time());
166 0           print $OUT "\t- original version; created by idl2xs_c\n";
167 0           print $OUT "\t\tfrom ",$self->{srcname},", ",$self->{srcname_size}," octets, ",POSIX::ctime($self->{srcname_mtime});
168 0           close $OUT;
169            
170 0           $filename = 'test.pl';
171 0 0         open $OUT, '>', $filename
172             or die "can't open $filename ($!).\n";
173 0           print $OUT "# Before `make install' is performed this script should be runnable with\n";
174 0           print $OUT "# `make test'. After `make install' it should work as `perl test.pl'\n";
175 0           print $OUT "\n";
176 0           print $OUT "######################### We start with some black magic to print on failure.\n";
177 0           print $OUT "\n";
178 0           print $OUT "# Change 1..1 below to 1..last_test_to_print .\n";
179 0           print $OUT "# (It may become useful if the test is moved to ./t subdirectory.)\n";
180 0           print $OUT "\n";
181 0           print $OUT "BEGIN { \$| = 1; print \"1..1\\n\"; }\n";
182 0           print $OUT "END {print \"not ok 1\\n\" unless \$loaded;}\n";
183 0           print $OUT "use ",$src_name,";\n";
184 0           print $OUT "\$loaded = 1;\n";
185 0           print $OUT "print \"ok 1\\n\";\n";
186 0           print $OUT "\n";
187 0           print $OUT "######################### End of black magic.\n";
188 0           print $OUT "\n";
189 0           print $OUT "# Insert your test code below (better if it prints \"ok 13\"\n";
190 0           print $OUT "# (correspondingly \"not ok 13\") depending on the success of chunk 13\n";
191 0           print $OUT "# of the test code):\n";
192 0           close $OUT;
193            
194 0           my $path = $INC{'CORBA/XS/CVisitor.pm'};
195 0           $path =~ s/CVisitor\.pm$//i;
196 0           $path .= 'corba.c';
197 0 0         open my $IN, '<', $path
198             or die "can't read $path ($!)";
199 0           $filename = 'corba.c';
200 0 0         open $OUT, '>', $filename
201             or die "can't open $filename ($!).\n";
202 0           while (<$IN>) {
203 0           print $OUT $_;
204             }
205 0           close $OUT;
206 0           close $IN;
207            
208 0           do 'Makefile.PL';
209             }
210            
211             #
212             # 3.7 Module Declaration
213             #
214            
215             sub visitModules {
216 0     0 0   my $self = shift;
217 0           my($node) = @_;
218 0 0         unless (exists $node->{$self->{num_key}}) {
219 0           $node->{$self->{num_key}} = 0;
220             }
221 0           my $module = ${$node->{list_decl}}[$node->{$self->{num_key}}];
  0            
222 0           $module->visit($self);
223 0           $node->{$self->{num_key}} ++;
224             }
225            
226             sub visitModule {
227 0     0 0   my $self = shift;
228 0           my($node) = @_;
229 0           my $FH = $self->{out};
230 0 0         if ($self->{srcname} eq $node->{filename}) {
231 0           foreach (@{$node->{list_decl}}) {
  0            
232 0           $self->_get_defn($_)->visit($self);
233             }
234             }
235             else {
236 0           $self->_insert_inc($node->{filename});
237             }
238             }
239            
240             #
241             # 3.8 Interface Declaration
242             #
243            
244             sub visitRegularInterface {
245 0     0 0   my $self = shift;
246 0           my($node) = @_;
247 0 0         if ($self->{srcname} eq $node->{filename}) {
248 0           $self->{itf} = $node->{c_name};
249 0           my $FH = $self->{out};
250 0           print $FH "/* interface ",$node->{pl_name}," */\n";
251 0           print $FH "\n";
252 0           foreach (values %{$node->{hash_attribute_operation}}) {
  0            
253 0           $self->_get_defn($_)->visit($self);
254             }
255             }
256             }
257            
258             sub visitAbstractInterface {
259 0     0 0   my $self = shift;
260 0           my($node) = @_;
261 0 0         if ($self->{srcname} eq $node->{filename}) {
262 0           $self->{itf} = $node->{c_name};
263 0           my $FH = $self->{out};
264 0           print $FH "/* abstract interface ",$node->{pl_name}," */\n";
265 0           print $FH "\n";
266 0           foreach (values %{$node->{hash_attribute_operation}}) {
  0            
267 0           $self->_get_defn($_)->visit($self);
268             }
269             }
270             }
271            
272 0     0 0   sub visitForwardRegularInterface {
273             # empty
274             }
275            
276 0     0 0   sub visitForwardAbstractInterface {
277             # empty
278             }
279            
280 0     0 0   sub visitBaseInterface {
281             # C mapping is aligned with CORBA 2.1
282             }
283            
284 0     0 0   sub visitForwardBaseInterface {
285             # C mapping is aligned with CORBA 2.1
286             }
287            
288             #
289             # 3.10 Constant Declaration
290             #
291            
292 0     0 0   sub visitConstant {
293             # empty
294             }
295            
296             #
297             # 3.11 Type Declaration
298             #
299            
300 0     0 0   sub visitTypeDeclarators {
301             # empty
302             }
303            
304 0     0 0   sub visitNativeType {
305             # empty
306             }
307            
308             #
309             # 3.11.2 Constructed Types
310             #
311            
312 0     0 0   sub visitStructType {
313             # empty
314             }
315            
316 0     0 0   sub visitUnionType {
317             # empty
318             }
319            
320 0     0 0   sub visitForwardStructType {
321             # empty
322             }
323            
324 0     0 0   sub visitForwardUnionType {
325             # empty
326             }
327            
328 0     0 0   sub visitEnumType {
329             # empty
330             }
331            
332             #
333             # 3.12 Exception Declaration
334             #
335            
336 0     0 0   sub visitException {
337             # empty
338             }
339            
340             #
341             # 3.13 Operation Declaration
342             #
343            
344             sub visitOperation {
345 0     0 0   my $self = shift;
346 0           my($node) = @_;
347 0           my $FH = $self->{out};
348 0           $self->{has_methods} = 1;
349 0           my $c_package = $node->{pl_package};
350 0           $c_package =~ s/::/_/g;
351 0 0         if (exists $node->{modifier}) { # oneway
352 0           print $FH "extern void cdr_",$self->{itf},"_",$node->{c_name},"(void * ref, char *is);\n";
353 0           print $FH "\n";
354 0           print $FH "XS(XS_",$c_package,"_cdr_",$node->{pl_name},")\n";
355 0           print $FH "{\n";
356 0           print $FH " dXSARGS;\n";
357 0           print $FH " if (items != 2)\n";
358 0           print $FH " Perl_croak(aTHX_ \"Usage: ",$node->{pl_package},"::cdr_",$node->{pl_name},"(ref, is)\");\n";
359 0           print $FH " {\n";
360 0           print $FH " void * ref = (void *)SvIV(ST(0));\n";
361 0           print $FH " char * is = (char *)SvPV(ST(1),PL_na);\n";
362 0           print $FH " dXSTARG;\n";
363 0           print $FH " cdr_",$self->{itf},"_",$node->{c_name},"(ref, is);\n";
364 0           print $FH " XSprePUSH; PUSHi((IV)0);\n";
365 0           print $FH " }\n";
366 0           print $FH " XSRETURN(1);\n";
367 0           print $FH "}\n";
368 0           print $FH "\n";
369             }
370             else {
371 0           print $FH "extern int cdr_",$self->{itf},"_",$node->{c_name},"(void * ref, char *is, char **os);\n";
372 0           print $FH "\n";
373 0           print $FH "XS(XS_",$c_package,"_cdr_",$node->{pl_name},")\n";
374 0           print $FH "{\n";
375 0           print $FH " dXSARGS;\n";
376 0           print $FH " if (items != 3)\n";
377 0           print $FH " Perl_croak(aTHX_ \"Usage: ",$node->{pl_package},"::cdr_",$node->{pl_name},"(ref, is, os)\");\n";
378 0           print $FH " {\n";
379 0           print $FH " void * ref = (void *)SvIV(ST(0));\n";
380 0           print $FH " char * is = (char *)SvPV(ST(1),PL_na);\n";
381 0           print $FH " char * os;\n";
382 0           print $FH " int size;\n";
383 0           print $FH " dXSTARG;\n";
384 0           print $FH " size = cdr_",$self->{itf},"_",$node->{c_name},"(ref, is, &os);\n";
385 0           print $FH " if (size >= 0)\n";
386 0           print $FH " sv_setpvn((SV*)ST(2), os, size);\n";
387 0           print $FH " SvSETMAGIC(ST(2));\n";
388 0           print $FH " XSprePUSH; PUSHi((IV)size);\n";
389 0           print $FH " }\n";
390 0           print $FH " XSRETURN(1);\n";
391 0           print $FH "}\n";
392 0           print $FH "\n";
393             }
394 0           $self->{newXS} .= " newXS(\"" . $node->{pl_package} . "::cdr_" . $node->{pl_name} . "\", XS_";
395 0           $self->{newXS} .= $c_package . "_cdr_" . $node->{pl_name} . ", file);\n";
396             }
397            
398             #
399             # 3.14 Attribute Declaration
400             #
401            
402             sub visitAttribute {
403 0     0 0   my $self = shift;
404 0           my($node) = @_;
405 0           $node->{_get}->visit($self);
406 0 0         $node->{_set}->visit($self) if (exists $node->{_set});
407             }
408            
409             1;
410