Annotation of researchv10dc/cmd/icon/src/iconx/ocat.c, revision 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.