Re: Private variable ?



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]