Annotation of researchv10dc/cmd/icon/src/iconx/oset.c, revision 1.1.1.1

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:    }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.