545 lines
20 KiB
C++
545 lines
20 KiB
C++
#include <stdlib.h>
|
|
#include <stddef.h>
|
|
#include <string.h>
|
|
|
|
#include "complexSupport.h"
|
|
extern int corba_binding;
|
|
|
|
void use_ref( Schema, Express, FILES * );
|
|
|
|
void
|
|
create_builtin_type_decl( FILES * files, char * name ) {
|
|
//fprintf( files->incall, "extern TypeDescriptor *%s%s_TYPE;\n",
|
|
// TD_PREFIX, name );
|
|
}
|
|
|
|
void
|
|
create_builtin_type_defn( FILES * files, char * name ) {
|
|
//fprintf( files->initall, "\t%s%s_TYPE = TypeDescriptor (",
|
|
// TD_PREFIX, name );
|
|
//fprintf( files->initall, "\"%s\", %s_TYPE, \"%s\");\n",
|
|
// PrettyTmpName( name ), StrToUpper( name ), StrToLower( name ) );
|
|
}
|
|
|
|
/******************************************************************
|
|
** Procedure: print_file_header
|
|
** Parameters: const Schema schema - top-level schema being printed
|
|
** FILE* file - file on which to print header
|
|
** Returns:
|
|
** Description: handles file related tasks that need to be done once
|
|
** at the beginning of processing.
|
|
** In this case the file schema.h is initiated
|
|
** Status: ok 1/15/91
|
|
******************************************************************/
|
|
|
|
void
|
|
print_file_header( Express express, FILES * files ) {
|
|
//files -> incall = FILEcreate( "schema.h" );
|
|
|
|
/* prevent RCS from expanding this! */
|
|
//fprintf( files->incall, "import sdai\n" );
|
|
//fprintf( files->incall, "import Registry\n" );
|
|
|
|
//fprintf( files->incall, "\n#include <STEPaggregate.h>\n" );
|
|
//fprintf( files->incall, "\n#include <STEPundefined.h>\n" );
|
|
//fprintf( files->incall, "\n#include <ExpDict.h>\n" );
|
|
//fprintf( files->incall, "\n#include <STEPattribute.h>\n" );
|
|
|
|
//fprintf( files->incall, "\n#include <Sdaiclasses.h>\n" );
|
|
//fprintf( files->incall, "import Sdaiclasses\n" );
|
|
//fprintf( files->incall, "extern void SchemaInit (Registry &);\n" );
|
|
//fprintf( files->incall, "extern void InitSchemasAndEnts (Registry &);\n" );
|
|
|
|
//files -> initall = FILEcreate( "schema.py" );
|
|
//fprintf( files->initall, "/* %cId$ */ \n", '\044' );
|
|
//fprintf( files->initall, "#include <schema.h>\n" );
|
|
//fprintf( files->initall, "import schema\n" );
|
|
//fprintf( files-> initall, "class Registry:\n" );
|
|
|
|
//fprintf( files->initall, "\tdef SchemaInit (Registry reg)\n{\n" );
|
|
//fprintf( files->initall, "\t extern void InitSchemasAndEnts " );
|
|
//fprintf( files->initall, "(Registry & r);\n" );
|
|
//fprintf( files->initall, "\t InitSchemasAndEnts (reg);\n" );
|
|
|
|
// This file will contain instantiation statements for all the schemas and
|
|
// entities in the express file. (They must all be in separate function
|
|
// called first by SchemaInit() so that all entities will exist
|
|
//files -> create = FILEcreate( "SdaiAll.py" );
|
|
//fprintf( files->create, "/* %cId$ */ \n", '\044' );
|
|
//fprintf( files->create, "#include <schema.h>\n" );
|
|
//fprintf( files->create, "import schema" );
|
|
//fprintf( files->create, "\nvoid\nInitSchemasAndEnts (Registry & reg)\n{\n" );
|
|
|
|
// This file declares all entity classes as incomplete types. This will
|
|
// allow all the .h files to reference all .h's. We can then have e.g.,
|
|
// entX from schemaA have attribute attr1 = entY from schemaB.
|
|
//files -> classes = FILEcreate( "Sdaiclasses.h" );
|
|
//fprintf( files->classes, "/* %cId$ */ \n", '$' );
|
|
//fprintf( files->classes, "#include <schema.h>\n" );
|
|
|
|
/* create built-in types */
|
|
/* no need to generate
|
|
create_builtin_type_decl(files,"INTEGER");
|
|
create_builtin_type_decl(files,"REAL");
|
|
create_builtin_type_decl(files,"STRING");
|
|
create_builtin_type_decl(files,"BINARY");
|
|
create_builtin_type_decl(files,"BOOLEAN");
|
|
create_builtin_type_decl(files,"LOGICAL");
|
|
create_builtin_type_decl(files,"NUMBER");
|
|
create_builtin_type_decl(files,"GENERIC");
|
|
*/
|
|
/* create built-in types */
|
|
/* no need to generate
|
|
create_builtin_type_defn(files,"INTEGER");
|
|
create_builtin_type_defn(files,"REAL");
|
|
create_builtin_type_defn(files,"STRING");
|
|
create_builtin_type_defn(files,"BINARY");
|
|
create_builtin_type_defn(files,"BOOLEAN");
|
|
create_builtin_type_defn(files,"LOGICAL");
|
|
create_builtin_type_defn(files,"NUMBER");
|
|
create_builtin_type_defn(files,"GENERIC");
|
|
*/
|
|
|
|
}
|
|
|
|
/******************************************************************
|
|
** Procedure: print_file_trailer
|
|
** Parameters: const Schema schema - top-level schema printed
|
|
** FILE* file - file on which to print trailer
|
|
** Returns:
|
|
** Description: handles cleaning up things at end of processing
|
|
** Status: ok 1/15/91
|
|
******************************************************************/
|
|
|
|
/*ARGSUSED*/
|
|
void
|
|
print_file_trailer( Express express, FILES * files ) {
|
|
//FILEclose( files->incall );
|
|
//FILEclose( files->initall );
|
|
//fprintf( files->create, "}\n\n" );
|
|
//FILEclose( files->create );
|
|
//fprintf( files->classes, "\n" );
|
|
//FILEclose( files->classes );
|
|
}
|
|
|
|
/******************************************************************
|
|
** SCHEMA SECTION **/
|
|
|
|
/******************************************************************
|
|
** Procedure: SCOPEPrint
|
|
** Parameters: const Scope scope - scope to print
|
|
** FILE* file - file on which to print
|
|
** Returns:
|
|
** Description: cycles through the scopes of the input Express schema
|
|
** Side Effects: calls functions for processing entities and types
|
|
** Status: working 1/15/91
|
|
** -- it's still not clear how include files should be organized
|
|
** and what the relationship is between this organization and the
|
|
** organization of the schemas in the input Express
|
|
******************************************************************/
|
|
|
|
void
|
|
SCOPEPrint( Scope scope, FILES * files, Schema schema, Express model,
|
|
ComplexCollect * col, int cnt ) {
|
|
Linked_List list = SCOPEget_entities_superclass_order( scope );
|
|
DictionaryEntry de;
|
|
Type i;
|
|
int redefs = 0;// index = 0;
|
|
|
|
/* fill in the values for the type descriptors */
|
|
/* and print the enumerations */
|
|
//fprintf( files -> inc, "\n/*\t************** TYPES \t*/\n" );
|
|
//fprintf( files -> lib, "\n/*\t************** TYPES \t*/\n" );
|
|
SCOPEdo_types( scope, t, de )
|
|
// First check for one exception: Say enumeration type B is defined
|
|
// to be a rename of enum A. If A is in this schema but has not been
|
|
// processed yet, we must wait till it's processed first. The reason
|
|
// is because B will basically be defined with a couple of typedefs to
|
|
// the classes which represent A. (To simplify, we wait even if A is
|
|
// in another schema, so long as it's been processed.)
|
|
if( ( t->search_id == CANPROCESS )
|
|
&& ( TYPEis_enumeration( t ) )
|
|
&& ( ( i = TYPEget_ancestor( t ) ) != NULL )
|
|
&& ( i->search_id >= CANPROCESS ) ) {
|
|
redefs = 1;
|
|
}
|
|
SCOPEod
|
|
|
|
SCOPEdo_types( scope, t, de )
|
|
// Do the non-redefined enumerations:
|
|
if( ( t->search_id == CANPROCESS )
|
|
&& !( TYPEis_enumeration( t ) && TYPEget_head( t ) ) ) {
|
|
TYPEprint_descriptions( t, files, schema );
|
|
if( !TYPEis_select( t ) ) {
|
|
// Selects have a lot more processing and are done below.
|
|
t->search_id = PROCESSED;
|
|
}
|
|
}
|
|
SCOPEod;
|
|
|
|
// process redifined enumerations
|
|
if( redefs ) {
|
|
SCOPEdo_types( scope, t, de )
|
|
if( t->search_id == CANPROCESS && TYPEis_enumeration( t ) ) {
|
|
TYPEprint_descriptions( t, files, schema );
|
|
t->search_id = PROCESSED;
|
|
}
|
|
SCOPEod;
|
|
}
|
|
|
|
/* do the select definitions next, since they depend on the others */
|
|
//fprintf( files->inc, "\n//\t***** Build the SELECT Types \t\n" );
|
|
// Note - say we have sel B, rename of sel A (as above by enum's). Here
|
|
// we don't have to worry about printing B before A. This is checked in
|
|
// TYPEselect_print().
|
|
SCOPEdo_types( scope, t, de )
|
|
if( t->search_id == CANPROCESS ) {
|
|
// Only selects haven't been processed yet and may still be set to
|
|
// CANPROCESS.
|
|
TYPEselect_print( t, files, schema );
|
|
t->search_id = PROCESSED;
|
|
}
|
|
SCOPEod;
|
|
|
|
// process each entity. This must be done *before* typedefs are defined
|
|
LISTdo( list, e, Entity );
|
|
if( e->search_id == CANPROCESS ) {
|
|
ENTITYPrint( e, files, schema );
|
|
e->search_id = PROCESSED;
|
|
}
|
|
LISTod;
|
|
|
|
LISTfree( list );
|
|
}
|
|
|
|
|
|
void
|
|
PrintModelContentsSchema( Scope scope, FILES * files, Schema schema,
|
|
Express model ) {
|
|
Linked_List list;
|
|
char nm[BUFSIZ];
|
|
DictionaryEntry de;
|
|
|
|
//fprintf( files -> inc, "\n/*\t************** TYPES \t*/\n" );
|
|
// Types should be exported to schema_name.DefinedDataTypes
|
|
//fprintf( files -> lib, "\n/*\t************** TYPES \t*/\n" );
|
|
//fprintf( files -> init, "\n/*\t************** TYPES \t*/\n" );
|
|
|
|
/* do \'new\'s for types descriptors */
|
|
SCOPEdo_types( scope, t, de )
|
|
//TYPEprint_new( t, files->create, schema );
|
|
SCOPEod;
|
|
|
|
/* do \'new\'s for entity descriptors */
|
|
list = SCOPEget_entities_superclass_order( scope );
|
|
//fprintf( files->init, "\n\t//\t***** Describe the Entities \t*/\n" );
|
|
fprintf( files->inc, "\n//\t***** Describe the Entities \t\n" );
|
|
LISTdo( list, e, Entity );
|
|
ENTITYput_superclass( e ); /* find supertype to use for single */
|
|
ENTITYprint_new( e, files, schema, 0 ); /* inheritance */
|
|
LISTod;
|
|
|
|
// Print Entity Classes
|
|
LISTdo( list, e, Entity );
|
|
ENTITYPrint( e, files, schema );
|
|
LISTod;
|
|
/* fill in the values for the type descriptors */
|
|
/* and print the enumerations */
|
|
//fprintf(files->lib,"register_defined_types():\n");
|
|
fprintf( files->inc, "\n//\t***** Describe the Other Types \t\n" );
|
|
SCOPEdo_types( scope, t, de )
|
|
TYPEprint_descriptions( t, files, schema );
|
|
if( TYPEis_select( t ) ) {
|
|
/* do the select aggregates here */
|
|
strncpy( nm, SelectName( TYPEget_name( t ) ), BUFSIZ );
|
|
fprintf( files->inc, "class %s;\ntypedef %s * %sH;\n", nm, nm, nm );
|
|
fprintf( files->inc,
|
|
"typedef %s * %s_ptr;\ntypedef %s_ptr %s_var;\n\n",
|
|
nm, nm, nm, nm );
|
|
fprintf( files->inc, "class %ss;\ntypedef %ss * %ssH;\n", nm, nm, nm );
|
|
fprintf( files->inc,
|
|
"typedef %ss * %ss_ptr;\ntypedef %ss_ptr %ss_var;\n\n",
|
|
nm, nm, nm, nm );
|
|
}
|
|
SCOPEod;
|
|
|
|
/* build the typedefs */
|
|
SCOPEdo_types( scope, t, de )
|
|
if( !( TYPEis_select( t ) ) ) {
|
|
TYPEprint_typedefs( t, files ->inc );
|
|
}
|
|
SCOPEod;
|
|
|
|
/* do the select definitions next, since they depend on the others */
|
|
fprintf( files->inc, "\n//\t***** Build the SELECT Types \t\n" );
|
|
//fprintf( files->init, "\n//\t***** Add the TypeDescriptor's to the"
|
|
// " SELECT Types \t\n" );
|
|
SCOPEdo_types( scope, t, de )
|
|
if( TYPEis_select( t ) ) {
|
|
TYPEselect_print( t, files, schema );
|
|
}
|
|
SCOPEod;
|
|
|
|
LISTfree( list );
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************
|
|
** Procedure: SCHEMAprint
|
|
** Parameters: const Schema schema - schema to print
|
|
** FILES *file - file on which to print
|
|
** Express model - fedex rep of entire EXPRESS file
|
|
** ComplexCollect col - all the complex entity info pertaining
|
|
** to this EXPRESS file
|
|
** int suffix - suffix to use for generated cc files
|
|
** Returns:
|
|
** Description: handles initialization of files specific to schemas
|
|
** Side Effects:
|
|
** Status:
|
|
******************************************************************/
|
|
|
|
void
|
|
SCHEMAprint( Schema schema, FILES * files, Express model, void * complexCol,
|
|
int suffix ) {
|
|
char schnm[MAX_LEN], sufnm[MAX_LEN], fnm[MAX_LEN], *np;
|
|
/* sufnm = schema name + suffix */
|
|
FILE * libfile,
|
|
//*incfile,
|
|
//*schemafile = files->incall,
|
|
// *schemainit = files->initall,
|
|
*initfile
|
|
// *createall = files->create
|
|
;
|
|
Rule r;
|
|
Function f;
|
|
Procedure p;
|
|
DictionaryEntry de;
|
|
char * tmpstr = 0;
|
|
unsigned int tmpstr_size = 0;
|
|
/********** create files based on name of schema ***********/
|
|
/* return if failure */
|
|
/* 1. header file */
|
|
//sprintf( schnm, "%s%s", SCHEMA_FILE_PREFIX,
|
|
// StrToUpper( SCHEMAget_name( schema ) ) );
|
|
sprintf( schnm, "%s", SCHEMAget_name( schema ) );
|
|
if( suffix == 0 ) {
|
|
sprintf( sufnm, "%s", schnm );
|
|
} else {
|
|
sprintf( sufnm, "%s_%d", schnm, suffix );
|
|
}
|
|
sprintf( fnm, "%s.h", sufnm );
|
|
|
|
np = fnm + strlen( fnm ) - 1; /* point to end of constant part of string */
|
|
|
|
/* 2. class source file */
|
|
sprintf( np, "py" );
|
|
if( !( libfile = ( files -> lib ) = FILEcreate( fnm ) ) ) {
|
|
return;
|
|
}
|
|
//fprintf( libfile, "/* %cId$ */ \n", '$' );
|
|
fprintf(libfile,"from SCL.SCLBase import *\n");
|
|
fprintf(libfile,"from SCL.SimpleDataTypes import *\n");
|
|
fprintf(libfile,"from SCL.ConstructedDataTypes import *\n");
|
|
fprintf(libfile,"from SCL.AggregationDataTypes import *\n");
|
|
fprintf(libfile,"from SCL.TypeChecker import check_type\n");
|
|
fprintf(libfile,"from SCL.Expr import *\n");
|
|
|
|
/********** do the schemas ***********/
|
|
|
|
/* really, create calls for entity constructors */
|
|
SCOPEPrint( schema, files, schema, model, ( ComplexCollect * )complexCol,
|
|
suffix );
|
|
|
|
/********** close the files ***********/
|
|
FILEclose( libfile );
|
|
//FILEclose( incfile );
|
|
//if( schema->search_id == PROCESSED ) {
|
|
// fprintf( initfile, "\n}\n" );
|
|
// FILEclose( initfile );
|
|
//} else {
|
|
// fclose( initfile );
|
|
//}
|
|
}
|
|
|
|
/******************************************************************
|
|
** Procedure: getMCPrint
|
|
** Parameters:
|
|
Express express - in memory representation of an express model
|
|
FILE* schema_h - generated schema.h file
|
|
FILE* schema_cc - schema.cc file
|
|
** Returns:
|
|
** Description: drives functions to generate code for all the schemas
|
|
** in an Express model into one set of files -- works with
|
|
** print_schemas_combined
|
|
** Side Effects: generates code
|
|
** Status: 24-Feb-1992 new -kcm
|
|
******************************************************************/
|
|
void
|
|
getMCPrint( Express express, FILE * schema_h, FILE * schema_cc ) {
|
|
DictionaryEntry de;
|
|
Schema schema;
|
|
|
|
fprintf( schema_h,
|
|
"\nSCLP23(Model_contents_ptr) GetModelContents(char *schemaName);\n" );
|
|
fprintf( schema_cc, "%s%s%s%s",
|
|
"// Generate a function to be called by Model to help it\n",
|
|
"// create the necessary Model_contents without the\n",
|
|
"// dictionary (Registry) handle since it doesn't have a\n",
|
|
"// predetermined way to access to the handle.\n" );
|
|
fprintf( schema_cc,
|
|
"\nSCLP23(Model_contents_ptr) GetModelContents(char *schemaName)\n{\n" );
|
|
DICTdo_type_init( express->symbol_table, &de, OBJ_SCHEMA );
|
|
schema = ( Scope )DICTdo( &de );
|
|
fprintf( schema_cc,
|
|
" if(!strcmp(schemaName, \"%s\"))\n",
|
|
SCHEMAget_name( schema ) );
|
|
fprintf( schema_cc,
|
|
" return (SCLP23(Model_contents_ptr)) new SdaiModel_contents_%s; \n",
|
|
SCHEMAget_name( schema ) );
|
|
while( ( schema = ( Scope )DICTdo( &de ) ) != 0 ) {
|
|
fprintf( schema_cc,
|
|
" else if(!strcmp(schemaName, \"%s\"))\n",
|
|
SCHEMAget_name( schema ) );
|
|
fprintf( schema_cc,
|
|
" return (SCLP23(Model_contents_ptr)) new SdaiModel_contents_%s; \n",
|
|
SCHEMAget_name( schema ) );
|
|
}
|
|
fprintf( schema_cc, "}\n" );
|
|
}
|
|
|
|
/******************************************************************
|
|
** Procedure: EXPRESSPrint
|
|
** Parameters:
|
|
Express express -- in memory representation of an express model
|
|
FILES* files -- set of output files to print to
|
|
** Returns:
|
|
** Description: drives functions to generate code for all the schemas
|
|
** in an Express model into one set of files -- works with
|
|
** print_schemas_combined
|
|
** Side Effects: generates code
|
|
** Status: 24-Feb-1992 new -kcm
|
|
******************************************************************/
|
|
void
|
|
EXPRESSPrint( Express express, ComplexCollect & col, FILES * files ) {
|
|
char fnm [MAX_LEN], *np;
|
|
const char * schnm; /* schnm is really "express name" */
|
|
FILE * libfile;
|
|
//FILE * incfile;
|
|
//FILE * schemafile = files -> incall;
|
|
//FILE * schemainit = files -> initall;
|
|
FILE * initfile;
|
|
/* new */
|
|
Schema schema;
|
|
DictionaryEntry de;
|
|
|
|
|
|
/********** create files based on name of schema ***********/
|
|
/* return if failure */
|
|
/* 1. header file */
|
|
sprintf( fnm, "%s.h", schnm = ClassName( EXPRESSget_basename( express ) ) );
|
|
//if( !( incfile = ( files -> inc ) = FILEcreate( fnm ) ) ) {
|
|
// return;
|
|
//}
|
|
//fprintf( incfile, "/* %cId$ */\n", '$' );
|
|
|
|
//fprintf( incfile, "#ifdef __O3DB__\n" );
|
|
//fprintf( incfile, "#include <OpenOODB.h>\n" );
|
|
//fprintf( incfile, "#endif\n\n" );
|
|
//fprintf( incfile, "#include <sdai.h> \n" );
|
|
/* fprintf (incfile, "#include <schema.h> \n");*/
|
|
/* fprintf (incfile, "extern void %sInit (Registry & r);\n", schnm);*/
|
|
|
|
//np = fnm + strlen( fnm ) - 1; /* point to end of constant part of string */
|
|
|
|
/* 2. class source file */
|
|
//sprintf( np, "cc" );
|
|
if( !( libfile = ( files -> lib ) = FILEcreate( fnm ) ) ) {
|
|
return;
|
|
}
|
|
//fprintf( libfile, "/* %cId$ */\n", '$' );
|
|
//fprintf( libfile, "#include <%s.h> n", schnm );
|
|
|
|
/* 3. source code to initialize entity registry */
|
|
/* prints header of file for input function */
|
|
|
|
//sprintf( np, "init.cc" );
|
|
//if( !( initfile = ( files -> init ) = FILEcreate( fnm ) ) ) {
|
|
// return;
|
|
//}
|
|
//fprintf( initfile, "/* $Id%d */\n", '$' );
|
|
//fprintf( initfile, "#include <%s.h>\n\n", schnm );
|
|
//fprintf( initfile, "void \n%sInit (Registry& reg)\n{\n", schnm );
|
|
|
|
/********** record in files relating to entire input ***********/
|
|
|
|
/* add to schema's include and initialization file */
|
|
//fprintf( schemafile, "#include <%s.h>\n\n", schnm );
|
|
//fprintf( schemafile, "extern void %sInit (Registry & r);\n", schnm );
|
|
//fprintf( schemainit, "\t extern void %sInit (Registry & r);\n", schnm );
|
|
//fprintf( schemainit, "\t %sInit (reg);\n", schnm );
|
|
|
|
/********** do all schemas ***********/
|
|
DICTdo_init( express->symbol_table, &de );
|
|
while( 0 != ( schema = ( Scope )DICTdo( &de ) ) ) {
|
|
SCOPEPrint( schema, files, schema, express, &col, 0 );
|
|
}
|
|
|
|
|
|
/********** close the files ***********/
|
|
FILEclose( libfile );
|
|
//FILEclose( incfile );
|
|
//fprintf( initfile, "\n}\n" );
|
|
//FILEclose( initfile );
|
|
|
|
}
|
|
|
|
/******************************************************************
|
|
** Procedure: print_schemas_combined
|
|
** Parameters:
|
|
Express express -- in memory representation of an express model
|
|
FILES* files -- set of output files to print to
|
|
** Returns:
|
|
** Description: drives functions to generate code for all the schemas
|
|
** in an Express model into one set of files -- works with EXPRESSPrint
|
|
** Side Effects: generates code
|
|
** Status: 24-Feb-1992 new -kcm
|
|
******************************************************************/
|
|
|
|
void
|
|
print_schemas_combined( Express express, ComplexCollect & col, FILES * files ) {
|
|
|
|
EXPRESSPrint( express, col, files );
|
|
}
|
|
|
|
/*
|
|
** Procedure: print_file
|
|
** Parameters: const Schema schema - top-level schema to print
|
|
** FILE* file - file on which to print
|
|
** Returns: void
|
|
** Description: this function calls one of two different functions
|
|
** depending on whether the output should be combined into a single
|
|
** set of files or a separate set for each schema
|
|
**
|
|
*/
|
|
|
|
void
|
|
print_file( Express express ) {
|
|
extern void RESOLUTIONsucceed( void );
|
|
int separate_schemas = 1;
|
|
ComplexCollect col( express );
|
|
|
|
File_holder files;
|
|
|
|
resolution_success();
|
|
|
|
print_file_header( express, &files );
|
|
if( separate_schemas ) {
|
|
print_schemas_separate( express, ( void * )&col, &files );
|
|
} else {
|
|
print_schemas_combined( express, col, &files );
|
|
}
|
|
print_file_trailer( express, &files );
|
|
//print_complex( col, ( const char * )"compstructs.cc" );
|
|
}
|