text: /*****************************************************************************
   * entnode.cc                                                                *
   *                                                                           *
   * Description: The EntNode class is used to store a collection of entity    *
   *              names.  It stores them in alphabetical order.  It is the key *
   *              component of the EntList classes, which are used to store    *
   *              information on the instantiable complex entity types.  This  *
   *              file contains EntNode member function definitions.           *
   *                                                                           *
   * Created by:  David Rosenfeld                                              *
   * Date:        9/18/96                                                      *
   *****************************************************************************/
  
  #include "complexSupport.h"
  #include <scl_memmgr.h>
  
  EntNode::EntNode( char * namelist[] )
  /*
   * Given a list of entity names, creates a sorted linked list of EntNodes
   * corresponding to the list.  Final name must be "*" (otherwise we won't
   * know where to stop).  This function first builds the list, then sets
   * this to the first element, and then deletes the first element.  We do
   * this to ensure that this points to the start of the list.
   */
  {
      int j = 1, comp;
      EntNode * prev, *prev2 = NULL, // prev2 - the one before prev
                       *newnode, *firstnode;
      char * nm;
  
      // Create a first EntNode:
      firstnode = prev = new EntNode( namelist[0] );
      // The following 3 lines are a ridiculous kludge to simplify testing.
      // We make the assumption that ents whose name start with C or M have
      // >1 supertype.  (We make sure this is the case in the test file.)
      // When this code becomes a part of the SCL, it'll be easy to get this
      // info right from the entity structs anyway, so I'm not bothering
      // writing anything more sophisticated.
      if( *namelist[0] == 'c' || *namelist[0] == 'm' || *namelist[0] == 'j' ) {
          firstnode->multSuprs( TRUE );
      }
  
      while( *namelist[j] != '*' ) {
          nm = namelist[j];
          while( prev != NULL && ( comp = strcmp( prev->name, nm ) ) < 0 ) {
              prev2 = prev;
              prev = prev->next;
          }
  
          // One exceptional case:  If new name is same as prev, skip it:
          if( comp != 0 ) {
              // At this point, we know the new node belongs between prev2 and
              // prev.  prev or prev2 may = NULL if newnode belongs at the end of
              // the list or before the beginning, respectively.
              newnode = new EntNode( nm );
              // Same kludge:
              if( *nm == 'c' || *nm == 'm' || *nm == 'j' ) {
                  newnode->multSuprs( TRUE );
              }
              newnode->next = prev;
              if( prev2 == NULL ) {
                  // This will be the case if the inner while was never entered.
                  // That happens when newnode belonged at the beginning of the
                  // list.  If so, reset firstnode.
                  firstnode = newnode;
              } else {
                  prev2->next = newnode;
              }
          }
          // Reset for next namelist:
          prev = firstnode;
          prev2 = NULL;
          j++;
      }
  
      // Finally, place the contents of firstnode in 'this', and delete first-
      // node.  This ensures that 'this' is first.
      strcpy( name, firstnode->name );
      next = firstnode->next;
      multSupers = firstnode->multSupers;
      firstnode->next = NULL;
      // (Otherwise, deleting firstnode would delete entire list.)
      delete firstnode;
  }
  
  void EntNode::markAll( MarkType stamp )
  /*
   * Marks/unmarks all the nodes in this's list (default is to mark).
   */
  {
      EntNode * node = this;
  
      while( node != NULL ) {
          node->mark = stamp;
          node = node->next;
      }
  }
  
  int EntNode::allMarked()
  /*
   * Returns TRUE if this and all nodes following it are marked.
   */
  {
      EntNode * node = this;
  
      while( node != NULL ) {
          if( node->mark == NOMARK ) {
              return FALSE;
          }
          node = node->next;
      }
      return TRUE;
  }
  
  int EntNode::unmarkedCount()
  /*
   * Returns the number of unmarked nodes in this's list.
   */
  {
      int count = 0;
      EntNode * node = this;
  
      while( node != NULL ) {
          if( node->mark == NOMARK ) {
              count++;
          }
          node = node->next;
      }
      return count;
  }
  