On Fri, Nov 30, 2012 at 11:02:40AM -0500, Eric Blake wrote:
> This introduces a few new APIs for dealing with strings.
> One to split a char * into a char **, another to join a
> char ** into a char *, and finally one to free a char **
Do we also want to migrate virsh.c:vshStringToArray() to
this file, with its additional magic of supporting ',,'
as an escape sequence for literal comma in one of the
strings being split?
I don't really like that magic escape behaviour for a
general purpose string splitting function. IMHO if the
thing being split needs to use ',' then the delimitor
should be changed.
> +char *virStringJoin(const char **strings,
> + const char *delim)
> +{
Should this function have a third argument that says how many
elements are in strings (and leave it 0 if strings is
NULL-terminated)? Otherwise, callers will have to ensure
that there is a trailing NULL element in strings, instead
of being able to specifically request the joining of an
exact amount of strings.
I don't much like the idea of having one API that deals
with two different ways of representing the array bounds.
If we want explicited sized arrays, I think it'd be nicer
to have a parallel set of APIs todo that (albeit sharing
internal impl where appropriate)
> + size_t len = 0;
> + size_t delimlen = strlen(delim);
> + const char **tmp = strings;
> + char *string;
> + char *offset;
> +
> + while (tmp && *tmp) {
> + len += strlen(*tmp);
> + len += delimlen;
> + tmp++;
> + }
Would it be any easier to write this function in terms of
virBuffer, instead of rolling it by hand? Untested:
char *virStringJoin(const char **strings,
const char *delim)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
if (strings && *strings) {
virBufferAdd(&buf, *strings, 0);
while (*++strings) {
virBufferAdd(&buf, delim, 0);
virBufferAdd(*strings);
}
}
return virBufferContentAndReset(&buf);
}
I guess there's not much difference in efficiency
there & it is shorter, so why not.
> +char **virStringSplit(const char *string,
> + const char *delim,
> + size_t max_tokens);
Worth marking ATTRIBUTE_NONNULL(2)? It looks like you
intend to allow NULL for arg 1 though (in which case the
return is also NULL).
We shouldn't allow NULL for arg 1, since then
a NULL return value can be either an error or
valid, depending on the parameters, which has
unpleasant semantics.
Daniel
--
|:
http://berrange.com -o-
http://www.flickr.com/photos/dberrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|:
http://entangle-photo.org -o-
http://live.gnome.org/gtk-vnc :|