Ejemplo n.º 1
0
static struct value *lns_value_of_type(struct info *info, struct regexp *rx) {
    struct value *result = make_value(V_REGEXP, ref(info));
    if (rx)
        result->regexp = ref(rx);
    else
        result->regexp = regexp_make_empty(ref(info));
    return result;
}
Ejemplo n.º 2
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;
}