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 :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list