Ejemplo n.º 1
0
SOL_API struct sol_vector
sol_str_slice_split(const struct sol_str_slice slice,
    const char *delim,
    size_t maxsplit)
{
    struct sol_vector v = SOL_VECTOR_INIT(struct sol_str_slice);
    const char *str = slice.data;
    ssize_t dlen;
    size_t len;

    if (!slice.len || !delim)
        return v;

    maxsplit = (maxsplit) ? : slice.len - 1;
    if (maxsplit == SIZE_MAX) //once we compare to maxsplit + 1
        maxsplit--;

    dlen = strlen(delim);
    len = slice.len;

#define CREATE_SLICE(_str, _len) \
    do { \
        s = sol_vector_append(&v); \
        if (!s) \
            goto err; \
        s->data = _str; \
        s->len = _len; \
    } while (0)

    while (str && (v.len < maxsplit + 1)) {
        struct sol_str_slice *s;
        char *token = memmem(str, len, delim, dlen);
        if (!token) {
            CREATE_SLICE(str, len);
            break;
        }

        if (v.len == (uint16_t)maxsplit)
            CREATE_SLICE(str, len);
        else
            CREATE_SLICE(str, (size_t)(token - str));

        len -= (token - str) + dlen;
        str = token + dlen;
    }
#undef CREATE_SLICE

    return v;

err:
    sol_vector_clear(&v);
    return v;
}
Ejemplo n.º 2
0
struct sol_vector
sol_util_str_split(const struct sol_str_slice slice, const char *delim, size_t maxsplit)
{
    struct sol_vector v = SOL_VECTOR_INIT(struct sol_str_slice);
    ssize_t dlen, len;
    const char *str = slice.data;

    if (!slice.len || !delim)
        return v;

    maxsplit = (maxsplit) ? : slice.len;
    dlen = strlen(delim);
    len = slice.len;

#define CREATE_SLICE(_str, _len) \
    do { \
        s = sol_vector_append(&v); \
        if (!s) \
            goto err; \
        s->data = _str; \
        s->len = _len; \
    } while (0)

    while (str && (v.len < maxsplit)) {
        struct sol_str_slice *s;
        char *token = memmem(str, len, delim, dlen);
        if (!token) {
            CREATE_SLICE(str, len);
            break;
        }

        len -= (token - str) + dlen;
        CREATE_SLICE(str, token - str);
        str = token + dlen;
    }
#undef CREATE_SLICE

    return v;

err:
    sol_vector_clear(&v);
    return v;
}
Ejemplo n.º 3
0
static struct sol_vector
string_regexp_search_and_split(struct string_regexp_search_data *mdata)
{
    int r;
    size_t str_len, match_sz;
    pcre *compiled_re = NULL;
    pcre_extra *p_extra = NULL;
    int *match_vector, sub_match_count = 0;
    struct sol_vector v = SOL_VECTOR_INIT(struct sol_str_slice);

#define CREATE_SLICE(_str, _len) \
    do { \
        struct sol_str_slice *s; \
        s = sol_vector_append(&v); \
        if (!s) \
            goto err; \
        s->data = (const char *)_str; \
        s->len = _len; \
    } while (0)

    //mdata->string should never be NULL
    str_len = strlen(mdata->string);
    if (!str_len)
        return v;

    r = pcre_compile_do(mdata->node, mdata->regexp, &compiled_re,
        &p_extra, &sub_match_count);
    SOL_INT_CHECK(r, < 0, v);

    match_sz = (sub_match_count + 1) * 3;
    match_vector = calloc(match_sz, sizeof(*match_vector));

    r = pcre_exec(compiled_re, p_extra, mdata->string, str_len,
        0, 0, match_vector, match_sz);

    if (r < 0) {
        sol_flow_send_error_packet(mdata->node, EINVAL,
            "Fail on matching regular expression '%s' on string %s",
            mdata->regexp, mdata->string);
        goto err;
    } else {
        int i;

        /* The value returned by pcre_exec() is one more than the
         * highest numbered pair that has been set. If the vector is
         * too small to hold all the captured substring offsets, it is
         * used as far as possible (up to two-thirds of its length),
         * and the function returns a value of zero.
         */
        if (r == 0) { // should not happen, but let's treat the case
            sol_flow_send_error_packet(mdata->node, EINVAL,
                "A memory overflow happened while executing"
                " regular expression '%s' on string %s",
                mdata->regexp, mdata->string);
            goto err;
        }
        for (i = 0; i < r; i++) {
            CREATE_SLICE(mdata->string + match_vector[i * 2],
                match_vector[i * 2 + 1] - match_vector[i * 2]);
        }
    }

err:
    if (p_extra != NULL)
        pcre_free(p_extra);
    pcre_free(compiled_re);
    free(match_vector);

    return v;
#undef CREATE_SLICE
}