1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-12-04 14:46:47 -05:00

Don't cast qsort comparison function pointers.

Instead, convert the element pointers inside the comparison functions.

The last argument of qsort() is supposed to be of type
int (*)(const void *, const void *).  Previously, comp_links() was
defined to take struct link * instead of const void *, and the type
mismatch was silenced by casting the function pointer to void *.
This was in principle not portable because:

(1) The different pointer types may have different representations.
    In a word-oriented machine, the const void * might include a byte
    selector while the struct link * might not.

(2) Casting a function pointer to a data pointer can lose bits in some
    memory models.  Apparently this does not occur in POSIX-conforming
    systems though, as dlsym() would fail if it did.

This commit also fixes hits_cmp() and compare_dir_entries(), which
had similar problems.  However, I'm leaving alias_compare() in
src/intl/gettext/localealias.c unchanged for now, so as not to diverge
from the GNU version.

I also checked the bsearch() calls but they were all okay, apart from
one that used the alias_compare() mentioned above.
This commit is contained in:
Kalle Olavi Niemitalo 2007-10-06 05:59:20 +03:00 committed by Kalle Olavi Niemitalo
parent 4a6908c843
commit e2cc0bd434
3 changed files with 15 additions and 7 deletions

View File

@ -494,9 +494,12 @@ render_document_frames(struct session *ses, int no_cache)
}
}
/* comparison function for qsort() */
static int
comp_links(struct link *l1, struct link *l2)
comp_links(const void *v1, const void *v2)
{
const struct link *l1 = v1, *l2 = v2;
assert(l1 && l2);
if_assert_failed return 0;
return (l1->number - l2->number);
@ -516,7 +519,7 @@ sort_links(struct document *document)
if_assert_failed return;
qsort(document->links, document->nlinks, sizeof(*document->links),
(void *) comp_links);
comp_links);
if (!document->height) return;

View File

@ -973,9 +973,12 @@ struct entity_cache {
unsigned char str[20]; /* Suffice in any case. */
};
/* comparison function for qsort() */
static int
hits_cmp(struct entity_cache *a, struct entity_cache *b)
hits_cmp(const void *v1, const void *v2)
{
const struct entity_cache *a = v1, *b = v2;
if (a->hits == b->hits) return 0;
if (a->hits > b->hits) return -1;
else return 1;
@ -1134,7 +1137,7 @@ end:
/* Sort entries by hit order. */
if (nb_entity_cache[slen] > 1)
qsort(&entity_cache[slen][0], nb_entity_cache[slen],
sizeof(entity_cache[slen][0]), (void *) hits_cmp);
sizeof(entity_cache[slen][0]), hits_cmp);
/* Increment number of cache entries if possible.
* Else, just replace the least used entry. */

View File

@ -481,9 +481,12 @@ stat_date(struct string *string, struct stat *stp)
/** @} */
/* comparison function for qsort() */
static int
compare_dir_entries(struct directory_entry *d1, struct directory_entry *d2)
compare_dir_entries(const void *v1, const void *v2)
{
const struct directory_entry *d1 = v1, *d2 = v2;
if (d1->name[0] == '.' && d1->name[1] == '.' && !d1->name[2]) return -1;
if (d2->name[0] == '.' && d2->name[1] == '.' && !d2->name[2]) return 1;
if (d1->attrib[0] == 'd' && d2->attrib[0] != 'd') return -1;
@ -580,8 +583,7 @@ get_directory_entries(unsigned char *dirname, int get_hidden)
return NULL;
}
qsort(entries, size, sizeof(*entries),
(int (*)(const void *, const void *)) compare_dir_entries);
qsort(entries, size, sizeof(*entries), compare_dir_entries);
memset(&entries[size], 0, sizeof(*entries));