tty.c revision 1.7 1 /* $NetBSD: tty.c,v 1.7 1998/03/30 01:30:14 mrg Exp $ */
2
3 /*-
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Christos Zoulas of Cornell University.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 */
38
39 #include <sys/cdefs.h>
40 #if !defined(lint) && !defined(SCCSID)
41 #if 0
42 static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93";
43 #else
44 __RCSID("$NetBSD: tty.c,v 1.7 1998/03/30 01:30:14 mrg Exp $");
45 #endif
46 #endif /* not lint && not SCCSID */
47
48 /*
49 * tty.c: tty interface stuff
50 */
51 #include "sys.h"
52 #include "tty.h"
53 #include "el.h"
54
55 typedef struct ttymodes_t {
56 char *m_name;
57 u_int m_value;
58 int m_type;
59 } ttymodes_t;
60
61 typedef struct ttymap_t {
62 int nch, och; /* Internal and termio rep of chars */
63 el_action_t bind[3]; /* emacs, vi, and vi-cmd */
64 } ttymap_t;
65
66
67 private ttyperm_t ttyperm = {
68 {
69 { "iflag:", ICRNL, (INLCR|IGNCR) },
70 { "oflag:", (OPOST|ONLCR), ONLRET },
71 { "cflag:", 0, 0 },
72 { "lflag:", (ISIG|ICANON|ECHO|ECHOE|ECHOCTL|IEXTEN),
73 (NOFLSH|ECHONL|EXTPROC|FLUSHO) },
74 { "chars:", 0, 0 },
75 },
76 {
77 { "iflag:", (INLCR|ICRNL), IGNCR },
78 { "oflag:", (OPOST|ONLCR), ONLRET },
79 { "cflag:", 0, 0 },
80 { "lflag:", ISIG,
81 (NOFLSH|ICANON|ECHO|ECHOK|ECHONL|EXTPROC|IEXTEN|FLUSHO) },
82 { "chars:", (C_SH(C_MIN)|C_SH(C_TIME)|C_SH(C_SWTCH)|C_SH(C_DSWTCH)|
83 C_SH(C_SUSP)|C_SH(C_DSUSP)|C_SH(C_EOL)|C_SH(C_DISCARD)|
84 C_SH(C_PGOFF)|C_SH(C_PAGE)|C_SH(C_STATUS)), 0 }
85 },
86 {
87 { "iflag:", 0, IXON | IXOFF },
88 { "oflag:", 0, 0 },
89 { "cflag:", 0, 0 },
90 { "lflag:", 0, ISIG | IEXTEN },
91 { "chars:", 0, 0 },
92 }
93 };
94
95 private ttychar_t ttychar = {
96 {
97 CINTR, CQUIT, CERASE, CKILL,
98 CEOF, CEOL, CEOL2, CSWTCH,
99 CDSWTCH, CERASE2, CSTART, CSTOP,
100 CWERASE, CSUSP, CDSUSP, CREPRINT,
101 CDISCARD, CLNEXT, CSTATUS, CPAGE,
102 CPGOFF, CKILL2, CBRK, CMIN,
103 CTIME
104 },
105 {
106 CINTR, CQUIT, CERASE, CKILL,
107 _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
108 _POSIX_VDISABLE, CERASE2, CSTART, CSTOP,
109 _POSIX_VDISABLE, CSUSP, _POSIX_VDISABLE, _POSIX_VDISABLE,
110 CDISCARD, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
111 _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1,
112 0
113 },
114 {
115 0, 0, 0, 0,
116 0, 0, 0, 0,
117 0, 0, 0, 0,
118 0, 0, 0, 0,
119 0, 0, 0, 0,
120 0, 0, 0, 0,
121 0
122 }
123 };
124
125 private ttymap_t tty_map[] = {
126 #ifdef VERASE
127 { C_ERASE, VERASE,
128 { ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR } },
129 #endif /* VERASE */
130 #ifdef VERASE2
131 { C_ERASE2, VERASE2,
132 { ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR } },
133 #endif /* VERASE2 */
134 #ifdef VKILL
135 { C_KILL, VKILL,
136 { EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED } },
137 #endif /* VKILL */
138 #ifdef VKILL2
139 { C_KILL2, VKILL2,
140 { EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED } },
141 #endif /* VKILL2 */
142 #ifdef VEOF
143 { C_EOF, VEOF,
144 { EM_DELETE_OR_LIST, VI_LIST_OR_EOF, ED_UNASSIGNED } },
145 #endif /* VEOF */
146 #ifdef VWERASE
147 { C_WERASE, VWERASE,
148 { ED_DELETE_PREV_WORD, ED_DELETE_PREV_WORD, ED_PREV_WORD } },
149 #endif /* VWERASE */
150 #ifdef VREPRINT
151 { C_REPRINT, VREPRINT,
152 { ED_REDISPLAY, ED_INSERT, ED_REDISPLAY } },
153 #endif /* VREPRINT */
154 #ifdef VLNEXT
155 { C_LNEXT, VLNEXT,
156 { ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED } },
157 #endif /* VLNEXT */
158 { -1, -1,
159 { ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED } }
160 };
161
162 private ttymodes_t ttymodes[] = {
163 # ifdef IGNBRK
164 { "ignbrk", IGNBRK, M_INP },
165 # endif /* IGNBRK */
166 # ifdef BRKINT
167 { "brkint", BRKINT, M_INP },
168 # endif /* BRKINT */
169 # ifdef IGNPAR
170 { "ignpar", IGNPAR, M_INP },
171 # endif /* IGNPAR */
172 # ifdef PARMRK
173 { "parmrk", PARMRK, M_INP },
174 # endif /* PARMRK */
175 # ifdef INPCK
176 { "inpck", INPCK, M_INP },
177 # endif /* INPCK */
178 # ifdef ISTRIP
179 { "istrip", ISTRIP, M_INP },
180 # endif /* ISTRIP */
181 # ifdef INLCR
182 { "inlcr", INLCR, M_INP },
183 # endif /* INLCR */
184 # ifdef IGNCR
185 { "igncr", IGNCR, M_INP },
186 # endif /* IGNCR */
187 # ifdef ICRNL
188 { "icrnl", ICRNL, M_INP },
189 # endif /* ICRNL */
190 # ifdef IUCLC
191 { "iuclc", IUCLC, M_INP },
192 # endif /* IUCLC */
193 # ifdef IXON
194 { "ixon", IXON, M_INP },
195 # endif /* IXON */
196 # ifdef IXANY
197 { "ixany", IXANY, M_INP },
198 # endif /* IXANY */
199 # ifdef IXOFF
200 { "ixoff", IXOFF, M_INP },
201 # endif /* IXOFF */
202 # ifdef IMAXBEL
203 { "imaxbel",IMAXBEL,M_INP },
204 # endif /* IMAXBEL */
205
206 # ifdef OPOST
207 { "opost", OPOST, M_OUT },
208 # endif /* OPOST */
209 # ifdef OLCUC
210 { "olcuc", OLCUC, M_OUT },
211 # endif /* OLCUC */
212 # ifdef ONLCR
213 { "onlcr", ONLCR, M_OUT },
214 # endif /* ONLCR */
215 # ifdef OCRNL
216 { "ocrnl", OCRNL, M_OUT },
217 # endif /* OCRNL */
218 # ifdef ONOCR
219 { "onocr", ONOCR, M_OUT },
220 # endif /* ONOCR */
221 # ifdef ONOEOT
222 { "onoeot", ONOEOT, M_OUT },
223 # endif /* ONOEOT */
224 # ifdef ONLRET
225 { "onlret", ONLRET, M_OUT },
226 # endif /* ONLRET */
227 # ifdef OFILL
228 { "ofill", OFILL, M_OUT },
229 # endif /* OFILL */
230 # ifdef OFDEL
231 { "ofdel", OFDEL, M_OUT },
232 # endif /* OFDEL */
233 # ifdef NLDLY
234 { "nldly", NLDLY, M_OUT },
235 # endif /* NLDLY */
236 # ifdef CRDLY
237 { "crdly", CRDLY, M_OUT },
238 # endif /* CRDLY */
239 # ifdef TABDLY
240 { "tabdly", TABDLY, M_OUT },
241 # endif /* TABDLY */
242 # ifdef XTABS
243 { "xtabs", XTABS, M_OUT },
244 # endif /* XTABS */
245 # ifdef BSDLY
246 { "bsdly", BSDLY, M_OUT },
247 # endif /* BSDLY */
248 # ifdef VTDLY
249 { "vtdly", VTDLY, M_OUT },
250 # endif /* VTDLY */
251 # ifdef FFDLY
252 { "ffdly", FFDLY, M_OUT },
253 # endif /* FFDLY */
254 # ifdef PAGEOUT
255 { "pageout",PAGEOUT,M_OUT },
256 # endif /* PAGEOUT */
257 # ifdef WRAP
258 { "wrap", WRAP, M_OUT },
259 # endif /* WRAP */
260
261 # ifdef CIGNORE
262 { "cignore",CIGNORE,M_CTL },
263 # endif /* CBAUD */
264 # ifdef CBAUD
265 { "cbaud", CBAUD, M_CTL },
266 # endif /* CBAUD */
267 # ifdef CSTOPB
268 { "cstopb", CSTOPB, M_CTL },
269 # endif /* CSTOPB */
270 # ifdef CREAD
271 { "cread", CREAD, M_CTL },
272 # endif /* CREAD */
273 # ifdef PARENB
274 { "parenb", PARENB, M_CTL },
275 # endif /* PARENB */
276 # ifdef PARODD
277 { "parodd", PARODD, M_CTL },
278 # endif /* PARODD */
279 # ifdef HUPCL
280 { "hupcl", HUPCL, M_CTL },
281 # endif /* HUPCL */
282 # ifdef CLOCAL
283 { "clocal", CLOCAL, M_CTL },
284 # endif /* CLOCAL */
285 # ifdef LOBLK
286 { "loblk", LOBLK, M_CTL },
287 # endif /* LOBLK */
288 # ifdef CIBAUD
289 { "cibaud", CIBAUD, M_CTL },
290 # endif /* CIBAUD */
291 # ifdef CRTSCTS
292 # ifdef CCTS_OFLOW
293 { "ccts_oflow",CCTS_OFLOW,M_CTL },
294 # else
295 { "crtscts",CRTSCTS,M_CTL },
296 # endif /* CCTS_OFLOW */
297 # endif /* CRTSCTS */
298 # ifdef CRTS_IFLOW
299 { "crts_iflow",CRTS_IFLOW,M_CTL },
300 # endif /* CRTS_IFLOW */
301 # ifdef CDTRCTS
302 { "cdtrcts",CDTRCTS,M_CTL },
303 # endif /* CDTRCTS */
304 # ifdef MDMBUF
305 { "mdmbuf", MDMBUF, M_CTL },
306 # endif /* MDMBUF */
307 # ifdef RCV1EN
308 { "rcv1en", RCV1EN, M_CTL },
309 # endif /* RCV1EN */
310 # ifdef XMT1EN
311 { "xmt1en", XMT1EN, M_CTL },
312 # endif /* XMT1EN */
313
314 # ifdef ISIG
315 { "isig", ISIG, M_LIN },
316 # endif /* ISIG */
317 # ifdef ICANON
318 { "icanon", ICANON, M_LIN },
319 # endif /* ICANON */
320 # ifdef XCASE
321 { "xcase", XCASE, M_LIN },
322 # endif /* XCASE */
323 # ifdef ECHO
324 { "echo", ECHO, M_LIN },
325 # endif /* ECHO */
326 # ifdef ECHOE
327 { "echoe", ECHOE, M_LIN },
328 # endif /* ECHOE */
329 # ifdef ECHOK
330 { "echok", ECHOK, M_LIN },
331 # endif /* ECHOK */
332 # ifdef ECHONL
333 { "echonl", ECHONL, M_LIN },
334 # endif /* ECHONL */
335 # ifdef NOFLSH
336 { "noflsh", NOFLSH, M_LIN },
337 # endif /* NOFLSH */
338 # ifdef TOSTOP
339 { "tostop", TOSTOP, M_LIN },
340 # endif /* TOSTOP */
341 # ifdef ECHOCTL
342 { "echoctl",ECHOCTL,M_LIN },
343 # endif /* ECHOCTL */
344 # ifdef ECHOPRT
345 { "echoprt",ECHOPRT,M_LIN },
346 # endif /* ECHOPRT */
347 # ifdef ECHOKE
348 { "echoke", ECHOKE, M_LIN },
349 # endif /* ECHOKE */
350 # ifdef DEFECHO
351 { "defecho",DEFECHO,M_LIN },
352 # endif /* DEFECHO */
353 # ifdef FLUSHO
354 { "flusho", FLUSHO, M_LIN },
355 # endif /* FLUSHO */
356 # ifdef PENDIN
357 { "pendin", PENDIN, M_LIN },
358 # endif /* PENDIN */
359 # ifdef IEXTEN
360 { "iexten", IEXTEN, M_LIN },
361 # endif /* IEXTEN */
362 # ifdef NOKERNINFO
363 { "nokerninfo",NOKERNINFO,M_LIN },
364 # endif /* NOKERNINFO */
365 # ifdef ALTWERASE
366 { "altwerase",ALTWERASE,M_LIN },
367 # endif /* ALTWERASE */
368 # ifdef EXTPROC
369 { "extproc",EXTPROC, M_LIN },
370 # endif /* EXTPROC */
371
372 # if defined(VINTR)
373 { "intr", C_SH(C_INTR), M_CHAR },
374 # endif /* VINTR */
375 # if defined(VQUIT)
376 { "quit", C_SH(C_QUIT), M_CHAR },
377 # endif /* VQUIT */
378 # if defined(VERASE)
379 { "erase", C_SH(C_ERASE), M_CHAR },
380 # endif /* VERASE */
381 # if defined(VKILL)
382 { "kill", C_SH(C_KILL), M_CHAR },
383 # endif /* VKILL */
384 # if defined(VEOF)
385 { "eof", C_SH(C_EOF), M_CHAR },
386 # endif /* VEOF */
387 # if defined(VEOL)
388 { "eol", C_SH(C_EOL), M_CHAR },
389 # endif /* VEOL */
390 # if defined(VEOL2)
391 { "eol2", C_SH(C_EOL2), M_CHAR },
392 # endif /* VEOL2 */
393 # if defined(VSWTCH)
394 { "swtch", C_SH(C_SWTCH), M_CHAR },
395 # endif /* VSWTCH */
396 # if defined(VDSWTCH)
397 { "dswtch", C_SH(C_DSWTCH), M_CHAR },
398 # endif /* VDSWTCH */
399 # if defined(VERASE2)
400 { "erase2", C_SH(C_ERASE2), M_CHAR },
401 # endif /* VERASE2 */
402 # if defined(VSTART)
403 { "start", C_SH(C_START), M_CHAR },
404 # endif /* VSTART */
405 # if defined(VSTOP)
406 { "stop", C_SH(C_STOP), M_CHAR },
407 # endif /* VSTOP */
408 # if defined(VWERASE)
409 { "werase", C_SH(C_WERASE), M_CHAR },
410 # endif /* VWERASE */
411 # if defined(VSUSP)
412 { "susp", C_SH(C_SUSP), M_CHAR },
413 # endif /* VSUSP */
414 # if defined(VDSUSP)
415 { "dsusp", C_SH(C_DSUSP), M_CHAR },
416 # endif /* VDSUSP */
417 # if defined(VREPRINT)
418 { "reprint", C_SH(C_REPRINT),M_CHAR },
419 # endif /* VREPRINT */
420 # if defined(VDISCARD)
421 { "discard", C_SH(C_DISCARD),M_CHAR },
422 # endif /* VDISCARD */
423 # if defined(VLNEXT)
424 { "lnext", C_SH(C_LNEXT), M_CHAR },
425 # endif /* VLNEXT */
426 # if defined(VSTATUS)
427 { "status", C_SH(C_STATUS), M_CHAR },
428 # endif /* VSTATUS */
429 # if defined(VPAGE)
430 { "page", C_SH(C_PAGE), M_CHAR },
431 # endif /* VPAGE */
432 # if defined(VPGOFF)
433 { "pgoff", C_SH(C_PGOFF), M_CHAR },
434 # endif /* VPGOFF */
435 # if defined(VKILL2)
436 { "kill2", C_SH(C_KILL2), M_CHAR },
437 # endif /* VKILL2 */
438 # if defined(VBRK)
439 { "brk", C_SH(C_BRK), M_CHAR },
440 # endif /* VBRK */
441 # if defined(VMIN)
442 { "min", C_SH(C_MIN), M_CHAR },
443 # endif /* VMIN */
444 # if defined(VTIME)
445 { "time", C_SH(C_TIME), M_CHAR },
446 # endif /* VTIME */
447 { NULL, 0, -1 },
448 };
449
450
451
452 #define tty_getty(el, td) tcgetattr((el)->el_infd, (td))
453 #define tty_setty(el, td) tcsetattr((el)->el_infd, TCSADRAIN, (td))
454
455 #define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1)
456 #define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8)
457 #define tty__cooked_mode(td) ((td)->c_lflag & ICANON)
458
459 private void tty__getchar __P((struct termios *, unsigned char *));
460 private void tty__setchar __P((struct termios *, unsigned char *));
461 private speed_t tty__getspeed __P((struct termios *));
462 private int tty_setup __P((EditLine *));
463
464 #define t_qu t_ts
465
466
467 /* tty_setup():
468 * Get the tty parameters and initialize the editing state
469 */
470 private int
471 tty_setup(el)
472 EditLine *el;
473 {
474 int rst = 1;
475 if (tty_getty(el, &el->el_tty.t_ed) == -1) {
476 #ifdef DEBUG_TTY
477 (void) fprintf(el->el_errfile,
478 "tty_setup: tty_getty: %s\n", strerror(errno));
479 #endif /* DEBUG_TTY */
480 return(-1);
481 }
482 el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed;
483
484 el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex);
485 el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex);
486 el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex);
487
488 el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][M_INP].t_clrmask;
489 el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][M_INP].t_setmask;
490
491 el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][M_OUT].t_clrmask;
492 el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][M_OUT].t_setmask;
493
494 el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][M_CTL].t_clrmask;
495 el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][M_CTL].t_setmask;
496
497 el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][M_LIN].t_clrmask;
498 el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][M_LIN].t_setmask;
499
500 /*
501 * Reset the tty chars to reasonable defaults
502 * If they are disabled, then enable them.
503 */
504 if (rst) {
505 if (tty__cooked_mode(&el->el_tty.t_ts)) {
506 tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
507 /*
508 * Don't affect CMIN and CTIME for the editor mode
509 */
510 for (rst = 0; rst < C_NCC - 2; rst++)
511 if (el->el_tty.t_c[TS_IO][rst] != el->el_tty.t_vdisable &&
512 el->el_tty.t_c[ED_IO][rst] != el->el_tty.t_vdisable)
513 el->el_tty.t_c[ED_IO][rst] = el->el_tty.t_c[TS_IO][rst];
514 for (rst = 0; rst < C_NCC; rst++)
515 if (el->el_tty.t_c[TS_IO][rst] != el->el_tty.t_vdisable)
516 el->el_tty.t_c[EX_IO][rst] = el->el_tty.t_c[TS_IO][rst];
517 }
518 tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
519 if (tty_setty(el, &el->el_tty.t_ex) == -1) {
520 #ifdef DEBUG_TTY
521 (void) fprintf(el->el_errfile, "tty_setup: tty_setty: %s\n",
522 strerror(errno));
523 #endif /* DEBUG_TTY */
524 return(-1);
525 }
526 }
527 else
528 tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
529
530 el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][M_INP].t_clrmask;
531 el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][M_INP].t_setmask;
532
533 el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][M_OUT].t_clrmask;
534 el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][M_OUT].t_setmask;
535
536 el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][M_CTL].t_clrmask;
537 el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][M_CTL].t_setmask;
538
539 el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][M_LIN].t_clrmask;
540 el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][M_LIN].t_setmask;
541
542 tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
543 return 0;
544 }
545
546 protected int
547 tty_init(el)
548 EditLine *el;
549 {
550 el->el_tty.t_mode = EX_IO;
551 el->el_tty.t_vdisable = _POSIX_VDISABLE;
552 (void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t));
553 (void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t));
554 return tty_setup(el);
555 } /* end tty_init */
556
557
558 /* tty_end():
559 * Restore the tty to its original settings
560 */
561 protected void
562 /*ARGSUSED*/
563 tty_end(el)
564 EditLine *el;
565 {
566 /* XXX: Maybe reset to an initial state? */
567 }
568
569
570 /* tty__getspeed():
571 * Get the tty speed
572 */
573 private speed_t
574 tty__getspeed(td)
575 struct termios *td;
576 {
577 speed_t spd;
578
579 if ((spd = cfgetispeed(td)) == 0)
580 spd = cfgetospeed(td);
581 return spd;
582 } /* end tty__getspeed */
583
584
585 /* tty__getchar():
586 * Get the tty characters
587 */
588 private void
589 tty__getchar(td, s)
590 struct termios *td;
591 unsigned char *s;
592 {
593 # ifdef VINTR
594 s[C_INTR] = td->c_cc[VINTR];
595 # endif /* VINTR */
596 # ifdef VQUIT
597 s[C_QUIT] = td->c_cc[VQUIT];
598 # endif /* VQUIT */
599 # ifdef VERASE
600 s[C_ERASE] = td->c_cc[VERASE];
601 # endif /* VERASE */
602 # ifdef VKILL
603 s[C_KILL] = td->c_cc[VKILL];
604 # endif /* VKILL */
605 # ifdef VEOF
606 s[C_EOF] = td->c_cc[VEOF];
607 # endif /* VEOF */
608 # ifdef VEOL
609 s[C_EOL] = td->c_cc[VEOL];
610 # endif /* VEOL */
611 # ifdef VEOL2
612 s[C_EOL2] = td->c_cc[VEOL2];
613 # endif /* VEOL2 */
614 # ifdef VSWTCH
615 s[C_SWTCH] = td->c_cc[VSWTCH];
616 # endif /* VSWTCH */
617 # ifdef VDSWTCH
618 s[C_DSWTCH] = td->c_cc[VDSWTCH];
619 # endif /* VDSWTCH */
620 # ifdef VERASE2
621 s[C_ERASE2] = td->c_cc[VERASE2];
622 # endif /* VERASE2 */
623 # ifdef VSTART
624 s[C_START] = td->c_cc[VSTART];
625 # endif /* VSTART */
626 # ifdef VSTOP
627 s[C_STOP] = td->c_cc[VSTOP];
628 # endif /* VSTOP */
629 # ifdef VWERASE
630 s[C_WERASE] = td->c_cc[VWERASE];
631 # endif /* VWERASE */
632 # ifdef VSUSP
633 s[C_SUSP] = td->c_cc[VSUSP];
634 # endif /* VSUSP */
635 # ifdef VDSUSP
636 s[C_DSUSP] = td->c_cc[VDSUSP];
637 # endif /* VDSUSP */
638 # ifdef VREPRINT
639 s[C_REPRINT]= td->c_cc[VREPRINT];
640 # endif /* VREPRINT */
641 # ifdef VDISCARD
642 s[C_DISCARD]= td->c_cc[VDISCARD];
643 # endif /* VDISCARD */
644 # ifdef VLNEXT
645 s[C_LNEXT] = td->c_cc[VLNEXT];
646 # endif /* VLNEXT */
647 # ifdef VSTATUS
648 s[C_STATUS] = td->c_cc[VSTATUS];
649 # endif /* VSTATUS */
650 # ifdef VPAGE
651 s[C_PAGE] = td->c_cc[VPAGE];
652 # endif /* VPAGE */
653 # ifdef VPGOFF
654 s[C_PGOFF] = td->c_cc[VPGOFF];
655 # endif /* VPGOFF */
656 # ifdef VKILL2
657 s[C_KILL2] = td->c_cc[VKILL2];
658 # endif /* KILL2 */
659 # ifdef VMIN
660 s[C_MIN] = td->c_cc[VMIN];
661 # endif /* VMIN */
662 # ifdef VTIME
663 s[C_TIME] = td->c_cc[VTIME];
664 # endif /* VTIME */
665 } /* tty__getchar */
666
667
668 /* tty__setchar():
669 * Set the tty characters
670 */
671 private void
672 tty__setchar(td, s)
673 struct termios *td;
674 unsigned char *s;
675 {
676 # ifdef VINTR
677 td->c_cc[VINTR] = s[C_INTR];
678 # endif /* VINTR */
679 # ifdef VQUIT
680 td->c_cc[VQUIT] = s[C_QUIT];
681 # endif /* VQUIT */
682 # ifdef VERASE
683 td->c_cc[VERASE] = s[C_ERASE];
684 # endif /* VERASE */
685 # ifdef VKILL
686 td->c_cc[VKILL] = s[C_KILL];
687 # endif /* VKILL */
688 # ifdef VEOF
689 td->c_cc[VEOF] = s[C_EOF];
690 # endif /* VEOF */
691 # ifdef VEOL
692 td->c_cc[VEOL] = s[C_EOL];
693 # endif /* VEOL */
694 # ifdef VEOL2
695 td->c_cc[VEOL2] = s[C_EOL2];
696 # endif /* VEOL2 */
697 # ifdef VSWTCH
698 td->c_cc[VSWTCH] = s[C_SWTCH];
699 # endif /* VSWTCH */
700 # ifdef VDSWTCH
701 td->c_cc[VDSWTCH] = s[C_DSWTCH];
702 # endif /* VDSWTCH */
703 # ifdef VERASE2
704 td->c_cc[VERASE2] = s[C_ERASE2];
705 # endif /* VERASE2 */
706 # ifdef VSTART
707 td->c_cc[VSTART] = s[C_START];
708 # endif /* VSTART */
709 # ifdef VSTOP
710 td->c_cc[VSTOP] = s[C_STOP];
711 # endif /* VSTOP */
712 # ifdef VWERASE
713 td->c_cc[VWERASE] = s[C_WERASE];
714 # endif /* VWERASE */
715 # ifdef VSUSP
716 td->c_cc[VSUSP] = s[C_SUSP];
717 # endif /* VSUSP */
718 # ifdef VDSUSP
719 td->c_cc[VDSUSP] = s[C_DSUSP];
720 # endif /* VDSUSP */
721 # ifdef VREPRINT
722 td->c_cc[VREPRINT] = s[C_REPRINT];
723 # endif /* VREPRINT */
724 # ifdef VDISCARD
725 td->c_cc[VDISCARD] = s[C_DISCARD];
726 # endif /* VDISCARD */
727 # ifdef VLNEXT
728 td->c_cc[VLNEXT] = s[C_LNEXT];
729 # endif /* VLNEXT */
730 # ifdef VSTATUS
731 td->c_cc[VSTATUS] = s[C_STATUS];
732 # endif /* VSTATUS */
733 # ifdef VPAGE
734 td->c_cc[VPAGE] = s[C_PAGE];
735 # endif /* VPAGE */
736 # ifdef VPGOFF
737 td->c_cc[VPGOFF] = s[C_PGOFF];
738 # endif /* VPGOFF */
739 # ifdef VKILL2
740 td->c_cc[VKILL2] = s[C_KILL2];
741 # endif /* VKILL2 */
742 # ifdef VMIN
743 td->c_cc[VMIN] = s[C_MIN];
744 # endif /* VMIN */
745 # ifdef VTIME
746 td->c_cc[VTIME] = s[C_TIME];
747 # endif /* VTIME */
748 } /* tty__setchar */
749
750
751 /* tty_bind_char():
752 * Rebind the editline functions
753 */
754 protected void
755 tty_bind_char(el, force)
756 EditLine *el;
757 int force;
758 {
759 unsigned char *t_n = el->el_tty.t_c[ED_IO];
760 unsigned char *t_o = el->el_tty.t_ed.c_cc;
761 char new[2], old[2];
762 ttymap_t *tp;
763 el_action_t *dmap, *dalt, *map, *alt;
764 new[1] = old[1] = '\0';
765
766
767 map = el->el_map.key;
768 alt = el->el_map.alt;
769 if (el->el_map.type == MAP_VI) {
770 dmap = el->el_map.vii;
771 dalt = el->el_map.vic;
772 }
773 else {
774 dmap = el->el_map.emacs;
775 dalt = NULL;
776 }
777
778 for (tp = tty_map; tp->nch != -1; tp++) {
779 new[0] = t_n[tp->nch];
780 old[0] = t_o[tp->och];
781 if (new[0] == old[0] && !force)
782 continue;
783 /* Put the old default binding back, and set the new binding */
784 key_clear(el, map, old);
785 map[(int)old[0]] = dmap[(int)old[0]];
786 key_clear(el, map, new);
787 /* MAP_VI == 1, MAP_EMACS == 0... */
788 map[(int)new[0]] = tp->bind[(int)el->el_map.type];
789 if (dalt) {
790 key_clear(el, alt, old);
791 alt[(int)old[0]] = dalt[(int)old[0]];
792 key_clear(el, alt, new);
793 alt[(int)new[0]] = tp->bind[(int)el->el_map.type+1];
794 }
795 }
796 }
797
798 /* tty_rawmode():
799 * Set terminal into 1 character at a time mode.
800 */
801 protected int
802 tty_rawmode(el)
803 EditLine *el;
804 {
805 if (el->el_tty.t_mode == ED_IO)
806 return (0);
807
808 if (tty_getty(el, &el->el_tty.t_ts) == -1) {
809 #ifdef DEBUG_TTY
810 (void) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\n", strerror(errno));
811 #endif /* DEBUG_TTY */
812 return(-1);
813 }
814
815 /*
816 * We always keep up with the eight bit setting and the speed of the
817 * tty. But only we only believe changes that are made to cooked mode!
818 */
819 el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts);
820 el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts);
821
822 if (tty__getspeed(&el->el_tty.t_ex) != el->el_tty.t_speed ||
823 tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) {
824 (void) cfsetispeed(&el->el_tty.t_ex, el->el_tty.t_speed);
825 (void) cfsetospeed(&el->el_tty.t_ex, el->el_tty.t_speed);
826 (void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed);
827 (void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed);
828 }
829
830 if (tty__cooked_mode(&el->el_tty.t_ts)) {
831 if (el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) {
832 el->el_tty.t_ex.c_cflag = el->el_tty.t_ts.c_cflag;
833 el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][M_CTL].t_clrmask;
834 el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][M_CTL].t_setmask;
835
836 el->el_tty.t_ed.c_cflag = el->el_tty.t_ts.c_cflag;
837 el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][M_CTL].t_clrmask;
838 el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][M_CTL].t_setmask;
839 }
840
841 if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) &&
842 (el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) {
843 el->el_tty.t_ex.c_lflag = el->el_tty.t_ts.c_lflag;
844 el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][M_LIN].t_clrmask;
845 el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][M_LIN].t_setmask;
846
847 el->el_tty.t_ed.c_lflag = el->el_tty.t_ts.c_lflag;
848 el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][M_LIN].t_clrmask;
849 el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][M_LIN].t_setmask;
850 }
851
852 if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) &&
853 (el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) {
854 el->el_tty.t_ex.c_iflag = el->el_tty.t_ts.c_iflag;
855 el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][M_INP].t_clrmask;
856 el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][M_INP].t_setmask;
857
858 el->el_tty.t_ed.c_iflag = el->el_tty.t_ts.c_iflag;
859 el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][M_INP].t_clrmask;
860 el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][M_INP].t_setmask;
861 }
862
863 if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) &&
864 (el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) {
865 el->el_tty.t_ex.c_oflag = el->el_tty.t_ts.c_oflag;
866 el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][M_OUT].t_clrmask;
867 el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][M_OUT].t_setmask;
868
869 el->el_tty.t_ed.c_oflag = el->el_tty.t_ts.c_oflag;
870 el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][M_OUT].t_clrmask;
871 el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][M_OUT].t_setmask;
872 }
873
874 if (tty__gettabs(&el->el_tty.t_ex) == 0)
875 el->el_tty.t_tabs = 0;
876 else
877 el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0;
878
879 {
880 int i;
881
882 tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
883 /*
884 * Check if the user made any changes.
885 * If he did, then propagate the changes to the
886 * edit and execute data structures.
887 */
888 for (i = 0; i < C_NCC; i++)
889 if (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i])
890 break;
891
892 if (i != C_NCC) {
893 /*
894 * Propagate changes only to the unprotected chars
895 * that have been modified just now.
896 */
897 for (i = 0; i < C_NCC; i++) {
898 if (!((el->el_tty.t_t[ED_IO][M_CHAR].t_setmask & C_SH(i)))
899 && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
900 el->el_tty.t_c[ED_IO][i] = el->el_tty.t_c[TS_IO][i];
901 if (el->el_tty.t_t[ED_IO][M_CHAR].t_clrmask & C_SH(i))
902 el->el_tty.t_c[ED_IO][i] = el->el_tty.t_vdisable;
903 }
904 tty_bind_char(el, 0);
905 tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
906
907 for (i = 0; i < C_NCC; i++) {
908 if (!((el->el_tty.t_t[EX_IO][M_CHAR].t_setmask & C_SH(i)))
909 && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
910 el->el_tty.t_c[EX_IO][i] = el->el_tty.t_c[TS_IO][i];
911 if (el->el_tty.t_t[EX_IO][M_CHAR].t_clrmask & C_SH(i))
912 el->el_tty.t_c[EX_IO][i] = el->el_tty.t_vdisable;
913 }
914 tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
915 }
916 }
917 }
918
919 if (tty_setty(el, &el->el_tty.t_ed) == -1) {
920 #ifdef DEBUG_TTY
921 (void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n",
922 strerror(errno));
923 #endif /* DEBUG_TTY */
924 return -1;
925 }
926 el->el_tty.t_mode = ED_IO;
927 return (0);
928 } /* end tty_rawmode */
929
930
931 /* tty_cookedmode():
932 * Set the tty back to normal mode
933 */
934 protected int
935 tty_cookedmode(el)
936 EditLine *el;
937 { /* set tty in normal setup */
938 if (el->el_tty.t_mode == EX_IO)
939 return (0);
940
941 if (tty_setty(el, &el->el_tty.t_ex) == -1) {
942 #ifdef DEBUG_TTY
943 (void) fprintf(el->el_errfile, "tty_cookedmode: tty_setty: %s\n",
944 strerror(errno));
945 #endif /* DEBUG_TTY */
946 return -1;
947 }
948 el->el_tty.t_mode = EX_IO;
949 return (0);
950 } /* end tty_cookedmode */
951
952
953 /* tty_quotemode():
954 * Turn on quote mode
955 */
956 protected int
957 tty_quotemode(el)
958 EditLine *el;
959 {
960 if (el->el_tty.t_mode == QU_IO)
961 return 0;
962
963 el->el_tty.t_qu = el->el_tty.t_ed;
964
965 el->el_tty.t_qu.c_iflag &= ~el->el_tty.t_t[QU_IO][M_INP].t_clrmask;
966 el->el_tty.t_qu.c_iflag |= el->el_tty.t_t[QU_IO][M_INP].t_setmask;
967
968 el->el_tty.t_qu.c_oflag &= ~el->el_tty.t_t[QU_IO][M_OUT].t_clrmask;
969 el->el_tty.t_qu.c_oflag |= el->el_tty.t_t[QU_IO][M_OUT].t_setmask;
970
971 el->el_tty.t_qu.c_cflag &= ~el->el_tty.t_t[QU_IO][M_CTL].t_clrmask;
972 el->el_tty.t_qu.c_cflag |= el->el_tty.t_t[QU_IO][M_CTL].t_setmask;
973
974 el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][M_LIN].t_clrmask;
975 el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][M_LIN].t_setmask;
976
977 if (tty_setty(el, &el->el_tty.t_qu) == -1) {
978 #ifdef DEBUG_TTY
979 (void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n",
980 strerror(errno));
981 #endif /* DEBUG_TTY */
982 return -1;
983 }
984 el->el_tty.t_mode = QU_IO;
985 return 0;
986 } /* end tty_quotemode */
987
988
989 /* tty_noquotemode():
990 * Turn off quote mode
991 */
992 protected int
993 tty_noquotemode(el)
994 EditLine *el;
995 {
996 if (el->el_tty.t_mode != QU_IO)
997 return 0;
998 if (tty_setty(el, &el->el_tty.t_ed) == -1) {
999 #ifdef DEBUG_TTY
1000 (void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n",
1001 strerror(errno));
1002 #endif /* DEBUG_TTY */
1003 return -1;
1004 }
1005 el->el_tty.t_mode = ED_IO;
1006 return 0;
1007 }
1008
1009 /* tty_stty():
1010 * Stty builtin
1011 */
1012 protected int
1013 /*ARGSUSED*/
1014 tty_stty(el, argc, argv)
1015 EditLine *el;
1016 int argc;
1017 char **argv;
1018 {
1019 ttymodes_t *m;
1020 char x, *d;
1021 int aflag = 0;
1022 char *s;
1023 char *name;
1024 int z = EX_IO;
1025
1026 if (argv == NULL)
1027 return -1;
1028 name = *argv++;
1029
1030 while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0')
1031 switch (argv[0][1]) {
1032 case 'a':
1033 aflag++;
1034 argv++;
1035 break;
1036 case 'd':
1037 argv++;
1038 z = ED_IO;
1039 break;
1040 case 'x':
1041 argv++;
1042 z = EX_IO;
1043 break;
1044 case 'q':
1045 argv++;
1046 z = QU_IO;
1047 break;
1048 default:
1049 (void) fprintf(el->el_errfile, "%s: Unknown switch `%c'.\n",
1050 name, argv[0][1]);
1051 return -1;
1052 }
1053
1054 if (!argv || !*argv) {
1055 int i = -1;
1056 int len = 0, st = 0, cu;
1057 for (m = ttymodes; m->m_name; m++) {
1058 if (m->m_type != i) {
1059 (void) fprintf(el->el_outfile, "%s%s", i != -1 ? "\n" : "",
1060 el->el_tty.t_t[z][m->m_type].t_name);
1061 i = m->m_type;
1062 st = len = strlen(el->el_tty.t_t[z][m->m_type].t_name);
1063 }
1064
1065 x = (el->el_tty.t_t[z][i].t_setmask & m->m_value) ? '+' : '\0';
1066 x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value) ? '-' : x;
1067
1068 if (x != '\0' || aflag) {
1069
1070 cu = strlen(m->m_name) + (x != '\0') + 1;
1071
1072 if (len + cu >= el->el_term.t_size.h) {
1073 (void) fprintf(el->el_outfile, "\n%*s", st, "");
1074 len = st + cu;
1075 }
1076 else
1077 len += cu;
1078
1079 if (x != '\0')
1080 (void) fprintf(el->el_outfile, "%c%s ", x, m->m_name);
1081 else
1082 (void) fprintf(el->el_outfile, "%s ", m->m_name);
1083 }
1084 }
1085 (void) fprintf(el->el_outfile, "\n");
1086 return 0;
1087 }
1088
1089 while (argv && (s = *argv++)) {
1090 switch (*s) {
1091 case '+':
1092 case '-':
1093 x = *s++;
1094 break;
1095 default:
1096 x = '\0';
1097 break;
1098 }
1099 d = s;
1100 for (m = ttymodes; m->m_name; m++)
1101 if (strcmp(m->m_name, d) == 0)
1102 break;
1103
1104 if (!m->m_name) {
1105 (void) fprintf(el->el_errfile, "%s: Invalid argument `%s'.\n",
1106 name, d);
1107 return -1;
1108 }
1109
1110 switch (x) {
1111 case '+':
1112 el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value;
1113 el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
1114 break;
1115 case '-':
1116 el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
1117 el->el_tty.t_t[z][m->m_type].t_clrmask |= m->m_value;
1118 break;
1119 default:
1120 el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
1121 el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
1122 break;
1123 }
1124 }
1125 return 0;
1126 } /* end tty_stty */
1127
1128
1129 #ifdef notyet
1130 /* tty_printchar():
1131 * DEbugging routine to print the tty characters
1132 */
1133 private void
1134 tty_printchar(el, s)
1135 EditLine *el;
1136 unsigned char *s;
1137 {
1138 ttyperm_t *m;
1139 int i;
1140
1141 for (i = 0; i < C_NCC; i++) {
1142 for (m = el->el_tty.t_t; m->m_name; m++)
1143 if (m->m_type == M_CHAR && C_SH(i) == m->m_value)
1144 break;
1145 if (m->m_name)
1146 (void) fprintf(el->el_errfile, "%s ^%c ", m->m_name, s[i] + 'A'-1);
1147 if (i % 5 == 0)
1148 (void) fprintf(el->el_errfile, "\n");
1149 }
1150 (void) fprintf(el->el_errfile, "\n");
1151 }
1152 #endif /* notyet */
1153