Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include "sam.h"

/*
 * Check that list has room for one more element.
 */
static void
growlist(List *l, int esize)
{
        uchar *p;

        if(l->listptr == nil || l->nalloc == 0){
                l->nalloc = INCR;
                l->listptr = emalloc(INCR*esize);
                l->nused = 0;
        }
        else if(l->nused == l->nalloc){
                p = erealloc(l->listptr, (l->nalloc+INCR)*esize);
                l->listptr = p;
                memset(p+l->nalloc*esize, 0, INCR*esize);
                l->nalloc += INCR;
        }
}

/*
 * Remove the ith element from the list
 */
void
dellist(List *l, int i)
{
        Posn *pp;
        void **vpp;

        l->nused--;

        switch(l->type){
        case 'P':
                pp = l->posnptr+i;
                memmove(pp, pp+1, (l->nused-i)*sizeof(*pp));
                break;
        case 'p':
                vpp = l->voidpptr+i;
                memmove(vpp, vpp+1, (l->nused-i)*sizeof(*vpp));
                break;
        }
}

/*
 * Add a new element, whose position is i, to the list
 */
void
inslist(List *l, int i, ...)
{
        Posn *pp;
        void **vpp;
        va_list list;


        va_start(list, i);
        switch(l->type){
        case 'P':
                growlist(l, sizeof(*pp));
                pp = l->posnptr+i;
                memmove(pp+1, pp, (l->nused-i)*sizeof(*pp));
                *pp = va_arg(list, Posn);
                break;
        case 'p':
                growlist(l, sizeof(*vpp));
                vpp = l->voidpptr+i;
                memmove(vpp+1, vpp, (l->nused-i)*sizeof(*vpp));
                *vpp = va_arg(list, void*);
                break;
        }
        va_end(list);

        l->nused++;
}

void
listfree(List *l)
{
        free(l->listptr);
        free(l);
}

List*
listalloc(int type)
{
        List *l;

        l = emalloc(sizeof(List));
        l->type = type;
        l->nalloc = 0;
        l->nused = 0;

        return l;
}