Exemple #1
0
static void combust_tree(graphcut_workspace_t*w, posqueue_t*q1, posqueue_t*q2, path_t*path)
{
    graph_t*graph = w->graph;
    int t;
    for(t=0;t<path->length-1 && path->firsthalf[t+1];t++) {
        node_t*pos = path->pos[t];
	halfedge_t*dir = path->dir[t];
        node_t*newpos = dir->fwd->node;
        if(!dir->weight) {
            /* disconnect node */
            DBG printf("remove link %d -> %d from tree 1\n", NR(pos), NR(newpos));
	   
	    dir->used = 0;
            w->flags1[NR(newpos)] &= ACTIVE;
            bool_op(w, w->flags1, newpos, ~IN_TREE, 0);

            /* try to reconnect the path to some other tree part */
            if(reconnect(w, w->flags1, newpos, 0)) {
                bool_op(w, w->flags1, newpos, ~0, IN_TREE);
            } else {
                destroy_subtree(w, w->flags1, newpos, q1);
                break;
            }
        }
    }

    for(t=path->length-1;t>0 && !path->firsthalf[t-1];t--) {
        node_t*pos = path->pos[t];
        node_t*newpos = path->pos[t-1];
        halfedge_t*dir = path->dir[t-1]->fwd;
        node_t*newpos2 = dir->fwd->node;
        assert(newpos == newpos2);
        if(!dir->fwd->weight) {
            /* disconnect node */
            DBG printf("remove link %d->%d from tree 2\n", NR(pos), NR(newpos));

	    dir->used = 0;
            w->flags2[NR(newpos)] &= ACTIVE;
            bool_op(w, w->flags2, newpos, ~IN_TREE, 0);

            /* try to reconnect the path to some other tree part */
            if(reconnect(w, w->flags2, newpos, 1)) {
                bool_op(w, w->flags2, newpos, ~0, IN_TREE);
            } else {
                destroy_subtree(w, w->flags2, newpos, q2);
                break;
            }
        }
    }
}
Exemple #2
0
/*--------------------------------------------------------------------------*/
FilterResult filter(const char *start, 
                    const char **end, 
                    SLPAttributes slp_attr, 
                    int recursion_depth)
