]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
archive_utility_string_sort: Use qsort directly
authorTobias Stoeckmann <tobias@stoeckmann.org>
Thu, 29 May 2025 16:19:47 +0000 (18:19 +0200)
committerTobias Stoeckmann <tobias@stoeckmann.org>
Fri, 30 May 2025 15:41:12 +0000 (17:41 +0200)
The utility function "archive_utility_string_sort" is a custom qsort
implementation. Since qsort is specified in C11 and POSIX.1-2008
which libarchive is based on, use system's qsort directly.

The function is not used directly in libarchive, so this is a good
way to save around 500 bytes in resulting library without breaking
compatibility for any user of this function (none found).

Also allows more than UINT_MAX entries which previously were limited
by data type and (way earlier) due to recursion.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
libarchive/archive_util.c

index 3a8caad5262b5c33812baaeaf34fc7a70e36fc22..97185c0043c1c3b2846a0795b973f85b28ca1fe7 100644 (file)
@@ -77,7 +77,7 @@
 #define O_CLOEXEC      0
 #endif
 
-static int archive_utility_string_sort_helper(char **, unsigned int);
+static int __LA_LIBC_CC archive_utility_string_sort_helper(const void *, const void *);
 
 /* Generic initialization of 'struct archive' objects. */
 int
@@ -630,73 +630,25 @@ __archive_ensure_cloexec_flag(int fd)
 }
 
 /*
- * Utility function to sort a group of strings using quicksort.
+ * Utility functions to sort a group of strings using quicksort.
  */
 static int
-archive_utility_string_sort_helper(char **strings, unsigned int n)
+__LA_LIBC_CC
+archive_utility_string_sort_helper(const void *p1, const void *p2)
 {
-       unsigned int i, lesser_count, greater_count;
-       char **lesser, **greater, **tmp, *pivot;
-       int retval1, retval2;
-
-       /* A list of 0 or 1 elements is already sorted */
-       if (n <= 1)
-               return (ARCHIVE_OK);
-
-       lesser_count = greater_count = 0;
-       lesser = greater = NULL;
-       pivot = strings[0];
-       for (i = 1; i < n; i++)
-       {
-               if (strcmp(strings[i], pivot) < 0)
-               {
-                       lesser_count++;
-                       tmp = realloc(lesser, lesser_count * sizeof(*tmp));
-                       if (!tmp) {
-                               free(greater);
-                               free(lesser);
-                               return (ARCHIVE_FATAL);
-                       }
-                       lesser = tmp;
-                       lesser[lesser_count - 1] = strings[i];
-               }
-               else
-               {
-                       greater_count++;
-                       tmp = realloc(greater, greater_count * sizeof(*tmp));
-                       if (!tmp) {
-                               free(greater);
-                               free(lesser);
-                               return (ARCHIVE_FATAL);
-                       }
-                       greater = tmp;
-                       greater[greater_count - 1] = strings[i];
-               }
-       }
+       const char * const * const s1 = p1;
+       const char * const * const s2 = p2;
 
-       /* quicksort(lesser) */
-       retval1 = archive_utility_string_sort_helper(lesser, lesser_count);
-       for (i = 0; i < lesser_count; i++)
-               strings[i] = lesser[i];
-       free(lesser);
-
-       /* pivot */
-       strings[lesser_count] = pivot;
-
-       /* quicksort(greater) */
-       retval2 = archive_utility_string_sort_helper(greater, greater_count);
-       for (i = 0; i < greater_count; i++)
-               strings[lesser_count + 1 + i] = greater[i];
-       free(greater);
-
-       return (retval1 < retval2) ? retval1 : retval2;
+       return strcmp(*s1, *s2);
 }
 
 int
 archive_utility_string_sort(char **strings)
 {
-         unsigned int size = 0;
-         while (strings[size] != NULL)
+       size_t size = 0;
+       while (strings[size] != NULL)
                size++;
-         return archive_utility_string_sort_helper(strings, size);
+       qsort(strings, size, sizeof(char *),
+             archive_utility_string_sort_helper);
+       return (ARCHIVE_OK);
 }