Better to write a piece of code of the general form:
while (condition) {
/* concatenate thingb onto thinga */
}
This method seems far too redundant especially when frequently used
in practice. I see little advantage to using it apose to the current
implementation of my function, which could be described as a variadic
implementation of strlcat().
The largest problem with the current version is the usage of an 'end
of list' marker, which could easily be omitted. If it where omitted,
the bug would be simple to trace however. I would like to hear about
any concerns you have about its current implementation and use.
[...] I know of no second version, my implementation is unchanged, is
portable, and has no known reentrancy or threading problems. [...]
The second version I was refering to was that of my function:
Example:
char vbuf[VAST_BUF];
ret = vast(vbuf, VAST_BUF, "Put it", " together.", EOL);
Well, here you are starting at the right end, the interface to your
function. Get that right and you can then implement it in various
ways. My objection to your above interface is that there is no way
to control or prevent overflow, which is one of the points of
strlcat (its return shows what is actually needed). The other
direction is to have the routine always saw off the required space
via malloc, so it never fails barring memory exhaustion. Then your
prototype interface would be:
char *bigcat(const char *s1, ...);
returning NULL on failure, and requiring a final NULL in the list
of concatanees. The only interfacing foulup possible is omitting
the final NULL. An initial NULL could simply return an empty
string, so you can confidently pass the non-null results onward.
You are also confident that the returned item can be passed to
free. There are also no restrictions on the input strings
origins. The usage could then be:
if (!(s = bigcat(s1, s2, s3, s4, NULL))) theoperationfailed();
else {
/* further processing and use of s */
free(s);
}
s = NULL;
In fact, you can safely use this to inject things in front of a
bigcat string within the "further processing" above by:
s = bigcat("prefix string", s, NULL)
except that that is liable to a memory leak when the prefix
operation fails, similar to having realloc fail. The cure is the
same, use a temp.
Just some random thoughts.