int main(int argc, char *argv[]) { printf("%s----%s--->%d\n", argv[1], argv[2], sub_str_count(argv[1], argv[2])); return 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; }