Ejemplo n.º 1
0
int main(int argc, char *argv[])
{
	printf("%s----%s--->%d\n", argv[1], argv[2], sub_str_count(argv[1], argv[2]));
	return 0;
}
Ejemplo n.º 2
0
char *
string_replace(struct sol_flow_node *node,
    char *value,
    char *change_from,
    char *change_to,
    bool *replaced,
    size_t max_count)
{
    char *ret = NULL;
    size_t value_len = strlen(value);
    size_t change_to_len = strlen(change_to);
    size_t change_from_len = strlen(change_from);

    *replaced = true;

    if (max_count == 0) {
        ret = strdup(value);
        goto end;
    }

    if (strcmp(change_from, change_to) == 0) {
        ret = strdup(value);
        goto end;
    }

    if (change_from_len == change_to_len) {
        /* same length */
        if (change_from_len == 0) {
            ret = strdup(value);
            goto end;
        }
        if (change_from_len == 1) {
            /* replace characters */
            ret = strdup(value);
            replace_1_char_in_place(ret, ret + value_len, change_from[0],
                change_to[0], max_count);
        } else {
            char *token;
            ssize_t i;

            ret = strdup(value);
            token = memmem(value, value_len, change_from, change_from_len);
            if (!token)
                goto end;

            i = token - value;

            memcpy(ret, value, value_len);
            /* change everything in-place, starting with this one */
            memcpy(ret +  i, change_to, change_to_len);
            i += change_from_len;

            while (--max_count > 0) {
                token = memmem(value + i, value_len - i, change_from,
                    change_from_len);
                if (!token)
                    break;
                memcpy(ret +  i, change_to, change_to_len);
                i += change_from_len;
            }
        }
    } else {
        ssize_t count, i, j, ires, new_size;
        int r;

        count = sub_str_count(value, value_len,
            change_from, change_from_len, max_count);
        if (count == 0) {
            ret = strdup(value);
            goto end;
        }

        if (change_from_len < change_to_len &&
            change_to_len - change_from_len >
            (INT32_MAX - value_len) / count) {
            sol_flow_send_error_packet(node, EINVAL,
                "replace string is too long");
            goto end;
        }
        r = sol_util_ssize_mul(count,
            (ssize_t)(change_to_len - change_from_len), &new_size);
        if (r < 0 ||
            (new_size > 0 && SSIZE_MAX - new_size < (ssize_t)value_len)) {
            sol_flow_send_error_packet(node, EINVAL,
                "replace string is too long");
            goto end;
        }

        new_size += value_len;

        if (new_size == 0) {
            ret = (char *)"";
            goto end;
        }

        ret = calloc(new_size + 1, sizeof(*ret));
        if (!ret)
            goto end;

        ires = i = 0;
        if (change_from_len > 0) {
            while (count-- > 0) {
                char *token;

                /* look for next match */
                token = memmem(value + i, value_len - i, change_from,
                    change_from_len);
                if (!token) {
                    free(ret);
                    ret = strdup(value);
                    return ret;
                }

                j = sub_str_find(value +  i, value_len - i,
                    change_from, change_from_len, i);
                if (j == -1)
                    break;
                else if (j > i) {
                    /* copy unchanged part [i:j] */
                    memcpy(ret +  ires, value +  i, (j - i));
                    ires += j - i;
                }
                /* copy substitution string */
                if (change_to_len > 0) {
                    memcpy(ret +  ires, change_to, change_to_len);
                    ires += change_to_len;
                }
                i = j + change_from_len;
            }
            if (i < (ssize_t)value_len)
                /* copy tail [i:] */
                memcpy(ret +  ires, value +  i, (value_len - i));
        } else {
            /* interleave */
            while (count > 0) {
                memcpy(ret +  ires, change_to, change_to_len);
                ires += change_to_len;
                if (--count <= 0)
                    break;
                memcpy(ret +  ires, value +  i, 1);
                ires++;
                i++;
            }
            memcpy(ret +  ires, value +  i, (value_len - i));
        }
    }

    return ret;

// no changes (ret != NULL) and error (ret == NULL) cases
end:
    *replaced = false;
    return ret;
}