Fix how keywords are picked up.
[nvi.git] / cl / cl_bsd.c
blob90299b01a3ade01428b3a06641e622b343bf75d3
1 /*-
2 * Copyright (c) 1995, 1996
3 * Keith Bostic. All rights reserved.
5 * See the LICENSE file for redistribution information.
6 */
8 #include "config.h"
10 #ifndef lint
11 static const char sccsid[] = "$Id: cl_bsd.c,v 8.32 2000/12/01 13:56:17 skimo Exp $ (Berkeley) $Date: 2000/12/01 13:56:17 $";
12 #endif /* not lint */
14 #include <sys/types.h>
15 #include <sys/queue.h>
16 #include <sys/time.h>
18 #include <bitstring.h>
19 #include <ctype.h>
20 #include <signal.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <termios.h>
25 #include <unistd.h>
27 #include "../common/common.h"
28 #include "../vi/vi.h"
29 #include "cl.h"
31 static char *ke; /* Keypad on. */
32 static char *ks; /* Keypad off. */
33 static char *vb; /* Visible bell string. */
36 * HP's support the entire System V curses package except for the tigetstr
37 * and tigetnum functions. Ultrix supports the BSD curses package except
38 * for the idlok function. Cthulu only knows why. Break things up into a
39 * minimal set of functions.
42 #ifndef HAVE_CURSES_WADDNSTR
44 * waddnstr --
46 * PUBLIC: #ifndef HAVE_CURSES_WADDNSTR
47 * PUBLIC: int waddnstr __P((WINDOW*, char *, int));
48 * PUBLIC: #endif
50 int
51 waddnstr(w, s, n)
52 WINDOW *w;
53 char *s;
54 int n;
56 int ch;
58 while (n-- && (ch = *s++))
59 waddch(w, ch);
60 return (OK);
62 #endif
64 #ifndef HAVE_CURSES_BEEP
66 * beep --
68 * PUBLIC: #ifndef HAVE_CURSES_BEEP
69 * PUBLIC: void beep __P((void));
70 * PUBLIC: #endif
72 void
73 beep()
75 (void)write(1, "\007", 1); /* '\a' */
77 #endif /* !HAVE_CURSES_BEEP */
79 #ifndef HAVE_CURSES_FLASH
81 * flash --
82 * Flash the screen.
84 * PUBLIC: #ifndef HAVE_CURSES_FLASH
85 * PUBLIC: void flash __P((void));
86 * PUBLIC: #endif
88 void
89 flash()
91 if (vb != NULL) {
92 (void)tputs(vb, 1, cl_putchar);
93 (void)fflush(stdout);
94 } else
95 beep();
97 #endif /* !HAVE_CURSES_FLASH */
99 #ifndef HAVE_CURSES_IDLOK
101 * idlok --
102 * Turn on/off hardware line insert/delete.
104 * PUBLIC: #ifndef HAVE_CURSES_IDLOK
105 * PUBLIC: void idlok __P((WINDOW *, int));
106 * PUBLIC: #endif
108 void
109 idlok(win, bf)
110 WINDOW *win;
111 int bf;
113 return;
115 #endif /* !HAVE_CURSES_IDLOK */
117 #ifndef HAVE_CURSES_KEYPAD
119 * keypad --
120 * Put the keypad/cursor arrows into or out of application mode.
122 * PUBLIC: #ifndef HAVE_CURSES_KEYPAD
123 * PUBLIC: int keypad __P((void *, int));
124 * PUBLIC: #endif
127 keypad(a, on)
128 void *a;
129 int on;
131 char *p;
133 if ((p = tigetstr(on ? "smkx" : "rmkx")) != (char *)-1) {
134 (void)tputs(p, 0, cl_putchar);
135 (void)fflush(stdout);
137 return (0);
139 #endif /* !HAVE_CURSES_KEYPAD */
141 #ifndef HAVE_CURSES_NEWTERM
143 * newterm --
144 * Create a new curses screen.
146 * PUBLIC: #ifndef HAVE_CURSES_NEWTERM
147 * PUBLIC: void *newterm __P((const char *, FILE *, FILE *));
148 * PUBLIC: #endif
150 void *
151 newterm(a, b, c)
152 const char *a;
153 FILE *b, *c;
155 return (initscr());
157 #endif /* !HAVE_CURSES_NEWTERM */
159 #ifndef HAVE_CURSES_SETUPTERM
161 * setupterm --
162 * Set up terminal.
164 * PUBLIC: #ifndef HAVE_CURSES_SETUPTERM
165 * PUBLIC: void setupterm __P((char *, int, int *));
166 * PUBLIC: #endif
168 void
169 setupterm(ttype, fno, errp)
170 char *ttype;
171 int fno, *errp;
173 static char buf[2048];
174 char *p;
176 if ((*errp = tgetent(buf, ttype)) > 0) {
177 if (ke != NULL)
178 free(ke);
179 ke = ((p = tigetstr("rmkx")) == (char *)-1) ?
180 NULL : strdup(p);
181 if (ks != NULL)
182 free(ks);
183 ks = ((p = tigetstr("smkx")) == (char *)-1) ?
184 NULL : strdup(p);
185 if (vb != NULL)
186 free(vb);
187 vb = ((p = tigetstr("flash")) == (char *)-1) ?
188 NULL : strdup(p);
191 #endif /* !HAVE_CURSES_SETUPTERM */
193 #ifndef HAVE_CURSES_TIGETSTR
194 /* Terminfo-to-termcap translation table. */
195 typedef struct _tl {
196 char *terminfo; /* Terminfo name. */
197 char *termcap; /* Termcap name. */
198 } TL;
199 static const TL list[] = {
200 "cols", "co", /* Terminal columns. */
201 "cup", "cm", /* Cursor up. */
202 "cuu1", "up", /* Cursor up. */
203 "el", "ce", /* Clear to end-of-line. */
204 "flash", "vb", /* Visible bell. */
205 "kcub1", "kl", /* Cursor left. */
206 "kcud1", "kd", /* Cursor down. */
207 "kcuf1", "kr", /* Cursor right. */
208 "kcuu1", "ku", /* Cursor up. */
209 "kdch1", "kD", /* Delete character. */
210 "kdl1", "kL", /* Delete line. */
211 "ked", "kS", /* Delete to end of screen. */
212 "kel", "kE", /* Delete to eol. */
213 "kend", "@7", /* Go to eol. */
214 "khome", "kh", /* Go to sol. */
215 "kich1", "kI", /* Insert at cursor. */
216 "kil1", "kA", /* Insert line. */
217 "kind", "kF", /* Scroll down. */
218 "kll", "kH", /* Go to eol. */
219 "knp", "kN", /* Page down. */
220 "kpp", "kP", /* Page up. */
221 "kri", "kR", /* Scroll up. */
222 "lines", "li", /* Terminal lines. */
223 "rmcup", "te", /* Terminal end string. */
224 "rmkx", "ke", /* Exit "keypad-transmit" mode. */
225 "rmso", "se", /* Standout end. */
226 "smcup", "ti", /* Terminal initialization string. */
227 "smkx", "ks", /* Enter "keypad-transmit" mode. */
228 "smso", "so", /* Standout begin. */
231 #ifdef _AIX
233 * AIX's implementation for function keys greater than 10 is different and
234 * only goes as far as 36.
236 static const char codes[] = {
237 /* 0-10 */ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ';',
238 /* 11-20 */ '<', '>', '!', '@', '#', '$', '%', '^', '&', '*',
239 /* 21-30 */ '(', ')', '-', '_', '+', ',', ':', '?', '[', ']',
240 /* 31-36 */ '{', '}', '|', '~', '/', '='
243 #else
246 * !!!
247 * Historically, the 4BSD termcap code didn't support functions keys greater
248 * than 9. This was silently enforced -- asking for key k12 would return the
249 * value for k1. We try and get around this by using the tables specified in
250 * the terminfo(TI_ENV) man page from the 3rd Edition SVID. This assumes the
251 * implementors of any System V compatibility code or an extended termcap used
252 * those codes.
254 static const char codes[] = {
255 /* 0-10 */ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ';',
256 /* 11-19 */ '1', '2', '3', '4', '5', '6', '7', '8', '9',
257 /* 20-63 */ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
258 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
259 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
260 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
262 #endif /* _AIX */
265 * lcmp --
266 * list comparison routine for bsearch.
268 static int
269 lcmp(a, b)
270 const void *a, *b;
272 return (strcmp(a, ((TL *)b)->terminfo));
276 * tigetstr --
278 * Vendors put the prototype for tigetstr into random include files, including
279 * <term.h>, which we can't include because it makes other systems unhappy.
280 * Try and work around the problem, since we only care about the return value.
282 * PUBLIC: #ifdef HAVE_CURSES_TIGETSTR
283 * PUBLIC: char *tigetstr();
284 * PUBLIC: #else
285 * PUBLIC: char *tigetstr __P((char *));
286 * PUBLIC: #endif
288 char *
289 tigetstr(name)
290 char *name;
292 static char sbuf[256];
293 TL *tlp;
294 int n;
295 char *p, keyname[3];
297 if ((tlp = bsearch(name,
298 list, sizeof(list) / sizeof(TL), sizeof(TL), lcmp)) == NULL) {
299 #ifdef _AIX
300 if (name[0] == 'k' &&
301 name[1] == 'f' && (n = atoi(name + 2)) <= 36) {
302 keyname[0] = 'k';
303 keyname[1] = codes[n];
304 keyname[2] = '\0';
305 #else
306 if (name[0] == 'k' &&
307 name[1] == 'f' && (n = atoi(name + 2)) <= 63) {
308 keyname[0] = n <= 10 ? 'k' : 'F';
309 keyname[1] = codes[n];
310 keyname[2] = '\0';
311 #endif
312 name = keyname;
314 } else
315 name = tlp->termcap;
317 p = sbuf;
318 #ifdef _AIX
319 return ((p = tgetstr(name, &p)) == NULL ? (char *)-1 : strcpy(sbuf, p));
320 #else
321 return (tgetstr(name, &p) == NULL ? (char *)-1 : sbuf);
322 #endif
326 * tigetnum --
328 * PUBLIC: #ifndef HAVE_CURSES_TIGETSTR
329 * PUBLIC: int tigetnum __P((char *));
330 * PUBLIC: #endif
333 tigetnum(name)
334 char *name;
336 TL *tlp;
337 int val;
339 if ((tlp = bsearch(name,
340 list, sizeof(list) / sizeof(TL), sizeof(TL), lcmp)) != NULL) {
341 name = tlp->termcap;
344 return ((val = tgetnum(name)) == -1 ? -2 : val);
346 #endif /* !HAVE_CURSES_TIGETSTR */