windows-nt/Source/XPSP1/NT/sdktools/asn1/asn1c/list.c
2020-09-26 16:20:57 +08:00

108 lines
2.6 KiB
C

/* Copyright (C) Boris Nikolaus, Germany, 1996-1997. All rights reserved. */
/* Copyright (C) Microsoft Corporation, 1997-1998. All rights reserved. */
#include "precomp.h"
/* get length of a singly linked list */
size_t SLlength(void *head, size_t offset)
{
size_t nelem = 0;
while (head) {
/*LINTED*/
head = *(void **)((char *)head + offset);
nelem++;
}
return nelem;
}
/* search for an element in a singly linked list */
int SLcontains(void *head, size_t offset, void *elem)
{
while (head) {
if (head == elem)
return 1;
/*LINTED pointer cast may result in improper alignment*/
head = *(void **)((char *)head + offset);
}
return 0;
}
/* copy elements of a singly linked list into an array */
void SLtoA(void *head, size_t offset, size_t elemsize, void **base, size_t *nelem)
{
void *p;
*nelem = SLlength(head, offset);
if (!*nelem) {
*base = NULL;
return;
}
p = *base = malloc(*nelem * elemsize);
/*LINTED*/
for (; head; head = *(void **)((char *)head + offset)) {
memcpy(p, head, elemsize);
p = (void *)((char *)p + elemsize);
}
}
/* copy pointers to elements of a singly linked list into an array */
void SLtoAP(void *head, size_t offset, void ***base, size_t *nelem)
{
void **p;
*nelem = SLlength(head, offset);
if (!*nelem) {
*base = NULL;
return;
}
p = *base = (void **)malloc(*nelem * sizeof(void *));
/*LINTED*/
for (; head; head = *(void **)((char *)head + offset)) {
*p++ = head;
}
}
/* copy elements of an array into a singly linked list */
void AtoSL(void *base, size_t offset, size_t nelem, size_t elemsize, void **head)
{
while (nelem--) {
*head = malloc(elemsize);
memcpy(*head, base, elemsize);
base = (void *)((char *)base + elemsize);
/*LINTED*/
head = (void **)((char *)*head + offset);
}
*head = NULL;
}
/* user defined compare function of qsortSL */
static int (*qsortSL_CmpFnCb)(const void *, const void *, void *);
static void *qsortSL_Context;
/* compare function of qsortSL */
static int __cdecl qsortSL_CmpFn(const void *p1, const void *p2)
{
return qsortSL_CmpFnCb(*(void **)p1, *(void **)p2, qsortSL_Context);
}
/* sort a singly linked list */
void qsortSL(void **head, size_t offset, int (*cmpfn)(const void *, const void *, void *), void *context)
{
void **base, **p;
size_t nelem;
SLtoAP(*head, offset, &base, &nelem);
qsortSL_CmpFnCb = cmpfn;
qsortSL_Context = context;
qsort(base, nelem, sizeof(void *), qsortSL_CmpFn);
p = base;
while (nelem--) {
*head = *p++;
/*LINTED*/
head = (void **)((char *)*head + offset);
}
*head = NULL;
free(base);
}