Пример #1
0
Файл: types.c Проект: 8l/awl
static awlval* awlval_slice_step_str(awlval* x, int start, int end, int step) {
    char* sliced = strsubstr(x->str, start, end);
    if (step > 1 && strlen(sliced)) {
        char* stepped = strstep(sliced, step);
        free(sliced);
        sliced = stepped;
    }
    free(x->str);
    x->str = sliced;
    return x;
}
Пример #2
0
/**
 * Make sub-string replacing by regular compiled expression matching
 *
 * @param __re - compiled regular expression
 * @param __s - source string
 * @param __mask - mask of replacement
 * @return replaced string
 * @sideeffect allocate memory for return value
 */
char*
regexp_replace (const regexp_t *__re, const char *__s, const char *__mask)
{
    char *shift = (char*)__s;
    char *dummy, *prefix = NULL, *buf = NULL;
    size_t l, r, len, buf_len = 0, prefix_len = 0;

    for (;;)
    {
        dummy = regexp_replace_iterator (__re, shift, __mask, &l, &r);
        len = 0;

        if (dummy)
        {
            len = strlen (dummy);
        }

        if (l > 0)
        {
            /* There is non-empty prefix */

            if (prefix_len < l)
            {
                prefix_len = l;
                prefix = realloc (prefix, prefix_len + 1);
            }

            strsubstr (shift, 0, l, prefix);
        }
        else
        {
            if (!prefix)
            {
                prefix = strdup ("");
                prefix_len = 0;
            }
            else
            {
                prefix[0] = 0;
            }
        }

        if (l + len > 0)
        {
            BOOL zerolize = 0;
            /* It there is something to append */
            buf_len += l + len;

            if (!buf)
            {
                zerolize = TRUE;
            }

            buf = realloc (buf, buf_len + 1);

            if (zerolize)
            {
                buf[0] = 0;
            }

            /* Append new prefix to buffer */
            strcat (buf, prefix);

            if (dummy)
            {
                /* Append replaced string and free it */
                strcat (buf, dummy);
                free (dummy);
            }
        }

        shift += r;

        if (!dummy || !r ||
                !TEST_FLAG (__re->modifiers, REGEXP_REPLACE_GLOBAL))
        {
            /* FINITO */
            break;
        }
    }

    SAFE_FREE (prefix);

    /* Append suffix */
    buf_len += strlen (shift);

    if (buf)
    {
        buf = realloc (buf, buf_len + 1);
        strcat (buf, shift);
    }
    else
    {
        buf = malloc (buf_len + 1);
        strcpy (buf, shift);
    }

    return buf;
}
Пример #3
0
/**
 * Iterator for regexp_replace()
 *
 * @param __re - compiled regular expression
 * @param __s - source string
 * @param __mask - mask of replacement
 * @param __l - left offset of replaced sub-string
 * @param __r - right offset of replaced sub-string
 * @return replaced string
 * @sideeffect allocate memory for return value
 */
static char*
regexp_replace_iterator (const regexp_t *__re,
                         const char *__s, const char *__mask,
                         size_t *__l, size_t *__r)
{
    int i, vector_count;

    char *token, *shift, *append;
    char *out = NULL;
    char **substrings = NULL;

    size_t len, cur_size = 0;

    int ovector_size = (strlen (__s) + 1) * 2;
    int *ovector = malloc (sizeof (int) * ovector_size);
    int flags, errno;

    (*__l) = (*__r) = 0;

    /* Get the vector of matches */
    vector_count = regexp_get_vector (__re, __s, ovector, ovector_size);
    if (vector_count <= 0)
    {
        /* No matched sub-strings */
        return 0;
    }

    /* Get named sub-strings */
    substrings = malloc (vector_count * sizeof (char*));
    for (i = 0; i < vector_count; i++)
    {
        len = ovector[i * 2 + 1] - ovector[i * 2];
        substrings[i] = malloc (len + 1);
        strsubstr (__s, ovector[i * 2], len, substrings[i]);
    }

    shift = (char*)__mask;

    len = strlen (__mask);
    cur_size = len + 1;
    MALLOC_ZERO (out, cur_size);

    /* Token can't be longer than mask string */
    token = malloc (len + 1);

    while ((shift = replace_parser_iterator (shift, &token, &flags, &errno)))
    {
        if (errno == REGEXP_OK)
        {
            if (flags & PF_NAMED_STRING)
            {
                /* Numbered string */
                int index = atoi (token);
                if (index >= vector_count)
                {
                    /* If index is out of range, append empty string */
                    append = "";
                }
                else
                {
                    append = substrings[index];
                }
            }
            else
            {
                /* Just append token */
                append = token;
            }

            len = strlen (append);
            cur_size += len;
            out = realloc (out, cur_size);

            strcat (out, append);
        }
        else
        {
            SAFE_FREE (out);
            break;
        }
    }

    free (token);

    (*__l) = ovector[0];
    (*__r) = ovector[1];

    for (i = 0; i < vector_count; ++i)
    {
        free (substrings[i]);
    }

    free (substrings);
    free (ovector);

    return out;
}