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 / ENUMERAT.CPP < prev    next >
C/C++ Source or Header  |  1994-08-06  |  17KB  |  664 lines

  1.  
  2. #include <Enumerat.h>
  3.  
  4. /*
  5. * NIST STEP Core Class Library
  6. * clstepcore/Enumeration.cc
  7. * February, 1994
  8. * K. C. Morris
  9. * David Sauder
  10.  
  11. * Development of this software was funded by the United States Government,
  12. * and is not subject to copyright.
  13. */
  14.  
  15. /* $Id: Enumeration.cc,v 2.0.1.6 1994/06/08 19:45:51 ian Exp $  */
  16.  
  17. //static char rcsid[] ="$Id: Enumeration.cc,v 2.0.1.6 1994/06/08 19:45:51 ian Exp $";
  18.  
  19. #include <strstrea.h>
  20. #include <read_fun.h>
  21.  
  22. ///////////////////////////////////////////////////////////////////////////////
  23. // class Logical
  24. ///////////////////////////////////////////////////////////////////////////////
  25.  
  26. Logical::operator LOGICAL () const  {
  27.   switch (v) {
  28.   case sdaiUNKNOWN:  return sdaiUNKNOWN;
  29.   case sdaiFALSE: return sdaiFALSE;
  30.   case sdaiTRUE: return sdaiTRUE;
  31.   default: return sdaiUNKNOWN;
  32. }}
  33.  
  34. const char * 
  35. Logical::element_at (int n)  const {
  36.   switch (n)  {
  37.   case sdaiUNKNOWN:  return "U";
  38.   case sdaiFALSE: return "F";
  39.   case sdaiTRUE: return "T";
  40.   default: return "";
  41.   }
  42. }
  43.  
  44. ///////////////////////////////////////////////////////////////////////////////
  45. // class Boolean  29-Sep-1994
  46. ///////////////////////////////////////////////////////////////////////////////
  47.  
  48. Boolean::Boolean (LOGICAL val)  {
  49.   if (val == sdaiUNKNOWN) return;
  50.   set_value (val);
  51. }
  52.  
  53. Boolean::operator LOGICAL () const  {
  54.   switch (v) {
  55.   case sdaiFALSE: return sdaiFALSE;
  56.   case sdaiTRUE: return sdaiTRUE;
  57.   default: return sdaiUNKNOWN;
  58. }}
  59.  
  60. const char * 
  61. Boolean::element_at (int n)  const {
  62.   switch (n)  {
  63.   case sdaiFALSE: return "F";
  64.   case sdaiTRUE: return "T";
  65.   default: return "";
  66.   }
  67. }
  68.  
  69. Boolean::operator int () const  {
  70.   if (v == sdaiFALSE)  return 0;
  71.   else return 1;
  72. }
  73.  
  74. ///////////////////////////////////////////////////////////////////////////////
  75.  
  76. /******************************************************************
  77.  ** Procedure:  DebugDisplay
  78.  ** Parameters:  ostream& out
  79.  ** Returns:  
  80.  ** Description:  prints out some information on the enumerated 
  81.  **               item for debugging purposes
  82.  ** Side Effects:  
  83.  ** Status:  ok 2/1/91
  84.  ******************************************************************/
  85. void
  86. STEPenumeration::DebugDisplay (ostream& out) const  {
  87.     SCLstring tmp;
  88.     out << "Value  :  " <<  v  << "  " 
  89.     << asStr (tmp) 
  90.         << ": for type " << Name () << "\n";
  91.     out << "valid values are  ";
  92.     int i =0;
  93.     while (element_at (i))  
  94.       {
  95.       out << element_at (i++) << "  ";
  96.       }
  97.     STEPwrite (out);
  98.     out << "\n";
  99.     
  100. }    
  101.  
  102. // Read an Enumeration value 
  103. // ENUMERATION = "." UPPER { UPPER | DIGIT } "."
  104. // *note* UPPER is defined as alpha or underscore.
  105. // returns: Severity of the error.
  106. // error message and error Severity is written to ErrorDescriptor *err.
  107. // int AssignVal is: 
  108. // true => value is assigned to the STEPenumeration; 
  109. // true or false => value is read and appropriate error info is set and 
  110. //     returned.
  111. // int needDelims is: 
  112. // false => absence of the period delimiters is not an error; 
  113. // true => delimiters must be valid; 
  114. // true or false => non-matching delimiters are flagged as an error
  115.  
  116. Severity 
  117. STEPenumeration::ReadEnum(istream& in, ErrorDescriptor *err, int AssignVal,
  118.               int needDelims)
  119. {
  120.     if(AssignVal)
  121.     set_null();
  122.  
  123.     SCLstring str;
  124.     char c;
  125.     char messageBuf[512];
  126.     messageBuf[0] = '\0';
  127.  
  128.     int validDelimiters = 1;
  129.  
  130.     in >> ws; // skip white space
  131.  
  132.     if( in.good() )
  133.     {
  134.     in.get(c);
  135.     if( c == '.' || isalpha(c))
  136.     {
  137.         if( c == '.' )
  138.         {
  139.         in.get(c); // push past the delimiter
  140.         // since found a valid delimiter it is now invalid until the 
  141.         //   matching ending delim is found
  142.         validDelimiters = 0;
  143.         }
  144.  
  145.         // look for UPPER
  146.         if( in.good() && ( isalpha(c) || c == '_' ) )
  147.         {
  148.         str.Append(c);
  149.         in.get(c);
  150.         }
  151.  
  152.         // look for UPPER or DIGIT
  153.         while( in.good() && ( isalnum(c) || c == '_' ) )
  154.         {
  155.         str.Append(c);
  156.         in.get(c);
  157.         }
  158.         // if character is not the delimiter unread it
  159.         if(in.good() && (c != '.') )
  160.         in.putback(c);
  161.  
  162.         // a value was read
  163.         if(str.Length() > 0)
  164.         {
  165.         int i =0;
  166.         const char *strval = str.chars();
  167.         SCLstring tmp;
  168.         while( (i < no_elements ())  &&  
  169.                (strcmp( (char *)StrToUpper( strval, tmp ), 
  170.                          element_at (i) ) != 0) )
  171.             ++i;
  172.         if ( no_elements () == i)
  173.         {    //  exhausted all the possible values 
  174.             err->GreaterSeverity(SEVERITY_WARNING);
  175.             err->AppendToDetailMsg("Invalid Enumeration value.\n");
  176.             err->AppendToUserMsg("Invalid Enumeration value.\n");
  177.         }
  178.         else
  179.         {
  180.             if(AssignVal)
  181.             v = i;
  182.         }
  183.  
  184.         // now also check the delimiter situation
  185.         if(c == '.') // if found ending delimiter
  186.         {
  187.             // if expecting delim (i.e. validDelimiter == 0)
  188.             if(!validDelimiters) 
  189.             {
  190.             validDelimiters = 1; // everything is fine
  191.             }
  192.             else // found ending delimiter but no initial delimiter
  193.             {
  194.             validDelimiters = 0;
  195.             }
  196.         }
  197.         // didn't find any delimiters at all and need them.
  198.         else if(needDelims) 
  199.         {
  200.             validDelimiters = 0;
  201.         }
  202.  
  203.         if (!validDelimiters)
  204.         {    
  205.             err->GreaterSeverity(SEVERITY_WARNING);
  206.             if(needDelims)
  207.             sprintf(messageBuf, 
  208.               "Enumerated value has invalid period delimiters.\n");
  209.             else
  210.             sprintf(messageBuf, 
  211.                "Mismatched period delimiters for enumeration.\n");
  212.             err->AppendToDetailMsg(messageBuf);
  213.             err->AppendToUserMsg(messageBuf);
  214.         }
  215.         return err->severity();
  216.         }
  217.         // found valid or invalid delimiters with no associated value 
  218.         else if( (c == '.') || !validDelimiters)
  219.         {
  220.         err->GreaterSeverity(SEVERITY_WARNING);
  221.         err->AppendToDetailMsg(
  222.        "Enumerated has valid or invalid period delimiters with no value.\n"
  223.                       );
  224.         err->AppendToUserMsg(
  225.        "Enumerated has valid or invalid period delimiters with no value.\n"
  226.                       );
  227.         return err->severity();
  228.         }
  229.         else // no delims and no value
  230.         err->GreaterSeverity(SEVERITY_INCOMPLETE);
  231.  
  232.     }
  233.     else if( (c == ',') || (c == ')') )
  234.     {
  235.         in.putback(c);
  236.         err->GreaterSeverity(SEVERITY_INCOMPLETE);
  237.     }
  238.     else
  239.     {
  240.         in.putback(c);
  241.         err->GreaterSeverity(SEVERITY_WARNING);
  242.         sprintf(messageBuf, "Invalid enumeration value.\n");
  243.         err->AppendToDetailMsg(messageBuf);
  244.         err->AppendToUserMsg(messageBuf);
  245.     }
  246.     }
  247.     else // hit eof (assuming there was no error state for istream passed in)
  248.     {
  249.     err->GreaterSeverity(SEVERITY_INCOMPLETE);
  250.     }
  251.     return err->severity();
  252. }
  253.  
  254. /*
  255. Severity 
  256. STEPenumeration::StrToVal (const char * s)
  257. {
  258.     put (s);
  259.     return SEVERITY_NULL;
  260. }
  261. */
  262.  
  263. Severity 
  264. STEPenumeration::StrToVal (const char * s, ErrorDescriptor *err, int optional)
  265. {
  266.     istrstream in ((char *)s); // sz defaults to length of s
  267.  
  268.     Severity sev = ReadEnum(in, err, 1, 0);
  269.     if( (err->severity() == SEVERITY_INCOMPLETE) && optional)
  270.     err->severity(SEVERITY_NULL);
  271.  
  272.     return err->severity();
  273. }
  274.  
  275. // reads an enumerated value in STEP file format 
  276. Severity
  277. STEPenumeration::STEPread (const char *s, ErrorDescriptor *err, int optional)
  278. {
  279.     istrstream in((char *)s);
  280.     return STEPread (in, err, optional);
  281. }
  282.  
  283. // reads an enumerated value in STEP file format 
  284. Severity
  285. STEPenumeration::STEPread (istream& in, ErrorDescriptor *err, int optional)
  286. {
  287.     Severity sev = ReadEnum(in, err, 1, 1);
  288.     if( (err->severity() == SEVERITY_INCOMPLETE) && optional)
  289.     err->severity(SEVERITY_NULL);
  290.  
  291.     return err->severity();
  292. }
  293.  
  294.  
  295. const char * 
  296. STEPenumeration::asStr (SCLstring &s) const  {
  297.     if (v != ENUM_NULL) 
  298.     {
  299. //    s = elements[v];
  300.     return s = element_at (v);
  301. //    return s.chars();
  302.     }
  303.     else return "";
  304. }
  305.  
  306. void 
  307. STEPenumeration::STEPwrite (ostream& out)  const  {
  308.     if( is_null() )
  309.     out << '$';
  310.     else
  311.     {
  312.     SCLstring tmp;
  313.     out << "." <<  asStr (tmp) << ".";
  314.     }
  315. }
  316.  
  317. const char * 
  318. STEPenumeration::STEPwrite (SCLstring &s) const
  319. {
  320.     if( is_null() )
  321.     {
  322.     s.set_null();
  323.     }
  324.     else
  325.     {
  326.     SCLstring tmp;
  327.     s = ".";
  328.     s.Append(asStr(tmp));
  329.     s.Append('.');
  330.     }
  331.     return s.chars();
  332. }
  333.  
  334. //STEPenumeration::STEPenumeration (const char * const e)
  335. //:  elements (e)
  336. //{  
  337. //}
  338.  
  339. /******************************************************************
  340.  ** Procedure:  set_elements
  341.  ** Parameters:  
  342.  ** Returns:  
  343.  ** Description:  
  344.  ** Side Effects:  
  345.  ** Status:  
  346.  ******************************************************************/
  347. #ifdef OBSOLETE
  348. void
  349. STEPenumeration::set_elements (const char * const e [])  {
  350.     elements = e;
  351. }
  352. #endif
  353. Severity 
  354. STEPenumeration::EnumValidLevel(istream &in, ErrorDescriptor *err,
  355.                 int optional, char *tokenList, 
  356.                 int needDelims, int clearError)
  357. {
  358.     if(clearError)
  359.     err->ClearErrorMsg();
  360.  
  361.     in >> ws; // skip white space
  362.     char c = ' '; 
  363.     c = in.peek();
  364.     if(c == '$' || in.eof())
  365.     {
  366.     if(!optional)
  367.         err->GreaterSeverity(SEVERITY_INCOMPLETE);
  368.     if(in)
  369.         in >> c;
  370.     CheckRemainingInput(in, err, "enumeration", tokenList);
  371.     return err->severity();
  372.     }
  373.     else
  374.     {
  375.     ErrorDescriptor error;
  376.  
  377.     ReadEnum(in, &error, 0, needDelims);
  378.     CheckRemainingInput(in, &error, "enumeration", tokenList);
  379.  
  380.     Severity sev = error.severity();
  381.     if(sev < SEVERITY_INCOMPLETE)
  382.     {
  383.         err->AppendToDetailMsg(error.DetailMsg());
  384.         err->AppendToUserMsg(error.UserMsg());
  385.         err->GreaterSeverity(error.severity());
  386.     }
  387.     else if(sev == SEVERITY_INCOMPLETE && !optional)
  388.         err->GreaterSeverity(SEVERITY_INCOMPLETE);
  389.     }
  390.     return err->severity();
  391. }
  392.  
  393. Severity 
  394. STEPenumeration::EnumValidLevel(const char *value, ErrorDescriptor *err,
  395.                 int optional, char *tokenList, 
  396.                 int needDelims, int clearError)
  397. {
  398.     istrstream in((char *)value);
  399.     return EnumValidLevel (in, err, optional, tokenList, needDelims,
  400.                clearError);
  401. /*
  402.  
  403.     char messageBuf[BUFSIZ];
  404.     messageBuf[0] = '\0';
  405.  
  406.     if(attrValue)
  407.     {
  408.     int len = strlen (attrValue);
  409.     char *valstart = new char [len + 1];
  410.     char *val = valstart;
  411.  
  412.     int numFound = sscanf(attrValue," %s", val);
  413.     if(numFound != EOF)
  414.     {
  415.         int i = 0;
  416.         if(val [0] == '.')  // strip the delims
  417.         {
  418.  
  419.         val++;
  420.         char * pos = strchr(val, '.');
  421.         if (pos) 
  422.             *pos = '\0';
  423.         else
  424.         {
  425.             err->AppendToDetailMsg(
  426.             "Missing ending period delimiter for enumerated value.\n");
  427.             err->AppendToUserMsg(
  428.             "Missing ending period delimiter for enumerated value.\n");
  429.             err->GreaterSeverity(SEVERITY_WARNING);
  430.         }
  431.         }
  432.  
  433.         SCLstring tmp;
  434.         while((i < no_elements() ) && 
  435.         (strcmp( (char *)StrToUpper(val, tmp), element_at (i) ) != 0))
  436.         ++i;
  437.         if(no_elements() == i)    // exhausted all the possible values 
  438.         {
  439.         err->GreaterSeverity(SEVERITY_WARNING);
  440.         sprintf(messageBuf, 
  441.             "attribute %s: Invalid enumeration value: '%s'",
  442.             Name(), val);
  443.         err->AppendToUserMsg(messageBuf);
  444.         err->AppendToDetailMsg(messageBuf);
  445. //        DebugDisplay ();
  446.         return SEVERITY_WARNING;
  447.         }
  448.         err->GreaterSeverity(SEVERITY_NULL);
  449.         return SEVERITY_NULL;
  450.     }
  451.     delete [] valstart;
  452.     }
  453.     if(optional) 
  454.     {
  455.     err->GreaterSeverity(SEVERITY_NULL);
  456.     return SEVERITY_NULL;
  457.     }
  458.     else
  459.     {
  460.     err->GreaterSeverity(SEVERITY_INCOMPLETE);
  461.     return SEVERITY_INCOMPLETE;
  462.     }
  463. */
  464. }
  465.  
  466. /******************************************************************
  467.  ** Procedure:  set_value
  468.  ** Parameters:  char * n  OR  in i  -- value to be set
  469.  ** Returns:  value set 
  470.  ** Description:  sets the value of an enumerated attribute
  471.  **     case is not important in the character based version
  472.  **     if value is not acceptable, a warning is printed and 
  473.  **     processing continues
  474.  ** Side Effects:  
  475.  ** Status:  ok 2.91
  476.  ******************************************************************/
  477. int
  478. STEPenumeration::set_value (const char * n)  {  
  479.     //  assigns the appropriate value based on n
  480.     if  ( !n || (!strcmp (n, "")) )  return set_value (ENUM_NULL);
  481.     
  482.     int i =0;
  483.     SCLstring tmp;
  484.     while ((i < no_elements ())  &&  
  485.        (strcmp ( (char *)StrToUpper( n, tmp ),  element_at (i)) != 0 ) )
  486.     ++i;
  487.     if ( no_elements () == i)  {  //  exhausted all the possible values 
  488.     return set_value (ENUM_NULL);
  489.     }
  490.     v = i;    
  491.     return v;
  492.     
  493. }
  494.  
  495. //  set_value is the same function as put
  496. int
  497. STEPenumeration::set_value (const int i)  {  
  498.     if (i == ENUM_NULL)  {
  499.     v = ENUM_NULL;
  500.     return ENUM_NULL;
  501.     }    
  502.     if (i < no_elements ())  return (v =i);
  503.     // otherwise 
  504.     cerr << "(OLD Warning:) invalid enumeration value " << i
  505.     << " for " <<  Name () << "\n";
  506.     DebugDisplay ();
  507.     return  ENUM_NULL ;
  508.     
  509. }
  510.  
  511. STEPenumeration& 
  512. STEPenumeration::operator= (const int i)
  513. {
  514.     put (i);
  515.     return *this;
  516. }
  517.  
  518. STEPenumeration&
  519. STEPenumeration::operator= (const STEPenumeration& Senum)
  520. {
  521.     put (Senum.asInt());
  522.     return *this;
  523. }
  524.  
  525. ostream &operator<< ( ostream& out, const STEPenumeration& a )
  526. {
  527.     SCLstring tmp;
  528.     out << a.asStr( tmp );
  529.     return out;
  530.  
  531. }
  532.  
  533.  
  534. #ifdef pojoldStrToValNstepRead
  535.  
  536. Severity 
  537. STEPenumeration::StrToVal (const char * s, ErrorDescriptor *err, int optional)
  538. {
  539.     const char *sPtr = s;
  540.     while(isspace(*sPtr)) sPtr++;
  541.     if(*sPtr == '\0')
  542.     {
  543.     if(optional) 
  544.     {
  545.         err->GreaterSeverity(SEVERITY_NULL);
  546.         return SEVERITY_NULL;
  547.     }
  548.     else
  549.     {
  550.         err->GreaterSeverity(SEVERITY_INCOMPLETE);
  551.         return SEVERITY_INCOMPLETE;
  552.     }
  553.     }
  554.     else if(*sPtr == '.') // look for initial period delimiter
  555.     {
  556.     return STEPread(sPtr, err);
  557.     }
  558.     else
  559.     {
  560.         // look for ending period delimiter (an error)
  561.     char *periodLoc = strchr(sPtr, '.');
  562.     if (periodLoc)
  563.     {    // found an ending period w/out initial period
  564.         char *tmp = new char[strlen(sPtr) + 1];
  565.         strcpy(tmp, sPtr);
  566.         tmp[periodLoc - sPtr] = '\0'; // write over ending period
  567.         err->GreaterSeverity(SEVERITY_WARNING);
  568.         err->AppendToDetailMsg(
  569.         "Ending period delimiter without initial period delimiter.\n");
  570.         err->AppendToUserMsg(
  571.         "Ending period delimiter without initial period delimiter.\n");
  572.         delete [] tmp;
  573.         if( ValidLevel(sPtr, err, optional) )
  574.         { // remaining value is valid so assign it
  575.         put(tmp);
  576.         return SEVERITY_WARNING;
  577.         }
  578.         else
  579.         {
  580.         err->AppendToDetailMsg("Invalid Enumerated value.\n");
  581.         err->AppendToUserMsg("Invalid Enumerated value.\n");
  582.         return SEVERITY_WARNING;
  583.         }
  584.     }
  585.     // no surrounding delimiters
  586.     else if( ValidLevel(sPtr, err, optional) )
  587.     { // value is valid so assign it
  588.         put (sPtr);  
  589.         return SEVERITY_NULL;
  590.     }
  591.     else
  592.     {
  593.         err->AppendToDetailMsg("Invalid Enumerated value.\n");
  594.         err->AppendToUserMsg("Invalid Enumerated value.\n");
  595.         return SEVERITY_WARNING;
  596.     }
  597.     }
  598. }
  599.  
  600.  
  601. Severity
  602. STEPenumeration::STEPread (istream& in, ErrorDescriptor *err, int optional)
  603. {
  604.     char enumValue [BUFSIZ];
  605.     char c;
  606.     char errStr[BUFSIZ];
  607.     errStr[0] = '\0';
  608.  
  609.     err->severity(SEVERITY_NULL); // assume ok until error happens
  610.     in >> c;
  611.     switch (c)  
  612.       {
  613.     case '.':
  614.       in.getline (enumValue, BUFSIZ, '.');// reads but does not store the .
  615. /*
  616.   // gcc 2.3.3 - It does and should read the . It doesn't store it DAS 4/27/93
  617.       char * pos = index(enumValue, '.');
  618.       if (pos) *pos = '\0';
  619.       //  NON-STANDARD (GNUism)  getline should not retrieve .
  620.       //  function gcount is unavailable
  621. */
  622.       if(in.fail())
  623.       {
  624.           err->GreaterSeverity(SEVERITY_WARNING);
  625.           err->AppendToUserMsg(
  626.             "Missing ending period delimiter for enumerated value.\n");
  627.           err->AppendToDetailMsg(
  628.             "Missing ending period delimiter for enumerated value.\n");
  629.       }
  630.       if(ValidLevel(enumValue, err, optional) == SEVERITY_NULL)
  631.           set_value (enumValue);
  632.       else
  633.       {
  634.           err->AppendToDetailMsg("Invalid enumerated value.\n");
  635.           err->GreaterSeverity(SEVERITY_WARNING);
  636.           set_value(ENUM_NULL);
  637.       }          
  638.       break;
  639.       
  640.     case ',':    // for next attribute or next aggregate value?
  641.     case ')':    // for end of aggregate value?
  642.     default:
  643.       in.putback (c);
  644.       set_value (ENUM_NULL);
  645.       if(optional) err->GreaterSeverity(SEVERITY_NULL);
  646.       else           err->GreaterSeverity(SEVERITY_INCOMPLETE);
  647.       break;
  648.       
  649. /*
  650.     default:
  651.       set_value (ENUM_NULL);
  652.         // read didn't know what to do
  653.       err->GreaterSeverity(SEVERITY_INPUT_ERROR); 
  654.       sprintf(errStr,
  655.            "STEPenumeration::STEPread(): warning : poorly delimited %s %s",
  656.             Name(), "enumerated value was ignored.");
  657.       err->AppendToDetailMsg(errStr);
  658. */
  659.       }  
  660.     return err->severity();
  661. }
  662.  
  663. #endif
  664.