This is the first of two commits (didn't want to dump them all into the
[openssl.git] / crypto / stack / stack.c
index be132d5..8f57daa 100644 (file)
@@ -76,9 +76,10 @@ const char *STACK_version="Stack" OPENSSL_VERSION_PTEXT;
 
 #include <errno.h>
 
-int (*sk_set_cmp_func(STACK *sk, int (*c)(const void *,const void *)))(const void *, const void *)
+int (*sk_set_cmp_func(STACK *sk, int (*c)(const char * const *,const char * const *)))
+               (const char * const *, const char * const *)
        {
-       int (*old)(const void *,const void *)=sk->comp;
+       int (*old)(const char * const *,const char * const *)=sk->comp;
 
        if (sk->comp != c)
                sk->sorted=0;
@@ -108,7 +109,7 @@ err:
        return(NULL);
        }
 
-STACK *sk_new(int (*c)(const void *, const void *))
+STACK *sk_new(int (*c)(const char * const *, const char * const *))
        {
        STACK *ret;
        int i;
@@ -218,13 +219,24 @@ int sk_find(STACK *st, char *data)
                }
        sk_sort(st);
        if (data == NULL) return(-1);
-       comp_func=st->comp;
+       /* This (and the "qsort" below) are the two places in OpenSSL
+        * where we need to convert from our standard (type **,type **)
+        * compare callback type to the (void *,void *) type required by
+        * bsearch. However, the "data" it is being called(back) with are
+        * not (type *) pointers, but the *pointers* to (type *) pointers,
+        * so we get our extra level of pointer dereferencing that way. */
+       comp_func=(int (*)(const void *,const void *))(st->comp);
        r=(char **)bsearch(&data,(char *)st->data,
                st->num,sizeof(char *), comp_func);
        if (r == NULL) return(-1);
        i=(int)(r-st->data);
        for ( ; i>0; i--)
-               if ((*st->comp)(&(st->data[i-1]),&data) < 0)
+               /* This needs a cast because the type being pointed to from
+                * the "&" expressions are (char *) rather than (const char *).
+                * For an explanation, read:
+                * http://www.eskimo.com/~scs/C-faq/q11.10.html :-) */
+               if ((*st->comp)((const char * const *)&(st->data[i-1]),
+                               (const char * const *)&data) < 0)
                        break;
        return(i);
        }
@@ -303,7 +315,12 @@ void sk_sort(STACK *st)
        {
        int (*comp_func)(const void *,const void *);
 
-       comp_func=st->comp;
+       /* same comment as in sk_find ... previously st->comp was declared
+        * as a (void*,void*) callback type, but this made the population
+        * of the callback pointer illogical - our callbacks compare
+        * type** with type**, so we leave the casting until absolutely
+        * necessary (ie. "now"). */
+       comp_func=(int (*)(const void *,const void *))(st->comp);
        qsort(st->data,st->num,sizeof(char *), comp_func);
        st->sorted=1;
        }