root/src/noitedit/tty.c

Revision 647ef348e1bcdee83786760f7616926b52a6bac1, 28.9 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 9 months ago)

Various code cleanliness fixes.

  • 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 (tty__cooked_mode(&el->el_tty.t_ts)) {
509                 tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
510                 /*
511                  * Don't affect CMIN and CTIME for the editor mode
512                  */
513                 for (rst = 0; rst < C_NCC - 2; rst++)
514                         if (el->el_tty.t_c[TS_IO][rst] !=
515                               el->el_tty.t_vdisable
516                             && el->el_tty.t_c[ED_IO][rst] !=
517                               el->el_tty.t_vdisable)
518                                 el->el_tty.t_c[ED_IO][rst] =
519                                     el->el_tty.t_c[TS_IO][rst];
520                 for (rst = 0; rst < C_NCC; rst++)
521                         if (el->el_tty.t_c[TS_IO][rst] !=
522                             el->el_tty.t_vdisable)
523                                 el->el_tty.t_c[EX_IO][rst] =
524                                     el->el_tty.t_c[TS_IO][rst];
525         }
526         tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
527         if (tty_setty(el, &el->el_tty.t_ex) == -1) {
528 #ifdef DEBUG_TTY
529                 (void) el->el_err_printf(el,
530                     "tty_setup: tty_setty: %s\r\n",
531                     strerror(errno));
532 #endif /* DEBUG_TTY */
533                 return (-1);
534         }
535
536         el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask;
537         el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask;
538
539         el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask;
540         el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][MD_OUT].t_setmask;
541
542         el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask;
543         el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][MD_CTL].t_setmask;
544
545         el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask;
546         el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][MD_LIN].t_setmask;
547
548         tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
549         tty_bind_char(el, 1);
550         return (0);
551 }
552
553 protected int
554 tty_init(EditLine *el)
555 {
556         el->el_tty.t_mode = EX_IO;
557         el->el_tty.t_vdisable = _POSIX_VDISABLE;
558         (void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t));
559         (void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t));
560         return (tty_setup(el));
561 }
562
563
564 /* tty_end():
565  *      Restore the tty to its original settings
566  */
567 protected void
568 /*ARGSUSED*/
569 tty_end(EditLine *el)
570 {
571
572         /* XXX: Maybe reset to an initial state? */
573 }
574
575
576 /* tty__getspeed():
577  *      Get the tty speed
578  */
579 private speed_t
580 tty__getspeed(struct termios *td)
581 {
582         speed_t spd;
583
584         if ((spd = cfgetispeed(td)) == 0)
585                 spd = cfgetospeed(td);
586         return (spd);
587 }
588
589
590 /* tty__getchar():
591  *      Get the tty characters
592  */
593 private void
594 tty__getchar(struct termios *td, unsigned char *s)
595 {
596
597 #ifdef VINTR
598         s[C_INTR] = td->c_cc[VINTR];
599 #endif /* VINTR */
600 #ifdef VQUIT
601         s[C_QUIT] = td->c_cc[VQUIT];
602 #endif /* VQUIT */
603 #ifdef VERASE
604         s[C_ERASE] = td->c_cc[VERASE];
605 #endif /* VERASE */
606 #ifdef VKILL
607         s[C_KILL] = td->c_cc[VKILL];
608 #endif /* VKILL */
609 #ifdef VEOF
610         s[C_EOF] = td->c_cc[VEOF];
611 #endif /* VEOF */
612 #ifdef VEOL
613         s[C_EOL] = td->c_cc[VEOL];
614 #endif /* VEOL */
615 #ifdef VEOL2
616         s[C_EOL2] = td->c_cc[VEOL2];
617 #endif /* VEOL2 */
618 #ifdef VSWTCH
619         s[C_SWTCH] = td->c_cc[VSWTCH];
620 #endif /* VSWTCH */
621 #ifdef VDSWTCH
622         s[C_DSWTCH] = td->c_cc[VDSWTCH];
623 #endif /* VDSWTCH */
624 #ifdef VERASE2
625         s[C_ERASE2] = td->c_cc[VERASE2];
626 #endif /* VERASE2 */
627 #ifdef VSTART
628         s[C_START] = td->c_cc[VSTART];
629 #endif /* VSTART */
630 #ifdef VSTOP
631         s[C_STOP] = td->c_cc[VSTOP];
632 #endif /* VSTOP */
633 #ifdef VWERASE
634         s[C_WERASE] = td->c_cc[VWERASE];
635 #endif /* VWERASE */
636 #ifdef VSUSP
637         s[C_SUSP] = td->c_cc[VSUSP];
638 #endif /* VSUSP */
639 #ifdef VDSUSP
640         s[C_DSUSP] = td->c_cc[VDSUSP];
641 #endif /* VDSUSP */
642 #ifdef VREPRINT
643         s[C_REPRINT] = td->c_cc[VREPRINT];
644 #endif /* VREPRINT */
645 #ifdef VDISCARD
646         s[C_DISCARD] = td->c_cc[VDISCARD];
647 #endif /* VDISCARD */
648 #ifdef VLNEXT
649         s[C_LNEXT] = td->c_cc[VLNEXT];
650 #endif /* VLNEXT */
651 #ifdef VSTATUS
652         s[C_STATUS] = td->c_cc[VSTATUS];
653 #endif /* VSTATUS */
654 #ifdef VPAGE
655         s[C_PAGE] = td->c_cc[VPAGE];
656 #endif /* VPAGE */
657 #ifdef VPGOFF
658         s[C_PGOFF] = td->c_cc[VPGOFF];
659 #endif /* VPGOFF */
660 #ifdef VKILL2
661         s[C_KILL2] = td->c_cc[VKILL2];
662 #endif /* KILL2 */
663 #ifdef VMIN
664         s[C_MIN] = td->c_cc[VMIN];
665 #endif /* VMIN */
666 #ifdef VTIME
667         s[C_TIME] = td->c_cc[VTIME];
668 #endif /* VTIME */
669 }                               /* tty__getchar */
670
671
672 /* tty__setchar():
673  *      Set the tty characters
674  */
675 private void
676 tty__setchar(struct termios *td, unsigned char *s)
677 {
678
679 #ifdef VINTR
680         td->c_cc[VINTR] = s[C_INTR];
681 #endif /* VINTR */
682 #ifdef VQUIT
683         td->c_cc[VQUIT] = s[C_QUIT];
684 #endif /* VQUIT */
685 #ifdef VERASE
686         td->c_cc[VERASE] = s[C_ERASE];
687 #endif /* VERASE */
688 #ifdef VKILL
689         td->c_cc[VKILL] = s[C_KILL];
690 #endif /* VKILL */
691 #ifdef VEOF
692         td->c_cc[VEOF] = s[C_EOF];
693 #endif /* VEOF */
694 #ifdef VEOL
695         td->c_cc[VEOL] = s[C_EOL];
696 #endif /* VEOL */
697 #ifdef VEOL2
698         td->c_cc[VEOL2] = s[C_EOL2];
699 #endif /* VEOL2 */
700 #ifdef VSWTCH
701         td->c_cc[VSWTCH] = s[C_SWTCH];
702 #endif /* VSWTCH */
703 #ifdef VDSWTCH
704         td->c_cc[VDSWTCH] = s[C_DSWTCH];
705 #endif /* VDSWTCH */
706 #ifdef VERASE2
707         td->c_cc[VERASE2] = s[C_ERASE2];
708 #endif /* VERASE2 */
709 #ifdef VSTART
710         td->c_cc[VSTART] = s[C_START];
711 #endif /* VSTART */
712 #ifdef VSTOP
713         td->c_cc[VSTOP] = s[C_STOP];
714 #endif /* VSTOP */
715 #ifdef VWERASE
716         td->c_cc[VWERASE] = s[C_WERASE];
717 #endif /* VWERASE */
718 #ifdef VSUSP
719         td->c_cc[VSUSP] = s[C_SUSP];
720 #endif /* VSUSP */
721 #ifdef VDSUSP
722         td->c_cc[VDSUSP] = s[C_DSUSP];
723 #endif /* VDSUSP */
724 #ifdef VREPRINT
725         td->c_cc[VREPRINT] = s[C_REPRINT];
726 #endif /* VREPRINT */
727 #ifdef VDISCARD
728         td->c_cc[VDISCARD] = s[C_DISCARD];
729 #endif /* VDISCARD */
730 #ifdef VLNEXT
731         td->c_cc[VLNEXT] = s[C_LNEXT];
732 #endif /* VLNEXT */
733 #ifdef VSTATUS
734         td->c_cc[VSTATUS] = s[C_STATUS];
735 #endif /* VSTATUS */
736 #ifdef VPAGE
737         td->c_cc[VPAGE] = s[C_PAGE];
738 #endif /* VPAGE */
739 #ifdef VPGOFF
740         td->c_cc[VPGOFF] = s[C_PGOFF];
741 #endif /* VPGOFF */
742 #ifdef VKILL2
743         td->c_cc[VKILL2] = s[C_KILL2];
744 #endif /* VKILL2 */
745 #ifdef VMIN
746         td->c_cc[VMIN] = s[C_MIN];
747 #endif /* VMIN */
748 #ifdef VTIME
749         td->c_cc[VTIME] = s[C_TIME];
750 #endif /* VTIME */
751 }                               /* tty__setchar */
752
753
754 /* tty_bind_char():
755  *      Rebind the editline functions
756  */
757 protected void
758 tty_bind_char(EditLine *el, int force)
759 {
760
761         unsigned char *t_n = el->el_tty.t_c[ED_IO];
762         unsigned char *t_o = el->el_tty.t_ed.c_cc;
763         unsigned char new[2], old[2];
764         const ttymap_t *tp;
765         el_action_t *map, *alt;
766         const el_action_t *dmap, *dalt;
767         new[1] = old[1] = '\0';
768
769         map = el->el_map.key;
770         alt = el->el_map.alt;
771         if (el->el_map.type == MAP_VI) {
772                 dmap = el->el_map.vii;
773                 dalt = el->el_map.vic;
774         } else {
775                 dmap = el->el_map.emacs;
776                 dalt = NULL;
777         }
778
779         for (tp = tty_map; tp->nch != -1; tp++) {
780                 new[0] = t_n[tp->nch];
781                 old[0] = t_o[tp->och];
782                 if (new[0] == old[0] && !force)
783                         continue;
784                 /* Put the old default binding back, and set the new binding */
785                 key_clear(el, map, (char *)old);
786                 map[old[0]] = dmap[old[0]];
787                 key_clear(el, map, (char *)new);
788                 /* MAP_VI == 1, MAP_EMACS == 0... */
789                 map[new[0]] = tp->bind[el->el_map.type];
790                 if (dalt) {
791                         key_clear(el, alt, (char *)old);
792                         alt[old[0]] = dalt[old[0]];
793                         key_clear(el, alt, (char *)new);
794                         alt[new[0]] = tp->bind[el->el_map.type + 1];
795                 }
796         }
797 }
798
799
800 /* tty_rawmode():
801  *      Set terminal into 1 character at a time mode.
802  */
803 protected int
804 tty_rawmode(EditLine *el)
805 {
806
807         if (el->el_tty.t_mode == ED_IO || el->el_tty.t_mode == QU_IO)
808                 return (0);
809
810         if (el->el_flags & EDIT_DISABLED)
811                 return (0);
812
813         if (tty_getty(el, &el->el_tty.t_ts) == -1) {
814 #ifdef DEBUG_TTY
815                 (void) el->el_err_printf(el, "tty_rawmode: tty_getty: %s\r\n",
816                     strerror(errno));
817 #endif /* DEBUG_TTY */
818                 return (-1);
819         }
820         /*
821          * We always keep up with the eight bit setting and the speed of the
822          * tty. But only we only believe changes that are made to cooked mode!
823          */
824         el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts);
825         el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts);
826
827         if (tty__getspeed(&el->el_tty.t_ex) != el->el_tty.t_speed ||
828             tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) {
829                 (void) cfsetispeed(&el->el_tty.t_ex, el->el_tty.t_speed);
830                 (void) cfsetospeed(&el->el_tty.t_ex, el->el_tty.t_speed);
831                 (void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed);
832                 (void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed);
833         }
834         if (tty__cooked_mode(&el->el_tty.t_ts)) {
835                 if (el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) {
836                         el->el_tty.t_ex.c_cflag =
837                             el->el_tty.t_ts.c_cflag;
838                         el->el_tty.t_ex.c_cflag &=
839                             ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask;
840                         el->el_tty.t_ex.c_cflag |=
841                             el->el_tty.t_t[EX_IO][MD_CTL].t_setmask;
842
843                         el->el_tty.t_ed.c_cflag =
844                             el->el_tty.t_ts.c_cflag;
845                         el->el_tty.t_ed.c_cflag &=
846                             ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask;
847                         el->el_tty.t_ed.c_cflag |=
848                             el->el_tty.t_t[ED_IO][MD_CTL].t_setmask;
849                 }
850                 if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) &&
851                     (el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) {
852                         el->el_tty.t_ex.c_lflag =
853                             el->el_tty.t_ts.c_lflag;
854                         el->el_tty.t_ex.c_lflag &=
855                             ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask;
856                         el->el_tty.t_ex.c_lflag |=
857                             el->el_tty.t_t[EX_IO][MD_LIN].t_setmask;
858
859                         el->el_tty.t_ed.c_lflag =
860                             el->el_tty.t_ts.c_lflag;
861                         el->el_tty.t_ed.c_lflag &=
862                             ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask;
863                         el->el_tty.t_ed.c_lflag |=
864                             el->el_tty.t_t[ED_IO][MD_LIN].t_setmask;
865                 }
866                 if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) &&
867                     (el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) {
868                         el->el_tty.t_ex.c_iflag =
869                             el->el_tty.t_ts.c_iflag;
870                         el->el_tty.t_ex.c_iflag &=
871                             ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask;
872                         el->el_tty.t_ex.c_iflag |=
873                             el->el_tty.t_t[EX_IO][MD_INP].t_setmask;
874
875                         el->el_tty.t_ed.c_iflag =
876                             el->el_tty.t_ts.c_iflag;
877                         el->el_tty.t_ed.c_iflag &=
878                             ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask;
879                         el->el_tty.t_ed.c_iflag |=
880                             el->el_tty.t_t[ED_IO][MD_INP].t_setmask;
881                 }
882                 if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) &&
883                     (el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) {
884                         el->el_tty.t_ex.c_oflag =
885                             el->el_tty.t_ts.c_oflag;
886                         el->el_tty.t_ex.c_oflag &=
887                             ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask;
888                         el->el_tty.t_ex.c_oflag |=
889                             el->el_tty.t_t[EX_IO][MD_OUT].t_setmask;
890
891                         el->el_tty.t_ed.c_oflag =
892                             el->el_tty.t_ts.c_oflag;
893                         el->el_tty.t_ed.c_oflag &=
894                             ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask;
895                         el->el_tty.t_ed.c_oflag |=
896                             el->el_tty.t_t[ED_IO][MD_OUT].t_setmask;
897                 }
898                 if (tty__gettabs(&el->el_tty.t_ex) == 0)
899                         el->el_tty.t_tabs = 0;
900                 else
901                         el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0;
902
903                 {
904                         int i;
905
906                         tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
907                         /*
908                          * Check if the user made any changes.
909                          * If he did, then propagate the changes to the
910                          * edit and execute data structures.
911                          */
912                         for (i = 0; i < C_NCC; i++)
913                                 if (el->el_tty.t_c[TS_IO][i] !=
914                                     el->el_tty.t_c[EX_IO][i])
915                                         break;
916
917                         if (i != C_NCC) {
918                                 /*
919                                  * Propagate changes only to the unprotected
920                                  * chars that have been modified just now.
921                                  */
922                                 for (i = 0; i < C_NCC; i++) {
923                                         if (!((el->el_tty.t_t[ED_IO][MD_CHAR].t_setmask & C_SH(i)))
924                                             && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
925                                                 el->el_tty.t_c[ED_IO][i] = el->el_tty.t_c[TS_IO][i];
926                                         if (el->el_tty.t_t[ED_IO][MD_CHAR].t_clrmask & C_SH(i))
927                                                 el->el_tty.t_c[ED_IO][i] = el->el_tty.t_vdisable;
928                                 }
929                                 tty_bind_char(el, 0);
930                                 tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
931
932                                 for (i = 0; i < C_NCC; i++) {
933                                         if (!((el->el_tty.t_t[EX_IO][MD_CHAR].t_setmask & C_SH(i)))
934                                             && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
935                                                 el->el_tty.t_c[EX_IO][i] = el->el_tty.t_c[TS_IO][i];
936                                         if (el->el_tty.t_t[EX_IO][MD_CHAR].t_clrmask & C_SH(i))
937                                                 el->el_tty.t_c[EX_IO][i] = el->el_tty.t_vdisable;
938                                 }
939                                 tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
940                         }
941                 }
942         }
943         if (tty_setty(el, &el->el_tty.t_ed) == -1) {
944 #ifdef DEBUG_TTY
945                 (void) el->el_err_printf(el, "tty_rawmode: tty_setty: %s\r\n",
946                     strerror(errno));
947 #endif /* DEBUG_TTY */
948                 return (-1);
949         }
950         el->el_tty.t_mode = ED_IO;
951         return (0);
952 }
953
954
955 /* tty_cookedmode():
956  *      Set the tty back to normal mode
957  */
958 protected int
959 tty_cookedmode(EditLine *el)
960 {                               /* set tty in normal setup */
961
962         if (el->el_tty.t_mode == EX_IO)
963                 return (0);
964
965         if (el->el_flags & EDIT_DISABLED)
966                 return (0);
967
968         if (tty_setty(el, &el->el_tty.t_ex) == -1) {
969 #ifdef DEBUG_TTY
970                 (void) el->el_err_printf(el,
971                     "tty_cookedmode: tty_setty: %s\r\n",
972                     strerror(errno));
973 #endif /* DEBUG_TTY */
974                 return (-1);
975         }
976         el->el_tty.t_mode = EX_IO;
977         return (0);
978 }
979
980
981 /* tty_quotemode():
982  *      Turn on quote mode
983  */
984 protected int
985 tty_quotemode(EditLine *el)
986 {
987         if (el->el_tty.t_mode == QU_IO)
988                 return (0);
989
990         el->el_tty.t_qu = el->el_tty.t_ed;
991
992         el->el_tty.t_qu.c_iflag &= ~el->el_tty.t_t[QU_IO][MD_INP].t_clrmask;
993         el->el_tty.t_qu.c_iflag |= el->el_tty.t_t[QU_IO][MD_INP].t_setmask;
994
995         el->el_tty.t_qu.c_oflag &= ~el->el_tty.t_t[QU_IO][MD_OUT].t_clrmask;
996         el->el_tty.t_qu.c_oflag |= el->el_tty.t_t[QU_IO][MD_OUT].t_setmask;
997
998         el->el_tty.t_qu.c_cflag &= ~el->el_tty.t_t[QU_IO][MD_CTL].t_clrmask;
999         el->el_tty.t_qu.c_cflag |= el->el_tty.t_t[QU_IO][MD_CTL].t_setmask;
1000
1001         el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][MD_LIN].t_clrmask;
1002         el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][MD_LIN].t_setmask;
1003
1004         if (tty_setty(el, &el->el_tty.t_qu) == -1) {
1005 #ifdef DEBUG_TTY
1006                 (void) el_err_printf(el, "QuoteModeOn: tty_setty: %s\r\n",
1007                     strerror(errno));
1008 #endif /* DEBUG_TTY */
1009                 return (-1);
1010         }
1011         el->el_tty.t_mode = QU_IO;
1012         return (0);
1013 }
1014
1015
1016 /* tty_noquotemode():
1017  *      Turn off quote mode
1018  */
1019 protected int
1020 tty_noquotemode(EditLine *el)
1021 {
1022
1023         if (el->el_tty.t_mode != QU_IO)
1024                 return (0);
1025         if (tty_setty(el, &el->el_tty.t_ed) == -1) {
1026 #ifdef DEBUG_TTY
1027                 (void) el->el_err_printf(el, "QuoteModeOff: tty_setty: %s\r\n",
1028                     strerror(errno));
1029 #endif /* DEBUG_TTY */
1030                 return (-1);
1031         }
1032         el->el_tty.t_mode = ED_IO;
1033         return (0);
1034 }
1035
1036
1037 /* tty_stty():
1038  *      Stty builtin
1039  */
1040 protected int
1041 /*ARGSUSED*/
1042 tty_stty(EditLine *el, int argc, char **argv)
1043 {
1044         const ttymodes_t *m;
1045         char x = '\0', *d;
1046         int aflag = 0;
1047         char *s;
1048         char *name;
1049         int z = EX_IO;
1050
1051         if (argv == NULL)
1052                 return (-1);
1053         name = *argv++;
1054
1055         while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0')
1056                 switch (argv[0][1]) {
1057                 case 'a':
1058                         aflag++;
1059                         argv++;
1060                         break;
1061                 case 'd':
1062                         argv++;
1063                         z = ED_IO;
1064                         break;
1065                 case 'x':
1066                         argv++;
1067                         z = EX_IO;
1068                         break;
1069                 case 'q':
1070                         argv++;
1071                         z = QU_IO;
1072                         break;
1073                 default:
1074                         (void) el->el_err_printf(el,
1075                             "%s: Unknown switch `%c'.\r\n",
1076                             name, argv[0][1]);
1077                         return (-1);
1078                 }
1079
1080         if (!argv || !*argv) {
1081                 int i = -1;
1082                 int len = 0, st = 0, cu;
1083                 for (m = ttymodes; m->m_name; m++) {
1084                         if (m->m_type != i) {
1085                                 (void) el->el_std_printf(el, "%s%s",
1086                                     i != -1 ? "\n" : "",
1087                                     el->el_tty.t_t[z][m->m_type].t_name);
1088                                 i = m->m_type;
1089                                 st = len =
1090                                     strlen(el->el_tty.t_t[z][m->m_type].t_name);
1091                         }
1092       if (i >= 0) {
1093                           x = (el->el_tty.t_t[z][i].t_setmask & m->m_value)
1094                               ?  '+' : '\0';
1095                           x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value)
1096                               ? '-' : x;
1097       }
1098
1099                         if (x != '\0' || aflag) {
1100
1101                                 cu = strlen(m->m_name) + (x != '\0') + 1;
1102
1103                                 if (len + cu >= el->el_term.t_size.h) {
1104                                         (void) el->el_std_printf(el, "\n%*s",
1105                                             st, "");
1106                                         len = st + cu;
1107                                 } else
1108                                         len += cu;
1109
1110                                 if (x != '\0')
1111                                         (void) el->el_std_printf(el, "%c%s ",
1112                                             x, m->m_name);
1113                                 else
1114                                         (void) el->el_std_printf(el, "%s ",
1115                                             m->m_name);
1116                         }
1117                 }
1118                 (void) el->el_std_printf(el, "\n");
1119                 return (0);
1120         }
1121         while (argv && (s = *argv++)) {
1122                 switch (*s) {
1123                 case '+':
1124                 case '-':
1125                         x = *s++;
1126                         break;
1127                 default:
1128                         x = '\0';
1129                         break;
1130                 }
1131                 d = s;
1132                 for (m = ttymodes; m->m_name; m++)
1133                         if (strcmp(m->m_name, d) == 0)
1134                                 break;
1135
1136                 if (!m->m_name) {
1137                         (void) el->el_err_printf(el,
1138                             "%s: Invalid argument `%s'.\r\n", name, d);
1139                         return (-1);
1140                 }
1141                 switch (x) {
1142                 case '+':
1143                         el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value;
1144                         el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
1145                         break;
1146                 case '-':
1147                         el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
1148                         el->el_tty.t_t[z][m->m_type].t_clrmask |= m->m_value;
1149                         break;
1150                 default:
1151                         el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
1152                         el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
1153                         break;
1154                 }
1155         }
1156         return (0);
1157 }
1158
1159
1160 #ifdef notyet
1161 /* tty_printchar():
1162  *      DEbugging routine to print the tty characters
1163  */
1164 private void
1165 tty_printchar(EditLine *el, unsigned char *s)
1166 {
1167         ttyperm_t *m;
1168         int i;
1169
1170         for (i = 0; i < C_NCC; i++) {
1171                 for (m = el->el_tty.t_t; m->m_name; m++)
1172                         if (m->m_type == MD_CHAR && C_SH(i) == m->m_value)
1173                                 break;
1174                 if (m->m_name)
1175                         (void) el->el_err_printf(el, "%s ^%c ",
1176                             m->m_name, s[i] + 'A' - 1);
1177                 if (i % 5 == 0)
1178                         (void) el->el_err_printf(el, "\r\n");
1179         }
1180         (void) el->el_err_printf(el, "\r\n");
1181 }
1182 #endif /* notyet */
Note: See TracBrowser for help on using the browser.