]> sjero.net Git - wget/blobdiff - src/utils.c
[svn] Added reordering of addresses to try IPv4 first and the associated
[wget] / src / utils.c
index 0692bcb339776b28d132f96e8fa2c4961ac5f21d..1afb8429edac906df2beb0ea32b7f182bfffc16a 100644 (file)
@@ -1825,7 +1825,7 @@ xsleep (double seconds)
 
 #endif /* not WINDOWS */
 
-/* Encode the string S of length LENGTH to base64 format and place it
+/* Encode the string STR of length LENGTH to base64 format and place it
    to B64STORE.  The output will be \0-terminated, and must point to a
    writable buffer of at least 1+BASE64_LENGTH(length) bytes.  It
    returns the length of the resulting base64 data, not counting the
@@ -1835,7 +1835,7 @@ xsleep (double seconds)
    base64 data.  */
 
 int
-base64_encode (const char *s, int length, char *b64store)
+base64_encode (const char *str, int length, char *b64store)
 {
   /* Conversion table.  */
   static char tbl[64] = {
@@ -1849,7 +1849,8 @@ base64_encode (const char *s, int length, char *b64store)
     '4','5','6','7','8','9','+','/'
   };
   int i;
-  unsigned char *p = (unsigned char *) b64store;
+  const unsigned char *s = (const unsigned char *) str;
+  char *p = b64store;
 
   /* Transform the 3x8 bits to 4x6 bits, as required by base64.  */
   for (i = 0; i < length; i += 3)
@@ -1870,7 +1871,7 @@ base64_encode (const char *s, int length, char *b64store)
   /* ...and zero-terminate it.  */
   *p = '\0';
 
-  return p - (unsigned char *) b64store;
+  return p - b64store;
 }
 
 #define IS_ASCII(c) (((c) & 0x80) == 0)
@@ -1974,3 +1975,49 @@ base64_decode (const char *base64, char *to)
 #undef IS_ASCII
 #undef IS_BASE64
 #undef NEXT_BASE64_CHAR
+\f
+/* Simple merge sort for use by stable_sort.  Implementation courtesy
+   Zeljko Vrba.  */
+
+static void
+mergesort_internal (void *base, void *temp, size_t size, size_t from, size_t to,
+                   int (*cmpfun) PARAMS ((const void *, const void *)))
+{
+#define ELT(array, pos) ((char *)(array) + (pos) * size)
+  if (from < to)
+    {
+      size_t i, j, k;
+      size_t mid = (to + from) / 2;
+      mergesort_internal (base, temp, size, from, mid, cmpfun);
+      mergesort_internal (base, temp, size, mid + 1, to, cmpfun);
+      i = from;
+      j = mid + 1;
+      for (k = from; (i <= mid) && (j <= to); k++)
+       if (cmpfun (ELT (base, i), ELT (base, j)) <= 0)
+         memcpy (ELT (temp, k), ELT (base, i++), size);
+       else
+         memcpy (ELT (temp, k), ELT (base, j++), size);
+      while (i <= mid)
+       memcpy (ELT (temp, k++), ELT (base, i++), size);
+      while (j <= to)
+       memcpy (ELT (temp, k++), ELT (base, j++), size);
+      for (k = from; k <= to; k++)
+       memcpy (ELT (base, k), ELT (temp, k), size);
+    }
+#undef ELT
+}
+
+/* Stable sort with interface exactly like standard library's qsort.
+   Uses mergesort internally, allocating temporary storage with
+   alloca.  */
+
+void
+stable_sort (void *base, size_t nmemb, size_t size,
+            int (*cmpfun) PARAMS ((const void *, const void *)))
+{
+  if (size > 1)
+    {
+      void *temp = alloca (nmemb * size * sizeof (void *));
+      mergesort_internal (base, temp, size, 0, nmemb - 1, cmpfun);
+    }
+}