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 / SCL.EXE / AGGREGAT.CPP next >
C/C++ Source or Header  |  1994-08-29  |  42KB  |  1,739 lines

  1.  
  2. /*
  3. * NIST STEP Core Class Library
  4. * clstepcore/STEPaggregate.cc
  5. * February, 1994
  6. * K. C. Morris
  7. * David Sauder
  8.  
  9. * Development of this software was funded by the United States Government,
  10. * and is not subject to copyright.
  11. */
  12.  
  13. /* $Id: STEPaggregate.cc,v 2.0.1.2 1994/04/05 16:39:22 sauderd Exp $ */
  14.  
  15. #include <stdio.h> 
  16.  
  17. #include <read_func.h>
  18. #include <aggregat.h>
  19. #include <attribut.h>
  20. #include <sentity.h>
  21. #include <instmgr.h>
  22.  
  23. #define STRING_DELIM '\''
  24.  
  25. static char rcsid[] = "$Id: STEPaggregate.cc,v 2.0.1.2 1994/04/05 16:39:22 sauderd Exp $";
  26.  
  27. /******************************************************************
  28. **      Functions for manipulating aggregate attributes
  29.  
  30. **  KNOWN BUGs:  
  31. **     -- treatment of aggregates of reals or ints is inconsistent with
  32. **        other aggregates (there's no classes for these)
  33. **     -- no two- dimensional aggregates are implemented
  34. **/
  35.  
  36. STEPaggregate NilSTEPaggregate;
  37.  
  38.  
  39. ///////////////////////////////////////////////////////////////////////////////
  40. // STEPaggregate
  41. ///////////////////////////////////////////////////////////////////////////////
  42.  
  43. STEPaggregate::STEPaggregate  ()  
  44. {
  45.     _null = 1;
  46. }
  47.  
  48. STEPaggregate::~STEPaggregate  ()  
  49. {
  50. }
  51.  
  52. STEPaggregate& 
  53. STEPaggregate::ShallowCopy (const STEPaggregate& a) 
  54. {
  55.   cerr << "Internal error:  " << __FILE__ << ": " <<  __LINE__
  56.        << "\n" << _POC_ "\n";
  57.   cerr << "function:  STEPaggregate::ShallowCopy \n" << "\n";
  58.   return *this;
  59. }
  60.  
  61.     // do not require exchange file format
  62. Severity 
  63. STEPaggregate::AggrValidLevel(const char *value, ErrorDescriptor *err, 
  64.                   const TypeDescriptor *elem_type, InstMgr *insts, 
  65.                   int optional, char *tokenList, int addFileId, 
  66.                   int clearError)
  67. {
  68.     if(clearError)
  69.     err->ClearErrorMsg();
  70.  
  71.     istrstream in ((char *)value); // sz defaults to length of s
  72.  
  73.     ReadValue(in, err, elem_type, insts, addFileId, 0, 0);
  74.     CheckRemainingInput(in, err, elem_type->AttrTypeName(), tokenList);
  75.     if( optional && (err->severity() == SEVERITY_INCOMPLETE) )
  76.     err->severity(SEVERITY_NULL);
  77.     return err->severity();
  78. }
  79.  
  80.     // require exchange file format
  81. Severity 
  82. STEPaggregate::AggrValidLevel(istream &in, ErrorDescriptor *err, 
  83.                   const TypeDescriptor *elem_type, InstMgr *insts, 
  84.                   int optional, char *tokenList, int addFileId, 
  85.                   int clearError)
  86. {
  87.     if(clearError)
  88.     err->ClearErrorMsg();
  89.  
  90.     ReadValue(in, err, elem_type, insts, addFileId, 0, 1);
  91.     CheckRemainingInput(in, err, elem_type->AttrTypeName(), tokenList);
  92.     if( optional && (err->severity() == SEVERITY_INCOMPLETE) )
  93.     err->severity(SEVERITY_NULL);
  94.     return err->severity();
  95. }
  96.  
  97. // if exchangeFileFormat == 1 then paren delims are required.
  98.  
  99. Severity 
  100. STEPaggregate::ReadValue(istream &in, ErrorDescriptor *err, 
  101.              const TypeDescriptor *elem_type, 
  102.              InstMgr *insts, int addFileId, 
  103.              int assignVal, int exchangeFileFormat)
  104. {
  105.     ErrorDescriptor errdesc;
  106.     char errmsg[BUFSIZ];
  107.     int value_cnt = 0;
  108.  
  109.     if(assignVal)
  110.     Empty ();  // read new values and discard existing ones
  111.  
  112.     char c;
  113.     int validDelims = 1;
  114.  
  115.     in >> ws; // skip white space
  116.  
  117.     c = in.peek(); // does not advance input
  118.  
  119.     if(in.eof() || c == '$')
  120.     {
  121.     _null = 1;
  122.     err->GreaterSeverity(SEVERITY_INCOMPLETE);
  123.     return SEVERITY_INCOMPLETE;
  124.     }
  125.  
  126.     if(c == '(')
  127.     {
  128.     in.get(c);
  129.     validDelims = 0; // signal expectation for end paren delim
  130.     }
  131.     else if(exchangeFileFormat)
  132.     {    // error did not find opening delim
  133.         // cannot recover so give up and let STEPattribute recover
  134.     err->GreaterSeverity(SEVERITY_INPUT_ERROR);
  135.     return SEVERITY_INPUT_ERROR;
  136.     }
  137.     else if(!in.good())
  138.     {// this should actually have been caught by skipping white space above
  139.     err->GreaterSeverity(SEVERITY_INCOMPLETE);
  140.     return SEVERITY_INCOMPLETE;
  141.     }
  142.  
  143.     STEPnode * item = 0;
  144.     if(!assignVal)  // if not assigning values only need one node.  So only 
  145.             // one node is created. It is used to read the values
  146.     item = (STEPnode*)NewNode();
  147.  
  148.     // ')' is the end of the aggregate
  149.     while (in.good() && (c != ')') )
  150.     {
  151.     value_cnt++;
  152.     if(assignVal) // create a new node each time through the loop
  153.         item = (STEPnode*)NewNode();
  154.  
  155.     errdesc.ClearErrorMsg();
  156.  
  157.     if(exchangeFileFormat)
  158.         item->STEPread(in, &errdesc);
  159.     else
  160.         item->StrToVal(in, &errdesc);
  161.  
  162.     // read up to the next delimiter and set errors if garbage is
  163.     // found before specified delims (i.e. comma and quote)
  164.     CheckRemainingInput(in, &errdesc, elem_type->AttrTypeName(), ",)");
  165.  
  166.     if (errdesc.severity() < SEVERITY_INCOMPLETE)
  167.     {
  168.         sprintf (errmsg, "  index:  %d\n", value_cnt );
  169.         errdesc.PrependToDetailMsg(errmsg);
  170.         err->AppendToDetailMsg(errdesc.DetailMsg());
  171.         err->AppendToUserMsg(errdesc.UserMsg());
  172.     }
  173.     if(assignVal) // pass the node to STEPaggregate
  174.         AddNode (item);
  175.  
  176.     in >> ws; // skip white space (although should already be skipped)
  177.     in.get(c); // read delim
  178.  
  179.     // CheckRemainingInput should have left the input right at the delim
  180.     // so that it would be read in in.get() above.  Since it did not find
  181.     // the delim this does not know how to find it either!
  182.     if( (c != ',') && (c != ')') )
  183.     {
  184.         // cannot recover so give up and let STEPattribute recover
  185.         err->GreaterSeverity(SEVERITY_INPUT_ERROR);
  186.         return SEVERITY_INPUT_ERROR;
  187. /*
  188.         // error read until you find a delimiter
  189.         SCLstring tmp;
  190.         while(in.good() && !strchr(",)", c) )
  191.         {
  192.         in.get(c);
  193.         tmp.Append(c);
  194.         }
  195.         // BUG could overwrite the error message buffer
  196.         sprintf(errmsg, "ERROR aggr. elem. followed by \'%s\' garbage.\n",
  197.             tmp.chars());
  198.         err->AppendToDetailMsg(errmsg);
  199.         err->AppendToUserMsg(errmsg);
  200.         err->GreaterSeverity(SEVERITY_WARNING);
  201.         if(!in.good())
  202.         return err->severity();
  203. */
  204.     }
  205.     }
  206.     return err->severity();
  207. }
  208.  
  209. Severity 
  210. STEPaggregate::StrToVal(const char *s, ErrorDescriptor *err, 
  211.             const TypeDescriptor *elem_type, InstMgr *insts, 
  212.             int addFileId)
  213. {
  214.     istrstream in((char *)s);
  215.     return ReadValue(in, err, elem_type, insts, addFileId, 1, 0);
  216. }
  217.  
  218. ///////////////////////////////////////////////////////////////////////////////
  219.  
  220. Severity 
  221. STEPaggregate::STEPread(istream& in, ErrorDescriptor *err, 
  222.             const TypeDescriptor *elem_type, 
  223.             InstMgr *insts, int addFileId)
  224. {
  225.     return ReadValue(in, err, elem_type, insts, addFileId, 1, 1);
  226. }
  227.  
  228. const char * 
  229. STEPaggregate::asStr(SCLstring & s) const
  230. {
  231.     s.set_null();
  232.  
  233.     if(!_null)
  234.     {
  235.     s = "(";
  236.     STEPnode * n = (STEPnode *) head;
  237.     SCLstring tmp;
  238.     while (n)
  239.     {
  240.         s.Append( n->STEPwrite(tmp) );
  241.         if (n = (STEPnode *) n -> NextNode ())
  242.         s.Append(',');
  243.     }
  244.     s.Append(')');
  245.     }
  246.     return s.chars();
  247. }
  248.  
  249. void
  250. STEPaggregate::STEPwrite(ostream& out) const
  251. {
  252.     if(!_null)
  253.     {
  254.     out << '(';
  255.     STEPnode * n = (STEPnode *)head;
  256.     SCLstring s;
  257.     while (n)  
  258.     {
  259.         out << n->STEPwrite (s);
  260.         if ( n = (STEPnode *)(n -> NextNode ()) )
  261.         out <<  ',';
  262.     }
  263.     out << ')';
  264.     }
  265.     else
  266.     out << '$';
  267. }
  268.  
  269. SingleLinkNode *
  270. STEPaggregate::NewNode () 
  271. {
  272.   cerr << "Internal error:  " << __FILE__ << ": " <<  __LINE__ << "\n" ;
  273.   cerr << "function:  STEPaggregate::NewNode \n" << _POC_ << "\n";
  274.   return 0;
  275. }
  276.  
  277. void
  278. STEPaggregate::AddNode(SingleLinkNode *n)
  279. {
  280.     SingleLinkList::AppendNode(n);
  281.     _null = 0;
  282. }
  283.  
  284. void
  285. STEPaggregate::Empty()
  286. {
  287.     SingleLinkList::Empty();
  288.     _null = 1;
  289. }
  290.  
  291.  
  292. ///////////////////////////////////////////////////////////////////////////////
  293. // STEPnode
  294. ///////////////////////////////////////////////////////////////////////////////
  295.  
  296. Severity
  297. STEPnode::StrToVal(const char *s, ErrorDescriptor *err)
  298. {
  299.     // defined in subtypes
  300.   cerr << "Internal error:  " << __FILE__ << ": " <<  __LINE__ << "\n" ;
  301.     err->AppendToDetailMsg(
  302.     " function: STEPnode::StrToVal() called instead of virtual function.\n"
  303.                );
  304.     err->AppendToDetailMsg("Aggr. attr value: '\n");
  305.     err->AppendToDetailMsg("not assigned.\n");
  306.     err->AppendToDetailMsg(_POC_);
  307.     err->GreaterSeverity(SEVERITY_BUG);
  308.     return SEVERITY_BUG;
  309. }
  310.  
  311. Severity
  312. STEPnode::StrToVal(istream &in, ErrorDescriptor *err)
  313. {
  314.     // defined in subtypes
  315.   cerr << "Internal error:  " << __FILE__ << ": " <<  __LINE__ << "\n" ;
  316.     err->AppendToDetailMsg(
  317.     " function: STEPnode::StrToVal() called instead of virtual function.\n"
  318.                );
  319.     err->AppendToDetailMsg("Aggr. attr value: '\n");
  320.     err->AppendToDetailMsg("not assigned.\n");
  321.     err->AppendToDetailMsg(_POC_);
  322.     err->GreaterSeverity(SEVERITY_BUG);
  323.     return SEVERITY_BUG;
  324. }
  325.  
  326. Severity 
  327. STEPnode::STEPread(const char *s, ErrorDescriptor *err)
  328. {
  329.     //  defined in subclasses
  330.   cerr << "Internal error:  " << __FILE__ << ": " <<  __LINE__ << "\n" ;
  331.   cerr << "function:  STEPnode::STEPread called instead of virtual function.\n"
  332.        << _POC_ << "\n";
  333.  
  334.     err->AppendToDetailMsg(
  335.     " function: STEPnode::STEPread() called instead of virtual function.\n"
  336.                );
  337.     err->AppendToDetailMsg(_POC_);
  338.     err->GreaterSeverity(SEVERITY_BUG);
  339.  
  340.     return SEVERITY_BUG;
  341. }
  342.  
  343. Severity 
  344. STEPnode::STEPread(istream &in, ErrorDescriptor *err)
  345. {
  346.   cerr << "Internal error:  " << __FILE__ << ": " <<  __LINE__ << "\n" ;
  347.   cerr << "function:  STEPnode::STEPread called instead of virtual function.\n"
  348.        << _POC_ << "\n";
  349.  
  350.     err->AppendToDetailMsg(
  351.     " function: STEPnode::STEPread() called instead of virtual function.\n"
  352.                );
  353.     err->AppendToDetailMsg(_POC_);
  354.     err->GreaterSeverity(SEVERITY_BUG);
  355.     return SEVERITY_BUG;
  356. }
  357.  
  358. const char *
  359. STEPnode::asStr(SCLstring &s)
  360. {
  361.     //  defined in subclasses
  362.   cerr << "Internal error:  " << __FILE__ << ": " <<  __LINE__ << "\n" ;
  363.   cerr << "function:  STEPnode::asStr called instead of virtual function.\n" 
  364.        << _POC_ << "\n";
  365.  
  366.   return "";
  367. }
  368.  
  369. const char *
  370. STEPnode::STEPwrite (SCLstring &s)
  371. {
  372.   cerr << "Internal error:  " << __FILE__ << ": " <<  __LINE__ << "\n" ;
  373.  cerr << "function:  STEPnode::STEPwrite called instead of virtual function.\n"
  374.       << _POC_ << "\n";
  375.  
  376.  return "";
  377. }
  378.  
  379. void 
  380. STEPnode::STEPwrite (ostream& out)
  381. {
  382.   cerr << "Internal error:  " << __FILE__ << ": " <<  __LINE__ << "\n" ;
  383.  cerr << "function:  STEPnode::STEPwrite called instead of virtual function.\n"
  384.        << _POC_ << "\n";
  385. }
  386.  
  387. ///////////////////////////////////////////////////////////////////////////////
  388. // GenericAggregate
  389. ///////////////////////////////////////////////////////////////////////////////
  390.  
  391. SingleLinkNode *
  392. GenericAggregate::NewNode () 
  393. {
  394.     return new GenericAggrNode();
  395. }
  396.  
  397. STEPaggregate& 
  398. GenericAggregate::ShallowCopy (const STEPaggregate& a)
  399. {
  400.     Empty();
  401.     
  402.     SingleLinkNode* next = a.GetHead();
  403.     SingleLinkNode* copy;
  404.  
  405.     while (next) 
  406.     {
  407.     copy = new GenericAggrNode (*(GenericAggrNode*)next);
  408.     AddNode(copy);
  409.     next = next->NextNode();
  410.     }
  411.     if(head)
  412.     _null = 0;
  413.     else
  414.     _null = 1;
  415.     return *this;
  416.     
  417. }
  418.  
  419. ///////////////////////////////////////////////////////////////////////////////
  420. // GenericAggrNode
  421. ///////////////////////////////////////////////////////////////////////////////
  422.  
  423. GenericAggrNode::GenericAggrNode (const char *str)
  424. {  
  425.     value = str;
  426. };
  427.  
  428. GenericAggrNode::GenericAggrNode (GenericAggrNode& gan)
  429. {  
  430.     value = gan.value;
  431. };
  432.  
  433. GenericAggrNode::GenericAggrNode()
  434. {
  435. }
  436.  
  437. GenericAggrNode::~GenericAggrNode()
  438. {
  439. }
  440.  
  441. SingleLinkNode *
  442. GenericAggrNode::NewNode () 
  443. {
  444.     return new GenericAggrNode();
  445. }
  446.  
  447. Severity 
  448. GenericAggrNode::StrToVal(const char *s, ErrorDescriptor *err)
  449. {
  450.     return value.STEPread(s, err);
  451. }
  452.  
  453. //TODO
  454. Severity 
  455. GenericAggrNode::StrToVal(istream &in, ErrorDescriptor *err)
  456. {
  457.     return value.STEPread(in, err);
  458. }
  459.  
  460. Severity 
  461. GenericAggrNode::STEPread(const char *s, ErrorDescriptor *err)
  462. {
  463.     istrstream in((char *) s);
  464.     return value.STEPread(in, err);
  465. }
  466.  
  467. Severity 
  468. GenericAggrNode::STEPread(istream &in, ErrorDescriptor *err)
  469. {
  470.     return value.STEPread(in, err);
  471. }
  472.  
  473. const char *
  474. GenericAggrNode::asStr(SCLstring &s)  
  475. {
  476.     s.set_null();
  477.     value.asStr(s);
  478.     return s.chars();
  479. }
  480.  
  481. const char *
  482. GenericAggrNode::STEPwrite(SCLstring &s)
  483. {
  484.     return value.STEPwrite(s);
  485. /*
  486. // CHECK do we write dollar signs for nulls within an aggregate? DAS
  487.     if(_value)
  488.     return (const char *)_value;
  489.     else
  490.     return "$";
  491. */
  492. }
  493.  
  494. void
  495. GenericAggrNode::STEPwrite (ostream& out)
  496. {
  497.     value.STEPwrite(out);
  498. }
  499.  
  500. ///////////////////////////////////////////////////////////////////////////////
  501. // EntityAggregate
  502. ///////////////////////////////////////////////////////////////////////////////
  503.  
  504. EntityAggregate::EntityAggregate () 
  505. {
  506. }
  507.  
  508. EntityAggregate::~EntityAggregate ()
  509. {
  510. //    delete v;
  511. }
  512.  
  513.  
  514. // if exchangeFileFormat == 1 then delims are required.
  515.  
  516. Severity 
  517. EntityAggregate::ReadValue(istream &in, ErrorDescriptor *err, 
  518.              const TypeDescriptor *elem_type, 
  519.              InstMgr *insts, int addFileId, 
  520.              int assignVal, int exchangeFileFormat)
  521. {
  522.     ErrorDescriptor errdesc;
  523.     char errmsg[BUFSIZ];
  524.     int value_cnt = 0;
  525.  
  526.     if(assignVal)
  527.     Empty ();  // read new values and discard existing ones
  528.  
  529.     char c;
  530.     int validDelims = 1;
  531.  
  532.     in >> ws; // skip white space
  533.  
  534.     c = in.peek(); // does not advance input
  535.  
  536.     if(in.eof() || (c == '$') )
  537.     {
  538.     _null = 1;
  539.     err->GreaterSeverity(SEVERITY_INCOMPLETE);
  540.     return SEVERITY_INCOMPLETE;
  541.     }
  542.  
  543.     if(c == '(')
  544.     {
  545.     in.get(c);
  546.     validDelims = 0; // signal expectation for end delim
  547.     }
  548.     else if(exchangeFileFormat)
  549.     {    // error did not find opening delim
  550.     // give up because you do not know where to stop reading.
  551.     err->GreaterSeverity(SEVERITY_INPUT_ERROR);
  552.     return SEVERITY_INPUT_ERROR;
  553.     }
  554.     else if(!in.good())
  555.     {// this should actually have been caught by skipping white space above
  556.     err->GreaterSeverity(SEVERITY_INCOMPLETE);
  557.     return SEVERITY_INCOMPLETE;
  558.     }
  559.  
  560.     EntityNode * item = 0;
  561.     if(!assignVal)  // if not assigning values only need one node.  So only 
  562.             // one node is created. It is used to read the values
  563.     item = new EntityNode();
  564.  
  565.     while (in.good() && (c != ')') )
  566.     {
  567.     value_cnt++;
  568.     if(assignVal) // create a new node each time through the loop
  569.         item = new EntityNode();
  570.  
  571.     errdesc.ClearErrorMsg();
  572.  
  573.     if(exchangeFileFormat)
  574.         item->STEPread(in, &errdesc, elem_type, insts, addFileId);
  575.     else
  576.         item->StrToVal(in, &errdesc, elem_type, insts, addFileId);
  577.  
  578.     // read up to the next delimiter and set errors if garbage is
  579.     // found before specified delims (i.e. comma and quote)
  580.     CheckRemainingInput(in, &errdesc, elem_type->AttrTypeName(), ",)");
  581.  
  582.     if (errdesc.severity() < SEVERITY_INCOMPLETE)
  583.     {
  584.         sprintf (errmsg, "  index:  %d\n", value_cnt );
  585.         errdesc.PrependToDetailMsg(errmsg);
  586.         err->AppendToDetailMsg(errdesc.DetailMsg());
  587.         err->AppendToUserMsg(errdesc.UserMsg());
  588.     }
  589.     if(assignVal)
  590.         AddNode (item);
  591.  
  592.     in >> ws; // skip white space (although should already be skipped)
  593.     in.get(c); // read delim
  594.  
  595.     // CheckRemainingInput should have left the input right at the delim
  596.     // so that it would be read in in.get() above.  Since it did not find
  597.     // the delim this does not know how to find it either!
  598.     if( (c != ',') && (c != ')') )
  599.     {
  600.         // cannot recover so give up and let STEPattribute recover
  601.         err->GreaterSeverity(SEVERITY_INPUT_ERROR);
  602.         return SEVERITY_INPUT_ERROR;
  603. /*
  604.         // error read until you find a delimiter
  605.         SCLstring tmp;
  606.         while(in.good() && !strchr(",)", c) )
  607.         {
  608.         in.get(c);
  609.         tmp.Append(c);
  610.         }
  611.         // BUG could overwrite the error message buffer
  612.         sprintf(errmsg, "ERROR aggr. elem. followed by \'%s\' garbage.\n",
  613.             tmp.chars());
  614.         err->AppendToDetailMsg(errmsg);
  615.         err->AppendToUserMsg(errmsg);
  616.         err->GreaterSeverity(SEVERITY_WARNING);
  617.         if(!in.good())
  618.         return err->severity();
  619. */
  620.     }
  621.     }
  622.     return err->severity();
  623. }
  624.  
  625.  
  626. STEPaggregate& 
  627. EntityAggregate::ShallowCopy (const STEPaggregate& a)  
  628. {
  629.     const EntityNode * tmp = (const EntityNode*) a.GetHead ();
  630.     while (tmp) 
  631.     {
  632.     AddNode (new EntityNode (tmp -> node));
  633.     tmp = (const EntityNode*) tmp -> NextNode ();
  634.     }
  635.     if(head)
  636.     _null = 0;
  637.     else
  638.     _null = 1;
  639.  
  640.     return *this;
  641. }
  642.  
  643.  
  644. SingleLinkNode *    
  645. EntityAggregate::NewNode ()  
  646. {
  647.     return new EntityNode ();
  648. }
  649.  
  650. ///////////////////////////////////////////////////////////////////////////////
  651. // EntityNode
  652. ///////////////////////////////////////////////////////////////////////////////
  653.  
  654. EntityNode::EntityNode  (STEPentity * e) : node (e) 
  655. {
  656. }
  657.  
  658. SingleLinkNode *    
  659. EntityNode::NewNode ()  
  660. {
  661.     return new EntityNode ();
  662. }
  663. ///////////////////////////////////////////////////////////////////////////////
  664.  
  665. Severity 
  666. EntityNode::StrToVal(const char *s, ErrorDescriptor *err, 
  667.              const TypeDescriptor *elem_type,
  668.              InstMgr *insts, int addFileId)
  669. {
  670. //    STEPentity *se = ReadEntityRef(s, err, ",)", insts, addFileId);
  671.     STEPentity *se = ReadEntityRef(s, err, 0, insts, addFileId);
  672.     if( se != S_ENTITY_NULL )
  673.     {
  674.     ErrorDescriptor error;
  675.     if(EntityValidLevel(se, elem_type, &error) == SEVERITY_NULL)
  676.         node = se;
  677.     else
  678.     {
  679.         node = S_ENTITY_NULL;
  680.         err->AppendToDetailMsg(error.DetailMsg());
  681.         err->AppendToUserMsg(error.UserMsg());
  682.         err->GreaterSeverity(error.severity());
  683.     }
  684.     }
  685.     else
  686.     node = S_ENTITY_NULL;
  687.     return err->severity();
  688. }
  689.  
  690. Severity 
  691. EntityNode::StrToVal(istream &in, ErrorDescriptor *err, 
  692.              const TypeDescriptor *elem_type,
  693.              InstMgr *insts, int addFileId)
  694. {
  695.     return STEPread(in, err, elem_type, insts, addFileId);
  696. }
  697.  
  698. Severity 
  699. EntityNode::STEPread(const char *s, ErrorDescriptor *err, 
  700.              const TypeDescriptor *elem_type, 
  701.              InstMgr *insts, int addFileId)
  702. {
  703.     istrstream in((char *)s);
  704.     return STEPread(in, err, elem_type, insts, addFileId);
  705. }
  706.  
  707. Severity 
  708. EntityNode::STEPread(istream &in, ErrorDescriptor *err, 
  709.              const TypeDescriptor *elem_type,
  710.              InstMgr *insts, int addFileId)
  711. {
  712.     STEPentity *se = ReadEntityRef(in, err, ",)", insts, addFileId);
  713.     if( se != S_ENTITY_NULL )
  714.     {
  715.     ErrorDescriptor error;
  716.     if( EntityValidLevel(se, elem_type, &error) == SEVERITY_NULL )
  717.         node = se;
  718.     else
  719.     {
  720.         node = S_ENTITY_NULL;
  721.         err->AppendToDetailMsg(error.DetailMsg());
  722.         err->AppendToUserMsg(error.UserMsg());
  723.         err->GreaterSeverity(error.severity());
  724.     }
  725.     }
  726.     else
  727.     node = S_ENTITY_NULL;
  728. //    CheckRemainingInput(in, err, "enumeration", ",)");
  729.     return err->severity();
  730. }
  731.  
  732. const char *
  733. EntityNode::asStr (SCLstring &s)  
  734. {
  735.     s.set_null();
  736.     if (!node || (node == S_ENTITY_NULL))     //  nothing
  737.     return "";
  738.     else // otherwise return entity id
  739.     {
  740.     char tmp [64];
  741.     sprintf(tmp, "#%d", node->STEPfile_id);
  742.     s = tmp;
  743.     }
  744.     return s.chars();
  745. }    
  746.  
  747. const char *
  748. EntityNode::STEPwrite(SCLstring &s)
  749. {
  750.     if (!node || (node == S_ENTITY_NULL) )     //  nothing
  751.     {
  752.     s = "$";
  753.     return s.chars();
  754.     }
  755.     asStr(s);
  756.     return s.chars();
  757. }
  758.  
  759. void 
  760. EntityNode::STEPwrite(ostream& out)
  761. {
  762.     if (!node || (node == S_ENTITY_NULL))     //  nothing
  763.       out << "$";
  764.     SCLstring s;
  765.     out << asStr(s);
  766. }
  767.  
  768.  
  769. ///////////////////////////////////////////////////////////////////////////////
  770. // SelectAggregate
  771. ///////////////////////////////////////////////////////////////////////////////
  772.  
  773. SelectAggregate::SelectAggregate () 
  774. {
  775. }
  776.  
  777. SelectAggregate::~SelectAggregate ()
  778. {
  779. //    delete v;
  780. }
  781.  
  782.  
  783. // if exchangeFileFormat == 1 then delims are required.
  784.  
  785. Severity 
  786. SelectAggregate::ReadValue(istream &in, ErrorDescriptor *err, 
  787.                const TypeDescriptor *elem_type, 
  788.                InstMgr *insts, int addFileId, 
  789.                int assignVal, int exchangeFileFormat)
  790. {
  791.     ErrorDescriptor errdesc;
  792.     char errmsg[BUFSIZ];
  793.     int value_cnt = 0;
  794.  
  795.     if(assignVal)
  796.     Empty ();  // read new values and discard existing ones
  797.  
  798.     char c;
  799.     int validDelims = 1;
  800.  
  801.     in >> ws; // skip white space
  802.  
  803.     c = in.peek(); // does not advance input
  804.  
  805.     if(in.eof() || (c == '$') )
  806.     {
  807.     _null = 1;
  808.     err->GreaterSeverity(SEVERITY_INCOMPLETE);
  809.     return SEVERITY_INCOMPLETE;
  810.     }
  811.  
  812.     if(c == '(')
  813.     {
  814.     in.get(c);
  815.     validDelims = 0; // signal expectation for end delim
  816.     }
  817.     else if(exchangeFileFormat)
  818.     {    // error did not find opening delim
  819.     // give up because you do not know where to stop reading.
  820.     err->GreaterSeverity(SEVERITY_INPUT_ERROR);
  821.     return SEVERITY_INPUT_ERROR;
  822.     }
  823.     else if(!in.good())
  824.     {// this should actually have been caught by skipping white space above
  825.     err->GreaterSeverity(SEVERITY_INCOMPLETE);
  826.     return SEVERITY_INCOMPLETE;
  827.     }
  828.  
  829.     SelectNode * item = 0;
  830.     if(!assignVal)  // if not assigning values only need one node.  So only 
  831.             // one node is created. It is used to read the values
  832.     item = (SelectNode *) NewNode ();
  833.  
  834.     while (in.good() && (c != ')') )
  835.     {
  836.     value_cnt++;
  837.     if(assignVal) // create a new node each time through the loop
  838.       item = (SelectNode *) NewNode ();
  839.  
  840.     errdesc.ClearErrorMsg();
  841.  
  842.     if(exchangeFileFormat)
  843.         item->STEPread(in, &errdesc, elem_type, insts, addFileId);
  844.     else
  845.         item->StrToVal(in, &errdesc, elem_type, insts, addFileId);
  846.  
  847.     // read up to the next delimiter and set errors if garbage is
  848.     // found before specified delims (i.e. comma and quote)
  849.     CheckRemainingInput(in, &errdesc, elem_type->AttrTypeName(), ",)");
  850.  
  851.     if (errdesc.severity() < SEVERITY_INCOMPLETE)
  852.     {
  853.         sprintf (errmsg, "  index:  %d\n", value_cnt );
  854.         errdesc.PrependToDetailMsg(errmsg);
  855.         err->AppendFromErrorArg(&errdesc);
  856. //        err->AppendToDetailMsg(errdesc.DetailMsg());
  857. //        err->AppendToUserMsg(errdesc.UserMsg());
  858.     }
  859.     if(assignVal)
  860.         AddNode (item);
  861.  
  862.     in >> ws; // skip white space (although should already be skipped)
  863.     in.get(c); // read delim
  864.  
  865.     // CheckRemainingInput should have left the input right at the delim
  866.     // so that it would be read in in.get() above.  Since it did not find
  867.     // the delim this does not know how to find it either!
  868.     if( (c != ',') && (c != ')') )
  869.     {
  870.         // cannot recover so give up and let STEPattribute recover
  871.         err->GreaterSeverity(SEVERITY_INPUT_ERROR);
  872.         return SEVERITY_INPUT_ERROR;
  873.     }
  874.     }
  875.     return err->severity();
  876. }
  877.  
  878.  
  879. STEPaggregate& 
  880. SelectAggregate::ShallowCopy (const STEPaggregate& a)  
  881. {
  882.     const SelectNode * tmp = (const SelectNode*) a.GetHead ();
  883.     while (tmp) 
  884.     {
  885.     AddNode (new SelectNode (tmp -> node));
  886.     tmp = (const SelectNode*) tmp -> NextNode ();
  887.     }
  888.     if(head)
  889.     _null = 0;
  890.     else
  891.     _null = 1;
  892.  
  893.     return *this;
  894. }
  895.  
  896.  
  897. SingleLinkNode *    
  898. SelectAggregate::NewNode ()  
  899. {
  900.     return new SelectNode ();
  901. }
  902.  
  903. ///////////////////////////////////////////////////////////////////////////////
  904. // SelectNode
  905. ///////////////////////////////////////////////////////////////////////////////
  906.  
  907. SingleLinkNode *    
  908. SelectNode::NewNode ()  
  909. {
  910.     return new SelectNode ();
  911. }
  912. ///////////////////////////////////////////////////////////////////////////////
  913.  
  914. Severity 
  915. SelectNode::StrToVal(const char *s, ErrorDescriptor *err, 
  916.              const TypeDescriptor *elem_type,
  917.              InstMgr *insts, int addFileId)
  918. {
  919. /*
  920.     STEPentity *se = ReadEntityRef(s, err, 0, insts, addFileId);
  921.     if( se != S_ENTITY_NULL )
  922.     {
  923.     ErrorDescriptor error;
  924.     if(SelectValidLevel(se, elem_type, &error) == SEVERITY_NULL)
  925.         node = se;
  926.     else
  927.     {
  928.         node = S_ENTITY_NULL;
  929.         err->AppendToDetailMsg(error.DetailMsg());
  930.         err->AppendToUserMsg(error.UserMsg());
  931.         err->GreaterSeverity(error.severity());
  932.     }
  933.     }
  934.     else
  935.     node = S_ENTITY_NULL;
  936. */
  937.     // KC you will have to decide what to do here
  938.     istrstream in((char*)s);
  939.     if (err->severity( node->STEPread(in, err, insts) ) != SEVERITY_NULL)
  940.     err->AppendToDetailMsg (node ->Error ());
  941.     return err->severity();
  942. }
  943.  
  944. Severity 
  945. SelectNode::StrToVal(istream &in, ErrorDescriptor *err, 
  946.              const TypeDescriptor *elem_type,
  947.              InstMgr *insts, int addFileId)
  948. {
  949.     return STEPread(in, err, elem_type, insts, addFileId);
  950. }
  951.  
  952. Severity 
  953. SelectNode::STEPread(const char *s, ErrorDescriptor *err, 
  954.              const TypeDescriptor *elem_type, 
  955.              InstMgr *insts, int addFileId)
  956. {
  957.     istrstream in((char *)s);
  958.     return STEPread(in, err, elem_type, insts, addFileId);
  959. }
  960.  
  961. Severity 
  962. SelectNode::STEPread(istream &in, ErrorDescriptor *err, 
  963.              const TypeDescriptor *elem_type,
  964.              InstMgr *insts, int addFileId)
  965. {
  966.   if (!node)  {
  967.     cerr << "Internal error:  " << __FILE__ << ": " <<  __LINE__ << "\n" 
  968.      << _POC_ "\n";
  969.     cerr << "function:  SelectNode::STEPread \n" << "\n";
  970.     return SEVERITY_BUG;
  971.   }
  972.   err->severity( node->STEPread(in, err, insts, addFileId));
  973.   CheckRemainingInput(in, err, "select", ",)");
  974.   return err->severity();
  975. }
  976.  
  977. const char *
  978. SelectNode::asStr (SCLstring &s)  
  979. {
  980.     s.set_null();
  981.     if ( !node || (node->is_null()) )     //  nothing
  982.     return "";
  983.     else // otherwise return entity id
  984.     {
  985.       node -> STEPwrite (s);
  986.       return s.chars ();
  987.     }
  988. }    
  989.  
  990. const char *
  991. SelectNode::STEPwrite(SCLstring &s)
  992. {
  993.     s.set_null();
  994.     if ( !node || (node->is_null()) )     //  nothing
  995.     {
  996.     s = "$";
  997.     return "$";
  998.     }
  999.     node -> STEPwrite (s);
  1000.     return s.chars();
  1001. }
  1002.  
  1003. void 
  1004. SelectNode::STEPwrite(ostream& out)
  1005. {
  1006.     if ( !node || (node->is_null()) )     //  nothing
  1007.       out << "$";
  1008.     SCLstring s;
  1009.     out << asStr(s);
  1010. }
  1011.  
  1012. ///////////////////////////////////////////////////////////////////////////////
  1013. // StringAggregate
  1014. ///////////////////////////////////////////////////////////////////////////////
  1015.  
  1016. /******************************************************************
  1017. STEPaggregate& 
  1018. StringAggregate::ShallowCopy (const STEPaggregate&);
  1019. ******************************************************************/
  1020.  
  1021. STEPaggregate& 
  1022. StringAggregate::ShallowCopy (const STEPaggregate& a)
  1023. {
  1024.     Empty();
  1025.     
  1026.     SingleLinkNode* next = a.GetHead();
  1027.     SingleLinkNode* copy;
  1028.  
  1029.     while (next) 
  1030.     {
  1031.     copy = new StringNode (*(StringNode*)next);
  1032.     AddNode(copy);
  1033.     next = next->NextNode();
  1034.     }
  1035.     if(head)
  1036.     _null = 0;
  1037.     else
  1038.     _null = 1;
  1039.     return *this;
  1040.     
  1041. }
  1042.  
  1043. SingleLinkNode *
  1044. StringAggregate::NewNode () 
  1045. {
  1046.     return new StringNode ();
  1047. }
  1048.  
  1049. ///////////////////////////////////////////////////////////////////////////////
  1050. // StringNode
  1051. ///////////////////////////////////////////////////////////////////////////////
  1052.  
  1053. StringNode::StringNode(StringNode& sn)
  1054. {
  1055.     value = sn.value.chars();
  1056. }
  1057.  
  1058. StringNode::StringNode(const char * sStr)
  1059. {
  1060.     // value is an SdaiString (the memory is copied)
  1061.     value = sStr;
  1062.  
  1063. /*
  1064.   // I do not think that you are expecting sStr in exchange file format
  1065.     ErrorDescriptor err;
  1066.     if(value.STEPread(sStr, &err) < SEVERITY_USERMSG)
  1067.     value.set_null();
  1068. */
  1069. }
  1070.  
  1071. SingleLinkNode *
  1072. StringNode::NewNode () 
  1073. {
  1074.     return new StringNode ();
  1075. }
  1076.  
  1077. ///////////////////////////////////////////////////////////////////////////////
  1078. // non-whitespace chars following s are considered garbage and is an error.
  1079. // a valid value will still be assigned if it exists before the garbage.
  1080. ///////////////////////////////////////////////////////////////////////////////
  1081.  
  1082. Severity 
  1083. StringNode::StrToVal(const char *s, ErrorDescriptor *err)
  1084. {
  1085.     return STEPread(s, err);
  1086. }
  1087.  
  1088. // this function assumes you will check for garbage following input
  1089.  
  1090. Severity 
  1091. StringNode::StrToVal(istream &in, ErrorDescriptor *err)
  1092. {
  1093.     return value.STEPread(in, err);
  1094. }
  1095.  
  1096. // non-whitespace chars following s are considered garbage and is an error.
  1097. // a valid value will still be assigned if it exists before the garbage.
  1098. Severity 
  1099. StringNode::STEPread(const char *s, ErrorDescriptor *err)
  1100. {
  1101.     istrstream in((char *)s);
  1102.  
  1103.     value.STEPread(in, err);
  1104.     CheckRemainingInput(in, err, "string", ",)");
  1105.     return err->severity();
  1106. }
  1107.  
  1108. // this function assumes you will check for garbage following input
  1109.  
  1110. Severity 
  1111. StringNode::STEPread(istream &in, ErrorDescriptor *err)
  1112. {
  1113.     return value.STEPread(in, err);
  1114. }
  1115.  
  1116. const char *
  1117. StringNode::asStr(SCLstring &s)
  1118. {
  1119. //    return value.asStr(); // this does not put quotes around the value
  1120.  
  1121.     value.asStr(s);
  1122.     return s.chars();
  1123. }
  1124.  
  1125. const char *
  1126. StringNode::STEPwrite (SCLstring &s)
  1127. {
  1128.     value.STEPwrite(s);
  1129.     return s.chars();
  1130. }
  1131.  
  1132. void
  1133. StringNode::STEPwrite (ostream& out)
  1134. {
  1135.     value.STEPwrite(out);
  1136. }
  1137. ///////////////////////////////////////////////////////////////////////////////
  1138. // BinaryAggregate
  1139. ///////////////////////////////////////////////////////////////////////////////
  1140.  
  1141. /******************************************************************
  1142. STEPaggregate& 
  1143. BinaryAggregate::ShallowCopy (const STEPaggregate&);
  1144. ******************************************************************/
  1145.  
  1146. STEPaggregate& 
  1147. BinaryAggregate::ShallowCopy (const STEPaggregate& a)
  1148. {
  1149.     Empty();
  1150.     
  1151.     SingleLinkNode* next = a.GetHead();
  1152.     SingleLinkNode* copy;
  1153.  
  1154.     while (next) 
  1155.     {
  1156.     copy = new BinaryNode (*(BinaryNode*)next);
  1157.     AddNode(copy);
  1158.     next = next->NextNode();
  1159.     }
  1160.     if(head)
  1161.     _null = 0;
  1162.     else
  1163.     _null = 1;
  1164.     return *this;
  1165.     
  1166. }
  1167.  
  1168. SingleLinkNode *
  1169. BinaryAggregate::NewNode () 
  1170. {
  1171.     return new BinaryNode ();
  1172. }
  1173.  
  1174. ///////////////////////////////////////////////////////////////////////////////
  1175. // BinaryNode
  1176. ///////////////////////////////////////////////////////////////////////////////
  1177.  
  1178. BinaryNode::BinaryNode(BinaryNode& bn)
  1179. {
  1180.     value = bn.value.chars();
  1181. }
  1182.  
  1183. BinaryNode::BinaryNode(const char *sStr)
  1184. {
  1185.     // value is an SdaiBinary (the memory is copied)
  1186.     value = sStr;
  1187. }
  1188.  
  1189. SingleLinkNode *
  1190. BinaryNode::NewNode () 
  1191. {
  1192.     return new BinaryNode ();
  1193. }
  1194.  
  1195. ///////////////////////////////////////////////////////////////////////////////
  1196. // non-whitespace chars following s are considered garbage and is an error.
  1197. // a valid value will still be assigned if it exists before the garbage.
  1198. ///////////////////////////////////////////////////////////////////////////////
  1199.  
  1200. Severity 
  1201. BinaryNode::StrToVal(const char *s, ErrorDescriptor *err)
  1202. {
  1203.     return STEPread(s, err);
  1204. }
  1205.  
  1206. // this function assumes you will check for garbage following input
  1207.  
  1208. Severity 
  1209. BinaryNode::StrToVal(istream &in, ErrorDescriptor *err)
  1210. {
  1211.     return value.STEPread(in, err);
  1212. }
  1213.  
  1214. // non-whitespace chars following s are considered garbage and is an error.
  1215. // a valid value will still be assigned if it exists before the garbage.
  1216.  
  1217. Severity 
  1218. BinaryNode::STEPread(const char *s, ErrorDescriptor *err)
  1219. {
  1220.     istrstream in((char *)s);
  1221.  
  1222.     value.STEPread(in, err);
  1223.     CheckRemainingInput(in, err, "binary", ",)");
  1224.     return err->severity();
  1225. }
  1226.  
  1227. // this function assumes you will check for garbage following input
  1228.  
  1229. Severity 
  1230. BinaryNode::STEPread(istream &in, ErrorDescriptor *err)
  1231. {
  1232.     return value.STEPread(in, err);
  1233. }
  1234.  
  1235. const char *
  1236. BinaryNode::asStr(SCLstring &s)
  1237. {
  1238.     s = value.chars();
  1239.     return s.chars();
  1240. }
  1241.  
  1242. const char *
  1243. BinaryNode::STEPwrite (SCLstring &s)
  1244. {
  1245.     value.STEPwrite(s);
  1246.     return s.chars();
  1247. }
  1248.  
  1249. void
  1250. BinaryNode::STEPwrite (ostream& out)
  1251. {
  1252.     value.STEPwrite(out);
  1253. }
  1254.  
  1255. ///////////////////////////////////////////////////////////////////////////////
  1256. // EnumAggregate
  1257. ///////////////////////////////////////////////////////////////////////////////
  1258.  
  1259. // COPY
  1260. STEPaggregate& 
  1261. EnumAggregate::ShallowCopy (const STEPaggregate& a)
  1262. {
  1263.     const EnumNode * tmp = (const EnumNode *) a.GetHead();
  1264.     EnumNode * to;
  1265.     
  1266.     while (tmp) 
  1267.     {
  1268.     to = (EnumNode *) NewNode ();
  1269.     to -> node -> put (tmp -> node ->asInt());
  1270.     AddNode (to);
  1271.     tmp = (const EnumNode *) tmp -> NextNode ();
  1272.     }
  1273.     if(head)
  1274.     _null = 0;
  1275.     else
  1276.     _null = 1;
  1277.  
  1278.     return *this;
  1279. }
  1280.  
  1281. EnumAggregate::EnumAggregate ()
  1282. {
  1283.     
  1284. }
  1285.  
  1286. EnumAggregate::~EnumAggregate ()
  1287. {
  1288.     
  1289. }
  1290.  
  1291. /******************************************************************
  1292.  ** Procedure:  EnumAggregate::NewNode
  1293.  ** Parameters:  
  1294.  ** Returns:  a new EnumNode which is of the correct derived type
  1295.  ** Description:  creates a node to put in an list of enumerated values
  1296.  **               function is virtual so that the right node will be 
  1297.  **               created
  1298.  ** Side Effects:  
  1299.  ** Status:  ok 2/91
  1300.  ******************************************************************/
  1301.  
  1302. /*EnumNode **/
  1303.  
  1304. SingleLinkNode *
  1305. EnumAggregate::NewNode ()
  1306. {
  1307.     //  defined in subclass
  1308.   cerr << "Internal error:  " << __FILE__ << ": " <<  __LINE__ << "\n" ;
  1309.   cerr << "function:  EnumAggregate::NewNode () called instead of virtual function. \n" 
  1310.        << _POC_ << "\n";
  1311.   return 0;
  1312. }
  1313.  
  1314. ///////////////////////////////////////////////////////////////////////////////
  1315. // EnumNode
  1316. ///////////////////////////////////////////////////////////////////////////////
  1317.  
  1318. SingleLinkNode *
  1319. EnumNode::NewNode ()
  1320. {
  1321.     //  defined in subclass
  1322.   cerr << "Internal error:  " << __FILE__ << ": " <<  __LINE__ << "\n" ;
  1323.   cerr << "function:  EnumNode::NewNode () called instead of virtual function. \n" 
  1324.        << _POC_ << "\n";
  1325.   return 0;
  1326. }
  1327.  
  1328. /*
  1329. // insts and addFileId are used for the EntityNode virtual definition of this
  1330. // function
  1331. Severity
  1332. EnumNode::StrToVal(const char *s, ErrorDescriptor *err)
  1333. {
  1334.     char messageBuf[BUFSIZ];
  1335.     messageBuf[0] = '\0';
  1336.  
  1337.     Severity sev = SEVERITY_NULL;
  1338.     int len = strlen (s);
  1339.     char *val = new char [len + 1];
  1340.     val[0] = '\0';
  1341.     char *saveForDelete = val;
  1342.  
  1343.     int numFound = sscanf((char *)s," %s", val);
  1344.     if(numFound != EOF)
  1345.     {
  1346.     if(val [0] == '.')  // strip the delims
  1347.     {
  1348.         val++;
  1349.         char * pos = strchr(val, '.');
  1350.         if (pos) 
  1351.         *pos = '\0';
  1352.         else 
  1353.         {
  1354.         sev = SEVERITY_WARNING;
  1355.         err->GreaterSeverity(SEVERITY_WARNING);
  1356.         err->AppendToDetailMsg("Missing matching \'.\' delimiter.\n");
  1357.         }
  1358.     }
  1359.     if(elem_type)
  1360.     {
  1361.         if(elem_type->BaseType() == BOOLEAN_TYPE)
  1362.         {
  1363.         switch(val[0])
  1364.         {
  1365.           case 't':
  1366.           case 'f':
  1367.           case 'T':
  1368.           case 'F':
  1369.             break;
  1370.           default:
  1371.             sev = SEVERITY_WARNING;
  1372.             err->GreaterSeverity(SEVERITY_WARNING);
  1373.             sprintf(messageBuf, "Invalid boolean value: \'%s\'.\n",
  1374.                 val);
  1375.             err->AppendToDetailMsg(messageBuf);
  1376.             break;
  1377.         }
  1378.         }
  1379.     }
  1380.         // assign based on the result of this element (the error descriptor
  1381.         // contains the error level for the whole aggregate).
  1382. //    if(assignVal && sev > SEVERITY_WARNING)
  1383.     if(1 && sev > SEVERITY_WARNING)
  1384.         node -> put (val);
  1385.     }
  1386. //STEPenumeration::EnumValidLevel(const char *value, ErrorDescriptor *err,
  1387. //                int optional, char *tokenList, 
  1388. //                int needDelims, int clearError)
  1389.  
  1390.     node->EnumValidLevel((char *)val, err, 0, 0, 0, 0);
  1391.     delete [] saveForDelete;
  1392.  
  1393.     // an element being null shouldn't make the aggregate incomplete!!
  1394.     if(err->severity() == SEVERITY_INCOMPLETE)
  1395.     err->severity(SEVERITY_NULL);
  1396.     return err->severity();
  1397. }
  1398. */
  1399.  
  1400. ///////////////////////////////////////////////////////////////////////////////
  1401. // non-whitespace chars following s are considered garbage and is an error.
  1402. // a valid value will still be assigned if it exists before the garbage.
  1403. ///////////////////////////////////////////////////////////////////////////////
  1404.  
  1405. Severity
  1406. EnumNode::StrToVal(const char *s, ErrorDescriptor *err)
  1407. {
  1408.     return STEPread(s, err);
  1409. }
  1410.  
  1411. // this function assumes you will check for garbage following input
  1412.  
  1413. Severity 
  1414. EnumNode::StrToVal(istream &in, ErrorDescriptor *err)
  1415. {
  1416.     return node->STEPread(in, err);
  1417. }
  1418.  
  1419. // non-whitespace chars following s are considered garbage and is an error.
  1420. // a valid value will still be assigned if it exists before the garbage.
  1421.  
  1422. Severity 
  1423. EnumNode::STEPread(const char *s, ErrorDescriptor *err)
  1424. {
  1425.     istrstream in((char *)s); // sz defaults to length of s
  1426.  
  1427.     int nullable = 0;
  1428.     node->STEPread (in, err,  nullable);
  1429.     CheckRemainingInput(in, err, "enumeration", ",)");
  1430.     return err->severity();
  1431. }
  1432.  
  1433. // this function assumes you will check for garbage following input
  1434.  
  1435. Severity 
  1436. EnumNode::STEPread(istream &in, ErrorDescriptor *err)
  1437. {
  1438.     int nullable = 0;
  1439.     node->STEPread (in, err,  nullable);
  1440.     return err->severity();
  1441. }
  1442.  
  1443. const char *
  1444. EnumNode::asStr (SCLstring &s)  
  1445. {
  1446.     node -> asStr(s);
  1447.     return s.chars();
  1448. }
  1449.  
  1450. const char *
  1451. EnumNode::STEPwrite (SCLstring &s)
  1452. {
  1453.     node->STEPwrite(s);
  1454.     return s.chars();
  1455.  
  1456. /*
  1457.     static char buf[BUFSIZ];
  1458.     buf[0] = '\0';
  1459.     
  1460. //    const char *str = asStr();
  1461. //    if( (strlen(str) > 0) && (str[0] != '$') )
  1462.  
  1463.     if(!(node->is_null()))
  1464.     {
  1465.     buf[0] = '.';
  1466.     buf[1] = '\0';
  1467. //    strcat(buf, str);
  1468.     strcat(buf, asStr());
  1469.     strcat(buf, ".");
  1470.     }
  1471.     return buf;
  1472.  */
  1473. }
  1474.  
  1475. void 
  1476. EnumNode::STEPwrite (ostream& out)
  1477. {
  1478. //    out << '.' << asStr() << '.';
  1479.     node->STEPwrite(out);
  1480. }
  1481.  
  1482. ///////////////////////////////////////////////////////////////////////////////
  1483. // Logicals
  1484. ///////////////////////////////////////////////////////////////////////////////
  1485.  
  1486. //EnumNode * 
  1487.  
  1488. SingleLinkNode *
  1489. Logicals::NewNode ()  
  1490. {
  1491.     return new EnumNode (new Logical);
  1492. }    
  1493.  
  1494. ///////////////////////////////////////////////////////////////////////////////
  1495. // RealAggregate
  1496. ///////////////////////////////////////////////////////////////////////////////
  1497.  
  1498. SingleLinkNode *
  1499. RealAggregate::NewNode ()  
  1500. {
  1501.     return new RealNode();
  1502. }    
  1503.  
  1504. // COPY
  1505. STEPaggregate& 
  1506. RealAggregate::ShallowCopy (const STEPaggregate& a)
  1507. {
  1508.     const RealNode * tmp = (const RealNode *) a.GetHead();
  1509.     RealNode * to;
  1510.     
  1511.     while (tmp) 
  1512.     {
  1513.     to = (RealNode *) NewNode ();
  1514.     to -> value = tmp -> value;
  1515.     AddNode (to);
  1516.     tmp = (const RealNode *) tmp -> NextNode ();
  1517.     }
  1518.     if(head)
  1519.     _null = 0;
  1520.     else
  1521.     _null = 1;
  1522.     return *this;
  1523. }
  1524.  
  1525. ///////////////////////////////////////////////////////////////////////////////
  1526. // IntAggregate
  1527. ///////////////////////////////////////////////////////////////////////////////
  1528.  
  1529. SingleLinkNode *
  1530. IntAggregate::NewNode ()  
  1531. {
  1532.     return new IntNode();
  1533. }    
  1534.  
  1535. // COPY
  1536. STEPaggregate& 
  1537. IntAggregate::ShallowCopy (const STEPaggregate& a)
  1538. {
  1539.     const IntNode * tmp = (const IntNode *) a.GetHead();
  1540.     IntNode * to;
  1541.     
  1542.     while (tmp) 
  1543.     {
  1544.     to = (IntNode *) NewNode ();
  1545.     to -> value = tmp -> value;
  1546.     AddNode (to);
  1547.     tmp = (const IntNode *) tmp -> NextNode ();
  1548.     }
  1549.     if(head)
  1550.     _null = 0;
  1551.     else
  1552.     _null = 1;
  1553.     return *this;
  1554. }
  1555.  
  1556. ///////////////////////////////////////////////////////////////////////////////
  1557. // RealNode
  1558. ///////////////////////////////////////////////////////////////////////////////
  1559.  
  1560. SingleLinkNode *
  1561. RealNode::NewNode ()  
  1562. {
  1563.     return new RealNode();
  1564. }    
  1565.  
  1566. Severity 
  1567. RealNode::StrToVal(const char *s, ErrorDescriptor *err)
  1568. {
  1569.     if( ReadReal(value, s, err, 0) ) // returns true if value is assigned
  1570.     _null = 0;
  1571.     else
  1572.     {
  1573.     set_null();
  1574.     value = S_REAL_NULL;
  1575.     }
  1576.     return err->severity ();
  1577. }
  1578.  
  1579. Severity 
  1580. RealNode::StrToVal(istream &in, ErrorDescriptor *err)
  1581. {
  1582.     if( ReadReal(value, in, err, 0) ) // returns true if value is assigned
  1583.     _null = 0;
  1584.     else
  1585.     {
  1586.     set_null();
  1587.     value = S_REAL_NULL;
  1588.     }
  1589.     return err->severity ();
  1590. }
  1591.  
  1592.  
  1593. Severity 
  1594. RealNode::STEPread(const char *s, ErrorDescriptor *err)
  1595. {
  1596.     if( ReadReal(value, s, err, 0) ) // returns true if value is assigned
  1597.     _null = 0;
  1598.     else
  1599.     {
  1600.     set_null();
  1601.     value = S_REAL_NULL;
  1602.     }
  1603.     return err->severity ();
  1604. }
  1605.  
  1606. Severity 
  1607. RealNode::STEPread(istream &in, ErrorDescriptor *err)
  1608. {
  1609.     if( ReadReal(value, in, err, ",)") ) // returns true if value is assigned
  1610.     _null = 0;
  1611.     else
  1612.     {
  1613.     set_null();
  1614.     value = S_REAL_NULL;
  1615.     }
  1616.     return err->severity ();
  1617. }
  1618.  
  1619. const char *
  1620. RealNode::asStr(SCLstring &s)
  1621. {
  1622.     STEPwrite(s);
  1623.     return s.chars();
  1624. }
  1625.  
  1626. const char *
  1627. RealNode::STEPwrite(SCLstring &s)
  1628. {
  1629.     char tmp[BUFSIZ];
  1630.     if(value != S_REAL_NULL)
  1631.     {
  1632.     sprintf(tmp, "%#g", value);
  1633.     s = tmp;
  1634.     }
  1635.     else
  1636.     {
  1637.     sprintf(tmp, "0.0", value);
  1638.     s = tmp;
  1639.     }
  1640.     return s.chars();
  1641. }
  1642.  
  1643. void 
  1644. RealNode::STEPwrite(ostream& out)
  1645. {
  1646.     SCLstring s;
  1647.     out << STEPwrite(s);
  1648. }
  1649.  
  1650. ///////////////////////////////////////////////////////////////////////////////
  1651. // IntNode
  1652. ///////////////////////////////////////////////////////////////////////////////
  1653.  
  1654. SingleLinkNode *
  1655. IntNode::NewNode ()  
  1656. {
  1657.     return new IntNode();
  1658. }    
  1659.  
  1660. Severity 
  1661. IntNode::StrToVal(const char *s, ErrorDescriptor *err)
  1662. {
  1663.     if( ReadInteger(value, s, err, 0) ) // returns true if value is assigned
  1664.     _null = 0;
  1665.     else
  1666.     {
  1667.     set_null();
  1668.     value = S_INT_NULL;
  1669.     }
  1670.     return err->severity ();
  1671. }
  1672.  
  1673. Severity 
  1674. IntNode::StrToVal(istream &in, ErrorDescriptor *err)
  1675. {
  1676.     if( ReadInteger(value, in, err, 0) ) // returns true if value is assigned
  1677.     _null = 0;
  1678.     else
  1679.     {
  1680.     set_null();
  1681.     value = S_INT_NULL;
  1682.     }
  1683.     return err->severity ();
  1684. }
  1685.  
  1686. Severity 
  1687. IntNode::STEPread(const char *s, ErrorDescriptor *err)
  1688. {
  1689.     if( ReadInteger(value, s, err, 0) ) // returns true if value is assigned
  1690.     _null = 0;
  1691.     else
  1692.     {
  1693.     set_null();
  1694.     value = S_INT_NULL;
  1695.     }
  1696.     return err->severity ();
  1697. }
  1698.  
  1699. Severity 
  1700. IntNode::STEPread(istream &in, ErrorDescriptor *err)
  1701. {
  1702.     if( ReadInteger(value, in, err, ",)") ) // returns true if value is assigned
  1703.     _null = 0;
  1704.     else
  1705.     {
  1706.     set_null();
  1707.     value = S_INT_NULL;
  1708.     }
  1709.     return err->severity ();
  1710. }
  1711.  
  1712. const char *
  1713. IntNode::asStr(SCLstring &s)
  1714. {
  1715.     STEPwrite(s);
  1716.     return s.chars();
  1717. }
  1718.  
  1719. const char *
  1720. IntNode::STEPwrite(SCLstring &s)
  1721. {
  1722.     char tmp[BUFSIZ];
  1723.     if(value != S_INT_NULL)
  1724.     {
  1725.     sprintf(tmp, "%d", value);
  1726.     s = tmp;
  1727.     }
  1728.     else
  1729.     s.set_null();
  1730.     return s.chars();
  1731. }
  1732.  
  1733. void 
  1734. IntNode::STEPwrite(ostream& out)
  1735. {
  1736.     SCLstring s;
  1737.     out << STEPwrite(s);
  1738. }
  1739.