|
|
1.1 root 1: #include "../h/rt.h"
2:
3: /*
4: * x ++ y - union of csets x and y or of sets x and y.
5: */
6:
7: unioncs(nargs, arg2, arg1, arg0)
8: int nargs;
9: struct descrip arg2, arg1, arg0;
10: {
11: DclSave
12: register int i;
13: union block *bp;
14: int *cs1, *cs2, csbuf1[CSETSIZE], csbuf2[CSETSIZE];
15: extern struct b_cset *alccset();
16: #ifdef SETS
17: int res;
18: struct b_set *srcp, *tstp, *dstp;
19: struct b_selem *ep;
20: struct descrip *dp, *hook;
21: extern struct b_set *alcset();
22: extern struct b_selem *alcselem();
23: extern struct descrip *memb();
24: #endif SETS
25:
26: SetBound;
27: #ifdef SETS
28: DeRef(arg1)
29: DeRef(arg2)
30: if (QUAL(arg1) || QUAL(arg2))
31: goto skipsets;
32: if (TYPE(arg1) == T_SET && TYPE(arg2) != T_SET)
33: runerr(119,&arg2);
34: if (TYPE(arg2) == T_SET && TYPE(arg1) != T_SET)
35: runerr(119,&arg1);
36: if (TYPE(arg1) == T_SET && TYPE(arg2) == T_SET) {
37: /*
38: * Both x and y are sets - do set union
39: * get enough space for a set as big as x + y.
40: */
41: hneed(sizeof(struct b_set) + (BLKLOC(arg1)->set.setsize +
42: BLKLOC(arg2)->set.setsize) * sizeof(struct b_selem));
43: /*
44: * Select the larger of the two sets as the source
45: * copy each element to a new set for the result
46: * then insert each member of the second set into the
47: * result set if it is not already there.
48: */
49: if (BLKLOC(arg1)->set.setsize >= BLKLOC(arg2)->set.setsize) {
50: srcp = (struct b_set *) BLKLOC(arg1);
51: tstp = (struct b_set *) BLKLOC(arg2);
52: }
53: else {
54: srcp = (struct b_set *) BLKLOC(arg2);
55: tstp = (struct b_set *) BLKLOC(arg1);
56: }
57: arg0.type = D_SET;
58: dstp = alcset();
59: BLKLOC(arg0) = (union block *) dstp;
60: for (i = 0; i < NBUCKETS; i++) {
61: ep = (struct b_selem *) BLKLOC(srcp->sbucks[i]);
62: dp = &dstp->sbucks[i];
63: while (ep != NULL) {
64: dp->type = D_SELEM;
65: BLKLOC(*dp) = (union block *) alcselem(&ep->setmem, ep->hnum);
66: dp = &BLKLOC(*dp)->selem.sblink;
67: dstp->setsize++;
68: ep = (struct b_selem *) BLKLOC(ep->sblink);
69: }
70: }
71: for (i = 0; i < NBUCKETS; i++) {
72: ep = (struct b_selem *) BLKLOC(tstp->sbucks[i]);
73: while (ep != NULL) {
74: hook = memb(dstp, &ep->setmem, ep->hnum, &res);
75: if (res == 0)
76: addmem(dstp, alcselem(&ep->setmem, ep->hnum), hook);
77: ep = (struct b_selem *) BLKLOC(ep->sblink);
78: }
79: }
80: }
81: else {
82: skipsets:
83: #endif SETS
84:
85: hneed(sizeof(struct b_cset));
86:
87: /*
88: * x and y must be csets.
89: */
90: if (cvcset(&arg1, &cs1, csbuf1) == NULL)
91: runerr(104, &arg1);
92: if (cvcset(&arg2, &cs2, csbuf2) == NULL)
93: runerr(104, &arg2);
94:
95: /*
96: * Allocate a new cset and in each word of it, compute the value
97: * of the bitwise union of the corresponding words in the
98: * x and y csets.
99: */
100: bp = (union block *) alccset();
101: for (i = 0; i < CSETSIZE; i++)
102: bp->cset.bits[i] = cs1[i] | cs2[i];
103:
104: arg0.type = D_CSET;
105: BLKLOC(arg0) = bp;
106: #ifdef SETS
107: }
108: #endif SETS
109: ClearBound;
110: }
111:
112: Opblock(unioncs,2,"++")
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.