testexecmgmt/ucc/BinInternal/rpcgen/ae_component_rpc.c
changeset 0 3da2a79470a7
equal deleted inserted replaced
-1:000000000000 0:3da2a79470a7
       
     1 /*
       
     2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  
       
    15 * System Includes
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 #include <stdio.h>
       
    22 #include <assert.h>
       
    23 #include <stdlib.h>
       
    24 #include <string.h>
       
    25 #include <ctype.h>
       
    26 #include <time.h>
       
    27 #include "rpc_util.h"
       
    28 #include "rpc_pars.h"
       
    29 #include "rpc_scan.h"
       
    30 
       
    31 
       
    32 /*********************************************************************
       
    33  *
       
    34  * Local Includes
       
    35  *
       
    36  ********************************************************************/
       
    37 #include "ae_component_rpc.h"
       
    38 
       
    39 
       
    40 /*********************************************************************
       
    41  *
       
    42  * Definitions
       
    43  *
       
    44  ********************************************************************/
       
    45 #define BANNER_START "/****************************************************************************************\n"
       
    46 #define BANNER_LINE  " * "
       
    47 #define BANNER_END   " ***************************************************************************************/\n"
       
    48 
       
    49 
       
    50 /*********************************************************************
       
    51  *
       
    52  * Macro Functions
       
    53  *
       
    54  ********************************************************************/
       
    55 #define O(x)	     f_print(fout,x);
       
    56 
       
    57 
       
    58 /*********************************************************************
       
    59  *
       
    60  * Types
       
    61  *
       
    62  ********************************************************************/
       
    63 typedef void (*header_func_t)(char *filename, definition *program);
       
    64 typedef void (*footer_func_t)(definition *program);
       
    65 typedef void (*proc_func_t)(definition *program,proc_list *proc, char *version);
       
    66 
       
    67 
       
    68 /*********************************************************************
       
    69  *
       
    70  * Prototypes
       
    71  *
       
    72  ********************************************************************/
       
    73 void open_input( char *infile, char *define );
       
    74 void open_output( char *infile, char *outfile );
       
    75 char *extendfile( char *file, char *ext );
       
    76 char *locase( char *str);
       
    77 
       
    78 // filename related helpers
       
    79 void PrintStartDefs( definition *def );
       
    80 void PrintEndDefs( definition *def );
       
    81 void PrintIncludeInterfaceHeader();
       
    82 
       
    83 // banners
       
    84 void PrintFileBanner( char *filename );
       
    85 void PrintBanner( char *title );
       
    86 void PrintAutogenBanner( char *filename );
       
    87 void PrintAutogenModBanner( char *filename );
       
    88 
       
    89 // classname helpers
       
    90 char *ComponentClassname( definition *def );
       
    91 char *ClientComponentClassname( definition *def );
       
    92 char *ServiceManagerClassname( definition *def );
       
    93 
       
    94 // function helpers
       
    95 void PrintClientStubSignature( int indent, char *classname, proc_list *proc );
       
    96 void PrintComponentInstanceMethodSignature( char *classname, definition *program, proc_list *proc );
       
    97 void PrintSetErrorValue( int indent, definition *program, proc_list *proc, char *error );
       
    98 int IsSetErrorCallRequired( proc_list *proc );
       
    99 void PrintServiceCheck( definition *program, proc_list *proc );
       
   100 void PrintCallFromServiceStubToInstance( definition *program, proc_list *proc, char *extraargs );
       
   101 void PrintCallFromServiceStubToStatic( definition *program, proc_list *proc, char *extra_args );
       
   102 
       
   103 // misc helpers
       
   104 char *ucase( char *str );
       
   105 void trace( int indent, definition *program, proc_list *proc, char *fname, int enter );
       
   106 
       
   107 // service stub implementations
       
   108 void output_header_service_implementation( char *filename, definition *program );
       
   109 void output_footer_service_implementation( definition *program );
       
   110 void output_proc_service_implementation( definition *program, proc_list *proc, char *version );
       
   111 void output_std_proc_service_implementation( definition *program, proc_list *proc );
       
   112 void output_cstr_proc_service_implementation( definition *program, proc_list *proc );
       
   113 void output_dstr_proc_service_implementation( definition *program, proc_list *proc );
       
   114 void output_startup_proc_service_implementation( definition *program, proc_list *proc );
       
   115 void output_shutdown_proc_service_implementation( definition *program, proc_list *proc );
       
   116 void output_list_proc_service_implementation( definition *program, proc_list *proc );
       
   117 void output_static_proc_service_implementation( definition *program, proc_list *proc );
       
   118 
       
   119 // service manager class header
       
   120 void output_header_svc_header( char *filename, definition *program );
       
   121 void output_footer_svc_header( definition *program );
       
   122 void output_proc_svc_header( definition *program, proc_list *proc, char *version );
       
   123 
       
   124 // service manager class cpp
       
   125 void output_header_svc_cpp( char *filename, definition *program );
       
   126 void output_footer_svc_cpp( definition *program );
       
   127 void output_proc_svc_cpp( definition *program, proc_list *proc, char *version );
       
   128 
       
   129 // server component class header
       
   130 void output_header_inst_header( char *filename, definition *program );
       
   131 void output_footer_inst_header( definition *program );
       
   132 void output_proc_inst_header( definition *program, proc_list *proc, char *version );
       
   133 
       
   134 // server component class cpp
       
   135 void output_header_inst_cpp( char *filename, definition *program );
       
   136 void output_footer_inst_cpp( definition *program );
       
   137 void output_proc_inst_cpp( definition *program, proc_list *proc, char *version );
       
   138 
       
   139 // client component stub class header
       
   140 void output_header_stub_header( char *filename, definition *program );
       
   141 void output_footer_stub_header( definition *program );
       
   142 void output_proc_stub_header( definition *program, proc_list *proc, char *version );
       
   143 
       
   144 // client component stub class cpp
       
   145 void output_header_stub_cpp( char *filename, definition *program );
       
   146 void output_footer_stub_cpp( definition *program );
       
   147 void output_proc_stub_cpp( definition *program, proc_list *proc, char *version );
       
   148 void output_proc_stub_cpp_std( definition *program, proc_list *proc, char *version );
       
   149 
       
   150 
       
   151 /*********************************************************************
       
   152  *
       
   153  * Static Vars
       
   154  *
       
   155  ********************************************************************/
       
   156 static header_func_t hf[] = { output_header_service_implementation, output_header_svc_header, output_header_svc_cpp,	output_header_inst_header,	output_header_inst_cpp,	output_header_stub_header,	output_header_stub_cpp	};
       
   157 static footer_func_t ff[] = { output_footer_service_implementation, output_footer_svc_header, output_footer_svc_cpp,	output_footer_inst_header,	output_footer_inst_cpp,	output_footer_stub_header,	output_footer_stub_cpp	};
       
   158 static proc_func_t   pf[] = { output_proc_service_implementation,   output_proc_svc_header,	  output_proc_svc_cpp,		output_proc_inst_header,	output_proc_inst_cpp,	output_proc_stub_header,	output_proc_stub_cpp	};
       
   159 
       
   160 static char *input_filename;
       
   161 static int gtype;
       
   162 static int trace_points[7] = { 0 };
       
   163 
       
   164 /*********************************************************************
       
   165  *
       
   166  * ae_output_rpc_file()
       
   167  *
       
   168  ********************************************************************/
       
   169 void ae_output_rpc_file( char *infile, char *outfile, int type )
       
   170 {
       
   171 	char tmpfilename[128];
       
   172 	char *outfilename;
       
   173 	int foundprogram = 0;
       
   174 	definition *def, *def_program;
       
   175 	version_list *vp;
       
   176 	proc_list *proc;
       
   177 
       
   178 	// save some stuff for use down the chain
       
   179 	input_filename = infile;
       
   180 	gtype = type;
       
   181 
       
   182 	// open the input file 
       
   183 	open_input( infile, "-DRPC_SVC" );
       
   184 
       
   185 	// look for the program definition
       
   186 	while( (def = get_definition()) ) {
       
   187 		if( def->def_kind == DEF_PROGRAM ) {
       
   188 			def_program = def;
       
   189 			foundprogram++;
       
   190 		}
       
   191 	}
       
   192 
       
   193 	// if there is no program then exit 
       
   194 	if( foundprogram == 0 ) {
       
   195 		return;
       
   196 	}
       
   197 
       
   198 	// open the output file
       
   199 	if( (type == TYPE_SVC_MGR_H) || (type == TYPE_SVC_MGR_C) ) {
       
   200 		sprintf( tmpfilename, "%s", ServiceManagerClassname(def_program) );
       
   201 		infile = tmpfilename;
       
   202 	} else if( (type == TYPE_INST_H) || (type == TYPE_INST_C) ) {
       
   203 		sprintf( tmpfilename, "%s", ComponentClassname(def_program) );
       
   204 		infile = tmpfilename;
       
   205 	} else if( (type == TYPE_CLIENT_H) || (type == TYPE_CLIENT_C) ) {
       
   206 		sprintf( tmpfilename, "%s", ClientComponentClassname(def_program) );
       
   207 		infile = tmpfilename;
       
   208 	}
       
   209 	outfilename = extendfile(infile, outfile);
       
   210 	open_output( infile, outfilename );
       
   211 
       
   212 	// if there is more than one program then say I don't handle this
       
   213 	if( foundprogram > 1 ) {
       
   214 		fprintf( stderr, "ERROR: PR0094 modifications can't handle multiple program definitions in a single file.\n" );
       
   215 		return;
       
   216 	}
       
   217 
       
   218 	// I also don't handle multiple versions in a single file
       
   219 	vp = def_program->def.pr.versions;
       
   220 	if( vp->next != NULL ) {
       
   221 		fprintf( stderr, "ERROR: PR0094 modifications can't handle multiple program versions in a single file.\n" );
       
   222 		return;
       
   223 	}
       
   224 
       
   225 	// HOOK: Insert header code
       
   226 	hf[type]( outfilename, def_program );
       
   227 
       
   228 	// process each procedure
       
   229 	for( proc = vp->procs; proc != NULL; proc = proc->next ) {
       
   230 		// HOOK: Insert proc code
       
   231 		pf[type]( def_program, proc, vp->vers_num );
       
   232 	}
       
   233 
       
   234 	// HOOK: Insert footer code
       
   235 	ff[type]( def_program );
       
   236 
       
   237 	// done
       
   238 	return;
       
   239 }
       
   240 
       
   241 
       
   242 /*********************************************************************
       
   243  *
       
   244  * SECTION: Service Stub Implementation
       
   245  *
       
   246  ********************************************************************/
       
   247 
       
   248 /*********************************************************************
       
   249  *
       
   250  * Service Stub Implementation -- START
       
   251  *
       
   252  ********************************************************************/
       
   253 void output_header_service_implementation( char *filename, definition *program )
       
   254 {
       
   255 	// output the autogen banner
       
   256 	PrintAutogenBanner( filename );
       
   257 
       
   258 	// output the system includes
       
   259 	PrintBanner( "System Includes" );
       
   260 	f_print( fout, "#include <assert.h>\n" );
       
   261 
       
   262 	// output the local includes
       
   263 	PrintBanner( "Local Includes" );
       
   264 	f_print( fout, "#include \"%s.h\"\n", ServiceManagerClassname(program) );
       
   265 	f_print( fout, "#include \"%s.h\"\n", ComponentClassname(program) );
       
   266 	f_print( fout, "#include \"CComponentManager.h\"\n" );
       
   267 
       
   268 	// output the static variables
       
   269 	PrintBanner( "Static Variables" );
       
   270 	f_print( fout, "static CComponentManager<%s> *iComponentManager;\n", ComponentClassname(program) );
       
   271 }
       
   272 
       
   273 
       
   274 /*********************************************************************
       
   275  *
       
   276  * Service Stub Implementation -- END
       
   277  *
       
   278  ********************************************************************/
       
   279 void output_footer_service_implementation( definition *program )
       
   280 {
       
   281 }
       
   282 
       
   283 
       
   284 /*********************************************************************
       
   285  *
       
   286  * Service Stub Implementation -- METHOD GENERATION (TOP LEVEL)
       
   287  *
       
   288  ********************************************************************/
       
   289 void output_proc_service_implementation( definition *program, proc_list *proc, char *version )
       
   290 {
       
   291 	char str[512];
       
   292 
       
   293 	// print banner
       
   294 	sprintf( str, "PUBLIC FUNCTION: %s", locase(proc->proc_name) );
       
   295 	PrintBanner( str );
       
   296 
       
   297 	// print the function signature
       
   298 	ptype( proc->res_prefix, proc->res_type, 1 );
       
   299 	f_print( fout, "*");
       
   300 	pvname( proc->proc_name, version );
       
   301 	f_print(fout, "( ");
       
   302 	ptype( proc->arg_prefix, proc->arg_type, 1 );
       
   303 	f_print(fout, "*aArgs, CLIENT *aDutout )\n");
       
   304 
       
   305 	// demux based on the name of the prefix
       
   306 	if( strncmp(proc->proc_name,"SS_",3) == 0 ) {
       
   307 		output_startup_proc_service_implementation( program, proc );
       
   308 	} else if( strncmp(proc->proc_name,"SC_",3) == 0 ) {
       
   309 		output_shutdown_proc_service_implementation( program, proc );
       
   310 	} else if( strncmp(proc->proc_name,"CSTR_",5) == 0 ) {
       
   311 		output_cstr_proc_service_implementation( program, proc );
       
   312 	} else if( strncmp(proc->proc_name,"DSTR_",5) == 0 ) {
       
   313 		output_dstr_proc_service_implementation( program, proc );
       
   314 	} else if( strncmp(proc->proc_name,"LIST_",5) == 0 ) {
       
   315 		output_list_proc_service_implementation( program, proc );
       
   316 	} else if( strncmp(proc->proc_name,"ST_",3) == 0 ) {
       
   317 		output_static_proc_service_implementation( program, proc );
       
   318 	} else {
       
   319 		output_std_proc_service_implementation( program, proc );
       
   320 	}
       
   321 }
       
   322 
       
   323 
       
   324 /*********************************************************************
       
   325  *
       
   326  * Service Stub Implementation -- METHOD GENERATION (STANDARD METHODS)
       
   327  *
       
   328  ********************************************************************/
       
   329 void output_std_proc_service_implementation( definition *program, proc_list *proc )
       
   330 {
       
   331 	int void_return_type = 0;
       
   332 
       
   333 	// start
       
   334 	f_print( fout, "{\n" );
       
   335 
       
   336 	// check for void return value
       
   337 	if( strncmp(proc->res_type,"void",4) == 0 ) {
       
   338 		void_return_type = 1;
       
   339 	}
       
   340 
       
   341 	// declare variables
       
   342 	f_print( fout, "\tstatic " );
       
   343 	if( void_return_type == 0 ) {
       
   344 		ptype( proc->res_prefix, proc->res_type, 1 );
       
   345 	} else {
       
   346 		f_print( fout, "int " );
       
   347 	}	
       
   348 	f_print( fout, "rv;\n");
       
   349 	f_print( fout, "\tint instance_key;\n" );
       
   350 	f_print( fout, "\t%s *session;\n\n", ComponentClassname(program) );
       
   351 	trace( 1, program, proc, NULL, 1 );
       
   352 
       
   353 	// check that the service is already started
       
   354 	PrintServiceCheck( program, proc );
       
   355 
       
   356 	// set the return value to generic error
       
   357 	O( "\t// set the return value to generic error\n" );
       
   358 	PrintSetErrorValue( 1, program, proc, "ERR_FAILED_TO_RETRIEVE_KEY" );
       
   359 	f_print( fout, "\n" );
       
   360 
       
   361 	// get the key for the instance from the args
       
   362 	O( "\t// get the key for the instance from the args\n" );
       
   363 	f_print( fout, "\tinstance_key = %s::GetInstanceKeyFromArgs( %s, (void*)aArgs );\n", ServiceManagerClassname(program), proc->proc_name );
       
   364 	O( "\tif( instance_key < 0 ) {\n" );
       
   365 	trace( 2, program, proc, NULL, 0 );
       
   366 	O( "\t\treturn &rv;\n" );
       
   367 	O( "\t}\n" );
       
   368 	O( "\n" );
       
   369 
       
   370 	// make sure the key is valid
       
   371 	O( "\t// make sure the key is valid\n" );
       
   372 	O( "\tif( iComponentManager->IsValidKey(instance_key) == 0 ) {\n" );		
       
   373 	PrintSetErrorValue( 2, program, proc, "ERR_INSTANCE_DOES_NOT_EXIST" );
       
   374 	O( "\t\treturn &rv;\n" );
       
   375 	O( "\t}\n" );
       
   376 	O( "\n" );
       
   377 	
       
   378 	// get the instance
       
   379 	O( "\t// get the instance\n" );
       
   380 	O( "\tsession = iComponentManager->GetInstance( instance_key );\n" );
       
   381 	O( "\tassert( session != NULL );\n" );
       
   382 	O( "\n" );
       
   383 
       
   384 	// call the corresponding method on the instance and return the result
       
   385 	PrintCallFromServiceStubToInstance( program, proc, NULL );
       
   386 	trace( 1, program, proc, NULL, 0 );
       
   387 	f_print( fout, "\treturn &rv;\n" );
       
   388 	f_print( fout, "}\n" );
       
   389 }
       
   390 
       
   391 
       
   392 /*********************************************************************
       
   393  *
       
   394  * Service Stub Implementation -- METHOD GENERATION (STATIC METHODS)
       
   395  *
       
   396  ********************************************************************/
       
   397 void output_static_proc_service_implementation( definition *program, proc_list *proc )
       
   398 {
       
   399 	int void_return_type = 0;
       
   400 
       
   401 	// start
       
   402 	f_print( fout, "{\n" );
       
   403 
       
   404 	// check for void return value
       
   405 	if( strncmp(proc->res_type,"void",4) == 0 ) {
       
   406 		void_return_type = 1;
       
   407 	}
       
   408 
       
   409 	// declare the return variable
       
   410 	f_print( fout, "\tstatic " );
       
   411 	if( void_return_type == 0 ) {
       
   412 		ptype( proc->res_prefix, proc->res_type, 1 );
       
   413 	} else {
       
   414 		f_print( fout, "int " );
       
   415 	}	
       
   416 	f_print( fout, "rv;\n");
       
   417 	trace( 1, program, proc, NULL, 1 );
       
   418 	O( "\n" );
       
   419 
       
   420 	// check that the service is already started
       
   421 	PrintServiceCheck( program, proc );
       
   422 
       
   423 	// call the corresponding method on the instance and return the result
       
   424 	PrintCallFromServiceStubToStatic( program, proc, NULL );
       
   425 	trace( 1, program, proc, NULL, 0 );
       
   426 	f_print( fout, "\treturn &rv;\n" );
       
   427 	f_print( fout, "}\n" );
       
   428 }
       
   429 
       
   430 
       
   431 /*********************************************************************
       
   432  *
       
   433  * Service Stub Implementation -- METHOD GENERATION (CSTR METHODS)
       
   434  *
       
   435  ********************************************************************/
       
   436 void output_cstr_proc_service_implementation( definition *program, proc_list *proc )
       
   437 {
       
   438 	int integer_return_type;
       
   439 
       
   440 	// start
       
   441 	f_print( fout, "{\n" );
       
   442 
       
   443 	// a void return type is illegal for a cstr_ method
       
   444 	if( strncmp(proc->res_type,"void",4) == 0 ) {
       
   445 		fprintf( stderr, "ERROR: 'cstr_' methods must not have void return type.\n" );
       
   446 		return;
       
   447 	}
       
   448 
       
   449 	// declare variables
       
   450 	f_print( fout, "\tstatic " );
       
   451 	ptype( proc->res_prefix, proc->res_type, 1 );
       
   452 	f_print( fout, "rv;\n" );
       
   453 	f_print( fout, "\tint result;\n" );
       
   454 	f_print( fout, "\tint internal_err;\n" );
       
   455 	f_print( fout, "\tint instance_key;\n" );
       
   456 	f_print( fout, "\t%s *session;\n", ComponentClassname(program) );
       
   457 	trace( 1, program, proc, NULL, 1 );
       
   458 	O( "\n" );
       
   459 	
       
   460 	// check that the service is already started
       
   461 	PrintServiceCheck( program, proc );
       
   462 
       
   463 	// create a new component instance
       
   464 	O( "\t// create a new component instance\n" );
       
   465 	O( "\tinstance_key = iComponentManager->CreateInstance();\n" );
       
   466 	O( "\tif( instance_key < 0 ) {\n" );
       
   467 	PrintSetErrorValue( 2, program, proc, "instance_key" );
       
   468 	trace( 2, program, proc, NULL, 0 );
       
   469 	O( "\t\treturn &rv;\n" );
       
   470 	O( "\t}\n\n" );
       
   471 
       
   472 	// get the instance
       
   473 	O( "\t// get the instance\n" );
       
   474 	O( "\tsession = iComponentManager->GetInstance( instance_key );\n" );
       
   475 	O( "\tassert( session != NULL );\n" );
       
   476 	O( "\n" );
       
   477 
       
   478 	// call the corresponding method on the instance
       
   479 	PrintCallFromServiceStubToInstance( program, proc, NULL );
       
   480 
       
   481 	// now extract the top level error code
       
   482 	integer_return_type = IsSetErrorCallRequired( proc );
       
   483 	if( integer_return_type == 0 ) {
       
   484 		f_print( fout, "\tresult = rv;\n" );
       
   485 	} else {
       
   486 		f_print( fout, "\tresult = %s::GetError( %s, (void*)&rv );\n", ServiceManagerClassname(program), proc->proc_name );
       
   487 	}
       
   488 	O( "\n" );
       
   489 
       
   490 	// if the method fails then we cleanup the instance -- otherwise we set the instance key
       
   491 	// as the return value
       
   492 	O( "\t// if the method fails then we cleanup the instance -- otherwise we set the instance key\n" );
       
   493 	O( "\t// as the return value\n" );
       
   494 	O( "\tif( result != ERR_NONE ) {\n" );
       
   495 	O( "\t\tinternal_err = iComponentManager->DeleteInstance( instance_key );\n" );
       
   496 	O( "\t\tassert( internal_err == 0 );\n" );
       
   497 	O( "\t} else { \n" );
       
   498 	PrintSetErrorValue( 2, program, proc, "instance_key" );
       
   499 	O( "\t}\n" );
       
   500 	O( "\n" );
       
   501 
       
   502 	// done
       
   503 	f_print( fout, "\t// done\n" );
       
   504 	trace( 1, program, proc, NULL, 0 );
       
   505 	f_print( fout, "\treturn &rv;\n" );
       
   506 	f_print( fout, "}\n" );
       
   507 }
       
   508 
       
   509 
       
   510 /*********************************************************************
       
   511  *
       
   512  * Service Stub Implementation -- METHOD GENERATION (DSTR METHODS)
       
   513  *
       
   514  ********************************************************************/
       
   515 void output_dstr_proc_service_implementation( definition *program, proc_list *proc )
       
   516 {
       
   517 	int integer_return_type;
       
   518 
       
   519 	// start
       
   520 	f_print( fout, "{\n" );
       
   521 
       
   522 	// declare variables
       
   523 	f_print( fout, "\tstatic " );
       
   524 	ptype( proc->res_prefix, proc->res_type, 1 );
       
   525 	f_print( fout, "rv;\n" );
       
   526 	f_print( fout, "\tint result;\n" );
       
   527 	f_print( fout, "\tint internal_err;\n" );
       
   528 	f_print( fout, "\tint instance_key;\n" );
       
   529 	f_print( fout, "\tint should_delete = 1;\n" );
       
   530 	f_print( fout, "\t%s *session;\n\n", ComponentClassname(program) );
       
   531 	trace( 1, program, proc, NULL, 1 );
       
   532 	
       
   533 	// check that the service is already started
       
   534 	PrintServiceCheck( program, proc );
       
   535 
       
   536 	// get the key for the instance from the args
       
   537 	O( "\t// get the key for the instance from the args\n" );
       
   538 	f_print( fout, "\tinstance_key = %s::GetInstanceKeyFromArgs( %s, (void*)aArgs );\n", ServiceManagerClassname(program), proc->proc_name );
       
   539 	O( "\tif( instance_key < 0 ) {\n" );
       
   540 	PrintSetErrorValue( 2, program, proc, "instance_key" );
       
   541 	trace( 2, program, proc, NULL, 0 );
       
   542 	O( "\t\treturn &rv;\n" );
       
   543 	O( "\t}\n" );
       
   544 
       
   545 	// make sure the key is valid
       
   546 	O( "\t// make sure the key is valid\n" );
       
   547 	O( "\tif( iComponentManager->IsValidKey(instance_key) == 0 ) {\n" );		
       
   548 	PrintSetErrorValue( 2, program, proc, "ERR_INSTANCE_DOES_NOT_EXIST" );
       
   549 	O( "\t\treturn &rv;\n" );
       
   550 	O( "\t}\n" );
       
   551 	O( "\n" );
       
   552 
       
   553 	// get the instance
       
   554 	O( "\t// get the instance\n" );
       
   555 	O( "\tsession = iComponentManager->GetInstance( instance_key );\n" );
       
   556 	O( "\tassert( session != NULL );\n" );
       
   557 	O( "\n" );
       
   558 
       
   559 	// call the corresponding method on the instance
       
   560 	PrintCallFromServiceStubToInstance( program, proc, "&should_delete" );
       
   561 	O( "\n" );
       
   562 
       
   563 	// now extract the top level error code
       
   564 	integer_return_type = IsSetErrorCallRequired( proc );
       
   565 	if( integer_return_type == 0 ) {
       
   566 		f_print( fout, "\tresult = rv;\n" );
       
   567 	} else {
       
   568 		f_print( fout, "\tresult = %s::GetError( %s, (void*)&rv );\n", ServiceManagerClassname(program), proc->proc_name );
       
   569 	}
       
   570 	O( "\n" );
       
   571 
       
   572 	// it is illegal for the method to succeed but not delete the instance
       
   573 	O( "\t// it is illegal for the method to succeed but not delete the instance\n" );	
       
   574 	O( "\tassert( (result != ERR_NONE) || (should_delete == 1) );\n\n" );
       
   575 
       
   576 	// delete the instance if requested
       
   577 	O( "\t// delete the instance if requested\n" );
       
   578 	O( "\tif( should_delete != 0 ) {\n" );
       
   579 	O( "\t\tinternal_err = iComponentManager->DeleteInstance( instance_key );\n" );
       
   580 	O( "\t\tassert( internal_err == ERR_NONE );\n" );
       
   581 	O( "\t}\n\n" );
       
   582 
       
   583 	// done
       
   584 	f_print( fout, "\t// done\n" );
       
   585 	trace( 1, program, proc, NULL, 0 );
       
   586 	f_print( fout, "\treturn &rv;\n" );
       
   587 	f_print( fout, "}\n" );
       
   588 }
       
   589 
       
   590 
       
   591 /*********************************************************************
       
   592  *
       
   593  * Service Stub Implementation -- METHOD GENERATION (STARTUP METHODS)
       
   594  *
       
   595  ********************************************************************/
       
   596 void output_startup_proc_service_implementation( definition *program, proc_list *proc )
       
   597 {
       
   598 	// check the function's signature
       
   599 	if( strcmp(proc->res_type,"int") != 0 ) {
       
   600 		fprintf( stderr, "ERROR: 'SS_' method has the incorrect return type. Must be 'int'.\n" );
       
   601 	}
       
   602 
       
   603 	// start
       
   604 	f_print( fout, "{\n" );
       
   605 
       
   606 	// declare variables
       
   607 	f_print( fout, "\tstatic int rv;\n" );
       
   608 	trace( 1, program, proc, NULL, 1 );
       
   609 
       
   610 	// check that the service isn't already started
       
   611 	f_print( fout, "\n" );
       
   612 	f_print( fout, "\t// if the service is already started then return an error\n" );
       
   613 	f_print( fout, "\tif( iComponentManager != NULL ) {\n" );
       
   614 	f_print( fout, "\t\trv = ERR_SERVICE_ALREADY_STARTED;\n" );
       
   615 	trace( 2, program, proc, NULL, 0 );
       
   616 	f_print( fout, "\t\treturn &rv;\n" );
       
   617 	f_print( fout, "\t}\n" );
       
   618 
       
   619 	// create the component manager
       
   620 	f_print( fout, "\n" );
       
   621 	f_print( fout, "\t// create the component manager\n" );
       
   622 	f_print( fout, "\tiComponentManager = new CComponentManager<%s>( INFO_MAXIMUM_OBJECTS );\n", ComponentClassname(program) );
       
   623 	f_print( fout, "\tif( iComponentManager == NULL ) {\n" );
       
   624 	f_print( fout, "\t\trv = ERR_FAILED_TO_CREATE_COMPONENT_MANAGER;\n" );
       
   625 	trace( 2, program, proc, NULL, 0 );
       
   626 	f_print( fout, "\t\treturn &rv;\n" );
       
   627 	f_print( fout, "\t}\n" );
       
   628 
       
   629 	// call the service manager
       
   630 	f_print( fout, "\n" );
       
   631 	f_print( fout, "\t// call the custom service manager\n" );
       
   632 	f_print( fout, "\trv = %s::StartRPCService( iComponentManager, aArgs );\n", ServiceManagerClassname(program) );
       
   633 	f_print( fout, "\tif( rv != ERR_NONE ) {\n" );
       
   634 	f_print( fout, "\t\tdelete iComponentManager;\n" );
       
   635 	f_print( fout, "\t\tiComponentManager = NULL;\n" );
       
   636 	trace( 2, program, proc, NULL, 0 );
       
   637 	f_print( fout, "\t\treturn &rv;\n" );
       
   638 	f_print( fout, "\t}\n" );
       
   639 
       
   640 	// done
       
   641 	f_print( fout, "\n" );
       
   642 	f_print( fout, "\t// success\n" );
       
   643 	f_print( fout, "\trv = ERR_NONE;\n" );
       
   644 	trace( 1, program, proc, NULL, 0 );
       
   645 	f_print( fout, "\treturn &rv;\n" );
       
   646 	f_print( fout, "}\n" );
       
   647 }
       
   648 
       
   649 
       
   650 /*********************************************************************
       
   651  *
       
   652  * Service Stub Implementation -- METHOD GENERATION (SHUTDOWN METHODS)
       
   653  *
       
   654  ********************************************************************/
       
   655 void output_shutdown_proc_service_implementation( definition *program, proc_list *proc )
       
   656 {
       
   657 	// check the function's signature
       
   658 	if( strcmp(proc->res_type,"int") != 0 ) {
       
   659 		fprintf( stderr, "ERROR: 'SC_' method has the incorrect return type. Must be 'int'.\n" );
       
   660 	}
       
   661 	if( strcmp(proc->arg_type,"int") != 0 ) {
       
   662 		fprintf( stderr, "ERROR: 'SC_' method has the incorrect argument type. Must be 'int'.\n" );
       
   663 	}
       
   664 
       
   665 	// start
       
   666 	f_print( fout, "{\n" );
       
   667 
       
   668 	// declare variables
       
   669 	f_print( fout, "\tstatic int rv;\n" );
       
   670 	f_print( fout, "\tint instance_count;\n" );
       
   671 	f_print( fout, "\tint err;\n" );
       
   672 	trace( 1, program, proc, NULL, 1 );
       
   673 	f_print( fout, "\n" );
       
   674 	
       
   675 	// check that the service is already started
       
   676 	PrintServiceCheck( program, proc );
       
   677 
       
   678 	// check for active sessions
       
   679 	f_print( fout, "\t// if there are active sessions and the force flag isn't set then return an error\n" );
       
   680 	f_print( fout, "\tinstance_count = iComponentManager->GetInstanceCount();\n" );
       
   681 	f_print( fout, "\tif( (instance_count > 0) && (*aArgs == 0) ) {\n" );
       
   682 	f_print( fout, "\t\trv = ERR_ACTIVE_USER_SESSIONS;\n" );
       
   683 	trace( 2, program, proc, NULL, 0 );
       
   684 	f_print( fout, "\t\treturn &rv;\n" );
       
   685 	f_print( fout, "\t};\n" );
       
   686 
       
   687 	f_print( fout, "\n" );
       
   688 	f_print( fout, "\t// if the force flag IS set then reset all active connections\n" );
       
   689 	f_print( fout, "\tinstance_count = iComponentManager->GetInstanceCount();\n" );
       
   690 	f_print( fout, "\tif( instance_count > 0 ) {\n" );
       
   691 	f_print( fout, "\t\terr = iComponentManager->DeleteAllInstances();\n" );
       
   692 	f_print( fout, "\t\tif( err != 0 ) {\n" ); 
       
   693 	f_print( fout, "\t\t\trv = ERR_FAILED_TO_REMOVE_ACTIVE_SESSIONS;\n" );
       
   694 	trace( 3, program, proc, NULL, 0 );
       
   695 	f_print( fout, "\t\t\treturn &rv;\n" );
       
   696 	f_print( fout, "\t\t}\n" );
       
   697 	f_print( fout, "\t}\n" );
       
   698 
       
   699 	// call the service manager
       
   700 	f_print( fout, "\n" );
       
   701 	f_print( fout, "\t// call the custom service manager\n" );
       
   702 	f_print( fout, "\trv = %s::StopRPCService();\n", ServiceManagerClassname(program) );
       
   703 	f_print( fout, "\tif( rv != ERR_NONE ) {\n" );
       
   704 	trace( 2, program, proc, NULL, 0 );
       
   705 	f_print( fout, "\t\treturn &rv;\n" );
       
   706 	f_print( fout, "\t}\n" );
       
   707 	
       
   708 	// delete the component manager
       
   709 	f_print( fout, "\n" );
       
   710 	f_print( fout, "\t// delete the component manager\n" );
       
   711 	f_print( fout, "\tdelete iComponentManager;\n" );
       
   712 	f_print( fout, "\tiComponentManager = NULL;\n" );
       
   713 
       
   714 	// done
       
   715 	f_print( fout, "\n" );
       
   716 	f_print( fout, "\t// success\n" );
       
   717 	f_print( fout, "\trv = ERR_NONE;\n" );
       
   718 	trace( 1, program, proc, NULL, 0 );
       
   719 	f_print( fout, "\treturn &rv;\n" );
       
   720 	f_print( fout, "}\n" );
       
   721 }
       
   722 
       
   723 
       
   724 /*********************************************************************
       
   725  *
       
   726  * Service Stub Implementation -- METHOD GENERATION (LIST METHODS)
       
   727  *
       
   728  ********************************************************************/
       
   729 void output_list_proc_service_implementation( definition *program, proc_list *proc )
       
   730 {
       
   731 	int void_return_type = 0;
       
   732 
       
   733 	// check that the signature is correct
       
   734 	if( strcmp(proc->res_type,"TComponentList") != 0 ) {
       
   735 		fprintf( stderr, "ERROR: 'LIST_' method has incorrect return type. Must be TComponentList.\n" );
       
   736 		return;
       
   737 	}
       
   738 	if( strcmp(proc->arg_type,"void") != 0 ) {
       
   739 		fprintf( stderr, "ERROR: 'LIST_' method has incorrect argument type. Must be void.\n" );
       
   740 		return;
       
   741 	}
       
   742 
       
   743 	// start
       
   744 	f_print( fout, "{\n" );
       
   745 
       
   746 	// check for void return value
       
   747 	if( strncmp(proc->res_type,"void",4) == 0 ) {
       
   748 		void_return_type = 1;
       
   749 	}
       
   750 
       
   751 	// declare variables
       
   752 	f_print( fout, "\tstatic " );
       
   753 	if( void_return_type == 0 ) {
       
   754 		ptype( proc->res_prefix, proc->res_type, 1 );
       
   755 	} else {
       
   756 		f_print( fout, "int " );
       
   757 	}	
       
   758 	f_print( fout, "rv;\n");
       
   759 	f_print( fout, "\tint i, valid_count, component_instance_count;\n" );
       
   760 	f_print( fout, "\n" );
       
   761 	trace( 1, program, proc, NULL, 1 );
       
   762 
       
   763 	// free any allocate memory
       
   764 	O( "\t//free any allocated memory\n" );
       
   765 	O( "\tif( rv.TComponentList_val != NULL ) {\n" );
       
   766 	O( "\t\tfree( rv.TComponentList_val );\n" );
       
   767 	O( "\t\trv.TComponentList_val = NULL;\n" );
       
   768 	O( "\t\trv.TComponentList_len = 0;\n" );
       
   769 	O( "\t}\n" );
       
   770 	O( "\n" );
       
   771 
       
   772 	// check that the service is already started
       
   773 	PrintServiceCheck( program, proc );
       
   774 
       
   775 	// set the return value to generic error
       
   776 	O( "\t// set the return value to generic error\n" );
       
   777 	PrintSetErrorValue( 1, program, proc, "ERR_FAILED_TO_RETRIEVE_KEY" );
       
   778 	f_print( fout, "\n" );
       
   779 
       
   780 	// get the number of active component instances
       
   781 	O( "\t// get the number of active component instances\n" );
       
   782 	O( "\tcomponent_instance_count = iComponentManager->GetInstanceCount();\n" );
       
   783 	O( "\n" );
       
   784 	O( "\t// if there are one or more instances then allocate the memory\n" );
       
   785 	O( "\tif( component_instance_count > 0 ) {\n" );
       
   786 	O( "\t\trv.TComponentList_val = (int*)malloc( sizeof(int) * component_instance_count );\n" );
       
   787 	O( "\t\tassert( rv.TComponentList_val != NULL );\n" );
       
   788 	O( "\t\trv.TComponentList_len = component_instance_count;\n" );
       
   789 	O( "\t}\n" );
       
   790 	O( "\n" );
       
   791 
       
   792 	// set the values
       
   793 	O( "\t// store all the currently active IDs in the list\n" );
       
   794 	O( "\tfor( i = 0, valid_count = 0; i < INFO_MAXIMUM_OBJECTS; i++ ) {\n" );
       
   795 	O( "\t\tif( iComponentManager->IsValidKey(i) != 0 ) {\n" );
       
   796 	O( "\t\t\tassert( valid_count < component_instance_count );\n" );
       
   797 	O( "\t\t\t(rv.TComponentList_val)[valid_count++] = i;\n" );
       
   798 	O( "\t\t}\n" );
       
   799 	O( "\t}\n" );
       
   800 	O( "\n" );
       
   801 
       
   802 	// ok finish up
       
   803 	O( "\t// ok return everything\n" );
       
   804 	f_print( fout, "\treturn &rv;\n" );
       
   805 	f_print( fout, "}\n" );
       
   806 }
       
   807 
       
   808 /*********************************************************************
       
   809  *
       
   810  * SECTION: Service Manager Definition (HEADER FILE)
       
   811  *
       
   812  ********************************************************************/
       
   813 
       
   814 /*********************************************************************
       
   815  *
       
   816  * Service Manager Definition -- START
       
   817  *
       
   818  ********************************************************************/
       
   819 void output_header_svc_header( char *filename, definition *program )
       
   820 {
       
   821 	char cname[256];
       
   822 
       
   823 	// output the autogen banner
       
   824 	PrintAutogenModBanner( filename );
       
   825 	PrintStartDefs( program );
       
   826 
       
   827 	// output the local includes
       
   828 	PrintBanner( "Local Includes" );
       
   829 	PrintIncludeInterfaceHeader();
       
   830 	f_print( fout, "#include \"%s.h\"\n", ComponentClassname(program) );
       
   831 	f_print( fout, "#include \"CComponentManager.h\"\n" );
       
   832 
       
   833 	// output the definition banner
       
   834 	sprintf( cname, "Definition: %s", ServiceManagerClassname(program) );
       
   835 	PrintBanner( cname );
       
   836 
       
   837 	// output the definition 
       
   838 	f_print( fout, "class %s\n{\n", ServiceManagerClassname(program) );
       
   839 	f_print( fout, "public:\n" );
       
   840 	f_print( fout, "\t/* standard methods */\n" );
       
   841 	f_print( fout, "\tstatic int GetInstanceKeyFromArgs( int aMethod, void *aArgs );\n" );
       
   842 	f_print( fout, "\tstatic int SetError( int aMethod, void *aArgs, int aError );\n" );
       
   843 	f_print( fout, "\tstatic int GetError( int aMethod, void *aArgs );\n" );
       
   844 }
       
   845 
       
   846 
       
   847 /*********************************************************************
       
   848  *
       
   849  * Service Manager Definition -- END
       
   850  *
       
   851  ********************************************************************/
       
   852 void output_footer_svc_header( definition *program )
       
   853 {
       
   854 	f_print( fout, "};\n" );
       
   855 	PrintEndDefs( program );
       
   856 }
       
   857 
       
   858 
       
   859 /*********************************************************************
       
   860  *
       
   861  * Service Manager Definition -- METHOD GENERATION
       
   862  *
       
   863  ********************************************************************/
       
   864 void output_proc_svc_header( definition *program, proc_list *proc, char *version )
       
   865 {
       
   866 	static int custom_comment_written = 0;
       
   867 
       
   868 	// the StartRPCService function takes the argument to the SS_ function.
       
   869 	if( strncmp(proc->proc_name,"SS_",3) == 0 ) {
       
   870 		f_print( fout, "\tstatic int StartRPCService( CComponentManager<%s> *aComponentManager, %s *aArg );\n", ComponentClassname(program), proc->arg_type );
       
   871 	}
       
   872 
       
   873 	// the StopRPCService function takes no params
       
   874 	if( strncmp(proc->proc_name,"SC_",3) == 0 ) {
       
   875 		f_print( fout, "\tstatic int StopRPCService();\n" );
       
   876 	}
       
   877 
       
   878 	// print the header for any static methods
       
   879 	if( strncmp(proc->proc_name,"ST_",3) == 0 ) {
       
   880 		if( custom_comment_written == 0 ) {
       
   881 			f_print( fout, "\n\t/* custom methods */\n" );
       
   882 			custom_comment_written = 1;
       
   883 		}
       
   884 		f_print( fout, "\tstatic " );
       
   885 		PrintComponentInstanceMethodSignature( NULL, program, proc );
       
   886 		f_print( fout, ";\n" );
       
   887 	}
       
   888 }
       
   889 
       
   890 
       
   891 /*********************************************************************
       
   892  *
       
   893  * SECTION: Service Manager Implementation (CPP FILE)
       
   894  *
       
   895  ********************************************************************/
       
   896 
       
   897 /*********************************************************************
       
   898  *
       
   899  * Service Manager Implementation -- START
       
   900  *
       
   901  ********************************************************************/
       
   902 void output_header_svc_cpp( char *filename, definition *program )
       
   903 {
       
   904 	proc_list *proc;
       
   905 
       
   906 	// output the autogen banner
       
   907 	PrintAutogenModBanner( filename );
       
   908 
       
   909 	// output the system includes
       
   910 	PrintBanner( "System Includes" );
       
   911 	f_print( fout, "#include <stdio.h>\n" );
       
   912 
       
   913 	// output the local includes
       
   914 	PrintBanner( "Local Includes" );
       
   915 	f_print( fout, "#include \"%s.h\"\n", ServiceManagerClassname(program) );
       
   916 	PrintIncludeInterfaceHeader();
       
   917 
       
   918 	// file-scope statics
       
   919 	PrintBanner( "File-scope variables" );
       
   920 	f_print( fout, "static CComponentManager<%s> *iComponentManager;\n", ComponentClassname(program) );
       
   921 
       
   922 	// output the implementation banner
       
   923 	PrintBanner( "Implementation" );
       
   924 
       
   925 	// output GetInstanceKeyFromArgs
       
   926 	PrintBanner( "PUBLIC: GetInstanceKeyFromArgs" );
       
   927 	f_print( fout, "int %s::GetInstanceKeyFromArgs( int aMethod, void *aArgs )\n", ServiceManagerClassname(program) );
       
   928 	f_print( fout, "{\n" );
       
   929 	f_print( fout, "\tint rv;\n" );
       
   930 	trace( 1, program, NULL, "GetInstanceKeyFromArgs", 1 );
       
   931 	f_print( fout, "\tswitch( aMethod ) {\n" );
       
   932 	for( proc = (program->def.pr.versions)->procs; proc != NULL; proc = proc->next ) {
       
   933 		if( strncmp(proc->proc_name,"SS_",3) != 0 ) {
       
   934 			if( strncmp(proc->proc_name,"SC_",3) != 0 ) {
       
   935 				if( strncmp(proc->proc_name,"LIST_",5) != 0 ) {
       
   936 					if( strncmp(proc->proc_name,"CSTR_",5) != 0 ) {
       
   937 						if( strncmp(proc->proc_name,"ST_",3) != 0 ) {
       
   938 							f_print( fout, "\tcase %s:\n", proc->proc_name );
       
   939 						}
       
   940 					}
       
   941 				}
       
   942 			}
       
   943 		}
       
   944 	}
       
   945 	f_print( fout, "\tdefault:\n" );
       
   946 	f_print( fout, "\t\trv = ERR_INVALID_METHOD;\n" );
       
   947 	f_print( fout, "\t\tbreak;\n" );
       
   948 	f_print( fout, "\t}\n" );
       
   949 	trace( 1, program, NULL, "GetInstanceKeyFromArgs", 0 );
       
   950 	f_print( fout, "\treturn rv;\n" );
       
   951 	f_print( fout, "}\n" );
       
   952 
       
   953 	// output SetError
       
   954 	PrintBanner( "PUBLIC: SetError" );
       
   955 	f_print( fout, "int %s::SetError( int aMethod, void *aArgs, int aError )\n", ServiceManagerClassname(program) );
       
   956 	f_print( fout, "{\n" );
       
   957 	f_print( fout, "\tint rv;\n" );
       
   958 	trace( 1, program, NULL, "SetError", 1 );
       
   959 	f_print( fout, "\tswitch( aMethod ) {\n" );
       
   960 	for( proc = (program->def.pr.versions)->procs; proc != NULL; proc = proc->next ) {
       
   961 		if( IsSetErrorCallRequired(proc) ) {
       
   962 			f_print( fout, "\tcase %s:\n", proc->proc_name );
       
   963 		}
       
   964 	}
       
   965 	f_print( fout, "\tdefault:\n" );
       
   966 	f_print( fout, "\t\trv = ERR_INVALID_METHOD;\n" );
       
   967 	f_print( fout, "\t\tbreak;\n" );
       
   968 	f_print( fout, "\t}\n" );
       
   969 	trace( 1, program, NULL, "SetError", 0 );
       
   970 	f_print( fout, "\treturn rv;\n" );
       
   971 	f_print( fout, "}\n" );
       
   972 
       
   973 	// output GetError
       
   974 	PrintBanner( "PUBLIC: GetError" );
       
   975 	f_print( fout, "int %s::GetError( int aMethod, void *aArgs )\n", ServiceManagerClassname(program) );
       
   976 	f_print( fout, "{\n" );
       
   977 	f_print( fout, "\tint rv = ERR_NONE;\n" );
       
   978 	trace( 1, program, NULL, "GetError", 1 );
       
   979 	f_print( fout, "\tswitch( aMethod ) {\n" );
       
   980 	for( proc = (program->def.pr.versions)->procs; proc != NULL; proc = proc->next ) {
       
   981 		if( IsSetErrorCallRequired(proc) ) {
       
   982 			f_print( fout, "\tcase %s:\n", proc->proc_name );
       
   983 		}
       
   984 	}
       
   985 	f_print( fout, "\tdefault:\n" );
       
   986 	f_print( fout, "\t\tassert( \"!INVALID CALL\" );\n" );
       
   987 //	f_print( fout, "\t\trv = ERR_INVALID_METHOD;\n" );
       
   988 	f_print( fout, "\t\tbreak;\n" );
       
   989 	f_print( fout, "\t}\n" );
       
   990 	trace( 1, program, NULL, "GetError", 0 );
       
   991 	f_print( fout, "\treturn rv;\n" );
       
   992 	f_print( fout, "}\n" );
       
   993 
       
   994 }
       
   995 
       
   996 
       
   997 /*********************************************************************
       
   998  *
       
   999  * Service Manager Implementation -- END
       
  1000  *
       
  1001  ********************************************************************/
       
  1002 void output_footer_svc_cpp( definition *program )
       
  1003 {
       
  1004 }
       
  1005 
       
  1006 
       
  1007 /*********************************************************************
       
  1008  *
       
  1009  * Service Manager Implementation -- METHOD GENERATION
       
  1010  *
       
  1011  ********************************************************************/
       
  1012 void output_proc_svc_cpp( definition *program, proc_list *proc, char *version )
       
  1013 {
       
  1014 	int void_return_type = 0;
       
  1015 	char str[512];
       
  1016 
       
  1017 	// output StartService
       
  1018 	if( strncmp(proc->proc_name,"SS_",3) == 0 ) {
       
  1019 		PrintBanner( "PUBLIC: StartRPCService" );
       
  1020 		f_print( fout, "int %s::StartRPCService( CComponentManager<%s> *aComponentManager, %s *aArg )\n", ServiceManagerClassname(program), ComponentClassname(program), proc->arg_type );
       
  1021 		f_print( fout, "{\n" );
       
  1022 		trace( 1, program, NULL, "StartRPCService", 1 );
       
  1023 		f_print( fout, "\tassert( iComponentManager == NULL );\n" );
       
  1024 		f_print( fout, "\tiComponentManager = aComponentManager;\n" );
       
  1025 		trace( 1, program, NULL, "StartRPCService", 0 );
       
  1026 		f_print( fout, "\treturn ERR_NONE;\n" );
       
  1027 		f_print( fout, "}\n" );
       
  1028 	}
       
  1029 
       
  1030 	// output StopRPCService
       
  1031 	if( strncmp(proc->proc_name,"SC_",3) == 0 ) {
       
  1032 		PrintBanner( "PUBLIC: StopRPCService" );
       
  1033 		f_print( fout, "int %s::StopRPCService()\n", ServiceManagerClassname(program) );
       
  1034 		f_print( fout, "{\n" );
       
  1035 		trace( 1, program, NULL, "StopRPCService", 1 );
       
  1036 		f_print( fout, "\tiComponentManager = NULL;\n" );
       
  1037 		trace( 1, program, NULL, "StopRPCService", 0 );
       
  1038 		f_print( fout, "\treturn ERR_NONE;\n" );
       
  1039 		f_print( fout, "}\n" );
       
  1040 	}
       
  1041 
       
  1042 	// if this isn't a static method then exit
       
  1043 	if( strncmp(proc->proc_name,"ST_",3) != 0 ) {
       
  1044 		return;
       
  1045 	}
       
  1046 
       
  1047 	// print banner
       
  1048 	_snprintf( str, 512, "PUBLIC: %s", locase(proc->proc_name) );
       
  1049 	PrintBanner( str );
       
  1050 
       
  1051 	// print the function signature
       
  1052 	PrintComponentInstanceMethodSignature( ServiceManagerClassname(program), program, proc );
       
  1053 	f_print( fout, "\n");
       
  1054 
       
  1055 	// check if the returntype is void
       
  1056 	if( strncmp(proc->res_type,"void",4) == 0 ) {
       
  1057 		void_return_type = 1;
       
  1058 	}
       
  1059 
       
  1060 	// open the function
       
  1061 	f_print( fout, "{\n" );
       
  1062 
       
  1063 	// declare the return value
       
  1064 	if( void_return_type == 0 ) {
       
  1065 		f_print( fout, "\t" );
       
  1066 		ptype( proc->res_prefix, proc->res_type, 1 );
       
  1067 		f_print( fout, "rv;\n" );
       
  1068 		trace( 1, program, proc, NULL, 1 );
       
  1069 		PrintSetErrorValue( 1, program, proc, "ERR_NONE" );
       
  1070 	} else {
       
  1071 		trace( 1, program, proc, NULL, 1 );
       
  1072 	}
       
  1073 
       
  1074 	// return the value
       
  1075 	trace( 1, program, proc, NULL, 0 );
       
  1076 	if( void_return_type == 0 ) {
       
  1077 		f_print( fout, "\treturn rv;\n" );
       
  1078 	}
       
  1079 
       
  1080 	// close the function
       
  1081 	f_print( fout, "}\n" );
       
  1082 }
       
  1083 
       
  1084 
       
  1085 /*********************************************************************
       
  1086  *
       
  1087  * SECTION: Service Component Definition (HEADER FILE)
       
  1088  *
       
  1089  ********************************************************************/
       
  1090 
       
  1091 /*********************************************************************
       
  1092  *
       
  1093  * Service Component Definition - START
       
  1094  *
       
  1095  ********************************************************************/
       
  1096 void output_header_inst_header( char *filename, definition *program )
       
  1097 {
       
  1098 	char cname[256];
       
  1099 
       
  1100 	// output the file banner
       
  1101 	PrintAutogenModBanner( filename );
       
  1102 	PrintStartDefs( program );
       
  1103 
       
  1104 	// output the local includes
       
  1105 	PrintBanner( "Local Includes" );
       
  1106 	PrintIncludeInterfaceHeader();
       
  1107 
       
  1108 	// output the definition banner
       
  1109 	sprintf( cname, "Definition: %s", ComponentClassname(program) );
       
  1110 	PrintBanner( cname );
       
  1111 
       
  1112 	// output the definition 
       
  1113 	f_print( fout, "class %s\n{\n", ComponentClassname(program) );
       
  1114 	f_print( fout, "public:\n" );
       
  1115 	f_print( fout, "\t// Standard Methods\n" );
       
  1116 	f_print( fout, "\t%s();\n", ComponentClassname(program) );
       
  1117 	f_print( fout, "\t~%s();\n", ComponentClassname(program) );
       
  1118 	f_print( fout, "\tint GetKey();\n" );
       
  1119 	f_print( fout, "\tvoid SetKey( int aKey );\n" );
       
  1120 	f_print( fout, "\n" );
       
  1121 	f_print( fout, "\t// RPC Service Methods\n" );
       
  1122 }
       
  1123 
       
  1124 
       
  1125 /*********************************************************************
       
  1126  *
       
  1127  * Service Component Definition - END
       
  1128  *
       
  1129  ********************************************************************/
       
  1130 void output_footer_inst_header( definition *program )
       
  1131 {
       
  1132 	f_print( fout, "\n" );
       
  1133 	f_print( fout, "private:\n" );
       
  1134 	f_print( fout, "\tint iKey;\n" );
       
  1135 	f_print( fout, "};\n" );
       
  1136 	PrintEndDefs( program );
       
  1137 }
       
  1138 
       
  1139 
       
  1140 /*********************************************************************
       
  1141  *
       
  1142  * Service Component Definition - METHOD GENERATION
       
  1143  *
       
  1144  ********************************************************************/
       
  1145 void output_proc_inst_header( definition *program, proc_list *proc, char *version )
       
  1146 {
       
  1147 	// ss and sc methods aren't included in the component
       
  1148 	if( strncmp(proc->proc_name,"SS_",3) == 0 ) {
       
  1149 		return;
       
  1150 	}
       
  1151 	if( strncmp(proc->proc_name,"SC_",3) == 0 ) {
       
  1152 		return;
       
  1153 	}
       
  1154 	if( strncmp(proc->proc_name,"LIST_",5) == 0 ) {
       
  1155 		return;
       
  1156 	}
       
  1157 	if( strncmp(proc->proc_name,"ST_",3) == 0 ) {
       
  1158 		return;
       
  1159 	}
       
  1160 	// print the function signature
       
  1161 	f_print( fout, "\t" );
       
  1162 	PrintComponentInstanceMethodSignature( NULL, program, proc );
       
  1163 	f_print( fout, ";\n" );
       
  1164 }
       
  1165 
       
  1166 
       
  1167 /*********************************************************************
       
  1168  *
       
  1169  * SECTION: Service Component Implementation 
       
  1170  *
       
  1171  ********************************************************************/
       
  1172 
       
  1173 /*********************************************************************
       
  1174  *
       
  1175  * Service Component Implementation - START
       
  1176  *
       
  1177  ********************************************************************/
       
  1178 void output_header_inst_cpp( char *filename, definition *program )
       
  1179 {
       
  1180 	// output the system includes
       
  1181 	PrintAutogenModBanner( filename );
       
  1182 	PrintFileBanner( "System Includes" );
       
  1183 	f_print( fout, "#include <stdio.h>\n" );
       
  1184 
       
  1185 	// output the local includes
       
  1186 	PrintBanner( "Local Includes" );
       
  1187 	f_print( fout, "#include \"%s.h\"\n", ServiceManagerClassname(program) );
       
  1188 	f_print( fout, "#include \"%s.h\"\n", ComponentClassname(program) );
       
  1189 
       
  1190 	// output the implementation banner
       
  1191 	PrintBanner( "Implementation" );
       
  1192 
       
  1193 	// output the impl for the constructor
       
  1194 	f_print( fout, "%s::%s()\n", ComponentClassname(program), ComponentClassname(program) );
       
  1195 	f_print( fout, "{\n" );
       
  1196 	trace( 1, program, NULL, "Constructor", 1 );
       
  1197 	trace( 1, program, NULL, "Constructor", 0 );
       
  1198 	f_print( fout, "}\n\n" );
       
  1199 
       
  1200 	// output the impl for the destructor
       
  1201 	f_print( fout, "%s::~%s()\n", ComponentClassname(program), ComponentClassname(program) );
       
  1202 	f_print( fout, "{\n" );
       
  1203 	trace( 1, program, NULL, "Destructor", 1 );
       
  1204 	trace( 1, program, NULL, "Destructor", 0 );
       
  1205 	f_print( fout, "}\n\n" );
       
  1206 
       
  1207 	// output the impl for get key
       
  1208 	f_print( fout, "int %s::GetKey()\n", ComponentClassname(program) );
       
  1209 	f_print( fout, "{\n" );
       
  1210 	trace( 1, program, NULL, "GetKey", 1 );
       
  1211 	trace( 1, program, NULL, "GetKey", 0 );
       
  1212 	f_print( fout, "\treturn iKey;\n" );
       
  1213 	f_print( fout, "}\n\n" );
       
  1214 
       
  1215 	// output the impl for set key
       
  1216 	f_print( fout, "void %s::SetKey( int aKey )\n", ComponentClassname(program) );
       
  1217 	f_print( fout, "{\n" );
       
  1218 	trace( 1, program, NULL, "SetKey", 1 );
       
  1219 	f_print( fout, "\tiKey = aKey;\n" );
       
  1220 	trace( 1, program, NULL, "SetKey", 0 );
       
  1221 	f_print( fout, "}\n" );
       
  1222 }
       
  1223 
       
  1224 
       
  1225 /*********************************************************************
       
  1226  *
       
  1227  * Service Component Implementation - END
       
  1228  *
       
  1229  ********************************************************************/
       
  1230 void output_footer_inst_cpp( definition *program )
       
  1231 {
       
  1232 }
       
  1233 
       
  1234 
       
  1235 /*********************************************************************
       
  1236  *
       
  1237  * Service Component Implementation - METHOD GENERATION
       
  1238  *
       
  1239  ********************************************************************/
       
  1240 void output_proc_inst_cpp( definition *program, proc_list *proc, char *version )
       
  1241 {
       
  1242 	char str[256];
       
  1243 	int void_return_type = 0;
       
  1244 
       
  1245 	// ss and sc methods aren't included in the component
       
  1246 	if( strncmp(proc->proc_name,"SS_",3) == 0 ) {
       
  1247 		return;
       
  1248 	}
       
  1249 	if( strncmp(proc->proc_name,"SC_",3) == 0 ) {
       
  1250 		return;
       
  1251 	}
       
  1252 	if( strncmp(proc->proc_name,"LIST_",5) == 0 ) {
       
  1253 		return;
       
  1254 	}
       
  1255 	if( strncmp(proc->proc_name,"ST_",3) == 0 ) {
       
  1256 		return;
       
  1257 	}
       
  1258 
       
  1259 	// print banner
       
  1260 	sprintf( str, "PUBLIC FUNCTION: %s", locase(proc->proc_name) );
       
  1261 	PrintBanner( str );
       
  1262 
       
  1263 	// print the function signature
       
  1264 	PrintComponentInstanceMethodSignature( ComponentClassname(program), program, proc );
       
  1265 	f_print( fout, "\n");
       
  1266 
       
  1267 	// check if the returntype is void
       
  1268 	if( strncmp(proc->res_type,"void",4) == 0 ) {
       
  1269 		void_return_type = 1;
       
  1270 	}
       
  1271 
       
  1272 	// open the function
       
  1273 	f_print( fout, "{\n" );
       
  1274 
       
  1275 	// declare the return value
       
  1276 	if( void_return_type == 0 ) {
       
  1277 		f_print( fout, "\t" );
       
  1278 		ptype( proc->res_prefix, proc->res_type, 1 );
       
  1279 		f_print( fout, "rv;\n" );
       
  1280 		trace( 1, program, proc, NULL, 1 );
       
  1281 		PrintSetErrorValue( 1, program, proc, "ERR_NONE" );
       
  1282 	} else {
       
  1283 		trace( 1, program, proc, NULL, 1 );
       
  1284 	}
       
  1285 
       
  1286 	// return the value
       
  1287 	trace( 1, program, proc, NULL, 0 );
       
  1288 	if( void_return_type == 0 ) {
       
  1289 		f_print( fout, "\treturn rv;\n" );
       
  1290 	}
       
  1291 
       
  1292 	// close the function
       
  1293 	f_print( fout, "}\n" );
       
  1294 }
       
  1295 
       
  1296 
       
  1297 /*********************************************************************
       
  1298  *
       
  1299  * SECTION - Client Stub Class Definition (HEADER FILE)
       
  1300  *
       
  1301  ********************************************************************/
       
  1302 
       
  1303 /*********************************************************************
       
  1304  *
       
  1305  * Client Stub Class Definition - START
       
  1306  *
       
  1307  ********************************************************************/
       
  1308 void output_header_stub_header( char *filename, definition *program )
       
  1309 {
       
  1310 	char cname[256];
       
  1311 
       
  1312 	// output the file banner
       
  1313 	PrintFileBanner( filename );
       
  1314 	PrintStartDefs( program );
       
  1315 
       
  1316 	// output the system includes
       
  1317 	PrintBanner( "System Includes" );
       
  1318 	O( "#include <rpc/rpc.h>\n" );
       
  1319 	O( "#include <string>\n" );
       
  1320 	O( "using namespace std;\n" );
       
  1321 	PrintIncludeInterfaceHeader();
       
  1322 
       
  1323 	// output the definition banner
       
  1324 	sprintf( cname, "Definition: %s", ClientComponentClassname(program) );
       
  1325 	PrintBanner( cname );
       
  1326 
       
  1327 	// output the definition 
       
  1328 	f_print( fout, "class %s\n{\n", ClientComponentClassname(program) );
       
  1329 	f_print( fout, "public:\n" );
       
  1330 	f_print( fout, "\t// standard methods\n" );
       
  1331 	f_print( fout, "\t%s();\n", ClientComponentClassname(program) );
       
  1332 	f_print( fout, "\t~%s();\n", ClientComponentClassname(program) );
       
  1333 	f_print( fout, "\tint Connect( string aRemoteHost );\n" );
       
  1334 	f_print( fout, "\tint Disconnect();\n" );
       
  1335 	f_print( fout, "\tchar *GetLastRPCError( int *aIntErr );\n" );
       
  1336 	f_print( fout, "\n" );
       
  1337 	f_print( fout, "\t// service methods\n" );
       
  1338 
       
  1339 }
       
  1340 
       
  1341 /*********************************************************************
       
  1342  *
       
  1343  * Client Stub Class Definition - END
       
  1344  *
       
  1345  ********************************************************************/
       
  1346 void output_footer_stub_header( definition *program )
       
  1347 {
       
  1348 	f_print( fout, "\n" );
       
  1349 	f_print( fout, "private:\n" );
       
  1350 	f_print( fout, "\tstruct rpc_err iLastRPCError;\n" );
       
  1351 	f_print( fout, "\tCLIENT *cl;\n" );
       
  1352 	f_print( fout, "};\n" );
       
  1353 	PrintEndDefs( program );
       
  1354 }
       
  1355 
       
  1356 
       
  1357 /*********************************************************************
       
  1358  *
       
  1359  * Client Stub Class Definition - METHOD GENERATION
       
  1360  *
       
  1361  ********************************************************************/
       
  1362 void output_proc_stub_header( definition *program, proc_list *proc, char *version )
       
  1363 {
       
  1364 	// Print the signature header
       
  1365 	PrintClientStubSignature( 1, NULL, proc );
       
  1366 	f_print( fout, ";\n" );
       
  1367 }
       
  1368 
       
  1369 
       
  1370 /*********************************************************************
       
  1371  *
       
  1372  * SECTION - Client Stub Class Implementation
       
  1373  *
       
  1374  ********************************************************************/
       
  1375 
       
  1376 /*********************************************************************
       
  1377  *
       
  1378  * Client Stub Class Implementation - START
       
  1379  *
       
  1380  ********************************************************************/
       
  1381 void output_header_stub_cpp( char *filename, definition *program )
       
  1382 {
       
  1383 	version_list *vp;
       
  1384 
       
  1385 	// get the version info for use later 
       
  1386 	vp = program->def.pr.versions;
       
  1387 
       
  1388 	// output the system includes
       
  1389 	PrintFileBanner( "System Includes" );
       
  1390 	O( "#include <stdio.h>\n" );
       
  1391 	O( "#include <assert.h>\n" );
       
  1392 	O( "#include <rpc/types.h>\n" );
       
  1393 
       
  1394 	// output the local includes
       
  1395 	PrintBanner( "Local Includes" );
       
  1396 	f_print( fout, "#include \"%s.h\"\n", ClientComponentClassname(program) );
       
  1397 
       
  1398 	// output the implementation banner
       
  1399 	PrintBanner( "Implementation" );
       
  1400 
       
  1401 	// output the impl for the constructor
       
  1402 	f_print( fout, "%s::%s()\n", ClientComponentClassname(program), ClientComponentClassname(program) );
       
  1403 	f_print( fout, "{\n" );
       
  1404 	trace( 1, program, NULL, "Constructor", 1 );
       
  1405 	f_print( fout, "\tcl = NULL;\n" );
       
  1406 	f_print( fout, "\tiLastRPCError.re_status = RPC_SUCCESS;\n" );
       
  1407 	trace( 1, program, NULL, "Constructor", 0 );
       
  1408 	f_print( fout, "}\n\n" );
       
  1409 
       
  1410 	// output the impl for the destructor
       
  1411 	f_print( fout, "%s::~%s()\n", ClientComponentClassname(program), ClientComponentClassname(program) );
       
  1412 	f_print( fout, "{\n" );
       
  1413 	trace( 1, program, NULL, "Destructor", 1 );
       
  1414 	f_print( fout, "\tassert( cl == NULL );\n" );
       
  1415 	trace( 1, program, NULL, "Destructor", 0 );
       
  1416 	f_print( fout, "}\n\n" );
       
  1417 
       
  1418 	// output the impl for getlastrpcerror
       
  1419 	f_print( fout, "char *%s::GetLastRPCError( int *aIntErr )\n", ClientComponentClassname(program) );
       
  1420 	f_print( fout, "{\n" );
       
  1421 	f_print( fout, "\tstruct rpc_err rpcerr;\n" );
       
  1422 	f_print( fout, "\n" );
       
  1423 	trace( 1, program, NULL, "GetLastRPCError", 1 );
       
  1424 	f_print( fout, "\t// check that the handle is valid\n" );
       
  1425 	f_print( fout, "\tif( cl == NULL ) {\n" );
       
  1426 	f_print( fout, "\t\treturn NULL;\n" );
       
  1427 	f_print( fout, "\t}\n" );
       
  1428 	f_print( fout, "\n" );
       
  1429 	O( "\t// pass the aIntErr\n" );
       
  1430 	O( "\tif( aIntErr != NULL ) {\n" );
       
  1431 	O( "\t\tclnt_geterr( cl, &rpcerr );\n" );
       
  1432 	O( "\t\t*aIntErr = rpcerr.re_status;\n" );
       
  1433 	O( "\t}\n" );
       
  1434 	O( "\n" );
       
  1435 	O( "\t// return the errorstring\n" );
       
  1436 	trace( 1, program, NULL, "GetLastRPCError", 0 );
       
  1437 	O( "\treturn clnt_sperror( cl, NULL );\n" );
       
  1438 	O( "}\n" );
       
  1439 	f_print( fout, "\n" );
       
  1440 
       
  1441 	// output the impl for connect
       
  1442 	f_print( fout, "int %s::Connect( string aRemoteHost )\n", ClientComponentClassname(program) );
       
  1443 	f_print( fout, "{\n" );
       
  1444 	trace( 1, program, NULL, "Connect", 1 );
       
  1445 	f_print( fout, "\t// check that we are not already connected\n" );
       
  1446 	f_print( fout, "\tif( cl != NULL ) {\n" );
       
  1447 	trace( 2, program, NULL, "Connect", 0 );
       
  1448 	f_print( fout, "\t\treturn ERR_STUB_ALREADY_CONNECTED;\n" );
       
  1449 	f_print( fout, "\t}\n" );
       
  1450 	f_print( fout, "\n" );
       
  1451 	f_print( fout, "\t// start the rpc library\n" );
       
  1452 	f_print( fout, "\trpc_nt_init();\n" );
       
  1453 	f_print( fout, "\n" );
       
  1454 	f_print( fout, "\t// connect to the service\n" );
       
  1455 	f_print( fout, "\tcl = clnt_create( aRemoteHost.c_str(), %s, %s, \"tcp\" );\n", program->def_name, vp->vers_name );
       
  1456 	f_print( fout, "\tif( cl == NULL ) {\n" );
       
  1457 	f_print( fout, "\t\trpc_nt_exit();\n" );
       
  1458 	trace( 2, program, NULL, "Connect", 0 );
       
  1459 	f_print( fout, "\t\treturn ERR_FAILED_TO_CONNECT;\n" );
       
  1460 	f_print( fout, "\t}\n" );
       
  1461 	f_print( fout, "\n" );
       
  1462 	f_print( fout, "\t// done\n" );
       
  1463 	trace( 1, program, NULL, "Connect", 0 );
       
  1464 	f_print( fout, "\treturn ERR_NONE;\n" );
       
  1465 	f_print( fout, "}\n\n" );
       
  1466 
       
  1467 	// output the impl for disconnect
       
  1468 	f_print( fout, "int %s::Disconnect( )\n", ClientComponentClassname(program) );
       
  1469 	f_print( fout, "{\n" );
       
  1470 	trace( 1, program, NULL, "Disconnect", 1 );
       
  1471 	f_print( fout, "\t// check that we are connected\n" );
       
  1472 	f_print( fout, "\tif( cl == NULL ) {\n" );
       
  1473 	trace( 2, program, NULL, "Disconnect", 0 );
       
  1474 	f_print( fout, "\t\treturn ERR_STUB_NOT_CONNECTED;\n" );
       
  1475 	f_print( fout, "\t}\n" );
       
  1476 	f_print( fout, "\n" );
       
  1477 	f_print( fout, "\t// cleanup the client handle\n" );
       
  1478 	f_print( fout, "\tclnt_destroy( cl );\n" );
       
  1479 	f_print( fout, "\tcl = NULL;\n" );
       
  1480 	f_print( fout, "\trpc_nt_exit();\n" );
       
  1481 	f_print( fout, "\n" );
       
  1482 	f_print( fout, "\t// done\n" );
       
  1483 	trace( 1, program, NULL, "Disconnect", 0 );
       
  1484 	f_print( fout, "\treturn ERR_NONE;\n" );
       
  1485 	f_print( fout, "}\n" );
       
  1486 }
       
  1487 
       
  1488 
       
  1489 /*********************************************************************
       
  1490  *
       
  1491  * Client Stub Class Implementation - END
       
  1492  *
       
  1493  ********************************************************************/
       
  1494 void output_footer_stub_cpp( definition *program )
       
  1495 {
       
  1496 }
       
  1497 
       
  1498 
       
  1499 /*********************************************************************
       
  1500  *
       
  1501  * Client Stub Class Implementation - METHOD GENERATION
       
  1502  *
       
  1503  ********************************************************************/
       
  1504 void output_proc_stub_cpp( definition *program, proc_list *proc, char *version )
       
  1505 {
       
  1506 	char str[256];
       
  1507 	//	int void_return_type = 0;
       
  1508 
       
  1509 	// ss and sc methods aren't included in the component
       
  1510 //	if( strncmp(proc->proc_name,"SS_",3) == 0 ) {
       
  1511 //		return;
       
  1512 //	}
       
  1513 //	if( strncmp(proc->proc_name,"SC_",3) == 0 ) {
       
  1514 //		return;
       
  1515 //	}
       
  1516 
       
  1517 	// print banner
       
  1518 	sprintf( str, "PUBLIC FUNCTION: %s", locase(proc->proc_name) );
       
  1519 	PrintBanner( str );
       
  1520 
       
  1521 	// print the function signature
       
  1522 	sprintf( str, "%s", ClientComponentClassname(program) );
       
  1523 	PrintClientStubSignature( 0, str, proc );
       
  1524 	f_print( fout, "\n" );
       
  1525 
       
  1526 	// print the body
       
  1527 	output_proc_stub_cpp_std( program, proc, version );
       
  1528 }
       
  1529 
       
  1530 
       
  1531 void output_proc_stub_cpp_std( definition *program, proc_list *proc, char *version )
       
  1532 {
       
  1533 	int void_return_value = 0;
       
  1534 	int void_arg_type = 0;
       
  1535 	version_list *vp = program->def.pr.versions;
       
  1536 
       
  1537 	// open the body
       
  1538 	f_print( fout, "{\n" );
       
  1539 
       
  1540 	// find out if we have a void return value
       
  1541 	if( strncmp(proc->res_type,"void",4) == 0 ) {
       
  1542 		void_return_value = 1;
       
  1543 	}
       
  1544 
       
  1545 	// find out if we have a void arg, if so then declare a dummy arg
       
  1546 	f_print( fout, "\tstruct rpc_err rerr;\n" );
       
  1547 	if( strncmp(proc->arg_type,"void",4) == 0 ) {
       
  1548 		void_arg_type = 1;
       
  1549 		f_print( fout, "\tint aArgs = 0;\n" );
       
  1550 	}
       
  1551 	f_print( fout, "\n" );
       
  1552 	trace( 1, program, proc, NULL, 1 );
       
  1553 
       
  1554 	// check the rv (if needed)
       
  1555 	if( void_return_value == 0 ) {
       
  1556 		f_print( fout, "\t// check the rv pointer\n" );
       
  1557 		f_print( fout, "\tif( rv == NULL ) {\n" );
       
  1558 		trace( 2, program, proc, NULL, 0 );
       
  1559 		f_print( fout, "\t\treturn ERR_INVALID_RV_POINTER;\n" );
       
  1560 		f_print( fout, "\t}\n" );
       
  1561 		f_print( fout, "\n" );
       
  1562 	}
       
  1563 
       
  1564 	// check that we are connected
       
  1565 	f_print( fout, "\t// check that we have a connection\n" );
       
  1566 	f_print( fout, "\tif( cl == NULL ) {\n" );
       
  1567 	f_print( fout, "\t\treturn ERR_STUB_NOT_CONNECTED;\n" );
       
  1568 	trace( 2, program, proc, NULL, 0 );
       
  1569 	f_print( fout, "\t}\n" );
       
  1570 	f_print( fout, "\n" );
       
  1571 
       
  1572 	// do the call
       
  1573 	f_print( fout, "\t// do the call\n\t" );
       
  1574 	if( void_return_value == 0 ) {
       
  1575 		f_print( fout, "*rv = *" );
       
  1576 	}
       
  1577 	f_print( fout, "%s_%s( &aArgs, cl );\n", locase(proc->proc_name), vp->vers_num );
       
  1578 	f_print( fout, "\n" );
       
  1579 
       
  1580 	// check for rpc errors and return the result
       
  1581 	f_print( fout, "\t// check for rpc errors and return the result\n" );
       
  1582 	f_print( fout, "\tclnt_geterr( cl, &rerr );\n" );
       
  1583 	f_print( fout, "\tif( rerr.re_status != RPC_SUCCESS ) {\n" );
       
  1584 	f_print( fout, "\t\tiLastRPCError = rerr;\n" );
       
  1585 	trace( 2, program, proc, NULL, 0 );
       
  1586 	f_print( fout, "\t\treturn ERR_RPC_ERROR;\n" );
       
  1587 	f_print( fout, "\t}\n" );
       
  1588 	trace( 1, program, proc, NULL, 0 );
       
  1589 	f_print( fout, "\treturn ERR_NONE;\n" );
       
  1590 	f_print( fout, "}\n" );
       
  1591 }
       
  1592 
       
  1593 
       
  1594 
       
  1595 /*********************************************************************
       
  1596  *
       
  1597  * SECTION - HELPERS
       
  1598  *
       
  1599  ********************************************************************/
       
  1600 
       
  1601 /*********************************************************************
       
  1602  *
       
  1603  * HELPERS: Filename Related Code Generation
       
  1604  *
       
  1605  ********************************************************************/
       
  1606 void PrintStartDefs( definition *def )
       
  1607 {
       
  1608 	char cstr[64];
       
  1609 
       
  1610 	// find the prefix
       
  1611 	cstr[0] = 0;
       
  1612 	if( gtype == TYPE_CLIENT_H ) {
       
  1613 		sprintf( cstr, "CC" );
       
  1614 	} else if( gtype == TYPE_INST_H ) {
       
  1615 		sprintf( cstr, "CS" );
       
  1616 	} else if( gtype == TYPE_SVC_MGR_H ) {
       
  1617 		sprintf( cstr, "CSVC" );
       
  1618 	}
       
  1619 
       
  1620 	// print the tags
       
  1621 	f_print( fout, "#ifndef __%s%s_H__\n", cstr, ucase(def->def_name) );
       
  1622 	f_print( fout, "#define __%s%s_H__\n", cstr, ucase(def->def_name) );
       
  1623 }
       
  1624 
       
  1625 
       
  1626 void PrintEndDefs( definition *def )
       
  1627 {
       
  1628 	f_print( fout, "\n#endif\n" ); 
       
  1629 }
       
  1630 
       
  1631 
       
  1632 void PrintIncludeInterfaceHeader()
       
  1633 {
       
  1634 	char *ptr, delim = 0;
       
  1635 
       
  1636 	// find the '.' in the input filename (.x) and set to null
       
  1637 	ptr = strchr( input_filename, '.' );
       
  1638 	if( ptr != NULL ) {
       
  1639 		delim = *ptr;
       
  1640 		*ptr = 0;
       
  1641 	}
       
  1642 
       
  1643 	// print the line
       
  1644 	f_print( fout, "#include \"%s.h\"\n", input_filename );
       
  1645 
       
  1646 	// put the dot back
       
  1647 	if( delim != 0 ) {
       
  1648 		*ptr = delim;
       
  1649 	}
       
  1650 }
       
  1651 
       
  1652 
       
  1653 /*********************************************************************
       
  1654  *
       
  1655  * HELPERS: Classname Related Code Generation
       
  1656  *
       
  1657  ********************************************************************/
       
  1658 char *ComponentClassname( definition *def )
       
  1659 {
       
  1660 	static char component_classname[256];
       
  1661 	sprintf( component_classname, "CS%c%s", toupper(def->def_name[0]), locase(&(def->def_name[1])) );
       
  1662 	return component_classname;
       
  1663 }
       
  1664 
       
  1665 
       
  1666 char *ClientComponentClassname( definition *def )
       
  1667 {
       
  1668 	static char component_classname[256];
       
  1669 	sprintf( component_classname, "CC%c%s", toupper(def->def_name[0]), locase(&(def->def_name[1])) );
       
  1670 	return component_classname;
       
  1671 }
       
  1672 
       
  1673 
       
  1674 char *ServiceManagerClassname( definition *def )
       
  1675 {
       
  1676 	static char service_manager_classname[256];
       
  1677 	sprintf( service_manager_classname, "CSvc%c%s", toupper(def->def_name[0]), locase(&(def->def_name[1])) );
       
  1678 	return service_manager_classname;
       
  1679 }
       
  1680 
       
  1681 
       
  1682 /*********************************************************************
       
  1683  *
       
  1684  * HELPERS: Function Related Code Generation
       
  1685  *
       
  1686  ********************************************************************/
       
  1687 void PrintCallFromServiceStubToInstance( definition *program, proc_list *proc, char *extra_args )
       
  1688 {
       
  1689 	int void_arg_type = 0;
       
  1690 	int void_res_type = 0;
       
  1691 
       
  1692 	// check for a void argument
       
  1693 	if( strncmp(proc->arg_type,"void",4) == 0 ) {
       
  1694 		void_arg_type = 1;
       
  1695 	}
       
  1696 
       
  1697 	// check for a void ret
       
  1698 	if( strncmp(proc->res_type,"void",4) == 0 ) {
       
  1699 		void_res_type = 1;
       
  1700 	}
       
  1701 
       
  1702 	// print the comment
       
  1703 	O( "\t// call the corresponding method on the instance\n\t" );
       
  1704 
       
  1705 	// only store the return value is the thing doesn't return void
       
  1706 	if( void_res_type == 0 ) {
       
  1707 		f_print( fout, "rv = " );
       
  1708 	} else {
       
  1709 		f_print( fout, "rv = ERR_NONE;\n\t" );
       
  1710 	}
       
  1711 
       
  1712 	// print the method name and open the bracket
       
  1713 	f_print( fout, "session->%s(", locase(proc->proc_name) );
       
  1714 
       
  1715 	// if we have more to print then put in a space
       
  1716 	if( (void_arg_type == 0) || (extra_args != NULL) ) {
       
  1717 		f_print( fout, " " );
       
  1718 	}
       
  1719 
       
  1720 	// put in the args 
       
  1721 	if( void_arg_type == 0 ) {
       
  1722 		f_print( fout, "*aArgs" );
       
  1723 		if( extra_args != NULL ) {
       
  1724 			f_print( fout, "," );
       
  1725 		}
       
  1726 		f_print( fout, " " );
       
  1727 	}
       
  1728 
       
  1729 	// put the extra args + space
       
  1730 	if( extra_args != NULL ) {
       
  1731 		f_print( fout, "%s ", extra_args );
       
  1732 	}
       
  1733 
       
  1734 	// close up
       
  1735 	f_print( fout, ");\n" );
       
  1736 }
       
  1737 
       
  1738 
       
  1739 void PrintCallFromServiceStubToStatic( definition *program, proc_list *proc, char *extra_args )
       
  1740 {
       
  1741 	int void_arg_type = 0;
       
  1742 	int void_res_type = 0;
       
  1743 
       
  1744 	// check for a void argument
       
  1745 	if( strncmp(proc->arg_type,"void",4) == 0 ) {
       
  1746 		void_arg_type = 1;
       
  1747 	}
       
  1748 
       
  1749 	// check for a void ret
       
  1750 	if( strncmp(proc->res_type,"void",4) == 0 ) {
       
  1751 		void_res_type = 1;
       
  1752 	}
       
  1753 
       
  1754 	// print the comment
       
  1755 	O( "\t// call the corresponding method on the instance\n" );
       
  1756 
       
  1757 	// only store the return value is the thing doesn't return void
       
  1758 	if( void_res_type == 0 ) {
       
  1759 		f_print( fout, "\trv = " );
       
  1760 	} else {
       
  1761 		f_print( fout, "\trv = ERR_NONE;\n\t" );
       
  1762 	}
       
  1763 
       
  1764 	// print the method name and open the bracket
       
  1765 	f_print( fout, "%s::", ServiceManagerClassname(program) );
       
  1766 	f_print( fout, "%s(", locase(proc->proc_name) );
       
  1767 
       
  1768 	// if we have more to print then put in a space
       
  1769 	if( (void_arg_type == 0) || (extra_args != NULL) ) {
       
  1770 		f_print( fout, " " );
       
  1771 	}
       
  1772 
       
  1773 	// put in the args 
       
  1774 	if( void_arg_type == 0 ) {
       
  1775 		f_print( fout, "*aArgs" );
       
  1776 		if( extra_args != NULL ) {
       
  1777 			f_print( fout, "," );
       
  1778 		}
       
  1779 		f_print( fout, " " );
       
  1780 	}
       
  1781 
       
  1782 	// put the extra args + space
       
  1783 	if( extra_args != NULL ) {
       
  1784 		f_print( fout, "%s ", extra_args );
       
  1785 	}
       
  1786 
       
  1787 	// close up
       
  1788 	f_print( fout, ");\n" );
       
  1789 }
       
  1790 
       
  1791 
       
  1792 void PrintServiceCheck( definition *program, proc_list *proc )
       
  1793 {
       
  1794 	// check that the service is already started
       
  1795 	f_print( fout, "\t// check that the service is started\n" );
       
  1796 	f_print( fout, "\tif( iComponentManager == NULL ) {\n" );
       
  1797 	PrintSetErrorValue( 2, program, proc, "ERR_SERVICE_NOT_RUNNING" );
       
  1798 	trace( 2, program, proc, NULL, 0 );
       
  1799 	f_print( fout, "\t\treturn &rv;\n" );
       
  1800 	f_print( fout, "\t}\n\n" );
       
  1801 }
       
  1802 
       
  1803 
       
  1804 void PrintClientStubSignature( int indent, char *classname, proc_list *proc )
       
  1805 {
       
  1806 	int i;
       
  1807 	int non_void_argument;
       
  1808 
       
  1809 	// indent
       
  1810 	for( i = 0; i < indent; i++ ) {
       
  1811 		f_print( fout, "\t" );
       
  1812 	}
       
  1813 
       
  1814 	// print the function signature
       
  1815 	f_print( fout, "int " );
       
  1816 	
       
  1817 	// print classname if defined
       
  1818 	if( classname != NULL ) {
       
  1819 		f_print( fout, "%s::", classname );
       
  1820 	}
       
  1821 	f_print( fout, "%s( ", locase(proc->proc_name) );
       
  1822 
       
  1823 	// only put in the arg if it isn't void
       
  1824 	if( strncmp(proc->arg_type,"void",4) != 0 ) {
       
  1825 		ptype( proc->arg_prefix, proc->arg_type, 1 );
       
  1826 		f_print( fout, "aArgs" );
       
  1827 		non_void_argument = 1;
       
  1828 	}
       
  1829 
       
  1830 	// only put the return value if it is non-null
       
  1831 	if( strncmp(proc->res_type,"void",4) != 0 ) {
       
  1832 		if( non_void_argument == 1 ) {
       
  1833 			f_print( fout, ", " );
       
  1834 		}
       
  1835 		ptype( proc->res_prefix, proc->res_type, 1 );
       
  1836 		f_print( fout, "*rv " );
       
  1837 	} else {
       
  1838 		f_print( fout, " " );
       
  1839 	}
       
  1840 
       
  1841 	// close the bracket
       
  1842 	f_print( fout, ")" );
       
  1843 }
       
  1844 
       
  1845 
       
  1846 void PrintComponentInstanceMethodSignature( char *classname, definition *program, proc_list *proc )
       
  1847 {
       
  1848 	int void_arg_type = 0;
       
  1849 	int i_am_a_destructor = 0;
       
  1850 
       
  1851 	// print the return type
       
  1852 	ptype( proc->res_prefix, proc->res_type, 1 );
       
  1853 
       
  1854 	// now print the method name
       
  1855 	if( classname != NULL ) {
       
  1856 		f_print( fout, "%s::", classname );
       
  1857 	}
       
  1858 	f_print( fout, "%s( ", locase(proc->proc_name) );
       
  1859 
       
  1860 	// see if the arg is null
       
  1861 	if( strncmp(proc->arg_type,"void",4) == 0 ) {
       
  1862 		void_arg_type = 1;
       
  1863 	}
       
  1864 
       
  1865 	// see if this is a destr
       
  1866 	if( strncmp(proc->proc_name,"DSTR_",5) == 0 ) {
       
  1867 		i_am_a_destructor = 1;
       
  1868 	}
       
  1869 
       
  1870 	// if the rv is null and we are not a destructor then
       
  1871 	if( (void_arg_type == 1) && (i_am_a_destructor == 1) ) {
       
  1872 		f_print( fout, "int *aDeleteInstance " );
       
  1873 	} else if( (void_arg_type == 0) && (i_am_a_destructor == 1) ) {
       
  1874 		ptype( proc->arg_prefix, proc->arg_type, 1 );
       
  1875 		f_print( fout, "aArgs, int *aDeleteInstance " );
       
  1876 	} else if( (void_arg_type == 1) && (i_am_a_destructor == 0) ) {
       
  1877 		f_print( fout, "void " );
       
  1878 	} else if( (void_arg_type == 0) && (i_am_a_destructor == 0) ) {
       
  1879 		ptype( proc->arg_prefix, proc->arg_type, 1 );
       
  1880 		f_print( fout, "aArgs " );
       
  1881 	}
       
  1882 	f_print( fout, ")");
       
  1883 }
       
  1884 
       
  1885 
       
  1886 void PrintSetErrorValue( int indent, definition *program, proc_list *proc, char *error )
       
  1887 {
       
  1888 	int i;
       
  1889 	int set_error_call_required = 0;
       
  1890 
       
  1891 	// check params
       
  1892 	assert( program != NULL );
       
  1893 	assert( proc != NULL );
       
  1894 	assert( error != NULL );
       
  1895 
       
  1896 	// write the indent
       
  1897 	for( i = 0; i < indent; i++ ) {
       
  1898 		f_print( fout, "\t" );
       
  1899 	}
       
  1900 
       
  1901 	// check if we need a set error call
       
  1902 	set_error_call_required = IsSetErrorCallRequired( proc );
       
  1903 
       
  1904 	// if it is integral then we just do an assignment
       
  1905 	if( set_error_call_required == 0 ) {
       
  1906 		f_print( fout, "rv = %s;\n", error );
       
  1907 	} else {
       
  1908 		f_print( fout, "%s::SetError( %s, (void*)&rv, %s );\n", ServiceManagerClassname(program), proc->proc_name, error );
       
  1909 	}
       
  1910 
       
  1911 	// done
       
  1912 }
       
  1913 
       
  1914 
       
  1915 int IsSetErrorCallRequired( proc_list *proc )
       
  1916 {
       
  1917 	int set_error_call_required = 1;
       
  1918 
       
  1919 	if( strncmp(proc->res_type,"int",3) == 0 ) {
       
  1920 		set_error_call_required = 0;
       
  1921 	} else if( strncmp(proc->res_type,"short",5) == 0 ) {
       
  1922 		set_error_call_required = 0;
       
  1923 	} else if( strncmp(proc->res_type,"long",4) == 0 ) {
       
  1924 		set_error_call_required = 0;
       
  1925 	} else if( strncmp(proc->res_type,"void",4) == 0 ) {
       
  1926 		set_error_call_required = 0;
       
  1927 	}
       
  1928 
       
  1929 	return set_error_call_required;
       
  1930 }
       
  1931 
       
  1932 /*********************************************************************
       
  1933  *
       
  1934  * HELPERS: File Banners
       
  1935  *
       
  1936  ********************************************************************/
       
  1937 void PrintAutogenBanner( char *filename )
       
  1938 {
       
  1939 	time_t ltime;
       
  1940 
       
  1941 	f_print( fout, "%s", BANNER_START );
       
  1942 	f_print( fout, "%s\n", BANNER_LINE );
       
  1943 	f_print( fout, "%sTHIS FILE IS AUTOGENERATED. Do not modify the contents of this file directly\n", BANNER_LINE );
       
  1944 	f_print( fout, "%sas changes will be lost\n", BANNER_LINE );
       
  1945 	f_print( fout, "%s\n", BANNER_LINE );
       
  1946 	f_print( fout, "%s%s\n", BANNER_LINE, filename );
       
  1947 	time( &ltime );
       
  1948 	f_print( fout, "%s%s", BANNER_LINE, ctime(&ltime) );
       
  1949 	f_print( fout, "%s\n", BANNER_LINE );
       
  1950 	f_print( fout, "%s", BANNER_END );
       
  1951 }
       
  1952 
       
  1953 void PrintAutogenModBanner( char *filename )
       
  1954 {
       
  1955 	time_t ltime;
       
  1956 
       
  1957 	f_print( fout, "%s", BANNER_START );
       
  1958 	f_print( fout, "%s\n", BANNER_LINE );
       
  1959 	f_print( fout, "%sThis file was autogenerated by rpcgen, but should be modified by the developer.\n", BANNER_LINE );
       
  1960 	f_print( fout, "%sMake sure you don't use the -component_mod flag in future or this file will be overwritten.\n", BANNER_LINE );
       
  1961 	f_print( fout, "%s\n", BANNER_LINE );
       
  1962 	f_print( fout, "%s%s\n", BANNER_LINE, filename );
       
  1963 	time( &ltime );
       
  1964 	f_print( fout, "%s%s", BANNER_LINE, ctime(&ltime) );
       
  1965 	f_print( fout, "%s\n", BANNER_LINE );
       
  1966 	f_print( fout, "%s", BANNER_END );
       
  1967 }
       
  1968 
       
  1969 
       
  1970 void PrintBanner( char *title )
       
  1971 {
       
  1972 	f_print( fout, "\n\n%s", BANNER_START );
       
  1973 	f_print( fout, "%s\n", BANNER_LINE );
       
  1974 	f_print( fout, "%s%s\n", BANNER_LINE, title );
       
  1975 	f_print( fout, "%s\n", BANNER_LINE );
       
  1976 	f_print( fout, "%s", BANNER_END );
       
  1977 }
       
  1978 
       
  1979 
       
  1980 void PrintFileBanner( char *filename )
       
  1981 {
       
  1982 	f_print( fout, "%s", BANNER_START );
       
  1983 	f_print( fout, "%s\n", BANNER_LINE );
       
  1984 	f_print( fout, "%s%s\n", BANNER_LINE, filename );
       
  1985 	f_print( fout, "%s\n", BANNER_LINE );
       
  1986 	f_print( fout, "%s", BANNER_END );
       
  1987 }
       
  1988 
       
  1989 
       
  1990 /*********************************************************************
       
  1991  *
       
  1992  * HELPERS: Miscellaneous Helpers
       
  1993  *
       
  1994  ********************************************************************/
       
  1995 char *ucase( char *str )
       
  1996 {
       
  1997 	unsigned int i;
       
  1998 	static char rstr[1024];
       
  1999 	assert( strlen(str) < (1024 + 1) );
       
  2000 	for( i = 0; i < strlen(str); i++ ) {
       
  2001 		rstr[i] = toupper(str[i]);
       
  2002 	}
       
  2003 	rstr[i] = 0;
       
  2004 	return rstr;
       
  2005 }
       
  2006 
       
  2007 
       
  2008 void trace( int indent, definition *program, proc_list *proc, char *fname, int enter )
       
  2009 {
       
  2010 	int i;
       
  2011 	char direction[32];
       
  2012 	char function_name[512];
       
  2013 
       
  2014 	// return if the type is not traced
       
  2015 	if( trace_points[gtype] == 0 ) {
       
  2016 		return;
       
  2017 	}
       
  2018 
       
  2019 	// do the indent
       
  2020 	for( i = 0; i < indent; i++ ) {
       
  2021 		f_print( fout, "\t" );
       
  2022 	}	
       
  2023 
       
  2024 	// get the direction string
       
  2025 	sprintf( direction, "%s", ((enter == 1) ? "Entering " : "Exiting" ) );
       
  2026 
       
  2027 	// get the classname
       
  2028 	switch( gtype ) {
       
  2029 	case TYPE_SVC_STUB_IMPL:
       
  2030 		sprintf( function_name, "%s::", "ServiceStub" );
       
  2031 		break;
       
  2032 
       
  2033 	case TYPE_SVC_MGR_C:
       
  2034 		sprintf( function_name, "%s::", ServiceManagerClassname(program) );
       
  2035 		break;
       
  2036 
       
  2037 	case TYPE_INST_C:
       
  2038 		sprintf( function_name, "%s::", ComponentClassname(program) );
       
  2039 		break;
       
  2040 
       
  2041 	case TYPE_CLIENT_C:
       
  2042 		sprintf( function_name, "%s::", ClientComponentClassname(program) );
       
  2043 		break;
       
  2044 
       
  2045 	case TYPE_SVC_MGR_H:
       
  2046 	case TYPE_INST_H:
       
  2047 	case TYPE_CLIENT_H:
       
  2048 		assert( !"INVALID TYPE" );
       
  2049 		break;
       
  2050 	}
       
  2051 
       
  2052 	// append the function name
       
  2053 	if( proc == NULL ) {
       
  2054 		sprintf( &(function_name[strlen(function_name)]), "%s", fname );
       
  2055 	} else {
       
  2056 		sprintf( &(function_name[strlen(function_name)]), "%s", proc->proc_name );
       
  2057 	}
       
  2058 
       
  2059 	// output the trace line
       
  2060 	f_print( fout, "fprintf( stderr, \"TRACE: " );
       
  2061 	f_print( fout, "%s ", direction );
       
  2062 	f_print( fout, "%s ", function_name );
       
  2063 	f_print( fout, "(%%d)\\n\", __LINE__ );\n" );
       
  2064 }
       
  2065 	
       
  2066 	 
       
  2067 /*********************************************************************
       
  2068  *
       
  2069  * PUBLIC FUNCTION: ae_set_trace
       
  2070  *
       
  2071  ********************************************************************/
       
  2072 void ae_set_trace( int type )
       
  2073 {
       
  2074 	trace_points[type] = 1;
       
  2075 }
       
  2076 
       
  2077 
       
  2078 /*********************************************************************
       
  2079  *
       
  2080  * PUBLIC FUNCTION: ae_extend_custom_types - if the passed type is
       
  2081  * one of the basic types then it is returned unmodified. Otherwise
       
  2082  * we extend it with some namespacing construct.
       
  2083  *
       
  2084  * I am going to say that any type that begins with 'T' is a custom
       
  2085  * type. This is true of everything (I think). I'm still going to 
       
  2086  * check whether it is one of the in-built types to verify this. If
       
  2087  * something is neither 'T' nor an inbuilt type then I'll print a 
       
  2088  * warning.
       
  2089  *
       
  2090  ********************************************************************/
       
  2091 char *ae_extend_custom_types( char *base_type )
       
  2092 {
       
  2093 	int is_basic_type = 0, match, i;
       
  2094 	char *ptr, *n;
       
  2095 	static char *basic_type[] = { "void", "int", "bool", "short", "array", "bytes", "char", "double", "float", "long", "string", "u_char", "u_int", "u_long", "u_short", "vector", "enum", "struct", "wrapstring", NULL };
       
  2096 
       
  2097 	// see if the type is one of the basic types. 	
       
  2098 	for( i = 0; basic_type[i] != NULL; i++ ) {
       
  2099 		match = strcmp( base_type, basic_type[i] );
       
  2100 		if( match == 0 ) {
       
  2101 			is_basic_type = 1;
       
  2102 		}
       
  2103 	}
       
  2104 
       
  2105 	// check that either 'T' or is_basic_type is set
       
  2106 	if( (base_type[0] != 'T') && (is_basic_type == 0) ) {
       
  2107 		fprintf( stderr, "WARNING: don't know how to handle type '%s'.\n", base_type );
       
  2108 		is_basic_type = 1;
       
  2109 	}
       
  2110 
       
  2111 	// check that both are not set
       
  2112 	assert( (base_type[0] != 'T') || (is_basic_type != 1) );
       
  2113 
       
  2114 	// if is_basic_type is set then just strcpy
       
  2115 	if( is_basic_type ) {
       
  2116 		n = base_type;
       
  2117 	}
       
  2118 
       
  2119 	// if 'T' then extend
       
  2120 	if( base_type[0] == 'T' ) {
       
  2121 		n = (char*)malloc( strlen(infilename) + 1 + strlen(base_type) + 1 ); 
       
  2122 		assert( n != NULL );
       
  2123 		strcpy( n, infilename );
       
  2124 		ptr = strchr( n, '.' );
       
  2125 		if( ptr != NULL )
       
  2126 			*ptr = 0;
       
  2127 		strcat( n, "_" );
       
  2128 		strcat( n, base_type );
       
  2129 	}
       
  2130 
       
  2131 	return n;
       
  2132 }