aboutsummaryrefslogtreecommitdiff
path: root/contrib/nvi/cl
diff options
context:
space:
mode:
authorPeter Wemm <peter@FreeBSD.org>2013-08-11 08:38:10 +0000
committerPeter Wemm <peter@FreeBSD.org>2013-08-11 08:38:10 +0000
commit84ed61ee234d2654ec965be5bfdda4269f9dc4fd (patch)
treefcfc8dee7b416cacdea763f18f34e0930234186a /contrib/nvi/cl
parent17c17f89c51e74499873b6115c9516b3302f2eb6 (diff)
Notes
Diffstat (limited to 'contrib/nvi/cl')
-rw-r--r--contrib/nvi/cl/README.signal174
-rw-r--r--contrib/nvi/cl/cl.h78
-rw-r--r--contrib/nvi/cl/cl_bsd.c346
-rw-r--r--contrib/nvi/cl/cl_funcs.c704
-rw-r--r--contrib/nvi/cl/cl_main.c471
-rw-r--r--contrib/nvi/cl/cl_read.c334
-rw-r--r--contrib/nvi/cl/cl_screen.c581
-rw-r--r--contrib/nvi/cl/cl_term.c460
8 files changed, 0 insertions, 3148 deletions
diff --git a/contrib/nvi/cl/README.signal b/contrib/nvi/cl/README.signal
deleted file mode 100644
index 7faa45673b75..000000000000
--- a/contrib/nvi/cl/README.signal
+++ /dev/null
@@ -1,174 +0,0 @@
-# @(#)README.signal 10.1 (Berkeley) 6/23/95
-
-There are six (normally) asynchronous actions about which vi cares:
-SIGHUP, SIGINT, SIGQUIT, SIGTERM, SIGTSTP and SIGWINCH.
-
-The assumptions:
- 1: The DB routines are not reentrant.
- 2: The curses routines may not be reentrant.
- 3: Neither DB nor curses will restart system calls.
-
-XXX
-Note, most C library functions don't restart system calls. So, we should
-*probably* start blocking around any imported function that we don't know
-doesn't make a system call. This is going to be a genuine annoyance...
-
-SIGHUP, SIGTERM
- Used for file recovery. The DB routines can't be reentered, nor
- can they handle interrupted system calls, so the vi routines that
- call DB block signals. This means that DB routines could be
- called at interrupt time, if necessary.
-
-SIGQUIT
- Disabled by the signal initialization routines. Historically, ^\
- switched vi into ex mode, and we continue that practice.
-
-SIGWINCH:
- The interrupt routine sets a global bit which is checked by the
- key-read routine, so there are no reentrancy issues. This means
- that the screen will not resize until vi runs out of keys, but
- that doesn't seem like a problem.
-
-SIGINT and SIGTSTP are a much more difficult issue to resolve. Vi has
-to permit the user to interrupt long-running operations. Generally, a
-search, substitution or read/write is done on a large file, or, the user
-creates a key mapping with an infinite loop. This problem will become
-worse as more complex semantics are added to vi, especially things like
-making it a pure text widget. There are four major solutions on the table,
-each of which have minor permutations.
-
-1: Run in raw mode.
-
- The up side is that there's no asynchronous behavior to worry about,
- and obviously no reentrancy problems. The down side is that it's easy
- to misinterpret characters (e.g. :w big_file^Mi^V^C is going to look
- like an interrupt) and it's easy to get into places where we won't see
- interrupt characters (e.g. ":map a ixx^[hxxaXXX" infinitely loops in
- historic implementations of vi). Periodically reading the terminal
- input buffer might solve the latter problem, but it's not going to be
- pretty.
-
- Also, we're going to be checking for ^C's and ^Z's both, all over
- the place -- I hate to litter the source code with that. For example,
- the historic version of vi didn't permit you to suspend the screen if
- you were on the colon command line. This isn't right. ^Z isn't a vi
- command, it's a terminal event. (Dammit.)
-
-2: Run in cbreak mode. There are two problems in this area. First, the
- current curses implementations (both System V and Berkeley) don't give
- you clean cbreak modes. For example, the IEXTEN bit is left on, turning
- on DISCARD and LNEXT. To clarify, what vi WANTS is 8-bit clean, with
- the exception that flow control and signals are turned on, and curses
- cbreak mode doesn't give you this.
-
- We can either set raw mode and twiddle the tty, or cbreak mode and
- twiddle the tty. I chose to use raw mode, on the grounds that raw
- mode is better defined and I'm less likely to be surprised by a curses
- implementation down the road. The twiddling consists of setting ISIG,
- IXON/IXOFF, and disabling some of the interrupt characters (see the
- comments in cl_init.c). This is all found in historic System V (SVID
- 3) and POSIX 1003.1-1992, so it should be fairly portable.
-
- The second problem is that vi permits you to enter literal signal
- characters, e.g. ^V^C. There are two possible solutions. First, you
- can turn off signals when you get a ^V, but that means that a network
- packet containing ^V and ^C will lose, since the ^C may take effect
- before vi reads the ^V. (This is particularly problematic if you're
- talking over a protocol that recognizes signals locally and sends OOB
- packets when it sees them.) Second, you can turn the ^C into a literal
- character in vi, but that means that there's a race between entering
- ^V<character>^C, i.e. the sequence may end up being ^V^C<character>.
- Also, the second solution doesn't work for flow control characters, as
- they aren't delivered to the program as signals.
-
- Generally, this is what historic vi did. (It didn't have the curses
- problems because it didn't use curses.) It entered signals following
- ^V characters into the input stream, (which is why there's no way to
- enter a literal flow control character).
-
-3: Run in mostly raw mode; turn signals on when doing an operation the
- user might want to interrupt, but leave them off most of the time.
-
- This works well for things like file reads and writes. This doesn't
- work well for trying to detect infinite maps. The problem is that
- you can write the code so that you don't have to turn on interrupts
- per keystroke, but the code isn't pretty and it's hard to make sure
- that an optimization doesn't cover up an infinite loop. This also
- requires interaction or state between the vi parser and the key
- reading routines, as an infinite loop may still be returning keys
- to the parser.
-
- Also, if the user inserts an interrupt into the tty queue while the
- interrupts are turned off, the key won't be treated as an interrupt,
- and requiring the user to pound the keyboard to catch an interrupt
- window is nasty.
-
-4: Run in mostly raw mode, leaving signals on all of the time. Done
- by setting raw mode, and twiddling the tty's termios ISIG bit.
-
- This works well for the interrupt cases, because the code only has
- to check to see if the interrupt flag has been set, and can otherwise
- ignore signals. It's also less likely that we'll miss a case, and we
- don't have to worry about synchronizing between the vi parser and the
- key read routines.
-
- The down side is that we have to turn signals off if the user wants
- to enter a literal character (e.g. ^V^C). If the user enters the
- combination fast enough, or as part of a single network packet,
- the text input routines will treat it as a signal instead of as a
- literal character. To some extent, we have this problem already,
- since we turn off flow control so that the user can enter literal
- XON/XOFF characters.
-
- This is probably the easiest to code, and provides the smoothest
- programming interface.
-
-There are a couple of other problems to consider.
-
-First, System V's curses doesn't handle SIGTSTP correctly. If you use the
-newterm() interface, the TSTP signal will leave you in raw mode, and the
-final endwin() will leave you in the correct shell mode. If you use the
-initscr() interface, the TSTP signal will return you to the correct shell
-mode, but the final endwin() will leave you in raw mode. There you have
-it: proof that drug testing is not making any significant headway in the
-computer industry. The 4BSD curses is deficient in that it does not have
-an interface to the terminal keypad. So, regardless, we have to do our
-own SIGTSTP handling.
-
-The problem with this is that if we do our own SIGTSTP handling, in either
-models #3 or #4, we're going to have to call curses routines at interrupt
-time, which means that we might be reentering curses, which is something we
-don't want to do.
-
-Second, SIGTSTP has its own little problems. It's broadcast to the entire
-process group, not sent to a single process. The scenario goes something
-like this: the shell execs the mail program, which execs vi. The user hits
-^Z, and all three programs get the signal, in some random order. The mail
-program goes to sleep immediately (since it probably didn't have a SIGTSTP
-handler in place). The shell gets a SIGCHLD, does a wait, and finds out
-that the only child in its foreground process group (of which it's aware)
-is asleep. It then optionally resets the terminal (because the modes aren't
-how it left them), and starts prompting the user for input. The problem is
-that somewhere in the middle of all of this, vi is resetting the terminal,
-and getting ready to send a SIGTSTP to the process group in order to put
-itself to sleep. There's a solution to all of this: when vi starts, it puts
-itself into its own process group, and then only it (and possible child
-processes) receive the SIGTSTP. This permits it to clean up the terminal
-and switch back to the original process group, where it sends that process
-group a SIGTSTP, putting everyone to sleep and waking the shell.
-
-Third, handing SIGTSTP asynchronously is further complicated by the child
-processes vi may fork off. If vi calls ex, ex resets the terminal and
-starts running some filter, and SIGTSTP stops them both, vi has to know
-when it restarts that it can't repaint the screen until ex's child has
-finished running. This is solveable, but it's annoying.
-
-Well, somebody had to make a decision, and this is the way it's going to be
-(unless I get talked out of it). SIGINT is handled asynchronously, so
-that we can pretty much guarantee that the user can interrupt any operation
-at any time. SIGTSTP is handled synchronously, so that we don't have to
-reenter curses and so that we don't have to play the process group games.
-^Z is recognized in the standard text input and command modes. (^Z should
-also be recognized during operations that may potentially take a long time.
-The simplest solution is probably to twiddle the tty, install a handler for
-SIGTSTP, and then restore normal tty modes when the operation is complete.)
diff --git a/contrib/nvi/cl/cl.h b/contrib/nvi/cl/cl.h
deleted file mode 100644
index 2ef2b8d1f81e..000000000000
--- a/contrib/nvi/cl/cl.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*-
- * Copyright (c) 1993, 1994
- * The Regents of the University of California. All rights reserved.
- * Copyright (c) 1993, 1994, 1995, 1996
- * Keith Bostic. All rights reserved.
- *
- * See the LICENSE file for redistribution information.
- *
- * @(#)cl.h 10.19 (Berkeley) 9/24/96
- */
-
-typedef struct _cl_private {
- CHAR_T ibuf[256]; /* Input keys. */
-
- int eof_count; /* EOF count. */
-
- struct termios orig; /* Original terminal values. */
- struct termios ex_enter;/* Terminal values to enter ex. */
- struct termios vi_enter;/* Terminal values to enter vi. */
-
- char *el; /* Clear to EOL terminal string. */
- char *cup; /* Cursor movement terminal string. */
- char *cuu1; /* Cursor up terminal string. */
- char *rmso, *smso; /* Inverse video terminal strings. */
- char *smcup, *rmcup; /* Terminal start/stop strings. */
-
- int killersig; /* Killer signal. */
-#define INDX_HUP 0
-#define INDX_INT 1
-#define INDX_TERM 2
-#define INDX_WINCH 3
-#define INDX_MAX 4 /* Original signal information. */
- struct sigaction oact[INDX_MAX];
-
- enum { /* Tty group write mode. */
- TGW_UNKNOWN=0, TGW_SET, TGW_UNSET } tgw;
-
- enum { /* Terminal initialization strings. */
- TE_SENT=0, TI_SENT } ti_te;
-
-#define CL_IN_EX 0x0001 /* Currently running ex. */
-#define CL_RENAME 0x0002 /* X11 xterm icon/window renamed. */
-#define CL_RENAME_OK 0x0004 /* User wants the windows renamed. */
-#define CL_SCR_EX_INIT 0x0008 /* Ex screen initialized. */
-#define CL_SCR_VI_INIT 0x0010 /* Vi screen initialized. */
-#define CL_SIGHUP 0x0020 /* SIGHUP arrived. */
-#define CL_SIGINT 0x0040 /* SIGINT arrived. */
-#define CL_SIGTERM 0x0080 /* SIGTERM arrived. */
-#define CL_SIGWINCH 0x0100 /* SIGWINCH arrived. */
-#define CL_STDIN_TTY 0x0200 /* Talking to a terminal. */
- u_int32_t flags;
-} CL_PRIVATE;
-
-#define CLP(sp) ((CL_PRIVATE *)((sp)->gp->cl_private))
-#define GCLP(gp) ((CL_PRIVATE *)gp->cl_private)
-
-/* Return possibilities from the keyboard read routine. */
-typedef enum { INP_OK=0, INP_EOF, INP_ERR, INP_INTR, INP_TIMEOUT } input_t;
-
-/* The screen line relative to a specific window. */
-#define RLNO(sp, lno) (sp)->woff + (lno)
-
-/* X11 xterm escape sequence to rename the icon/window. */
-#define XTERM_RENAME "\033]0;%s\007"
-
-/*
- * XXX
- * Some implementations of curses.h don't define these for us. Used for
- * compatibility only.
- */
-#ifndef TRUE
-#define TRUE 1
-#endif
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#include "cl_extern.h"
diff --git a/contrib/nvi/cl/cl_bsd.c b/contrib/nvi/cl/cl_bsd.c
deleted file mode 100644
index 22124e5780b2..000000000000
--- a/contrib/nvi/cl/cl_bsd.c
+++ /dev/null
@@ -1,346 +0,0 @@
-/*-
- * Copyright (c) 1995, 1996
- * Keith Bostic. All rights reserved.
- *
- * See the LICENSE file for redistribution information.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)cl_bsd.c 8.29 (Berkeley) 7/1/96";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <ctype.h>
-#include <curses.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "../common/common.h"
-#include "../vi/vi.h"
-#include "cl.h"
-
-static char *ke; /* Keypad on. */
-static char *ks; /* Keypad off. */
-static char *vb; /* Visible bell string. */
-
-/*
- * HP's support the entire System V curses package except for the tigetstr
- * and tigetnum functions. Ultrix supports the BSD curses package except
- * for the idlok function. Cthulu only knows why. Break things up into a
- * minimal set of functions.
- */
-
-#ifndef HAVE_CURSES_ADDNSTR
-/*
- * addnstr --
- *
- * PUBLIC: #ifndef HAVE_CURSES_ADDNSTR
- * PUBLIC: int addnstr __P((char *, int));
- * PUBLIC: #endif
- */
-int
-addnstr(s, n)
- char *s;
- int n;
-{
- int ch;
-
- while (n-- && (ch = *s++))
- addch(ch);
- return (OK);
-}
-#endif
-
-#ifndef HAVE_CURSES_BEEP
-/*
- * beep --
- *
- * PUBLIC: #ifndef HAVE_CURSES_BEEP
- * PUBLIC: void beep __P((void));
- * PUBLIC: #endif
- */
-void
-beep()
-{
- (void)write(1, "\007", 1); /* '\a' */
-}
-#endif /* !HAVE_CURSES_BEEP */
-
-#ifndef HAVE_CURSES_FLASH
-/*
- * flash --
- * Flash the screen.
- *
- * PUBLIC: #ifndef HAVE_CURSES_FLASH
- * PUBLIC: void flash __P((void));
- * PUBLIC: #endif
- */
-void
-flash()
-{
- if (vb != NULL) {
- (void)tputs(vb, 1, cl_putchar);
- (void)fflush(stdout);
- } else
- beep();
-}
-#endif /* !HAVE_CURSES_FLASH */
-
-#ifndef HAVE_CURSES_IDLOK
-/*
- * idlok --
- * Turn on/off hardware line insert/delete.
- *
- * PUBLIC: #ifndef HAVE_CURSES_IDLOK
- * PUBLIC: void idlok __P((WINDOW *, int));
- * PUBLIC: #endif
- */
-void
-idlok(win, bf)
- WINDOW *win;
- int bf;
-{
- return;
-}
-#endif /* !HAVE_CURSES_IDLOK */
-
-#ifndef HAVE_CURSES_KEYPAD
-/*
- * keypad --
- * Put the keypad/cursor arrows into or out of application mode.
- *
- * PUBLIC: #ifndef HAVE_CURSES_KEYPAD
- * PUBLIC: int keypad __P((void *, int));
- * PUBLIC: #endif
- */
-int
-keypad(a, on)
- void *a;
- int on;
-{
- char *p;
-
- if ((p = tigetstr(on ? "smkx" : "rmkx")) != (char *)-1) {
- (void)tputs(p, 0, cl_putchar);
- (void)fflush(stdout);
- }
- return (0);
-}
-#endif /* !HAVE_CURSES_KEYPAD */
-
-#ifndef HAVE_CURSES_NEWTERM
-/*
- * newterm --
- * Create a new curses screen.
- *
- * PUBLIC: #ifndef HAVE_CURSES_NEWTERM
- * PUBLIC: void *newterm __P((const char *, FILE *, FILE *));
- * PUBLIC: #endif
- */
-void *
-newterm(a, b, c)
- const char *a;
- FILE *b, *c;
-{
- return (initscr());
-}
-#endif /* !HAVE_CURSES_NEWTERM */
-
-#ifndef HAVE_CURSES_SETUPTERM
-/*
- * setupterm --
- * Set up terminal.
- *
- * PUBLIC: #ifndef HAVE_CURSES_SETUPTERM
- * PUBLIC: void setupterm __P((char *, int, int *));
- * PUBLIC: #endif
- */
-void
-setupterm(ttype, fno, errp)
- char *ttype;
- int fno, *errp;
-{
- static char buf[2048];
- char *p;
-
- if ((*errp = tgetent(buf, ttype)) > 0) {
- if (ke != NULL)
- free(ke);
- ke = ((p = tigetstr("rmkx")) == (char *)-1) ?
- NULL : strdup(p);
- if (ks != NULL)
- free(ks);
- ks = ((p = tigetstr("smkx")) == (char *)-1) ?
- NULL : strdup(p);
- if (vb != NULL)
- free(vb);
- vb = ((p = tigetstr("flash")) == (char *)-1) ?
- NULL : strdup(p);
- }
-}
-#endif /* !HAVE_CURSES_SETUPTERM */
-
-#ifndef HAVE_CURSES_TIGETSTR
-/* Terminfo-to-termcap translation table. */
-typedef struct _tl {
- char *terminfo; /* Terminfo name. */
- char *termcap; /* Termcap name. */
-} TL;
-static const TL list[] = {
- "cols", "co", /* Terminal columns. */
- "cup", "cm", /* Cursor up. */
- "cuu1", "up", /* Cursor up. */
- "el", "ce", /* Clear to end-of-line. */
- "flash", "vb", /* Visible bell. */
- "kcub1", "kl", /* Cursor left. */
- "kcud1", "kd", /* Cursor down. */
- "kcuf1", "kr", /* Cursor right. */
- "kcuu1", "ku", /* Cursor up. */
- "kdch1", "kD", /* Delete character. */
- "kdl1", "kL", /* Delete line. */
- "ked", "kS", /* Delete to end of screen. */
- "kel", "kE", /* Delete to eol. */
- "kend", "@7", /* Go to eol. */
- "khome", "kh", /* Go to sol. */
- "kich1", "kI", /* Insert at cursor. */
- "kil1", "kA", /* Insert line. */
- "kind", "kF", /* Scroll down. */
- "kll", "kH", /* Go to eol. */
- "knp", "kN", /* Page down. */
- "kpp", "kP", /* Page up. */
- "kri", "kR", /* Scroll up. */
- "lines", "li", /* Terminal lines. */
- "rmcup", "te", /* Terminal end string. */
- "rmkx", "ke", /* Exit "keypad-transmit" mode. */
- "rmso", "se", /* Standout end. */
- "smcup", "ti", /* Terminal initialization string. */
- "smkx", "ks", /* Enter "keypad-transmit" mode. */
- "smso", "so", /* Standout begin. */
-};
-
-#ifdef _AIX
-/*
- * AIX's implementation for function keys greater than 10 is different and
- * only goes as far as 36.
- */
-static const char codes[] = {
-/* 0-10 */ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ';',
-/* 11-20 */ '<', '>', '!', '@', '#', '$', '%', '^', '&', '*',
-/* 21-30 */ '(', ')', '-', '_', '+', ',', ':', '?', '[', ']',
-/* 31-36 */ '{', '}', '|', '~', '/', '='
-};
-
-#else
-
-/*
- * !!!
- * Historically, the 4BSD termcap code didn't support functions keys greater
- * than 9. This was silently enforced -- asking for key k12 would return the
- * value for k1. We try and get around this by using the tables specified in
- * the terminfo(TI_ENV) man page from the 3rd Edition SVID. This assumes the
- * implementors of any System V compatibility code or an extended termcap used
- * those codes.
- */
-static const char codes[] = {
-/* 0-10 */ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ';',
-/* 11-19 */ '1', '2', '3', '4', '5', '6', '7', '8', '9',
-/* 20-63 */ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
- 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
- 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-};
-#endif /* _AIX */
-
-/*
- * lcmp --
- * list comparison routine for bsearch.
- */
-static int
-lcmp(a, b)
- const void *a, *b;
-{
- return (strcmp(a, ((TL *)b)->terminfo));
-}
-
-/*
- * tigetstr --
- *
- * Vendors put the prototype for tigetstr into random include files, including
- * <term.h>, which we can't include because it makes other systems unhappy.
- * Try and work around the problem, since we only care about the return value.
- *
- * PUBLIC: #ifdef HAVE_CURSES_TIGETSTR
- * PUBLIC: char *tigetstr();
- * PUBLIC: #else
- * PUBLIC: char *tigetstr __P((char *));
- * PUBLIC: #endif
- */
-char *
-tigetstr(name)
- char *name;
-{
- static char sbuf[256];
- TL *tlp;
- int n;
- char *p, keyname[3];
-
- if ((tlp = bsearch(name,
- list, sizeof(list) / sizeof(TL), sizeof(TL), lcmp)) == NULL) {
-#ifdef _AIX
- if (name[0] == 'k' &&
- name[1] == 'f' && (n = atoi(name + 2)) <= 36) {
- keyname[0] = 'k';
- keyname[1] = codes[n];
- keyname[2] = '\0';
-#else
- if (name[0] == 'k' &&
- name[1] == 'f' && (n = atoi(name + 2)) <= 63) {
- keyname[0] = n <= 10 ? 'k' : 'F';
- keyname[1] = codes[n];
- keyname[2] = '\0';
-#endif
- name = keyname;
- }
- } else
- name = tlp->termcap;
-
- p = sbuf;
-#ifdef _AIX
- return ((p = tgetstr(name, &p)) == NULL ? (char *)-1 : strcpy(sbuf, p));
-#else
- return (tgetstr(name, &p) == NULL ? (char *)-1 : sbuf);
-#endif
-}
-
-/*
- * tigetnum --
- *
- * PUBLIC: #ifndef HAVE_CURSES_TIGETSTR
- * PUBLIC: int tigetnum __P((char *));
- * PUBLIC: #endif
- */
-int
-tigetnum(name)
- char *name;
-{
- TL *tlp;
- int val;
-
- if ((tlp = bsearch(name,
- list, sizeof(list) / sizeof(TL), sizeof(TL), lcmp)) != NULL) {
- name = tlp->termcap;
- }
-
- return ((val = tgetnum(name)) == -1 ? -2 : val);
-}
-#endif /* !HAVE_CURSES_TIGETSTR */
diff --git a/contrib/nvi/cl/cl_funcs.c b/contrib/nvi/cl/cl_funcs.c
deleted file mode 100644
index 40315ee85e89..000000000000
--- a/contrib/nvi/cl/cl_funcs.c
+++ /dev/null
@@ -1,704 +0,0 @@
-/*-
- * Copyright (c) 1993, 1994
- * The Regents of the University of California. All rights reserved.
- * Copyright (c) 1993, 1994, 1995, 1996
- * Keith Bostic. All rights reserved.
- *
- * See the LICENSE file for redistribution information.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)cl_funcs.c 10.50 (Berkeley) 9/24/96";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <ctype.h>
-#include <curses.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "../common/common.h"
-#include "../vi/vi.h"
-#include "cl.h"
-
-/*
- * cl_addstr --
- * Add len bytes from the string at the cursor, advancing the cursor.
- *
- * PUBLIC: int cl_addstr __P((SCR *, const char *, size_t));
- */
-int
-cl_addstr(sp, str, len)
- SCR *sp;
- const char *str;
- size_t len;
-{
- CL_PRIVATE *clp;
- size_t oldy, oldx;
- int iv;
-
- clp = CLP(sp);
-
- /*
- * If ex isn't in control, it's the last line of the screen and
- * it's a split screen, use inverse video.
- */
- iv = 0;
- getyx(stdscr, oldy, oldx);
- if (!F_ISSET(sp, SC_SCR_EXWROTE) &&
- oldy == RLNO(sp, LASTLINE(sp)) && IS_SPLIT(sp)) {
- iv = 1;
- (void)standout();
- }
-
- if (addnstr(str, len) == ERR)
- return (1);
-
- if (iv)
- (void)standend();
- return (0);
-}
-
-/*
- * cl_attr --
- * Toggle a screen attribute on/off.
- *
- * PUBLIC: int cl_attr __P((SCR *, scr_attr_t, int));
- */
-int
-cl_attr(sp, attribute, on)
- SCR *sp;
- scr_attr_t attribute;
- int on;
-{
- CL_PRIVATE *clp;
-
- clp = CLP(sp);
-
- switch (attribute) {
- case SA_ALTERNATE:
- /*
- * !!!
- * There's a major layering violation here. The problem is that the
- * X11 xterm screen has what's known as an "alternate" screen. Some
- * xterm termcap/terminfo entries include sequences to switch to/from
- * that alternate screen as part of the ti/te (smcup/rmcup) strings.
- * Vi runs in the alternate screen, so that you are returned to the
- * same screen contents on exit from vi that you had when you entered
- * vi. Further, when you run :shell, or :!date or similar ex commands,
- * you also see the original screen contents. This wasn't deliberate
- * on vi's part, it's just that it historically sent terminal init/end
- * sequences at those times, and the addition of the alternate screen
- * sequences to the strings changed the behavior of vi. The problem
- * caused by this is that we don't want to switch back to the alternate
- * screen while getting a new command from the user, when the user is
- * continuing to enter ex commands, e.g.:
- *
- * :!date <<< switch to original screen
- * [Hit return to continue] <<< prompt user to continue
- * :command <<< get command from user
- *
- * Note that the :command input is a true vi input mode, e.g., input
- * maps and abbreviations are being done. So, we need to be able to
- * switch back into the vi screen mode, without flashing the screen.
- *
- * To make matters worse, the curses initscr() and endwin() calls will
- * do this automatically -- so, this attribute isn't as controlled by
- * the higher level screen as closely as one might like.
- */
- if (on) {
- if (clp->ti_te != TI_SENT) {
- clp->ti_te = TI_SENT;
- if (clp->smcup == NULL)
- (void)cl_getcap(sp, "smcup", &clp->smcup);
- if (clp->smcup != NULL)
- (void)tputs(clp->smcup, 1, cl_putchar);
- }
- } else
- if (clp->ti_te != TE_SENT) {
- clp->ti_te = TE_SENT;
- if (clp->rmcup == NULL)
- (void)cl_getcap(sp, "rmcup", &clp->rmcup);
- if (clp->rmcup != NULL)
- (void)tputs(clp->rmcup, 1, cl_putchar);
- (void)fflush(stdout);
- }
- (void)fflush(stdout);
- break;
- case SA_INVERSE:
- if (F_ISSET(sp, SC_EX | SC_SCR_EXWROTE)) {
- if (clp->smso == NULL)
- return (1);
- if (on)
- (void)tputs(clp->smso, 1, cl_putchar);
- else
- (void)tputs(clp->rmso, 1, cl_putchar);
- (void)fflush(stdout);
- } else {
- if (on)
- (void)standout();
- else
- (void)standend();
- }
- break;
- default:
- abort();
- }
- return (0);
-}
-
-/*
- * cl_baud --
- * Return the baud rate.
- *
- * PUBLIC: int cl_baud __P((SCR *, u_long *));
- */
-int
-cl_baud(sp, ratep)
- SCR *sp;
- u_long *ratep;
-{
- CL_PRIVATE *clp;
-
- /*
- * XXX
- * There's no portable way to get a "baud rate" -- cfgetospeed(3)
- * returns the value associated with some #define, which we may
- * never have heard of, or which may be a purely local speed. Vi
- * only cares if it's SLOW (w300), slow (w1200) or fast (w9600).
- * Try and detect the slow ones, and default to fast.
- */
- clp = CLP(sp);
- switch (cfgetospeed(&clp->orig)) {
- case B50:
- case B75:
- case B110:
- case B134:
- case B150:
- case B200:
- case B300:
- case B600:
- *ratep = 600;
- break;
- case B1200:
- *ratep = 1200;
- break;
- default:
- *ratep = 9600;
- break;
- }
- return (0);
-}
-
-/*
- * cl_bell --
- * Ring the bell/flash the screen.
- *
- * PUBLIC: int cl_bell __P((SCR *));
- */
-int
-cl_bell(sp)
- SCR *sp;
-{
- if (F_ISSET(sp, SC_EX | SC_SCR_EXWROTE))
- (void)write(STDOUT_FILENO, "\07", 1); /* \a */
- else {
- /*
- * Vi has an edit option which determines if the terminal
- * should be beeped or the screen flashed.
- */
- if (O_ISSET(sp, O_FLASH))
- (void)flash();
- else
- (void)beep();
- }
- return (0);
-}
-
-/*
- * cl_clrtoeol --
- * Clear from the current cursor to the end of the line.
- *
- * PUBLIC: int cl_clrtoeol __P((SCR *));
- */
-int
-cl_clrtoeol(sp)
- SCR *sp;
-{
- return (clrtoeol() == ERR);
-}
-
-/*
- * cl_cursor --
- * Return the current cursor position.
- *
- * PUBLIC: int cl_cursor __P((SCR *, size_t *, size_t *));
- */
-int
-cl_cursor(sp, yp, xp)
- SCR *sp;
- size_t *yp, *xp;
-{
- /*
- * The curses screen support splits a single underlying curses screen
- * into multiple screens to support split screen semantics. For this
- * reason the returned value must be adjusted to be relative to the
- * current screen, and not absolute. Screens that implement the split
- * using physically distinct screens won't need this hack.
- */
- getyx(stdscr, *yp, *xp);
- *yp -= sp->woff;
- return (0);
-}
-
-/*
- * cl_deleteln --
- * Delete the current line, scrolling all lines below it.
- *
- * PUBLIC: int cl_deleteln __P((SCR *));
- */
-int
-cl_deleteln(sp)
- SCR *sp;
-{
- CHAR_T ch;
- CL_PRIVATE *clp;
- size_t col, lno, spcnt, oldy, oldx;
-
- clp = CLP(sp);
-
- /*
- * This clause is required because the curses screen uses reverse
- * video to delimit split screens. If the screen does not do this,
- * this code won't be necessary.
- *
- * If the bottom line was in reverse video, rewrite it in normal
- * video before it's scrolled.
- *
- * Check for the existence of a chgat function; XSI requires it, but
- * historic implementations of System V curses don't. If it's not
- * a #define, we'll fall back to doing it by hand, which is slow but
- * acceptable.
- *
- * By hand means walking through the line, retrieving and rewriting
- * each character. Curses has no EOL marker, so track strings of
- * spaces, and copy the trailing spaces only if there's a non-space
- * character following.
- */
- if (!F_ISSET(sp, SC_SCR_EXWROTE) && IS_SPLIT(sp)) {
- getyx(stdscr, oldy, oldx);
-#ifdef mvchgat
- mvchgat(RLNO(sp, LASTLINE(sp)), 0, -1, A_NORMAL, 0, NULL);
-#else
- for (lno = RLNO(sp, LASTLINE(sp)), col = spcnt = 0;;) {
- (void)move(lno, col);
- ch = winch(stdscr);
- if (isblank(ch))
- ++spcnt;
- else {
- (void)move(lno, col - spcnt);
- for (; spcnt > 0; --spcnt)
- (void)addch(' ');
- (void)addch(ch);
- }
- if (++col >= sp->cols)
- break;
- }
-#endif
- (void)move(oldy, oldx);
- }
-
- /*
- * The bottom line is expected to be blank after this operation,
- * and other screens must support that semantic.
- */
- return (deleteln() == ERR);
-}
-
-/*
- * cl_ex_adjust --
- * Adjust the screen for ex. This routine is purely for standalone
- * ex programs. All special purpose, all special case.
- *
- * PUBLIC: int cl_ex_adjust __P((SCR *, exadj_t));
- */
-int
-cl_ex_adjust(sp, action)
- SCR *sp;
- exadj_t action;
-{
- CL_PRIVATE *clp;
- int cnt;
-
- clp = CLP(sp);
- switch (action) {
- case EX_TERM_SCROLL:
- /* Move the cursor up one line if that's possible. */
- if (clp->cuu1 != NULL)
- (void)tputs(clp->cuu1, 1, cl_putchar);
- else if (clp->cup != NULL)
- (void)tputs(tgoto(clp->cup,
- 0, LINES - 2), 1, cl_putchar);
- else
- return (0);
- /* FALLTHROUGH */
- case EX_TERM_CE:
- /* Clear the line. */
- if (clp->el != NULL) {
- (void)putchar('\r');
- (void)tputs(clp->el, 1, cl_putchar);
- } else {
- /*
- * Historically, ex didn't erase the line, so, if the
- * displayed line was only a single glyph, and <eof>
- * was more than one glyph, the output would not fully
- * overwrite the user's input. To fix this, output
- * the maxiumum character number of spaces. Note,
- * this won't help if the user entered extra prompt
- * or <blank> characters before the command character.
- * We'd have to do a lot of work to make that work, and
- * it's almost certainly not worth the effort.
- */
- for (cnt = 0; cnt < MAX_CHARACTER_COLUMNS; ++cnt)
- (void)putchar('\b');
- for (cnt = 0; cnt < MAX_CHARACTER_COLUMNS; ++cnt)
- (void)putchar(' ');
- (void)putchar('\r');
- (void)fflush(stdout);
- }
- break;
- default:
- abort();
- }
- return (0);
-}
-
-/*
- * cl_insertln --
- * Push down the current line, discarding the bottom line.
- *
- * PUBLIC: int cl_insertln __P((SCR *));
- */
-int
-cl_insertln(sp)
- SCR *sp;
-{
- /*
- * The current line is expected to be blank after this operation,
- * and the screen must support that semantic.
- */
- return (insertln() == ERR);
-}
-
-/*
- * cl_keyval --
- * Return the value for a special key.
- *
- * PUBLIC: int cl_keyval __P((SCR *, scr_keyval_t, CHAR_T *, int *));
- */
-int
-cl_keyval(sp, val, chp, dnep)
- SCR *sp;
- scr_keyval_t val;
- CHAR_T *chp;
- int *dnep;
-{
- CL_PRIVATE *clp;
-
- /*
- * VEOF, VERASE and VKILL are required by POSIX 1003.1-1990,
- * VWERASE is a 4BSD extension.
- */
- clp = CLP(sp);
- switch (val) {
- case KEY_VEOF:
- *dnep = (*chp = clp->orig.c_cc[VEOF]) == _POSIX_VDISABLE;
- break;
- case KEY_VERASE:
- *dnep = (*chp = clp->orig.c_cc[VERASE]) == _POSIX_VDISABLE;
- break;
- case KEY_VKILL:
- *dnep = (*chp = clp->orig.c_cc[VKILL]) == _POSIX_VDISABLE;
- break;
-#ifdef VWERASE
- case KEY_VWERASE:
- *dnep = (*chp = clp->orig.c_cc[VWERASE]) == _POSIX_VDISABLE;
- break;
-#endif
- default:
- *dnep = 1;
- break;
- }
- return (0);
-}
-
-/*
- * cl_move --
- * Move the cursor.
- *
- * PUBLIC: int cl_move __P((SCR *, size_t, size_t));
- */
-int
-cl_move(sp, lno, cno)
- SCR *sp;
- size_t lno, cno;
-{
- /* See the comment in cl_cursor. */
- if (move(RLNO(sp, lno), cno) == ERR) {
- msgq(sp, M_ERR,
- "Error: move: l(%u) c(%u) o(%u)", lno, cno, sp->woff);
- return (1);
- }
- return (0);
-}
-
-/*
- * cl_refresh --
- * Refresh the screen.
- *
- * PUBLIC: int cl_refresh __P((SCR *, int));
- */
-int
-cl_refresh(sp, repaint)
- SCR *sp;
- int repaint;
-{
- CL_PRIVATE *clp;
-
- clp = CLP(sp);
-
- /*
- * If we received a killer signal, we're done, there's no point
- * in refreshing the screen.
- */
- if (clp->killersig)
- return (0);
-
- /*
- * If repaint is set, the editor is telling us that we don't know
- * what's on the screen, so we have to repaint from scratch.
- *
- * In the curses library, doing wrefresh(curscr) is okay, but the
- * screen flashes when we then apply the refresh() to bring it up
- * to date. So, use clearok().
- */
- if (repaint)
- clearok(curscr, 1);
- return (refresh() == ERR);
-}
-
-/*
- * cl_rename --
- * Rename the file.
- *
- * PUBLIC: int cl_rename __P((SCR *, char *, int));
- */
-int
-cl_rename(sp, name, on)
- SCR *sp;
- char *name;
- int on;
-{
- GS *gp;
- CL_PRIVATE *clp;
- char *ttype;
-
- gp = sp->gp;
- clp = CLP(sp);
-
- ttype = OG_STR(gp, GO_TERM);
-
- /*
- * XXX
- * We can only rename windows for xterm.
- */
- if (on) {
- if (F_ISSET(clp, CL_RENAME_OK) &&
- !strncmp(ttype, "xterm", sizeof("xterm") - 1)) {
- F_SET(clp, CL_RENAME);
- (void)printf(XTERM_RENAME, name);
- (void)fflush(stdout);
- }
- } else
- if (F_ISSET(clp, CL_RENAME)) {
- F_CLR(clp, CL_RENAME);
- (void)printf(XTERM_RENAME, ttype);
- (void)fflush(stdout);
- }
- return (0);
-}
-
-/*
- * cl_suspend --
- * Suspend a screen.
- *
- * PUBLIC: int cl_suspend __P((SCR *, int *));
- */
-int
-cl_suspend(sp, allowedp)
- SCR *sp;
- int *allowedp;
-{
- struct termios t;
- CL_PRIVATE *clp;
- GS *gp;
- size_t oldy, oldx;
- int changed;
-
- gp = sp->gp;
- clp = CLP(sp);
- *allowedp = 1;
-
- /*
- * The ex implementation of this function isn't needed by screens not
- * supporting ex commands that require full terminal canonical mode
- * (e.g. :suspend).
- *
- * The vi implementation of this function isn't needed by screens not
- * supporting vi process suspension, i.e. any screen that isn't backed
- * by a UNIX shell.
- *
- * Setting allowedp to 0 will cause the editor to reject the command.
- */
- if (F_ISSET(sp, SC_EX)) {
- /* Save the terminal settings, and restore the original ones. */
- if (F_ISSET(clp, CL_STDIN_TTY)) {
- (void)tcgetattr(STDIN_FILENO, &t);
- (void)tcsetattr(STDIN_FILENO,
- TCSASOFT | TCSADRAIN, &clp->orig);
- }
-
- /* Stop the process group. */
- (void)kill(0, SIGTSTP);
-
- /* Time passes ... */
-
- /* Restore terminal settings. */
- if (F_ISSET(clp, CL_STDIN_TTY))
- (void)tcsetattr(STDIN_FILENO, TCSASOFT | TCSADRAIN, &t);
- return (0);
- }
-
- /*
- * Move to the lower left-hand corner of the screen.
- *
- * XXX
- * Not sure this is necessary in System V implementations, but it
- * shouldn't hurt.
- */
- getyx(stdscr, oldy, oldx);
- (void)move(LINES - 1, 0);
- (void)refresh();
-
- /*
- * Temporarily end the screen. System V introduced a semantic where
- * endwin() could be restarted. We use it because restarting curses
- * from scratch often fails in System V. 4BSD curses didn't support
- * restarting after endwin(), so we have to do what clean up we can
- * without calling it.
- */
-#ifdef HAVE_BSD_CURSES
- /* Save the terminal settings. */
- (void)tcgetattr(STDIN_FILENO, &t);
-#endif
-
- /* Restore the cursor keys to normal mode. */
- (void)keypad(stdscr, FALSE);
-
- /* Restore the window name. */
- (void)cl_rename(sp, NULL, 0);
-
-#ifdef HAVE_BSD_CURSES
- (void)cl_attr(sp, SA_ALTERNATE, 0);
-#else
- (void)endwin();
-#endif
- /*
- * XXX
- * Restore the original terminal settings. This is bad -- the
- * reset can cause character loss from the tty queue. However,
- * we can't call endwin() in BSD curses implementations, and too
- * many System V curses implementations don't get it right.
- */
- (void)tcsetattr(STDIN_FILENO, TCSADRAIN | TCSASOFT, &clp->orig);
-
- /* Stop the process group. */
- (void)kill(0, SIGTSTP);
-
- /* Time passes ... */
-
- /*
- * If we received a killer signal, we're done. Leave everything
- * unchanged. In addition, the terminal has already been reset
- * correctly, so leave it alone.
- */
- if (clp->killersig) {
- F_CLR(clp, CL_SCR_EX_INIT | CL_SCR_VI_INIT);
- return (0);
- }
-
-#ifdef HAVE_BSD_CURSES
- /* Restore terminal settings. */
- if (F_ISSET(clp, CL_STDIN_TTY))
- (void)tcsetattr(STDIN_FILENO, TCSASOFT | TCSADRAIN, &t);
-
- (void)cl_attr(sp, SA_ALTERNATE, 1);
-#endif
-
- /* Set the window name. */
- (void)cl_rename(sp, sp->frp->name, 1);
-
- /* Put the cursor keys into application mode. */
- (void)keypad(stdscr, TRUE);
-
- /* Refresh and repaint the screen. */
- (void)move(oldy, oldx);
- (void)cl_refresh(sp, 1);
-
- /* If the screen changed size, set the SIGWINCH bit. */
- if (cl_ssize(sp, 1, NULL, NULL, &changed))
- return (1);
- if (changed)
- F_SET(CLP(sp), CL_SIGWINCH);
-
- return (0);
-}
-
-/*
- * cl_usage --
- * Print out the curses usage messages.
- *
- * PUBLIC: void cl_usage __P((void));
- */
-void
-cl_usage()
-{
-#define USAGE "\
-usage: ex [-eFRrSsv] [-c command] [-t tag] [-w size] [file ...]\n\
-usage: vi [-eFlRrSv] [-c command] [-t tag] [-w size] [file ...]\n"
- (void)fprintf(stderr, "%s", USAGE);
-#undef USAGE
-}
-
-#ifdef DEBUG
-/*
- * gdbrefresh --
- * Stub routine so can flush out curses screen changes using gdb.
- */
-int
-gdbrefresh()
-{
- refresh();
- return (0); /* XXX Convince gdb to run it. */
-}
-#endif
diff --git a/contrib/nvi/cl/cl_main.c b/contrib/nvi/cl/cl_main.c
deleted file mode 100644
index 2889f709cbb2..000000000000
--- a/contrib/nvi/cl/cl_main.c
+++ /dev/null
@@ -1,471 +0,0 @@
-/*-
- * Copyright (c) 1993, 1994
- * The Regents of the University of California. All rights reserved.
- * Copyright (c) 1993, 1994, 1995, 1996
- * Keith Bostic. All rights reserved.
- *
- * See the LICENSE file for redistribution information.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)cl_main.c 10.36 (Berkeley) 10/14/96";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-
-#include <bitstring.h>
-#include <curses.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "../common/common.h"
-#ifdef RUNNING_IP
-#include "../ip/ip.h"
-#endif
-#include "cl.h"
-#include "pathnames.h"
-
-GS *__global_list; /* GLOBAL: List of screens. */
-sigset_t __sigblockset; /* GLOBAL: Blocked signals. */
-
-static void cl_func_std __P((GS *));
-static CL_PRIVATE *cl_init __P((GS *));
-static GS *gs_init __P((char *));
-static void perr __P((char *, char *));
-static int setsig __P((int, struct sigaction *, void (*)(int)));
-static void sig_end __P((GS *));
-static void term_init __P((char *, char *));
-
-/*
- * main --
- * This is the main loop for the standalone curses editor.
- */
-int
-main(argc, argv)
- int argc;
- char *argv[];
-{
- static int reenter;
- CL_PRIVATE *clp;
- GS *gp;
- size_t rows, cols;
- int rval;
- char *ip_arg, **p_av, **t_av, *ttype;
-
- /* If loaded at 0 and jumping through a NULL pointer, stop. */
- if (reenter++)
- abort();
-
- /* Create and initialize the global structure. */
- __global_list = gp = gs_init(argv[0]);
-
- /*
- * Strip out any arguments that vi isn't going to understand. There's
- * no way to portably call getopt twice, so arguments parsed here must
- * be removed from the argument list.
- */
-#ifdef RUNNING_IP
- ip_arg = NULL;
- for (p_av = t_av = argv;;) {
- if (*t_av == NULL) {
- *p_av = NULL;
- break;
- }
- if (!strcmp(*t_av, "--")) {
- while ((*p_av++ = *t_av++) != NULL);
- break;
- }
- if (!memcmp(*t_av, "-I", sizeof("-I") - 1)) {
- if (t_av[0][2] != '\0') {
- ip_arg = t_av[0] + 2;
- ++t_av;
- --argc;
- continue;
- }
- if (t_av[1] != NULL) {
- ip_arg = t_av[1];
- t_av += 2;
- argc -= 2;
- continue;
- }
- }
- *p_av++ = *t_av++;
- }
-
- /*
- * If we're being called as an editor library, we're done here, we
- * get loaded with the curses screen, we don't share much code.
- */
- if (ip_arg != NULL)
- exit (ip_main(argc, argv, gp, ip_arg));
-#else
- ip_arg = argv[0];
-#endif
-
- /* Create and initialize the CL_PRIVATE structure. */
- clp = cl_init(gp);
-
- /*
- * Initialize the terminal information.
- *
- * We have to know what terminal it is from the start, since we may
- * have to use termcap/terminfo to find out how big the screen is.
- */
- if ((ttype = getenv("TERM")) == NULL)
- ttype = "unknown";
- term_init(gp->progname, ttype);
-
- /* Add the terminal type to the global structure. */
- if ((OG_D_STR(gp, GO_TERM) =
- OG_STR(gp, GO_TERM) = strdup(ttype)) == NULL)
- perr(gp->progname, NULL);
-
- /* Figure out how big the screen is. */
- if (cl_ssize(NULL, 0, &rows, &cols, NULL))
- exit (1);
-
- /* Add the rows and columns to the global structure. */
- OG_VAL(gp, GO_LINES) = OG_D_VAL(gp, GO_LINES) = rows;
- OG_VAL(gp, GO_COLUMNS) = OG_D_VAL(gp, GO_COLUMNS) = cols;
-
- /* Ex wants stdout to be buffered. */
- (void)setvbuf(stdout, NULL, _IOFBF, 0);
-
- /* Start catching signals. */
- if (sig_init(gp, NULL))
- exit (1);
-
- /* Run ex/vi. */
- rval = editor(gp, argc, argv);
-
- /* Clean up signals. */
- sig_end(gp);
-
- /* Clean up the terminal. */
- (void)cl_quit(gp);
-
- /*
- * XXX
- * Reset the O_MESG option.
- */
- if (clp->tgw != TGW_UNKNOWN)
- (void)cl_omesg(NULL, clp, clp->tgw == TGW_SET);
-
- /*
- * XXX
- * Reset the X11 xterm icon/window name.
- */
- if (F_ISSET(clp, CL_RENAME)) {
- (void)printf(XTERM_RENAME, ttype);
- (void)fflush(stdout);
- }
-
- /* If a killer signal arrived, pretend we just got it. */
- if (clp->killersig) {
- (void)signal(clp->killersig, SIG_DFL);
- (void)kill(getpid(), clp->killersig);
- /* NOTREACHED */
- }
-
- /* Free the global and CL private areas. */
-#if defined(DEBUG) || defined(PURIFY) || defined(LIBRARY)
- free(clp);
- free(gp);
-#endif
-
- exit (rval);
-}
-
-/*
- * gs_init --
- * Create and partially initialize the GS structure.
- */
-static GS *
-gs_init(name)
- char *name;
-{
- CL_PRIVATE *clp;
- GS *gp;
- char *p;
-
- /* Figure out what our name is. */
- if ((p = strrchr(name, '/')) != NULL)
- name = p + 1;
-
- /* Allocate the global structure. */
- CALLOC_NOMSG(NULL, gp, GS *, 1, sizeof(GS));
- if (gp == NULL)
- perr(name, NULL);
-
-
- gp->progname = name;
- return (gp);
-}
-
-/*
- * cl_init --
- * Create and partially initialize the CL structure.
- */
-static CL_PRIVATE *
-cl_init(gp)
- GS *gp;
-{
- CL_PRIVATE *clp;
- int fd;
-
- /* Allocate the CL private structure. */
- CALLOC_NOMSG(NULL, clp, CL_PRIVATE *, 1, sizeof(CL_PRIVATE));
- if (clp == NULL)
- perr(gp->progname, NULL);
- gp->cl_private = clp;
-
- /*
- * Set the CL_STDIN_TTY flag. It's purpose is to avoid setting
- * and resetting the tty if the input isn't from there. We also
- * use the same test to determine if we're running a script or
- * not.
- */
- if (isatty(STDIN_FILENO))
- F_SET(clp, CL_STDIN_TTY);
- else
- F_SET(gp, G_SCRIPTED);
-
- /*
- * We expect that if we've lost our controlling terminal that the
- * open() (but not the tcgetattr()) will fail.
- */
- if (F_ISSET(clp, CL_STDIN_TTY)) {
- if (tcgetattr(STDIN_FILENO, &clp->orig) == -1)
- goto tcfail;
- } else if ((fd = open(_PATH_TTY, O_RDONLY, 0)) != -1) {
- if (tcgetattr(fd, &clp->orig) == -1) {
-tcfail: perr(gp->progname, "tcgetattr");
- exit (1);
- }
- (void)close(fd);
- }
-
- /* Initialize the list of curses functions. */
- cl_func_std(gp);
-
- return (clp);
-}
-
-/*
- * term_init --
- * Initialize terminal information.
- */
-static void
-term_init(name, ttype)
- char *name, *ttype;
-{
- int err;
-
- /* Set up the terminal database information. */
- setupterm(ttype, STDOUT_FILENO, &err);
- switch (err) {
- case -1:
- (void)fprintf(stderr,
- "%s: No terminal database found\n", name);
- exit (1);
- case 0:
- (void)fprintf(stderr,
- "%s: %s: unknown terminal type\n", name, ttype);
- exit (1);
- }
-}
-
-#define GLOBAL_CLP \
- CL_PRIVATE *clp = GCLP(__global_list);
-static void
-h_hup(signo)
- int signo;
-{
- GLOBAL_CLP;
-
- F_SET(clp, CL_SIGHUP);
- clp->killersig = SIGHUP;
-}
-
-static void
-h_int(signo)
- int signo;
-{
- GLOBAL_CLP;
-
- F_SET(clp, CL_SIGINT);
-}
-
-static void
-h_term(signo)
- int signo;
-{
- GLOBAL_CLP;
-
- F_SET(clp, CL_SIGTERM);
- clp->killersig = SIGTERM;
-}
-
-static void
-h_winch(signo)
- int signo;
-{
- GLOBAL_CLP;
-
- F_SET(clp, CL_SIGWINCH);
-}
-#undef GLOBAL_CLP
-
-/*
- * sig_init --
- * Initialize signals.
- *
- * PUBLIC: int sig_init __P((GS *, SCR *));
- */
-int
-sig_init(gp, sp)
- GS *gp;
- SCR *sp;
-{
- CL_PRIVATE *clp;
-
- clp = GCLP(gp);
-
- if (sp == NULL) {
- (void)sigemptyset(&__sigblockset);
- if (sigaddset(&__sigblockset, SIGHUP) ||
- setsig(SIGHUP, &clp->oact[INDX_HUP], h_hup) ||
- sigaddset(&__sigblockset, SIGINT) ||
- setsig(SIGINT, &clp->oact[INDX_INT], h_int) ||
- sigaddset(&__sigblockset, SIGTERM) ||
- setsig(SIGTERM, &clp->oact[INDX_TERM], h_term)
-#ifdef SIGWINCH
- ||
- sigaddset(&__sigblockset, SIGWINCH) ||
- setsig(SIGWINCH, &clp->oact[INDX_WINCH], h_winch)
-#endif
- ) {
- perr(gp->progname, NULL);
- return (1);
- }
- } else
- if (setsig(SIGHUP, NULL, h_hup) ||
- setsig(SIGINT, NULL, h_int) ||
- setsig(SIGTERM, NULL, h_term)
-#ifdef SIGWINCH
- ||
- setsig(SIGWINCH, NULL, h_winch)
-#endif
- ) {
- msgq(sp, M_SYSERR, "signal-reset");
- }
- return (0);
-}
-
-/*
- * setsig --
- * Set a signal handler.
- */
-static int
-setsig(signo, oactp, handler)
- int signo;
- struct sigaction *oactp;
- void (*handler) __P((int));
-{
- struct sigaction act;
-
- /*
- * Use sigaction(2), not signal(3), since we don't always want to
- * restart system calls. The example is when waiting for a command
- * mode keystroke and SIGWINCH arrives. Besides, you can't portably
- * restart system calls (thanks, POSIX!). On the other hand, you
- * can't portably NOT restart system calls (thanks, Sun!). SunOS
- * used SA_INTERRUPT as their extension to NOT restart read calls.
- * We sure hope nobody else used it for anything else. Mom told me
- * there'd be days like this. She just never told me that there'd
- * be so many.
- */
- act.sa_handler = handler;
- sigemptyset(&act.sa_mask);
-
-#ifdef SA_INTERRUPT
- act.sa_flags = SA_INTERRUPT;
-#else
- act.sa_flags = 0;
-#endif
- return (sigaction(signo, &act, oactp));
-}
-
-/*
- * sig_end --
- * End signal setup.
- */
-static void
-sig_end(gp)
- GS *gp;
-{
- CL_PRIVATE *clp;
-
- clp = GCLP(gp);
- (void)sigaction(SIGHUP, NULL, &clp->oact[INDX_HUP]);
- (void)sigaction(SIGINT, NULL, &clp->oact[INDX_INT]);
- (void)sigaction(SIGTERM, NULL, &clp->oact[INDX_TERM]);
-#ifdef SIGWINCH
- (void)sigaction(SIGWINCH, NULL, &clp->oact[INDX_WINCH]);
-#endif
-}
-
-/*
- * cl_func_std --
- * Initialize the standard curses functions.
- */
-static void
-cl_func_std(gp)
- GS *gp;
-{
- gp->scr_addstr = cl_addstr;
- gp->scr_attr = cl_attr;
- gp->scr_baud = cl_baud;
- gp->scr_bell = cl_bell;
- gp->scr_busy = NULL;
- gp->scr_clrtoeol = cl_clrtoeol;
- gp->scr_cursor = cl_cursor;
- gp->scr_deleteln = cl_deleteln;
- gp->scr_event = cl_event;
- gp->scr_ex_adjust = cl_ex_adjust;
- gp->scr_fmap = cl_fmap;
- gp->scr_insertln = cl_insertln;
- gp->scr_keyval = cl_keyval;
- gp->scr_move = cl_move;
- gp->scr_msg = NULL;
- gp->scr_optchange = cl_optchange;
- gp->scr_refresh = cl_refresh;
- gp->scr_rename = cl_rename;
- gp->scr_screen = cl_screen;
- gp->scr_suspend = cl_suspend;
- gp->scr_usage = cl_usage;
-}
-
-/*
- * perr --
- * Print system error.
- */
-static void
-perr(name, msg)
- char *name, *msg;
-{
- (void)fprintf(stderr, "%s:", name);
- if (msg != NULL)
- (void)fprintf(stderr, "%s:", msg);
- (void)fprintf(stderr, "%s\n", strerror(errno));
- exit(1);
-}
diff --git a/contrib/nvi/cl/cl_read.c b/contrib/nvi/cl/cl_read.c
deleted file mode 100644
index 8a95a77b2438..000000000000
--- a/contrib/nvi/cl/cl_read.c
+++ /dev/null
@@ -1,334 +0,0 @@
-/*-
- * Copyright (c) 1993, 1994
- * The Regents of the University of California. All rights reserved.
- * Copyright (c) 1993, 1994, 1995, 1996
- * Keith Bostic. All rights reserved.
- *
- * See the LICENSE file for redistribution information.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)cl_read.c 10.15 (Berkeley) 9/24/96";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <curses.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "../common/common.h"
-#include "../ex/script.h"
-#include "cl.h"
-
-static input_t cl_read __P((SCR *,
- u_int32_t, CHAR_T *, size_t, int *, struct timeval *));
-static int cl_resize __P((SCR *, size_t, size_t));
-
-/*
- * cl_event --
- * Return a single event.
- *
- * PUBLIC: int cl_event __P((SCR *, EVENT *, u_int32_t, int));
- */
-int
-cl_event(sp, evp, flags, ms)
- SCR *sp;
- EVENT *evp;
- u_int32_t flags;
- int ms;
-{
- struct timeval t, *tp;
- CL_PRIVATE *clp;
- size_t lines, columns;
- int changed, nr;
-
- /*
- * Queue signal based events. We never clear SIGHUP or SIGTERM events,
- * so that we just keep returning them until the editor dies.
- */
- clp = CLP(sp);
-retest: if (LF_ISSET(EC_INTERRUPT) || F_ISSET(clp, CL_SIGINT)) {
- if (F_ISSET(clp, CL_SIGINT)) {
- F_CLR(clp, CL_SIGINT);
- evp->e_event = E_INTERRUPT;
- } else
- evp->e_event = E_TIMEOUT;
- return (0);
- }
- if (F_ISSET(clp, CL_SIGHUP | CL_SIGTERM | CL_SIGWINCH)) {
- if (F_ISSET(clp, CL_SIGHUP)) {
- evp->e_event = E_SIGHUP;
- return (0);
- }
- if (F_ISSET(clp, CL_SIGTERM)) {
- evp->e_event = E_SIGTERM;
- return (0);
- }
- if (F_ISSET(clp, CL_SIGWINCH)) {
- F_CLR(clp, CL_SIGWINCH);
- if (cl_ssize(sp, 1, &lines, &columns, &changed))
- return (1);
- if (changed) {
- (void)cl_resize(sp, lines, columns);
- evp->e_event = E_WRESIZE;
- return (0);
- }
- /* No real change, ignore the signal. */
- }
- }
-
- /* Set timer. */
- if (ms == 0)
- tp = NULL;
- else {
- t.tv_sec = ms / 1000;
- t.tv_usec = (ms % 1000) * 1000;
- tp = &t;
- }
-
- /* Read input characters. */
- switch (cl_read(sp, LF_ISSET(EC_QUOTED | EC_RAW),
- clp->ibuf, sizeof(clp->ibuf), &nr, tp)) {
- case INP_OK:
- evp->e_csp = clp->ibuf;
- evp->e_len = nr;
- evp->e_event = E_STRING;
- break;
- case INP_EOF:
- evp->e_event = E_EOF;
- break;
- case INP_ERR:
- evp->e_event = E_ERR;
- break;
- case INP_INTR:
- goto retest;
- case INP_TIMEOUT:
- evp->e_event = E_TIMEOUT;
- break;
- default:
- abort();
- }
- return (0);
-}
-
-/*
- * cl_read --
- * Read characters from the input.
- */
-static input_t
-cl_read(sp, flags, bp, blen, nrp, tp)
- SCR *sp;
- u_int32_t flags;
- CHAR_T *bp;
- size_t blen;
- int *nrp;
- struct timeval *tp;
-{
- struct termios term1, term2;
- struct timeval poll;
- CL_PRIVATE *clp;
- GS *gp;
- SCR *tsp;
- fd_set rdfd;
- input_t rval;
- int maxfd, nr, term_reset;
-
- gp = sp->gp;
- clp = CLP(sp);
- term_reset = 0;
-
- /*
- * 1: A read from a file or a pipe. In this case, the reads
- * never timeout regardless. This means that we can hang
- * when trying to complete a map, but we're going to hang
- * on the next read anyway.
- */
- if (!F_ISSET(clp, CL_STDIN_TTY)) {
- switch (nr = read(STDIN_FILENO, bp, blen)) {
- case 0:
- return (INP_EOF);
- case -1:
- goto err;
- default:
- *nrp = nr;
- return (INP_OK);
- }
- /* NOTREACHED */
- }
-
- /*
- * 2: A read with an associated timeout, e.g., trying to complete
- * a map sequence. If input exists, we fall into #3.
- */
- FD_ZERO(&rdfd);
- poll.tv_sec = 0;
- poll.tv_usec = 0;
- if (tp != NULL) {
- FD_SET(STDIN_FILENO, &rdfd);
- switch (select(STDIN_FILENO + 1,
- &rdfd, NULL, NULL, tp == NULL ? &poll : tp)) {
- case 0:
- return (INP_TIMEOUT);
- case -1:
- goto err;
- default:
- break;
- }
- }
-
- /*
- * The user can enter a key in the editor to quote a character. If we
- * get here and the next key is supposed to be quoted, do what we can.
- * Reset the tty so that the user can enter a ^C, ^Q, ^S. There's an
- * obvious race here, when the key has already been entered, but there's
- * nothing that we can do to fix that problem.
- *
- * The editor can ask for the next literal character even thought it's
- * generally running in line-at-a-time mode. Do what we can.
- */
- if (LF_ISSET(EC_QUOTED | EC_RAW) && !tcgetattr(STDIN_FILENO, &term1)) {
- term_reset = 1;
- if (LF_ISSET(EC_QUOTED)) {
- term2 = term1;
- term2.c_lflag &= ~ISIG;
- term2.c_iflag &= ~(IXON | IXOFF);
- (void)tcsetattr(STDIN_FILENO,
- TCSASOFT | TCSADRAIN, &term2);
- } else
- (void)tcsetattr(STDIN_FILENO,
- TCSASOFT | TCSADRAIN, &clp->vi_enter);
- }
-
- /*
- * 3: Wait for input.
- *
- * Select on the command input and scripting window file descriptors.
- * It's ugly that we wait on scripting file descriptors here, but it's
- * the only way to keep from locking out scripting windows.
- */
- if (F_ISSET(gp, G_SCRWIN)) {
-loop: FD_ZERO(&rdfd);
- FD_SET(STDIN_FILENO, &rdfd);
- maxfd = STDIN_FILENO;
- for (tsp = gp->dq.cqh_first;
- tsp != (void *)&gp->dq; tsp = tsp->q.cqe_next)
- if (F_ISSET(sp, SC_SCRIPT)) {
- FD_SET(sp->script->sh_master, &rdfd);
- if (sp->script->sh_master > maxfd)
- maxfd = sp->script->sh_master;
- }
- switch (select(maxfd + 1, &rdfd, NULL, NULL, NULL)) {
- case 0:
- abort();
- case -1:
- goto err;
- default:
- break;
- }
- if (!FD_ISSET(STDIN_FILENO, &rdfd)) {
- if (sscr_input(sp))
- return (INP_ERR);
- goto loop;
- }
- }
-
- /*
- * 4: Read the input.
- *
- * !!!
- * What's going on here is some scary stuff. Ex runs the terminal in
- * canonical mode. So, the <newline> character terminating a line of
- * input is returned in the buffer, but a trailing <EOF> character is
- * not similarly included. As ex uses 0<EOF> and ^<EOF> as autoindent
- * commands, it has to see the trailing <EOF> characters to determine
- * the difference between the user entering "0ab" and "0<EOF>ab". We
- * leave an extra slot in the buffer, so that we can add a trailing
- * <EOF> character if the buffer isn't terminated by a <newline>. We
- * lose if the buffer is too small for the line and exactly N characters
- * are entered followed by an <EOF> character.
- */
-#define ONE_FOR_EOF 1
- switch (nr = read(STDIN_FILENO, bp, blen - ONE_FOR_EOF)) {
- case 0: /* EOF. */
- /*
- * ^D in canonical mode returns a read of 0, i.e. EOF. EOF is
- * a valid command, but we don't want to loop forever because
- * the terminal driver is returning EOF because the user has
- * disconnected. The editor will almost certainly try to write
- * something before this fires, which should kill us, but You
- * Never Know.
- */
- if (++clp->eof_count < 50) {
- bp[0] = clp->orig.c_cc[VEOF];
- *nrp = 1;
- rval = INP_OK;
-
- } else
- rval = INP_EOF;
- break;
- case -1: /* Error or interrupt. */
-err: if (errno == EINTR)
- rval = INP_INTR;
- else {
- rval = INP_ERR;
- msgq(sp, M_SYSERR, "input");
- }
- break;
- default: /* Input characters. */
- if (F_ISSET(sp, SC_EX) && bp[nr - 1] != '\n')
- bp[nr++] = clp->orig.c_cc[VEOF];
- *nrp = nr;
- clp->eof_count = 0;
- rval = INP_OK;
- break;
- }
-
- /* Restore the terminal state if it was modified. */
- if (term_reset)
- (void)tcsetattr(STDIN_FILENO, TCSASOFT | TCSADRAIN, &term1);
- return (rval);
-}
-
-/*
- * cl_resize --
- * Reset the options for a resize event.
- */
-static int
-cl_resize(sp, lines, columns)
- SCR *sp;
- size_t lines, columns;
-{
- ARGS *argv[2], a, b;
- char b1[1024];
-
- a.bp = b1;
- b.bp = NULL;
- a.len = b.len = 0;
- argv[0] = &a;
- argv[1] = &b;
-
- (void)snprintf(b1, sizeof(b1), "lines=%lu", (u_long)lines);
- a.len = strlen(b1);
- if (opts_set(sp, argv, NULL))
- return (1);
- (void)snprintf(b1, sizeof(b1), "columns=%lu", (u_long)columns);
- a.len = strlen(b1);
- if (opts_set(sp, argv, NULL))
- return (1);
- return (0);
-}
diff --git a/contrib/nvi/cl/cl_screen.c b/contrib/nvi/cl/cl_screen.c
deleted file mode 100644
index 2ce58e80cc78..000000000000
--- a/contrib/nvi/cl/cl_screen.c
+++ /dev/null
@@ -1,581 +0,0 @@
-/*-
- * Copyright (c) 1993, 1994
- * The Regents of the University of California. All rights reserved.
- * Copyright (c) 1993, 1994, 1995, 1996
- * Keith Bostic. All rights reserved.
- *
- * See the LICENSE file for redistribution information.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)cl_screen.c 10.49 (Berkeley) 9/24/96";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-
-#include <bitstring.h>
-#include <curses.h>
-#include <errno.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "../common/common.h"
-#include "cl.h"
-
-static int cl_ex_end __P((GS *));
-static int cl_ex_init __P((SCR *));
-static void cl_freecap __P((CL_PRIVATE *));
-static int cl_vi_end __P((GS *));
-static int cl_vi_init __P((SCR *));
-static int cl_putenv __P((char *, char *, u_long));
-
-/*
- * cl_screen --
- * Switch screen types.
- *
- * PUBLIC: int cl_screen __P((SCR *, u_int32_t));
- */
-int
-cl_screen(sp, flags)
- SCR *sp;
- u_int32_t flags;
-{
- CL_PRIVATE *clp;
- GS *gp;
-
- gp = sp->gp;
- clp = CLP(sp);
-
- /* See if the current information is incorrect. */
- if (F_ISSET(gp, G_SRESTART)) {
- if (cl_quit(gp))
- return (1);
- F_CLR(gp, G_SRESTART);
- }
-
- /* See if we're already in the right mode. */
- if (LF_ISSET(SC_EX) && F_ISSET(sp, SC_SCR_EX) ||
- LF_ISSET(SC_VI) && F_ISSET(sp, SC_SCR_VI))
- return (0);
-
- /*
- * Fake leaving ex mode.
- *
- * We don't actually exit ex or vi mode unless forced (e.g. by a window
- * size change). This is because many curses implementations can't be
- * called twice in a single program. Plus, it's faster. If the editor
- * "leaves" vi to enter ex, when it exits ex we'll just fall back into
- * vi.
- */
- if (F_ISSET(sp, SC_SCR_EX))
- F_CLR(sp, SC_SCR_EX);
-
- /*
- * Fake leaving vi mode.
- *
- * Clear out the rest of the screen if we're in the middle of a split
- * screen. Move to the last line in the current screen -- this makes
- * terminal scrolling happen naturally. Note: *don't* move past the
- * end of the screen, as there are ex commands (e.g., :read ! cat file)
- * that don't want to. Don't clear the info line, its contents may be
- * valid, e.g. :file|append.
- */
- if (F_ISSET(sp, SC_SCR_VI)) {
- F_CLR(sp, SC_SCR_VI);
-
- if (sp->q.cqe_next != (void *)&gp->dq) {
- (void)move(RLNO(sp, sp->rows), 0);
- clrtobot();
- }
- (void)move(RLNO(sp, sp->rows) - 1, 0);
- refresh();
- }
-
- /* Enter the requested mode. */
- if (LF_ISSET(SC_EX)) {
- if (cl_ex_init(sp))
- return (1);
- F_SET(clp, CL_IN_EX | CL_SCR_EX_INIT);
-
- /*
- * If doing an ex screen for ex mode, move to the last line
- * on the screen.
- */
- if (F_ISSET(sp, SC_EX) && clp->cup != NULL)
- tputs(tgoto(clp->cup,
- 0, O_VAL(sp, O_LINES) - 1), 1, cl_putchar);
- } else {
- if (cl_vi_init(sp))
- return (1);
- F_CLR(clp, CL_IN_EX);
- F_SET(clp, CL_SCR_VI_INIT);
- }
- return (0);
-}
-
-/*
- * cl_quit --
- * Shutdown the screens.
- *
- * PUBLIC: int cl_quit __P((GS *));
- */
-int
-cl_quit(gp)
- GS *gp;
-{
- CL_PRIVATE *clp;
- int rval;
-
- rval = 0;
- clp = GCLP(gp);
-
- /*
- * If we weren't really running, ignore it. This happens if the
- * screen changes size before we've called curses.
- */
- if (!F_ISSET(clp, CL_SCR_EX_INIT | CL_SCR_VI_INIT))
- return (0);
-
- /* Clean up the terminal mappings. */
- if (cl_term_end(gp))
- rval = 1;
-
- /* Really leave vi mode. */
- if (F_ISSET(clp, CL_STDIN_TTY) &&
- F_ISSET(clp, CL_SCR_VI_INIT) && cl_vi_end(gp))
- rval = 1;
-
- /* Really leave ex mode. */
- if (F_ISSET(clp, CL_STDIN_TTY) &&
- F_ISSET(clp, CL_SCR_EX_INIT) && cl_ex_end(gp))
- rval = 1;
-
- /*
- * If we were running ex when we quit, or we're using an implementation
- * of curses where endwin() doesn't get this right, restore the original
- * terminal modes.
- *
- * XXX
- * We always do this because it's too hard to figure out what curses
- * implementations get it wrong. It may discard type-ahead characters
- * from the tty queue.
- */
- (void)tcsetattr(STDIN_FILENO, TCSADRAIN | TCSASOFT, &clp->orig);
-
- F_CLR(clp, CL_SCR_EX_INIT | CL_SCR_VI_INIT);
- return (rval);
-}
-
-/*
- * cl_vi_init --
- * Initialize the curses vi screen.
- */
-static int
-cl_vi_init(sp)
- SCR *sp;
-{
- CL_PRIVATE *clp;
- GS *gp;
- char *o_cols, *o_lines, *o_term, *ttype;
-
- gp = sp->gp;
- clp = CLP(sp);
-
- /* If already initialized, just set the terminal modes. */
- if (F_ISSET(clp, CL_SCR_VI_INIT))
- goto fast;
-
- /* Curses vi always reads from (and writes to) a terminal. */
- if (!F_ISSET(clp, CL_STDIN_TTY) || !isatty(STDOUT_FILENO)) {
- msgq(sp, M_ERR,
- "016|Vi's standard input and output must be a terminal");
- return (1);
- }
-
- /* We'll need a terminal type. */
- if (opts_empty(sp, O_TERM, 0))
- return (1);
- ttype = O_STR(sp, O_TERM);
-
- /*
- * XXX
- * Changing the row/column and terminal values is done by putting them
- * into the environment, which is then read by curses. What this loses
- * in ugliness, it makes up for in stupidity. We can't simply put the
- * values into the environment ourselves, because in the presence of a
- * kernel mechanism for returning the window size, entering values into
- * the environment will screw up future screen resizing events, e.g. if
- * the user enters a :shell command and then resizes their window. So,
- * if they weren't already in the environment, we make sure to delete
- * them immediately after setting them.
- *
- * XXX
- * Putting the TERM variable into the environment is necessary, even
- * though we're using newterm() here. We may be using initscr() as
- * the underlying function.
- */
- o_term = getenv("TERM");
- cl_putenv("TERM", ttype, 0);
- o_lines = getenv("LINES");
- cl_putenv("LINES", NULL, (u_long)O_VAL(sp, O_LINES));
- o_cols = getenv("COLUMNS");
- cl_putenv("COLUMNS", NULL, (u_long)O_VAL(sp, O_COLUMNS));
-
- /*
- * We don't care about the SCREEN reference returned by newterm, we
- * never have more than one SCREEN at a time.
- *
- * XXX
- * The SunOS initscr() can't be called twice. Don't even think about
- * using it. It fails in subtle ways (e.g. select(2) on fileno(stdin)
- * stops working). (The SVID notes that applications should only call
- * initscr() once.)
- *
- * XXX
- * The HP/UX newterm doesn't support the NULL first argument, so we
- * have to specify the terminal type.
- */
- errno = 0;
- if (newterm(ttype, stdout, stdin) == NULL) {
- if (errno)
- msgq(sp, M_SYSERR, "%s", ttype);
- else
- msgq(sp, M_ERR, "%s: unknown terminal type", ttype);
- return (1);
- }
-
- if (o_term == NULL)
- unsetenv("TERM");
- if (o_lines == NULL)
- unsetenv("LINES");
- if (o_cols == NULL)
- unsetenv("COLUMNS");
-
- /*
- * XXX
- * Someone got let out alone without adult supervision -- the SunOS
- * newterm resets the signal handlers. There's a race, but it's not
- * worth closing.
- */
- (void)sig_init(sp->gp, sp);
-
- /*
- * We use raw mode. What we want is 8-bit clean, however, signals
- * and flow control should continue to work. Admittedly, it sounds
- * like cbreak, but it isn't. Using cbreak() can get you additional
- * things like IEXTEN, which turns on flags like DISCARD and LNEXT.
- *
- * !!!
- * If raw isn't turning off echo and newlines, something's wrong.
- * However, it shouldn't hurt.
- */
- noecho(); /* No character echo. */
- nonl(); /* No CR/NL translation. */
- raw(); /* 8-bit clean. */
- idlok(stdscr, 1); /* Use hardware insert/delete line. */
-
- /* Put the cursor keys into application mode. */
- (void)keypad(stdscr, TRUE);
-
- /*
- * XXX
- * The screen TI sequence just got sent. See the comment in
- * cl_funcs.c:cl_attr().
- */
- clp->ti_te = TI_SENT;
-
- /*
- * XXX
- * Historic implementations of curses handled SIGTSTP signals
- * in one of three ways. They either:
- *
- * 1: Set their own handler, regardless.
- * 2: Did not set a handler if a handler was already installed.
- * 3: Set their own handler, but then called any previously set
- * handler after completing their own cleanup.
- *
- * We don't try and figure out which behavior is in place, we force
- * it to SIG_DFL after initializing the curses interface, which means
- * that curses isn't going to take the signal. Since curses isn't
- * reentrant (i.e., the whole curses SIGTSTP interface is a fantasy),
- * we're doing The Right Thing.
- */
- (void)signal(SIGTSTP, SIG_DFL);
-
- /*
- * If flow control was on, turn it back on. Turn signals on. ISIG
- * turns on VINTR, VQUIT, VDSUSP and VSUSP. The main curses code
- * already installed a handler for VINTR. We're going to disable the
- * other three.
- *
- * XXX
- * We want to use ^Y as a vi scrolling command. If the user has the
- * DSUSP character set to ^Y (common practice) clean it up. As it's
- * equally possible that the user has VDSUSP set to 'a', we disable
- * it regardless. It doesn't make much sense to suspend vi at read,
- * so I don't think anyone will care. Alternatively, we could look
- * it up in the table of legal command characters and turn it off if
- * it matches one. VDSUSP wasn't in POSIX 1003.1-1990, so we test for
- * it.
- *
- * XXX
- * We don't check to see if the user had signals enabled originally.
- * If they didn't, it's unclear what we're supposed to do here, but
- * it's also pretty unlikely.
- */
- if (tcgetattr(STDIN_FILENO, &clp->vi_enter)) {
- msgq(sp, M_SYSERR, "tcgetattr");
- goto err;
- }
- if (clp->orig.c_iflag & IXON)
- clp->vi_enter.c_iflag |= IXON;
- if (clp->orig.c_iflag & IXOFF)
- clp->vi_enter.c_iflag |= IXOFF;
-
- clp->vi_enter.c_lflag |= ISIG;
-#ifdef VDSUSP
- clp->vi_enter.c_cc[VDSUSP] = _POSIX_VDISABLE;
-#endif
- clp->vi_enter.c_cc[VQUIT] = _POSIX_VDISABLE;
- clp->vi_enter.c_cc[VSUSP] = _POSIX_VDISABLE;
-
- /*
- * XXX
- * OSF/1 doesn't turn off the <discard>, <literal-next> or <status>
- * characters when curses switches into raw mode. It should be OK
- * to do it explicitly for everyone.
- */
-#ifdef VDISCARD
- clp->vi_enter.c_cc[VDISCARD] = _POSIX_VDISABLE;
-#endif
-#ifdef VLNEXT
- clp->vi_enter.c_cc[VLNEXT] = _POSIX_VDISABLE;
-#endif
-#ifdef VSTATUS
- clp->vi_enter.c_cc[VSTATUS] = _POSIX_VDISABLE;
-#endif
-
- /* Initialize terminal based information. */
- if (cl_term_init(sp))
- goto err;
-
-fast: /* Set the terminal modes. */
- if (tcsetattr(STDIN_FILENO, TCSASOFT | TCSADRAIN, &clp->vi_enter)) {
- msgq(sp, M_SYSERR, "tcsetattr");
-err: (void)cl_vi_end(sp->gp);
- return (1);
- }
- return (0);
-}
-
-/*
- * cl_vi_end --
- * Shutdown the vi screen.
- */
-static int
-cl_vi_end(gp)
- GS *gp;
-{
- CL_PRIVATE *clp;
-
- clp = GCLP(gp);
-
- /* Restore the cursor keys to normal mode. */
- (void)keypad(stdscr, FALSE);
-
- /*
- * If we were running vi when we quit, scroll the screen up a single
- * line so we don't lose any information.
- *
- * Move to the bottom of the window (some endwin implementations don't
- * do this for you).
- */
- if (!F_ISSET(clp, CL_IN_EX)) {
- (void)move(0, 0);
- (void)deleteln();
- (void)move(LINES - 1, 0);
- (void)refresh();
- }
-
- cl_freecap(clp);
-
- /* End curses window. */
- (void)endwin();
-
- /*
- * XXX
- * The screen TE sequence just got sent. See the comment in
- * cl_funcs.c:cl_attr().
- */
- clp->ti_te = TE_SENT;
-
- return (0);
-}
-
-/*
- * cl_ex_init --
- * Initialize the ex screen.
- */
-static int
-cl_ex_init(sp)
- SCR *sp;
-{
- CL_PRIVATE *clp;
-
- clp = CLP(sp);
-
- /* If already initialized, just set the terminal modes. */
- if (F_ISSET(clp, CL_SCR_EX_INIT))
- goto fast;
-
- /* If not reading from a file, we're done. */
- if (!F_ISSET(clp, CL_STDIN_TTY))
- return (0);
-
- /* Get the ex termcap/terminfo strings. */
- (void)cl_getcap(sp, "cup", &clp->cup);
- (void)cl_getcap(sp, "smso", &clp->smso);
- (void)cl_getcap(sp, "rmso", &clp->rmso);
- (void)cl_getcap(sp, "el", &clp->el);
- (void)cl_getcap(sp, "cuu1", &clp->cuu1);
-
- /* Enter_standout_mode and exit_standout_mode are paired. */
- if (clp->smso == NULL || clp->rmso == NULL) {
- if (clp->smso != NULL) {
- free(clp->smso);
- clp->smso = NULL;
- }
- if (clp->rmso != NULL) {
- free(clp->rmso);
- clp->rmso = NULL;
- }
- }
-
- /*
- * Turn on canonical mode, with normal input and output processing.
- * Start with the original terminal settings as the user probably
- * had them (including any local extensions) set correctly for the
- * current terminal.
- *
- * !!!
- * We can't get everything that we need portably; for example, ONLCR,
- * mapping <newline> to <carriage-return> on output isn't required
- * by POSIX 1003.1b-1993. If this turns out to be a problem, then
- * we'll either have to play some games on the mapping, or we'll have
- * to make all ex printf's output \r\n instead of \n.
- */
- clp->ex_enter = clp->orig;
- clp->ex_enter.c_lflag |= ECHO | ECHOE | ECHOK | ICANON | IEXTEN | ISIG;
-#ifdef ECHOCTL
- clp->ex_enter.c_lflag |= ECHOCTL;
-#endif
-#ifdef ECHOKE
- clp->ex_enter.c_lflag |= ECHOKE;
-#endif
- clp->ex_enter.c_iflag |= ICRNL;
- clp->ex_enter.c_oflag |= OPOST;
-#ifdef ONLCR
- clp->ex_enter.c_oflag |= ONLCR;
-#endif
-
-fast: if (tcsetattr(STDIN_FILENO, TCSADRAIN | TCSASOFT, &clp->ex_enter)) {
- msgq(sp, M_SYSERR, "tcsetattr");
- return (1);
- }
- return (0);
-}
-
-/*
- * cl_ex_end --
- * Shutdown the ex screen.
- */
-static int
-cl_ex_end(gp)
- GS *gp;
-{
- CL_PRIVATE *clp;
-
- clp = GCLP(gp);
-
- cl_freecap(clp);
-
- return (0);
-}
-
-/*
- * cl_getcap --
- * Retrieve termcap/terminfo strings.
- *
- * PUBLIC: int cl_getcap __P((SCR *, char *, char **));
- */
-int
-cl_getcap(sp, name, elementp)
- SCR *sp;
- char *name, **elementp;
-{
- size_t len;
- char *t;
-
- if ((t = tigetstr(name)) != NULL &&
- t != (char *)-1 && (len = strlen(t)) != 0) {
- MALLOC_RET(sp, *elementp, char *, len + 1);
- memmove(*elementp, t, len + 1);
- }
- return (0);
-}
-
-/*
- * cl_freecap --
- * Free any allocated termcap/terminfo strings.
- */
-static void
-cl_freecap(clp)
- CL_PRIVATE *clp;
-{
- if (clp->el != NULL) {
- free(clp->el);
- clp->el = NULL;
- }
- if (clp->cup != NULL) {
- free(clp->cup);
- clp->cup = NULL;
- }
- if (clp->cuu1 != NULL) {
- free(clp->cuu1);
- clp->cuu1 = NULL;
- }
- if (clp->rmso != NULL) {
- free(clp->rmso);
- clp->rmso = NULL;
- }
- if (clp->smso != NULL) {
- free(clp->smso);
- clp->smso = NULL;
- }
-}
-
-/*
- * cl_putenv --
- * Put a value into the environment.
- */
-static int
-cl_putenv(name, str, value)
- char *name, *str;
- u_long value;
-
-{
- char buf[40];
-
- if (str == NULL) {
- (void)snprintf(buf, sizeof(buf), "%lu", value);
- return (setenv(name, buf, 1));
- } else
- return (setenv(name, str, 1));
-}
diff --git a/contrib/nvi/cl/cl_term.c b/contrib/nvi/cl/cl_term.c
deleted file mode 100644
index c36bb3830e9f..000000000000
--- a/contrib/nvi/cl/cl_term.c
+++ /dev/null
@@ -1,460 +0,0 @@
-/*-
- * Copyright (c) 1993, 1994
- * The Regents of the University of California. All rights reserved.
- * Copyright (c) 1993, 1994, 1995, 1996
- * Keith Bostic. All rights reserved.
- *
- * See the LICENSE file for redistribution information.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)cl_term.c 10.22 (Berkeley) 9/15/96";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/queue.h>
-#include <sys/stat.h>
-
-#include <bitstring.h>
-#include <curses.h>
-#include <errno.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "../common/common.h"
-#include "cl.h"
-
-static int cl_pfmap __P((SCR *, seq_t, CHAR_T *, size_t, CHAR_T *, size_t));
-
-/*
- * XXX
- * THIS REQUIRES THAT ALL SCREENS SHARE A TERMINAL TYPE.
- */
-typedef struct _tklist {
- char *ts; /* Key's termcap string. */
- char *output; /* Corresponding vi command. */
- char *name; /* Name. */
- u_char value; /* Special value (for lookup). */
-} TKLIST;
-static TKLIST const c_tklist[] = { /* Command mappings. */
- {"kil1", "O", "insert line"},
- {"kdch1", "x", "delete character"},
- {"kcud1", "j", "cursor down"},
- {"kel", "D", "delete to eol"},
- {"kind", "\004", "scroll down"}, /* ^D */
- {"kll", "$", "go to eol"},
- {"kend", "$", "go to eol"},
- {"khome", "^", "go to sol"},
- {"kich1", "i", "insert at cursor"},
- {"kdl1", "dd", "delete line"},
- {"kcub1", "h", "cursor left"},
- {"knp", "\006", "page down"}, /* ^F */
- {"kpp", "\002", "page up"}, /* ^B */
- {"kri", "\025", "scroll up"}, /* ^U */
- {"ked", "dG", "delete to end of screen"},
- {"kcuf1", "l", "cursor right"},
- {"kcuu1", "k", "cursor up"},
- {NULL},
-};
-static TKLIST const m1_tklist[] = { /* Input mappings (lookup). */
- {NULL},
-};
-static TKLIST const m2_tklist[] = { /* Input mappings (set or delete). */
- {"kcud1", "\033ja", "cursor down"}, /* ^[ja */
- {"kcub1", "\033ha", "cursor left"}, /* ^[ha */
- {"kcuu1", "\033ka", "cursor up"}, /* ^[ka */
- {"kcuf1", "\033la", "cursor right"}, /* ^[la */
- {NULL},
-};
-
-/*
- * cl_term_init --
- * Initialize the special keys defined by the termcap/terminfo entry.
- *
- * PUBLIC: int cl_term_init __P((SCR *));
- */
-int
-cl_term_init(sp)
- SCR *sp;
-{
- KEYLIST *kp;
- SEQ *qp;
- TKLIST const *tkp;
- char *t;
-
- /* Command mappings. */
- for (tkp = c_tklist; tkp->name != NULL; ++tkp) {
- if ((t = tigetstr(tkp->ts)) == NULL || t == (char *)-1)
- continue;
- if (seq_set(sp, tkp->name, strlen(tkp->name), t, strlen(t),
- tkp->output, strlen(tkp->output), SEQ_COMMAND,
- SEQ_NOOVERWRITE | SEQ_SCREEN))
- return (1);
- }
-
- /* Input mappings needing to be looked up. */
- for (tkp = m1_tklist; tkp->name != NULL; ++tkp) {
- if ((t = tigetstr(tkp->ts)) == NULL || t == (char *)-1)
- continue;
- for (kp = keylist;; ++kp)
- if (kp->value == tkp->value)
- break;
- if (kp == NULL)
- continue;
- if (seq_set(sp, tkp->name, strlen(tkp->name), t, strlen(t),
- &kp->ch, 1, SEQ_INPUT, SEQ_NOOVERWRITE | SEQ_SCREEN))
- return (1);
- }
-
- /* Input mappings that are already set or are text deletions. */
- for (tkp = m2_tklist; tkp->name != NULL; ++tkp) {
- if ((t = tigetstr(tkp->ts)) == NULL || t == (char *)-1)
- continue;
- /*
- * !!!
- * Some terminals' <cursor_left> keys send single <backspace>
- * characters. This is okay in command mapping, but not okay
- * in input mapping. That combination is the only one we'll
- * ever see, hopefully, so kluge it here for now.
- */
- if (!strcmp(t, "\b"))
- continue;
- if (tkp->output == NULL) {
- if (seq_set(sp, tkp->name, strlen(tkp->name),
- t, strlen(t), NULL, 0,
- SEQ_INPUT, SEQ_NOOVERWRITE | SEQ_SCREEN))
- return (1);
- } else
- if (seq_set(sp, tkp->name, strlen(tkp->name),
- t, strlen(t), tkp->output, strlen(tkp->output),
- SEQ_INPUT, SEQ_NOOVERWRITE | SEQ_SCREEN))
- return (1);
- }
-
- /*
- * Rework any function key mappings that were set before the
- * screen was initialized.
- */
- for (qp = sp->gp->seqq.lh_first; qp != NULL; qp = qp->q.le_next)
- if (F_ISSET(qp, SEQ_FUNCMAP))
- (void)cl_pfmap(sp, qp->stype,
- qp->input, qp->ilen, qp->output, qp->olen);
- return (0);
-}
-
-/*
- * cl_term_end --
- * End the special keys defined by the termcap/terminfo entry.
- *
- * PUBLIC: int cl_term_end __P((GS *));
- */
-int
-cl_term_end(gp)
- GS *gp;
-{
- SEQ *qp, *nqp;
-
- /* Delete screen specific mappings. */
- for (qp = gp->seqq.lh_first; qp != NULL; qp = nqp) {
- nqp = qp->q.le_next;
- if (F_ISSET(qp, SEQ_SCREEN))
- (void)seq_mdel(qp);
- }
- return (0);
-}
-
-/*
- * cl_fmap --
- * Map a function key.
- *
- * PUBLIC: int cl_fmap __P((SCR *, seq_t, CHAR_T *, size_t, CHAR_T *, size_t));
- */
-int
-cl_fmap(sp, stype, from, flen, to, tlen)
- SCR *sp;
- seq_t stype;
- CHAR_T *from, *to;
- size_t flen, tlen;
-{
- /* Ignore until the screen is running, do the real work then. */
- if (F_ISSET(sp, SC_VI) && !F_ISSET(sp, SC_SCR_VI))
- return (0);
- if (F_ISSET(sp, SC_EX) && !F_ISSET(sp, SC_SCR_EX))
- return (0);
-
- return (cl_pfmap(sp, stype, from, flen, to, tlen));
-}
-
-/*
- * cl_pfmap --
- * Map a function key (private version).
- */
-static int
-cl_pfmap(sp, stype, from, flen, to, tlen)
- SCR *sp;
- seq_t stype;
- CHAR_T *from, *to;
- size_t flen, tlen;
-{
- size_t nlen;
- char *p, keyname[64];
-
- (void)snprintf(keyname, sizeof(keyname), "kf%d", atoi(from + 1));
- if ((p = tigetstr(keyname)) == NULL ||
- p == (char *)-1 || strlen(p) == 0)
- p = NULL;
- if (p == NULL) {
- msgq_str(sp, M_ERR, from, "233|This terminal has no %s key");
- return (1);
- }
-
- nlen = snprintf(keyname,
- sizeof(keyname), "function key %d", atoi(from + 1));
- return (seq_set(sp, keyname, nlen,
- p, strlen(p), to, tlen, stype, SEQ_NOOVERWRITE | SEQ_SCREEN));
-}
-
-/*
- * cl_optchange --
- * Curses screen specific "option changed" routine.
- *
- * PUBLIC: int cl_optchange __P((SCR *, int, char *, u_long *));
- */
-int
-cl_optchange(sp, opt, str, valp)
- SCR *sp;
- int opt;
- char *str;
- u_long *valp;
-{
- CL_PRIVATE *clp;
-
- clp = CLP(sp);
-
- switch (opt) {
- case O_COLUMNS:
- case O_LINES:
- case O_TERM:
- /*
- * Changing the columns, lines or terminal require that
- * we restart the screen.
- */
- F_SET(sp->gp, G_SRESTART);
- F_CLR(sp, SC_SCR_EX | SC_SCR_VI);
- break;
- case O_MESG:
- (void)cl_omesg(sp, clp, !*valp);
- break;
- case O_WINDOWNAME:
- if (*valp) {
- F_CLR(clp, CL_RENAME_OK);
-
- (void)cl_rename(sp, NULL, 0);
- } else {
- F_SET(clp, CL_RENAME_OK);
-
- /*
- * If the screen is live, i.e. we're not reading the
- * .exrc file, update the window.
- */
- if (sp->frp != NULL && sp->frp->name != NULL)
- (void)cl_rename(sp, sp->frp->name, 1);
- }
- break;
- }
- return (0);
-}
-
-/*
- * cl_omesg --
- * Turn the tty write permission on or off.
- *
- * PUBLIC: int cl_omesg __P((SCR *, CL_PRIVATE *, int));
- */
-int
-cl_omesg(sp, clp, on)
- SCR *sp;
- CL_PRIVATE *clp;
- int on;
-{
- struct stat sb;
- char *tty;
-
- /* Find the tty, get the current permissions. */
- if ((tty = ttyname(STDERR_FILENO)) == NULL) {
- if (sp != NULL)
- msgq(sp, M_SYSERR, "stderr");
- return (1);
- }
- if (stat(tty, &sb) < 0) {
- if (sp != NULL)
- msgq(sp, M_SYSERR, "%s", tty);
- return (1);
- }
-
- /* Save the original status if it's unknown. */
- if (clp->tgw == TGW_UNKNOWN)
- clp->tgw = sb.st_mode & S_IWGRP ? TGW_SET : TGW_UNSET;
-
- /* Toggle the permissions. */
- if (on) {
- if (chmod(tty, sb.st_mode | S_IWGRP) < 0) {
- if (sp != NULL)
- msgq(sp, M_SYSERR,
- "046|messages not turned on: %s", tty);
- return (1);
- }
- } else
- if (chmod(tty, sb.st_mode & ~S_IWGRP) < 0) {
- if (sp != NULL)
- msgq(sp, M_SYSERR,
- "045|messages not turned off: %s", tty);
- return (1);
- }
- return (0);
-}
-
-/*
- * cl_ssize --
- * Return the terminal size.
- *
- * PUBLIC: int cl_ssize __P((SCR *, int, size_t *, size_t *, int *));
- */
-int
-cl_ssize(sp, sigwinch, rowp, colp, changedp)
- SCR *sp;
- int sigwinch;
- size_t *rowp, *colp;
- int *changedp;
-{
-#ifdef TIOCGWINSZ
- struct winsize win;
-#endif
- size_t col, row;
- int rval;
- char *p;
-
- /* Assume it's changed. */
- if (changedp != NULL)
- *changedp = 1;
-
- /*
- * !!!
- * sp may be NULL.
- *
- * Get the screen rows and columns. If the values are wrong, it's
- * not a big deal -- as soon as the user sets them explicitly the
- * environment will be set and the screen package will use the new
- * values.
- *
- * Try TIOCGWINSZ.
- */
- row = col = 0;
-#ifdef TIOCGWINSZ
- if (ioctl(STDERR_FILENO, TIOCGWINSZ, &win) != -1) {
- row = win.ws_row;
- col = win.ws_col;
- }
-#endif
- /* If here because of suspend or a signal, only trust TIOCGWINSZ. */
- if (sigwinch) {
- /*
- * Somebody didn't get TIOCGWINSZ right, or has suspend
- * without window resizing support. The user just lost,
- * but there's nothing we can do.
- */
- if (row == 0 || col == 0) {
- if (changedp != NULL)
- *changedp = 0;
- return (0);
- }
-
- /*
- * SunOS systems deliver SIGWINCH when windows are uncovered
- * as well as when they change size. In addition, we call
- * here when continuing after being suspended since the window
- * may have changed size. Since we don't want to background
- * all of the screens just because the window was uncovered,
- * ignore the signal if there's no change.
- */
- if (sp != NULL &&
- row == O_VAL(sp, O_LINES) && col == O_VAL(sp, O_COLUMNS)) {
- if (changedp != NULL)
- *changedp = 0;
- return (0);
- }
-
- if (rowp != NULL)
- *rowp = row;
- if (colp != NULL)
- *colp = col;
- return (0);
- }
-
- /*
- * !!!
- * If TIOCGWINSZ failed, or had entries of 0, try termcap. This
- * routine is called before any termcap or terminal information
- * has been set up. If there's no TERM environmental variable set,
- * let it go, at least ex can run.
- */
- if (row == 0 || col == 0) {
- if ((p = getenv("TERM")) == NULL)
- goto noterm;
- if (row == 0)
- if ((rval = tigetnum("lines")) < 0)
- msgq(sp, M_SYSERR, "tigetnum: lines");
- else
- row = rval;
- if (col == 0)
- if ((rval = tigetnum("cols")) < 0)
- msgq(sp, M_SYSERR, "tigetnum: cols");
- else
- col = rval;
- }
-
- /* If nothing else, well, it's probably a VT100. */
-noterm: if (row == 0)
- row = 24;
- if (col == 0)
- col = 80;
-
- /*
- * !!!
- * POSIX 1003.2 requires the environment to override everything.
- * Often, people can get nvi to stop messing up their screen by
- * deleting the LINES and COLUMNS environment variables from their
- * dot-files.
- */
- if ((p = getenv("LINES")) != NULL)
- row = strtol(p, NULL, 10);
- if ((p = getenv("COLUMNS")) != NULL)
- col = strtol(p, NULL, 10);
-
- if (rowp != NULL)
- *rowp = row;
- if (colp != NULL)
- *colp = col;
- return (0);
-}
-
-/*
- * cl_putchar --
- * Function version of putchar, for tputs.
- *
- * PUBLIC: int cl_putchar __P((int));
- */
-int
-cl_putchar(ch)
- int ch;
-{
- return (putchar(ch));
-}