git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH 1/3] add QSORT
@ 2016-09-29 15:23 René Scharfe
  2016-09-29 15:27 ` [PATCH 2/3] use QSORT René Scharfe
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: René Scharfe @ 2016-09-29 15:23 UTC (permalink / raw)
  To: Git List; +Cc: Junio C Hamano

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>
---
 contrib/coccinelle/qsort.cocci | 19 +++++++++++++++++++
 git-compat-util.h              |  8 ++++++++
 2 files changed, 27 insertions(+)
 create mode 100644 contrib/coccinelle/qsort.cocci

diff --git a/contrib/coccinelle/qsort.cocci b/contrib/coccinelle/qsort.cocci
new file mode 100644
index 0000000..a094e7c
--- /dev/null
+++ b/contrib/coccinelle/qsort.cocci
@@ -0,0 +1,19 @@
+@@
+expression base, nmemb, compar;
+@@
+- qsort(base, nmemb, sizeof(*base), compar);
++ QSORT(base, nmemb, compar);
+
+@@
+expression base, nmemb, compar;
+@@
+- qsort(base, nmemb, sizeof(base[0]), compar);
++ QSORT(base, nmemb, compar);
+
+@@
+type T;
+T *base;
+expression nmemb, compar;
+@@
+- qsort(base, nmemb, sizeof(T), compar);
++ QSORT(base, nmemb, compar);
diff --git a/git-compat-util.h b/git-compat-util.h
index 8aab0c3..d7ed137 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -977,6 +977,14 @@ void git_qsort(void *base, size_t nmemb, size_t size,
 #define qsort git_qsort
 #endif
 
+#define QSORT(base, n, compar) sane_qsort((base), (n), sizeof(*(base)), compar)
+static void inline sane_qsort(void *base, size_t nmemb, size_t size,
+			      int(*compar)(const void *, const void *))
+{
+	if (nmemb > 1)
+		qsort(base, nmemb, size, compar);
+}
+
 #ifndef REG_STARTEND
 #error "Git requires REG_STARTEND support. Compile with NO_REGEX=NeedsStartEnd"
 #endif
-- 
2.10.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2016-10-05 16:16 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-29 15:23 [PATCH 1/3] add QSORT René Scharfe
2016-09-29 15:27 ` [PATCH 2/3] use QSORT René Scharfe
2016-09-29 15:29 ` [PATCH 3/3] remove unnecessary check before QSORT René Scharfe
2016-09-29 22:36 ` [PATCH 1/3] add QSORT Junio C Hamano
2016-09-29 23:21   ` René Scharfe
2016-09-29 23:40     ` René Scharfe
2016-10-01 16:19   ` René Scharfe
2016-10-03 16:46     ` Kevin Bracey
2016-10-03 17:09     ` Kevin Bracey
2016-10-03 22:00       ` René Scharfe
2016-10-04  5:28         ` Kevin Bracey
2016-10-04 20:31           ` René Scharfe
2016-10-05 15:00             ` Kevin Bracey

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).