home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / window / wwwrite.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-18  |  7.3 KB  |  299 lines

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