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

1.1       root        1: /*
                      2:  * File: fstruct.c
                      3:  *  Contents: delete, get, insert, member, pop, pull, push, put, sort
                      4:  */
                      5: 
                      6: #include "../h/rt.h"
                      7: 
                      8: /*
                      9:  * delete(S,x) - delete element x from set S if it is there
                     10:  *  (always succeeds and returns S).
                     11:  */
                     12: 
                     13: FncDcl(delete,2)
                     14:    {
                     15:    register struct descrip *pd;
                     16:    int res ;
                     17:    extern struct descrip *memb();
                     18: 
                     19:    Arg0 = Arg1;
                     20: 
                     21:    if (Arg1.dword != D_Set)
                     22:        runerr(119,&Arg1);
                     23: 
                     24:       /*
                     25:       * The technique and philosophy here are the same
                     26:       *  as used in insert - see comment there.
                     27:       */
                     28:    pd = memb((struct b_set *)BlkLoc(Arg1),&Arg2,hash(&Arg2),&res);
                     29:    if (res == 1) {
                     30:       /*
                     31:       * The element is there so delete it.
                     32:       */
                     33:       *pd = BlkLoc(*pd)->selem.clink;
                     34:       (BlkLoc(Arg1)->set.size)--;
                     35:       }
                     36:    Return;
                     37:    }
                     38: 
                     39: 
                     40: /*
                     41:  * get(x) - get an element from end of list x.
                     42:  *  Identical to pop(x).
                     43:  */
                     44: 
                     45: FncDcl(get,1)
                     46:    {
                     47:    register word i;
                     48:    register struct b_list *hp;
                     49:    register struct b_lelem *bp;
                     50:    extern struct b_lelem *alclstb();
                     51: 
                     52:    /*
                     53:     * x must be a list.
                     54:     */
                     55:    if (Arg1.dword != D_List)
                     56:       runerr(108, &Arg1);
                     57: 
                     58:    /*
                     59:     * Fail if the list is empty.
                     60:     */
                     61:    hp = (struct b_list *) BlkLoc(Arg1);
                     62:    if (hp->size <= 0)
                     63:       Fail;
                     64: 
                     65:    /*
                     66:     * Point bp at the first list block.  If the first block has no
                     67:     *  elements in use, point bp at the next list block.
                     68:     */
                     69:    bp = (struct b_lelem *) BlkLoc(hp->listhead);
                     70:    if (bp->nused <= 0) {
                     71:       bp = (struct b_lelem *) BlkLoc(bp->listnext);
                     72:       BlkLoc(hp->listhead) = (union block *) bp;
                     73:       bp->listprev = nulldesc;
                     74:       }
                     75:    /*
                     76:     * Locate first element and assign it to Arg0 for return.
                     77:     */
                     78:    i = bp->first;
                     79:    Arg0 = bp->lslots[i];
                     80:    /*
                     81:     * Set bp->first to new first element, or 0 if the block is now
                     82:     *  empty.  Decrement the usage count for the block and the size
                     83:     *  of the list.
                     84:     */
                     85:    if (++i >= bp->nelem)
                     86:       i = 0;
                     87:    bp->first = i;
                     88:    bp->nused--;
                     89:    hp->size--;
                     90:    Return;
                     91:    }
                     92: 
                     93: 
                     94: /*
                     95:  * insert(S,x) - insert element x into set S if not already there
                     96:  *  (always succeeds and returns S).
                     97:  */
                     98: 
                     99: FncDcl(insert,2)
                    100:    {
                    101:    register struct descrip *pd;
                    102:    register word hn;
                    103:    int res;
                    104:    extern struct b_selem *alcselem();
                    105:    extern struct descrip *memb();
                    106: 
                    107:    Arg0 = Arg1;
                    108: 
                    109:    if (Arg1.dword != D_Set)
                    110:       runerr(119,&Arg1);
                    111: 
                    112:       /*
                    113:       * We may need at most one new element.
                    114:       */
                    115:    blkreq((word)sizeof(struct b_selem));
                    116:    hn = hash(&Arg2);
                    117:    /*
                    118:     * If Arg2 is a member of set Arg1 then res will have the
                    119:     *  value 1 and pd will have a pointer to the descriptor
                    120:     *  that points to that member.
                    121:     *  If Arg2 is not a member of the set then res will have
                    122:     *  the value 0 and pd will point to the descriptor
                    123:     *  which should point to the member - thus we know where
                    124:     *  to link in the new element without having to do any
                    125:     *  repetitive looking.
                    126:     */
                    127:    pd = memb((struct b_set *)BlkLoc(Arg1),&Arg2,hn,&res);
                    128:    if (res == 0)
                    129:       /*
                    130:       * The element is not in the set - insert it.
                    131:       */
                    132:       addmem((struct b_set *)BlkLoc(Arg1),alcselem(&Arg2,hn),pd);
                    133:    Return;
                    134:    }
                    135: 
                    136: 
                    137: /*
                    138:  * member(S,x) - returns x if x is a member of set S otherwise fails.
                    139:  */
                    140: 
                    141: FncDcl(member,2)
                    142:    {
                    143:    int res;
                    144:    extern struct descrip *memb();
                    145: 
                    146:    if (Arg1.dword != D_Set)
                    147:       runerr(119,&Arg1);       /* S is not a set  */
                    148: 
                    149:    /* If Arg2 is a member of set Arg1 then "res" will have the
                    150:     * value 1 otherwise it will have the value 0.
                    151:     */
                    152:    memb((struct b_set *)BlkLoc(Arg1),&Arg2,hash(&Arg2),&res);
                    153:    if (res == 1) {             /* It is a member. */
                    154:       Arg0 = Arg2;             /* Return the member if it is in Arg1. */
                    155:       Return;
                    156:       }
                    157:    Fail;
                    158:    }
                    159: 
                    160: 
                    161: /*
                    162:  * pop(x) - pop an element from beginning of list x.
                    163:  */
                    164: 
                    165: /* >pop */
                    166: FncDcl(pop,1)
                    167:    {
                    168:    register word i;
                    169:    register struct b_list *hp;
                    170:    register struct b_lelem *bp;
                    171:    extern struct b_lelem *alclstb();
                    172: 
                    173:    /*
                    174:     * Arg1 must be a list.
                    175:     */
                    176:    if (Arg1.dword != D_List)
                    177:       runerr(108, &Arg1);
                    178: 
                    179:    /*
                    180:     * Fail if the list is empty.
                    181:     */
                    182:    hp = (struct b_list *) BlkLoc(Arg1);
                    183:    if (hp->size <= 0)
                    184:       Fail;
                    185: 
                    186:    /*
                    187:     * Point bp to the first list block.  If the first block has no
                    188:     *  elements in use, point bp at the next list block.
                    189:     */
                    190:    bp = (struct b_lelem *) BlkLoc(hp->listhead);
                    191:    if (bp->nused <= 0) {
                    192:       bp = (struct b_lelem *) BlkLoc(bp->listnext);
                    193:       BlkLoc(hp->listhead) = (union block *) bp;
                    194:       bp->listprev = nulldesc;
                    195:       }
                    196:    /*
                    197:     * Locate first element and assign it to Arg0 for return.
                    198:     */
                    199:    i = bp->first;
                    200:    Arg0 = bp->lslots[i];
                    201: 
                    202:    /*
                    203:     * Set bp->first to new first element, or 0 if the block is now
                    204:     *  empty.  Decrement the usage count for the block and the size
                    205:     *  of the list.
                    206:     */
                    207:    if (++i >= bp->nelem)
                    208:       i = 0;
                    209:    bp->first = i;
                    210:    bp->nused--;
                    211:    hp->size--;
                    212:    Return;
                    213:    }
                    214: /* <pop */
                    215: 
                    216: 
                    217: /*
                    218:  * pull(x) - pull an element from end of list x.
                    219:  */
                    220: 
                    221: FncDcl(pull,1)
                    222:    {
                    223:    register word i;
                    224:    register struct b_list *hp;
                    225:    register struct b_lelem *bp;
                    226:    extern struct b_lelem *alclstb();
                    227: 
                    228:    /*
                    229:     * x must be a list.
                    230:     */
                    231:    if (Arg1.dword != D_List)
                    232:       runerr(108, &Arg1);
                    233: 
                    234:    /*
                    235:     * Point at list header block and fail if the list is empty.
                    236:     */
                    237:    hp = (struct b_list *) BlkLoc(Arg1);
                    238:    if (hp->size <= 0)
                    239:       Fail;
                    240:    /*
                    241:     * Point bp at the last list element block.  If the last block has no
                    242:     *  elements in use, point bp at the previous list element block.
                    243:     */
                    244:    bp = (struct b_lelem *) BlkLoc(hp->listtail);
                    245:    if (bp->nused <= 0) {
                    246:       bp = (struct b_lelem *) BlkLoc(bp->listprev);
                    247:       BlkLoc(hp->listtail) = (union block *) bp;
                    248:       bp->listnext = nulldesc;
                    249:       }
                    250:    /*
                    251:     * Set i to position of last element and assign the element to
                    252:     *  Arg0 for return.  Decrement the usage count for the block
                    253:     *  and the size of the list.
                    254:     */
                    255:    i = bp->first + bp->nused - 1;
                    256:    if (i >= bp->nelem)
                    257:       i -= bp->nelem;
                    258:    Arg0 = bp->lslots[i];
                    259:    bp->nused--;
                    260:    hp->size--;
                    261:    Return;
                    262:    }
                    263: 
                    264: 
                    265: /*
                    266:  * push(x,val) - push val onto beginning of list x.
                    267:  */
                    268: FncDcl(push,2)
                    269:    {
                    270:    register word i;
                    271:    register struct b_list *hp;
                    272:    register struct b_lelem *bp;
                    273:    extern struct b_lelem *alclstb();
                    274: 
                    275:    /*
                    276:     * x must be a list.
                    277:     */
                    278:    if (Arg1.dword != D_List)
                    279:       runerr(108, &Arg1);
                    280: 
                    281:    /*
                    282:     * A new list element block might be needed, so ensure space for it.
                    283:     */
                    284:    blkreq((word)sizeof(struct b_lelem)+MinListSlots*sizeof(struct descrip));
                    285: 
                    286:    /*
                    287:     * Point hp at the list header block and bp at the first
                    288:     * list element block.
                    289:     */
                    290:    hp = (struct b_list *) BlkLoc(Arg1);
                    291:    bp = (struct b_lelem *) BlkLoc(hp->listhead);
                    292:    /*
                    293:     * If the first list element block is full,
                    294:     * allocate a new list element block, make it the first list
                    295:     *  element block and make it the previous block of the
                    296:     *  former first list element block.
                    297:     */
                    298:    if (bp->nused >= bp->nelem) {
                    299:       bp = alclstb((word)MinListSlots, (word)0, (word)0);
                    300:       BlkLoc(hp->listhead)->lelem.listprev.dword = D_Lelem;
                    301:       BlkLoc(BlkLoc(hp->listhead)->lelem.listprev) = (union block *) bp;
                    302:       bp->listnext = hp->listhead;
                    303:       BlkLoc(hp->listhead) = (union block *) bp;
                    304:       }
                    305:    /*
                    306:     * Set i to position of new first element and assign val (Arg2) to
                    307:     *  that element.
                    308:     */
                    309:    i = bp->first - 1;
                    310:    if (i < 0)
                    311:       i = bp->nelem - 1;
                    312:    bp->lslots[i] = Arg2;
                    313:    /*
                    314:     * Adjust value of location of first element, block usage count,
                    315:     *  and current list size.
                    316:     */
                    317:    bp->first = i;
                    318:    bp->nused++;
                    319:    hp->size++;
                    320:    /*
                    321:     * Return the list.
                    322:     */
                    323:    Arg0 = Arg1;
                    324:    Return;
                    325:    }
                    326: 
                    327: 
                    328: /*
                    329:  * put(x,val) - put val onto end of list x.
                    330:  */
                    331: 
                    332: FncDcl(put,2)
                    333:    {
                    334:    register word i;
                    335:    register struct b_list *hp;
                    336:    register struct b_lelem *bp;
                    337:    extern struct b_lelem *alclstb();
                    338: 
                    339:    /*
                    340:     * Arg1 must be a list.
                    341:     */
                    342:    if (Arg1.dword != D_List)
                    343:       runerr(108, &Arg1);
                    344: 
                    345:    /*
                    346:     * A new list element block might be needed, so ensure space for it.
                    347:     */
                    348:    blkreq((word)sizeof(struct b_lelem)+MinListSlots*sizeof(struct descrip));
                    349: 
                    350: /* >put */
                    351:    /*
                    352:     * Point hp to the list header block and bp to the last
                    353:     *  list element block.
                    354:     */
                    355:    hp = (struct b_list *) BlkLoc(Arg1);
                    356:    bp = (struct b_lelem *) BlkLoc(hp->listtail);
                    357: 
                    358:    /*
                    359:     * If the last list element block is full, allocate a new
                    360:     *  list element block, make it the first list element block
                    361:     *  and it make it the next block of the former last list
                    362:     *  element block.
                    363:     */
                    364:    if (bp->nused >= bp->nelem) {
                    365:       bp = alclstb((word)MinListSlots, (word)0, (word)0);
                    366:       BlkLoc(hp->listtail)->lelem.listnext.dword = D_Lelem;
                    367:       BlkLoc(BlkLoc(hp->listtail)->lelem.listnext) = (union block *) bp;
                    368:       bp->listprev = hp->listtail;
                    369:       BlkLoc(hp->listtail) = (union block *) bp;
                    370:       }
                    371: 
                    372:    /*
                    373:     * Set i to position of new last element and assign Arg2 to
                    374:     *  that element.
                    375:     */
                    376:    i = bp->first + bp->nused;
                    377:    if (i >= bp->nelem)
                    378:       i -= bp->nelem;
                    379:    bp->lslots[i] = Arg2;
                    380: 
                    381:    /*
                    382:     * Adjust block usage count and current list size.
                    383:     */
                    384:    bp->nused++;
                    385:    hp->size++;
                    386: 
                    387:    /*
                    388:     * Return the list.
                    389:     */
                    390:    Arg0 = Arg1;
                    391:    Return;
                    392:    }
                    393: /* <put */
                    394: 
                    395: 
                    396: struct dpair {
                    397:    struct descrip dr;
                    398:    struct descrip dv;
                    399:    };
                    400: 
                    401: /*
                    402:  * sort(l) - sort list l.
                    403:  * sort(S) - sort set S.
                    404:  * sort(t,i) - sort table.
                    405:  */
                    406: 
                    407: FncDcl(sort,2)
                    408:    {
                    409:    register struct descrip *d1;
                    410:    register word size;
                    411:    register int i;
                    412:    word nelem;
                    413:    struct b_list *lp, *tp;
                    414:    union block *bp, *ep;
                    415:    extern struct b_list *alclist();
                    416:    extern struct b_lelem *alclstb();
                    417:    extern anycmp(), trefcmp(), tvalcmp(), trcmp3(), tvcmp4();
                    418: 
                    419:    if (Arg1.dword == D_List) {
                    420:       /*
                    421:        * Sort the list by copying it into a new list and then using
                    422:        *  qsort to sort the descriptors.  (That was easy!)
                    423:        */
                    424:       size = BlkLoc(Arg1)->list.size;
                    425:       cplist(&Arg1, &Arg0, (word)1, size + 1);
                    426:       qsort(BlkLoc(BlkLoc(Arg0)->list.listhead)->lelem.lslots, size,
                    427:             sizeof(struct descrip), anycmp);
                    428:       }
                    429:    else if (Arg1.dword == D_Set) {
                    430:       /*
                    431:        * Create a list the size of the set (or at least 
                    432:        *  MinListSlots), copy each element into the list, and
                    433:        *  then sort the list using qsort as in list sorting
                    434:        *  and return the sorted list.
                    435:        */
                    436:    nelem = size = BlkLoc(Arg1)->set.size;
                    437:    if(nelem < MinListSlots)
                    438:       nelem = MinListSlots;
                    439:    blkreq(sizeof(struct b_list) + sizeof(struct b_lelem) +
                    440:       nelem * sizeof(struct descrip));
                    441: 
                    442:    bp = BlkLoc(Arg1);
                    443:    lp = alclist(size);
                    444:    lp->listhead.dword = lp->listtail.dword = D_Lelem;
                    445:       BlkLoc(lp->listtail) = (union block *) alclstb(nelem, (word)0, size);
                    446:    BlkLoc(lp->listhead) = BlkLoc(lp->listtail);
                    447:    if (size > 0) {  /* only need to sort non-empty sets */
                    448:       d1 = BlkLoc(lp->listhead)->lelem.lslots;
                    449:       for(i = 0; i < SSlots; i++) {
                    450:       ep = BlkLoc(bp->set.sbucks[i]);
                    451:       while (ep != NULL) {
                    452:          *d1 = ep->selem.setmem;
                    453:          d1++;
                    454:          ep = BlkLoc(ep->selem.clink);
                    455:          }
                    456:       }
                    457:       qsort(BlkLoc(lp->listhead)->lelem.lslots,size,
                    458:          sizeof(struct descrip),anycmp);
                    459:    }
                    460:    Arg0.dword = D_List;
                    461:    BlkLoc(Arg0) = (union block *) lp;
                    462:    }
                    463: 
                    464:    else if (Arg1.dword == D_Table) {
                    465:       /*
                    466:        * Default i (the type of sort) to 1.
                    467:        */
                    468:       defshort(&Arg2, 1);
                    469:       switch (IntVal(Arg2)) {
                    470: 
                    471:       /*
                    472:        * Cases 1 and 2 are as in standard Version 5.
                    473:        */
                    474:          case 1:
                    475:          case 2:
                    476:                 {
                    477:       /*
                    478:        * The list resulting from the sort will have as many elements as
                    479:        *  the table has, so get that value and also make a valid list
                    480:        *  block size out of it.
                    481:        */
                    482:       nelem = size = BlkLoc(Arg1)->table.size;
                    483:       if (nelem < MinListSlots)
                    484:          nelem = MinListSlots;
                    485:       /*
                    486:        * Ensure space for: the list header block and a list element
                    487:        *  block for the list which is to be returned,
                    488:        *  a list header block and a list element block for each of the two
                    489:        *  element lists the sorted list is to contain.  Note that the
                    490:        *  calculation might be better expressed as:
                    491:        *    list_header_size + list_block_size + nelem * descriptor_size +
                    492:        *     nelem * (list_header_size + list_block_size + 2*descriptor_size)
                    493:        */
                    494:       blkreq(sizeof(struct b_list) + sizeof(struct b_lelem) +
                    495:          nelem * (sizeof(struct b_list) + sizeof(struct b_lelem) +
                    496:             3 * sizeof(struct descrip)));
                    497:       /*
                    498:        * Point bp at the table header block of the table to be sorted
                    499:        *  and point lp at a newly allocated list
                    500:        *  that will hold the the result of sorting the table.
                    501:        */
                    502:       bp = BlkLoc(Arg1);
                    503:       lp = alclist(size);
                    504:       lp->listhead.dword = lp->listtail.dword = D_Lelem;
                    505:       BlkLoc(lp->listtail) = (union block *) alclstb(nelem, (word)0, size);
                    506:       BlkLoc(lp->listhead) = BlkLoc(lp->listtail);
                    507:       /*
                    508:        * If the table is empty, there is no need to sort anything.
                    509:        */
                    510:       if (size <= 0)
                    511:          break;
                    512:          /*
                    513:           * Point d1 at the start of the list elements in the new list
                    514:           *  element block in preparation for use as an index into the list.
                    515:           */
                    516:          d1 = BlkLoc(lp->listhead)->lelem.lslots;
                    517:          /*
                    518:           * Traverse the element chain for each table bucket.  For each
                    519:           *  element, allocate a two-element list and put the table
                    520:           *  entry value in the first element and the assigned value in
                    521:           *  the second element.  The two-element list is assigned to
                    522:           *  the descriptor that d1 points at.  When this is done, the
                    523:           *  list of two-element lists is complete, but unsorted.
                    524:           */
                    525:          for (i = 0; i < TSlots; i++) {
                    526:             ep = BlkLoc(bp->table.buckets[i]);
                    527:             while (ep != NULL) {
                    528:                d1->dword = D_List;
                    529:                tp = alclist((word)2);
                    530:                BlkLoc(*d1) = (union block *) tp;
                    531:                tp->listhead.dword = tp->listtail.dword = D_Lelem;
                    532:                BlkLoc(tp->listtail) = (union block *) alclstb((word)2, (word)0,
                    533:                   (word)2);
                    534:                BlkLoc(tp->listhead) = BlkLoc(tp->listtail);
                    535:                BlkLoc(tp->listhead)->lelem.lslots[0] = ep->telem.tref;
                    536:                BlkLoc(tp->listhead)->lelem.lslots[1] = ep->telem.tval;
                    537:                d1++;
                    538:                ep = BlkLoc(ep->telem.clink);
                    539:                }
                    540:             }
                    541:          /*
                    542:           * Sort the resulting two-element list using the sorting function
                    543:           *  determined by i.
                    544:           */
                    545:          if (IntVal(Arg2) == 1)
                    546:             qsort(BlkLoc(lp->listhead)->lelem.lslots, size,
                    547:                   sizeof(struct descrip), trefcmp);
                    548:          else
                    549:             qsort(BlkLoc(lp->listhead)->lelem.lslots, size,
                    550:                   sizeof(struct descrip), tvalcmp);
                    551:          break;                /* from cases 1 and 2 */
                    552:          }
                    553:       /*
                    554:        * Cases 3 and 4 were introduced in Version 5.10.
                    555:        */
                    556:          case 3 :
                    557:          case 4 :
                    558:                  {
                    559:       /*
                    560:        * The list resulting from the sort will have twice as many elements as
                    561:        *  the table has, so get that value and also make a valid list
                    562:        *  block size out of it.
                    563:        */
                    564:       nelem = size = BlkLoc(Arg1)->table.size * 2;
                    565:       if (nelem < MinListSlots)
                    566:          nelem = MinListSlots;
                    567:       /*
                    568:        * Ensure space for: the list header block and a list element
                    569:        *  block for the list which is to be returned, and two descriptors for
                    570:        *  each table element.
                    571:        */
                    572:       blkreq(sizeof(struct b_list) + Vsizeof(struct b_lelem) +
                    573:             (nelem * sizeof(struct descrip)));
                    574:       /*
                    575:        * Point bp at the table header block of the table to be sorted
                    576:        *  and point lp at a newly allocated list
                    577:        *  that will hold the the result of sorting the table.
                    578:        */
                    579:       bp = BlkLoc(Arg1);
                    580:       lp = alclist(size);
                    581:       lp->listhead.dword = lp->listtail.dword = D_Lelem;
                    582:       BlkLoc(lp->listtail) = (union block *) alclstb(nelem, (word)0, size);
                    583:       BlkLoc(lp->listhead) = BlkLoc(lp->listtail);
                    584:       /*
                    585:        * If the table is empty there's no need to sort anything.
                    586:        */
                    587:       if (size <= 0)
                    588:          break;
                    589: 
                    590:          /*
                    591:           * Point d1 at the start of the list elements in the new list
                    592:           *  element block in preparation for use as an index into the list.
                    593:           */
                    594:          d1 = BlkLoc(lp->listhead)->lelem.lslots;
                    595:          /*
                    596:           * Traverse the element chain for each table bucket.  For each
                    597:           *  table element copy the the entry descriptor and the value
                    598:           *  descriptor into adjacent descriptors in the lslots array
                    599:           *  in the list element block.
                    600:           *  When this is done we now need to sort this list.
                    601:           */
                    602:          for (i = 0; i < TSlots; i++) {
                    603:             ep = BlkLoc(bp->table.buckets[i]);
                    604:             while (ep != NULL) {
                    605:                *d1 = ep->telem.tref;
                    606:                d1++;
                    607:                *d1 = ep->telem.tval;
                    608:                d1++;
                    609:                ep = BlkLoc(ep->telem.clink);
                    610:                }
                    611:             }
                    612:          /*
                    613:           * Sort the resulting two-element list using the sorting function
                    614:           *  determined by i.
                    615:           */
                    616:          if (IntVal(Arg2) == 3)
                    617:             qsort(BlkLoc(lp->listhead)->lelem.lslots, size / 2,
                    618:                   (2 * sizeof(struct descrip)), trcmp3);
                    619:          else
                    620:             qsort(BlkLoc(lp->listhead)->lelem.lslots, size / 2,
                    621:                   (2 * sizeof(struct descrip)), tvcmp4);
                    622:             break; /* from case 3 or 4 */
                    623:             }
                    624: 
                    625:          default : runerr(205,&Arg2);
                    626:          } /* end of switch statement */
                    627:       /*
                    628:        * Make Arg0 point at the sorted list.
                    629:        */
                    630:       Arg0.dword = D_List;
                    631:       BlkLoc(Arg0) = (union block *) lp;
                    632:       }
                    633:    else /* Tried to sort something that wasn't a list or a table. */
                    634:       runerr(115, &Arg1);
                    635:    Return;
                    636:    }
                    637: 
                    638: /*
                    639:  * trefcmp(d1,d2) - compare two-element lists on first field.
                    640:  */
                    641: 
                    642: trefcmp(d1,d2)
                    643: struct descrip *d1, *d2;
                    644:    {
                    645:    extern anycmp();
                    646: 
                    647: #ifdef Debug
                    648:    if (d1->dword != D_List || d2->dword != D_List)
                    649:       syserr("trefcmp: internal consistency check fails.");
                    650: #endif Debug
                    651:    return (anycmp(&(BlkLoc(BlkLoc(*d1)->list.listhead)->lelem.lslots[0]),
                    652:                   &(BlkLoc(BlkLoc(*d2)->list.listhead)->lelem.lslots[0])));
                    653:    }
                    654: 
                    655: /*
                    656:  * tvalcmp(d1,d2) - compare two-element lists on second field.
                    657:  */
                    658: 
                    659: tvalcmp(d1,d2)
                    660: struct descrip *d1, *d2;
                    661:    {
                    662:    extern anycmp();
                    663: 
                    664: #ifdef Debug
                    665:    if (d1->dword != D_List || d2->dword != D_List)
                    666:       syserr("tvalcmp: internal consistency check fails.");
                    667: #endif Debug
                    668:    return (anycmp(&(BlkLoc(BlkLoc(*d1)->list.listhead)->lelem.lslots[1]),
                    669:                   &(BlkLoc(BlkLoc(*d2)->list.listhead)->lelem.lslots[1])));
                    670:    }
                    671: 
                    672: /*
                    673:  * The following two routines are used to compare descriptor pairs in the
                    674:  *  experimental table sort.
                    675:  *
                    676:  * trcmp3(dp1,dp2)
                    677:  */
                    678: 
                    679: trcmp3(dp1,dp2)
                    680: struct dpair *dp1,*dp2;
                    681: {
                    682:    extern anycmp();
                    683: 
                    684:    return (anycmp(&((*dp1).dr),&((*dp2).dr)));
                    685: }
                    686: /*
                    687:  * tvcmp4(dp1,dp2)
                    688:  */
                    689: 
                    690: tvcmp4(dp1,dp2)
                    691: struct dpair *dp1,*dp2;
                    692: 
                    693:    {
                    694:    extern anycmp();
                    695: 
                    696:    return (anycmp(&((*dp1).dv),&((*dp2).dv)));
                    697:    }

unix.superglobalmegacorp.com

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