Exemplo n.º 1
0
/*
 * Typechecking of lenses
 */
static struct value *disjoint_check(struct info *info, const char *msg,
                                    struct regexp *r1, struct regexp *r2) {
    struct fa *fa1 = NULL;
    struct fa *fa2 = NULL;
    struct fa *fa = NULL;
    struct value *exn = NULL;

    exn = regexp_to_fa(r1, &fa1);
    if (exn != NULL)
        goto done;

    exn = regexp_to_fa(r2, &fa2);
    if (exn != NULL)
        goto done;

    fa = fa_intersect(fa1, fa2);
    if (! fa_is_basic(fa, FA_EMPTY)) {
        size_t xmpl_len;
        char *xmpl;
        fa_example(fa, &xmpl, &xmpl_len);
        exn = make_exn_value(ref(info),
                             "overlapping lenses in %s", msg);

        exn_printf_line(exn, "Example matched by both: '%s'", xmpl);
        free(xmpl);
    }

 done:
    fa_free(fa);
    fa_free(fa1);
    fa_free(fa2);

    return exn;
}
Exemplo n.º 2
0
Arquivo: regexp.c Projeto: mchf/augeas
struct regexp *
regexp_minus(struct info *info, struct regexp *r1, struct regexp *r2) {
    struct regexp *result = NULL;
    struct fa *fa = NULL, *fa1 = NULL, *fa2 = NULL;
    int r;
    char *s = NULL;
    size_t s_len;

    fa1 = regexp_to_fa(r1);
    ERR_BAIL(r1->info);

    fa2 = regexp_to_fa(r2);
    ERR_BAIL(r2->info);

    fa = fa_minus(fa1, fa2);
    if (fa == NULL)
        goto error;

    r = fa_as_regexp(fa, &s, &s_len);
    if (r < 0)
        goto error;

    if (s == NULL) {
        /* FA is the empty set, which we can't represent as a regexp */
        goto error;
    }

    if (regexp_c_locale(&s, NULL) < 0)
        goto error;

    result = make_regexp(info, s, fa_is_nocase(fa));
    s = NULL;

 done:
    fa_free(fa);
    fa_free(fa1);
    fa_free(fa2);
    free(s);
    return result;
 error:
    unref(result, regexp);
    goto done;
}
Exemplo n.º 3
0
static struct value *ambig_concat_check(struct info *info, const char *msg,
                                        struct regexp *r1, struct regexp *r2) {
    struct fa *fa1 = NULL;
    struct fa *fa2 = NULL;
    struct value *result = NULL;

    result = regexp_to_fa(r1, &fa1);
    if (result != NULL)
        goto done;

    result = regexp_to_fa(r2, &fa2);
    if (result != NULL)
        goto done;

    result = ambig_check(info, fa1, fa2, msg);
 done:
    fa_free(fa1);
    fa_free(fa2);
    return result;
}
Exemplo n.º 4
0
static struct value *ambig_iter_check(struct info *info, const char *msg,
                                      struct regexp *r) {
    struct fa *fas = NULL, *fa = NULL;
    struct value *result = NULL;

    result = regexp_to_fa(r, &fa);
    if (result != NULL)
        goto done;

    fas = fa_iter(fa, 0, -1);

    result = ambig_check(info, fa, fas, msg);

 done:
    fa_free(fa);
    fa_free(fas);
    return result;
}
Exemplo n.º 5
0
/*
 * Lens primitives
 */
struct value *lns_make_prim(enum lens_tag tag, struct info *info,
                            struct regexp *regexp, struct string *string) {
    struct lens *lens = NULL;
    struct value *exn = NULL;
    struct fa *fa_slash = NULL;
    struct fa *fa_key = NULL;
    struct fa *fa_isect = NULL;

    /* Typecheck */
    if (tag == L_KEY) {
        exn = str_to_fa(info, "(.|\n)*/(.|\n)*", &fa_slash);
        if (exn != NULL)
            goto error;

        exn = regexp_to_fa(regexp, &fa_key);
        if (exn != NULL)
            goto error;

        fa_isect = fa_intersect(fa_slash, fa_key);
        if (! fa_is_basic(fa_isect, FA_EMPTY)) {
            exn = make_exn_value(info,
                                 "The key regexp /%s/ matches a '/'",
                                 regexp->pattern->str);
            goto error;
        }
        fa_free(fa_isect);
        fa_free(fa_key);
        fa_free(fa_slash);
        fa_isect = fa_key = fa_slash = NULL;
    } else if (tag == L_LABEL) {
        if (strchr(string->str, SEP) != NULL) {
            exn = make_exn_value(info,
                                 "The label string \"%s\" contains a '/'",
                                 string->str);
            goto error;
        }
    } else if (tag == L_DEL) {
        int cnt;
        const char *dflt = string->str;
        cnt = regexp_match(regexp, dflt, strlen(dflt), 0, NULL);
        if (cnt != strlen(dflt)) {
            char *s = escape(dflt, -1);
            char *r = escape(regexp->pattern->str, -1);
            exn = make_exn_value(info,
                   "del: the default value '%s' does not match /%s/",
                   s, r);
            FREE(s);
            FREE(r);
            goto error;
        }
    }

    /* Build the actual lens */
    lens = make_lens(tag, info);
    lens->regexp = regexp;
    lens->string = string;
    lens->key = (tag == L_KEY || tag == L_LABEL || tag == L_SEQ);
    lens->value = (tag == L_STORE);
    lens->consumes_value = (tag == L_STORE);
    lens->atype = regexp_make_empty(info);
    if (tag == L_DEL || tag == L_STORE || tag == L_KEY) {
        lens->ctype = ref(regexp);
    } else if (tag == L_LABEL || tag == L_SEQ || tag == L_COUNTER) {
        lens->ctype = regexp_make_empty(info);
    } else {
        assert(0);
    }
    return make_lens_value(lens);
 error:
    fa_free(fa_isect);
    fa_free(fa_key);
    fa_free(fa_slash);
    return exn;
}