|
|
BSD 4.3
#include "../h/rt.h"
/*
* cplist(d1,d2,i,j) - copy sublist d1[i:j] into d2.
*/
cplist(d1, d2, i, j)
struct descrip *d1, *d2;
int i, j;
{
register struct descrip *dp;
int size, nelem;
struct b_list *lp1, *lp2;
struct b_lelem *bp1, *bp2;
/*
* Calculate the size of the sublist and fail if it's less than 0.
* Also round nelem up to the minimum list block size.
*/
size = nelem = j - i;
if (size < 0)
fail();
if (nelem < LISTBLKSIZE)
nelem = LISTBLKSIZE;
/*
* Get pointers to the list and list elements for the source list
* (bp1, lp1) and the sublist (bp2, lp2).
*/
hneed(sizeof(struct b_list) + sizeof(struct b_lelem) +
nelem * sizeof(struct descrip));
lp1 = (struct b_list *) BLKLOC(*d1);
bp1 = (struct b_lelem *) BLKLOC(lp1->listhead);
lp2 = (struct b_list *) alclist(size);
bp2 = (struct b_lelem *) alclstb(nelem, 0, size);
lp2->listhead.type = lp2->listtail.type = D_LELEM;
BLKLOC(lp2->listhead) = BLKLOC(lp2->listtail) = (union block *) bp2;
dp = bp2->lslots;
/*
* Locate the block containing element i in the source list.
*/
if (size > 0) {
while (i > bp1->nused) {
i -= bp1->nused;
bp1 = (struct b_lelem *) BLKLOC(bp1->listnext);
}
}
/*
* Copy elements from the source list into the sublist, moving to
* the next list block in the source list when all elements in a
* block have been copied.
*/
while (size > 0) {
j = bp1->first + i - 1;
if (j >= bp1->nelem)
j -= bp1->nelem;
*dp++ = bp1->lslots[j];
if (++i > bp1->nused) {
i = 1;
bp1 = (struct b_lelem *) BLKLOC(bp1->listnext);
}
size--;
}
/*
* Fix type and location fields for the new list.
*/
d2->type = D_LIST;
BLKLOC(*d2) = (union block *) lp2;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.