home *** CD-ROM | disk | FTP | other *** search
- /*
- * File: ocat.c
- * Contents: cat, lconcat
- */
-
- #include "../h/config.h"
- #include "../h/rt.h"
- #include "rproto.h"
-
-
- /*
- * x || y - concatenate strings x and y.
- */
-
- OpDcl(cater,2,"||")
- {
- char sbuf1[MaxCvtLen]; /* buffers for conversion to string */
- char sbuf2[MaxCvtLen];
-
- /*
- * Convert arguments to strings if necessary.
- */
- if (cvstr(&Arg1, sbuf1) == CvtFail)
- RunErr(103, &Arg1);
- if (cvstr(&Arg2, sbuf2) == CvtFail)
- RunErr(103, &Arg2);
-
- if (StrLoc(Arg1) + StrLen(Arg1) == strfree) {
- /*
- * The end of Arg1 is at the end of the string space. Hence,
- * Arg1 was the last string allocated. Arg1 is not copied.
- * Instead, Arg2 is appended to the string space and the
- * result is pointed to the start of Arg1.
- * Space is only needed for the string being appended
- */
- if (strreq(StrLen(Arg2)) == Error)
- RunErr(0, NULL);
- StrLoc(Arg0) = StrLoc(Arg1);
- }
- else {
- /*
- * Ensure space for the resulting concatenated string
- */
- if (strreq(StrLen(Arg1) + StrLen(Arg2)) == Error)
- RunErr(0, NULL);
- /*
- * Otherwise, append Arg1 to the end of the string space and
- * point the result to the start of Arg1.
- */
- StrLoc(Arg0) = alcstr(StrLoc(Arg1),StrLen(Arg1));
- }
-
- /*
- * Append Arg2 to the end of the string space.
- */
- alcstr(StrLoc(Arg2),StrLen(Arg2));
- /*
- * Set the length of the result and return.
- */
- StrLen(Arg0) = StrLen(Arg1) + StrLen(Arg2);
- Return;
- }
-
- /*
- * x ||| y - concatenate lists x and y.
- */
-
- OpDcl(lconcat,2,"|||")
- {
- register struct b_list *bp1, *bp2;
- register struct b_lelem *lp1, *lp2;
- word size1, size2;
-
- /*
- * x and y must be lists.
- */
- if (Arg1.dword != D_List)
- RunErr(108, &Arg1);
- if (Arg2.dword != D_List)
- RunErr(108, &Arg2);
-
- /*
- * Get the size of both lists.
- */
- size1 = BlkLoc(Arg1)->list.size;
- size2 = BlkLoc(Arg2)->list.size;
-
- /*
- * Make a copy of both lists.
- */
- if (cplist(&Arg1, &Arg1, (word)1, size1 + 1) == Error)
- RunErr(0, NULL);
- if (cplist(&Arg2, &Arg2, (word)1, size2 + 1) == Error)
- RunErr(0, NULL);
-
- /*
- * Get a pointer to both lists. bp1 points to the copy of Arg1 and is
- * the list that will be returned.
- */
- bp1 = (struct b_list *) BlkLoc(Arg1);
- bp2 = (struct b_list *) BlkLoc(Arg2);
-
- /*
- * Perform the concatenation by hooking the lists together.
- */
- lp1 = (struct b_lelem *) bp1->listtail;
- lp2 = (struct b_lelem *) bp2->listhead;
-
- lp1->listnext = (union block *) lp2;
-
- lp2->listprev = (union block *) lp1;
-
- /*
- * Adjust the size field to reflect the length of the concatenated lists.
- */
- bp1->size = size1 + size2;
- bp1->listtail = bp2->listtail;
-
- Arg0 = Arg1;
- Return;
- }
-