Пример #1
0
range* do_range_expand(range_request* rr, const char* text)
{
    yyscan_t scanner;
    struct range_extras extra;
    int result;

    if (text == NULL) {
        range* r = range_new(rr);
        range_request_set(rr, r);
        return r;
    }
    current_rr = rr;
    extra.rr = rr;

    yylex_init(&scanner);
    yyset_extra(&extra, scanner);
    yy_scan_string(text, scanner);
    result = yyparse(scanner);
    yylex_destroy(scanner);
    current_rr = NULL;

    if (result != 0) {
        range* r = range_new(rr);
        range_request_warn(rr, "parsing [%s]", text);
        range_request_set(rr, r);
        return r;
    }

    range_request_set(rr, range_evaluate(rr, extra.theast));
    return range_request_results(rr);
}
Пример #2
0
range* range_evaluate(range_request* rr, const rangeast* ast)
{
    range* r;
    int i;
    rangeast* rtmp;
    range** ranges;
    range* r1;
    range* r2;
    range* r3;
    apr_pool_t* pool = range_request_pool(rr);
    
    switch (ast->type) {
        case AST_LITERAL:
            r = range_from_literal(rr, ast->data.string);
            return r;
        case AST_NONRANGE_LITERAL:
            r = range_from_nonrange_literal(rr, ast->data.string);
            return r;
        case AST_UNION:
            r1 = range_evaluate(rr, ast->children);
            r2 = range_evaluate(rr, ast->children->next);
            if (range_members(r1) > range_members(r2)) {
                range_union_inplace(rr, r1, r2);
                range_destroy(r2);
                return r1;
            } else {
                range_union_inplace(rr, r2, r1);
                range_destroy(r1);
                return r2;
            }
        case AST_GROUP:
            r1 = range_evaluate(rr, ast->children);
            r = range_from_group(rr, r1);
            range_destroy(r1);
            return r;
        case AST_DIFF:
            r1 = range_evaluate(rr, ast->children);
            if (ast->children->next->type == AST_REGEX) 
                r2 = range_from_match(rr, r1, ast->children->next->data.string);
            else
                r2 = range_evaluate(rr, ast->children->next);
            range_diff_inplace(rr, r1, r2);
            return r1;
        case AST_INTER:
            r1 = range_evaluate(rr, ast->children);
            if (ast->children->next->type == AST_REGEX)
                r2 = range_from_match(rr, r1, ast->children->next->data.string);
            else
                r2 = range_evaluate(rr, ast->children->next);
            r = range_from_inter(rr, r1, r2);
            range_destroy(r1);
            range_destroy(r2);
            return r;
        case AST_NOT:
            ranges = (range **)apr_palloc(pool, sizeof(range *) * (2));
            ranges[0] = range_from_literal(rr, "all:CLUSTER");
            ranges[1] = NULL;
            r1 = range_from_function(rr, "cluster", (const range**)ranges);
            r2 = range_evaluate(rr, ast->children);
            range_diff_inplace(rr, r1, r2);
            range_destroy(r2);
            range_destroy(ranges[0]);
            return r1;
        case AST_REGEX:
            ranges = (range **)apr_palloc(pool, sizeof(range *) * (2));
            ranges[0] = range_from_literal(rr, "all:CLUSTER");
            ranges[1] = NULL;
            r1 = range_from_function(rr, "cluster", (const range**)ranges);
            r = range_from_match(rr, r1, ast->data.string);
            range_destroy(r1);
            range_destroy(ranges[0]);
            return r;
        case AST_PARTS:
            r = range_from_rangeparts(rr, ast->data.parts);
            return r;
        case AST_BRACES:
            r1 = range_evaluate(rr, ast->children);
            r2 = range_evaluate(rr, ast->children->next);
            r3 = range_evaluate(rr, ast->children->next->next);
            r = range_from_braces(rr, r1, r2, r3);
            range_destroy(r1);
            range_destroy(r2);
            range_destroy(r3);
            return r;
        case AST_FUNCTION:
            i=0;
            for (rtmp = ast->children; rtmp; rtmp = rtmp->next)
                i++;

            ranges = (range **)apr_palloc(pool, sizeof(range *) * (i+1));
            ranges[i] = NULL;
            i=0;
            for (rtmp = ast->children; rtmp; rtmp = rtmp->next)
                ranges[i++] = range_evaluate(rr, rtmp);

            r = range_from_function(rr, ast->data.string, (const range**)ranges);
            for (i=0; ranges[i]; i++) range_destroy(ranges[i]);

            return r;
        case AST_NOTHING:
            r = range_new(rr);
            return r;
        default:
            fprintf(stderr, "ERROR IN LIBCRANGE: Corrupted AST\n");
            abort();
    }
}