summaryrefslogtreecommitdiffstats
path: root/src/sort_r.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sort_r.c')
-rw-r--r--src/sort_r.c135
1 files changed, 135 insertions, 0 deletions
diff --git a/src/sort_r.c b/src/sort_r.c
new file mode 100644
index 0000000..b1c8c84
--- /dev/null
+++ b/src/sort_r.c
@@ -0,0 +1,135 @@
+/* -*- Mode: c; c-basic-offset: 2 -*-
+ *
+ * sort_r.c - Portable sort_r
+ *
+ * Copyright (C) 2014, David Beckett http://www.dajobe.org/
+ *
+ * This package is Free Software and part of Redland http://librdf.org/
+ *
+ * It is licensed under the following three licenses as alternatives:
+ * 1. GNU Lesser General Public License (LGPL) V2.1 or any newer version
+ * 2. GNU General Public License (GPL) V2 or any newer version
+ * 3. Apache License, V2.0 or any newer version
+ *
+ * You may not use this file except in compliance with at least one of
+ * the above three licenses.
+ *
+ * See LICENSE.html or LICENSE.txt at the top of this package for the
+ * complete terms and further detail along with the license texts for
+ * the licenses in COPYING.LIB, COPYING and LICENSE-2.0.txt respectively.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <raptor_config.h>
+#endif
+
+
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+/* Raptor includes */
+#include "raptor2.h"
+#include "raptor_internal.h"
+
+
+#ifndef STANDALONE
+
+#if defined(HAVE_QSORT_R) || defined(HAVE_QSORT_S)
+/* Include inline code */
+#include "sort_r.h"
+#else
+#include "ssort.h"
+#endif
+
+
+/**
+ * raptor_sort_r:
+ * @base: the array to be sorted
+ * @nel: the number of elements in the array
+ * @width: the size in bytes of each element of the array
+ * @compar: comparison function
+ * @user_data: a pointer to be passed to the comparison function
+ *
+ * Sort an array with an extra user data arg for the comparison funciton.
+ *
+ * Sorts data at @base of @nel elememnts of width @width using
+ * comparison function @comp that takes args (void* data1, void*
+ * data2, @user_data) and returns <0, 0, or >0 for object comparison.
+ *
+ */
+void
+raptor_sort_r(void *base, size_t nel, size_t width,
+ raptor_data_compare_arg_handler compar, void *user_data)
+{
+#if defined(HAVE_QSORT_R) || defined(HAVE_QSORT_S)
+ sort_r(base, nel, width, compar, user_data);
+#else
+ ssort_r(base, nel, width, compar, user_data);
+#endif
+}
+
+
+#endif
+
+
+
+#ifdef STANDALONE
+
+/* one more prototype */
+int main(int argc, char *argv[]);
+
+
+/* Public Domain licensed example code by Isaac Turner from
+ * https://github.com/noporpoise/sort_r
+ */
+
+/* Isaac Turner 18 Nov 2013 Public Domain */
+
+/*
+Comparison function to sort an array of int, inverting a given region.
+`arg` should be of type int[2], with the elements representing the start and end
+of the region to invert (inclusive).
+*/
+static int sort_r_cmp(const void *aa, const void *bb, void *arg)
+{
+ const int *a = (const int*)aa;
+ const int *b = (const int*)bb;
+ const int *interval = (const int*)arg;
+ int cmp = *a - *b;
+ int inv_start = interval[0], inv_end = interval[1];
+ char norm = (*a < inv_start || *a > inv_end || *b < inv_start || *b > inv_end);
+ return norm ? cmp : -cmp;
+}
+
+int
+main(int argc, char *argv[])
+{
+ const char *program = raptor_basename(argv[0]);
+
+ int i;
+ /* sort 1..19, 30..20, 30..100 */
+ int arr[18] = {1, 5, 28, 4, 3, 2, 10, 20, 18, 25, 21, 29, 34, 35, 14, 100, 27, 19};
+ int tru[18] = {1, 2, 3, 4, 5, 10, 14, 18, 19, 29, 28, 27, 25, 21, 20, 34, 35, 100};
+
+ /* Region to invert: 20-30 (inclusive) */
+ int interval[2] = {20, 30};
+ int failures = 0;
+
+ raptor_sort_r(arr, 18, sizeof(int), sort_r_cmp, interval);
+
+ /* Check PASS/FAIL */
+ for(i = 0; i < 18; i++) {
+ if(arr[i] != tru[i]) {
+ printf("%s: sort_r() result %i: got %d expected %d", program,
+ i, arr[i], tru[i]);
+ failures++;
+ }
+ }
+
+ return failures;
+}
+
+#endif