|
|
1.1 ! root 1: /* ! 2: * File: oset.c ! 3: * Contents: compl, diff, inter, unions ! 4: */ ! 5: ! 6: #include "../h/rt.h" ! 7: ! 8: /* ! 9: * ~x - complement cset x. ! 10: */ ! 11: ! 12: /* >compl */ ! 13: OpDcl(compl,1,"~") ! 14: { ! 15: register int i, j; ! 16: union block *bp; ! 17: int *cs, csbuf[CsetSize]; ! 18: extern struct b_cset *alccset(); ! 19: ! 20: blkreq((word)sizeof(struct b_cset)); ! 21: ! 22: /* ! 23: * Arg1 must be a cset. ! 24: */ ! 25: if (cvcset(&Arg1, &cs, csbuf) == NULL) ! 26: runerr(104, &Arg1); ! 27: ! 28: /* ! 29: * Allocate a new cset and then copy each cset word from Arg1 ! 30: * itno the new cset words, complementing each. ! 31: */ ! 32: bp = (union block *) alccset(0); ! 33: for (i = 0; i < CsetSize; i++) { ! 34: bp->cset.bits[i] = ~cs[i]; ! 35: } ! 36: j = 0; ! 37: for (i = 0; i < CsetSize * CIntSize; i++) { ! 38: if (Testb(i, bp->cset.bits)) ! 39: j++; ! 40: } ! 41: bp->cset.size = j; ! 42: ! 43: Arg0.dword = D_Cset; ! 44: BlkLoc(Arg0) = bp; ! 45: Return; ! 46: } ! 47: /* <compl */ ! 48: ! 49: ! 50: /* ! 51: * x -- y - difference of csets x and y or of sets x and y. ! 52: */ ! 53: ! 54: OpDcl(diff,2,"--") ! 55: { ! 56: register word i, j; ! 57: register union block *bp; ! 58: int *cs1, *cs2, csbuf1[CsetSize], csbuf2[CsetSize]; ! 59: extern struct b_cset *alccset(); ! 60: struct descrip *dp; ! 61: struct b_set *srcp, *dstp, *tstp; ! 62: struct b_selem *sep; ! 63: extern struct b_set *alcset(); ! 64: extern struct b_selem *alcselem(); ! 65: ! 66: if (Qual(Arg1) || Qual(Arg2)) ! 67: goto skipsets; ! 68: if (Arg1.dword == D_Set && Arg2.dword != D_Set) ! 69: runerr(119,&Arg2); ! 70: if (Arg2.dword == D_Set && Arg1.dword != D_Set) ! 71: runerr(119,&Arg1); ! 72: if (Arg1.dword == D_Set && Arg2.dword == D_Set) { ! 73: /* ! 74: * Both x and y are sets - do set difference ! 75: * get enough space for a new set the size of x. ! 76: */ ! 77: blkreq(sizeof(struct b_set) + BlkLoc(Arg1)->set.size * ! 78: sizeof(struct b_selem)); ! 79: /* ! 80: * For each element in set x if it isn't in set y ! 81: * copy it directly into the result set. ! 82: */ ! 83: srcp = (struct b_set *) BlkLoc(Arg1); ! 84: tstp = (struct b_set *) BlkLoc(Arg2); ! 85: Arg0.dword = D_Set; ! 86: dstp = alcset(); ! 87: BlkLoc(Arg0) = (union block *) dstp; ! 88: for (i = 0; i < SSlots; i++) { ! 89: sep = (struct b_selem *) BlkLoc(srcp->sbucks[i]); ! 90: dp = &dstp->sbucks[i]; ! 91: while (sep != NULL) { ! 92: if ( !locate((struct b_selem *)BlkLoc(tstp->sbucks[i]), sep) ) { ! 93: dp->dword = D_Selem; ! 94: BlkLoc(*dp) = (union block *) alcselem(&sep->setmem, sep->hashnum); ! 95: dp = &BlkLoc(*dp)->selem.clink; ! 96: dstp->size++; ! 97: } ! 98: sep = (struct b_selem *) BlkLoc(sep->clink); ! 99: } ! 100: } ! 101: } ! 102: else { ! 103: skipsets: ! 104: blkreq((word)sizeof(struct b_cset)); ! 105: ! 106: /* ! 107: * x and y must be csets. ! 108: */ ! 109: if (cvcset(&Arg1, &cs1, csbuf1) == NULL) ! 110: runerr(104, &Arg1); ! 111: if (cvcset(&Arg2, &cs2, csbuf2) == NULL) ! 112: runerr(104, &Arg2); ! 113: ! 114: /* ! 115: * Allocate a new cset and in each word of it, compute the value ! 116: * of the bitwise difference of the corresponding words in the ! 117: * x and y csets. ! 118: */ ! 119: bp = (union block *) alccset(0); ! 120: for (i = 0; i < CsetSize; i++) { ! 121: bp->cset.bits[i] = cs1[i] & ~cs2[i]; ! 122: } ! 123: j = 0; ! 124: for (i = 0; i < CsetSize*CIntSize; i++) { ! 125: if (Testb(i,bp->cset.bits)) ! 126: j++; ! 127: } ! 128: bp->cset.size = j; ! 129: ! 130: Arg0.dword = D_Cset; ! 131: BlkLoc(Arg0) = bp; ! 132: } ! 133: Return; ! 134: } ! 135: ! 136: ! 137: /* ! 138: * x ** y - intersection of csets x and y or of sets x and y. ! 139: */ ! 140: ! 141: OpDcl(inter,2,"**") ! 142: { ! 143: register word i, j; ! 144: union block *bp; ! 145: int *cs1, csbuf1[CsetSize], *cs2, csbuf2[CsetSize]; ! 146: extern struct b_cset *alccset(); ! 147: struct descrip *dp; ! 148: struct b_set *srcp, *tstp, *dstp; ! 149: struct b_selem *sep; ! 150: extern struct b_set *alcset(); ! 151: extern struct b_selem *alcselem(); ! 152: ! 153: if (Qual(Arg1) || Qual(Arg2)) ! 154: goto skipsets; ! 155: if (Arg1.dword == D_Set && Arg2.dword != D_Set) ! 156: runerr(119,&Arg2); ! 157: if (Arg2.dword == D_Set && Arg1.dword != D_Set) ! 158: runerr(119,&Arg1); ! 159: if (Arg1.dword == D_Set && Arg2.dword == D_Set) { ! 160: /* ! 161: * Both x and y are sets - do set intersection ! 162: * get enough space for a new set the size of the smaller ! 163: * of the two sets. ! 164: */ ! 165: blkreq(sizeof(struct b_set) + Min(BlkLoc(Arg1)->set.size, ! 166: BlkLoc(Arg2)->set.size) * sizeof(struct b_selem)); ! 167: /* ! 168: * Using the smaller of the two sets as the source ! 169: * copy directly into the result each of its elements ! 170: * that are also members of the other set. ! 171: */ ! 172: if (BlkLoc(Arg1)->set.size <= BlkLoc(Arg2)->set.size) { ! 173: srcp = (struct b_set *) BlkLoc(Arg1); ! 174: tstp = (struct b_set *) BlkLoc(Arg2); ! 175: } ! 176: else { ! 177: srcp = (struct b_set *) BlkLoc(Arg2); ! 178: tstp = (struct b_set *) BlkLoc(Arg1); ! 179: } ! 180: Arg0.dword = D_Set; ! 181: dstp = alcset(); ! 182: BlkLoc(Arg0) = (union block *) dstp; ! 183: for (i = 0; i < SSlots; i++) { ! 184: sep = (struct b_selem *) BlkLoc(srcp->sbucks[i]); ! 185: dp = &dstp->sbucks[i]; ! 186: while (sep != NULL) { ! 187: if (locate((struct b_selem *)BlkLoc(tstp->sbucks[i]), sep)) { ! 188: dp->dword = D_Selem; ! 189: BlkLoc(*dp) = (union block *) alcselem(&sep->setmem, sep->hashnum); ! 190: dp = &BlkLoc(*dp)->selem.clink; ! 191: dstp->size++; ! 192: } ! 193: sep = (struct b_selem *) BlkLoc(sep->clink); ! 194: } ! 195: } ! 196: } ! 197: else { ! 198: skipsets: ! 199: blkreq((word)sizeof(struct b_cset)); ! 200: ! 201: /* ! 202: * x and y must be csets. ! 203: */ ! 204: if (cvcset(&Arg1, &cs1, csbuf1) == NULL) ! 205: runerr(104, &Arg1); ! 206: if (cvcset(&Arg2, &cs2, csbuf2) == NULL) ! 207: runerr(104, &Arg2); ! 208: ! 209: /* ! 210: * Allocate a new cset and in each word of it, compute the value ! 211: * of the bitwise intersection of the corresponding words in the ! 212: * x and y csets. ! 213: */ ! 214: bp = (union block *) alccset(0); ! 215: for (i = 0; i < CsetSize; i++) { ! 216: bp->cset.bits[i] = cs1[i] & cs2[i]; ! 217: } ! 218: j = 0; ! 219: for (i = 0; i < CsetSize*CIntSize; i++) { ! 220: if (Testb(i,bp->cset.bits)) ! 221: j++; ! 222: } ! 223: bp->cset.size = j; ! 224: ! 225: Arg0.dword = D_Cset; ! 226: BlkLoc(Arg0) = bp; ! 227: } ! 228: Return; ! 229: } ! 230: ! 231: ! 232: /* ! 233: * x ++ y - union of csets x and y or of sets x and y. ! 234: */ ! 235: ! 236: OpDcl(unions,2,"++") ! 237: { ! 238: register word i, j; ! 239: union block *bp; ! 240: int *cs1, *cs2, csbuf1[CsetSize], csbuf2[CsetSize]; ! 241: extern struct b_cset *alccset(); ! 242: int res; ! 243: struct b_set *srcp, *tstp, *dstp; ! 244: struct b_selem *ep; ! 245: struct descrip *dp, *hook; ! 246: extern struct b_set *alcset(); ! 247: extern struct b_selem *alcselem(); ! 248: extern struct descrip *memb(); ! 249: ! 250: if (Qual(Arg1) || Qual(Arg2)) ! 251: goto skipsets; ! 252: if (Arg1.dword == D_Set && Arg2.dword != D_Set) ! 253: runerr(119,&Arg2); ! 254: if (Arg2.dword == D_Set && Arg1.dword != D_Set) ! 255: runerr(119,&Arg1); ! 256: if (Arg1.dword == D_Set && Arg2.dword == D_Set) { ! 257: /* ! 258: * Both x and y are sets - do set union ! 259: * get enough space for a set as big as x + y. ! 260: */ ! 261: blkreq(sizeof(struct b_set) + (BlkLoc(Arg1)->set.size + ! 262: BlkLoc(Arg2)->set.size) * sizeof(struct b_selem)); ! 263: /* ! 264: * Select the larger of the two sets as the source ! 265: * copy each element to a new set for the result ! 266: * then insert each member of the second set into the ! 267: * result set if it is not already there. ! 268: */ ! 269: if (BlkLoc(Arg1)->set.size >= BlkLoc(Arg2)->set.size) { ! 270: srcp = (struct b_set *) BlkLoc(Arg1); ! 271: tstp = (struct b_set *) BlkLoc(Arg2); ! 272: } ! 273: else { ! 274: srcp = (struct b_set *) BlkLoc(Arg2); ! 275: tstp = (struct b_set *) BlkLoc(Arg1); ! 276: } ! 277: Arg0.dword = D_Set; ! 278: dstp = alcset(); ! 279: BlkLoc(Arg0) = (union block *) dstp; ! 280: for (i = 0; i < SSlots; i++) { ! 281: ep = (struct b_selem *) BlkLoc(srcp->sbucks[i]); ! 282: dp = &dstp->sbucks[i]; ! 283: while (ep != NULL) { ! 284: dp->dword = D_Selem; ! 285: BlkLoc(*dp) = (union block *) alcselem(&ep->setmem, ep->hashnum); ! 286: dp = &BlkLoc(*dp)->selem.clink; ! 287: dstp->size++; ! 288: ep = (struct b_selem *) BlkLoc(ep->clink); ! 289: } ! 290: } ! 291: for (i = 0; i < SSlots; i++) { ! 292: ep = (struct b_selem *) BlkLoc(tstp->sbucks[i]); ! 293: while (ep != NULL) { ! 294: hook = memb(dstp, &ep->setmem, ep->hashnum, &res); ! 295: if (res == 0) ! 296: addmem(dstp, alcselem(&ep->setmem, ep->hashnum), hook); ! 297: ep = (struct b_selem *) BlkLoc(ep->clink); ! 298: } ! 299: } ! 300: } ! 301: else { ! 302: skipsets: ! 303: ! 304: blkreq((word)sizeof(struct b_cset)); ! 305: ! 306: /* ! 307: * x and y must be csets. ! 308: */ ! 309: if (cvcset(&Arg1, &cs1, csbuf1) == NULL) ! 310: runerr(104, &Arg1); ! 311: if (cvcset(&Arg2, &cs2, csbuf2) == NULL) ! 312: runerr(104, &Arg2); ! 313: ! 314: /* ! 315: * Allocate a new cset and in each word of it, compute the value ! 316: * of the bitwise union of the corresponding words in the ! 317: * x and y csets. ! 318: */ ! 319: bp = (union block *) alccset(0); ! 320: for (i = 0; i < CsetSize; i++) { ! 321: bp->cset.bits[i] = cs1[i] | cs2[i]; ! 322: } ! 323: j = 0; ! 324: for (i = 0; i < CsetSize*CIntSize; i++) { ! 325: if (Testb(i,bp->cset.bits)) ! 326: j++; ! 327: } ! 328: bp->cset.size = j; ! 329: ! 330: Arg0.dword = D_Cset; ! 331: BlkLoc(Arg0) = bp; ! 332: } ! 333: Return; ! 334: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.