Annotation of 43BSD/contrib/icon/operators/rswap.c, revision 1.1

1.1     ! root        1: #include "../h/rt.h"
        !             2: 
        !             3: /*
        !             4:  * x <-> y - swap values of x and y.
        !             5:  * Reverses swap if resumed.
        !             6:  */
        !             7: 
        !             8: rswap(nargs, arg2v, arg2, arg1, arg0)
        !             9: int nargs;
        !            10: struct descrip arg2v, arg2, arg1, arg0;
        !            11:    {
        !            12:    register union block *bp1, *bp2;
        !            13:    int adj1, adj2;
        !            14: 
        !            15:    SetBound;
        !            16:    /*
        !            17:     * x and y must be variables.
        !            18:     */
        !            19:    if (QUAL(arg1) || !VAR(arg1))
        !            20:       runerr(111, &arg1);
        !            21:    if (QUAL(arg2) || !VAR(arg2))
        !            22:       runerr(111, &arg2);
        !            23:    /*
        !            24:     * Make copies of x and y as variables in arg0 and arg2v.
        !            25:     */
        !            26:    arg0 = arg1;
        !            27:    arg2v = arg2;
        !            28:    adj1 = adj2 = 0;
        !            29:    if (arg1.type == D_TVSUBS && arg2.type == D_TVSUBS) {
        !            30:       bp1 = BLKLOC(arg1);
        !            31:       bp2 = BLKLOC(arg2);
        !            32:       if (VARLOC(bp1->tvsubs.ssvar) == VARLOC(bp2->tvsubs.ssvar)) {
        !            33:          /*
        !            34:           * x and y are both substrings of the same string, set
        !            35:           *  adj1 and adj2 for use in locating the substrings after
        !            36:           *  an assignment has been made.  If x is to the right of y,
        !            37:           *  set adj1 := *x - *y, otherwise if y is to the right of x,
        !            38:           *  set adj2 := *y - *x.  Note that the adjustment values may
        !            39:           *  be negative.
        !            40:           */
        !            41:          if (bp1->tvsubs.sspos > bp2->tvsubs.sspos)
        !            42:             adj1 = bp1->tvsubs.sslen - bp2->tvsubs.sslen;
        !            43:          else if (bp2->tvsubs.sspos > bp1->tvsubs.sspos)
        !            44:             adj2 = bp2->tvsubs.sslen - bp1->tvsubs.sslen;
        !            45:             }
        !            46:       }
        !            47:    DeRef(arg1)
        !            48:    DeRef(arg2)
        !            49:    /*
        !            50:     * Do x := y
        !            51:     */
        !            52:    doasgn(&arg0, &arg2);
        !            53:    if (adj2 != 0)
        !            54:       /*
        !            55:        * y is to the right of x and the assignment x := y has shifted
        !            56:        *  the position of y.  Add adj2 to the position of y to account
        !            57:        *  for the replacement of x by y.
        !            58:        */
        !            59:       BLKLOC(arg2)->tvsubs.sspos += adj2;
        !            60:    doasgn(&arg2v, &arg1);
        !            61:    /*
        !            62:     * Do y := x
        !            63:     */
        !            64:    if (adj1 != 0)
        !            65:       /*
        !            66:        * x is to the right of y and the assignment y := x has shifted
        !            67:        *  the position of x.  Add adj2 to the position of x to account
        !            68:        *  for the replacement of y by x.
        !            69:        */
        !            70:       BLKLOC(arg1)->tvsubs.sspos += adj1;
        !            71:    /*
        !            72:     * Suspend x with the assignment in effect.
        !            73:     */
        !            74:    suspend();
        !            75:    /*
        !            76:     * If resumed, the assignments are undone.  Note that the string position
        !            77:     *  adjustments are identical to those done earlier.
        !            78:     */
        !            79:    doasgn(&arg0, &arg1);        /* restore x */
        !            80:    if (adj2 != 0)
        !            81:       BLKLOC(arg2)->tvsubs.sspos += adj2;
        !            82:    doasgn(&arg2v, &arg2);        /* restore y */
        !            83:    if (adj1 != 0)
        !            84:       BLKLOC(arg1)->tvsubs.sspos += adj1;
        !            85:    fail();
        !            86:    }
        !            87: 
        !            88: Opblockx(rswap,3,"<->",2)

unix.superglobalmegacorp.com

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