/***************************************************************************** * orlist.cc * * * * Description: OrList is a specialized class type which supports OR lists. * * This file contains the OrList member functions, which pro- * * vide the capability to undo previous choices, and select new * * ones. * * * * Created by: David Rosenfeld * * Date: 9/18/96 * *****************************************************************************/ #include "clstepcore/complexSupport.h" /** * Check if we matched nm. We have two possibilities here: If we have a * choice selected, we only check the selected choice. Say we're an OR * between SimpleLists C and D, and nm = C. If choice = D, we can't check * C. This is because we're already using this OR to match D, and it can * not match C. If however, this OR doesn't have any choice selected (it * = SATISFIED), we can check all our children. Since we don't need to * have a particular choice selected (D), so long as we could be used to * match C, we potentially have a match. (This all makes sense in the * context of a sub w/ >1 super, in which case we build a combo-CList and * may need to check if all sub-CLists matched the multi-sub, C.) */ bool OrList::hit( char * nm ) { EntList * child = getChild( choice ); if( child ) { // I.e., if we have a choice selected, check it only. return ( child->hit( nm ) ); } else { child = childList; while( child ) { if( child->viable > UNSATISFIED && child->hit( nm ) ) { // See MultList::hit() on why we must skip UNSATs. return true; } child = child->next; } } return false; } /** * Unmarks all the nodes of ents marked by the descendants of this. */ void OrList::unmarkAll( EntNode * ents ) { EntList * child; if( ( child = getChild( choice ) ) != NULL ) { // choice = the last selected path which we'll now undo. child->unmarkAll( ents ); } } /** * Accepts the first choice of our childList which marks any unmarked * nodes. If none of our current choices mark anything, choice is set to * LISTEND. If choice was set to LISTEND before calling aC(), we reset * choice to choice1, and search again. */ bool OrList::acceptChoice( EntNode * ents ) { EntList * child; if( choice == LISTEND ) { choice = choice1; } child = getChild( choice ); while( child ) { if( child->viable >= MATCHSOME && child->acceptChoice( ents ) ) { // acceptChoice() returns true if we marked something. return true; } child = child->next; choice++; } // If we got here, we must have gotten to the end of the childList without // finding a choice which marks something. choice = LISTEND; return false; }