home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftptest.leeds.ac.uk
/
2015.02.ftptest.leeds.ac.uk.tar
/
ftptest.leeds.ac.uk
/
bionet
/
CAE-GROUP
/
SCL-WIN3x
/
FED_PLUS.EXE
/
CLASSES.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-07-29
|
60KB
|
1,824 lines
/*
** Fed-x parser output module for generating C++ class definitions
** December 5, 1989
** release 2 17-Feb-1992
** release 3 March 1993
** release 4 December 1993
** K. C. Morris
**
** Development of Fed-x was funded by the United States Government,
** and is not subject to copyright.
*******************************************************************
The conventions used in this binding follow the proposed specification
for the STEP Standard Data Access Interface as defined in document
N350 ( August 31, 1993 ) of ISO 10303 TC184/SC4/WG7.
*******************************************************************/
/******************************************************************
*** The functions in this file generate the C++ code for ENTITY **
*** classes, TYPEs, and TypeDescriptors. ***
** **/
static char rcsid[] ="$Id: classes.c,v 1.47 1994/03/30 15:58:39 kc Exp $";
#include "classes.h"
static attr_count; /* number each attr to avoid inter-entity clashes */
static type_count; /* number each temporary type for same reason above */
char *FundamentalType(const Type,int);
extern int any_duplicates_in_select( const Linked_List list );
/******************************************************************
** Procedure: generate_attribute_name
** Parameters: Variable a, an Express attribute; char *out, the C++ name
** Description: converts an Express name into the corresponding C++ name
** Side Effects:
** Status: complete 8/5/93
******************************************************************/
void*
generate_attribute_name( Variable a, char *out )
{
char *temp, *p;
temp = a->name->symbol.name;/*EXPRto_string( VARget_name(a) ); */
p = temp;
if (! strncmp (StrToLower (p), "self\\", 5))
p = p +5;
/* copy p to out */
strncpy( out, StrToLower (p), BUFSIZ );
/* if there\'s an illegal character in out,
change it to a _ */
while (p = strrchr(out,'.'))
*p = '_';
free( temp );
return out;
}
/******************************************************************
** Procedure: TYPEget_express_type (const Type t)
** Parameters: const Type t -- type for attribute
** Returns: a string which is the type as it would appear in Express
** Description: supplies the type for error messages
and to register the entity
- calls itself recursively to create a description of
aggregate types
** Side Effects:
** Status: new 1/24/91
******************************************************************/
String
TYPEget_express_type (const Type t)
{
Class_Of_Type class;
Type bt;
char retval [BUFSIZ];
char *n, * permval, * aggr_type;
/* 1. "DEFINED" types */
/* case TYPE_ENUM: */
/* case TYPE_ENTITY: */
/* case TYPE_SELECT: */
if (n = TYPEget_name (t)) {
PrettyTmpName (n);
}
/* 2. "BASE" types */
class = TYPEget_type (t);
/* case TYPE_LOGICAL: */
if ((class == Class_Boolean_Type) || ( class == Class_Logical_Type))
return ("Logical");
/* case TYPE_INTEGER: */
if ( class == Class_Integer_Type)
return ("Integer ");
/* case TYPE_REAL:
case TYPE_NUMBER: */
if ((class == Class_Number_Type) || ( class == Class_Real_Type))
return ("Real ");
/* case TYPE_STRING: */
if (class == Class_String_Type)
return ("String ") ;
/* case TYPE_BINARY: */
if ( class == Class_Binary_Type)
return ("Binary ") ;
/* AGGREGATES
case TYPE_ARRAY:
case TYPE_BAG:
case TYPE_LIST:
case TYPE_SET:
*/
if (isAggregateType (t)) {
bt = TYPEget_nonaggregate_base_type (t);
class = TYPEget_type (bt);
/* case TYPE_ARRAY: */
if (TYPEget_type (t) == Class_Array_Type) {
aggr_type = "Array";
}
/* case TYPE_LIST: */
if (TYPEget_type (t) == Class_List_Type) {
aggr_type = "List";
}
/* case TYPE_SET: */
if (TYPEget_type (t) == Class_Set_Type) {
aggr_type = "Set";
}
/* case TYPE_BAG: */
if (TYPEget_type (t) == Class_Bag_Type) {
aggr_type = "Bag";
}
sprintf (retval, "%s of %s",
aggr_type, TYPEget_express_type (bt));
/* this will declare extra memory when aggregate is > 1D */
permval = malloc (strlen (retval) * sizeof (char) +1);
strcpy (permval, retval);
return permval;
}
/* default returns undefined */
printf ("WARNING2: type %s is undefined\n", TYPEget_name (t));
return ("SCLundefined");
}
/******************************************************************
** Procedure: ATTRsign_access_method
** Parameters: const Variable a -- attribute to print
access method signature for
** FILE* file -- file being written to
** Returns: nothing
** Description: prints the signature for an access method
based on the attribute type
** Side Effects:
** Status: complete 17-Feb-1992
******************************************************************/
void
ATTRsign_access_methods (Variable a, FILE* file)
{
Type t = VARget_type (a);
Class_Of_Type class;
char ctype [BUFSIZ];
char attrnm [BUFSIZ];
strcpy(attrnm,(char*)generate_attribute_name( a, attrnm ));
strncpy (attrnm, CheckWord (StrToLower (attrnm)), BUFSIZ);
attrnm[0] = toupper(attrnm[0]);
class = TYPEget_type(t);
strncpy (ctype, AccessType (t), BUFSIZ);
/* LOGICAL and ENUM use an enumerated value in the put funciton */
/* case TYPE_LOGICAL: */
if ((class == Class_Boolean_Type) || ( class == Class_Logical_Type)) {
fprintf (file, "\tconst Logical& %s() const;\n", attrnm);
fprintf (file, "\tvoid %s (LOGICAL x);\n", attrnm );
return;
}
/* case TYPE_ENUM: */
if ( class == Class_Enumeration_Type) {
fprintf (file, "\tconst %s& %s() const;\n", ctype, attrnm);
fprintf (file, "\tvoid %s (%s x);\n",
attrnm, EnumName (TYPEget_name (t)) );
return;
}
/* case STRING */
if ( class == Class_String_Type) {
fprintf (file, "\tconst %s& %s() const;\n", ctype, attrnm);
fprintf (file, "\tvoid %s (const char * x);\n", attrnm );
return;
}
/* case TYPE_BINARY: */
if ( class == Class_Binary_Type) {
fprintf (file, "\tconst %s& %s() const;\n", ctype, attrnm);
fprintf (file, "\tvoid %s (const %s& x);\n", attrnm, ctype );
return;
}
/* case TYPE_ENTITY: */
if (class == Class_Entity_Type) {
/* get method doesn\'t return const */
fprintf (file, "\t%s %s() const;\n", ctype, attrnm);
fprintf (file, "\tvoid %s (%s x);\n", attrnm, ctype );
return;
}
/* default: INTEGER, and NUMBER */
/* case TYPE_SELECT: */
/* case TYPE_AGGRETATES: */
/* case TYPE_ENTITY: */
/* is the same type as the data member */
fprintf (file, "\tconst %s %s() const;\n", ctype, attrnm);
fprintf (file, "\tvoid %s (%s x);\n", attrnm, ctype );
}
/******************************************************************
** Procedure: ATTRprint_access_methods_get_head
** Parameters: const Variable a -- attribute to find the type for
** FILE* file -- file being written
** Type t - type of the attribute
** Class_Of_Type class -- type name of the class
** const char *attrnm -- name of the attribute
** char *ctype -- (possibly returned) name of the attribute c++ type
** Returns: name to be used for the type of the c++ access functions
** Description: prints the access method get head based on the attribute type
** Side Effects:
** Status: complete 7/15/93 by DDH
******************************************************************/
void
ATTRprint_access_methods_get_head (const char * classnm, Variable a, FILE* file)
{
Type t = VARget_type (a);
Class_Of_Type class = TYPEget_type(t);
char ctype [BUFSIZ]; /* return type of the get function */
char funcnm [BUFSIZ]; /* name of member function */
strcpy(funcnm,(char*)generate_attribute_name( a, funcnm ));
funcnm[0] = toupper(funcnm[0]);
strncpy( ctype, AccessType (t), BUFSIZ );
/* case STRING: */
/* case TYPE_BINARY: */
/* string can\'t be const because it causes problems with SELECTs */
if (( class == Class_String_Type) || ( class == Class_Binary_Type)) {
fprintf (file, "\nconst %s& \n%s::%s() const\n", ctype, classnm, funcnm);
return;
}
/* case ENTITY: */
/* return value isn\'t const */
if ( class == Class_Entity_Type) {
fprintf (file, "\n%s \n%s::%s() const \n", ctype, classnm, funcnm);
return;
}
/* case TYPE_LOGICAL: */
if ((class == Class_Boolean_Type) || ( class == Class_Logical_Type)) {
fprintf (file, "\nconst Logical& \n%s::%s() const \n", classnm, funcnm);
return;
}
/* case TYPE_ENUM: */
if ( class == Class_Enumeration_Type)
sprintf (ctype, "%s &", TYPEget_ctype (t));
/* default: INTEGER and NUMBER */
/* case TYPE_AGGRETATES: */
/* case TYPE_SELECT: */
/* case TYPE_ENTITY: */
/* is the same type as the data member */
fprintf (file, "\nconst %s \n%s::%s() const \n", ctype, classnm, funcnm);
}
/******************************************************************
** Procedure: ATTRprint_access_methods_put_head
** Parameters: const Variable a -- attribute to find the type for
** FILE* file -- file being written to
** Type t - type of the attribute
** Class_Of_Type class -- type name of the class
** const char *attrnm -- name of the attribute
** char *ctype -- name of the attribute c++ type
** Returns: name to be used for the type of the c++ access functions
** Description: prints the access method put head based on the attribute type
** Side Effects:
** Status: complete 7/15/93 by DDH
******************************************************************/
void
ATTRprint_access_methods_put_head (CONST char * entnm, Variable a, FILE* file)
{
Type t = VARget_type (a);
char ctype [BUFSIZ];
char funcnm [BUFSIZ];
Class_Of_Type class = TYPEget_type (t);
strncpy( ctype, AccessType (t), BUFSIZ );
strcpy(funcnm,(char*)generate_attribute_name( a, funcnm ));
funcnm [0] = toupper (funcnm[0]);
/* case TYPE_LOGICAL: */
if ((class == Class_Boolean_Type) || ( class == Class_Logical_Type))
strcpy (ctype, "LOGICAL");
/* case TYPE_ENUM: */
if ( class == Class_Enumeration_Type)
strncpy (ctype, EnumName (TYPEget_name (t)), BUFSIZ);
/* case STRING:*/
if ( class == Class_String_Type)
strcpy (ctype, "const char *");
/* case TYPE_BINARY: */
if ( class == Class_Binary_Type)
sprintf (ctype, "const %s&", AccessType (t));
/* default: INTEGER and NUMBER */
/* case TYPE_AGGRETATES: */
/* case TYPE_ENTITY: */
/* case TYPE_SELECT: */
/* is the same type as the data member */
fprintf (file, "\nvoid \n%s::%s (%s x)\n", entnm, funcnm, ctype );
}
/******************************************************************
** Procedure: ATTRprint_access_method
** Parameters: const Variable a -- attribute to find the type for
** FILE* file -- file being written to
** Returns: name to be used for the type of the c++ access functions
** Description: prints the access method based on the attribute type
** Side Effects:
** Status: complete 1/15/91
** updated 17-Feb-1992 to print to library file instead of header
** updated 15-July-1993 to call the get/put head functions by DDH
******************************************************************/
void
ATTRprint_access_methods (CONST char * entnm, Variable a, FILE* file)
{
Type t = VARget_type (a);
Class_Of_Type class;
char ctype [BUFSIZ]; /* type of data member */
char return_type [BUFSIZ];
char attrnm [BUFSIZ];
char membernm[BUFSIZ];
strcpy(attrnm,(char*)generate_attribute_name( a, attrnm ));
strcpy( membernm, attrnm );
membernm[0] = toupper(membernm[0]);
class = TYPEget_type (t);
/* strncpy (ctype, TYPEget_ctype (t), BUFSIZ);*/
strncpy (ctype, AccessType (t), BUFSIZ);
ATTRprint_access_methods_get_head( entnm, a, file);
/* case TYPE_ENTITY: */
if ( class == Class_Entity_Type) {
fprintf (file, "\t{ return (%s) _%s; }\n", ctype, attrnm);
ATTRprint_access_methods_put_head( entnm, a, file);
fprintf (file, "\t{ _%s = x; }\n", attrnm );
return;
}
/* case TYPE_LOGICAL: */
if ((class == Class_Boolean_Type) || ( class == Class_Logical_Type)) {
fprintf (file, "\t{ return (const Logical&) _%s; }\n", attrnm);
ATTRprint_access_methods_put_head( entnm, a, file);
fprintf (file, "\t{ _%s.put (x); }\n", attrnm );
return;
}
/* case TYPE_ENUM: */
if ( class == Class_Enumeration_Type) {
fprintf (file, "\t{ return (const %s&) _%s; }\n", ctype, attrnm);
ATTRprint_access_methods_put_head( entnm, a, file);
fprintf (file, "\t{ _%s.put (x); }\n", attrnm );
return;
}
/* case TYPE_SELECT: */
if ( class == Class_Select_Type) {
fprintf (file, "\t{ return (const %s) &_%s; }\n", ctype, attrnm);
ATTRprint_access_methods_put_head( entnm, a, file);
fprintf (file, "\t{ _%s = x; }\n", attrnm );
return;
}
/* case TYPE_AGGRETATES: */
if ( isAggregate (a)) {
fprintf (file, "\t{ return (%s) &_%s; }\n", ctype, attrnm);
ATTRprint_access_methods_put_head( entnm, a, file);
fprintf (file, "\t{ _%s.ShallowCopy (*x); }\n", attrnm );
return;
}
/* case STRING:*/
/* case TYPE_BINARY: */
if (( class == Class_String_Type) || ( class == Class_Binary_Type)) {
fprintf (file, "\t{ return (const %s&) _%s; }\n", ctype, attrnm);
ATTRprint_access_methods_put_head( entnm, a, file);
fprintf (file, "\t{ _%s = x; }\n", attrnm );
return;
}
/* default: INTEGER and NUMBER */
/* is the same type as the data member */
fprintf (file, "\t{ return (const %s) _%s; }\n", ctype, attrnm);
ATTRprint_access_methods_put_head( entnm, a, file);
fprintf (file, "\t{ _%s = x; }\n", attrnm );
}
/******************************************************************
** Entity Generation */
/******************************************************************
** Procedure: ENTITYhead_print
** Parameters: const Entity entity
** FILE* file -- file being written to
** Returns:
** Description: prints the beginning of the class definition for the c++ code
** and the declaration of extern type descriptors for the registry
** Side Effects: generates c++ code
** Status: good 1/15/91
** added registry things 12-Apr-1993
******************************************************************/
void
ENTITYhead_print (Entity entity, FILE* file,Schema schema)
{
char buffer [BUFSIZ];
char entnm [BUFSIZ];
char attrnm [BUFSIZ];
char *buf = buffer;
char *tmp;
Linked_List list;
int attr_count_tmp = attr_count;
int super_cnt =0;
Entity super =0;
strncpy (entnm, ENTITYget_classname (entity), BUFSIZ);
LISTdo(ENTITYget_attributes(entity),v,Variable)
strcpy(attrnm,(char*)generate_attribute_name( v, attrnm ));
fprintf(file,"extern %sAttrDescriptor *%s%d%s%s;\n",
(VARget_inverse (v) ? "Inverse" : ""),
ATTR_PREFIX,attr_count_tmp++,
(VARis_derived (v) ? "D" : (VARget_inverse (v) ? "I" : "")),
attrnm);
LISTod
fprintf (file, "\nclass %s : ", entnm);
super = ENTITYput_superclass (entity);
if (super) fprintf (file, " public %s {\n ", ENTITYget_classname (super));
else
fprintf (file, " public STEPentity {\n");
#ifdef MULTIPLE_INHERITANCE
list = ENTITYget_supertypes (entity);
if (! LISTempty (list)) {
LISTdo (list, e, Entity)
/* if there\'s no super class yet,
or the super class doesn\'t have any attributes
*/
if ( (! super) || (! ENTITYhas_explicit_attributes (super) )) {
super = e;
++ super_cnt;
} else {
printf ("WARNING: multiple inheritance not implemented.\n");
printf ("\tin ENTITY %s\n\tSUPERTYPE %s IGNORED.\n\n",
ENTITYget_name (entity), ENTITYget_name (e));
}
LISTod;
fprintf (file, " public %s {\n ", ENTITYget_classname (super));
/* for multiple inheritance
LISTdo (list, e, Entity)
sprintf (buf, " public %s, ", ENTITYget_classname (e));
move (buf);
LISTod;
sprintf (buf - 2, " {\n");
move (buf);
fprintf(file,buffer);
*/
} else { /* if entity has no supertypes, it's at top of hierarchy */
fprintf (file, " public STEPentity {\n");
}
#endif
}
/******************************************************************
** Procedure: DataMemberPrint
** Parameters: const Entity entity -- entity being processed
** FILE* file -- file being written to
** Returns:
** Description: prints out the data members for an entity's c++ class
** definition
** Side Effects: generates c++ code
** Status: ok 1/15/91
******************************************************************/
void
DataMemberPrint(Entity entity, FILE* file,Schema schema)
{
Linked_List attr_list;
char entnm [BUFSIZ];
char attrnm [BUFSIZ];
const char * ctype, * etype;
strncpy (entnm, ENTITYget_classname (entity), BUFSIZ); /* assign entnm */
/* print list of attributes in the protected access area */
fprintf (file, " protected:\n");
attr_list = ENTITYget_attributes (entity);
LISTdo (attr_list, a, Variable)
if (VARget_initializer (a) == EXPRESSION_NULL) {
ctype = TYPEget_ctype (VARget_type (a));
strcpy(attrnm,(char*)generate_attribute_name( a, attrnm ));
if (!strcmp (ctype, "SCLundefined") ) {
printf ("WARNING: in entity %s:\n", ENTITYget_name (entity));
printf ("\tthe type for attribute %s is not fully implemented\n",
attrnm);
}
fprintf (file, "\t%s _%s ;", ctype, attrnm);
if (VARget_optional (a)) fprintf (file, " // OPTIONAL");
if (isAggregate (a)) {
/* if it's a named type, comment the type */
if (etype = TYPEget_name (TYPEget_nonaggregate_base_type (VARget_type (a))))
fprintf (file, "\t // of %s\n", etype);
}
fprintf (file, "\n");
}
LISTod;
}
/******************************************************************
** Procedure: MemberFunctionSign
** Parameters: Entity *entity -- entity being processed
** FILE* file -- file being written to
** Returns:
** Description: prints the signature for member functions
of a entity's class definition
** Side Effects: prints c++ code to a file
** Status: ok 1/1/5/91
** updated 17-Feb-1992 to print only the signature
and not the function definitions
******************************************************************/
void
MemberFunctionSign (Entity entity, FILE* file)
{
Linked_List attr_list;
static int entcode = 0;
char entnm [BUFSIZ];
strncpy (entnm, ENTITYget_classname (entity), BUFSIZ); /* assign entnm */
fprintf (file, " public: \n");
/* put in member functions which belong to all entities */
/* constructor: */
fprintf (file, "\n %s ( ); \n", entnm);
/* copy constructor*/
fprintf (file, " %s (%s& e ); \n",entnm,entnm);
/* destructor: */
fprintf (file, " ~%s ();\n", entnm);
/* fprintf (file, " char *Name () { return \"%s\"; }\n", */
/* PrettyTmpName (ENTITYget_name (entity)));*/
fprintf (file, " int opcode () { return %d ; } \n",
entcode++);
/* print signiture of access functions for attributes */
attr_list = ENTITYget_attributes (entity);
LISTdo (attr_list, a, Variable)
if (VARget_initializer (a) == EXPRESSION_NULL) {
/* retrieval and assignment */
ATTRsign_access_methods (a, file);
}
LISTod;
fprintf (file, "};\n");
/* print creation function for class */
fprintf (file, "inline %s *\ncreate_%s () { return new %s ; }\n",
entnm, entnm, entnm);
}
/******************************************************************
** Procedure: LIBdescribe_entity (entity, file, schema)
** Parameters: Entity entity -- entity being processed
** FILE* file -- file being written to
** Schema schema -- schema being processed
** Returns:
** Description: declares the global pointer to the EntityDescriptor
representing a particular entity
** Side Effects: prints c++ code to a file
** Status: ok 12-Apr-1993
******************************************************************/
void
LIBdescribe_entity (Entity entity, FILE* file, Schema schema)
{
Linked_List list;
int attr_count_tmp = attr_count;
char attrnm [BUFSIZ];
char * tmp;
fprintf(file,"EntityDescriptor *%s%s%s =0;\n",
SCHEMAget_name(schema),ENT_PREFIX,ENTITYget_name(entity));
LISTdo(ENTITYget_attributes(entity),v,Variable)
strcpy(attrnm,(char*)generate_attribute_name( v, attrnm ));
fprintf(file,"%sAttrDescriptor *%s%d%s%s =0;\n",
(VARget_inverse (v) ? "Inverse" : ""),
ATTR_PREFIX, attr_count_tmp++,
(VARis_derived (v) ? "D" : (VARget_inverse (v) ? "I" : "")),
attrnm);
LISTod
}
/******************************************************************
** Procedure: LIBmemberFunctionPrint
** Parameters: Entity *entity -- entity being processed
** FILE* file -- file being written to
** Returns:
** Description: prints the member functions for the class
representing an entity
** Side Effects: prints c++ code to a file
** Status: ok 17-Feb-1992
******************************************************************/
void
LIBmemberFunctionPrint (Entity entity, FILE* file)
{
Linked_List attr_list;
char entnm [BUFSIZ];
strncpy (entnm, ENTITYget_classname (entity), BUFSIZ); /* assign entnm */
/* 1. put in member functions which belong to all entities */
/* the common function are still in the class definition 17-Feb-1992 */
/* fprintf (file, " char *Name () { return \"%s\"; }\n",
PrettyTmpName (ENTITYget_name (entity)));
fprintf (file, " int opcode () { return %d ; }\n",
entcode++);
*/
/* 2. print access functions for attributes */
attr_list = ENTITYget_attributes (entity);
LISTdo (attr_list, a, Variable)
/* do for EXPLICIT and INVERSE attributes - but not DERIVED */
if ( ! VARis_derived (a) ) {
/* retrieval and assignment */
ATTRprint_access_methods (entnm, a, file);
}
LISTod;
}
/******************************************************************
** Procedure: ENTITYinc_print
** Parameters: Entity *entity -- entity being processed
** FILE* file -- file being written to
** Returns:
** Description: drives the generation of the c++ class definition code
** Side Effects: prints segment of the c++ .h file
** Status: ok 1/15/91
******************************************************************/
void
ENTITYinc_print (Entity entity, FILE* file,Schema schema)
{
ENTITYhead_print ( entity, file,schema);
DataMemberPrint (entity, file, schema);
MemberFunctionSign (entity, file);
}
/******************************************************************
** Procedure: LIBcopy_constructor
** Parameters:
** Returns:
** Description:
** Side Effects:
** Status: not used 17-Feb-1992
******************************************************************/
void
LIBcopy_constructor (Entity ent, FILE* file)
{
Linked_List attr_list;
Class_Of_Type class;
Type t;
char buffer [BUFSIZ],
attrnm[BUFSIZ],
*b = buffer, *n = '\0';
int count = attr_count;
char * tmp;
String entnm = ENTITYget_classname (ent);
Boolean opt;
String StrToLower (String word);
/*mjm7/10/91 copy constructor definition */
fprintf (file, "\t%s::%s(%s& e ) \n", entnm, entnm,entnm);
fprintf (file, " {");
/* attributes */
attr_list = ENTITYget_attributes (ent);
LISTdo (attr_list, a, Variable)
if (VARget_initializer (a) == EXPRESSION_NULL) {
/* include attribute if it is not derived */
strcpy(attrnm,(char*)generate_attribute_name( a, attrnm ));
t = VARget_type (a);
class = TYPEget_type (t);
opt = VARget_optional (a);
/* 1. initialize everything to NULL (even if not optional) */
/* default: to intialize attribute to NULL */
sprintf (b, "\t_%s = e.%s();\n", attrnm,attrnm);
/*mjm7/11/91 case TYPE_STRING */
if ((class == Class_String_Type) || (class == Class_Binary_Type))
sprintf (b, "\t_%s = strdup(e.%s());\n", attrnm,attrnm);
/* case TYPE_ENTITY: */
if ( class == Class_Entity_Type)
sprintf (b, "\t_%s = e.%s();\n", attrnm,attrnm);
/* previous line modified to conform with SDAI C++ Binding for PDES, Inc. Prototyping 5/22/91 CD */
/* case TYPE_ENUM: */
if (class == Class_Enumeration_Type)
sprintf (b, "\t_%s.put(e.%s().asInt());\n", attrnm,attrnm);
/* case TYPE_SELECT: */
if (class == Class_Select_Type)
sprintf (b, "DDDDDDD\t_%s.put(e.%s().asInt());\n", attrnm,attrnm);
/* case TYPE_BOOLEAN */
if ( class == Class_Boolean_Type)
sprintf (b, "\t_%s.put(e.%s().asInt());\n", attrnm,attrnm);
/* previous line modified to conform with SDAI C++ Binding for PDES, Inc. Prototyping 5/22/91 CD */
/* case TYPE_LOGICAL */
if ( class == Class_Logical_Type)
sprintf (b, "\t_%s.put(e.%s().asInt());\n", attrnm,attrnm);
/* previous line modified to conform with SDAI C++ Binding for PDES, Inc. Prototyping 5/22/91 CD */
/* case TYPE_ARRAY:
case TYPE_LIST:
case TYPE_SET:
case TYPE_BAG: */
if (isAggregateType (t))
*b = '\0';
fprintf (file, "%s", b) ;
fprintf (file, "\t attributes.push ");
/* 2. put attribute on attributes list */
/* default: */
fprintf (file,"\n\t(new STEPattribute (*%s%d%s, %s &_%s));\n",
ATTR_PREFIX,count,
/* (VARis_derived (t) ? "D" : (VARget_inverse (t) ? "I" : "")),*/
attrnm,
(TYPEis_entity (t) ? "(STEPentityH *)" : ""),
attrnm);
++count;
}
LISTod;
fprintf (file, " }\n");
}
/******************************************************************
** Procedure: LIBstructor_print
** Parameters: Entity *entity -- entity being processed
** FILE* file -- file being written to
** Returns:
** Description: prints the c++ code for entity class's
** constructor and destructor
** Side Effects: generates codes segment in c++ .cc file
** Status: ok 1/15/91
** Changes: Modified generator to initialize attributes to NULL based
** on the NULL symbols defined in "SDAI C++ Binding for PDES,
** Inc. Prototyping" by Stephen Clark.
** Change Date: 5/22/91 CD
** Changes: Modified STEPattribute constructors to take fewer arguments
** 21-Dec-1992 -kcm
******************************************************************/
void
LIBstructor_print (Entity entity, FILE* file, Schema schema)
{
Linked_List attr_list;
Type t;
char attrnm [BUFSIZ];
const char * entnm = ENTITYget_classname (entity);
int count = attr_count;
int first =1;
/* constructor definition */
fprintf (file, "%s::%s( ) \n", entnm, entnm);
fprintf (file, "{");
/* attributes */
/* fprintf (file, "\n\tSTEPattribute * a;\n");*/
/* what if entity comes from other schema? */
fprintf(file,"\nEntityDescriptor = %s%s%s;\n",
SCHEMAget_name(schema),ENT_PREFIX,ENTITYget_name(entity));
attr_list = ENTITYget_attributes (entity);
LISTdo (attr_list, a, Variable)
if (VARget_initializer (a) == EXPRESSION_NULL) {
/* include attribute if it is not derived */
strcpy(attrnm,(char*)generate_attribute_name( a, attrnm ));
t = VARget_type (a);
/* 1. declare the AttrDescriptor */
/* this is now in the header */
/* fprintf(file,"extern AttrDescriptor *%s%d%s;\n",*/
/* ATTR_PREFIX,count,VARget_name(a));*/
/* if the attribute is Explicit, make a STEPattribute */
/* if (VARis_simple_explicit (a)) {*/
if (( ! VARget_inverse (a)) && ( ! VARis_derived (a)) ) {
/* 1. create a new STEPattribute */
fprintf (file,"\n\t"
"%s a = new STEPattribute (*%s%d%s, %s &_%s);\n",
(first ? "STEPattribute *" : ""),
/* first time through declare a */
ATTR_PREFIX,count, attrnm,
(TYPEis_entity (t) ? "(STEPentityH *)" : ""),
attrnm);
if (first) first = 0 ;
/* 2. initialize everything to NULL (even if not optional) */
fprintf (file, "\ta -> set_null ();\n");
/* 3. put attribute on attributes list */
fprintf (file, "\t attributes.push (a);\n");
}
count++;
}
LISTod;
attr_list = ENTITYget_all_attributes (entity);
LISTdo (attr_list, a, Variable)
if (VARis_overrider (entity, a)) {
strcpy(attrnm,(char*)generate_attribute_name( a, attrnm ));
fprintf (file, "\tMakeDerived (\"%s\");\n", attrnm);
}
LISTod;
fprintf (file, "}\n");
/* copy constructor */
/* LIBcopy_constructor (entity, file); */
entnm = ENTITYget_classname (entity),
fprintf (file, "%s::%s (%s& e ) \n",entnm,entnm,entnm);
fprintf (file, "\t{ CopyAs((STEPentityH) &e);\t}\n");
/* print destructor */
/* currently empty, but should check to see if any attributes need
to be deleted -- attributes will need reference count */
entnm = ENTITYget_classname (entity),
fprintf (file, "%s::~%s () { }\n", entnm, entnm);
}
/******************************************************************
** Procedure: ENTITYlib_print
** Parameters: Entity *entity -- entity being processed
** FILE* file -- file being written to
** Returns:
** Description: drives the printing of the code for the class library
** additional member functions can be generated by writing a routine
** to generate the code and calling that routine from this procedure
** Side Effects: generates code segment for c++ library file
** Status: ok 1/15/91
******************************************************************/
void
ENTITYlib_print (Entity entity, FILE* file,Schema schema)
{
LIBdescribe_entity (entity, file, schema);
LIBstructor_print (entity, file,schema);
LIBmemberFunctionPrint (entity, file);
}
/* return 1 if types are predefined by us */
int
TYPEis_builtin(const Type t) {
switch( TYPEget_body(t)->type) {/* dunno if correct*/
case integer_:
case real_:
case string_:
case binary_:
case boolean_:
case number_:
case logical_:
return 1;
}
return 0;
}
/* return schema which original defined this object */
/* i.e., thread back through USE/REF starting from referencing schema */
Schema
owning_schema(char *name,Schema schema)
{
Rename *rename;
Schema result;
if (DICTlookup(schema->symbol_table,name))
return(schema);
/* Occurs in a fully USE'd schema? */
LISTdo(schema->u.schema->uselist,schema,Schema)
/* follow chain'd USEs */
result = owning_schema(name,schema);
if (result) return(result);
LISTod;
/* Occurs in a partially USE'd schema? */
rename = (Rename *)DICTlookup(schema->u.schema->usedict,name);
if (rename) {
return(owning_schema(rename->old->name,rename->schema));
}
/* Occurs in a fully REF'd schema? */
LISTdo(schema->u.schema->reflist,schema,Schema)
result = owning_schema(name,schema);
if (result) return result;
else continue; /* try another schema */
LISTod;
/* Occurs in a partially REF'd schema? */
rename = (Rename *)DICTlookup(schema->u.schema->refdict,name);
if (rename) {
return(owning_schema(rename->old->name,rename->schema));
}
/* cannot happen */
/* indicates some inconsistency in internal structures, */
/* since this was earlier traversed successfully */
return 0;
}
/* go down through a type's base type chain, dynamically making and */
/* printing new types for each base type */
void
print_typechain(FILE *f,const Type t,char *buf,Schema schema)
{
/* if we've been called, current type has no name */
/* nor is it a built-in type */
/* the type_count variable is there for debugging purposes */
Type base;
int count = type_count++;
fprintf(f,"\tTypeDescriptor * %s%d = new TypeDescriptor;\n",TD_PREFIX,count);
fprintf(f," %s%d->FundamentalType(%s);\n",TD_PREFIX,count,FundamentalType(t,1));
fprintf(f," %s%d->Description(\"%s\");\n",TD_PREFIX,count,TypeDescription(t));
if (TYPEget_body(t)) base = TYPEget_body(t)->base;
if (TYPEget_head(t)) {
fprintf(f,
"\t%s%d->ReferentType(%s%s%s);\n",
TD_PREFIX,count,
SCHEMAget_name(owning_schema(TYPEget_name(TYPEget_head(t)),schema)),
TYPEprefix (t), TYPEget_name(TYPEget_head(t)) );
} else if (TYPEis_builtin(base)) {/* dunno if correct*/
fprintf(f," %s%d->ReferentType(%s%s);\n",
TD_PREFIX,count,
TD_PREFIX,FundamentalType(base,0));
} else if (TYPEget_body(base)->type == entity_) {
fprintf(f," %s%d->ReferentType (%s%s%s);\n",
TYPEprefix (t) ,count,
/* following assumes we are not in a nested entity */
/* otherwise we should search upward for schema */
TYPEget_name(TYPEget_body(base)->entity->superscope),ENT_PREFIX,TYPEget_name(base));
} else if (TYPEget_name(base)) {
/* type ref with name */
fprintf(f," %s%d->ReferentType(%s%s%s);\n",TD_PREFIX,count,
SCHEMAget_name(owning_schema(TYPEget_name(base),schema)),TD_PREFIX,TYPEget_name(base));
} else {
/* no name, recurse */
char callee_buffer[MAX_LEN];
print_typechain(f,base,callee_buffer,schema);
fprintf(f," %s%d->ReferentType(%s);\n",TD_PREFIX,count,callee_buffer);
}
sprintf(buf,"%s%d",TD_PREFIX,count);
}
/******************************************************************
** Procedure: ENTITYincode_print
** Parameters: Entity *entity -- entity being processed
** FILE* file -- file being written to
** Returns:
** Description: generates code to enter entity in STEP registry
** Side Effects:
** Status: ok 1/15/91
******************************************************************/
void
ENTITYincode_print (Entity entity, FILE* file,Schema schema) /* ,FILES *files) */
{
#define entity_name ENTITYget_name(entity)
#define schema_name SCHEMAget_name(schema)
const char *cn = ENTITYget_classname(entity);
char attrnm [BUFSIZ];
const char * super_schema;
char * tmp;
#if 0
String cn_unsafe = ENTITYget_classname (entity);
char cn[MAX_LEN];
/* cn_unsafe points to a static buffer, grr..., so save it */
strcpy(cn,cn_unsafe);
#endif
fprintf(file,"\treg.AddEntity (*%s%s%s);\n",
schema_name,ENT_PREFIX,entity_name);
/* LISTdo(ENTITYget_subtypes(entity),sub,Entity)
fprintf(file," %s%s%s->Subtypes().AddNode(%s%s%s);\n",
schema_name,ENT_PREFIX,entity_name,
schema_name,ENT_PREFIX,ENTITYget_name(sub));
LISTod
*/
LISTdo(ENTITYget_supertypes(entity),sup,Entity)
/* set the owning schema of the supertype */
super_schema = SCHEMAget_name(ENTITYget_schema(sup));
/* print the supertype list for this entity */
fprintf(file," %s%s%s->AddSupertype(%s%s%s);\n",
schema_name,ENT_PREFIX,entity_name,
super_schema,
ENT_PREFIX,ENTITYget_name(sup));
/* add this entity to the subtype list of it's supertype */
fprintf(file," %s%s%s->AddSubtype(%s%s%s);\n",
super_schema,
ENT_PREFIX,ENTITYget_name(sup),
schema_name,ENT_PREFIX, entity_name);
LISTod
LISTdo(ENTITYget_attributes(entity),v,Variable)
strcpy(attrnm,(char*)generate_attribute_name( v, attrnm ));
/* do EXPLICIT and DERIVED attributes first */
/* if ( ! VARget_inverse (v)) {*/
/* first make sure that type descriptor exists */
if (TYPEget_name(v->type)) {
if ((!TYPEget_head(v->type)) &&
(TYPEget_body(v->type)->type == entity_))
{
/* fprintf(file, "\t%s%d%s%s = new %sAttrDescriptor(\"%s\",%s%s%s,%s,%s,%s,*%s%s%s);\n", */
fprintf(file, "\t%s%d%s%s = new %sAttrDescriptor(\"%s\",%s%s%s,%s,%s%s%s,*%s%s%s);\n",
ATTR_PREFIX,attr_count,
(VARis_derived (v) ? "D" :
(VARget_inverse (v) ? "I" : "")),
/* (VARis_derived (v) ? "D" : ""), */
attrnm,
(VARget_inverse (v) ? "Inverse" : ""),
StrToLower (attrnm), /* attribute name */
/* following assumes we are not in a nested */
/* entity otherwise we should search upward */
/* for schema */
/* attribute's type */
TYPEget_name(
TYPEget_body(v->type)->entity->superscope),
ENT_PREFIX,TYPEget_name(v->type),
(VARget_optional(v)?"T":"F"),
(VARget_unique(v)?"T":"F"),
/* (VARis_derived(v)?"T":"F"),*/
(VARget_inverse (v) ? "" : ","),
(VARget_inverse (v) ? "" :
(VARis_derived(v)?"T":"F")),
schema_name,ENT_PREFIX,TYPEget_name(entity)
);
} else {
/* type reference */
/* fprintf(file," %s%d%s%s = new %sAttrDescriptor(\"%s\",%s%s%s,%s,%s,%s,*%s%s%s);\n",*/
fprintf(file," %s%d%s%s = new %sAttrDescriptor(\"%s\",%s%s%s,%s,%s%s%s,*%s%s%s);\n",
ATTR_PREFIX,attr_count,
(VARis_derived (v) ? "D" :
(VARget_inverse (v) ? "I" : "")),
/* (VARis_derived (v) ? "D" : ""), */
attrnm,
(VARget_inverse (v) ? "Inverse" : ""),
StrToLower (attrnm),
SCHEMAget_name(
owning_schema(TYPEget_name(v->type),schema)
), TD_PREFIX,TYPEget_name(v->type),
(VARget_optional(v)?"T":"F"),
(VARget_unique(v)?"T":"F"),
/* (VARis_derived(v)?"T":"F"),*/
(VARget_inverse (v) ? "" : ","),
(VARget_inverse (v) ? "" :
(VARis_derived(v)?"T":"F")),
schema_name,ENT_PREFIX,TYPEget_name(entity)
);
}
} else if (TYPEis_builtin(v->type)) {
/* the type wasn\'t named -- it must be built in or aggregate */
/* fprintf(file," %s%d%s%s = new %sAttrDescriptor(\"%s\",%s%s,%s,%s,%s,*%s%s%s);\n",*/
fprintf(file," %s%d%s%s = new %sAttrDescriptor(\"%s\",%s%s,%s,%s%s%s,*%s%s%s);\n",
ATTR_PREFIX,attr_count,
(VARis_derived (v) ? "D" :
(VARget_inverse (v) ? "I" : "")),
/* (VARis_derived (v) ? "D" : ""), */
attrnm,
(VARget_inverse (v) ? "Inverse" : ""),
StrToLower (attrnm),
/* not sure about 0 here */ TD_PREFIX,FundamentalType(v->type,0),
(VARget_optional(v)?"T":"F"),
(VARget_unique(v)?"T":"F"),
/* (VARis_derived(v)?"T":"F"),*/
(VARget_inverse (v) ? "" : ","),
(VARget_inverse (v) ? "" :
(VARis_derived(v)?"T":"F")),
schema_name,ENT_PREFIX,TYPEget_name(entity)
);
} else {
/* manufacture new one(s) on the spot */
char typename_buf[MAX_LEN];
print_typechain(file, v->type, typename_buf, schema);
/* fprintf(file," %s%d%s%s = new %sAttrDescriptor(\"%s\",%s,%s,%s,%s,*%s%s%s);\n",*/
fprintf(file," %s%d%s%s = new %sAttrDescriptor(\"%s\",%s,%s,%s%s%s,*%s%s%s);\n",
ATTR_PREFIX,attr_count,
(VARis_derived (v) ? "D" :
(VARget_inverse (v) ? "I" : "")),
/* (VARis_derived (v) ? "D" : ""),*/
attrnm,
(VARget_inverse (v) ? "Inverse" : ""),
StrToLower (attrnm),
typename_buf,
(VARget_optional(v)?"T":"F"),
(VARget_unique(v)?"T":"F"),
/* (VARis_derived(v)?"T":"F"),*/
(VARget_inverse (v) ? "" : ","),
(VARget_inverse (v) ? "" :
(VARis_derived(v)?"T":"F")),
schema_name,ENT_PREFIX,TYPEget_name(entity)
);
}
fprintf(file," %s%s%s->Add%sAttr (%s%d%s%s);\n",
schema_name,ENT_PREFIX,TYPEget_name(entity),
(VARget_inverse (v) ? "Inverse" : "Explicit"),
ATTR_PREFIX,attr_count,
(VARis_derived (v) ? "D" : (VARget_inverse (v) ? "I" : "")),
/* (VARis_derived (v) ? "D" : ""),*/
attrnm);
#if 0
} else if (VARget_inverse (v)) {
/* do INVERSE attributes too */
/*
TODO -- write algorithm for determining descriptor of this attribute\'s inverse
*/
/* if ((!TYPEget_head(v->type)) && (TYPEget_body(v->type)->type == entity_)) { */
/* this should always be true for INVERSE attributes */
fprintf(file,"\t%s%dI%s = new InverseAttrDescriptor(\"%s\",%s%s%s,%s,%s,*%s%s%s);\n",
ATTR_PREFIX,attr_count,attrnm, /* descriptor name */
/* ATTR_PREFIX,attr_count,TYPEget_name(v->name), */
StrToLower (attrnm), /* attribute name */
/* StrToLower (TYPEget_name(v->name)), */
/* following assumes we are not in a nested entity */
/* otherwise we should search upward for schema */
/* attribute's type */
TYPEget_name(TYPEget_body(v->type)->entity->superscope),ENT_PREFIX,attrnm,
/*TYPEget_name(v->type), */
(VARget_optional(v)?"T":"F"),
(VARget_unique(v)?"T":"F"),
schema_name,ENT_PREFIX, TYPEget_name(entity));
fprintf(file,"\t%s%s%s->AddInverseAttr (%s%dI%s);\n",
schema_name,ENT_PREFIX,TYPEget_name(entity),
ATTR_PREFIX,attr_count,TYPEget_name(v->name));
/* }*/
}
#endif
attr_count++;
LISTod
#undef schema_name
}
#if 0
void
/* create calls to connect sub/supertype relationships */
ENTITYstype_connect(Entity entity, FILE* file,Schema schema)
{
LISTdo(ENTITYget_subtypes(entity),sub,Entity)
fprintf(file," %s->Subtypes().AddNode(%s);\n",
ENTITYget_name(sub));
LISTod
LISTdo(ENTITYget_supertypes(entity),sup,Entity)
fprintf(file," %s->Supertypes().AddNode(%s);\n",
ENTITYget_name(sup));
LISTod
}
#endif
/******************************************************************
** Procedure: ENTITYPrint
** Parameters: Entity *entity -- entity being processed
** FILE* file -- file being written to
** Returns:
** Description: drives the functions for printing out code in lib,
** include, and initialization files for a specific entity class
** Side Effects: generates code in 3 files
** Status: complete 1/15/91
******************************************************************/
void
ENTITYPrint(Entity entity, FILES* files,Schema schema)
{
char * n = ENTITYget_name (entity);
DEBUG ("Entering ENTITYPrint for %s \n", n);
fprintf (files->inc, "\n/////////\t ENTITY %s \n\n", n);
ENTITYinc_print (entity, files -> inc,schema);
fprintf (files->inc, "\n/////////\t END_ENTITY %s \n\n", n);
fprintf (files->lib, "\n/////////\t ENTITY %s \n\n", n);
ENTITYlib_print (entity, files -> lib,schema);
fprintf (files->lib, "\n/////////\t END_ENTITY %s \n\n", n);
fprintf (files->initent, "\n/////////\t ENTITY %s \n\n", n);
ENTITYincode_print (entity, files -> initent, schema);
fprintf (files->initent, "/////////\t END_ENTITY %s \n", n);
DEBUG ("DONE ENTITYPrint\n") ;
}
void
ENTITYprint_new(Entity entity,FILES *files, Schema schema)
{
const char * n;
fprintf(files->init," %s%s%s = new EntityDescriptor(\"%s\",%s%s,%s, (Creator) create_%s);\n",
SCHEMAget_name(schema),ENT_PREFIX,ENTITYget_name(entity),
PrettyTmpName (ENTITYget_name(entity)),
SCHEMA_PREFIX,SCHEMAget_name(schema),
(ENTITYget_abstract(entity)?"T":"F"),
ENTITYget_classname (entity)
);
n = ENTITYget_classname (entity);
fprintf (files->inc, "\nclass %s;\n", n);
fprintf (files->inc, "typedef %s * \t%sH;\n", n, n);
fprintf(files ->inc,"extern EntityDescriptor \t*%s%s%s;\n",
SCHEMAget_name(schema),ENT_PREFIX,ENTITYget_name(entity));
}
/******************************************************************
** TYPE GENERATION **/
/******************************************************************
** Procedure: TYPEprint_enum
** Parameters: const Type type - type to print
** FILE* f - file on which to print
** Returns:
** Requires: TYPEget_class(type) == TYPE_ENUM
** Description: prints code to represent an enumerated type in c++
** Side Effects: prints to header file
** Status: ok 1/15/91
** Changes: Modified to check for appropiate key words as described
** in "SDAI C++ Binding for PDES, Inc. Prototyping" by
** Stephen Clark.
** Change Date: 5/22/91 CD
******************************************************************/
const char *
EnumCElementName (Type type, Expression expr) {
static char buf [BUFSIZ];
sprintf (buf,"%s_%s",
StrToLower (TYPEget_name (type)),
StrToUpper (EXPget_name(expr)));
return buf;
}
char *
CheckEnumSymbol (char * s)
{
char b [BUFSIZ];
if (strcmp (s, "sdaiTRUE")
&& strcmp (s, "sdaiFALSE")
&& strcmp (s, "sdaiUNKNOWN")) {
/* if the symbol is not a reserved one */
return (s);
} else {
strcpy (b, s);
strcat (b, "_");
printf ("** warning: the enumerated value %s is already being used ", s);
printf (" and has been changed to %s **\n", b);
return (b);
}
}
void
TYPEenum_inc_print (const Type type, FILE* f)
{
DictionaryEntry de;
Expression expr;
char buffer [BUFSIZ],
*buf = buffer;
const char * n; /* pointer to class name */
int cnt =0;
buffer[0] = '\0';
fprintf (f, "\n////////// ENUMERATION TYPE %s\n", TYPEget_name (type));
/* print c++ enumerated values for class */
fprintf (f, "enum %s {\n", EnumName (TYPEget_name (type)));
DICTdo_type_init(ENUM_TYPEget_items(type),&de,OBJ_ENUM);
while (0 != (expr = (Expression)DICTdo(&de))) {
/* print the elements of the c++ enum type */
++cnt;
sprintf (buf,"\t%s,\n", EnumCElementName (type, expr));
move (buf);
}
sprintf (buf-2, "\n } ;\n");
fprintf(f,buffer);
/* print class for enumeration */
n = ClassName (TYPEget_name (type));
fprintf (f, "\nclass %s : public STEPenumeration {\n", n);
/* constructors */
fprintf (f, " public:\n\t%s (const char * n =0);\n", n);
/* fprintf (f, "\t%s (%s e) { Init (); set_value (e); }\n", */
fprintf (f, "\t%s (%s e) { set_value (e); }\n",
n, EnumName (TYPEget_name (type)));
/* destructor */
fprintf (f, "\t~%s () { }\n", n);
/* operator = */
fprintf (f, "\t%s& operator= (const %s& e)\n",
n, EnumName (TYPEget_name (type)));
fprintf (f, "\t\t{ set_value (e); return *this; }\n");
/* operator to cast to an enumerated type */
fprintf (f, "\toperator %s () const;\n",
EnumName (TYPEget_name (type)));
/* others */
fprintf (f, "\n\tinline virtual const char * Name () const\n");
fprintf (f, "\t\t{ return \"%s\" ; }\n", n);
fprintf (f, "\tinline virtual int no_elements () const { return %d; }\n",
cnt);
/* fprintf (f, " private:\n\tvoid Init ();\n");*/
fprintf (f, "\tvirtual const char * element_at (int n) const;\n");
/* end class definition */
fprintf (f, "};\n\n");
/* print things for aggregate class */
fprintf (f, "\nclass %ss : public EnumAggregate {\n", n);
/* fprintf (f, " public:\n\tvirtual EnumNode * NewNode () {\n");*/
fprintf (f, " public:\n\tvirtual SingleLinkNode * NewNode () {\n");
fprintf (f, "\t return new EnumNode (new %s);\t}\n};\n", n);
fprintf (f, "typedef %ss * %ssH;", n, n);
fprintf (f, "\n////////// END ENUMERATION %s\n\n", TYPEget_name (type));
}
void
TYPEenum_lib_print (const Type type, FILE* f)
{
DictionaryEntry de;
Expression expr;
const char *n; /* pointer to class name */
char buf [BUFSIZ];
char c_enum_ele [BUFSIZ];
fprintf (f, "\n////////// ENUMERATION TYPE %s\n", TYPEget_name (type));
n = ClassName(TYPEget_name(type));
/* set up the dictionary info */
/* fprintf (f, "void \t%s::Init () {\n", n);*/
/* fprintf (f, " static const char * const l [] = {\n");*/
fprintf (f, "const char * \n%s::element_at (int n) const {\n", n);
fprintf (f, " switch (n) {\n");
DICTdo_type_init(ENUM_TYPEget_items(type),&de,OBJ_ENUM);
while (0 != (expr = (Expression)DICTdo(&de))) {
strncpy (c_enum_ele, EnumCElementName (type, expr), BUFSIZ);
fprintf(f," case %s : return \"%s\";\n",
c_enum_ele,
StrToUpper (EXPget_name(expr)));
}
fprintf (f, " default: return \"\";\n }\n}\n");
/* fprintf (f, "\t 0\n };\n");*/
/* fprintf (f, " set_elements (l);\n v = ENUM_NULL;\n}\n");*/
/* constructors */
/* construct with character string */
fprintf (f, "%s::%s (const char * n ) {\n", n, n);
/* fprintf (f, " Init ();\n set_value (n);\n}\n");*/
fprintf (f, " set_value (n);\n}\n");
/* copy constructor */
/* fprintf (f, "%s::%s (%s& n ) {\n", n, n, n);*/
/* fprintf (f, " (l);\n");*/
/* operator = */
/* fprintf (f, "%s& \t%s::operator= (%s& x)", n, n, n);*/
/* fprintf (f, "\n\t{ put (x.asInt ()); return *this; }\n");*/
/* cast operator to an enumerated type */
fprintf (f, "%s::operator %s () const {\n", n,
EnumName (TYPEget_name (type)));
fprintf (f, " switch (v) {\n");
buf [0] = '\0';
DICTdo_type_init(ENUM_TYPEget_items(type),&de,OBJ_ENUM);
while (0 != (expr = (Expression)DICTdo(&de))) {
fprintf (f, "%s", buf);
strncpy (c_enum_ele, EnumCElementName (type, expr), BUFSIZ);
fprintf (f, "\tcase %s : ", c_enum_ele);
sprintf (buf, "return %s;\n", c_enum_ele);
}
/* print the last case with the default so sun c++ doesn\'t complain */
fprintf (f, "\n\tdefault : %s;\n }\n}\n", buf);
/* fprintf (f, "\t\tdefault: return 0;\n }\n}\n");*/
fprintf (f, "\n////////// END ENUMERATION %s\n", TYPEget_name (type));
}
/* return fundamental type but as the string which corresponds to */
/* the appropriate type descriptor */
/* if report_reftypes is true, report REFERENCE_TYPE when appropriate */
char *
FundamentalType(const Type t,int report_reftypes) {
if (report_reftypes && TYPEget_head(t)) return("REFERENCE_TYPE");
switch (TYPEget_body(t)->type) {
case integer_: return("INTEGER_TYPE");
case real_: return("REAL_TYPE");
case string_: return("STRING_TYPE");
case binary_: return("BINARY_TYPE");
case boolean_: return("BOOLEAN_TYPE");
case logical_: return("LOGICAL_TYPE");
case number_: return("NUMBER_TYPE");
case generic_: return("GENERIC_TYPE");
case aggregate_:
case array_:
case bag_:
case set_:
case list_: return("AGGREGATE_TYPE");
case entity_: return("ENTITY_TYPE");
case enumeration_: return("ENUM_TYPE");
case select_: return ("SELECT_TYPE");
default: return("UNKNOWN_TYPE");
}
}
/* return printable version of entire type definition */
/* return it in static buffer */
char *
TypeDescription(const Type t)
{
static char buf[4000];
buf[0] = '\0';
if (TYPEget_head(t)) Type_Description(TYPEget_head(t),buf);
else TypeBody_Description(TYPEget_body(t),buf);
/* should also print out where clause here */
return buf+1;
}
char *strcat_expr(Expression e,char *buf)
{
if (e == LITERAL_INFINITY) {
strcat(buf,"?");
} else if (e == LITERAL_PI) {
strcat(buf,"PI");
} else if (e == LITERAL_E) {
strcat(buf,"E");
} else if (e == LITERAL_ZERO) {
strcat(buf,"0");
} else if (e == LITERAL_ONE) {
strcat(buf,"1");
} else if (TYPEget_name(e)) {
strcat(buf,TYPEget_name(e));
} else if (TYPEget_body(e->type)->type == integer_) {
char tmpbuf[30];
sprintf(tmpbuf,"%d",e->u.integer);
strcat(buf,tmpbuf);
} else {
strcat(buf,"??");
}
return buf;
}
/* print t's bounds to end of buf */
char*
strcat_bounds(TypeBody b,char *buf)
{
if (!b->upper) return "";
strcat(buf," [");
strcat_expr(b->lower,buf);
strcat(buf,":");
strcat_expr(b->upper,buf);
strcat(buf,"]");
return buf;
}
char *TypeBody_Description(TypeBody body, char *buf)
{
Expression expr;
DictionaryEntry de;
char *s;
if (body->flags.unique) strcat(buf," UNIQUE");
if (body->flags.optional) strcat(buf," OPTIONAL");
switch (body->type) {
case integer_: strcat(buf," INTEGER"); break;
case real_: strcat(buf," REAL"); break;
case string_: strcat(buf," STRING"); break;
case binary_: strcat(buf," BINARY"); break;
case boolean_: strcat(buf," BOOLEAN"); break;
case logical_: strcat(buf," LOGICAL"); break;
case number_: strcat(buf," NUMBER"); break;
case entity_: strcat(buf," ");
strcat(buf,PrettyTmpName (TYPEget_name(body->entity)));
break;
case aggregate_:
case array_:
case bag_:
case set_:
case list_:
switch (body->type) {
/* ignore the aggregate bounds for now */
case aggregate_: strcat(buf," AGGREGATE OF"); break;
case array_: strcat(buf," ARRAY");
strcat_bounds(body,buf);
strcat(buf," OF"); break;
case bag_: strcat(buf," BAG");
strcat_bounds(body,buf);
strcat(buf," OF"); break;
case set_: strcat(buf," SET");
strcat_bounds(body,buf);
strcat(buf," OF"); break;
case list_: strcat(buf," LIST");
strcat_bounds(body,buf);
strcat(buf," of"); break;
}
Type_Description(body->base,buf);
break;
case enumeration_:
strcat(buf," ENUMERATION of (");
LISTdo(body->list,e,Expression)
strcat(buf,ENUMget_name(e));
strcat(buf,", ");
LISTod
/* find last comma and replace with ')' */
s = strrchr(buf,',');
if (s) strcpy(s,")");
break;
case select_:
strcat(buf," SELECT of (");
LISTdo (body->list, t, Type)
strcat (buf, PrettyTmpName (TYPEget_name(t)) );
strcat(buf,", ");
LISTod
/* find last comma and replace with ')' */
s = strrchr(buf,',');
if (s) strcpy(s,")");
break;
default: strcat(buf," UNKNOWN");
}
if (body->precision) {
strcat(buf," (");
strcat_expr(body->precision,buf);
strcat(buf,")");
}
if (body->flags.fixed) strcat(buf," FIXED");
return buf;
}
char *
Type_Description(const Type t,char *buf)
{
if (TYPEget_name(t)) {
strcat(buf," ");
strcat(buf,PrettyTmpName (TYPEget_name(t)));
} else {
TypeBody_Description(TYPEget_body(t),buf);
}
return buf;
}
/******************************************************************
** Procedure: TYPEprint_typedefs
** Parameters: const Type type
** Returns:
** Description: prints in header file typedefs for user defined types
** Side Effects:
** Status: 16-Mar-1993 kcm
******************************************************************/
void
TYPEprint_typedefs (Type t, FILE* f)
{
Class_Of_Type class;
char base [BUFSIZ] ;
char nm [BUFSIZ] ;
strncpy (nm, ClassName (TYPEget_name (t)), BUFSIZ);
/* do selects by themselves */
if (TYPEis_select (t) )
return;
if (TYPEis_enumeration (t))
if ( TYPEget_head(t) ) {
/* print the typedef for the enumeration class */
strncpy (base, ClassName (TYPEget_name(TYPEget_head(t))), BUFSIZ);
fprintf (f, "typedef %s \t%s;\n", base, nm);
/* print the typedef for the enumeration type */
strncpy (base, EnumName (TYPEget_name(TYPEget_head(t))), BUFSIZ);
strncpy (nm, EnumName (TYPEget_name (t)), BUFSIZ);
fprintf (f, "typedef %s \t%s;\n", base, nm);
return;
} else
return;
/* do the rest of the user defined types */
fprintf (f, "typedef %s \t%s;\n", TYPEget_ctype (t), nm);
if (TYPEis_aggregate (t) ) {
fprintf (f, "typedef %s * \t%sH;\n", nm, nm);
return;
}
}
void
TYPEprint_descriptions (const Type type, FILES* files, Schema schema)
{
Class_Of_Type class;
char tdnm [BUFSIZ];
strncpy (tdnm, TYPEtd_name (type, schema), BUFSIZ);
/* define type descriptor pointer */
/* in header for external use */
fprintf(files->inc,"extern %sTypeDescriptor \t*%s;\n",
(TYPEis_select (type) ? "Select" : ""),
tdnm);
/* in source - declare the real definition of the pointer */
fprintf(files -> lib,"%sTypeDescriptor \t*%s;\n",
(TYPEis_select (type) ? "Select" : ""),
tdnm);
/* fill in it's values */
/* in the SchemaInit function - already declared with basic values */
if (TYPEget_head(type)) {
if (!streq("",TYPEget_name(type))) {
/* type ref with name */
/* if (!TYPEget_head( TYPEget_head(type) ) ) */
/* if (TYPEget_head( TYPEget_head(type) ) ) */
fprintf(files->init,
"\t%s->ReferentType (%s%s%s);\n",
tdnm,
SCHEMAget_name(owning_schema(TYPEget_name(TYPEget_head(type)),schema)),
TYPEprefix (type), TYPEget_name(TYPEget_head(type)));
} else if (streq("",TYPEget_name(type))) {
/* no name, recurse */
char callee_buffer[MAX_LEN];
print_typechain(files -> init, TYPEget_head(type), callee_buffer,schema);
fprintf(files->init," %s->ReferentType(%s);\n",
tdnm, callee_buffer);
}
} else if (TYPEget_body(type)->type == enumeration_) {
TYPEenum_inc_print (type, files -> inc);
TYPEenum_lib_print (type, files -> lib);
} else if (TYPEget_body(type)->type == select_) {
/* the select definitions are done seperately, since they depend on the others */
/*******
TYPEselect_inc_print (type, files -> inc);
TYPEselect_lib_print (type, files -> lib);
*******/
} else if (TYPEis_builtin(type)) {
fprintf(files->init," %s->ReferentType(%s%s);\n",
tdnm, TD_PREFIX,FundamentalType(type,0));
} else if (TYPEget_body(type)->type == entity_) {
fprintf(files->init," %s->ReferentType (%s);\n",
tdnm,
/* following assumes we are not in a nested entity */
/* otherwise we should search upward for schema */
TYPEtd_name (type, TYPEget_body(type)->entity->superscope));
}
/* insert into type dictionary */
fprintf(files->init,"\treg.AddType (*%s);\n", tdnm);
}
void
TYPEprint_new (const Type type, FILES* files, Schema schema)
{
/* define type definition */
/* in source - the real definition of the TypeDescriptor */
FILE * f = files->init;
if( TYPEis_select(type) )
fprintf(f,"\t%s = new SelectTypeDescriptor (\n\t\t %d,\t//unique elements,\n",
TYPEtd_name (type, schema),
! any_duplicates_in_select (SEL_TYPEget_items(type)) );
else
fprintf(f,"\t%s = new TypeDescriptor (\n",
TYPEtd_name (type, schema));
/* fill in it's values */
fprintf(f,"\t\t \"%s\",\t// Name\n",
PrettyTmpName (TYPEget_name(type)));
fprintf(f,"\t\t %s,\t// FundamentalType\n",
FundamentalType(type,1));
fprintf(f,"\t\t \"%s\");\t// Description\n",
TypeDescription(type));
}