|
|
1.1 root 1: #include "../h/rt.h"
2:
3: /*
4: * x ||| y - concatenate lists x and y.
5: */
6:
7: lconcat(nargs, arg2, arg1, arg0)
8: int nargs;
9: struct descrip arg2, arg1, arg0;
10: {
11: register struct b_list *bp1, *bp2;
12: register struct b_lelem *lp1, *lp2;
13: int size1, size2;
14:
15: SetBound;
16: /*
17: * x and y must be lists.
18: */
19: DeRef(arg1)
20: DeRef(arg2)
21: if (QUAL(arg1) || TYPE(arg1) != T_LIST)
22: runerr(108, &arg1);
23: if (QUAL(arg2) || TYPE(arg2) != T_LIST)
24: runerr(108, &arg2);
25:
26: /*
27: * Get the size of both lists.
28: */
29: size1 = BLKLOC(arg1)->list.cursize;
30: size2 = BLKLOC(arg2)->list.cursize;
31:
32: /*
33: * Make a copy of both lists.
34: */
35: cplist(&arg1, &arg1, 1, size1 + 1);
36: cplist(&arg2, &arg2, 1, size2 + 1);
37:
38: /*
39: * Get a pointer to both lists. bp1 points to the copy of x and is
40: * the list that will be returned.
41: */
42: bp1 = (struct b_list *) BLKLOC(arg1);
43: bp2 = (struct b_list *) BLKLOC(arg2);
44:
45: /*
46: * Perform the concatenation by hooking the lists together so
47: * that the next list of x is y and the previous list of y is x.
48: */
49: lp1 = (struct b_lelem *) BLKLOC(bp1->listtail);
50: lp2 = (struct b_lelem *) BLKLOC(bp2->listhead);
51:
52: lp1->listnext.type = D_LELEM;
53: BLKLOC(lp1->listnext) = (union block *) lp2;
54:
55: lp2->listprev.type = D_LELEM;
56: BLKLOC(lp2->listprev) = (union block *) lp1;
57:
58: /*
59: * Adjust the size field to reflect the length of the concatenated lists.
60: */
61: bp1->cursize = size1 + size2;
62: BLKLOC(bp1->listtail) = BLKLOC(bp2->listtail);
63:
64: arg0 = arg1;
65: ClearBound;
66: }
67:
68: Opblock(lconcat,2,"|||")
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.