I agree that it would be better to avoid dynamic memory allocation here. Such a decision could be left to the caller, and if necessary one could write a wrapper. That said, I also agree that your code seems overly complicated, including the version from post #9. Trying my hand, I came up with:
Code:
char *insertstr(char *haystack, char const *needle, size_t size, size_t pos)
{
const size_t haystack_len = strlen(haystack);
const size_t needle_len = strlen(needle);
const size_t total_len = haystack_len + needle_len;
if (total_len >= size)
{
return NULL;
}
else if (needle_len == 0)
{
return haystack;
}
if (pos > haystack_len)
{
pos = haystack_len;
}
memmove(haystack + pos + needle_len, haystack + pos, haystack_len - pos);
strncpy(haystack + pos, needle, needle_len);
haystack[total_len] = '\0';
return haystack;
}
If you fear that memmove might be relatively expensive, then you can replace it with a loop that starts from the back to avoid overwriting across an overlap:
Code:
char *insertstr(char *haystack, char const *needle, size_t size, size_t pos)
{
const size_t haystack_len = strlen(haystack);
const size_t needle_len = strlen(needle);
const size_t total_len = haystack_len + needle_len;
size_t i;
if (total_len >= size)
{
return NULL;
}
else if (needle_len == 0)
{
return haystack;
}
if (pos > haystack_len)
{
pos = haystack_len;
}
i = haystack_len;
while (i-- > pos)
{
haystack[i + needle_len] = haystack[i];
}
strncpy(haystack + pos, needle, needle_len);
haystack[total_len] = '\0';
return haystack;
}