|
|
1.1 ! root 1: /* ! 2: * File: ocat.c ! 3: * Contents: cat, lconcat ! 4: */ ! 5: ! 6: #include "../h/rt.h" ! 7: ! 8: /* ! 9: * x || y - concatenate strings x and y. ! 10: */ ! 11: ! 12: /* >cat */ ! 13: OpDcl(cat,2,"||") ! 14: { ! 15: char sbuf1[MaxCvtLen]; /* buffers for conversion to string */ ! 16: char sbuf2[MaxCvtLen]; ! 17: extern char *alcstr(); ! 18: ! 19: /* ! 20: * Convert arguments to strings if necessary. ! 21: */ ! 22: if (cvstr(&Arg1, sbuf1) == NULL) ! 23: runerr(103, &Arg1); ! 24: if (cvstr(&Arg2, sbuf2) == NULL) ! 25: runerr(103, &Arg2); ! 26: ! 27: /* ! 28: * Ensure space for the resulting string. ! 29: */ ! 30: strreq(StrLen(Arg1) + StrLen(Arg2)); ! 31: ! 32: if (StrLoc(Arg1) + StrLen(Arg1) == strfree) ! 33: /* ! 34: * The end of Arg1 is at the end of the string space. Hence, Arg1 ! 35: * was the last string allocated. Arg1 is not copied. Instead, ! 36: * Arg2 is appended to the string space and the result is pointed ! 37: * to the start of Arg1. ! 38: */ ! 39: StrLoc(Arg0) = StrLoc(Arg1); ! 40: else ! 41: /* ! 42: * Otherwise, append Arg1 to the end of the string space and point ! 43: * the result to the start of Arg1. ! 44: */ ! 45: StrLoc(Arg0) = alcstr(StrLoc(Arg1),StrLen(Arg1)); ! 46: /* ! 47: * Append Arg2 to the end of the string space. ! 48: */ ! 49: alcstr(StrLoc(Arg2),StrLen(Arg2)); ! 50: /* ! 51: * Set the length of the result and return. ! 52: */ ! 53: StrLen(Arg0) = StrLen(Arg1) + StrLen(Arg2); ! 54: Return; ! 55: } ! 56: /* <cat */ ! 57: ! 58: ! 59: /* ! 60: * x ||| y - concatenate lists x and y. ! 61: */ ! 62: ! 63: OpDcl(lconcat,2,"|||") ! 64: { ! 65: register struct b_list *bp1, *bp2; ! 66: register struct b_lelem *lp1, *lp2; ! 67: word size1, size2; ! 68: ! 69: /* ! 70: * x and y must be lists. ! 71: */ ! 72: if (Qual(Arg1) || Arg1.dword != D_List) ! 73: runerr(108, &Arg1); ! 74: if (Qual(Arg2) || Arg2.dword != D_List) ! 75: runerr(108, &Arg2); ! 76: ! 77: /* ! 78: * Get the size of both lists. ! 79: */ ! 80: size1 = BlkLoc(Arg1)->list.size; ! 81: size2 = BlkLoc(Arg2)->list.size; ! 82: ! 83: /* ! 84: * Make a copy of both lists. ! 85: */ ! 86: cplist(&Arg1, &Arg1, (word)1, size1 + 1); ! 87: cplist(&Arg2, &Arg2, (word)1, size2 + 1); ! 88: ! 89: /* ! 90: * Get a pointer to both lists. bp1 points to the copy of x and is ! 91: * the list that will be returned. ! 92: */ ! 93: bp1 = (struct b_list *) BlkLoc(Arg1); ! 94: bp2 = (struct b_list *) BlkLoc(Arg2); ! 95: ! 96: /* ! 97: * Perform the concatenation by hooking the lists together so ! 98: * that the next list of x is y and the previous list of y is x. ! 99: */ ! 100: lp1 = (struct b_lelem *) BlkLoc(bp1->listtail); ! 101: lp2 = (struct b_lelem *) BlkLoc(bp2->listhead); ! 102: ! 103: lp1->listnext.dword = D_Lelem; ! 104: BlkLoc(lp1->listnext) = (union block *) lp2; ! 105: ! 106: lp2->listprev.dword = D_Lelem; ! 107: BlkLoc(lp2->listprev) = (union block *) lp1; ! 108: ! 109: /* ! 110: * Adjust the size field to reflect the length of the concatenated lists. ! 111: */ ! 112: bp1->size = size1 + size2; ! 113: BlkLoc(bp1->listtail) = BlkLoc(bp2->listtail); ! 114: ! 115: Arg0 = Arg1; ! 116: Return; ! 117: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.