Annotation of 43BSD/contrib/icon/operators/rswap.c, revision 1.1.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.