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,"++")