/* Parameters:                                                              */
/* start -- (IN) The start of the string to work in.                        */
/* end -- (OUT) The end of the string processed. After successful processing*/
/*              (ie, no PARSE_ERRORs), this will be pointed at the character*/
/*              following the last char in this level of the expression.    */
/* slp_attr -- (IN) The attributes handle to compare on.                    */
/* return_value -- (OUT) The result of the search. Only valid if SLP_OK was */
/*                       returned.                                          */
/*                                                                          */
/* Returns: SLP_OK on successful search (ie, the search was do-able).       */
/*          SLP_PARSE_ERROR on search error.  The end of the expression is  */
/*          returned through end.                                           */
/*--------------------------------------------------------------------------*/
{
    char *operator; /* Pointer to the operator substring. */
    const char *cur; /* Current working character. */
    const char *last_char; /* The last character in the working string. */
    FilterResult err = FR_UNSET; /* The result of an evaluation. */

    if(recursion_depth <= 0)
    {
        return FR_PARSE_ERROR;
    }

    recursion_depth--;

    if(*start != BRACKET_OPEN)
    {
        return FR_PARSE_ERROR;
    }

    /***** Get the current expression. *****/
    last_char = *end = find_bracket_end(start);
    if(*end == 0)
    {
        return FR_PARSE_ERROR;
    }
    (*end)++; /* Move the end pointer past the closing bracket. */

    /**** 
     * Check for the three legal characters that can follow an expression,
     * if the following character isn't one of those, the following character 
     * is trash.
     ****/
    if(!(**end == BRACKET_OPEN || **end == BRACKET_CLOSE || **end == '\0'))
    {
        return FR_PARSE_ERROR;
    }

    /***** check for boolean op. *****/
    cur = start;
    cur++;

    switch(*cur)
    {
    case('&'): /***** And. *****/
    case('|'): /***** Or. *****/
        {
            FilterResult stop_condition; /* Stop when this value is received. Used for short circuiting. */

            if(*cur == '&')
            {
                stop_condition = FR_EVAL_FALSE;
            }
            else if(*cur == '|')
            {
                stop_condition = FR_EVAL_TRUE;
            }

            cur++; /* Move past operator. */

            /*** Ensure that we have at least one operator. ***/
            if(*cur != BRACKET_OPEN || cur >= last_char)
            {
                return FR_PARSE_ERROR;
            }

            /*** Evaluate each operand. ***/
            /* NOTE: Due to the condition on the above "if", we are guarenteed that the first iteration of the loop is valid. */
            do 
            {
                err = filter(cur, &cur, slp_attr, recursion_depth);
                /*** Propagate errors. ***/
                if(err != FR_EVAL_TRUE && err != FR_EVAL_FALSE)
                {
                    return err;
                }

                /*** Short circuit. ***/
                if(err == stop_condition)
                {
                    return stop_condition;
                }
            } while(*cur == BRACKET_OPEN && cur < last_char); 


            /*** If we ever get here, it means we've evaluated every operand without short circuiting -- meaning that the operation failed. ***/
            return(stop_condition == FR_EVAL_TRUE ? FR_EVAL_FALSE : FR_EVAL_TRUE);
        }


    case('!'): /***** Not. *****/
        /**** Child. ****/
        cur++;
        err = filter(cur, &cur, slp_attr, recursion_depth);
        /*** Return errors. ***/
        if(err != FR_EVAL_TRUE && err != FR_EVAL_FALSE)
        {
            return err;
        }

        /*** Perform "not". ***/
        return(err == FR_EVAL_TRUE ? FR_EVAL_FALSE : FR_EVAL_TRUE);

    default: /***** Unknown operator. *****/
        ;
        /* We don't do anything here because this will catch the first character of every leaf predicate. */
    }

    /***** Check for leaf operator. *****/
    if(IS_VALID_TAG_CHAR(*cur))
    {
        Operation op;
        char *lhs, *rhs; /* The two operands. */
        char *val_start; /* The character after the operator. ie, the start of the rhs. */
        int lhs_len, rhs_len; /* Length of the lhs/rhs. */
        SLPType type;
        SLPError slp_err;

        /**** Demux leaf op. ****/
        /* Since all search operators contain a "=", we look for the equals 
         * sign, and then poke around on either side of that for the real 
         * value. 
         */
        operator = (char *)memchr(cur, '=', last_char - cur);
        if(operator == 0)
        {
            /**** No search operator. ****/
            return FR_PARSE_ERROR;
        }

        /* The rhs always follows the operator. (This doesn't really make 
        sense for PRESENT ops, but ignore that). */
        val_start = operator + 1; 

        /* Check for APPROX, GREATER, or LESS. Note that we shuffle the 
        operator pointer back to point at the start of the op. */
        if(operator == cur)
        {/* Check that we can poke back one char. */
            return FR_PARSE_ERROR;
        }

        switch(*(operator - 1))
        {
        case('~'):
            op = EQUAL; /* See Assumptions. */
            operator--;
            break;
        case('>'):
            op = GREATER;
            operator--;
            break;
        case('<'):
            op = LESS;
            operator--;
            break;
        default: /* No prefix to the '='. */
            /**** Check for PRESENT. ****/
            if((operator == last_char - 2) && (*(operator+1) == '*'))
            {
                op = PRESENT;
            }
            /**** It's none of the above: therefore it's EQUAL. ****/
            else
            {
                op = EQUAL;
            }
        }


        /***** Get operands. *****/
        /**** Left. ****/
        lhs_len = operator - cur;
        lhs = (char *)cur;

        /**** Right ****/
        rhs_len = last_char - val_start;
        rhs = val_start;

        /***** Do leaf operation. *****/
        /**** Check that tag exists. ****/
        slp_err = SLPAttrGetType_len(slp_attr, lhs, lhs_len, &type);
        if(slp_err == SLP_TAG_ERROR)
        { /* Tag  doesn't exist. */
            return FR_EVAL_FALSE;
        }
        else if(slp_err == SLP_OK)
        { /* Tag exists. */
            /**** Do operation. *****/
            if(op == PRESENT)
            {
                /*** Since the PRESENT operation is the same for all types, 
                do that now. ***/
                return FR_EVAL_TRUE;
            }
            else
            {
                /*** A type-specific operation. ***/
                switch(type)
                {
                case(SLP_BOOLEAN):
                    err = bool_op(slp_attr, lhs, lhs_len, rhs, rhs_len, op); 
                    break;
                case(SLP_INTEGER):
                    err = int_op(slp_attr, lhs, lhs_len, rhs, op); 
                    break;
                case(SLP_KEYWORD):
                    err = keyw_op(slp_attr, lhs, rhs, op); 
                    break;
                case(SLP_STRING):
                    err = str_op(slp_attr, lhs, lhs_len, rhs, rhs_len, op); 
                    break;
                case(SLP_OPAQUE):
                    assert(0); /* Opaque is not yet supported. */
                }
            }
        }
        else
        { /* Some other tag-related error. */
            err = FR_INTERNAL_SYSTEM_ERROR;
        }

        assert(err != FR_UNSET);
        return err;
    }

    /***** No operator. *****/
    return FR_PARSE_ERROR;
}