/usr/local/CPAN/CORBA-C/CORBA/C/SkeletonVisitor.pm
#
# Interface Definition Language (OMG IDL CORBA v3.0)
#
# C Language Mapping Specification, New Edition June 1999
#
package CORBA::C::SkeletonVisitor;
use strict;
use warnings;
our $VERSION = '2.60';
use File::Basename;
use POSIX qw(ctime);
# needs $node->{c_name} (CnameVisitor) and $node->{c_arg} (CincludeVisitor)
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $self = {};
bless $self, $class;
my ($parser, $prefix) = @_;
$prefix = 'skel_' if (!defined $prefix);
$self->{prefix} = $prefix;
$self->{srcname} = $parser->YYData->{srcname};
$self->{srcname_size} = $parser->YYData->{srcname_size};
$self->{srcname_mtime} = $parser->YYData->{srcname_mtime};
$self->{symbtab} = $parser->YYData->{symbtab};
my $filename = $prefix . basename($self->{srcname}, '.idl') . '.c';
$self->parse($filename);
$self->open_stream($filename);
$self->{done_hash} = {};
$self->{num_key} = 'num_skel_c';
return $self;
}
sub parse {
my $self = shift;
my ($filename) = @_;
$self->{merge} = {};
$self->{merge_comment} = {};
return unless ( -r $filename);
open my $IN, '<', $filename
or die "can't open $filename ($!).\n";
while (<$IN>) {
if (/\/\* START_EDIT (\(([^\)]+)\) )?\*\//) {
my $key = $2 || $self->{srcname};
my $code = q{};
while (<$IN>) {
last if (/\/\* STOP_EDIT/);
$code .= $_;
}
$self->{merge}->{$key} = $code;
}
elsif (/\/\* START_COMMENT (\(([^\)]+)\) )?\*\//) {
my $key = $2 || $self->{srcname};
my $code = q{};
while (<$IN>) {
last if (/\/\* STOP_COMMENT/);
$code .= $_;
}
$self->{merge_comment}->{$key} = $code;
}
}
close $IN;
}
sub merge {
my $self = shift;
my ($key, $default) = @_;
$default = q{} unless ($default);
$key = $self->{srcname} unless ($key);
if (exists $self->{merge}->{$key}) {
return $self->{merge}->{$key};
}
else {
return $default . "\n"
}
}
sub merge_comment {
my $self = shift;
my ($key) = @_;
$key = $self->{srcname} unless ($key);
if (exists $self->{merge_comment}->{$key}) {
return $self->{merge_comment}->{$key};
}
else {
return q{};
}
}
sub open_stream {
my $self = shift;
my ($filename) = @_;
open $self->{out}, '>', $filename
or die "can't open $filename ($!).\n";
$self->{filename} = $filename;
}
sub _get_defn {
my $self = shift;
my ($defn) = @_;
if (ref $defn) {
return $defn;
}
else {
return $self->{symbtab}->Lookup($defn);
}
}
#
# 3.5 OMG IDL Specification
#
sub visitSpecification {
my $self = shift;
my ($node) = @_;
my $filename = $self->{prefix} . basename($self->{srcname}, '.idl') . '.h';
my $FH = $self->{out};
print $FH "/* This file was partialy generated (by ",basename($0),").*/\n";
print $FH "/* From file : ",$self->{srcname},", ",$self->{srcname_size}," octets, ",POSIX::ctime($self->{srcname_mtime});
print $FH " */\n";
print $FH "\n";
print $FH "/* START_EDIT */\n";
print $FH $self->merge();
print $FH "/* STOP_EDIT */\n";
print $FH "\n";
print $FH "#include \"",$filename,"\"\n";
print $FH "\n";
foreach (@{$node->{list_decl}}) {
$self->_get_defn($_)->visit($self);
}
print $FH "\n";
print $FH "/* end of file : ",$self->{filename}," */\n";
close $FH;
}
#
# 3.7 Module Declaration
#
sub visitModules {
my $self = shift;
my ($node) = @_;
unless (exists $node->{$self->{num_key}}) {
$node->{$self->{num_key}} = 0;
}
my $module = ${$node->{list_decl}}[$node->{$self->{num_key}}];
$module->visit($self);
$node->{$self->{num_key}} ++;
}
sub visitModule {
my $self = shift;
my ($node) = @_;
if ($self->{srcname} eq $node->{filename}) {
my $defn = $self->{symbtab}->Lookup($node->{full});
my $FH = $self->{out};
print $FH "/*\n";
print $FH " * begin of module ",$defn->{c_name},"\n";
print $FH " */\n";
foreach (@{$node->{list_decl}}) {
$self->_get_defn($_)->visit($self);
}
print $FH "/*\n";
print $FH " * end of module ",$defn->{c_name},"\n";
print $FH " */\n";
}
}
#
# 3.8 Interface Declaration
#
sub visitRegularInterface {
my $self = shift;
my ($node) = @_;
if ($self->{srcname} eq $node->{filename}) {
my $FH = $self->{out};
print $FH "/* START_EDIT (",$node->{c_name},") */\n";
print $FH $self->merge($node->{c_name});
print $FH "/* STOP_EDIT (",$node->{c_name},") */\n";
print $FH "\n";
print $FH "/*\n";
print $FH " * begin of interface ",$node->{c_name},"\n";
print $FH " */\n";
$self->{itf} = $node->{c_name};
foreach (sort keys %{$node->{hash_attribute_operation}}) {
my $elt = ${$node->{hash_attribute_operation}}{$_};
$self->_get_defn($elt)->visit($self);
}
print $FH "/*\n";
print $FH " * end of interface ",$node->{c_name},"\n";
print $FH " */\n";
}
}
sub visitForwardRegularInterface {
# empty
}
sub visitBaseInterface {
# C mapping is aligned with CORBA 2.1
}
sub visitForwardBaseInterface {
# C mapping is aligned with CORBA 2.1
}
#
# 3.10 Constant Declaration
#
sub visitConstant {
# empty
}
#
# 3.11 Type Declaration
#
sub visitTypeDeclarators {
# empty
}
sub visitTypeDeclarator {
# empty
}
sub visitNativeType {
# C mapping is aligned with CORBA 2.1
}
sub visitStructType {
# empty
}
sub visitUnionType {
# empty
}
sub visitForwardStructType {
# empty
}
sub visitForwardUnionType {
# empty
}
sub visitEnumType {
# empty
}
#
# 3.12 Exception Declaration
#
sub visitException {
# empty
}
#
# 3.13 Operation Declaration
#
sub visitOperation {
my $self = shift;
my ($node) = @_;
my $name = $self->{prefix} . $self->{itf} . '_' . $node->{c_name};
my $FH = $self->{out};
print $FH "\n";
print $FH "/* START_COMMENT (",$name,") */\n";
print $FH $self->merge_comment($name);
print $FH "/* STOP_COMMENT (",$name,") */\n";
print $FH "/* ARGSUSED */\n";
if (exists $node->{modifier}) {
print $FH $node->{c_arg}," // oneway\n";
}
else {
print $FH $node->{c_arg},"\n";
}
print $FH $name,"(\n";
print $FH "\t",$self->{itf}," _o,\n";
foreach (@{$node->{list_param}}) { # parameter
my $type = $self->_get_defn($_->{type});
print $FH "\t",$_->{c_arg},", // ",$_->{attr};
print $FH " (variable length)\n" if (defined $type->{length});
print $FH " (fixed length)\n" unless (defined $type->{length});
}
if (exists $node->{list_context}) {
print $FH "\tCORBA_Context _ctx,\n";
}
print $FH "\tCORBA_Environment * _ev\n";
print $FH ")\n";
print $FH "{\n";
print $FH "/* START_EDIT (",$name,") */\n";
my $except;
if (exists $node->{list_raise}) {
foreach (@{$node->{list_raise}}) { # exception
my $defn = $self->_get_defn($_);
$except = "\tstatic " . $defn->{c_name} . " _" . $defn->{c_name} . ";\n";
}
}
print $FH $self->merge($name, $except);
print $FH "/* STOP_EDIT (",$name,") */\n";
print $FH "}\n";
print $FH "\n";
}
#
# 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
}
1;