|
|
1.1 ! root 1: #include "../h/rt.h" ! 2: ! 3: /* ! 4: * x ||| y - concatenate lists x and y. ! 5: */ ! 6: ! 7: lconcat(nargs, arg2, arg1, arg0) ! 8: int nargs; ! 9: struct descrip arg2, arg1, arg0; ! 10: { ! 11: register struct b_list *bp1, *bp2; ! 12: register struct b_lelem *lp1, *lp2; ! 13: int size1, size2; ! 14: ! 15: SetBound; ! 16: /* ! 17: * x and y must be lists. ! 18: */ ! 19: DeRef(arg1) ! 20: DeRef(arg2) ! 21: if (QUAL(arg1) || TYPE(arg1) != T_LIST) ! 22: runerr(108, &arg1); ! 23: if (QUAL(arg2) || TYPE(arg2) != T_LIST) ! 24: runerr(108, &arg2); ! 25: ! 26: /* ! 27: * Get the size of both lists. ! 28: */ ! 29: size1 = BLKLOC(arg1)->list.cursize; ! 30: size2 = BLKLOC(arg2)->list.cursize; ! 31: ! 32: /* ! 33: * Make a copy of both lists. ! 34: */ ! 35: cplist(&arg1, &arg1, 1, size1 + 1); ! 36: cplist(&arg2, &arg2, 1, size2 + 1); ! 37: ! 38: /* ! 39: * Get a pointer to both lists. bp1 points to the copy of x and is ! 40: * the list that will be returned. ! 41: */ ! 42: bp1 = (struct b_list *) BLKLOC(arg1); ! 43: bp2 = (struct b_list *) BLKLOC(arg2); ! 44: ! 45: /* ! 46: * Perform the concatenation by hooking the lists together so ! 47: * that the next list of x is y and the previous list of y is x. ! 48: */ ! 49: lp1 = (struct b_lelem *) BLKLOC(bp1->listtail); ! 50: lp2 = (struct b_lelem *) BLKLOC(bp2->listhead); ! 51: ! 52: lp1->listnext.type = D_LELEM; ! 53: BLKLOC(lp1->listnext) = (union block *) lp2; ! 54: ! 55: lp2->listprev.type = D_LELEM; ! 56: BLKLOC(lp2->listprev) = (union block *) lp1; ! 57: ! 58: /* ! 59: * Adjust the size field to reflect the length of the concatenated lists. ! 60: */ ! 61: bp1->cursize = size1 + size2; ! 62: BLKLOC(bp1->listtail) = BLKLOC(bp2->listtail); ! 63: ! 64: arg0 = arg1; ! 65: ClearBound; ! 66: } ! 67: ! 68: Opblock(lconcat,2,"|||")
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.