1: #ifndef lint
   2: static char sccsid[] = "@(#)wwwrite.c	3.23 5/2/86";
   3: #endif
   4: 
   5: /*
   6:  * Copyright (c) 1983 Regents of the University of California,
   7:  * All rights reserved.  Redistribution permitted subject to
   8:  * the terms of the Berkeley Software License Agreement.
   9:  */
  10: 
  11: #include "ww.h"
  12: #include "tt.h"
  13: #include "char.h"
  14: 
  15: /*
  16:  * To support control character expansion, we save the old
  17:  * p and q values in r and s, and point p at the beginning
  18:  * of the expanded string, and q at some safe place beyond it
  19:  * (p + 10).  At strategic points in the loops, we check
  20:  * for (r && !*p) and restore the saved values back into
  21:  * p and q.  Essentially, we implement a stack of depth 2,
  22:  * to avoid recursion, which might be a better idea.
  23:  */
  24: wwwrite(w, p, n)
  25: register struct ww *w;
  26: register char *p;
  27: int n;
  28: {
  29:     char hascursor;
  30:     char *savep = p;
  31:     char *q = p + n;
  32:     char *r = 0;
  33:     char *s;
  34: 
  35: #ifdef lint
  36:     s = 0;          /* define it before possible use */
  37: #endif
  38:     if (hascursor = w->ww_hascursor)
  39:         wwcursor(w, 0);
  40:     while (p < q && !w->ww_stopped && (!wwinterrupt() || w->ww_nointr)) {
  41:         if (r && !*p) {
  42:             p = r;
  43:             q = s;
  44:             r = 0;
  45:             continue;
  46:         }
  47:         if (w->ww_wstate == 0 && (isprt(*p)
  48:             || w->ww_unctrl && isunctrl(*p))) {
  49:             register i;
  50:             register union ww_char *bp;
  51:             int col, col1;
  52: 
  53:             if (w->ww_insert) { /* this is very slow */
  54:                 if (*p == '\t') {
  55:                     p++;
  56:                     w->ww_cur.c += 8 -
  57:                         (w->ww_cur.c - w->ww_w.l & 7);
  58:                     goto chklf;
  59:                 }
  60:                 if (!isprt(*p)) {
  61:                     r = p + 1;
  62:                     s = q;
  63:                     p = unctrl(*p);
  64:                     q = p + 10;
  65:                 }
  66:                 wwinschar(w, w->ww_cur.r, w->ww_cur.c,
  67:                     *p++ | w->ww_modes << WWC_MSHIFT);
  68:                 goto right;
  69:             }
  70: 
  71:             bp = &w->ww_buf[w->ww_cur.r][w->ww_cur.c];
  72:             i = w->ww_cur.c;
  73:             while (i < w->ww_w.r && p < q)
  74:                 if (!*p && r) {
  75:                     p = r;
  76:                     q = s;
  77:                     r = 0;
  78:                 } else if (*p == '\t') {
  79:                     register tmp = 8 - (i - w->ww_w.l & 7);
  80:                     p++;
  81:                     i += tmp;
  82:                     bp += tmp;
  83:                 } else if (isprt(*p)) {
  84:                     bp++->c_w = *p++
  85:                         | w->ww_modes << WWC_MSHIFT;
  86:                     i++;
  87:                 } else if (w->ww_unctrl && isunctrl(*p)) {
  88:                     r = p + 1;
  89:                     s = q;
  90:                     p = unctrl(*p);
  91:                     q = p + 10;
  92:                 } else
  93:                     break;
  94:             col = MAX(w->ww_cur.c, w->ww_i.l);
  95:             col1 = MIN(i, w->ww_i.r);
  96:             w->ww_cur.c = i;
  97:             if (w->ww_cur.r >= w->ww_i.t
  98:                 && w->ww_cur.r < w->ww_i.b) {
  99:                 register union ww_char *ns = wwns[w->ww_cur.r];
 100:                 register char *smap = &wwsmap[w->ww_cur.r][col];
 101:                 register char *win = w->ww_win[w->ww_cur.r];
 102:                 int nchanged = 0;
 103: 
 104:                 bp = w->ww_buf[w->ww_cur.r];
 105:                 for (i = col; i < col1; i++)
 106:                     if (*smap++ == w->ww_index) {
 107:                         nchanged++;
 108:                         ns[i].c_w = bp[i].c_w
 109:                             ^ win[i] << WWC_MSHIFT;
 110:                     }
 111:                 if (nchanged > 0) {
 112:                     wwtouched[w->ww_cur.r] |= WWU_TOUCHED;
 113:                     if (!w->ww_noupdate)
 114:                         wwupdate1(w->ww_cur.r,
 115:                             w->ww_cur.r + 1);
 116:                 }
 117:             }
 118: 
 119:         chklf:
 120:             if (w->ww_cur.c >= w->ww_w.r)
 121:                 goto crlf;
 122:         } else switch (w->ww_wstate) {
 123:         case 0:
 124:             switch (*p++) {
 125:             case '\n':
 126:                 if (w->ww_mapnl)
 127:         crlf:
 128:                     w->ww_cur.c = w->ww_w.l;
 129:         lf:
 130:                 if (++w->ww_cur.r >= w->ww_w.b) {
 131:                     w->ww_cur.r = w->ww_w.b - 1;
 132:                     if (w->ww_w.b < w->ww_b.b) {
 133:                         (void) wwscroll1(w, w->ww_i.t,
 134:                             w->ww_i.b, 1, 0);
 135:                         w->ww_buf++;
 136:                         w->ww_b.t--;
 137:                         w->ww_b.b--;
 138:                     } else
 139:                         wwdelline(w, w->ww_b.t);
 140:                 }
 141:                 break;
 142:             case '\b':
 143:                 if (--w->ww_cur.c < w->ww_w.l) {
 144:                     w->ww_cur.c = w->ww_w.r - 1;
 145:                     goto up;
 146:                 }
 147:                 break;
 148:             case '\r':
 149:                 w->ww_cur.c = w->ww_w.l;
 150:                 break;
 151:             case ctrl(g):
 152:                 ttputc(ctrl(g));
 153:                 break;
 154:             case ctrl([):
 155:                 w->ww_wstate = 1;
 156:                 break;
 157:             }
 158:             break;
 159:         case 1:
 160:             w->ww_wstate = 0;
 161:             switch (*p++) {
 162:             case '@':
 163:                 w->ww_insert = 1;
 164:                 break;
 165:             case 'A':
 166:         up:
 167:                 if (--w->ww_cur.r < w->ww_w.t) {
 168:                     w->ww_cur.r = w->ww_w.t;
 169:                     if (w->ww_w.t > w->ww_b.t) {
 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:                         wwinsline(w, w->ww_b.t);
 177:                 }
 178:                 break;
 179:             case 'B':
 180:                 goto lf;
 181:             case 'C':
 182:         right:
 183:                 w->ww_cur.c++;
 184:                 goto chklf;
 185:             case 'E':
 186:                 w->ww_buf -= w->ww_w.t - w->ww_b.t;
 187:                 w->ww_b.t = w->ww_w.t;
 188:                 w->ww_b.b = w->ww_b.t + w->ww_b.nr;
 189:                 w->ww_cur.r = w->ww_w.t;
 190:                 w->ww_cur.c = w->ww_w.l;
 191:                 wwclreos(w, w->ww_w.t, w->ww_w.l);
 192:                 break;
 193:             case 'H':
 194:                 w->ww_cur.r = w->ww_w.t;
 195:                 w->ww_cur.c = w->ww_w.l;
 196:                 break;
 197:             case 'J':
 198:                 wwclreos(w, w->ww_cur.r, w->ww_cur.c);
 199:                 break;
 200:             case 'K':
 201:                 wwclreol(w, w->ww_cur.r, w->ww_cur.c);
 202:                 break;
 203:             case 'L':
 204:                 wwinsline(w, w->ww_cur.r);
 205:                 break;
 206:             case 'M':
 207:                 wwdelline(w, w->ww_cur.r);
 208:                 break;
 209:             case 'N':
 210:                 wwdelchar(w, w->ww_cur.r, w->ww_cur.c);
 211:                 break;
 212:             case 'O':
 213:                 w->ww_insert = 0;
 214:                 break;
 215:             case 'Y':
 216:                 w->ww_wstate = 2;
 217:                 break;
 218:             case 'p':
 219:                 w->ww_modes |= WWM_REV;
 220:                 break;
 221:             case 'q':
 222:                 w->ww_modes &= ~WWM_REV;
 223:                 break;
 224:             case 'r':
 225:                 w->ww_modes |= WWM_UL;
 226:                 break;
 227:             case 's':
 228:                 w->ww_modes &= ~WWM_UL;
 229:                 break;
 230:             case 'F':
 231:                 w->ww_modes |= WWM_GRP;
 232:                 break;
 233:             case 'G':
 234:                 w->ww_modes &= ~WWM_GRP;
 235:                 break;
 236:             case 'P':
 237:                 w->ww_modes |= WWM_USR;
 238:                 break;
 239:             case 'Q':
 240:                 w->ww_modes &= ~WWM_USR;
 241:                 break;
 242:             }
 243:             break;
 244:         case 2:
 245:             w->ww_cur.r = w->ww_w.t +
 246:                 (unsigned)(*p++ - ' ') % w->ww_w.nr;
 247:             w->ww_wstate = 3;
 248:             break;
 249:         case 3:
 250:             w->ww_cur.c = w->ww_w.l +
 251:                 (unsigned)(*p++ - ' ') % w->ww_w.nc;
 252:             w->ww_wstate = 0;
 253:             break;
 254:         }
 255:     }
 256:     if (hascursor)
 257:         wwcursor(w, 1);
 258:     wwnwwr++;
 259:     wwnwwra += n;
 260:     n = p - savep;
 261:     wwnwwrc += n;
 262:     return n;
 263: }

Defined functions

Defined variables

sccsid defined in line 2; never used
Last modified: 1986-05-02
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1316
Valid CSS Valid XHTML 1.0 Strict