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