add QSORT

Add the macro QSORT, a convenient wrapper for qsort(3) that infers the size of the array elements and supports the convention of initializing empty arrays with a NULL pointer, which we use in some places. Calling qsort(3) directly with a NULL pointer is undefined -- even with an element count of zero -- and allows the compiler to optimize away any following NULL checks. Using the macro avoids such surprises. Add a semantic patch as well to demonstrate the macro's usage and to automate the transformation of trivial cases. Signed-off-by: Rene Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

René Scharfe committed Sep 29, 2016 at 17:23 UTC dbc540c7a5827529a3f58befc9e5b81a31ec8fab
2 files changed +27
contrib/coccinelle/qsort.cocci new
+19
@@ -0,0 +1,19 @@
1 +@@
2 +expression base, nmemb, compar;
3 +@@
4 +- qsort(base, nmemb, sizeof(*base), compar);
5 ++ QSORT(base, nmemb, compar);
6 +
7 +@@
8 +expression base, nmemb, compar;
9 +@@
10 +- qsort(base, nmemb, sizeof(base[0]), compar);
11 ++ QSORT(base, nmemb, compar);
12 +
13 +@@
14 +type T;
15 +T *base;
16 +expression nmemb, compar;
17 +@@
18 +- qsort(base, nmemb, sizeof(T), compar);
19 ++ QSORT(base, nmemb, compar);
git-compat-util.h
+8
@@ -977,6 +977,14 @@ void git_qsort(void *base, size_t nmemb, size_t size,
977 #define qsort git_qsort
978 #endif
979
980 +#define QSORT(base, n, compar) sane_qsort((base), (n), sizeof(*(base)), compar)
981 +static inline void sane_qsort(void *base, size_t nmemb, size_t size,
982 + int(*compar)(const void *, const void *))
983 +{
984 + if (nmemb > 1)
985 + qsort(base, nmemb, size, compar);
986 +}
987 +
988 #ifndef REG_STARTEND
989 #error "Git requires REG_STARTEND support. Compile with NO_REGEX=NeedsStartEnd"
990 #endif