From f22cc0c173b6d9c40cbe82bdb823ecf59f064591 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Mon, 27 Aug 2018 22:37:12 +0200 Subject: [PATCH] mescc: Mes C Library: Fix qsort to support duplicate entries. * lib/stdlib/qsort.c (qpart): Handle dupes. * scaffold/tests/81-qsort-dupes.c: New file. * build-aux/check-mescc.sh (tests): Run it. --- build-aux/check-mescc.sh | 1 + lib/stdlib/qsort.c | 5 +++- scaffold/tests/81-qsort-dupes.c | 42 +++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 scaffold/tests/81-qsort-dupes.c diff --git a/build-aux/check-mescc.sh b/build-aux/check-mescc.sh index 26fbcdcb..8abd15bd 100755 --- a/build-aux/check-mescc.sh +++ b/build-aux/check-mescc.sh @@ -125,6 +125,7 @@ t 7s-struct-short 80-setjmp 81-qsort +81-qsort-dupes 82-define 83-heterogenoous-init 84-struct-field-list diff --git a/lib/stdlib/qsort.c b/lib/stdlib/qsort.c index bac7f426..22f493e2 100644 --- a/lib/stdlib/qsort.c +++ b/lib/stdlib/qsort.c @@ -37,11 +37,14 @@ qpart (void *base, size_t count, size_t size, int (*compare)(void const *, void size_t i = 0; for (size_t j = 0; j < count; j++) { - if (compare (base+j*size, p) < 0) + int c = compare (base+j*size, p); + if (c < 0) { qswap (base+i*size, base+j*size, size); i++; } + else if (c == 0) + i++; } if (compare (base+count*size, base+i*size) < 0) qswap (base+i*size, base+count*size, size); diff --git a/scaffold/tests/81-qsort-dupes.c b/scaffold/tests/81-qsort-dupes.c new file mode 100644 index 00000000..7a949023 --- /dev/null +++ b/scaffold/tests/81-qsort-dupes.c @@ -0,0 +1,42 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * + * This file is part of GNU Mes. + * + * GNU Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * GNU Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Mes. If not, see . + */ + +#include +#include + +int +qsort_strcmp (void const* a, void const* b) +{ + return strcmp (*((char**) a), *((char**) b)); +} + +int +main () +{ + char* list[3] = {"foo", "foo", 0 }; + oputs ("\nls:\n"); + qsort (list, 2, sizeof (char*), qsort_strcmp); + for (int i = 0; i < 2; i++) + { + oputs (list[i]); oputs ("\n"); + } + + return 0; +}