File Coverage

blib/lib/CORBA/Python/LiteralVisitor.pm
Criterion Covered Total %
statement 9 339 2.6
branch 0 114 0.0
condition 0 33 0.0
subroutine 3 53 5.6
pod 0 47 0.0
total 12 586 2.0


line stmt bran cond sub pod time code
1              
2             #
3             # Interface Definition Language (OMG IDL CORBA v3.0)
4             #
5             # Python Language Mapping Specification, Version 1.2 November 2002
6             #
7              
8             package CORBA::Python::LiteralVisitor;
9              
10 1     1   4 use strict;
  1         2  
  1         30  
11 1     1   5 use warnings;
  1         2  
  1         34  
12              
13             our $VERSION = '2.66';
14              
15 1     1   5 use File::Basename;
  1         12  
  1         4283  
16              
17             # builds $node->{py_literal}
18              
19             sub new {
20 0     0 0   my $proto = shift;
21 0   0       my $class = ref($proto) || $proto;
22 0           my $self = {};
23 0           bless $self, $class;
24 0           my ($parser, $server) = @_;
25 0           $self->{key} = 'py_literal';
26 0           $self->{srcname} = $parser->YYData->{srcname};
27 0           $self->{symbtab} = $parser->YYData->{symbtab};
28 0 0         if (exists $parser->YYData->{opt_J}) {
29 0           $self->{base_package} = $parser->YYData->{opt_J};
30             }
31             else {
32 0           $self->{base_package} = q{};
33             }
34 0 0         $self->{server} = 1 if (defined $server);
35 0           $self->{import_substitution} = {};
36 0           return $self;
37             }
38              
39             sub _get_defn {
40 0     0     my $self = shift;
41 0           my $defn = shift;
42 0 0         if (ref $defn) {
43 0           return $defn;
44             }
45             else {
46 0           return $self->{symbtab}->Lookup($defn);
47             }
48             }
49              
50             sub _get_scoped_name {
51 0     0     my $self = shift;
52 0           my ($node, $scope) = @_;
53 0           my $scope_full = $scope->{full};
54 0           $scope_full =~ s/::[0-9A-Z_a-z]+$//;
55 0           my $name = $node->{full};
56 0 0         if ($name =~ /^::[0-9A-Z_a-z]+$/) {
57 0 0         if ($scope_full) {
58 0           my $basename = basename($self->{srcname}, '.idl');
59 0           $basename =~ s/\./_/g;
60 0 0         if (exists $self->{server}) {
61 0           $name = '_' . $basename . '_skel.' . $node->{py_name};
62             }
63             else {
64 0           $name = '_' . $basename . '.' . $node->{py_name};
65             }
66             }
67             else {
68 0           $name = $node->{py_name};
69             }
70             }
71             else {
72 0 0         if ($scope_full) {
73 0 0         if ($scope->isa('Constant')) {
74 0           while ($name !~ /^$scope_full/) {
75 0           my $defn = $self->_get_defn($scope_full);
76 0 0         last if ($defn->isa('Modules'));
77 0           $scope_full =~ s/::[0-9A-Z_a-z]+$//;
78 0 0         last unless ($scope_full);
79             }
80             }
81             else {
82 0           my $defn = $self->_get_defn($scope_full);
83 0           while (!$defn->isa('Modules')) {
84 0           $scope_full =~ s/::[0-9A-Z_a-z]+$//;
85 0 0         last unless ($scope_full);
86 0           $defn = $self->_get_defn($scope_full);
87             }
88             }
89 0           $name =~ s/^$scope_full//;
90 0           $name =~ s/^:://;
91 0 0         if (exists $self->{server}) {
92 0           $name =~ s/::/_skel\./;
93             }
94 0           $name =~ s/::/\./g;
95 0 0         if ($self->{base_package}) {
96 0           my $import_name = $name;
97 0           $import_name =~ s/\.[0-9A-Z_a-z]+$//;
98 0 0         if (exists $self->{import_substitution}->{$import_name}) {
99 0           $name =~ s/$import_name/$self->{import_substitution}->{$import_name}/;
100             }
101             }
102             }
103             else {
104 0           my $name2 = $node->{py_name};
105 0           $name =~ s/::[0-9A-Z_a-z]+$//;
106 0           while ($name) {
107 0           my $defn = $self->{symbtab}->Lookup($name);
108 0 0 0       if ($defn->isa('Interface') and exists $self->{server}) {
109 0           $name2 = $defn->{py_name} . '_skel.' . $name2;
110             }
111             else {
112 0           $name2 = $defn->{py_name} . '.' . $name2;
113             }
114 0           $name =~ s/::[0-9A-Z_a-z]+$//;
115             }
116 0           $name = $name2;
117             }
118             }
119 0           return $name;
120             }
121              
122             #
123             # 3.5 OMG IDL Specification
124             #
125              
126             sub visitSpecification {
127 0     0 0   my $self = shift;
128 0           my ($node) = @_;
129 0 0         if (exists $node->{list_import}) {
130 0           foreach (@{$node->{list_import}}) {
  0            
131 0           $self->_get_defn($_)->visit($self);
132             }
133             }
134 0           foreach (@{$node->{list_export}}) {
  0            
135 0           $self->_get_defn($_)->visit($self);
136             }
137             }
138              
139             #
140             # 3.6 Import Declaration
141             #
142              
143             sub visitImport {
144 0     0 0   my $self = shift;
145 0           my ($node) = @_;
146 0           foreach (@{$node->{list_decl}}) {
  0            
147 0           $self->_get_defn($_)->visit($self);
148             }
149             }
150              
151             #
152             # 3.7 Module Declaration
153             #
154              
155             sub visitModules {
156 0     0 0   my $self = shift;
157 0           my ($node) = @_;
158 0           foreach my $name (sort keys %{$node->{py_import}}) {
  0            
159 0 0         next if ($name eq '::CORBA');
160 0 0         next if ($name eq '::IOP');
161 0 0         next if ($name eq '::GIOP');
162 0 0 0       unless ( $name eq '::' or $name eq q{} ) {
163 0           $name =~ s/^:://;
164 0 0         if (exists $self->{server}) {
165 0           $name =~ s/::/_skel\./g;
166 0           $name .= '_skel';
167             }
168             else {
169 0           $name =~ s/::/\./g;
170             }
171 0 0         if ($self->{base_package}) {
172 0           my $full_import_name = $self->{base_package} . '.' . $name;
173 0           $full_import_name =~ s/\//\./g;
174 0           $self->{import_substitution}->{$name} = $full_import_name;
175             }
176             }
177             }
178 0           foreach (@{$node->{list_export}}) {
  0            
179 0           $self->_get_defn($_)->visit($self);
180             }
181             }
182              
183             #
184             # 3.8 Interface Declaration
185             #
186              
187             sub visitBaseInterface {
188 0     0 0   my $self = shift;
189 0           my ($node) = @_;
190 0 0         return if (exists $node->{$self->{key}});
191 0           $node->{$self->{key}} = 1;
192 0           foreach (@{$node->{list_export}}) {
  0            
193 0           $self->_get_defn($_)->visit($self);
194             }
195             }
196              
197 0     0 0   sub visitForwardBaseInterface {
198             # empty
199             }
200              
201             #
202             # 3.9 Value Declaration
203             #
204              
205             sub visitStateMember {
206 0     0 0   my $self = shift;
207 0           my ($node) = @_;
208 0           my $type = $self->_get_defn($node->{type});
209 0           $type->visit($self); # type_spec
210 0 0         if (exists $node->{array_size}) {
211 0           foreach (@{$node->{array_size}}) {
  0            
212 0           $_->visit($self, $node); # expression
213             }
214             }
215             }
216              
217             sub visitInitializer {
218 0     0 0   my $self = shift;
219 0           my ($node) = @_;
220 0           foreach (@{$node->{list_param}}) {
  0            
221 0           $_->visit($self); # parameter
222             }
223             }
224              
225             #
226             # 3.10 Constant Declaration
227             #
228              
229             sub visitConstant {
230 0     0 0   my $self = shift;
231 0           my ($node) = @_;
232 0           $node->{value}->visit($self, $node); # expression
233             }
234              
235             sub _Eval {
236 0     0     my $self = shift;
237 0           my ($list_expr, $type, $scope) = @_;
238 0           my $elt = $self->_get_defn(pop @{$list_expr});
  0            
239 0 0         if ( $elt->isa('Literal') ) {
    0          
    0          
    0          
    0          
240 0           $elt->visit($self, $type);
241 0           return $elt->{$self->{key}};
242             }
243             elsif ( $elt->isa('Enum') ) {
244 0           return $self->_get_scoped_name($elt, $scope);
245             }
246             elsif ( $elt->isa('Constant') ) {
247 0           return $self->_get_scoped_name($elt, $scope);
248             }
249             elsif ( $elt->isa('UnaryOp') ) {
250 0           my $right = $self->_Eval($list_expr, $type, $scope);
251 0           return $elt->{op} . $right;
252             }
253             elsif ( $elt->isa('BinaryOp') ) {
254 0           my $right = $self->_Eval($list_expr, $type, $scope);
255 0           my $left = $self->_Eval($list_expr, $type, $scope);
256 0           return '(' . $left . q{ } . $elt->{op} . q{ } . $right . ')';
257             }
258             else {
259 0           warn __PACKAGE__,"::_Eval: INTERNAL ERROR ",ref $elt,".\n";
260 0           return undef;
261             }
262             }
263              
264             sub visitExpression {
265 0     0 0   my $self = shift;
266 0           my ($node, $scope) = @_;
267 0           my $type = $self->_get_defn($node->{type});
268 0           while ($type->isa('TypeDeclarator')) {
269 0           $type = $self->_get_defn($type->{type});
270             }
271 0           my @list_expr = @{$node->{list_expr}}; # create a copy
  0            
272 0           my $str = $self->_Eval(\@list_expr, $type, $scope);
273 0           $type = $self->_get_defn($node->{type});
274 0 0         if ($type->isa('TypeDeclarator')) {
275 0           my $type2 = $self->_get_defn($type->{type});
276 0 0         unless ($type2->isa('EnumType')) {
277 0           $node->{$self->{key}} = $type->{py_name} . '(' . $str . ')';
278 0           return;
279             }
280             }
281 0           $node->{$self->{key}} = $str;
282             }
283              
284             sub visitIntegerLiteral {
285 0     0 0   my $self = shift;
286 0           my ($node, $type) = @_;
287 0           my $str = $node->{value};
288 0           $str =~ s/^\+//;
289 0 0         unless (exists $type->{auto}) {
290 0 0         if ($node->{lexeme} =~ /^0+$/) {
    0          
    0          
291 0           $str = '0';
292             }
293             elsif ($node->{lexeme} =~ /^0[Xx]/) {
294 0           my $fmt;
295 0 0         if ($type->{value} eq 'octet') {
    0          
    0          
    0          
    0          
    0          
    0          
296 0           $fmt = '0x%02x';
297             }
298             elsif ( $type->{value} eq 'short' ) {
299 0           $fmt = '0x%04x';
300             }
301             elsif ( $type->{value} eq 'unsigned short' ) {
302 0           $fmt = '0x%04x';
303             }
304             elsif ( $type->{value} eq 'long' ) {
305 0           $fmt = '0x%08x';
306             }
307             elsif ( $type->{value} eq 'unsigned long' ) {
308 0           $fmt = '0x%08x';
309             }
310             elsif ( $type->{value} eq 'long long' ) {
311 0           $fmt = '0x%016x';
312             }
313             elsif ( $type->{value} eq 'unsigned long long' ) {
314 0           $fmt = '0x%016x';
315             }
316 0           $str = sprintf($fmt, $node->{value});
317             }
318             elsif ($node->{lexeme} =~ /^0/) {
319 0           $str = sprintf('0%o', $node->{value});
320             }
321             else {
322 0           $str = sprintf('%d', $node->{value});
323             }
324 0 0 0       if ( $type->{value} eq 'unsigned long'
      0        
325             or $type->{value} eq 'long long'
326             or $type->{value} eq 'unsigned long long' ) {
327 0           $str .= 'L';
328             }
329             }
330 0           $node->{$self->{key}} = $str;
331             }
332              
333             sub visitStringLiteral {
334 0     0 0   my $self = shift;
335 0           my ($node) = @_;
336 0           my @list = unpack 'C*', $node->{value};
337 0           my $str = q{'};
338 0           foreach (@list) {
339 0 0 0       if ($_ < 32 or $_ >= 128) {
340 0           $str .= sprintf "\\x%02x", $_;
341             }
342             else {
343 0           $str .= chr $_;
344             }
345             }
346 0           $str .= q{'};
347 0           $node->{$self->{key}} = $str;
348             }
349              
350             sub visitWideStringLiteral {
351 0     0 0   my $self = shift;
352 0           my ($node) = @_;
353 0           my @list = unpack 'C*', $node->{value};
354 0           my $str = q{u'};
355 0           foreach (@list) {
356 0 0 0       if ($_ < 32 or ($_ >= 128 and $_ < 256)) {
    0 0        
357 0           $str .= sprintf "\\x%02x", $_;
358             }
359             elsif ($_ >= 256) {
360 0           $str .= sprintf "\\u%04x", $_;
361             }
362             else {
363 0           $str .= chr $_;
364             }
365             }
366 0           $str .= q{'};
367 0           $node->{$self->{key}} = $str;
368             }
369              
370             sub visitCharacterLiteral {
371 0     0 0   my $self = shift;
372 0           my ($node) = @_;
373 0           my @list = unpack 'C', $node->{value};
374 0           my $c = $list[0];
375 0           my $str = q{'};
376 0 0 0       if ($c < 32 or $c >= 128) {
377 0           $str .= sprintf "\\x%02x", $c;
378             }
379             else {
380 0           $str .= chr $c;
381             }
382 0           $str .= q{'};
383 0           $node->{$self->{key}} = $str;
384             }
385              
386             sub visitWideCharacterLiteral {
387 0     0 0   my $self = shift;
388 0           my ($node) = @_;
389 0           my @list = unpack 'C', $node->{value};
390 0           my $c = $list[0];
391 0           my $str = q{u'};
392 0 0 0       if ($c < 32 or ($c >= 128 and $c < 256)) {
    0 0        
393 0           $str .= sprintf "\\x%02x", $c;
394             }
395             elsif ($c >= 256) {
396 0           $str .= sprintf "\\u%04x", $c;
397             }
398             else {
399 0           $str .= chr $c;
400             }
401 0           $str .= q{'};
402 0           $node->{$self->{key}} = $str;
403             }
404              
405             sub visitFixedPtLiteral {
406 0     0 0   my $self = shift;
407 0           my ($node) = @_;
408 0           my $str = q{'};
409 0           $str .= $node->{value};
410 0           $str .= q{'};
411 0           $node->{$self->{key}} = $str;
412             }
413              
414             sub visitFloatingPtLiteral {
415 0     0 0   my $self = shift;
416 0           my ($node) = @_;
417 0           $node->{$self->{key}} = $node->{value};
418             }
419              
420             sub visitBooleanLiteral {
421 0     0 0   my $self = shift;
422 0           my ($node) = @_;
423 0 0         if ($node->{value} eq 'TRUE') {
424 0           $node->{$self->{key}} = 'True';
425             }
426             else {
427 0           $node->{$self->{key}} = 'False';
428             }
429             }
430              
431             #
432             # 3.11 Type Declaration
433             #
434              
435             sub visitTypeDeclarator {
436 0     0 0   my $self = shift;
437 0           my ($node) = @_;
438 0           my $type = $self->_get_defn($node->{type});
439 0           $type->visit($self, $node);
440 0 0         if (exists $node->{array_size}) {
441 0           foreach (@{$node->{array_size}}) {
  0            
442 0           $_->visit($self, $node); # expression
443             }
444             }
445             }
446              
447 0     0 0   sub visitNativeType {
448             # empty
449             }
450              
451             #
452             # 3.11.1 Basic Types
453             #
454              
455 0     0 0   sub visitBasicType {
456             # empty
457             }
458              
459             #
460             # 3.11.2 Constructed Types
461             #
462             # 3.11.2.1 Structures
463             #
464              
465             sub visitStructType {
466 0     0 0   my $self = shift;
467 0           my ($node) = @_;
468 0 0         return if (exists $node->{$self->{key}});
469 0           $node->{$self->{key}} = 1;
470 0           foreach (@{$node->{list_member}}) {
  0            
471 0           my $defn = $self->_get_defn($_);
472 0           $defn->visit($self, $node); # member
473             }
474             }
475              
476             sub visitMember {
477 0     0 0   my $self = shift;
478 0           my ($node, $type) = @_;
479 0           $self->_get_defn($node->{type})->visit($self, $type);
480 0 0         if (exists $node->{array_size}) {
481 0           foreach (@{$node->{array_size}}) {
  0            
482 0           $_->visit($self, $type); # expression
483             }
484             }
485             }
486              
487             # 3.11.2.2 Discriminated Unions
488             #
489              
490             sub visitUnionType {
491 0     0 0   my $self = shift;
492 0           my ($node) = @_;
493 0 0         return if (exists $node->{$self->{key}});
494 0           $node->{$self->{key}} = 1;
495 0           foreach (@{$node->{list_expr}}) {
  0            
496 0           $_->visit($self, $node); # case
497             }
498             }
499              
500             sub visitCase {
501 0     0 0   my $self = shift;
502 0           my ($node, $type) = @_;
503 0           foreach (@{$node->{list_label}}) {
  0            
504 0           $_->visit($self, $type); # default or expression
505             }
506 0           $node->{element}->visit($self, $type);
507             }
508              
509 0     0 0   sub visitDefault {
510             # empty
511             }
512              
513             sub visitElement {
514 0     0 0   my $self = shift;
515 0           my ($node, $type) = @_;
516 0           my $defn = $self->_get_defn($node->{value}); # member
517 0           $defn->visit($self, $type);
518             }
519              
520             # 3.11.2.4 Enumerations
521             #
522              
523 0     0 0   sub visitEnumType {
524             # empty
525             }
526              
527             #
528             # 3.11.3 Template Types
529             #
530              
531             sub visitSequenceType {
532 0     0 0   my $self = shift;
533 0           my ($node, $scope) = @_;
534 0           my $type = $self->_get_defn($node->{type});
535 0           $type->visit($self, $type);
536 0 0         $node->{max}->visit($self, $scope) if (exists $node->{max});
537             }
538              
539             sub visitStringType {
540 0     0 0   my $self = shift;
541 0           my ($node, $scope) = @_;
542 0 0         $node->{max}->visit($self, $scope) if (exists $node->{max});
543             }
544              
545             sub visitWideStringType {
546 0     0 0   my $self = shift;
547 0           my ($node, $scope) = @_;
548 0 0         $node->{max}->visit($self, $scope) if (exists $node->{max});
549             }
550              
551             sub visitFixedPtType {
552 0     0 0   my $self = shift;
553 0           my ($node, $scope) = @_;
554 0           $node->{d}->visit($self, $scope);
555 0           $node->{s}->visit($self, $scope);
556             }
557              
558 0     0 0   sub visitFixedPtConstType {
559             # empty
560             }
561              
562             #
563             # 3.12 Exception Declaration
564             #
565              
566             sub visitException {
567 0     0 0   my $self = shift;
568 0           my ($node) = @_;
569 0           foreach (@{$node->{list_member}}) {
  0            
570 0           my $defn = $self->_get_defn($_);
571 0           $defn->visit($self, $node); # member
572             }
573             }
574              
575             #
576             # 3.13 Operation Declaration
577             #
578              
579             sub visitOperation {
580 0     0 0   my $self = shift;
581 0           my ($node) = @_;
582 0           my $type = $self->_get_defn($node->{type});
583 0           $type->visit($self); # param_type_spec or void
584 0           foreach (@{$node->{list_param}}) {
  0            
585 0           $_->visit($self); # parameter
586             }
587             }
588              
589             sub visitParameter {
590 0     0 0   my $self = shift;
591 0           my ($node) = @_;
592 0           my $type = $self->_get_defn($node->{type});
593 0           $type->visit($self); # param_type_spec
594             }
595              
596 0     0 0   sub visitVoidType {
597             # empty
598             }
599              
600             #
601             # 3.14 Attribute Declaration
602             #
603              
604             sub visitAttribute {
605 0     0 0   my $self = shift;
606 0           my ($node) = @_;
607 0           my $type = $self->_get_defn($node->{type});
608 0           $type->visit($self); # param_type_spec
609             }
610              
611             #
612             # 3.15 Repository Identity Related Declarations
613             #
614              
615 0     0 0   sub visitTypeId {
616             # empty
617             }
618              
619 0     0 0   sub visitTypePrefix {
620             # empty
621             }
622              
623             #
624             # 3.16 Event Declaration
625             #
626              
627             #
628             # 3.17 Component Declaration
629             #
630              
631 0     0 0   sub visitProvides {
632             # empty
633             }
634              
635 0     0 0   sub visitUses {
636             # empty
637             }
638              
639 0     0 0   sub visitPublishes {
640             # empty
641             }
642              
643 0     0 0   sub visitEmits {
644             # empty
645             }
646              
647 0     0 0   sub visitConsumes {
648             # empty
649             }
650              
651             #
652             # 3.18 Home Declaration
653             #
654              
655             sub visitFactory {
656 0     0 0   my $self = shift;
657 0           my ($node) = @_;
658 0           foreach (@{$node->{list_param}}) {
  0            
659 0           $_->visit($self); # parameter
660             }
661             }
662              
663             sub visitFinder {
664 0     0 0   my $self = shift;
665 0           my ($node) = @_;
666 0           foreach (@{$node->{list_param}}) {
  0            
667 0           $_->visit($self); # parameter
668             }
669             }
670              
671             1;
672