I'm tired of writing:
bool sep = false;
while (...) {
if (sep)
virBufferAddChar(buf, ',');
sep = true;
virBufferAdd(buf, str);
}
This makes it easier, allowing one to write:
while (...)
virBufferAsprintf(buf, "%s,", str);
virBufferTrim(buf, ",", -1);
to trim any remaining comma.
* src/util/buf.h (virBufferTrim): Declare.
* src/util/buf.c (virBufferTrim): New function.
* tests/virbuftest.c (testBufTrim): Test it.
Return statements with parameter enclosed in parentheses were modified
and parentheses were removed. The whole change was scripted, here is how:
List of files was obtained using this command:
git grep -l -e '\<return\s*([^()]*\(([^()]*)[^()]*\)*)\s*;' | \
grep -e '\.[ch]$' -e '\.py$'
Found files were modified with this command:
sed -i -e \
's_^\(.*\<return\)\s*(\(\([^()]*([^()]*)[^()]*\)*\))\s*\(;.*$\)_\1 \2\4_' \
-e 's_^\(.*\<return\)\s*(\([^()]*\))\s*\(;.*$\)_\1 \2\3_'
Then checked for nonsense.
The whole command looks like this:
git grep -l -e '\<return\s*([^()]*\(([^()]*)[^()]*\)*)\s*;' | \
grep -e '\.[ch]$' -e '\.py$' | xargs sed -i -e \
's_^\(.*\<return\)\s*(\(\([^()]*([^()]*)[^()]*\)*\))\s*\(;.*$\)_\1 \2\4_' \
-e 's_^\(.*\<return\)\s*(\([^()]*\))\s*\(;.*$\)_\1 \2\3_'
Rather than having to adjust all callers in a chain to deal with
indentation, it is nicer to have virBuffer do auto-indentation.
* src/util/buf.h (_virBuffer): Increase size.
(virBufferAdjustIndent, virBufferGetIndent): New prototypes.
* src/libvirt_private.syms (buf.h): Export new functions.
* src/util/buf.c (virBufferAdjustIndent, virBufferGetIndent): New
functions.
(virBufferSetError, virBufferAdd, virBufferAddChar)
(virBufferVasprintf, virBufferStrcat, virBufferURIEncodeString):
Implement auto-indentation.
* tests/virbuftest.c (testBufAutoIndent): Test it.
(testBufInfiniteLoop): Don't rely on internals.
Idea by Daniel P. Berrange.
We already have virAsprintf, so picking a similar name helps for
seeing a similar purpose. Furthermore, the prefix V before printf
generally implies 'va_list', even though this variant was '...', and
the old name got in the way of adding a new va_list version.
global rename performed with:
$ git grep -l virBufferVSprintf \
| xargs -L1 sed -i 's/virBufferVSprintf/virBufferAsprintf/g'
then revert the changes in ChangeLog-old.
A few of the tests were missing basic sanity checks, while most
of them were doing copy-and-paste initialization (in fact, some
of them pasted the argc > 1 check more than once!). It's much
nicer to do things in one common place, and minimizes the size of
the next patch that fixes getcwd usage.
* tests/testutils.h (EXIT_AM_HARDFAIL): New define.
(progname, abs_srcdir): Define for all tests.
(VIRT_TEST_MAIN): Change callback signature.
* tests/testutils.c (virtTestMain): Do more common init.
* tests/commandtest.c (mymain): Simplify.
* tests/cputest.c (mymain): Likewise.
* tests/esxutilstest.c (mymain): Likewise.
* tests/eventtest.c (mymain): Likewise.
* tests/hashtest.c (mymain): Likewise.
* tests/networkxml2xmltest.c (mymain): Likewise.
* tests/nodedevxml2xmltest.c (myname): Likewise.
* tests/nodeinfotest.c (mymain): Likewise.
* tests/nwfilterxml2xmltest.c (mymain): Likewise.
* tests/qemuargv2xmltest.c (mymain): Likewise.
* tests/qemuhelptest.c (mymain): Likewise.
* tests/qemuxml2argvtest.c (mymain): Likewise.
* tests/qemuxml2xmltest.c (mymain): Likewise.
* tests/qparamtest.c (mymain): Likewise.
* tests/sexpr2xmltest.c (mymain): Likewise.
* tests/sockettest.c (mymain): Likewise.
* tests/statstest.c (mymain): Likewise.
* tests/storagepoolxml2xmltest.c (mymain): Likewise.
* tests/storagevolxml2xmltest.c (mymain): Likewise.
* tests/virbuftest.c (mymain): Likewise.
* tests/virshtest.c (mymain): Likewise.
* tests/vmx2xmltest.c (mymain): Likewise.
* tests/xencapstest.c (mymain): Likewise.
* tests/xmconfigtest.c (mymain): Likewise.
* tests/xml2sexprtest.c (mymain): Likewise.
* tests/xml2vmxtest.c (mymain): Likewise.
The current code will go into an infinite loop if the printf generated
string is >= 1000, AND exactly 1 character smaller than the amount of free
space in the buffer. When this happens, we are dropped into the loop body,
but nothing will actually change, because count == (buf->size - buf->use - 1),
and virBufferGrow returns unchanged if count < (buf->size - buf->use)
Fix this by removing the '- 1' bit from 'size'. The *nprintf functions handle
the NULL byte for us anyways, so we shouldn't need to manually accommodate
for it.
Here's a bug where we are actually hitting this issue:
https://bugzilla.redhat.com/show_bug.cgi?id=602772
v2: Eric's improvements: while -> if (), remove extra va_list variable,
make sure we report buffer error if snprintf fails
v3: Add tests/virbuftest which reproduces the infinite loop before this
patch, works correctly after