/usr/local/CPAN/CORBA-C/CORBA/C/LengthVisitor.pm
#
# Interface Definition Language (OMG IDL CORBA v3.0)
#
# C Language Mapping Specification, New Edition June 1999
#
package CORBA::C::LengthVisitor;
use strict;
use warnings;
our $VERSION = '2.60';
# builds $node->{length}
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $self = {};
bless $self, $class;
my ($parser) = @_;
$self->{srcname} = $parser->YYData->{srcname};
$self->{symbtab} = $parser->YYData->{symbtab};
$self->{done_hash} = {};
$self->{key} = 'c_name';
return $self;
}
sub _get_defn {
my $self = shift;
my ($defn) = @_;
if (ref $defn) {
return $defn;
}
else {
return $self->{symbtab}->Lookup($defn);
}
}
# See 1.8 Mapping Considerations for Constructed Types
#
sub _get_length {
my $self = shift;
my ($type) = @_;
if ( $type->isa('AnyType')
or $type->isa('SequenceType')
or $type->isa('StringType')
or $type->isa('WideStringType')
or $type->isa('ObjectType') ) {
return 'variable';
}
if ( $type->isa('StructType')
or $type->isa('UnionType')
or $type->isa('TypeDeclarator') ) {
return $type->{length};
}
return undef;
}
#
# 3.5 OMG IDL Specification
#
sub visitSpecification {
my $self = shift;
my ($node) = @_;
if (exists $node->{list_import}) {
foreach (@{$node->{list_import}}) {
$_->visit($self);
}
}
foreach (@{$node->{list_export}}) {
$self->{symbtab}->Lookup($_)->visit($self);
}
}
#
# 3.6 Import Declaration
#
sub visitImport {
my $self = shift;
my ($node) = @_;
foreach (@{$node->{list_decl}}) {
$self->{symbtab}->Lookup($_)->visit($self);
}
}
#
# 3.7 Module Declaration
#
sub visitModules {
my $self = shift;
my ($node) = @_;
foreach (@{$node->{list_export}}) {
$self->{symbtab}->Lookup($_)->visit($self);
}
}
#
# 3.8 Interface Declaration
#
sub visitBaseInterface {
my $self = shift;
my ($node) = @_;
return if (exists $node->{length});
# $node->{length} = 'variable';
# TODO : $self->{done}->{} ???
$node->{length} = q{}; # void* = CORBA_unsigned_long
foreach (@{$node->{list_export}}) {
$self->{symbtab}->Lookup($_)->visit($self);
}
}
sub visitForwardBaseInterface {
my $self = shift;
my ($node) = @_;
return if (exists $node->{length});
# $node->{length} = 'variable';
$node->{length} = q{}; # void* = CORBA_unsigned_long
}
#
# 3.9 Value Declaration
#
sub visitStateMember {
# C mapping is aligned with CORBA 2.1
my $self = shift;
my ($node) = @_;
$self->_get_defn($node->{type})->visit($self);
}
sub visitInitializer {
# C mapping is aligned with CORBA 2.1
my $self = shift;
my ($node) = @_;
foreach (@{$node->{list_param}}) {
$self->_get_defn($_->{type})->visit($self);
}
}
#
# 3.10 Constant Declaration
#
sub visitConstant {
}
#
# 3.11 Type Declaration
#
sub visitTypeDeclarator {
my $self = shift;
my ($node) = @_;
my $type = $self->_get_defn($node->{type});
if ( $type->isa('TypeDeclarator')
or $type->isa('StructType')
or $type->isa('UnionType')
or $type->isa('EnumType')
or $type->isa('SequenceType')
or $type->isa('FixedPtType') ) {
$type->visit($self);
}
$node->{length} = $self->_get_length($type);
}
sub visitNativeType {
# C mapping is aligned with CORBA 2.1
}
#
# 3.11.1 Basic Types
#
sub visitBasicType {
# fixed length
}
#
# 3.11.2 Constructed Types
#
# 3.11.2.1 Structures
#
sub visitStructType {
my $self = shift;
my ($node) = @_;
return if (exists $self->{done_hash}->{$node->{$self->{key}}});
$self->{done_hash}->{$node->{$self->{key}}} = 1;
$node->{length} = undef;
foreach (@{$node->{list_expr}}) {
my $type = $self->_get_defn($_->{type});
if ( $type->isa('TypeDeclarator')
or $type->isa('StructType')
or $type->isa('UnionType')
or $type->isa('SequenceType')
or $type->isa('StringType')
or $type->isa('WideStringType')
or $type->isa('FixedPtType') ) {
$type->visit($self);
}
$node->{length} ||= $self->_get_length($type);
}
}
# 3.11.2.2 Discriminated Unions
#
sub visitUnionType {
my $self = shift;
my ($node) = @_;
return if (exists $self->{done_hash}->{$node->{$self->{key}}});
$self->{done_hash}->{$node->{$self->{key}}} = 1;
$node->{length} = undef;
foreach (@{$node->{list_expr}}) {
my $type = $self->_get_defn($_->{element}->{type});
if ( $type->isa('TypeDeclarator')
or $type->isa('StructType')
or $type->isa('UnionType')
or $type->isa('SequenceType')
or $type->isa('StringType')
or $type->isa('WideStringType')
or $type->isa('FixedPtType') ) {
$type->visit($self);
}
$node->{length} ||= $self->_get_length($type);
}
my $type = $self->_get_defn($node->{type});
if ($type->isa('EnumType')) {
$type->visit($self);
}
}
# 3.11.2.4 Enumerations
#
sub visitEnumType {
# fixed length
}
#
# 3.11.3 Template Types
#
sub visitSequenceType {
my $self = shift;
my ($node) = @_;
$node->{length} = 'variable';
my $type = $self->_get_defn($node->{type});
if ( $type->isa('TypeDeclarator')
or $type->isa('StructType')
or $type->isa('UnionType')
or $type->isa('SequenceType')
or $type->isa('StringType')
or $type->isa('WideStringType')
or $type->isa('FixedPtType') ) {
$type->visit($self);
}
}
sub visitStringType {
my $self = shift;
my ($node) = @_;
$node->{length} = 'variable';
}
sub visitWideStringType {
my $self = shift;
my ($node) = @_;
$node->{length} = 'variable';
}
sub visitFixedPtType {
# fixed length
}
sub visitFixedPtConstType {
# fixed length
}
#
# 3.12 Exception Declaration
#
sub visitException {
my $self = shift;
my ($node) = @_;
$node->{length} = undef;
if (exists $node->{list_expr}) {
warn __PACKAGE__,"::visitException $node->{idf} : empty list_expr.\n"
unless (@{$node->{list_expr}});
foreach (@{$node->{list_expr}}) {
my $type = $self->_get_defn($_->{type});
if ( $type->isa('TypeDeclarator')
or $type->isa('StructType')
or $type->isa('UnionType')
or $type->isa('SequenceType')
or $type->isa('FixedPtType') ) {
$type->visit($self);
}
$node->{length} ||= $self->_get_length($type);
}
}
}
#
# 3.13 Operation Declaration
#
sub visitOperation {
my $self = shift;
my ($node) = @_;
my $type = $self->_get_defn($node->{type});
$type->visit($self);
foreach (@{$node->{list_param}}) {
$self->_get_defn($_->{type})->visit($self);
}
}
sub visitVoidType {
# empty
}
#
# 3.14 Attribute Declaration
#
sub visitAttribute {
my $self = shift;
my ($node) = @_;
$node->{_get}->visit($self);
$node->{_set}->visit($self) if (exists $node->{_set});
}
#
# 3.15 Repository Identity Related Declarations
#
sub visitTypeId {
# empty
}
sub visitTypePrefix {
# empty
}
#
# 3.16 Event Declaration
#
#
# 3.17 Component Declaration
#
sub visitProvides {
# empty
}
sub visitUses {
# empty
}
sub visitPublishes {
# empty
}
sub visitEmits {
# empty
}
sub visitConsumes {
# empty
}
#
# 3.18 Home Declaration
#
sub visitFactory {
# C mapping is aligned with CORBA 2.1
my $self = shift;
my ($node) = @_;
foreach (@{$node->{list_param}}) {
$self->_get_defn($_->{type})->visit($self);
}
}
sub visitFinder {
# C mapping is aligned with CORBA 2.1
my $self = shift;
my ($node) = @_;
foreach (@{$node->{list_param}}) {
$self->_get_defn($_->{type})->visit($self);
}
}
1;