From 7cfdcd004ec9c29b2d3ff288c41de24c82c58125 Mon Sep 17 00:00:00 2001 Message-Id: <7cfdcd004ec9c29b2d3ff288c41de24c82c58125.1386348946.git.jdenemar@redhat.com> From: "Daniel P. Berrange" Date: Mon, 2 Dec 2013 13:39:09 +0000 Subject: [PATCH] Introduce standard methods for sorting strings with qsort For https://bugzilla.redhat.com/show_bug.cgi?id=1035403 Add virStringSortCompare and virStringSortRevCompare as standard functions to use with qsort. Signed-off-by: Daniel P. Berrange (cherry picked from commit c60a2713d69e2cdbeac8bbdd85f49acdbae47600) Signed-off-by: Jiri Denemark --- src/libvirt_private.syms | 2 ++ src/lxc/lxc_container.c | 14 ++------------ src/util/virstring.c | 29 +++++++++++++++++++++++++++++ src/util/virstring.h | 3 +++ tests/virstringtest.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 82 insertions(+), 12 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 0421c5b..6821352 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1928,6 +1928,8 @@ virStringArrayHasString; virStringFreeList; virStringJoin; virStringListLength; +virStringSortCompare; +virStringSortRevCompare; virStringSplit; virStrncpy; virStrndup; diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index 01ed93e..c2cbfb4 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -483,16 +483,6 @@ error_out: /*_syscall2(int, pivot_root, char *, newroot, const char *, oldroot)*/ extern int pivot_root(const char * new_root,const char * put_old); -static int lxcContainerChildMountSort(const void *a, const void *b) -{ - const char **sa = (const char**)a; - const char **sb = (const char**)b; - - /* Deliberately reversed args - we need to unmount deepest - children first */ - return strcmp(*sb, *sa); -} - #ifndef MS_REC # define MS_REC 16384 #endif @@ -544,7 +534,7 @@ static int lxcContainerGetSubtree(const char *prefix, if (mounts) qsort(mounts, nmounts, sizeof(mounts[0]), - lxcContainerChildMountSort); + virStringSortRevCompare); ret = 0; cleanup: @@ -822,7 +812,7 @@ static int lxcContainerSetReadOnly(void) if (mounts) qsort(mounts, nmounts, sizeof(mounts[0]), - lxcContainerChildMountSort); + virStringSortRevCompare); for (i = 0; i < nmounts; i++) { VIR_DEBUG("Bind readonly %s", mounts[i]); diff --git a/src/util/virstring.c b/src/util/virstring.c index d11db5c..8d0ca70 100644 --- a/src/util/virstring.c +++ b/src/util/virstring.c @@ -616,3 +616,32 @@ size_t virStringListLength(char **strings) return i; } + + +/** + * virStringSortCompare: + * + * A comparator function for sorting strings in + * normal order with qsort(). + */ +int virStringSortCompare(const void *a, const void *b) +{ + const char **sa = (const char**)a; + const char **sb = (const char**)b; + + return strcmp(*sa, *sb); +} + +/** + * virStringSortRevCompare: + * + * A comparator function for sorting strings in + * reverse order with qsort(). + */ +int virStringSortRevCompare(const void *a, const void *b) +{ + const char **sa = (const char**)a; + const char **sb = (const char**)b; + + return strcmp(*sb, *sa); +} diff --git a/src/util/virstring.h b/src/util/virstring.h index b390150..13a6e5a 100644 --- a/src/util/virstring.h +++ b/src/util/virstring.h @@ -223,4 +223,7 @@ size_t virStringListLength(char **strings); virAsprintfInternal(false, 0, NULL, NULL, 0, \ strp, __VA_ARGS__) +int virStringSortCompare(const void *a, const void *b); +int virStringSortRevCompare(const void *a, const void *b); + #endif /* __VIR_STRING_H__ */ diff --git a/tests/virstringtest.c b/tests/virstringtest.c index 30803d4..b4ce679 100644 --- a/tests/virstringtest.c +++ b/tests/virstringtest.c @@ -231,6 +231,49 @@ cleanup: return ret; } + +static int +testStringSortCompare(const void *opaque ATTRIBUTE_UNUSED) +{ + const char *randlist[] = { + "tasty", "astro", "goat", "chicken", "turducken", + }; + const char *randrlist[] = { + "tasty", "astro", "goat", "chicken", "turducken", + }; + const char *sortlist[] = { + "astro", "chicken", "goat", "tasty", "turducken", + }; + const char *sortrlist[] = { + "turducken", "tasty", "goat", "chicken", "astro", + }; + int ret = -1; + size_t i; + + qsort(randlist, ARRAY_CARDINALITY(randlist), sizeof(randlist[0]), + virStringSortCompare); + qsort(randrlist, ARRAY_CARDINALITY(randrlist), sizeof(randrlist[0]), + virStringSortRevCompare); + + for (i = 0; i < ARRAY_CARDINALITY(randlist); i++) { + if (STRNEQ(randlist[i], sortlist[i])) { + fprintf(stderr, "sortlist[%zu] '%s' != randlist[%zu] '%s'\n", + i, sortlist[i], i, randlist[i]); + goto cleanup; + } + if (STRNEQ(randrlist[i], sortrlist[i])) { + fprintf(stderr, "sortrlist[%zu] '%s' != randrlist[%zu] '%s'\n", + i, sortrlist[i], i, randrlist[i]); + goto cleanup; + } + } + + ret = 0; + cleanup: + return ret; +} + + static int mymain(void) { @@ -282,6 +325,9 @@ mymain(void) if (virtTestRun("strdup", 1, testStrndupNegative, NULL) < 0) ret = -1; + if (virtTestRun("virStringSortCompare", 1, testStringSortCompare, NULL) < 0) + ret = -1; + return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE; } -- 1.8.4.5