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

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:    }

unix.superglobalmegacorp.com

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