|
|
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)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.