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 >
C/C++ Source or Header  |  1994-07-29  |  60KB  |  1,824 lines

  1. /*
  2. ** Fed-x parser output module for generating C++  class definitions
  3. ** December  5, 1989
  4. ** release 2 17-Feb-1992
  5. ** release 3 March 1993
  6. ** release 4 December 1993
  7. ** K. C. Morris
  8. **
  9. ** Development of Fed-x was funded by the United States Government,
  10. ** and is not subject to copyright.
  11.  
  12. *******************************************************************
  13. The conventions used in this binding follow the proposed specification
  14. for the STEP Standard Data Access Interface as defined in document
  15. N350 ( August 31, 1993 ) of ISO 10303 TC184/SC4/WG7.
  16. *******************************************************************/
  17.  
  18. /******************************************************************
  19. ***  The functions in this file generate the C++ code for ENTITY **
  20. ***  classes, TYPEs, and TypeDescriptors.                       ***
  21.  **                                **/
  22.  
  23. static char rcsid[] ="$Id: classes.c,v 1.47 1994/03/30 15:58:39 kc Exp $";
  24.  
  25. #include "classes.h"
  26.  
  27.  
  28. static attr_count;    /* number each attr to avoid inter-entity clashes */
  29. static type_count;    /* number each temporary type for same reason above */
  30.  
  31. char *FundamentalType(const Type,int);
  32. extern int any_duplicates_in_select( const Linked_List list );
  33.  
  34.  
  35. /******************************************************************
  36.  ** Procedure:  generate_attribute_name
  37.  ** Parameters:  Variable a, an Express attribute; char *out, the C++ name
  38.  ** Description:  converts an Express name into the corresponding C++ name
  39.  ** Side Effects:  
  40.  ** Status:  complete 8/5/93
  41.  ******************************************************************/
  42. void*
  43. generate_attribute_name( Variable a, char *out )
  44. {
  45.    char *temp, *p;
  46.  
  47.    temp = a->name->symbol.name;/*EXPRto_string( VARget_name(a) ); */
  48.    p = temp;
  49.    if (! strncmp (StrToLower (p), "self\\", 5)) 
  50.        p = p +5;
  51.    /*  copy p to out  */
  52.    strncpy( out, StrToLower (p), BUFSIZ );
  53.    /*  if there\'s an illegal character in out,
  54.        change it to a _     */
  55.    while (p = strrchr(out,'.'))
  56.      *p = '_';
  57.  
  58.    free( temp );
  59.    return out;
  60. }
  61.  
  62.  
  63. /******************************************************************
  64.  ** Procedure:  TYPEget_express_type (const Type t)
  65.  ** Parameters:  const Type t --  type for attribute
  66.  ** Returns:  a string which is the type as it would appear in Express 
  67.  ** Description:  supplies the type for error messages 
  68.                   and to register the entity
  69.           - calls itself recursively to create a description of 
  70.           aggregate types
  71.  ** Side Effects:  
  72.  ** Status:  new 1/24/91
  73.  ******************************************************************/
  74.  
  75. String
  76. TYPEget_express_type (const Type t)
  77. {      
  78.     Class_Of_Type class;
  79.     Type bt;
  80.     char retval [BUFSIZ];
  81.     char *n, * permval, * aggr_type;
  82.     
  83.  
  84.     /*  1.  "DEFINED" types    */
  85.     /*    case TYPE_ENUM:    */
  86.     /*    case TYPE_ENTITY:    */
  87.     /*    case TYPE_SELECT:       */
  88.  
  89.     if (n = TYPEget_name (t)) {
  90.       PrettyTmpName (n);
  91.     }
  92.  
  93.     /*   2.   "BASE" types     */
  94.     class = TYPEget_type (t);
  95.  
  96.     /*    case TYPE_LOGICAL:    */
  97.     if ((class == Class_Boolean_Type) || ( class == Class_Logical_Type))
  98.         return ("Logical"); 
  99.  
  100.     /*      case TYPE_INTEGER:    */
  101.     if ( class == Class_Integer_Type)
  102.     return ("Integer ");
  103.  
  104.     /*      case TYPE_REAL:
  105.         case TYPE_NUMBER:    */
  106.     if ((class == Class_Number_Type) || ( class == Class_Real_Type))
  107.     return ("Real "); 
  108.  
  109.     /*        case TYPE_STRING:    */
  110.     if (class == Class_String_Type)
  111.     return ("String ")      ;
  112.  
  113.     /*        case TYPE_BINARY:    */
  114.     if  ( class == Class_Binary_Type)
  115.     return ("Binary ")      ;
  116.  
  117.     /*  AGGREGATES
  118.     case TYPE_ARRAY:
  119.     case TYPE_BAG:
  120.     case TYPE_LIST:
  121.     case TYPE_SET:
  122.     */
  123.     if (isAggregateType (t)) {
  124.     bt = TYPEget_nonaggregate_base_type (t);
  125.     class = TYPEget_type (bt);
  126.         
  127.     /*    case TYPE_ARRAY:    */
  128.     if (TYPEget_type (t) == Class_Array_Type) {
  129.         aggr_type = "Array";
  130.     }
  131.     /*    case TYPE_LIST:    */
  132.     if (TYPEget_type (t) == Class_List_Type) {
  133.         aggr_type = "List";
  134.     }
  135.     /*  case TYPE_SET:    */
  136.     if (TYPEget_type (t) == Class_Set_Type) {
  137.         aggr_type = "Set";
  138.     }
  139.     /*  case TYPE_BAG:    */
  140.     if (TYPEget_type (t) == Class_Bag_Type) {
  141.         aggr_type = "Bag";
  142.     }
  143.     
  144.     sprintf (retval, "%s of %s", 
  145.          aggr_type, TYPEget_express_type (bt));
  146.  
  147.     /*  this will declare extra memory when aggregate is > 1D  */
  148.     
  149.     permval = malloc (strlen (retval) * sizeof (char) +1);
  150.     strcpy (permval, retval);
  151.     return permval;
  152.     
  153.     }
  154.  
  155.     /*  default returns undefined   */
  156.  
  157.     printf ("WARNING2:  type  %s  is undefined\n", TYPEget_name (t));
  158.     return ("SCLundefined");
  159.  
  160. }    
  161.  
  162. /******************************************************************
  163.  ** Procedure:  ATTRsign_access_method
  164.  ** Parameters:  const Variable a --  attribute to print
  165.                                       access method signature for 
  166.  **    FILE* file  --  file being written to
  167.  ** Returns:  nothing
  168.  ** Description:  prints the signature for an access method 
  169.                   based on the attribute type  
  170.  ** Side Effects:  
  171.  ** Status:  complete 17-Feb-1992
  172.  ******************************************************************/
  173.  
  174. void
  175. ATTRsign_access_methods (Variable a, FILE* file) 
  176. {
  177.     
  178.     Type t = VARget_type (a);
  179.     Class_Of_Type class;
  180.     char ctype [BUFSIZ];
  181.     char attrnm [BUFSIZ];
  182.  
  183.     strcpy(attrnm,(char*)generate_attribute_name( a, attrnm  ));
  184.     strncpy (attrnm, CheckWord (StrToLower (attrnm)), BUFSIZ);
  185.     attrnm[0] = toupper(attrnm[0]);
  186.  
  187.     class = TYPEget_type(t);
  188.     strncpy (ctype, AccessType (t), BUFSIZ);
  189.  
  190.     /*  LOGICAL and ENUM use an enumerated value in the put funciton  */
  191.     /*    case TYPE_LOGICAL:    */
  192.     if ((class == Class_Boolean_Type) || ( class == Class_Logical_Type))  {
  193.     fprintf (file, "\tconst Logical& %s() const;\n", attrnm);
  194.     fprintf (file, "\tvoid %s (LOGICAL x);\n", attrnm  );
  195.     return;
  196.     }    
  197.     /*    case TYPE_ENUM:    */
  198.     if ( class == Class_Enumeration_Type)  {
  199.     fprintf (file, "\tconst %s& %s() const;\n", ctype, attrnm);
  200.     fprintf (file, "\tvoid %s (%s x);\n", 
  201.          attrnm, EnumName (TYPEget_name (t)) );
  202.     return;
  203.     }
  204.  
  205.     /*  case STRING  */
  206.     if ( class == Class_String_Type) {
  207.       fprintf (file, "\tconst %s& %s() const;\n", ctype, attrnm);
  208.       fprintf (file, "\tvoid %s (const char * x);\n", attrnm );
  209.       return;
  210.     }    
  211.     /*        case TYPE_BINARY:    */
  212.     if ( class == Class_Binary_Type) {
  213.       fprintf (file, "\tconst %s& %s() const;\n", ctype, attrnm);
  214.       fprintf (file, "\tvoid %s (const %s& x);\n", attrnm, ctype );
  215.       return;
  216.     }    
  217.  
  218.     /*      case TYPE_ENTITY:    */
  219.     if (class == Class_Entity_Type)  {
  220.       /*  get method doesn\'t return const  */
  221.       fprintf (file, "\t%s %s() const;\n", ctype, attrnm);
  222.       fprintf (file, "\tvoid %s (%s x);\n", attrnm, ctype );
  223.       return;
  224.     }
  225.     /*  default:  INTEGER, and NUMBER    */
  226.     /*    case TYPE_SELECT:    */
  227.     /*    case TYPE_AGGRETATES:    */
  228.     /*      case TYPE_ENTITY:    */
  229.       /*  is the same type as the data member  */
  230.       fprintf (file, "\tconst %s %s() const;\n", ctype, attrnm);
  231.       fprintf (file, "\tvoid %s (%s x);\n", attrnm, ctype );
  232.  
  233. }    
  234.  
  235. /******************************************************************
  236.  ** Procedure:  ATTRprint_access_methods_get_head
  237.  ** Parameters:  const Variable a --  attribute to find the type for
  238.  **    FILE* file  --  file being written 
  239.  **    Type t - type of the attribute
  240.  **    Class_Of_Type class -- type name of the class
  241.  **    const char *attrnm -- name of the attribute
  242.  **    char *ctype -- (possibly returned) name of the attribute c++ type
  243.  ** Returns:  name to be used for the type of the c++ access functions
  244.  ** Description:  prints the access method get head based on the attribute type  
  245.  ** Side Effects:  
  246.  ** Status:  complete 7/15/93        by DDH
  247.  ******************************************************************/
  248. void
  249. ATTRprint_access_methods_get_head  (const char * classnm, Variable a, FILE* file) 
  250. {
  251.     Type t = VARget_type (a);
  252.     Class_Of_Type class = TYPEget_type(t);
  253.     char ctype [BUFSIZ];   /*  return type of the get function  */
  254.     char funcnm [BUFSIZ];  /*  name of member function  */
  255.  
  256.     strcpy(funcnm,(char*)generate_attribute_name( a, funcnm  ));
  257.     funcnm[0] = toupper(funcnm[0]);
  258.  
  259.     strncpy( ctype, AccessType (t), BUFSIZ );
  260.  
  261.     /*  case STRING:    */
  262.     /*        case TYPE_BINARY:    */
  263.     /*  string can\'t be const because it causes problems with SELECTs  */
  264.     if (( class == Class_String_Type) ||   ( class == Class_Binary_Type)) {
  265.       fprintf (file, "\nconst %s& \n%s::%s() const\n", ctype, classnm, funcnm);
  266.       return;
  267.     }
  268.     /*  case ENTITY:  */
  269.     /*  return value isn\'t const  */
  270.     if ( class == Class_Entity_Type) {
  271.       fprintf (file, "\n%s \n%s::%s() const \n", ctype, classnm, funcnm);
  272.       return;
  273.     }
  274.  
  275.     /*    case TYPE_LOGICAL:    */
  276.     if ((class == Class_Boolean_Type) || ( class == Class_Logical_Type))  {
  277.     fprintf (file, "\nconst Logical& \n%s::%s() const \n", classnm, funcnm);
  278.     return;
  279.     }    
  280.     /*    case TYPE_ENUM:    */
  281.     if ( class == Class_Enumeration_Type) 
  282.       sprintf  (ctype, "%s &", TYPEget_ctype (t));
  283.  
  284.  
  285.     /*  default:  INTEGER and NUMBER    */
  286.     /*    case TYPE_AGGRETATES:    */
  287.     /*    case TYPE_SELECT:    */
  288.     /*      case TYPE_ENTITY:    */
  289.       /*  is the same type as the data member  */
  290.     fprintf (file, "\nconst %s \n%s::%s() const \n", ctype, classnm, funcnm);
  291. }
  292.  
  293. /******************************************************************
  294.  ** Procedure:  ATTRprint_access_methods_put_head
  295.  ** Parameters:  const Variable a --  attribute to find the type for
  296.  **    FILE* file  --  file being written to
  297.  **    Type t - type of the attribute
  298.  **    Class_Of_Type class -- type name of the class
  299.  **    const char *attrnm -- name of the attribute
  300.  **    char *ctype -- name of the attribute c++ type
  301.  ** Returns:  name to be used for the type of the c++ access functions
  302.  ** Description:  prints the access method put head based on the attribute type  
  303.  ** Side Effects:  
  304.  ** Status:  complete 7/15/93        by DDH
  305.  ******************************************************************/
  306. void
  307. ATTRprint_access_methods_put_head  (CONST char * entnm, Variable a, FILE* file)
  308. {
  309.  
  310.   Type t = VARget_type (a);
  311.   char ctype [BUFSIZ];
  312.   char funcnm [BUFSIZ];
  313.   Class_Of_Type class = TYPEget_type (t);
  314.  
  315.   strncpy( ctype, AccessType (t), BUFSIZ );
  316.   strcpy(funcnm,(char*)generate_attribute_name( a, funcnm  ));
  317.   funcnm [0] = toupper (funcnm[0]);
  318.  
  319.   /*    case TYPE_LOGICAL:    */
  320.   if ((class == Class_Boolean_Type) || ( class == Class_Logical_Type))  
  321.     strcpy (ctype, "LOGICAL");
  322.  
  323.     /*    case TYPE_ENUM:    */
  324.   if ( class == Class_Enumeration_Type)  
  325.     strncpy (ctype, EnumName (TYPEget_name (t)), BUFSIZ);
  326.  
  327.  
  328.   /*  case STRING:*/
  329.   if ( class == Class_String_Type)  
  330.     strcpy (ctype, "const char *");
  331.  
  332.   /*        case TYPE_BINARY:    */
  333.   if ( class == Class_Binary_Type)
  334.     sprintf (ctype, "const %s&", AccessType (t));
  335.  
  336.   /*  default:  INTEGER and NUMBER    */
  337.   /*    case TYPE_AGGRETATES:    */
  338.   /*      case TYPE_ENTITY:    */
  339.   /*    case TYPE_SELECT:    */
  340.   /*  is the same type as the data member  */
  341.   fprintf (file, "\nvoid \n%s::%s (%s x)\n", entnm, funcnm, ctype );
  342. }
  343.  
  344. /******************************************************************
  345.  ** Procedure:  ATTRprint_access_method
  346.  ** Parameters:  const Variable a --  attribute to find the type for
  347.  **    FILE* file  --  file being written to
  348.  ** Returns:  name to be used for the type of the c++ access functions
  349.  ** Description:  prints the access method based on the attribute type  
  350.  ** Side Effects:  
  351.  ** Status:  complete 1/15/91
  352.  **      updated 17-Feb-1992 to print to library file instead of header
  353.  **    updated 15-July-1993 to call the get/put head functions    by DDH
  354.  ******************************************************************/
  355. void
  356. ATTRprint_access_methods  (CONST char * entnm, Variable a, FILE* file)
  357. {
  358.     Type t = VARget_type (a);
  359.     Class_Of_Type class;
  360.     char ctype [BUFSIZ];  /*  type of data member  */
  361.     char return_type [BUFSIZ];
  362.     char attrnm [BUFSIZ];
  363.     char membernm[BUFSIZ];
  364.  
  365.     strcpy(attrnm,(char*)generate_attribute_name( a, attrnm  ));
  366.     strcpy( membernm, attrnm );
  367.     membernm[0] = toupper(membernm[0]);    
  368.     class = TYPEget_type (t);
  369. /*    strncpy (ctype, TYPEget_ctype (t), BUFSIZ);*/
  370.     strncpy (ctype, AccessType (t), BUFSIZ);
  371.  
  372.     ATTRprint_access_methods_get_head( entnm, a, file);
  373.  
  374.     /*      case TYPE_ENTITY:    */
  375.     if ( class == Class_Entity_Type)  {
  376.     fprintf (file, "\t{ return (%s) _%s; }\n", ctype, attrnm);
  377.     ATTRprint_access_methods_put_head( entnm, a, file);
  378.     fprintf (file, "\t{ _%s = x; }\n", attrnm  );
  379.     return;
  380.     }    
  381.     /*    case TYPE_LOGICAL:    */
  382.     if ((class == Class_Boolean_Type) || ( class == Class_Logical_Type))  {
  383.     fprintf (file, "\t{ return (const Logical&) _%s; }\n", attrnm);
  384.     ATTRprint_access_methods_put_head( entnm, a, file);
  385.     fprintf (file, "\t{ _%s.put (x); }\n", attrnm  );
  386.     return;
  387.     }    
  388.     /*    case TYPE_ENUM:    */
  389.     if ( class == Class_Enumeration_Type)  {
  390.     fprintf (file, "\t{ return (const %s&) _%s; }\n", ctype, attrnm);
  391.     ATTRprint_access_methods_put_head( entnm, a, file);
  392.     fprintf (file, "\t{ _%s.put (x); }\n", attrnm  );
  393.     return;
  394.     }
  395.     /*    case TYPE_SELECT:    */
  396.     if ( class == Class_Select_Type)  {
  397.     fprintf (file, "\t{ return (const %s) &_%s; }\n",  ctype, attrnm);
  398.     ATTRprint_access_methods_put_head( entnm, a, file);
  399.     fprintf (file, "\t{ _%s = x; }\n", attrnm  );
  400.     return;
  401.     }
  402.     /*    case TYPE_AGGRETATES:    */
  403.     if ( isAggregate (a))         {
  404.     fprintf (file, "\t{ return (%s) &_%s; }\n", ctype, attrnm);
  405.     ATTRprint_access_methods_put_head( entnm, a, file);
  406.     fprintf (file, "\t{ _%s.ShallowCopy (*x); }\n", attrnm  );
  407.     return;
  408.     }
  409.     /*  case STRING:*/
  410.     /*        case TYPE_BINARY:    */
  411.     if (( class == Class_String_Type) || ( class == Class_Binary_Type))  {
  412.     fprintf (file, "\t{ return (const %s&) _%s; }\n", ctype, attrnm);
  413.     ATTRprint_access_methods_put_head( entnm, a, file);
  414.     fprintf (file, "\t{ _%s = x; }\n", attrnm  );
  415.     return;
  416.     }
  417.     /*  default:  INTEGER and NUMBER    */
  418.       /*  is the same type as the data member  */
  419.     fprintf (file, "\t{ return (const %s) _%s; }\n", ctype, attrnm);
  420.     ATTRprint_access_methods_put_head( entnm, a, file);
  421.     fprintf (file, "\t{ _%s = x; }\n", attrnm  );
  422. }
  423.  
  424. /******************************************************************
  425. **        Entity Generation                 */
  426.  
  427. /******************************************************************
  428.  ** Procedure:  ENTITYhead_print
  429.  ** Parameters:  const Entity entity
  430.  **   FILE* file  --  file being written to
  431.  ** Returns:  
  432.  ** Description:  prints the beginning of the class definition for the c++ code
  433.  **               and the declaration of extern type descriptors for the registry
  434.  ** Side Effects:  generates c++ code
  435.  ** Status:  good 1/15/91 
  436.  **          added registry things 12-Apr-1993
  437.  ******************************************************************/
  438.  
  439. void
  440. ENTITYhead_print (Entity entity, FILE* file,Schema schema)
  441. {
  442.     char buffer [BUFSIZ];
  443.     char entnm [BUFSIZ];
  444.     char attrnm [BUFSIZ];
  445.     char *buf = buffer;
  446.     char *tmp;
  447.     Linked_List list;
  448.     int attr_count_tmp = attr_count;
  449.     int super_cnt =0;
  450.     Entity super =0;
  451.  
  452.     strncpy (entnm, ENTITYget_classname (entity), BUFSIZ);
  453.  
  454.     LISTdo(ENTITYget_attributes(entity),v,Variable)
  455.       strcpy(attrnm,(char*)generate_attribute_name( v, attrnm  ));
  456.       fprintf(file,"extern %sAttrDescriptor *%s%d%s%s;\n",
  457.           (VARget_inverse (v) ? "Inverse" : ""),
  458.           ATTR_PREFIX,attr_count_tmp++, 
  459.           (VARis_derived (v) ? "D" : (VARget_inverse (v) ? "I" : "")),
  460.           attrnm);
  461.     LISTod            
  462.  
  463.     fprintf (file, "\nclass %s  :  ", entnm);
  464.  
  465.     super = ENTITYput_superclass (entity);
  466.     if (super)     fprintf (file, "  public %s  {\n ", ENTITYget_classname (super));
  467.     else 
  468.       fprintf (file, "  public STEPentity {\n");
  469.  
  470. #ifdef MULTIPLE_INHERITANCE 
  471.     list = ENTITYget_supertypes (entity);
  472.     if (! LISTempty (list)) {
  473.     LISTdo (list, e, Entity)
  474.       /*  if there\'s no super class yet, 
  475.           or the super class doesn\'t have any attributes
  476.           */
  477.       if ( (! super) || (! ENTITYhas_explicit_attributes (super) )) {
  478.         super = e;
  479.         ++ super_cnt;
  480.       }  else {
  481.         printf ("WARNING:  multiple inheritance not implemented.\n");
  482.         printf ("\tin ENTITY %s\n\tSUPERTYPE %s IGNORED.\n\n", 
  483.             ENTITYget_name (entity), ENTITYget_name (e));
  484.       }
  485.     LISTod;
  486.     fprintf (file, "  public %s  {\n ", ENTITYget_classname (super));
  487.  
  488. /*  for multiple inheritance
  489.     LISTdo (list, e, Entity)
  490.         sprintf (buf, "  public %s, ", ENTITYget_classname (e));
  491.         move (buf);
  492.     LISTod;
  493.     sprintf (buf - 2, " {\n");
  494.     move (buf);
  495.     fprintf(file,buffer);
  496. */
  497.     }  else {    /*  if entity has no supertypes, it's at top of hierarchy  */ 
  498.     fprintf (file, "  public STEPentity {\n");
  499.     }
  500. #endif
  501.     
  502. }
  503.  
  504. /******************************************************************
  505.  ** Procedure:  DataMemberPrint
  506.  ** Parameters:  const Entity entity  --  entity being processed
  507.  **   FILE* file  --  file being written to
  508.  ** Returns:  
  509.  ** Description:  prints out the data members for an entity's c++ class 
  510.  **               definition
  511.  ** Side Effects:  generates c++ code
  512.  ** Status:  ok 1/15/91
  513.  ******************************************************************/
  514.  
  515. void
  516. DataMemberPrint(Entity entity, FILE* file,Schema schema)
  517. {
  518.     
  519.     Linked_List attr_list;
  520.     char entnm [BUFSIZ];
  521.     char attrnm [BUFSIZ];    
  522.  
  523.     const char * ctype, * etype;
  524.     
  525.     strncpy (entnm, ENTITYget_classname (entity), BUFSIZ);  /*  assign entnm  */
  526.  
  527.     /*    print list of attributes in the protected access area     */
  528.  
  529.     fprintf (file, "  protected:\n");
  530.  
  531.     attr_list = ENTITYget_attributes (entity);
  532.     LISTdo (attr_list, a, Variable)
  533.     if (VARget_initializer (a) == EXPRESSION_NULL) {
  534.         ctype = TYPEget_ctype (VARget_type (a));
  535.         strcpy(attrnm,(char*)generate_attribute_name( a, attrnm  ));
  536.         if (!strcmp (ctype, "SCLundefined") ) {
  537.         printf ("WARNING:  in entity %s:\n", ENTITYget_name (entity)); 
  538.         printf ("\tthe type for attribute  %s is not fully implemented\n", 
  539.             attrnm);
  540.         }
  541.         fprintf (file, "\t%s _%s ;", ctype, attrnm);
  542.         if (VARget_optional (a)) fprintf (file, "    //  OPTIONAL");
  543.         if (isAggregate (a))         {
  544.         /*  if it's a named type, comment the type  */
  545.         if (etype = TYPEget_name (TYPEget_nonaggregate_base_type (VARget_type (a))))
  546.             fprintf (file, "\t  //  of  %s\n", etype);
  547.         }
  548.  
  549.         fprintf (file, "\n");
  550.     }    
  551.     
  552.     LISTod;
  553.  
  554. }
  555.  
  556. /******************************************************************
  557.  ** Procedure:  MemberFunctionSign
  558.  ** Parameters:  Entity *entity --  entity being processed
  559.  **     FILE* file  --  file being written to
  560.  ** Returns:  
  561.  ** Description:  prints the signature for member functions 
  562.                   of a entity's class definition
  563.  ** Side Effects:  prints c++ code to a file
  564.  ** Status:  ok 1/1/5/91
  565.  **  updated 17-Feb-1992 to print only the signature 
  566.              and not the function definitions
  567.  ******************************************************************/
  568.  
  569. void 
  570. MemberFunctionSign (Entity entity, FILE* file)
  571. {
  572.  
  573.     Linked_List attr_list;
  574.     static int entcode = 0;    
  575.     char entnm [BUFSIZ];
  576.  
  577.     strncpy (entnm, ENTITYget_classname (entity), BUFSIZ);  /*  assign entnm  */
  578.     
  579.     fprintf (file, "  public:  \n");
  580.  
  581.     /*    put in member functions which belong to all entities    */
  582.     /*    constructor:    */
  583.     fprintf (file, "\n    %s ( ); \n", entnm);
  584.     /*  copy constructor*/
  585.     fprintf (file, "    %s (%s& e ); \n",entnm,entnm);
  586.     /*    destructor:    */
  587.     fprintf (file, "    ~%s ();\n", entnm);
  588. /*    fprintf (file, "    char *Name () { return \"%s\"; }\n", */
  589. /*         PrettyTmpName (ENTITYget_name (entity)));*/
  590.     fprintf (file, "    int opcode ()  { return %d ; } \n", 
  591.          entcode++);
  592.  
  593.     /*    print signiture of access functions for attributes      */
  594.     attr_list = ENTITYget_attributes (entity);
  595.     LISTdo (attr_list, a, Variable)
  596.     if (VARget_initializer (a) == EXPRESSION_NULL) {
  597.  
  598.     /*  retrieval  and  assignment    */
  599.         ATTRsign_access_methods (a, file);
  600.     }
  601.     
  602.     LISTod;
  603.  
  604.     
  605.     fprintf (file, "};\n");
  606.  
  607.     /*  print creation function for class    */
  608.     fprintf (file, "inline %s *\ncreate_%s () {  return  new %s ;  }\n",
  609.      entnm, entnm, entnm);
  610.     
  611. }
  612.  
  613. /******************************************************************
  614.  ** Procedure:    LIBdescribe_entity (entity, file, schema)
  615.  ** Parameters:  Entity entity --  entity being processed
  616.  **     FILE* file  --  file being written to
  617.  **     Schema schema -- schema being processed
  618.  ** Returns:  
  619.  ** Description:  declares the global pointer to the EntityDescriptor
  620.                   representing a particular entity
  621.  ** Side Effects:  prints c++ code to a file
  622.  ** Status:  ok 12-Apr-1993
  623.  ******************************************************************/
  624. void
  625. LIBdescribe_entity (Entity entity, FILE* file, Schema schema)  
  626. {
  627.   Linked_List list;
  628.   int attr_count_tmp = attr_count;
  629.   char attrnm [BUFSIZ];
  630.   char * tmp;
  631.  
  632.   fprintf(file,"EntityDescriptor *%s%s%s =0;\n",
  633.       SCHEMAget_name(schema),ENT_PREFIX,ENTITYget_name(entity));
  634.     
  635.   LISTdo(ENTITYget_attributes(entity),v,Variable)
  636.     strcpy(attrnm,(char*)generate_attribute_name( v, attrnm  ));
  637.     fprintf(file,"%sAttrDescriptor *%s%d%s%s =0;\n",
  638.         (VARget_inverse (v) ? "Inverse" : ""),
  639.         ATTR_PREFIX, attr_count_tmp++, 
  640.         (VARis_derived (v) ? "D" : (VARget_inverse (v) ? "I" : "")),
  641.         attrnm);
  642.   LISTod            
  643.  
  644. }
  645.  
  646. /******************************************************************
  647.  ** Procedure:  LIBmemberFunctionPrint 
  648.  ** Parameters:  Entity *entity --  entity being processed
  649.  **     FILE* file  --  file being written to
  650.  ** Returns:  
  651.  ** Description:  prints the member functions for the class
  652.                   representing an entity
  653.  ** Side Effects:  prints c++ code to a file
  654.  ** Status:  ok 17-Feb-1992
  655.  ******************************************************************/
  656. void
  657. LIBmemberFunctionPrint (Entity entity, FILE* file)
  658. {
  659.  
  660.     Linked_List attr_list;
  661.     char entnm [BUFSIZ];
  662.  
  663.     strncpy (entnm, ENTITYget_classname (entity), BUFSIZ);  /*  assign entnm  */
  664.     
  665.     /*    1. put in member functions which belong to all entities    */
  666.     /*  the common function are still in the class definition 17-Feb-1992 */
  667.     /* fprintf (file, "    char *Name () { return \"%s\"; }\n", 
  668.          PrettyTmpName (ENTITYget_name (entity)));
  669.     fprintf (file, "    int opcode () { return %d ; }\n", 
  670.          entcode++);
  671.     */
  672.  
  673.     /*    2. print access functions for attributes      */
  674.     attr_list = ENTITYget_attributes (entity);
  675.     LISTdo (attr_list, a, Variable)
  676.     /*  do for EXPLICIT and INVERSE attributes - but not DERIVED */
  677.      if  ( ! VARis_derived (a)  )  {
  678.  
  679.        /*  retrieval  and  assignment    */
  680.        ATTRprint_access_methods (entnm, a, file);
  681.      }
  682.     
  683.     LISTod;
  684.  
  685. }
  686.  
  687. /******************************************************************
  688.  ** Procedure:  ENTITYinc_print
  689.  ** Parameters:  Entity *entity --  entity being processed
  690.  **     FILE* file  --  file being written to
  691.  ** Returns:  
  692.  ** Description:  drives the generation of the c++ class definition code
  693.  ** Side Effects:  prints segment of the c++ .h file
  694.  ** Status:  ok 1/15/91
  695.  ******************************************************************/
  696.  
  697. void 
  698. ENTITYinc_print (Entity entity, FILE* file,Schema schema)
  699. {
  700.     ENTITYhead_print ( entity, file,schema);
  701.     DataMemberPrint (entity, file, schema);
  702.     MemberFunctionSign (entity, file);
  703. }
  704.  
  705. /******************************************************************
  706.  ** Procedure:  LIBcopy_constructor 
  707.  ** Parameters:  
  708.  ** Returns:  
  709.  ** Description:  
  710.  ** Side Effects:  
  711.  ** Status:  not used 17-Feb-1992
  712.  ******************************************************************/
  713. void
  714. LIBcopy_constructor (Entity ent, FILE* file)
  715. {
  716.     Linked_List attr_list;
  717.     Class_Of_Type class;
  718.     Type t;
  719.     char buffer [BUFSIZ],
  720.              attrnm[BUFSIZ],
  721.       *b = buffer, *n = '\0';
  722.     int count = attr_count;
  723.     char * tmp;    
  724.     
  725.     String entnm = ENTITYget_classname (ent);
  726.     Boolean opt;    
  727.     String StrToLower (String word);
  728.  
  729.     /*mjm7/10/91 copy constructor definition  */
  730.     fprintf (file, "\t%s::%s(%s& e ) \n", entnm, entnm,entnm); 
  731.     fprintf (file, "  {");
  732.  
  733.     /*  attributes    */
  734.     attr_list = ENTITYget_attributes (ent);
  735.     LISTdo (attr_list, a, Variable)
  736.     if (VARget_initializer (a) == EXPRESSION_NULL) {
  737.         /*  include attribute if it is not derived    */
  738.         strcpy(attrnm,(char*)generate_attribute_name( a, attrnm  ));
  739.         t = VARget_type (a);
  740.         class = TYPEget_type (t);
  741.         opt = VARget_optional (a);
  742.         
  743.         /*  1. initialize everything to NULL (even if not optional)  */
  744.  
  745.         /*      default:  to intialize attribute to NULL    */
  746.         sprintf (b, "\t_%s = e.%s();\n", attrnm,attrnm);
  747.  
  748.         /*mjm7/11/91  case TYPE_STRING */
  749.         if ((class == Class_String_Type) || (class == Class_Binary_Type))
  750.         sprintf (b, "\t_%s = strdup(e.%s());\n", attrnm,attrnm);
  751.  
  752.  
  753.         /*      case TYPE_ENTITY:    */
  754.         if ( class == Class_Entity_Type)
  755.         sprintf (b, "\t_%s = e.%s();\n", attrnm,attrnm);
  756.         /* previous line modified to conform with SDAI C++ Binding for PDES, Inc. Prototyping 5/22/91 CD */
  757.  
  758.         /*    case TYPE_ENUM:    */
  759.         if (class == Class_Enumeration_Type) 
  760.           sprintf (b, "\t_%s.put(e.%s().asInt());\n", attrnm,attrnm);
  761.         /*    case TYPE_SELECT:    */
  762.         if (class == Class_Select_Type) 
  763.           sprintf (b, "DDDDDDD\t_%s.put(e.%s().asInt());\n", attrnm,attrnm);
  764.         /*   case TYPE_BOOLEAN    */
  765.         if ( class == Class_Boolean_Type)
  766.           sprintf (b, "\t_%s.put(e.%s().asInt());\n", attrnm,attrnm);
  767.         /* previous line modified to conform with SDAI C++ Binding for PDES, Inc. Prototyping 5/22/91 CD */
  768.  
  769.         /*   case TYPE_LOGICAL    */
  770.         if ( class == Class_Logical_Type)
  771.           sprintf (b, "\t_%s.put(e.%s().asInt());\n", attrnm,attrnm);
  772.         /* previous line modified to conform with SDAI C++ Binding for PDES, Inc. Prototyping 5/22/91 CD */
  773.     
  774.             /*    case TYPE_ARRAY:
  775.         case TYPE_LIST:
  776.         case TYPE_SET:
  777.         case TYPE_BAG:    */
  778.             if (isAggregateType (t)) 
  779.         *b = '\0';
  780.     
  781.             fprintf (file, "%s", b)          ;
  782.  
  783.         fprintf (file, "\t attributes.push ");
  784.  
  785.         /*  2.  put attribute on attributes list    */
  786.  
  787.         /*  default:    */
  788.  
  789.         fprintf (file,"\n\t(new STEPattribute (*%s%d%s, %s &_%s));\n", 
  790.              ATTR_PREFIX,count, 
  791. /*             (VARis_derived (t) ? "D" : (VARget_inverse (t) ? "I" : "")),*/
  792.              attrnm, 
  793.              (TYPEis_entity (t) ? "(STEPentityH *)" : ""),
  794.              attrnm);
  795.         ++count;
  796.         
  797.     }    
  798.     LISTod;
  799.     fprintf (file, " }\n");
  800.  
  801.  
  802. }
  803.  
  804. /******************************************************************
  805.  ** Procedure:  LIBstructor_print
  806.  ** Parameters:  Entity *entity --  entity being processed
  807.  **     FILE* file  --  file being written to
  808.  ** Returns:  
  809.  ** Description:  prints the c++ code for entity class's 
  810.  **     constructor and destructor
  811.  ** Side Effects:  generates codes segment in c++ .cc file
  812.  ** Status:  ok 1/15/91
  813.  ** Changes: Modified generator to initialize attributes to NULL based
  814.  **          on the NULL symbols defined in "SDAI C++ Binding for PDES,
  815.  **          Inc. Prototyping" by Stephen Clark.
  816.  ** Change Date: 5/22/91 CD
  817.  ** Changes: Modified STEPattribute constructors to take fewer arguments
  818.  **     21-Dec-1992 -kcm
  819.  ******************************************************************/
  820. void
  821. LIBstructor_print (Entity entity, FILE* file, Schema schema)
  822. {
  823.     Linked_List attr_list;
  824.     Type t;
  825.     char attrnm [BUFSIZ];
  826.     
  827.  
  828.     const char * entnm = ENTITYget_classname (entity);
  829.     int count = attr_count;
  830.     int first =1;
  831.  
  832.     /*  constructor definition  */
  833.     fprintf (file, "%s::%s( ) \n", entnm, entnm); 
  834.     fprintf (file, "{");
  835.  
  836.     /*  attributes    */
  837. /*    fprintf (file, "\n\tSTEPattribute * a;\n");*/
  838.  
  839.     /* what if entity comes from other schema? */
  840.     fprintf(file,"\nEntityDescriptor = %s%s%s;\n",
  841.         SCHEMAget_name(schema),ENT_PREFIX,ENTITYget_name(entity));
  842.  
  843.     attr_list = ENTITYget_attributes (entity);
  844.  
  845.     LISTdo (attr_list, a, Variable)
  846.     if (VARget_initializer (a) == EXPRESSION_NULL) {
  847.         /*  include attribute if it is not derived    */
  848.         strcpy(attrnm,(char*)generate_attribute_name( a, attrnm  ));
  849.         t = VARget_type (a);
  850.  
  851.         /*  1.  declare the AttrDescriptor    */
  852. /*  this is now in the header  */
  853. /*        fprintf(file,"extern AttrDescriptor *%s%d%s;\n",*/
  854. /*            ATTR_PREFIX,count,VARget_name(a));*/
  855.  
  856.         /*  if the attribute is Explicit, make a STEPattribute  */
  857. /*        if (VARis_simple_explicit (a))  {*/
  858.         if  (( ! VARget_inverse (a)) && ( ! VARis_derived (a)) )  {
  859.           /*  1. create a new STEPattribute    */
  860.           fprintf (file,"\n\t"
  861.                "%s a = new STEPattribute (*%s%d%s, %s &_%s);\n", 
  862.                (first ? "STEPattribute *" : ""),
  863.                /*  first time through declare a */
  864.                ATTR_PREFIX,count, attrnm, 
  865.                (TYPEis_entity (t) ? "(STEPentityH *)" : ""),
  866.                attrnm);
  867.           if (first)  first = 0 ;
  868.           /*  2. initialize everything to NULL (even if not optional)  */
  869.  
  870.           fprintf (file, "\ta -> set_null ();\n");
  871.         
  872.           /*  3.  put attribute on attributes list    */
  873.           fprintf (file, "\t attributes.push (a);\n");
  874.         }
  875.         count++;
  876.       }
  877.     
  878.     LISTod;
  879.  
  880.     attr_list = ENTITYget_all_attributes (entity);
  881.  
  882.     LISTdo (attr_list, a, Variable)
  883.       if (VARis_overrider (entity, a)) {
  884.     strcpy(attrnm,(char*)generate_attribute_name( a, attrnm  ));
  885.     fprintf (file, "\tMakeDerived (\"%s\");\n", attrnm);
  886.       }
  887.     LISTod;
  888.     fprintf (file, "}\n");
  889.  
  890.     /*  copy constructor  */
  891.     /*  LIBcopy_constructor (entity, file);    */
  892.     entnm = ENTITYget_classname (entity),
  893.     fprintf (file, "%s::%s (%s& e ) \n",entnm,entnm,entnm);
  894.     fprintf (file, "\t{  CopyAs((STEPentityH) &e);\t}\n");
  895.  
  896.     /*  print destructor  */
  897.     /*  currently empty, but should check to see if any attributes need
  898.     to be deleted -- attributes will need reference count  */
  899.  
  900.     entnm = ENTITYget_classname (entity),
  901.     fprintf (file, "%s::~%s () {  }\n", entnm, entnm);
  902.         
  903.     
  904. }
  905.  
  906. /******************************************************************
  907.  ** Procedure:  ENTITYlib_print
  908.  ** Parameters:  Entity *entity --  entity being processed
  909.  **     FILE* file  --  file being written to
  910.  ** Returns:  
  911.  ** Description:  drives the printing of the code for the class library
  912.  **     additional member functions can be generated by writing a routine 
  913.  **     to generate the code and calling that routine from this procedure
  914.  ** Side Effects:  generates code segment for c++ library file
  915.  ** Status:  ok 1/15/91
  916.  ******************************************************************/
  917.  
  918. void
  919. ENTITYlib_print (Entity entity, FILE* file,Schema schema)
  920. {
  921.   LIBdescribe_entity (entity, file, schema);
  922.   LIBstructor_print (entity, file,schema);
  923.   LIBmemberFunctionPrint (entity, file);
  924. }
  925.  
  926. /* return 1 if types are predefined by us */
  927. int
  928. TYPEis_builtin(const Type t) {
  929.     switch( TYPEget_body(t)->type) {/* dunno if correct*/
  930.     case integer_:
  931.     case real_:
  932.     case string_:
  933.     case binary_:
  934.     case boolean_:
  935.     case number_:
  936.     case logical_:
  937.         return 1;
  938.     }
  939.     return 0;
  940. }
  941.  
  942. /* return schema which original defined this object */
  943. /* i.e., thread back through USE/REF starting from referencing schema */
  944. Schema
  945. owning_schema(char *name,Schema schema)
  946. {
  947.     Rename *rename;
  948.     Schema result;
  949.  
  950.     if (DICTlookup(schema->symbol_table,name))
  951.         return(schema);
  952.  
  953.     /* Occurs in a fully USE'd schema? */
  954.     LISTdo(schema->u.schema->uselist,schema,Schema)
  955.         /* follow chain'd USEs */
  956.         result = owning_schema(name,schema);
  957.         if (result) return(result);
  958.     LISTod;
  959.  
  960.     /* Occurs in a partially USE'd schema? */
  961.     rename = (Rename *)DICTlookup(schema->u.schema->usedict,name);
  962.     if (rename) {
  963.         return(owning_schema(rename->old->name,rename->schema));
  964.     }
  965.     
  966.     /* Occurs in a fully REF'd schema? */
  967.     LISTdo(schema->u.schema->reflist,schema,Schema)
  968.         result = owning_schema(name,schema);
  969.         if (result) return result;
  970.         else continue;    /* try another schema */
  971.     LISTod;
  972.  
  973.     /* Occurs in a partially REF'd schema? */
  974.     rename = (Rename *)DICTlookup(schema->u.schema->refdict,name);
  975.     if (rename) {
  976.         return(owning_schema(rename->old->name,rename->schema));
  977.     }
  978.  
  979.     /* cannot happen */
  980.     /* indicates some inconsistency in internal structures, */
  981.     /* since this was earlier traversed successfully */
  982.     return 0;
  983. }    
  984.  
  985. /* go down through a type's base type chain, dynamically making and */
  986. /* printing new types for each base type */
  987. void
  988. print_typechain(FILE *f,const Type t,char *buf,Schema schema)
  989. {
  990.   /* if we've been called, current type has no name */
  991.   /* nor is it a built-in type */
  992.   /* the type_count variable is there for debugging purposes  */
  993.  
  994.     Type base;
  995.     int count = type_count++;
  996.  
  997.     fprintf(f,"\tTypeDescriptor * %s%d = new TypeDescriptor;\n",TD_PREFIX,count);
  998.     fprintf(f,"    %s%d->FundamentalType(%s);\n",TD_PREFIX,count,FundamentalType(t,1));
  999.     fprintf(f,"    %s%d->Description(\"%s\");\n",TD_PREFIX,count,TypeDescription(t));
  1000.  
  1001.     if (TYPEget_body(t)) base = TYPEget_body(t)->base;
  1002.  
  1003.     if (TYPEget_head(t)) {
  1004.         fprintf(f,
  1005.             "\t%s%d->ReferentType(%s%s%s);\n",
  1006.             TD_PREFIX,count,
  1007.             SCHEMAget_name(owning_schema(TYPEget_name(TYPEget_head(t)),schema)),
  1008.             TYPEprefix (t), TYPEget_name(TYPEget_head(t)) );
  1009.  
  1010.     } else if (TYPEis_builtin(base)) {/* dunno if correct*/
  1011.         fprintf(f,"    %s%d->ReferentType(%s%s);\n",
  1012.             TD_PREFIX,count,
  1013.             TD_PREFIX,FundamentalType(base,0));
  1014.  
  1015.     } else if (TYPEget_body(base)->type == entity_) {
  1016.         fprintf(f,"    %s%d->ReferentType (%s%s%s);\n",
  1017.             TYPEprefix (t) ,count,
  1018.             /* following assumes we are not in a nested entity */
  1019.             /* otherwise we should search upward for schema */
  1020.             TYPEget_name(TYPEget_body(base)->entity->superscope),ENT_PREFIX,TYPEget_name(base));
  1021.     } else if (TYPEget_name(base)) {
  1022.         /* type ref with name */
  1023.         fprintf(f,"    %s%d->ReferentType(%s%s%s);\n",TD_PREFIX,count,
  1024.             SCHEMAget_name(owning_schema(TYPEget_name(base),schema)),TD_PREFIX,TYPEget_name(base));
  1025.     } else {
  1026.         /* no name, recurse */
  1027.         char callee_buffer[MAX_LEN];
  1028.         print_typechain(f,base,callee_buffer,schema);
  1029.         fprintf(f,"    %s%d->ReferentType(%s);\n",TD_PREFIX,count,callee_buffer);
  1030.     }
  1031.     sprintf(buf,"%s%d",TD_PREFIX,count);
  1032. }
  1033.  
  1034. /******************************************************************
  1035.  ** Procedure:  ENTITYincode_print
  1036.  ** Parameters:  Entity *entity --  entity being processed
  1037.  **     FILE* file  --  file being written to
  1038.  ** Returns:  
  1039.  ** Description:  generates code to enter entity in STEP registry
  1040.  ** Side Effects:  
  1041.  ** Status:  ok 1/15/91
  1042.  ******************************************************************/
  1043. void
  1044. ENTITYincode_print (Entity entity, FILE* file,Schema schema)  /*  ,FILES *files) */
  1045. {
  1046. #define entity_name    ENTITYget_name(entity)
  1047. #define schema_name    SCHEMAget_name(schema)
  1048.  
  1049.     const char *cn = ENTITYget_classname(entity);
  1050.     char attrnm [BUFSIZ];
  1051.     const char * super_schema;
  1052.     char * tmp;
  1053. #if 0
  1054.     String cn_unsafe = ENTITYget_classname (entity);
  1055.     char cn[MAX_LEN];
  1056.  
  1057.     /* cn_unsafe points to a static buffer, grr..., so save it */
  1058.     strcpy(cn,cn_unsafe);
  1059. #endif
  1060.  
  1061.     fprintf(file,"\treg.AddEntity (*%s%s%s);\n",
  1062.         schema_name,ENT_PREFIX,entity_name);
  1063.  
  1064. /*    LISTdo(ENTITYget_subtypes(entity),sub,Entity)
  1065.         fprintf(file,"    %s%s%s->Subtypes().AddNode(%s%s%s);\n",
  1066.             schema_name,ENT_PREFIX,entity_name,
  1067.             schema_name,ENT_PREFIX,ENTITYget_name(sub));
  1068.     LISTod
  1069. */
  1070.  
  1071.     LISTdo(ENTITYget_supertypes(entity),sup,Entity)
  1072.           /*  set the owning schema of the supertype  */
  1073.       super_schema = SCHEMAget_name(ENTITYget_schema(sup));
  1074.         /* print the supertype list for this entity    */
  1075.         fprintf(file,"    %s%s%s->AddSupertype(%s%s%s);\n",
  1076.             schema_name,ENT_PREFIX,entity_name,
  1077.             super_schema,
  1078.             ENT_PREFIX,ENTITYget_name(sup));
  1079.  
  1080.         /* add this entity to the subtype list of it's supertype    */
  1081.         fprintf(file,"    %s%s%s->AddSubtype(%s%s%s);\n",
  1082.             super_schema,
  1083.             ENT_PREFIX,ENTITYget_name(sup),
  1084.             schema_name,ENT_PREFIX, entity_name);
  1085.     LISTod
  1086.  
  1087.     LISTdo(ENTITYget_attributes(entity),v,Variable)
  1088.       strcpy(attrnm,(char*)generate_attribute_name( v, attrnm  ));
  1089.       /*  do EXPLICIT and DERIVED attributes first  */
  1090. /*      if  ( ! VARget_inverse (v))  {*/
  1091.         /* first make sure that type descriptor exists */
  1092.         if (TYPEget_name(v->type)) {
  1093.             if ((!TYPEget_head(v->type)) && 
  1094.             (TYPEget_body(v->type)->type == entity_))
  1095.             {
  1096. /*            fprintf(file, "\t%s%d%s%s = new %sAttrDescriptor(\"%s\",%s%s%s,%s,%s,%s,*%s%s%s);\n", */
  1097.             fprintf(file, "\t%s%d%s%s = new %sAttrDescriptor(\"%s\",%s%s%s,%s,%s%s%s,*%s%s%s);\n",
  1098.                 ATTR_PREFIX,attr_count, 
  1099.                 (VARis_derived (v) ? "D" : 
  1100.                            (VARget_inverse (v) ? "I" : "")),
  1101.                  /* (VARis_derived (v) ? "D" : ""), */
  1102.                 attrnm,
  1103.  
  1104.                 (VARget_inverse (v) ? "Inverse" : ""),
  1105.  
  1106.                 StrToLower (attrnm),  /*  attribute name  */
  1107.  
  1108.                  /* following assumes we are not in a nested */
  1109.                  /* entity otherwise we should search upward */
  1110.                  /* for schema */
  1111.                  /* attribute's type  */
  1112.                 TYPEget_name(
  1113.                     TYPEget_body(v->type)->entity->superscope),
  1114.                 ENT_PREFIX,TYPEget_name(v->type), 
  1115.  
  1116.                 (VARget_optional(v)?"T":"F"),
  1117.  
  1118.                 (VARget_unique(v)?"T":"F"),
  1119.  
  1120. /*                (VARis_derived(v)?"T":"F"),*/
  1121.                 (VARget_inverse (v) ? "" : ","),
  1122.                 (VARget_inverse (v) ? "" : 
  1123.                     (VARis_derived(v)?"T":"F")),
  1124.  
  1125.                 schema_name,ENT_PREFIX,TYPEget_name(entity) 
  1126.                    );
  1127.             } else {
  1128.             /* type reference */
  1129. /*            fprintf(file,"    %s%d%s%s = new %sAttrDescriptor(\"%s\",%s%s%s,%s,%s,%s,*%s%s%s);\n",*/
  1130.             fprintf(file,"    %s%d%s%s = new %sAttrDescriptor(\"%s\",%s%s%s,%s,%s%s%s,*%s%s%s);\n",
  1131.                 ATTR_PREFIX,attr_count, 
  1132.                 (VARis_derived (v) ? "D" : 
  1133.                          (VARget_inverse (v) ? "I" : "")),
  1134.                  /*    (VARis_derived (v) ? "D" : ""), */
  1135.                 attrnm,
  1136.  
  1137.                 (VARget_inverse (v) ? "Inverse" : ""),
  1138.  
  1139.                 StrToLower (attrnm),
  1140.  
  1141.                 SCHEMAget_name(
  1142.                   owning_schema(TYPEget_name(v->type),schema)
  1143.                         ), TD_PREFIX,TYPEget_name(v->type),
  1144.  
  1145.                 (VARget_optional(v)?"T":"F"),
  1146.  
  1147.                 (VARget_unique(v)?"T":"F"),
  1148.  
  1149. /*                (VARis_derived(v)?"T":"F"),*/
  1150.                 (VARget_inverse (v) ? "" : ","),
  1151.                 (VARget_inverse (v) ? "" : 
  1152.                     (VARis_derived(v)?"T":"F")),
  1153.  
  1154.                 schema_name,ENT_PREFIX,TYPEget_name(entity)
  1155.                   );
  1156.             }  
  1157.         } else if (TYPEis_builtin(v->type)) {
  1158.           /*  the type wasn\'t named -- it must be built in or aggregate  */
  1159.  
  1160. /*            fprintf(file,"    %s%d%s%s = new %sAttrDescriptor(\"%s\",%s%s,%s,%s,%s,*%s%s%s);\n",*/
  1161.             fprintf(file,"    %s%d%s%s = new %sAttrDescriptor(\"%s\",%s%s,%s,%s%s%s,*%s%s%s);\n",
  1162.                 ATTR_PREFIX,attr_count, 
  1163.                 (VARis_derived (v) ? "D" : 
  1164.                     (VARget_inverse (v) ? "I" : "")),
  1165.                  /* (VARis_derived (v) ? "D" : ""), */
  1166.                 attrnm,
  1167.  
  1168.                 (VARget_inverse (v) ? "Inverse" : ""),
  1169.  
  1170.                 StrToLower (attrnm),
  1171. /* not sure about 0 here */    TD_PREFIX,FundamentalType(v->type,0),
  1172.  
  1173.                 (VARget_optional(v)?"T":"F"),
  1174.  
  1175.                 (VARget_unique(v)?"T":"F"),
  1176.  
  1177. /*                (VARis_derived(v)?"T":"F"),*/
  1178.                 (VARget_inverse (v) ? "" : ","),
  1179.                 (VARget_inverse (v) ? "" : 
  1180.                     (VARis_derived(v)?"T":"F")),
  1181.  
  1182.                 schema_name,ENT_PREFIX,TYPEget_name(entity)
  1183.                    );
  1184.         } else {
  1185.             /* manufacture new one(s) on the spot */
  1186.             char typename_buf[MAX_LEN];
  1187.             print_typechain(file, v->type, typename_buf, schema);
  1188. /*            fprintf(file,"    %s%d%s%s = new %sAttrDescriptor(\"%s\",%s,%s,%s,%s,*%s%s%s);\n",*/
  1189.             fprintf(file,"    %s%d%s%s = new %sAttrDescriptor(\"%s\",%s,%s,%s%s%s,*%s%s%s);\n",
  1190.                 ATTR_PREFIX,attr_count,
  1191.                 (VARis_derived (v) ? "D" : 
  1192.                          (VARget_inverse (v) ? "I" : "")),
  1193.                  /* (VARis_derived (v) ? "D" : ""),*/
  1194.                 attrnm,
  1195.  
  1196.                 (VARget_inverse (v) ? "Inverse" : ""),
  1197.  
  1198.                 StrToLower (attrnm),
  1199.  
  1200.                 typename_buf,
  1201.  
  1202.                 (VARget_optional(v)?"T":"F"),
  1203.  
  1204.                 (VARget_unique(v)?"T":"F"),
  1205.  
  1206. /*                (VARis_derived(v)?"T":"F"),*/
  1207.                 (VARget_inverse (v) ? "" : ","),
  1208.                 (VARget_inverse (v) ? "" : 
  1209.                     (VARis_derived(v)?"T":"F")),
  1210.  
  1211.                 schema_name,ENT_PREFIX,TYPEget_name(entity)
  1212.                    );
  1213.         }
  1214.  
  1215.  
  1216.         fprintf(file,"    %s%s%s->Add%sAttr (%s%d%s%s);\n",
  1217.             schema_name,ENT_PREFIX,TYPEget_name(entity),
  1218.           (VARget_inverse (v) ? "Inverse" : "Explicit"),
  1219.             ATTR_PREFIX,attr_count, 
  1220.           (VARis_derived (v) ? "D" : (VARget_inverse (v) ? "I" : "")),
  1221. /*            (VARis_derived (v) ? "D" : ""),*/
  1222.             attrnm);
  1223. #if 0
  1224.           } else   if  (VARget_inverse (v)) {
  1225.         /*  do INVERSE attributes too  */
  1226. /* 
  1227. TODO   -- write algorithm for determining descriptor of this attribute\'s inverse
  1228. */
  1229. /*        if ((!TYPEget_head(v->type)) && (TYPEget_body(v->type)->type == entity_)) {  */
  1230.                   /* this should always be true for INVERSE attributes  */
  1231.           fprintf(file,"\t%s%dI%s = new InverseAttrDescriptor(\"%s\",%s%s%s,%s,%s,*%s%s%s);\n",
  1232.               ATTR_PREFIX,attr_count,attrnm, /*  descriptor name */
  1233. /*              ATTR_PREFIX,attr_count,TYPEget_name(v->name), */
  1234.               StrToLower (attrnm), /*  attribute name  */
  1235. /*              StrToLower (TYPEget_name(v->name)), */  
  1236.               /* following assumes we are not in a nested entity */
  1237.               /* otherwise we should search upward for schema */
  1238.               /* attribute's type  */
  1239.               TYPEget_name(TYPEget_body(v->type)->entity->superscope),ENT_PREFIX,attrnm,
  1240. /*TYPEget_name(v->type), */
  1241.               (VARget_optional(v)?"T":"F"),
  1242.               (VARget_unique(v)?"T":"F"),
  1243.               schema_name,ENT_PREFIX, TYPEget_name(entity));
  1244.  
  1245.           fprintf(file,"\t%s%s%s->AddInverseAttr (%s%dI%s);\n",
  1246.               schema_name,ENT_PREFIX,TYPEget_name(entity),
  1247.               ATTR_PREFIX,attr_count,TYPEget_name(v->name));
  1248. /*        }*/
  1249.           }
  1250. #endif
  1251.     attr_count++;
  1252.  
  1253.     LISTod            
  1254.  
  1255. #undef schema_name
  1256. }
  1257.  
  1258. #if 0
  1259. void
  1260. /* create calls to connect sub/supertype relationships */
  1261. ENTITYstype_connect(Entity entity, FILE* file,Schema schema)
  1262. {
  1263.     LISTdo(ENTITYget_subtypes(entity),sub,Entity)
  1264.         fprintf(file,"    %s->Subtypes().AddNode(%s);\n",
  1265.             ENTITYget_name(sub));
  1266.     LISTod
  1267.  
  1268.     LISTdo(ENTITYget_supertypes(entity),sup,Entity)
  1269.         fprintf(file,"    %s->Supertypes().AddNode(%s);\n",
  1270.             ENTITYget_name(sup));
  1271.     LISTod
  1272.     }
  1273. #endif
  1274.  
  1275. /******************************************************************
  1276.  ** Procedure:  ENTITYPrint
  1277.  ** Parameters:  Entity *entity --  entity being processed
  1278.  **     FILE* file  --  file being written to
  1279.  ** Returns:  
  1280.  ** Description:  drives the functions for printing out code in lib,
  1281.  **     include, and initialization files for a specific entity class
  1282.  ** Side Effects:  generates code in 3 files
  1283.  ** Status:  complete 1/15/91
  1284.  ******************************************************************/
  1285.  
  1286.  
  1287. void
  1288. ENTITYPrint(Entity entity, FILES* files,Schema schema)
  1289. {
  1290.  
  1291.   char * n = ENTITYget_name (entity);
  1292.   DEBUG ("Entering ENTITYPrint for %s \n", n);
  1293.  
  1294.   fprintf (files->inc, "\n/////////\t ENTITY %s \n\n", n);
  1295.   ENTITYinc_print (entity, files -> inc,schema);
  1296.   fprintf (files->inc, "\n/////////\t END_ENTITY %s \n\n", n);
  1297.   
  1298.   fprintf (files->lib, "\n/////////\t ENTITY %s \n\n", n);
  1299.   ENTITYlib_print (entity, files -> lib,schema);
  1300.   fprintf (files->lib, "\n/////////\t END_ENTITY %s \n\n", n);
  1301.  
  1302.   fprintf (files->initent, "\n/////////\t ENTITY %s \n\n", n);
  1303.   ENTITYincode_print (entity, files -> initent, schema);
  1304.   fprintf (files->initent, "/////////\t END_ENTITY %s \n", n);
  1305.    
  1306.   DEBUG ("DONE ENTITYPrint\n")    ;
  1307. }
  1308.  
  1309. void
  1310. ENTITYprint_new(Entity entity,FILES *files, Schema schema)
  1311. {
  1312.     const char * n;
  1313.     fprintf(files->init,"    %s%s%s = new EntityDescriptor(\"%s\",%s%s,%s, (Creator) create_%s);\n",
  1314.         SCHEMAget_name(schema),ENT_PREFIX,ENTITYget_name(entity),
  1315.         PrettyTmpName (ENTITYget_name(entity)),
  1316.         SCHEMA_PREFIX,SCHEMAget_name(schema),
  1317.         (ENTITYget_abstract(entity)?"T":"F"),
  1318.         ENTITYget_classname (entity)  
  1319.         );
  1320.     n = ENTITYget_classname (entity);
  1321.     fprintf (files->inc, "\nclass %s;\n", n); 
  1322.     fprintf (files->inc, "typedef %s * \t%sH;\n", n, n);
  1323.     fprintf(files ->inc,"extern EntityDescriptor \t*%s%s%s;\n",
  1324.         SCHEMAget_name(schema),ENT_PREFIX,ENTITYget_name(entity));
  1325.     
  1326. }
  1327.  
  1328. /******************************************************************
  1329.  **            TYPE GENERATION                **/
  1330.  
  1331.  
  1332. /******************************************************************
  1333.  ** Procedure:    TYPEprint_enum
  1334.  ** Parameters:    const Type type    - type to print
  1335.  **        FILE*      f    - file on which to print
  1336.  ** Returns:    
  1337.  ** Requires:    TYPEget_class(type) == TYPE_ENUM
  1338.  ** Description:  prints code to represent an enumerated type in c++ 
  1339.  ** Side Effects:  prints to header file
  1340.  ** Status:  ok 1/15/91
  1341.  ** Changes: Modified to check for appropiate key words as described
  1342.  **          in "SDAI C++ Binding for PDES, Inc. Prototyping" by
  1343.  **          Stephen Clark.
  1344.  ** Change Date: 5/22/91  CD
  1345.  ******************************************************************/
  1346. const char * 
  1347. EnumCElementName (Type type, Expression expr)  {
  1348.  
  1349.   static char buf [BUFSIZ];
  1350.   sprintf (buf,"%s_%s", 
  1351.        StrToLower (TYPEget_name (type)),
  1352.        StrToUpper (EXPget_name(expr)));
  1353.  
  1354.   return buf;
  1355. }
  1356.  
  1357. char *
  1358. CheckEnumSymbol (char * s)
  1359. {
  1360.  
  1361.     char b [BUFSIZ];
  1362.     if (strcmp (s, "sdaiTRUE") 
  1363.     && strcmp (s, "sdaiFALSE") 
  1364.     && strcmp (s, "sdaiUNKNOWN")) {
  1365.     /*  if the symbol is not a reserved one    */
  1366.     return (s);
  1367.     
  1368.     } else {
  1369.     strcpy (b, s);
  1370.     strcat (b, "_");
  1371.     printf ("** warning:  the enumerated value %s is already being used ", s);
  1372.     printf (" and has been changed to %s **\n", b);
  1373.     return (b);
  1374.     }
  1375. }
  1376.  
  1377. void
  1378. TYPEenum_inc_print (const Type type, FILE* f)
  1379. {
  1380.     DictionaryEntry de;
  1381.     Expression expr;
  1382.  
  1383.     char buffer [BUFSIZ],
  1384.       *buf = buffer;
  1385.     const char * n;  /*  pointer to class name  */
  1386.     int cnt =0;
  1387.     
  1388.     buffer[0] = '\0';
  1389.  
  1390.     fprintf (f, "\n//////////  ENUMERATION TYPE %s\n", TYPEget_name (type));
  1391.  
  1392.     /*  print c++ enumerated values for class    */
  1393.     fprintf (f, "enum  %s  {\n", EnumName (TYPEget_name (type)));
  1394.     
  1395.     DICTdo_type_init(ENUM_TYPEget_items(type),&de,OBJ_ENUM);
  1396.     while (0 != (expr = (Expression)DICTdo(&de))) {
  1397.       /*  print the elements of the c++ enum type  */
  1398.         ++cnt;
  1399.             sprintf (buf,"\t%s,\n", EnumCElementName (type, expr));
  1400.             move (buf);
  1401.     }
  1402.     sprintf (buf-2, "\n } ;\n");
  1403.     fprintf(f,buffer);
  1404.  
  1405.     /*  print class for enumeration    */
  1406.     n = ClassName (TYPEget_name (type));
  1407.     fprintf (f, "\nclass %s  :  public STEPenumeration  {\n", n);
  1408.  
  1409.     /*    constructors    */
  1410.     fprintf (f, "  public:\n\t%s (const char * n =0);\n", n);
  1411. /*    fprintf (f, "\t%s (%s e) { Init ();  set_value (e);  }\n", */
  1412.     fprintf (f, "\t%s (%s e) {  set_value (e);  }\n", 
  1413.          n, EnumName (TYPEget_name (type)));
  1414.  
  1415.     /*    destructor    */
  1416.     fprintf (f, "\t~%s ()  {  }\n", n);
  1417.  
  1418.     /*      operator =      */
  1419.     fprintf (f, "\t%s& operator= (const %s& e)\n", 
  1420.          n, EnumName (TYPEget_name (type)));
  1421.     fprintf (f, "\t\t{  set_value (e);  return *this;  }\n");
  1422.  
  1423.     /*      operator to cast to an enumerated type  */
  1424.     fprintf (f, "\toperator %s () const;\n", 
  1425.          EnumName (TYPEget_name (type)));
  1426.  
  1427.     /*      others          */
  1428.     fprintf (f, "\n\tinline virtual const char * Name () const\n");
  1429.     fprintf (f, "\t\t{  return \"%s\" ;  }\n", n);
  1430.     fprintf (f, "\tinline virtual int no_elements () const  {  return %d;  }\n", 
  1431.          cnt);
  1432. /*    fprintf (f, "  private:\n\tvoid Init ();\n");*/
  1433.     fprintf (f, "\tvirtual const char * element_at (int n) const;\n"); 
  1434.  
  1435.     /*  end class definition  */
  1436.     fprintf (f, "};\n\n");
  1437.  
  1438.  
  1439.     /*  print things for aggregate class  */
  1440.     fprintf (f, "\nclass %ss  :  public  EnumAggregate  {\n", n);
  1441. /*    fprintf (f, "  public:\n\tvirtual EnumNode * NewNode ()  {\n");*/
  1442.     fprintf (f, "  public:\n\tvirtual SingleLinkNode * NewNode ()  {\n");
  1443.     fprintf (f, "\t  return new EnumNode (new %s);\t}\n};\n", n);
  1444.     fprintf (f, "typedef %ss * %ssH;", n, n);
  1445.     fprintf (f, "\n//////////  END ENUMERATION %s\n\n", TYPEget_name (type));
  1446. }
  1447.  
  1448. void
  1449. TYPEenum_lib_print (const Type type, FILE* f)
  1450. {
  1451.   DictionaryEntry de;
  1452.   Expression expr;
  1453.   const char *n;    /*  pointer to class name  */
  1454.   char buf [BUFSIZ];
  1455.   char c_enum_ele [BUFSIZ];
  1456.     
  1457.   fprintf (f, "\n//////////  ENUMERATION TYPE %s\n", TYPEget_name (type));
  1458.   n = ClassName(TYPEget_name(type));
  1459.     
  1460.   /*  set up the dictionary info  */
  1461. /*  fprintf (f, "void \t%s::Init ()  {\n", n);*/
  1462. /*  fprintf (f, "  static const char * const l [] = {\n");*/
  1463.   
  1464.   fprintf (f, "const char * \n%s::element_at (int n) const  {\n", n);
  1465.   fprintf (f, "  switch (n)  {\n");
  1466.   DICTdo_type_init(ENUM_TYPEget_items(type),&de,OBJ_ENUM);
  1467.   while (0 != (expr = (Expression)DICTdo(&de))) {
  1468.     strncpy (c_enum_ele, EnumCElementName (type, expr), BUFSIZ);
  1469.     fprintf(f,"  case %s :  return \"%s\";\n",
  1470.         c_enum_ele,
  1471.         StrToUpper (EXPget_name(expr)));
  1472.   }
  1473.   fprintf (f, "  default:  return \"\";\n  }\n}\n");
  1474. /*  fprintf (f, "\t 0\n  };\n");*/
  1475. /*  fprintf (f, "  set_elements (l);\n  v = ENUM_NULL;\n}\n");*/
  1476.  
  1477.   /*    constructors    */
  1478.   /*    construct with character string  */
  1479.   fprintf (f, "%s::%s (const char * n )  {\n", n, n);
  1480. /*  fprintf (f, "  Init ();\n  set_value (n);\n}\n");*/
  1481.   fprintf (f, "  set_value (n);\n}\n");
  1482.   
  1483.   /*    copy constructor  */
  1484. /*  fprintf (f, "%s::%s (%s& n )  {\n", n, n, n);*/
  1485. /*  fprintf (f, "   (l);\n");*/
  1486.   
  1487.  
  1488.   /*      operator =      */
  1489. /*  fprintf (f, "%s& \t%s::operator= (%s& x)", n, n, n);*/
  1490. /*  fprintf (f, "\n\t{  put (x.asInt ()); return *this;   }\n");*/
  1491.  
  1492.     /*      cast operator to an enumerated type  */
  1493.   fprintf (f, "%s::operator %s () const {\n", n, 
  1494.        EnumName (TYPEget_name (type)));
  1495.   fprintf (f, "  switch (v) {\n");
  1496.         buf [0] = '\0';
  1497.     DICTdo_type_init(ENUM_TYPEget_items(type),&de,OBJ_ENUM);
  1498.     while (0 != (expr = (Expression)DICTdo(&de))) {
  1499.       fprintf (f, "%s", buf);
  1500.       strncpy (c_enum_ele, EnumCElementName (type, expr), BUFSIZ);
  1501.       fprintf (f, "\tcase %s :  ", c_enum_ele);
  1502.       sprintf (buf, "return %s;\n", c_enum_ele);
  1503.     }
  1504.   /*  print the last case with the default so sun c++ doesn\'t complain */
  1505.     fprintf (f, "\n\tdefault :  %s;\n  }\n}\n", buf);
  1506. /*    fprintf (f, "\t\tdefault:  return 0;\n  }\n}\n");*/
  1507.          
  1508.  
  1509.   fprintf (f, "\n//////////  END ENUMERATION %s\n", TYPEget_name (type));
  1510.  
  1511. }
  1512.  
  1513.  
  1514.  
  1515.  
  1516.  
  1517. /* return fundamental type but as the string which corresponds to */
  1518. /* the appropriate type descriptor */
  1519. /* if report_reftypes is true, report REFERENCE_TYPE when appropriate */
  1520. char *
  1521. FundamentalType(const Type t,int report_reftypes) {
  1522.     if (report_reftypes && TYPEget_head(t)) return("REFERENCE_TYPE");
  1523.     switch (TYPEget_body(t)->type) {
  1524.     case integer_:        return("INTEGER_TYPE");
  1525.     case real_:        return("REAL_TYPE");
  1526.     case string_:        return("STRING_TYPE");
  1527.     case binary_:        return("BINARY_TYPE");
  1528.     case boolean_:        return("BOOLEAN_TYPE");
  1529.     case logical_:        return("LOGICAL_TYPE");
  1530.     case number_:        return("NUMBER_TYPE");
  1531.     case generic_:        return("GENERIC_TYPE");
  1532.     case aggregate_:
  1533.     case array_:
  1534.     case bag_:
  1535.     case set_:
  1536.     case list_:        return("AGGREGATE_TYPE");
  1537.     case entity_:        return("ENTITY_TYPE");
  1538.     case enumeration_:    return("ENUM_TYPE");
  1539.     case select_:           return ("SELECT_TYPE");
  1540.     default:        return("UNKNOWN_TYPE");
  1541.     }
  1542. }
  1543.  
  1544.  
  1545.  
  1546. /* return printable version of entire type definition */
  1547. /* return it in static buffer */
  1548. char *
  1549. TypeDescription(const Type t)
  1550. {
  1551.     static char buf[4000];
  1552.  
  1553.     buf[0] = '\0';
  1554.  
  1555.     if (TYPEget_head(t)) Type_Description(TYPEget_head(t),buf);
  1556.     else TypeBody_Description(TYPEget_body(t),buf);
  1557.  
  1558.     /* should also print out where clause here */
  1559.  
  1560.     return buf+1;
  1561. }
  1562.  
  1563. char *strcat_expr(Expression e,char *buf)
  1564. {
  1565.     if (e == LITERAL_INFINITY) {
  1566.         strcat(buf,"?");
  1567.     } else if (e == LITERAL_PI) {
  1568.         strcat(buf,"PI");
  1569.     } else if (e == LITERAL_E) {
  1570.         strcat(buf,"E");
  1571.     } else if (e == LITERAL_ZERO) {
  1572.         strcat(buf,"0");
  1573.     } else if (e == LITERAL_ONE) {
  1574.         strcat(buf,"1");
  1575.     } else if (TYPEget_name(e)) {
  1576.         strcat(buf,TYPEget_name(e));
  1577.     } else if (TYPEget_body(e->type)->type == integer_) {
  1578.         char tmpbuf[30];
  1579.         sprintf(tmpbuf,"%d",e->u.integer);
  1580.         strcat(buf,tmpbuf);
  1581.     } else {
  1582.         strcat(buf,"??");
  1583.     } 
  1584.     return buf;
  1585. }
  1586.  
  1587. /* print t's bounds to end of buf */
  1588. char*
  1589. strcat_bounds(TypeBody b,char *buf)
  1590. {
  1591.     if (!b->upper) return "";
  1592.  
  1593.     strcat(buf," [");
  1594.     strcat_expr(b->lower,buf);
  1595.     strcat(buf,":");
  1596.     strcat_expr(b->upper,buf);
  1597.     strcat(buf,"]"); 
  1598.     return buf;
  1599. }
  1600.  
  1601. char *TypeBody_Description(TypeBody body, char *buf)
  1602. {
  1603.     Expression expr;
  1604.     DictionaryEntry de;
  1605.     char *s;
  1606.  
  1607.     if (body->flags.unique)    strcat(buf," UNIQUE");
  1608.     if (body->flags.optional)    strcat(buf," OPTIONAL");
  1609.  
  1610.     switch (body->type) {
  1611.     case integer_:        strcat(buf," INTEGER");    break;
  1612.     case real_:        strcat(buf," REAL");    break;
  1613.     case string_:        strcat(buf," STRING");    break;
  1614.     case binary_:        strcat(buf," BINARY");    break;
  1615.     case boolean_:        strcat(buf," BOOLEAN");    break;
  1616.     case logical_:        strcat(buf," LOGICAL");    break;
  1617.     case number_:        strcat(buf," NUMBER");    break;
  1618.     case entity_:        strcat(buf," ");
  1619.                 strcat(buf,PrettyTmpName (TYPEget_name(body->entity)));
  1620.                 break;
  1621.     case aggregate_:
  1622.     case array_:
  1623.     case bag_:
  1624.     case set_:
  1625.     case list_:
  1626.         switch (body->type) {
  1627.         /* ignore the aggregate bounds for now */
  1628.         case aggregate_:    strcat(buf," AGGREGATE OF");     break;
  1629.         case array_:        strcat(buf," ARRAY");
  1630.                     strcat_bounds(body,buf);
  1631.                     strcat(buf," OF");        break;
  1632.         case bag_:        strcat(buf," BAG");
  1633.                     strcat_bounds(body,buf);
  1634.                     strcat(buf," OF");        break;
  1635.         case set_:        strcat(buf," SET");
  1636.                     strcat_bounds(body,buf);
  1637.                     strcat(buf," OF");        break;
  1638.         case list_:        strcat(buf," LIST");
  1639.                     strcat_bounds(body,buf);
  1640.                     strcat(buf," of");        break;
  1641.         }
  1642.  
  1643.         Type_Description(body->base,buf);
  1644.         break;
  1645.     case enumeration_:
  1646.         strcat(buf," ENUMERATION of (");
  1647.         LISTdo(body->list,e,Expression)
  1648.             strcat(buf,ENUMget_name(e));
  1649.             strcat(buf,", ");
  1650.         LISTod
  1651.         /* find last comma and replace with ')' */
  1652.         s = strrchr(buf,',');
  1653.         if (s) strcpy(s,")");
  1654.         break;
  1655.  
  1656.     case select_:
  1657.         strcat(buf," SELECT of (");
  1658.         LISTdo (body->list, t, Type)  
  1659.           strcat (buf, PrettyTmpName (TYPEget_name(t)) );
  1660.           strcat(buf,", ");
  1661.             LISTod
  1662.         /* find last comma and replace with ')' */
  1663.         s = strrchr(buf,',');
  1664.         if (s) strcpy(s,")");
  1665.         break;
  1666.     default:        strcat(buf," UNKNOWN");
  1667.     }
  1668.  
  1669.     if (body->precision) {
  1670.         strcat(buf," (");
  1671.         strcat_expr(body->precision,buf);
  1672.         strcat(buf,")");
  1673.     }
  1674.     if (body->flags.fixed)    strcat(buf," FIXED"); 
  1675.     return buf;
  1676. }
  1677.  
  1678. char *
  1679. Type_Description(const Type t,char *buf)
  1680. {
  1681.     if (TYPEget_name(t)) {
  1682.         strcat(buf," ");    
  1683.         strcat(buf,PrettyTmpName (TYPEget_name(t)));
  1684.     } else {
  1685.         TypeBody_Description(TYPEget_body(t),buf);
  1686.     } 
  1687.     return buf;
  1688. }
  1689.  
  1690. /******************************************************************
  1691.  ** Procedure:  TYPEprint_typedefs
  1692.  ** Parameters:  const Type type
  1693.  ** Returns:  
  1694.  ** Description:  prints in header file typedefs for user defined types
  1695.  ** Side Effects:  
  1696.  ** Status:  16-Mar-1993 kcm
  1697.  ******************************************************************/
  1698. void
  1699. TYPEprint_typedefs (Type t, FILE* f)  
  1700. {
  1701.   Class_Of_Type class;
  1702.   char base [BUFSIZ]  ;
  1703.   char nm [BUFSIZ]  ;
  1704.  
  1705.   strncpy (nm, ClassName (TYPEget_name (t)), BUFSIZ);
  1706.   
  1707.   /*  do selects by themselves  */
  1708.   if  (TYPEis_select (t) ) 
  1709.     return;
  1710.  
  1711.   if (TYPEis_enumeration (t))  
  1712.     if ( TYPEget_head(t) )  {
  1713.       /*  print the typedef for the enumeration class  */
  1714.       strncpy (base, ClassName (TYPEget_name(TYPEget_head(t))), BUFSIZ);
  1715.       fprintf (f, "typedef %s \t%s;\n", base, nm);
  1716.  
  1717.       /*  print the typedef for the enumeration type  */
  1718.       strncpy (base, EnumName (TYPEget_name(TYPEget_head(t))), BUFSIZ);
  1719.       strncpy (nm, EnumName (TYPEget_name (t)), BUFSIZ);
  1720.       fprintf (f, "typedef %s \t%s;\n", base, nm);
  1721.       return;
  1722.     }  else 
  1723.       return;
  1724.  
  1725.     /* do the rest of the user defined types */
  1726.     fprintf (f, "typedef %s \t%s;\n", TYPEget_ctype (t), nm);
  1727.  
  1728.   if (TYPEis_aggregate (t) ) {
  1729.     fprintf (f, "typedef %s * \t%sH;\n", nm, nm);
  1730.     return;
  1731.   }
  1732.  
  1733. }
  1734.  
  1735. void
  1736. TYPEprint_descriptions (const Type type, FILES* files, Schema schema)
  1737. {
  1738.   Class_Of_Type class;
  1739.   char tdnm [BUFSIZ];
  1740.  
  1741.   strncpy (tdnm, TYPEtd_name (type, schema), BUFSIZ);
  1742.  
  1743.   /* define type descriptor pointer */
  1744.   /*  in header for external use  */
  1745.   fprintf(files->inc,"extern %sTypeDescriptor \t*%s;\n",
  1746.       (TYPEis_select (type) ? "Select" : ""), 
  1747.       tdnm);
  1748.  
  1749.   /*  in source - declare the real definition of the pointer   */
  1750.   fprintf(files -> lib,"%sTypeDescriptor \t*%s;\n",
  1751.       (TYPEis_select (type) ? "Select" : ""), 
  1752.       tdnm);
  1753.  
  1754.   /* fill in it's values    */
  1755.   /*  in the SchemaInit function - already declared with basic values  */
  1756.   if (TYPEget_head(type)) {
  1757.     if (!streq("",TYPEget_name(type))) {
  1758.       /* type ref with name */
  1759. /*      if (!TYPEget_head( TYPEget_head(type) ) ) */
  1760. /*      if (TYPEget_head( TYPEget_head(type) ) ) */
  1761.     fprintf(files->init,
  1762.         "\t%s->ReferentType (%s%s%s);\n",
  1763.         tdnm, 
  1764.         SCHEMAget_name(owning_schema(TYPEget_name(TYPEget_head(type)),schema)),
  1765.         TYPEprefix (type), TYPEget_name(TYPEget_head(type)));
  1766.     } else if (streq("",TYPEget_name(type))) {
  1767.       /* no name, recurse */
  1768.       char callee_buffer[MAX_LEN];
  1769.       print_typechain(files -> init, TYPEget_head(type), callee_buffer,schema);
  1770.       fprintf(files->init,"    %s->ReferentType(%s);\n",
  1771.           tdnm, callee_buffer);
  1772.     }
  1773.   } else if (TYPEget_body(type)->type == enumeration_) {
  1774.     TYPEenum_inc_print (type, files -> inc);
  1775.     TYPEenum_lib_print (type, files -> lib);
  1776.   } else if (TYPEget_body(type)->type == select_) {
  1777.  
  1778.     /*  the select definitions are done seperately, since they depend on the others  */
  1779. /*******
  1780.   TYPEselect_inc_print (type, files -> inc);
  1781.   TYPEselect_lib_print (type, files -> lib);
  1782. *******/
  1783.  
  1784.   } else if (TYPEis_builtin(type)) {
  1785.     fprintf(files->init,"    %s->ReferentType(%s%s);\n",
  1786.         tdnm, TD_PREFIX,FundamentalType(type,0));
  1787.  
  1788.   } else if (TYPEget_body(type)->type == entity_) {
  1789.     fprintf(files->init,"    %s->ReferentType (%s);\n",
  1790.         tdnm,
  1791.         /* following assumes we are not in a nested entity */
  1792.         /* otherwise we should search upward for schema */
  1793.         TYPEtd_name (type, TYPEget_body(type)->entity->superscope));
  1794.   }
  1795.  
  1796.   /* insert into type dictionary */
  1797.   fprintf(files->init,"\treg.AddType (*%s);\n", tdnm);
  1798. }
  1799.  
  1800. void
  1801. TYPEprint_new (const Type type, FILES* files, Schema schema)
  1802. {
  1803.   /* define type definition */
  1804.   /*  in source - the real definition of the TypeDescriptor   */
  1805.   FILE * f = files->init;
  1806.  
  1807.   if( TYPEis_select(type) )
  1808.     fprintf(f,"\t%s = new SelectTypeDescriptor (\n\t\t  %d,\t//unique elements,\n",
  1809.         TYPEtd_name (type, schema),
  1810.         ! any_duplicates_in_select (SEL_TYPEget_items(type)) );
  1811.   else 
  1812.     fprintf(f,"\t%s = new TypeDescriptor (\n",
  1813.         TYPEtd_name (type, schema));
  1814.  
  1815.   /* fill in it's values    */
  1816.   fprintf(f,"\t\t  \"%s\",\t// Name\n",
  1817.       PrettyTmpName (TYPEget_name(type)));
  1818.   fprintf(f,"\t\t  %s,\t// FundamentalType\n",
  1819.       FundamentalType(type,1));
  1820.   fprintf(f,"\t\t  \"%s\");\t// Description\n",
  1821.       TypeDescription(type));
  1822.  
  1823. }
  1824.