]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Redo the strings sorting function, allocate/free memory as needed.
authorAndres Mejia <amejia004@gmail.com>
Sun, 10 Feb 2013 03:09:30 +0000 (22:09 -0500)
committerAndres Mejia <amejia004@gmail.com>
Sun, 10 Feb 2013 03:24:12 +0000 (22:24 -0500)
This is the normal implementation of quicksort.

libarchive/archive_util.c

index 57db5a6547c1a670d347698c6c0a3b6c1e6d78b2..0d6140774d2666311cf339419f78d31339f3c567 100644 (file)
@@ -508,29 +508,55 @@ __archive_ensure_cloexec_flag(int fd)
 static int
 archive_utility_string_sort_helper(char **strings, unsigned int n)
 {
-  unsigned int i, j, pivot;
-  char *tmp;
+  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);
 
-  pivot = 0;
+  lesser_count = greater_count = 0;
+  lesser = greater = NULL;
+  pivot = strings[0];
   for (i = 1; i < n; i++)
   {
-    if (strcmp(strings[i], strings[pivot]) < 0)
+    if (strcmp(strings[i], pivot) < 0)
     {
-      tmp = strings[i];
-      for (j = i; j > pivot; j--)
-      {
-        strings[j] = strings[j - 1];
-      }
-      strings[pivot] = tmp;
-      pivot++;
+      lesser_count++;
+      tmp = (char **)realloc(lesser, lesser_count * sizeof(char *));
+      if (!tmp)
+        return (ARCHIVE_FATAL);
+      lesser = tmp;
+      lesser[lesser_count - 1] = strings[i];
+    }
+    else
+    {
+      greater_count++;
+      tmp = (char **)realloc(greater, greater_count * sizeof(char *));
+      if (!tmp)
+        return (ARCHIVE_FATAL);
+      greater = tmp;
+      greater[greater_count - 1] = strings[i];
     }
   }
-  archive_utility_string_sort_helper(strings, pivot + 1);
-  archive_utility_string_sort_helper(strings + pivot + 1, n - (pivot + 1));
-  return (ARCHIVE_OK);
+
+  /* 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;
 }
 
 int