root/src/noitedit/tty.c

Revision 6480ae14408dabfad215b4f1369579f864f4b558, 28.9 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 5 years ago)

fixes #105... it's a hack, but it appears to work... loses invalid sequences, but I think that's the desired outcome... luckily

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