Re: Private variable ?
- From: Andrew Bainbridge-Smith <Andrew Bainbridge-Smith cmst csiro au>
- To: orbit-list gnome org
- Subject: Re: Private variable ?
- Date: Wed, 28 Mar 2001 08:39:47 +1000
Greetings,
I think the effort of parsing the generated C files with
--skeleton-impl to see if the various functions need to be
reimplemented is almost certainly too great. It is a difficult
problem to which I think there are better potential solutions.
I considered this issue almost 12 months ago and come up
with an alternative solution. Fundamental to the solution
was that I wanted to be able to take a standalone program
(non client/server) add a few bits and pieces and an *.idl
file and generate a client server pair. (Its easier to test
a standalone program).
To cut a long story short, I worked on some perl scripts to do
this, got it to a crudely acceptable state for myself and then
promptly ran out of time to continue to develop it. I have
attached the necessary files and test case below. So that others
can do with it as they wish. I will be coming back to further
develop this, probably around August. So if someone does take
this idea up please let me know. If people think this is a
very silly idea and there is something way better, then please
say so (and why!)
Cheers,
Andrew
PS:
To generate server: idl-scanner --standalone-server test tco.idl example.c
To generate client: idl-scanner --client tclient tco.idl example.c
--
Dr Andrew Bainbridge-Smith
Senior Research Engineer
Machine Vision Group
CSIRO Manufacturing Science and Technology
Australia
#!/opt/perl/bin/perl
#
# Copyright Andrew Bainbridge-Smith and CSIRO
# 28 March 2001
#
# May be distributed under GPL licence
#
# I would appreciate your comments if you use this code
#
# USAGE
# idl-scanner [--standalone-server | --server | --client]
# output-filename-prefix idl-file *.c-input-source-files
#
# The default option is standalone-server which generates a
# server source file with a main() body.
#
# The --server option does not generate a main(), helpful if this
# is going to be made else where.
#
# The --client option generates the client code, and main().
#
# Note: the input c source files must be heavily commented
# with the structured comments as given in the test case.
#
####################### FORWARD REFERENCES #######################
sub ScanImplementationPreamble;
sub ProcessPreamble;
sub GobbleSection;
sub ProcessTemplate;
sub ProcessServerTemplate;
sub ScanIDL;
sub ProcessBalanceGroup;
sub InsertServices;
############################## MAIN ##############################
my $i;
if ($ARGV[0] =~ /--/)
{
$flags = shift(@ARGV);
}
else
{
$flags = "--standalone-server";
}
SWITCH: {
$flags =~ /--standalone-server/ &&
do {
$standalone_server = 1;
$make_server = 1;
last SWITCH;
};
$flags =~ /--server/ &&
do {
$standalone_server = 0;
$make_server = 1;
last SWITCH;
};
$flags =~ /--client/ &&
do {
$standalone_server = 0;
$make_server = 0;
last SWITCH;
};
}
$outfile = shift(@ARGV);
if ($outfile !~ /^-$/)
{
open (SERVER, "> $outfile")
or die ("Can't open ($outfile) file for output\n");
select (SERVER);
}
$idl_file = shift(@ARGV);
($basename, $ignore) = split(/[.]/, $idl_file);
$num_service_calls = 0;
#
# Scan IDL File forming lists of interface ids, type definitions and stubs
# Results returned in global variables
# $num_of_interfaces
# @interface_ids
# %typedef_table
# %num_of_stubs
# @%stub_return_container
# @%stub_name_container
# @%stub_para_container
#
ScanIDL($idl_file);
#
# Scan preamble section of the Implementation file forming lists of
# poas, naming components, and sections: include, constants, data structures,
# function prototypes, global variables
# Results returned in global variables
# @%server_preamble_list
# @%client_reamble_list
# %use_local_poa
# %num_NS_components
# %poa_id
# @%naming_component_id
# @%naming_component_kind
#
while ($#ARGV >= 0)
{
$implementation = shift(@ARGV);
push(@implementation_list, $implementation);
ScanImplementationPreamble($implementation);
}
#
# Write server skeleton code
#
if ($make_server == 1)
{
ProcessTemplate ("server.template");
}
else
{
ProcessTemplate ("client.template");
}
for ($i=0; $i <= $#implementation_list; $i++)
{
$implementation_file = $implementation_list[$i];
InsertServices($implementation_file);
}
if ($outfile !~ /^-$/)
{
close (SERVER);
}
exit;
########################## END OF MAIN ###########################
######################## PROCESS TEMPLATE ########################
sub ProcessTemplate
{
my $i;
my $j;
my $scanline;
my ($template_file) = @_;
my $section_name;
my $section_size;
my @section;
open (TEMPLATE, "< $template_file")
or die ("Can't open server template file: $template_file");
while ($scanline = <TEMPLATE>)
{
SECTION_SWITCH: {
$scanline =~ /<creation string>/i &&
do {
printf ("/******************************************************************************/\n");
printf ("/* %72s */\n", "");
printf ("/* %-72s */\n", "Automatically generated");
printf ("/* %s*/\n", "on " . qx{date});
printf ("/* %s*/\n", "by " . qx{whoami});
printf ("/* %72s */\n", "");
printf ("/******************************************************************************/\n");
last SECTION_SWITCH;
};
$scanline =~ /<include>/i &&
do {
print ("$scanline");
$section_name = "<include>";
GobbleSection ($section_name, \$section_size, \ section,
*TEMPLATE{IO});
ProcessServerTemplate ($section_name, $section_size, \ section);
last SECTION_SWITCH;
};
$scanline =~ /<constants>/i &&
do {
print ("$scanline");
$section_name = "<constants>";
GobbleSection ($section_name, \$section_size, \ section,
*TEMPLATE{IO});
ProcessServerTemplate ($section_name, $section_size, \ section);
last SECTION_SWITCH;
};
$scanline =~ /<data structures>/i &&
do {
print ("$scanline");
$section_name = "<data structures>";
GobbleSection ($section_name, \$section_size, \ section,
*TEMPLATE{IO});
ProcessServerTemplate ($section_name, $section_size, \ section);
last SECTION_SWITCH;
};
$scanline =~ /<function prototypes>/i &&
do {
print ("$scanline");
$section_name = "<function prototypes>";
GobbleSection ($section_name, \$section_size, \ section,
*TEMPLATE{IO});
ProcessServerTemplate ($section_name, $section_size, \ section);
last SECTION_SWITCH;
};
$scanline =~ /<global variables>/i &&
do {
print ("$scanline");
$section_name = "<global variables>";
GobbleSection ($section_name, \$section_size, \ section,
*TEMPLATE{IO});
ProcessServerTemplate ($section_name, $section_size, \ section);
last SECTION_SWITCH;
};
$scanline =~ /<implementation>/i &&
do {
$section_name = "<implementation>";
GobbleSection ($section_name, \$section_size, \ section,
*TEMPLATE{IO});
ProcessServerTemplate ($section_name, $section_size, \ section);
last SECTION_SWITCH;
};
$scanline =~ /<standalone server>/i && ($standalone_server == 1) &&
do {
$section_name = "<standalone server>";
GobbleSection ($section_name, \$section_size, \ section,
*TEMPLATE{IO});
for ($i = 0; $i < $section_size; $i = $i + 1)
{
if ($section[$i] =~ /<interface id>/i)
{
for ($j = 0; $j < $num_of_interfaces; $j = $j +1)
{
my $template = $section[$i];
$template =~ s/<interface id>/$interface_ids[$j]/eig;
print ("$template");
}
}
else
{
print ("$section[$i]");
}
}
last SECTION_SWITCH;
};
}
}
close (TEMPLATE);
}
######################### GOBBLE SECTION #########################
sub GobbleSection
{
my ($section_name, $section_size_ref, $section_ref, $IO_HANDLE) = @_;
my $scanline;
$$section_size_ref = 0;
@$section_ref = ();
GOBBLE:
while ($scanline = <$IO_HANDLE>)
{
if ($scanline =~ /$section_name/i)
{
last GOBBLE;
}
elsif ($scanline =~ /<sub section>/i)
{
$$section_ref[$$section_size_ref] = "";
SUBGOBBLE:
while ($scanline = <$IO_HANDLE>)
{
if ($scanline =~ /<sub section>/i)
{
$$section_size_ref = $$section_size_ref + 1;
last SUBGOBBLE;
}
else
{
$$section_ref[$$section_size_ref] =
$$section_ref[$$section_size_ref] . $scanline;
}
}
}
else
{
$$section_ref[$$section_size_ref] = $scanline;
$$section_size_ref = $$section_size_ref + 1;
}
}
}
######################## PROCESS SECTION #########################
sub ProcessServerTemplate
{
my ($section_name, $section_size, $section_ref) = @_;
my $implementation_section;
my $i;
my $j;
my $k;
if ($make_server == 1)
{
$implementation_section = @server_preamble_list{$section_name};
}
else
{
$implementation_section = @client_preamble_list{$section_name};
}
while ($#$implementation_section >= 0)
{
print (shift(@$implementation_section));
}
my $counter = 1;
for ($i = 0; $i < $section_size; $i = $i + 1)
{
if ($$section_ref[$i] =~ /<interface id>/)
{
$counter = $num_of_interfaces;
}
}
for ($i = 0; $i < $counter; $i = $i +1)
{
my $id = $interface_ids[$i];
my $ns = $num_of_stubs{$id};
my $stub_name = @stub_name_container{$id};
my $stub_return= @stub_return_container{$id};
my $stub_para = @stub_para_container{$id};
if (defined($use_local_poa{$id}))
{
$local_poa_id = "<interface id>_poa";
}
else
{
$local_poa_id = "root_poa";
}
if (!defined($num_NS_components{$id}))
{
$num_NS_components{$id} = 1;
$naming_component_id{$id}[0] = "$id";
$naming_component_kind{$id}[0] = "server";
}
my $ns_id = @naming_component_id{$id};
my $ns_kind = @naming_component_kind{$id};
my @tsection = @$section_ref;
my $substitution_counter = 0;
while ($substitution_counter != $section_size)
{
$substitution_counter = 0;
for ($j = 0; $j < $section_size; $j = $j + 1)
{
SWITCH: {
$tsection[$j] =~ s/<interface id>/$id/gi &&
do {
last SWITCH;
};
$tsection[$j] =~ /<if standalone server>/i &&
do {
if ($standalone_server == 1)
{
$tsection[$j] =~ s/<if standalone server>/ /gi;
}
else
{
$tsection[$j] = "";
}
last SWITCH;
};
$tsection[$j] =~ s/<basename>/$basename/gi &&
do {
last SWITCH;
};
$tsection[$j] =~ /<stubname>/i &&
do {
my $accum = "";
for ($k = 0; $k < $ns; $k = $k + 1)
{
my $template = $tsection[$j];
$template =~ s/<stubname>/$stub_name_container{$id}[$k]/ei;
$template =~ s/<stub return>/$stub_return_container{$id}[$k]/ei;
$template =~ s/<stub parameters>/$stub_para_container{$id}[$k]/ei;
$template =~ s/,[ \t\n]*,/,/i;
$accum = $accum . $template;
}
$tsection[$j] = $accum;
last SWITCH;
};
$tsection[$j] =~ /<if local poa>/i &&
do {
if (defined($use_local_poa{$id}))
{
$tsection[$j] =~ s/<if local poa>//gi;
}
else
{
$tsection[$j] = "";
}
last SWITCH;
};
$tsection[$j] =~ s/<local number NS components>/$num_NS_components{$id}/gi &&
do {
last SWITCH;
};
$tsection[$j] =~ s/<local poa id>/$local_poa_id/egi &&
do {
last SWITCH;
};
$tsection[$j] =~ /<step NS component>/i &&
do {
my $accum = "";
for ($k = 0; $k < $num_NS_components{$id}; $k = $k + 1)
{
my $template = $tsection[$j];
$template =~ s/<step NS component>/$k/gie;
$template =~ s/<local name component id>/$$ns_id[$k]/gie;
$template =~ s/<local name component kind>/$$ns_kind[$k]/gie;
$accum = $accum . $template;
}
$tsection[$j] = $accum;
last SWITCH;
};
$substitution_counter = $substitution_counter + 1;
}
}
}
for ($j = 0; $j < $section_size; $j = $j + 1)
{
print ("$tsection[$j]");
}
}
}
######################### INSERT SERVICES ########################
sub InsertServices
{
my $i;
my $scanline;
my ($implementation_file) = @_;
my $function_head = "";
my $function_body = "";
my $section_name;
my $section_size;
my @section;
open (IMPLEMENTATION, "< $implementation_file")
or die ("Can't open implementation file for input: $implementation_file");
while ($scanline = <IMPLEMENTATION>)
{
SECTION_SWITCH: {
$scanline =~ /<service[ \t]+([\w:]+)>|<service>/i &&
do {
$function_head = "";
$function_body = "";
$section_name = "<service>";
@section = ();
GobbleSection ($section_name, \$section_size, \ section,
*IMPLEMENTATION{IO});
if (defined($1))
{
my @parts = split(/::/, $1);
my $id = shift(@parts);
while ($#parts > 0)
{
$id = join('_', $id, shift(@parts));
}
my $func = join('_', $id, shift(@parts));
my $ns = $num_of_stubs{$id};
my $stub_names = @stub_name_container{$id};
my $stub_returns= @stub_return_container{$id};
my $stub_paras = @stub_para_container{$id};
while (($line = shift(@section)) !~ /\{/gc)
{
$function_head = $function_head . $line;
}
$function_head = $function_head .
substr($line, 0, pos($line)-1);
$function_body = substr($line, pos($line)-1);
$function_body = join('', $function_body, @section);
$function_head = join(' ', split(/[ \n\t]/, $function_head));
if ($function_head =~ /^[ ]*([\w ]+)[ ]+([\w]+)[ ]*\(.*\)[ ]*$/)
{
my $impl_func = $2;
my $count = 0;
$count++, while ($func ne $$stub_names[$count]);
$function_head = "static $$stub_returns[$count] impl_$func\n" .
" \(POAHooks_$id* servant,\n" .
" $$stub_paras[$count],\n" .
" CORBA_Environment* ev)\n";
$function_head =~ s/,[ \t\n]*,/,/gi;
$service_call[$num_service_calls][0] = $id;
$service_call[$num_service_calls][1] = $func;
$service_call[$num_service_calls][2] = $impl_func;
$num_service_calls++;
}
}
else
{
$function_body = join('', @section);
}
print ($function_head, $function_body), if ($make_server == 1);
last SECTION_SWITCH;
};
$scanline =~ /<client>/i &&
do {
$function_head = "";
$function_body = "";
$section_name = "<client>";
@section = ();
GobbleSection ($section_name, \$section_size, \ section,
*IMPLEMENTATION{IO});
for ($i=0; $i < $section_size; $i++)
{
for ($j=0; $j < $num_service_calls; $j++)
{
$section[$i] =~ s/([ \t\n]+)($service_call[$j][2])[ \t\n]*\(([\w,\"\& \t\n]*)\)[ \t\n]*;/$1$service_call[$j][1]\($service_call[$j][0]_object, $3, \&ev\);\n if(ev._major != CORBA_NO_EXCEPTION) \{ fprintf(stderr, "Corba exception:: %s: %s\n", (ev._major == CORBA_SYSTEM_EXCEPTION ? "System" : "User"), CORBA_exception_id(&ev)); exit(1);\}/g;
$section[$i] =~ s/,[ \t\n]*,/,/g;
}
if ($section[$i] =~ /<corba init>/gi)
{
ProcessTemplate ("clientmain.template"),
if ($make_server == 0);
}
else
{
print ("$section[$i]"), if ($make_server == 0);
}
}
last SECTION_SWITCH;
};
}
}
close(IMPLEMENTATION);
}
################## SCAN IMPLEMENTATION PREAMBLE ##################
# Scan preamble section of the Implementation file forming lists of
# poas, naming components, and sections: include, constants, data structures,
# function prototypes, global variables
# Results returned in global variables
# @%server_preamble_list
# @%client_preamble_list
# %use_local_poa
# %num_NS_components
# %poa_id
# @%naming_component_id
# @%naming_component_kind
sub ScanImplementationPreamble
{
my $implementation_file = @_[0];
my $i;
my $j;
my $section;
my $section_size;
my $scanline;
open (IMPLEMENTATION, "< $implementation_file")
or die ("Can't open implementation file for input: $implementation_file");
PREAMBLE:
while ($scanline = <IMPLEMENTATION>)
{
SECTION_SWITCH:
{
$scanline =~ /<include>/i &&
do {
$section_name = "<include>";
GobbleSection ($section_name, \$section_size, \ section,
*IMPLEMENTATION{IO});
ProcessPreamble ($section_name, $section_size, \ section);
last SECTION_SWITCH;
};
$scanline =~ /<constants>/i &&
do {
$section_name = "<constants>";
GobbleSection ($section_name, \$section_size, \ section,
*IMPLEMENTATION{IO});
ProcessPreamble ($section_name, $section_size, \ section);
last SECTION_SWITCH;
};
$scanline =~ /<data structures>/i &&
do {
$section_name = "<data structures>";
GobbleSection ($section_name, \$section_size, \ section,
*IMPLEMENTATION{IO});
ProcessPreamble ($section_name, $section_size, \ section);
last SECTION_SWITCH;
};
$scanline =~ /<function prototypes>/i &&
do {
$section_name = "<function prototypes>";
GobbleSection ($section_name, \$section_size, \ section,
*IMPLEMENTATION{IO});
ProcessPreamble ($section_name, $section_size, \ section);
last SECTION_SWITCH;
};
$scanline =~ /<global variables>/i &&
do {
$section_name = "<global variables>";
GobbleSection ($section_name, \$section_size, \ section,
*IMPLEMENTATION{IO});
ProcessPreamble ($section_name, $section_size, \ section);
last SECTION_SWITCH;
};
$scanline =~ /<naming components[ \t]+([\w:]+)>/i &&
do {
my $id = join('_', split(/::/, $1));
$section_name = "<naming components>";
GobbleSection ($section_name, \$section_size, \ section,
*IMPLEMENTATION{IO});
for ($j=0; $j < $section_size; $j++)
{
$naming_component_id{$id}[$j] = $1,
$naming_component_kind{$id}[$j] = $2,
if ($section[$j] =~ /<namepair[ \t]+([\w]+)[ \t]+([\w]+)>/i);
}
$num_NS_components{$id} = $section_size;
last SECTION_SWITCH;
};
$scanline =~ /<use local poa[ \t]*([\w:]+)>/i &&
do {
my $id = join('_', split(/::/, $1));
$use_local_poa{$id} = 1;
};
$scanline =~ /<end of preamble>/ &&
do {
last PREAMBLE;
};
}
}
close (IMPLEMENTATION);
}
######################## PROCESS SECTION #########################
sub ProcessPreamble
{
my ($section_name, $section_size, $section_ref) = @_;
my $i;
my $j;
my @tsection = @$section_ref;
for ($j=0; $j < $section_size; $j++)
{
my $server_section_ref = @server_preamble_list{$section_name};
my $client_section_ref = @client_preamble_list{$section_name};
SWITCH: {
$tsection[$j] =~ s/<server[ \t]+only>//gi &&
do {
if (!defined($server_section_ref))
{
$server_preamble_list{$section_name}[0] = $tsection[$j];
}
else
{
push(@$server_section_ref, $tsection[$j]);
}
last SWITCH;
};
$tsection[$j] =~ s/<client[ \t]+only>//gi &&
do {
if (!defined($client_section_ref))
{
$client_preamble_list{$section_name}[0] = $tsection[$j];
}
else
{
push(@$client_section_ref, $tsection[$j]);
}
last SWITCH;
};
if (!defined($server_section_ref))
{
$server_preamble_list{$section_name}[0] = $tsection[$j];
}
else
{
push(@$server_section_ref, $tsection[$j]);
}
if (!defined($client_section_ref))
{
$client_preamble_list{$section_name}[0] = $tsection[$j];
}
else
{
push(@$client_section_ref, $tsection[$j]);
}
}
}
}
############################ SCAN IDL ############################
# Scan IDL File forming lists of interface ids, type definitions and stubs
# Results returned in global variables
# $num_of_interfaces
# @interface_ids
# %num_of_stubs
# @%stub_return_container
# @%stub_name_container
# @%stub_para_container
sub ScanIDL
{
my $idl_file = @_[0];
$typedef_table{"void"}[0] = "void";
$typedef_table{"short"}[0] = "CORBA_short";
$typedef_table{"unsigned short"}[0] = "CORBA_unsigned_short";
$typedef_table{"long"}[0] = "CORBA_long";
$typedef_table{"unsigned long"}[0] = "CORBA_unsigned_long";
$typedef_table{"long long"}[0] = "CORBA_long_long";
$typedef_table{"unsigned long long"}[0] = "CORBA_unsigned_long_long";
$typedef_table{"float"}[0] = "CORBA_float";
$typedef_table{"double"}[0] = "CORBA_double";
$typedef_table{"long double"}[0] = "CORBA_long_double";
$typedef_table{"boolean"}[0] = "CORBA_boolean";
$typedef_table{"octet"}[0] = "CORBA_octet";
$typedef_table{"char"}[0] = "CORBA_char";
$typedef_table{"string"}[0] = "CORBA_char*";
$local_symbol_size = 0;
open (IDL, "< $idl_file")
or die ("Can't open server implementation file for input: $idl_file");
$num_of_interfaces = 0;
$group{"\{"} = 0;
$group{"\}"} = 0;
$group{"\["} = 0;
$group{"\]"} = 0;
$group{"\("} = 0;
$group{"\)"} = 0;
$group{"\/\*"} = 0;
$group{"\*\/"} = 0;
$group{";"} = 0;
$pstring = "";
$processed = 1;
while ($scanline = <IDL>)
{
chomp($scanline);
while ($scanline =~ /\\$/)
{
chop($scanline);
$scanline = $scanline . <IDL>;
chomp($scanline);
}
$scanline = "", if ($scanline =~ /\#[ ]*define/);
@line = split(/[ \t\n]+/, $scanline);
push(@list, @line);
while (($#list >= 0) && ($processed == 1))
{
do {
$string = shift(@list);
LOOP1:
{
$y = substr($string, pos($string)-1,1),
$group{$y}++, redo LOOP1,
if ($string =~ /[\{\}\[\]\(\);]|\/\*|\*\//gc);
}
$pstring = join(' ', $pstring, $string);
} while (((($group{"\{"} != $group{"\}"}) &&
($group{"\["} != $group{"\]"}) &&
($group{"\("} != $group{"\)"}) &&
($group{"\/\*"} != $group{"\*\/"})) ||
($group{";"} == 0)) && ($#list >= 0));
if (($group{"\{"} == $group{"\}"}) &&
($group{"\["} == $group{"\]"}) &&
($group{"\("} == $group{"\)"}))
{
$processed = ProcessBalanceGroup(\$pstring);
@line = split(/[ \t\n]+/, $pstring);
unshift(@list, @line);
$pstring = "";
$group{"\{"} = 0;
$group{"\}"} = 0;
$group{"\["} = 0;
$group{"\]"} = 0;
$group{"\("} = 0;
$group{"\)"} = 0;
$group{"\/\*"} = 0;
$group{"\*\/"} = 0;
$group{";"} = 0;
}
}
$processed = 1;
}
if (length($pstring) != 0)
{
print (STDERR "Error: Group unbalanced\n");
print (STDERR "$pstring\n");
}
if ($#list >= 0)
{
print (STDERR "Error: unprocessed\n");
while ($#list >=0)
{
print (STDERR " > ", shift(@list));
}
print (STDERR "\n\n");
}
close(IDL);
}
############## Collect Tokens into a balanced group ##############
sub ProcessBalanceGroup
{
my ($string_ref) = @_;
my $processed = 0;
SWITCH:
{
$$string_ref =~ /^[ ]*module[ ]+([\w]+)[ ]*\{(.+)\}[ ]*;$/gci &&
do {
$module_id = $1;
$id = $1;
$local_symbol_size++;
$local_symbol_list{"$local_symbol_size"}[0] = ();
$$string_ref = $2 . "<pop local symbols>;";
$processed = 1;
last SWITCH;
};
$$string_ref =~ /^[ ]*<pop local symbols>;$/gci &&
do {
$symbol_ref = @local_symbol_list{"$local_symbol_size"};
while ($#$symbol_ref >= 0)
{
$key = shift(@$symbol_ref);
$types_ref = @typedef_table{$key};
pop(@$types_ref);
}
$local_symbol_size--;
$$string_ref = "";
$processed = 1;
last SWITCH;
};
$$string_ref =~ /^[ ]*typedef[ ]+([ \w]+)[ ]+([\w]+)([ ]*|[ ]*\[[ ]*[\w]+[ ]*\]);$/gci &&
do {
$types_ref = @typedef_table{$2};
if (!defined($types_ref))
{
$typedef_table{$2}[0] = join('_',$id, $2);
}
else
{
push(@$types_ref, join('_',$id, $2));
}
$symbol_ref = @local_symbol_list{"$local_symbol_size"};
push(@$symbol_ref, $2);
$$string_ref = "";
$processed = 1;
last SWITCH;
};
$$string_ref =~ /^[ ]*struct[ ]+([\w]+)[ ]*\{.*\}[ ]*;$/gci &&
do {
$types_ref = @typedef_table{$1};
if (!defined($types_ref))
{
$typedef_table{$1}[0] = join('_',$id, $1);
}
else
{
push(@$types_ref, join('_',$id, $1));
}
$symbol_ref = @local_symbol_list{"$local_symbol_size"};
push(@$symbol_ref, $1);
$$string_ref = "";
$processed = 1;
last SWITCH;
};
$$string_ref =~ /^[ ]*enum[ ]+([\w]+)[ ]*\{.*\}[ ]*;$/gci &&
do {
$types_ref = @typedef_table{$1};
if (!defined($types_ref))
{
$typedef_table{$1}[0] = join('_',$id, $1);
}
else
{
push(@$types_ref, join('_',$id, $1));
}
$symbol_ref = @local_symbol_list{"$local_symbol_size"};
push(@$symbol_ref, $1);
$$string_ref = "";
$processed = 1;
last SWITCH;
};
$$string_ref =~ /^[ ]*interface[ ]+([\w]+)[ ]*\{(.+)\}[ ]*;$/gci &&
do {
$id = join("_", $module_id, $1);
@interface_ids[$num_of_interfaces] = $id;
$num_of_interfaces = $num_of_interfaces+1;
$local_symbol_size++;
$local_symbol_list{"$local_symbol_size"}[0] = ();
$$string_ref = $2 . "<pop local symbols>;";
$processed = 1;
last SWITCH;
};
$$string_ref =~ /^[ ]*([ \w]+)[ ]+([\w]+)[ ]*\(([ \w,]*)\)[ ]*;$/gci &&
do {
$para_list = $3;
$func_name = join ('_', $id, $2);
$types_ref = @typedef_table{$1};
$return = $$types_ref[$#types_ref];
$para = "";
PARA_LOOP:
{
if ($para_list =~ /[ ]*([\w]+)[ ]+([ \w]+)[ ]+([\w]+)[ ]*($|,)/gci)
{
$types_ref = @typedef_table{$2};
if (!defined($types_ref))
{
$type = join('_', $id, $2);
print (STDERR "WARNING: using potentially unknown data type ($type)\n");
}
else
{
$type = $$types_ref[$#types_ref];
}
$var_name = $3;
if ($1 =~ /out/) {$type = $type . "*";}
$para = $para . $type . " " . $var_name. ", ";
redo PARA_LOOP;
}
}
chop($para); chop($para);
$stub_return_container{$id}[$num_of_stubs{$id}] = $return;
$stub_name_container{$id}[$num_of_stubs{$id}] = $func_name;
$stub_para_container{$id}[$num_of_stubs{$id}] = $para;
$num_of_stubs{$id}++;
$$string_ref = "";
$processed = 1;
last SWITCH;
};
$$string_ref =~ s/\/\*.*\*\///gci &&
do {
$processed = 1;
last SWITCH;
};
}
return $processed;
}
/******************************************************************************/
/* <creation string> */
/* Copyright Andrew Bainbridge-Smith and CSIRO, 28 March 2001 */
/* Distributed under GPL licence */
/******************************************************************************/
/******************************************************************************/
/* <include> */
/******************************************************************************/
<sub section>
<if standalone server>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/wait.h>
<sub section>
#include <orb/orbit.h>
#include <ORBitservices/CosNaming.h>
#include "<basename>.h"
/******************************************************************************/
/* <include> */
/******************************************************************************/
/******************************************************************************/
/* <constants> */
/******************************************************************************/
<sub section>
<if standalone server>
#define ORBIT_NAME_SERVER_DAEMONIZER "./nsd"
#define MAX_IOR_LENGTH 1024
<sub section>
/******************************************************************************/
/* <constants> */
/******************************************************************************/
/******************************************************************************/
/* <data structures> */
/******************************************************************************/
typedef struct {
POA_<interface id> servant;
PortableServer_POA poa;
} POAHooks_<interface id>;
/* <data structures> */
/******************************************************************************/
/* <function prototypes> */
/******************************************************************************/
static <interface id> <interface id>__create
(PortableServer_POA poa,
CORBA_Environment* ev);
static void <interface id>__destroy
(POAHooks_<interface id>* servant,
CORBA_Environment* ev);
static void <interface id>_server_init
(CORBA_ORB orb,
CORBA_Environment* ev);
<sub section>
static <stub return> impl_<stubname>
(POAHooks_<interface id>* servant,
<stub parameters>,
CORBA_Environment* ev);
<sub section>
/* <function prototypes> */
/* <function prototypes> */
<if standalone server>int get_naming_service_ior(char ior[]);
/* <function prototypes> */
/******************************************************************************/
/* <global variables> */
/******************************************************************************/
static PortableServer_ServantBase__epv <interface id>_base_epv =
{
NULL, /* _private data */
NULL, /* finalize routine */
NULL, /* default_POA routine */
};
static POA_<interface id>__epv <interface id>_epv =
{
NULL, /* _private */
(gpointer) & impl_<stubname>,
};
static POA_<interface id>__vepv <interface id>_vepv =
{
&<interface id>_base_epv,
&<interface id>_epv,
};
/* <global variables> */
/******************************************************************************/
/* <standalone server> */
/******************************************************************************/
int main
(int argc,
char* argv[])
{
CORBA_Environment ev;
CORBA_ORB orb;
CosNaming_NamingContext naming_service;
char ior[MAX_IOR_LENGTH];
int error_code;
/**************************************************************************/
/* Setup ORB */
/**************************************************************************/
CORBA_exception_init(&ev);
orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &ev);
if (ev._major != CORBA_NO_EXCEPTION)
{
fprintf(stderr, "Corba exception:: %s: %s\n",
(ev._major == CORBA_SYSTEM_EXCEPTION ? "System" : "User"),
CORBA_exception_id(&ev));
exit(1);
}
error_code = get_naming_service_ior (ior);
if (error_code != 0)
{
fprintf(stderr, "Error getting IOR of Naming Service (%d)\n\t%s\n",
error_code, strerror(errno));
exit(1);
}
naming_service = CORBA_ORB_string_to_object(orb, ior, &ev);
if (ev._major != CORBA_NO_EXCEPTION)
{
fprintf(stderr, "Corba exception:: %s: %s\n",
(ev._major == CORBA_SYSTEM_EXCEPTION ? "System" : "User"),
CORBA_exception_id(&ev));
exit(1);
}
orb->naming = naming_service;
/**************************************************************************/
/* Initialize Server */
/**************************************************************************/
<sub section>
<interface id>_server_init(orb, &ev);
if (ev._major != CORBA_NO_EXCEPTION)
{
fprintf(stderr, "Corba exception:: %s: %s\n",
(ev._major == CORBA_SYSTEM_EXCEPTION ? "System" : "User"),
CORBA_exception_id(&ev));
exit(1);
}
<sub section>
/**************************************************************************/
/* Run server --- loop forever and do not return */
/**************************************************************************/
CORBA_ORB_run(orb, &ev);
if (ev._major != CORBA_NO_EXCEPTION)
{
fprintf(stderr, "Corba exception:: %s: %s\n",
(ev._major == CORBA_SYSTEM_EXCEPTION ? "System" : "User"),
CORBA_exception_id(&ev));
exit(1);
}
}
/*********************** GET_NAMING_SERVICE_IOR ***********************/
/* */
/* Future enhancement --- allow multicast network ip and port-number to */
/* be passed to get_naming_service_ior() and used in call to */
/* ORBIT_NAME_SERVER_DAEMONIZER */
/* */
/* Future enhancement --- consider alternative to both this function */
/* and the program "nsd". Alternatives include: DHCP/bootp, INS, Jini, */
/* UPnP */
/******************************************************************************/
#define TESTLZ(call, code) \
{ int _status; if ((_status = (call)) < 0) return((code)); }
int get_naming_service_ior
(char ior[])
{
int terminated;
int child_pid;
int child_status;
int pipe_ends[2];
memset(ior, '\0', MAX_IOR_LENGTH);
/**********************************************************************/
/* Create pipe to talk to Name Service daemonizer */
/**********************************************************************/
TESTLZ(pipe(pipe_ends), 1);
/**********************************************************************/
/* Spawn child process which will run the Name Service */
/**********************************************************************/
if ((child_pid = fork()))
{
/******************************************************************/
/* Parent Process */
/* Read Name Service IOR from pipe and report result on STDOUT */
/******************************************************************/
read (pipe_ends[0], ior, MAX_IOR_LENGTH);
terminated = waitpid(child_pid, &child_status, WNOHANG);
}
else
{
/******************************************************************/
/* Child Process */
/* Close unnecessary files and set pipe_ends to stdin/stdout */
/******************************************************************/
/* Child Process */
(void)close(0);
(void)close(1);
TESTLZ((dup2(pipe_ends[0], 0)), 2);
TESTLZ((dup2(pipe_ends[1], 1)), 3);
(void)close(pipe_ends[0]);
(void)close(pipe_ends[1]);
/******************************************************************/
/* Exec Name service */
/******************************************************************/
TESTLZ(execlp(ORBIT_NAME_SERVER_DAEMONIZER,
ORBIT_NAME_SERVER_DAEMONIZER, NULL),
4);
/******************************************************************/
/* Shouldn't get passed here so signal error */
/******************************************************************/
return(5);
}
return(0);
}
/******************************************************************************/
/* <standalone server> */
/******************************************************************************/
/******************************************************************************/
/* <implementation> */
/******************************************************************************/
static <interface id> <interface id>__create
(PortableServer_POA poa,
CORBA_Environment* ev)
{
TCO_Commander retval;
POAHooks_<interface id>* newservant;
PortableServer_ObjectId* objid;
newservant = g_new0(POAHooks_<interface id>, 1);
newservant->servant.vepv = &<interface id>_vepv;
newservant->poa = poa;
POA_<interface id>__init((PortableServer_Servant) newservant, ev);
objid = PortableServer_POA_activate_object(poa, newservant, ev);
CORBA_free(objid);
retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);
return retval;
}
static void <interface id>__destroy
(POAHooks_<interface id>* servant,
CORBA_Environment* ev)
{
PortableServer_ObjectId* objid;
objid = PortableServer_POA_servant_to_id(servant->poa, servant, ev);
PortableServer_POA_deactivate_object(servant->poa, objid, ev);
CORBA_free(objid);
POA_<interface id>__fini((PortableServer_Servant) servant, ev);
g_free(servant);
}
static void <interface id>_server_init
(CORBA_ORB orb,
CORBA_Environment* ev)
{
<if local poa>PortableServer_POA <interface id>_poa;
PortableServer_POA root_poa;
PortableServer_POAManager root_poa_manager;
CosNaming_NamingContext naming_service;
CosNaming_NameComponent name_component[<local number NS components>];
CosNaming_Name server_name_binding;
CORBA_Object server_object;
/**************************************************************************/
/* Setup POA */
/**************************************************************************/
naming_service = (CosNaming_NamingContext)
CORBA_ORB_resolve_initial_references(orb, "NameService", ev);
if (ev->_major != CORBA_NO_EXCEPTION) return;
root_poa = (PortableServer_POA)
CORBA_ORB_resolve_initial_references(orb, "RootPOA", ev);
if (ev->_major != CORBA_NO_EXCEPTION) return;
root_poa_manager = PortableServer_POA__get_the_POAManager(root_poa, ev);
if (ev->_major != CORBA_NO_EXCEPTION) return;
<sub section>
<if local poa>
PortableServer_POA_create_poa(root_poa, "<interface id>_poa",
root_poa_manager, policy_list, ev);
if (ev->_major != CORBA_NO_EXCEPTION) return;
<interface id>_poa =
PortableServer_POA_find_poa(root_poa, "<interface id>_poa", ev);
if (ev->_major != CORBA_NO_EXCEPTION) return;
<sub section>
/**************************************************************************/
/* Initialize server object */
/**************************************************************************/
server_object = <interface id>__create(<local poa id>, ev);
if (ev->_major != CORBA_NO_EXCEPTION) return;
/**************************************************************************/
/* Bind server object to Name Service so that clients can find it */
/**************************************************************************/
<sub section>
name_component[<step NS component>].id = (CORBA_char*) malloc(strlen("<local name component id>")+1);
name_component[<step NS component>].kind = (CORBA_char*) malloc(strlen("<local name component kind>")+1);
strcpy(name_component[<step NS component>].id, "<local name component id>");
strcpy(name_component[<step NS component>].kind, "<local name component kind>");
<sub section>
server_name_binding._maximum = <local number NS components>;
server_name_binding._length = <local number NS components>;
server_name_binding._buffer = name_component;
server_name_binding._release = CORBA_FALSE;
CosNaming_NamingContext_bind(naming_service,
&server_name_binding,
server_object,
ev);
if (ev->_major != CORBA_NO_EXCEPTION) return;
/**************************************************************************/
/* Activate POA */
/**************************************************************************/
PortableServer_POAManager_activate(root_poa_manager, ev);
if (ev->_major != CORBA_NO_EXCEPTION) return;
}
/* <implementation> */
/******************************************************************************/
/* <creation string> */
/* Copyright Andrew Bainbridge-Smith and CSIRO, 28 March 2001 */
/* Distributed under GPL licence */
/******************************************************************************/
/******************************************************************************/
/* <include> */
/******************************************************************************/
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "orb/orbit.h"
#include "ORBitservices/CosNaming.h"
#include "<basename>.h"
/******************************************************************************/
/* <include> */
/******************************************************************************/
/******************************************************************************/
/* <constants> */
/******************************************************************************/
<sub section>
#define ORBIT_NAME_SERVER_DAEMONIZER "./nsd"
#define MAX_IOR_LENGTH 1024
<sub section>
/******************************************************************************/
/* <constants> */
/******************************************************************************/
/******************************************************************************/
/* <data structures> */
/******************************************************************************/
/* <data structures> */
/******************************************************************************/
/* <function prototypes> */
/******************************************************************************/
/* <function prototypes> */
/* <function prototypes> */
int get_naming_service_ior(char ior[]);
/* <function prototypes> */
/******************************************************************************/
/* <global variables> */
/******************************************************************************/
/* <global variables> */
/******************************************************************************/
/* <implementation> */
/******************************************************************************/
static void <interface id>_init_client
(CORBA_ORB orb,
<interface id>* object,
CORBA_Environment* ev)
{
CosNaming_NamingContext naming_service;
CosNaming_NameComponent name_component[<local number NS components>];
CosNaming_Name server_name_binding;
/**************************************************************************/
/* Resolve Binding to Server */
/**************************************************************************/
naming_service = (CosNaming_NamingContext)
CORBA_ORB_resolve_initial_references(orb, "NameService", ev);
if (ev->_major != CORBA_NO_EXCEPTION) return;
<sub section>
name_component[<step NS component>].id = (CORBA_char*) malloc(strlen("<local name component id>")+1);
name_component[<step NS component>].kind = (CORBA_char*) malloc(strlen("<local name component kind>")+1);
strcpy(name_component[<step NS component>].id, "<local name component id>");
strcpy(name_component[<step NS component>].kind, "<local name component kind>");
<sub section>
server_name_binding._maximum = <local number NS components>;
server_name_binding._length = <local number NS components>;
server_name_binding._buffer = name_component;
server_name_binding._release = CORBA_FALSE;
*object =
CosNaming_NamingContext_resolve(naming_service, &server_name_binding, ev);
if (ev->_major != CORBA_NO_EXCEPTION)
{
*object = NULL;
}
}
/******************************************************************************/
/* <implementation> */
/******************************************************************************/
/******************************************************************************/
/* <implementation> */
/******************************************************************************/
/*********************** GET_NAMING_SERVICE_IOR ***********************/
/* */
/* Future enhancement --- allow multicast network ip and port-number to */
/* be passed to get_naming_service_ior() and used in call to */
/* ORBIT_NAME_SERVER_DAEMONIZER */
/* */
/* Future enhancement --- consider alternative to both this function */
/* and the program "nsd". Alternatives include: DHCP/bootp, INS, Jini, */
/* UPnP */
/******************************************************************************/
#define TESTLZ(call, code) \
{ int _status; if ((_status = (call)) < 0) return((code)); }
int get_naming_service_ior
(char ior[])
{
int terminated;
int child_pid;
int child_status;
int pipe_ends[2];
memset(ior, '\0', MAX_IOR_LENGTH);
/**********************************************************************/
/* Create pipe to talk to Name Service daemonizer */
/**********************************************************************/
TESTLZ(pipe(pipe_ends), 1);
/**********************************************************************/
/* Spawn child process which will run the Name Service */
/**********************************************************************/
if ((child_pid = fork()))
{
/******************************************************************/
/* Parent Process */
/* Read Name Service IOR from pipe and report result on STDOUT */
/******************************************************************/
read (pipe_ends[0], ior, MAX_IOR_LENGTH);
terminated = waitpid(child_pid, &child_status, WNOHANG);
}
else
{
/******************************************************************/
/* Child Process */
/* Close unnecessary files and set pipe_ends to stdin/stdout */
/******************************************************************/
/* Child Process */
(void)close(0);
(void)close(1);
TESTLZ((dup2(pipe_ends[0], 0)), 2);
TESTLZ((dup2(pipe_ends[1], 1)), 3);
(void)close(pipe_ends[0]);
(void)close(pipe_ends[1]);
/******************************************************************/
/* Exec Name service */
/******************************************************************/
TESTLZ(execlp(ORBIT_NAME_SERVER_DAEMONIZER,
ORBIT_NAME_SERVER_DAEMONIZER, NULL),
4);
/******************************************************************/
/* Shouldn't get passed here so signal error */
/******************************************************************/
return(5);
}
return(0);
}
/******************************************************************************/
/* <implementation> */
/******************************************************************************/
/* Test example idl file */
module TCO {
#define MAX_ERROR_EVENTS 25
#define MAX_MESSAGE_LENGTH 80
#define MAX_FILENAME_LENGTH 80
typedef char EventMessage[MAX_MESSAGE_LENGTH];
typedef char EventFile[MAX_FILENAME_LENGTH];
struct structEventList{
long status;
long number_of_events;
long eventcodes[MAX_ERROR_EVENTS];
EventMessage eventmessage[MAX_ERROR_EVENTS];
EventFile eventfile[MAX_ERROR_EVENTS];
long eventline[MAX_ERROR_EVENTS];
};
typedef structEventList EventList;
interface Commander {
void SetStatus (in string status_field,
in long value,
inout EventList error_events);
void GetStatus (in string status_field,
out long value,
inout EventList error_events);
void Shutdown ();
};
};
/* Example test file. Note all the structed comments required */
/* Should also compile as a standalone program (not client/server) */
/* <include> */
/* <sub section> */
/* <client only> */
#include <stdio.h>
/* <sub section> */
/* <include> */
/* <constants> */
/*<sub section> */
/* <client only> */
#define MAX_ERROR_EVENTS 25
#define MAX_MESSAGE_LENGTH 80
#define MAX_FILENAME_LENGTH 80
/*<sub section> */
/* <constants> */
/* <data structures> */
/*<sub section> */
/* <client only> */
typedef char EventMessage[MAX_MESSAGE_LENGTH];
typedef char EventFile[MAX_FILENAME_LENGTH];
typedef struct structEventList{
long status;
long number_of_events;
long eventcodes[MAX_ERROR_EVENTS];
EventMessage eventmessage[MAX_ERROR_EVENTS];
EventFile eventfile[MAX_ERROR_EVENTS];
long eventline[MAX_ERROR_EVENTS];
} EventList;
/* <sub section> */
/* <data structures> */
/* <Global Variables> */
/* <sub section> */
/* <server only> */
int balance = 0;
/* <sub section> */
/* <Global Variables> */
/*****************************************************************************/
/* <Naming Components TCO::Commander> */
/* <namepair Hymod server> */
/* <Naming Components> */
/*****************************************************************************/
/* <End of Preamble> */
/* SERVER IMPLEMENTATION */
/* <Service TCO::Commander::SetStatus> */
static void
SetStatus(char* status_field,
int value,
EventList* error_events)
{
if (strcmp(status_field,"Balance") == 0)
{
balance = value;
}
if (strcmp(status_field,"Deposit") == 0)
{
balance = balance+value;
}
}
/* <Service> */
/* <Service TCO::Commander::GetStatus> */
static void
GetStatus(char* status_field,
int* value,
EventList* error_events)
{
if (strcmp(status_field,"Balance") == 0)
{
*value=balance;
}
else
{
*value=0;
}
}
/* <Service> */
/* <Service TCO::Commander::Shutdown> */
void
Shutdown()
{
exit(0);
}
/* <Service> */
/* <CLIENT> */
int main (int argc, char* argv[])
{
int value;
EventList error_events;
/* <corba init> */
SetStatus ("Balance", 100, &error_events);
GetStatus ("Balance", &value, &error_events);
printf ("Set Balance to %d (cf. 100)\n", value);
value = value/4;
SetStatus ("Deposit", value, &error_events);
GetStatus ("Balance", &value, &error_events);
printf ("After deposit balance is %d (cf. 125)\n", value);
Shutdown ();
printf ("Shutdown server --- next call should fail\n");
GetStatus ("Balance", &value, &error_events);
printf ("After shutdown balance is %d (cf. 0 or UNDEF)\n", value);
return(0);
}
/* <CLIENT> */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]