void rb_substring_find( Frag_Match_Info *fmi_p, qrb_tree * tree, const char * frag ) { int compVal; int n; qrb_node* n_p = RB_TREE_ROOT(tree); n = (int) strlen(frag); fmi_p->fmi_u.rbti.curr_n_p = NULL; // default fmi_p->fmi_u.rbti.first_n_p = NULL; fmi_p->fmi_u.rbti.last_n_p = NULL; //rb_tree_dump( tree ); while(1){ if( n_p == NULL ) return; //fprintf(stderr,"rb_substring_find: comparing '%s' to '%s', n = %d\n",frag,RB_NODE_KEY(n_p),n); compVal = strncmp( frag, RB_NODE_KEY(n_p), n ); if( compVal == 0 ){ // We have found a node that may be a match, // but we want to return the first match qrb_node *p_p; //fprintf(stderr,"rb_substring_find: match found at 0x%lx\n",(long)n_p); fmi_p->fmi_u.rbti.curr_n_p = n_p; // find the first one p_p = rb_predecessor_node(n_p); while( p_p != NULL && ! strncmp(frag,RB_NODE_KEY(p_p),n) ){ n_p = p_p; p_p = rb_predecessor_node(n_p); } fmi_p->fmi_u.rbti.first_n_p = n_p; // find the last one p_p = rb_successor_node(n_p); while( p_p != NULL && ! strncmp(frag,RB_NODE_KEY(p_p),n) ){ n_p = p_p; p_p = rb_successor_node(n_p); } fmi_p->fmi_u.rbti.last_n_p = n_p; // now set current to the first fmi_p->fmi_u.rbti.curr_n_p = fmi_p->fmi_u.rbti.first_n_p; return; } else if( compVal < 0 ){ //fprintf(stderr,"descending left\n"); n_p = n_p->left; } else { //fprintf(stderr,"descending right\n"); n_p = n_p->right; } } }
static const char *_rb_tree_advance_frag_match(QSP_ARG_DECL Frag_Match_Info * fmi_p, int direction ) { Item *ip; // there may be no items!? assert( fmi_p != NULL ); if( direction == CYC_FORWARD ){ if( CURR_FRAG(fmi_p) == LAST_FRAG(fmi_p) ) return NULL; else { SET_CURR_FRAG(fmi_p, rb_successor_node( CURR_RBT_FRAG(fmi_p) ) ); assert( CURR_FRAG(fmi_p) != NULL ); } } else { if( CURR_FRAG(fmi_p) == FIRST_FRAG(fmi_p) ) return NULL; else { SET_CURR_FRAG(fmi_p,rb_predecessor_node( CURR_RBT_FRAG(fmi_p) )); assert( CURR_FRAG(fmi_p) != NULL ); } } ip = RB_NODE_ITEM( CURR_RBT_FRAG(fmi_p) ); return ITEM_NAME(ip); }