Annotation of src/usr.bin/window/wwwrite.c, Revision 1.1
1.1 ! deraadt 1: /* $NetBSD: wwwrite.c,v 1.3 1995/09/28 10:36:01 tls Exp $ */
! 2:
! 3: /*
! 4: * Copyright (c) 1983, 1993
! 5: * The Regents of the University of California. All rights reserved.
! 6: *
! 7: * This code is derived from software contributed to Berkeley by
! 8: * Edward Wang at The University of California, Berkeley.
! 9: *
! 10: * Redistribution and use in source and binary forms, with or without
! 11: * modification, are permitted provided that the following conditions
! 12: * are met:
! 13: * 1. Redistributions of source code must retain the above copyright
! 14: * notice, this list of conditions and the following disclaimer.
! 15: * 2. Redistributions in binary form must reproduce the above copyright
! 16: * notice, this list of conditions and the following disclaimer in the
! 17: * documentation and/or other materials provided with the distribution.
! 18: * 3. All advertising materials mentioning features or use of this software
! 19: * must display the following acknowledgement:
! 20: * This product includes software developed by the University of
! 21: * California, Berkeley and its contributors.
! 22: * 4. Neither the name of the University nor the names of its contributors
! 23: * may be used to endorse or promote products derived from this software
! 24: * without specific prior written permission.
! 25: *
! 26: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 27: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 28: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 29: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 30: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 31: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 32: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 33: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 34: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 35: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 36: * SUCH DAMAGE.
! 37: */
! 38:
! 39: #ifndef lint
! 40: #if 0
! 41: static char sccsid[] = "@(#)wwwrite.c 8.1 (Berkeley) 6/6/93";
! 42: #else
! 43: static char rcsid[] = "$NetBSD: wwwrite.c,v 1.3 1995/09/28 10:36:01 tls Exp $";
! 44: #endif
! 45: #endif /* not lint */
! 46:
! 47: #include "ww.h"
! 48: #include "tt.h"
! 49: #include "char.h"
! 50:
! 51: #define UPDATE() \
! 52: if (!w->ww_noupdate && w->ww_cur.r >= 0 && w->ww_cur.r < wwnrow && \
! 53: wwtouched[w->ww_cur.r]) \
! 54: wwupdate1(w->ww_cur.r, w->ww_cur.r + 1)
! 55:
! 56: /*
! 57: * To support control character expansion, we save the old
! 58: * p and q values in r and s, and point p at the beginning
! 59: * of the expanded string, and q at some safe place beyond it
! 60: * (p + 10). At strategic points in the loops, we check
! 61: * for (r && !*p) and restore the saved values back into
! 62: * p and q. Essentially, we implement a stack of depth 2,
! 63: * to avoid recursion, which might be a better idea.
! 64: */
! 65: wwwrite(w, p, n)
! 66: register struct ww *w;
! 67: register char *p;
! 68: int n;
! 69: {
! 70: char hascursor;
! 71: char *savep = p;
! 72: char *q = p + n;
! 73: char *r = 0;
! 74: char *s;
! 75:
! 76: #ifdef lint
! 77: s = 0; /* define it before possible use */
! 78: #endif
! 79: if (hascursor = w->ww_hascursor)
! 80: wwcursor(w, 0);
! 81: while (p < q && !w->ww_stopped && (!wwinterrupt() || w->ww_nointr)) {
! 82: if (r && !*p) {
! 83: p = r;
! 84: q = s;
! 85: r = 0;
! 86: continue;
! 87: }
! 88: if (w->ww_wstate == 0 &&
! 89: (isprt(*p) || w->ww_unctrl && isunctrl(*p))) {
! 90: register i;
! 91: register union ww_char *bp;
! 92: int col, col1;
! 93:
! 94: if (w->ww_insert) { /* this is very slow */
! 95: if (*p == '\t') {
! 96: p++;
! 97: w->ww_cur.c += 8 -
! 98: (w->ww_cur.c - w->ww_w.l & 7);
! 99: goto chklf;
! 100: }
! 101: if (!isprt(*p)) {
! 102: r = p + 1;
! 103: s = q;
! 104: p = unctrl(*p);
! 105: q = p + 10;
! 106: }
! 107: wwinschar(w, w->ww_cur.r, w->ww_cur.c,
! 108: *p++, w->ww_modes);
! 109: goto right;
! 110: }
! 111:
! 112: bp = &w->ww_buf[w->ww_cur.r][w->ww_cur.c];
! 113: i = w->ww_cur.c;
! 114: while (i < w->ww_w.r && p < q)
! 115: if (!*p && r) {
! 116: p = r;
! 117: q = s;
! 118: r = 0;
! 119: } else if (*p == '\t') {
! 120: register tmp = 8 - (i - w->ww_w.l & 7);
! 121: p++;
! 122: i += tmp;
! 123: bp += tmp;
! 124: } else if (isprt(*p)) {
! 125: bp++->c_w = *p++
! 126: | w->ww_modes << WWC_MSHIFT;
! 127: i++;
! 128: } else if (w->ww_unctrl && isunctrl(*p)) {
! 129: r = p + 1;
! 130: s = q;
! 131: p = unctrl(*p);
! 132: q = p + 10;
! 133: } else
! 134: break;
! 135: col = MAX(w->ww_cur.c, w->ww_i.l);
! 136: col1 = MIN(i, w->ww_i.r);
! 137: w->ww_cur.c = i;
! 138: if (w->ww_cur.r >= w->ww_i.t
! 139: && w->ww_cur.r < w->ww_i.b) {
! 140: register union ww_char *ns = wwns[w->ww_cur.r];
! 141: register char *smap = &wwsmap[w->ww_cur.r][col];
! 142: register char *win = w->ww_win[w->ww_cur.r];
! 143: int nchanged = 0;
! 144:
! 145: bp = w->ww_buf[w->ww_cur.r];
! 146: for (i = col; i < col1; i++)
! 147: if (*smap++ == w->ww_index) {
! 148: nchanged++;
! 149: ns[i].c_w = bp[i].c_w
! 150: ^ win[i] << WWC_MSHIFT;
! 151: }
! 152: if (nchanged > 0)
! 153: wwtouched[w->ww_cur.r] |= WWU_TOUCHED;
! 154: }
! 155: chklf:
! 156: if (w->ww_cur.c >= w->ww_w.r)
! 157: goto crlf;
! 158: } else switch (w->ww_wstate) {
! 159: case 0:
! 160: switch (*p++) {
! 161: case '\n':
! 162: if (w->ww_mapnl)
! 163: crlf:
! 164: w->ww_cur.c = w->ww_w.l;
! 165: lf:
! 166: UPDATE();
! 167: if (++w->ww_cur.r >= w->ww_w.b) {
! 168: w->ww_cur.r = w->ww_w.b - 1;
! 169: if (w->ww_w.b < w->ww_b.b) {
! 170: (void) wwscroll1(w, w->ww_i.t,
! 171: w->ww_i.b, 1, 0);
! 172: w->ww_buf++;
! 173: w->ww_b.t--;
! 174: w->ww_b.b--;
! 175: } else
! 176: wwdelline(w, w->ww_b.t);
! 177: }
! 178: break;
! 179: case '\b':
! 180: if (--w->ww_cur.c < w->ww_w.l) {
! 181: w->ww_cur.c = w->ww_w.r - 1;
! 182: goto up;
! 183: }
! 184: break;
! 185: case '\r':
! 186: w->ww_cur.c = w->ww_w.l;
! 187: break;
! 188: case ctrl('g'):
! 189: ttputc(ctrl('g'));
! 190: break;
! 191: case ctrl('['):
! 192: w->ww_wstate = 1;
! 193: break;
! 194: }
! 195: break;
! 196: case 1:
! 197: w->ww_wstate = 0;
! 198: switch (*p++) {
! 199: case '@':
! 200: w->ww_insert = 1;
! 201: break;
! 202: case 'A':
! 203: up:
! 204: UPDATE();
! 205: if (--w->ww_cur.r < w->ww_w.t) {
! 206: w->ww_cur.r = w->ww_w.t;
! 207: if (w->ww_w.t > w->ww_b.t) {
! 208: (void) wwscroll1(w, w->ww_i.t,
! 209: w->ww_i.b, -1, 0);
! 210: w->ww_buf--;
! 211: w->ww_b.t++;
! 212: w->ww_b.b++;
! 213: } else
! 214: wwinsline(w, w->ww_b.t);
! 215: }
! 216: break;
! 217: case 'B':
! 218: goto lf;
! 219: case 'C':
! 220: right:
! 221: w->ww_cur.c++;
! 222: goto chklf;
! 223: case 'E':
! 224: w->ww_buf -= w->ww_w.t - w->ww_b.t;
! 225: w->ww_b.t = w->ww_w.t;
! 226: w->ww_b.b = w->ww_b.t + w->ww_b.nr;
! 227: w->ww_cur.r = w->ww_w.t;
! 228: w->ww_cur.c = w->ww_w.l;
! 229: wwclreos(w, w->ww_w.t, w->ww_w.l);
! 230: break;
! 231: case 'H':
! 232: UPDATE();
! 233: w->ww_cur.r = w->ww_w.t;
! 234: w->ww_cur.c = w->ww_w.l;
! 235: break;
! 236: case 'J':
! 237: wwclreos(w, w->ww_cur.r, w->ww_cur.c);
! 238: break;
! 239: case 'K':
! 240: wwclreol(w, w->ww_cur.r, w->ww_cur.c);
! 241: break;
! 242: case 'L':
! 243: UPDATE();
! 244: wwinsline(w, w->ww_cur.r);
! 245: break;
! 246: case 'M':
! 247: wwdelline(w, w->ww_cur.r);
! 248: break;
! 249: case 'N':
! 250: wwdelchar(w, w->ww_cur.r, w->ww_cur.c);
! 251: break;
! 252: case 'O':
! 253: w->ww_insert = 0;
! 254: break;
! 255: case 'P':
! 256: wwinschar(w, w->ww_cur.r, w->ww_cur.c, ' ', 0);
! 257: break;
! 258: case 'X':
! 259: wwupdate();
! 260: break;
! 261: case 'Y':
! 262: UPDATE();
! 263: w->ww_wstate = 2;
! 264: break;
! 265: case 'Z':
! 266: wwupdate();
! 267: xxflush(0);
! 268: break;
! 269: case 's':
! 270: w->ww_wstate = 4;
! 271: break;
! 272: case 'r':
! 273: w->ww_wstate = 5;
! 274: break;
! 275: }
! 276: break;
! 277: case 2:
! 278: w->ww_cur.r = w->ww_w.t +
! 279: (unsigned)(*p++ - ' ') % w->ww_w.nr;
! 280: w->ww_wstate = 3;
! 281: break;
! 282: case 3:
! 283: w->ww_cur.c = w->ww_w.l +
! 284: (unsigned)(*p++ - ' ') % w->ww_w.nc;
! 285: w->ww_wstate = 0;
! 286: break;
! 287: case 4:
! 288: w->ww_modes |= *p++ & wwavailmodes;
! 289: w->ww_wstate = 0;
! 290: break;
! 291: case 5:
! 292: w->ww_modes &= ~*p++;
! 293: w->ww_wstate = 0;
! 294: break;
! 295: }
! 296: }
! 297: if (hascursor)
! 298: wwcursor(w, 1);
! 299: wwnwwr++;
! 300: wwnwwra += n;
! 301: n = p - savep;
! 302: wwnwwrc += n;
! 303: return n;
! 304: }