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