4.3BSD/usr/contrib/icon/operators/swap.c

Compare this file to the similar file:
Show the results in this format:

#include "../h/rt.h"

/*
 * x :=: y - swap values of x and y.
 */

swap(nargs, arg2v, arg2, arg1, arg0)
int nargs;
struct descrip arg2v, arg2, arg1, arg0;
   {
   register union block *bp1, *bp2;
   int adj1, adj2;

   SetBound;
   /*
    * x and y must be variables.
    */
   if (QUAL(arg1) || !VAR(arg1))
      runerr(111, &arg1);
   if (QUAL(arg2) || !VAR(arg2))
      runerr(111, &arg2);
   /*
    * Make copies of x and y as variables in arg0 and arg2v.
    */
   arg0 = arg1;
   arg2v = arg2;
   adj1 = adj2 = 0;
   if (arg1.type == D_TVSUBS && arg2.type == D_TVSUBS) {
      bp1 = BLKLOC(arg1);
      bp2 = BLKLOC(arg2);
      if (VARLOC(bp1->tvsubs.ssvar) == VARLOC(bp2->tvsubs.ssvar)) {
         /*
	  * x and y are both substrings of the same string, set
	  *  adj1 and adj2 for use in locating the substrings after
	  *  an assignment has been made.  If x is to the right of y,
	  *  set adj1 := *x - *y, otherwise if y is to the right of x,
	  *  set adj2 := *y - *x.  Note that the adjustment values may
	  *  be negative.
	  */
         if (bp1->tvsubs.sspos > bp2->tvsubs.sspos)
            adj1 = bp1->tvsubs.sslen - bp2->tvsubs.sslen;
         else if (bp2->tvsubs.sspos > bp1->tvsubs.sspos)
            adj2 = bp2->tvsubs.sslen - bp1->tvsubs.sslen;
   	 }
      }
   DeRef(arg1)
   DeRef(arg2)
   /*
    * Do x := y
    */
   doasgn(&arg0, &arg2);
   if (adj2 != 0)
      /*
       * y is to the right of x and the assignment x := y has shifted
       *  the position of y.  Add adj2 to the position of y to account
       *  for the replacement of x by y.
       */
      BLKLOC(arg2)->tvsubs.sspos += adj2;
   /*
    * Do y := x
    */
   doasgn(&arg2v, &arg1);
   if (adj1 != 0)
      /*
       * x is to the right of y and the assignment y := x has shifted
       *  the position of x.  Add adj2 to the position of x to account
       *  for the replacement of y by x.
       */
      BLKLOC(arg1)->tvsubs.sspos += adj1;
   ClearBound;
   }

Opblockx(swap,3,":=:",2)