root/src/noitedit/tty.c

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

import of libedit... prepare to hack

  • 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 "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 "sys.h"
52 #include "el.h"
53 #include "tty.h"
54
55 typedef struct ttymodes_t {
56         const 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 const 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 | INLCR | ICRNL},
88                 {"oflag:", 0, 0},
89                 {"cflag:", 0, 0},
90                 {"lflag:", 0, ISIG | IEXTEN},
91                 {"chars:", 0, 0},
92         }
93 };
94
95 private const 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 const 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 const ttymodes_t ttymodes[] = {
163 #ifdef  IGNBRK
164         {"ignbrk", IGNBRK, MD_INP},
165 #endif /* IGNBRK */
166 #ifdef  BRKINT
167         {"brkint", BRKINT, MD_INP},
168 #endif /* BRKINT */
169 #ifdef  IGNPAR
170         {"ignpar", IGNPAR, MD_INP},
171 #endif /* IGNPAR */
172 #ifdef  PARMRK
173         {"parmrk", PARMRK, MD_INP},
174 #endif /* PARMRK */
175 #ifdef  INPCK
176         {"inpck", INPCK, MD_INP},
177 #endif /* INPCK */
178 #ifdef  ISTRIP
179         {"istrip", ISTRIP, MD_INP},
180 #endif /* ISTRIP */
181 #ifdef  INLCR
182         {"inlcr", INLCR, MD_INP},
183 #endif /* INLCR */
184 #ifdef  IGNCR
185         {"igncr", IGNCR, MD_INP},
186 #endif /* IGNCR */
187 #ifdef  ICRNL
188         {"icrnl", ICRNL, MD_INP},
189 #endif /* ICRNL */
190 #ifdef  IUCLC
191         {"iuclc", IUCLC, MD_INP},
192 #endif /* IUCLC */
193 #ifdef  IXON
194         {"ixon", IXON, MD_INP},
195 #endif /* IXON */
196 #ifdef  IXANY
197         {"ixany", IXANY, MD_INP},
198 #endif /* IXANY */
199 #ifdef  IXOFF
200         {"ixoff", IXOFF, MD_INP},
201 #endif /* IXOFF */
202 #ifdef  IMAXBEL
203         {"imaxbel", IMAXBEL, MD_INP},
204 #endif /* IMAXBEL */
205
206 #ifdef  OPOST
207         {"opost", OPOST, MD_OUT},
208 #endif /* OPOST */
209 #ifdef  OLCUC
210         {"olcuc", OLCUC, MD_OUT},
211 #endif /* OLCUC */
212 #ifdef  ONLCR
213         {"onlcr", ONLCR, MD_OUT},
214 #endif /* ONLCR */
215 #ifdef  OCRNL
216         {"ocrnl", OCRNL, MD_OUT},
217 #endif /* OCRNL */
218 #ifdef  ONOCR
219         {"onocr", ONOCR, MD_OUT},
220 #endif /* ONOCR */
221 #ifdef ONOEOT
222         {"onoeot", ONOEOT, MD_OUT},
223 #endif /* ONOEOT */
224 #ifdef  ONLRET
225         {"onlret", ONLRET, MD_OUT},
226 #endif /* ONLRET */
227 #ifdef  OFILL
228         {"ofill", OFILL, MD_OUT},
229 #endif /* OFILL */
230 #ifdef  OFDEL
231         {"ofdel", OFDEL, MD_OUT},
232 #endif /* OFDEL */
233 #ifdef  NLDLY
234         {"nldly", NLDLY, MD_OUT},
235 #endif /* NLDLY */
236 #ifdef  CRDLY
237         {"crdly", CRDLY, MD_OUT},
238 #endif /* CRDLY */
239 #ifdef  TABDLY
240         {"tabdly", TABDLY, MD_OUT},
241 #endif /* TABDLY */
242 #ifdef  XTABS
243         {"xtabs", XTABS, MD_OUT},
244 #endif /* XTABS */
245 #ifdef  BSDLY
246         {"bsdly", BSDLY, MD_OUT},
247 #endif /* BSDLY */
248 #ifdef  VTDLY
249         {"vtdly", VTDLY, MD_OUT},
250 #endif /* VTDLY */
251 #ifdef  FFDLY
252         {"ffdly", FFDLY, MD_OUT},
253 #endif /* FFDLY */
254 #ifdef  PAGEOUT
255         {"pageout", PAGEOUT, MD_OUT},
256 #endif /* PAGEOUT */
257 #ifdef  WRAP
258         {"wrap", WRAP, MD_OUT},
259 #endif /* WRAP */
260
261 #ifdef  CIGNORE
262         {"cignore", CIGNORE, MD_CTL},
263 #endif /* CBAUD */
264 #ifdef  CBAUD
265         {"cbaud", CBAUD, MD_CTL},
266 #endif /* CBAUD */
267 #ifdef  CSTOPB
268         {"cstopb", CSTOPB, MD_CTL},
269 #endif /* CSTOPB */
270 #ifdef  CREAD
271         {"cread", CREAD, MD_CTL},
272 #endif /* CREAD */
273 #ifdef  PARENB
274         {"parenb", PARENB, MD_CTL},
275 #endif /* PARENB */
276 #ifdef  PARODD
277         {"parodd", PARODD, MD_CTL},
278 #endif /* PARODD */
279 #ifdef  HUPCL
280         {"hupcl", HUPCL, MD_CTL},
281 #endif /* HUPCL */
282 #ifdef  CLOCAL
283         {"clocal", CLOCAL, MD_CTL},
284 #endif /* CLOCAL */
285 #ifdef  LOBLK
286         {"loblk", LOBLK, MD_CTL},
287 #endif /* LOBLK */
288 #ifdef  CIBAUD
289         {"cibaud", CIBAUD, MD_CTL},
290 #endif /* CIBAUD */
291 #ifdef CRTSCTS
292 #ifdef CCTS_OFLOW
293         {"ccts_oflow", CCTS_OFLOW, MD_CTL},
294 #else
295         {"crtscts", CRTSCTS, MD_CTL},
296 #endif /* CCTS_OFLOW */
297 #endif /* CRTSCTS */
298 #ifdef CRTS_IFLOW
299         {"crts_iflow", CRTS_IFLOW, MD_CTL},
300 #endif /* CRTS_IFLOW */
301 #ifdef CDTRCTS
302         {"cdtrcts", CDTRCTS, MD_CTL},
303 #endif /* CDTRCTS */
304 #ifdef MDMBUF
305         {"mdmbuf", MDMBUF, MD_CTL},
306 #endif /* MDMBUF */
307 #ifdef RCV1EN
308         {"rcv1en", RCV1EN, MD_CTL},
309 #endif /* RCV1EN */
310 #ifdef XMT1EN
311         {"xmt1en", XMT1EN, MD_CTL},
312 #endif /* XMT1EN */
313
314 #ifdef  ISIG
315         {"isig", ISIG, MD_LIN},
316 #endif /* ISIG */
317 #ifdef  ICANON
318         {"icanon", ICANON, MD_LIN},
319 #endif /* ICANON */
320 #ifdef  XCASE
321         {"xcase", XCASE, MD_LIN},
322 #endif /* XCASE */
323 #ifdef  ECHO
324         {"echo", ECHO, MD_LIN},
325 #endif /* ECHO */
326 #ifdef  ECHOE
327         {"echoe", ECHOE, MD_LIN},
328 #endif /* ECHOE */
329 #ifdef  ECHOK
330         {"echok", ECHOK, MD_LIN},
331 #endif /* ECHOK */
332 #ifdef  ECHONL
333         {"echonl", ECHONL, MD_LIN},
334 #endif /* ECHONL */
335 #ifdef  NOFLSH
336         {"noflsh", NOFLSH, MD_LIN},
337 #endif /* NOFLSH */
338 #ifdef  TOSTOP
339         {"tostop", TOSTOP, MD_LIN},
340 #endif /* TOSTOP */
341 #ifdef  ECHOCTL
342         {"echoctl", ECHOCTL, MD_LIN},
343 #endif /* ECHOCTL */
344 #ifdef  ECHOPRT
345         {"echoprt", ECHOPRT, MD_LIN},
346 #endif /* ECHOPRT */
347 #ifdef  ECHOKE
348         {"echoke", ECHOKE, MD_LIN},
349 #endif /* ECHOKE */
350 #ifdef  DEFECHO
351         {"defecho", DEFECHO, MD_LIN},
352 #endif /* DEFECHO */
353 #ifdef  FLUSHO
354         {"flusho", FLUSHO, MD_LIN},
355 #endif /* FLUSHO */
356 #ifdef  PENDIN
357         {"pendin", PENDIN, MD_LIN},
358 #endif /* PENDIN */
359 #ifdef  IEXTEN
360         {"iexten", IEXTEN, MD_LIN},
361 #endif /* IEXTEN */
362 #ifdef  NOKERNINFO
363         {"nokerninfo", NOKERNINFO, MD_LIN},
364 #endif /* NOKERNINFO */
365 #ifdef  ALTWERASE
366         {"altwerase", ALTWERASE, MD_LIN},
367 #endif /* ALTWERASE */
368 #ifdef  EXTPROC
369         {"extproc", EXTPROC, MD_LIN},
370 #endif /* EXTPROC */
371
372 #if defined(VINTR)
373         {"intr", C_SH(C_INTR), MD_CHAR},
374 #endif /* VINTR */
375 #if defined(VQUIT)
376         {"quit", C_SH(C_QUIT), MD_CHAR},
377 #endif /* VQUIT */
378 #if defined(VERASE)
379         {"erase", C_SH(C_ERASE), MD_CHAR},
380 #endif /* VERASE */
381 #if defined(VKILL)
382         {"kill", C_SH(C_KILL), MD_CHAR},
383 #endif /* VKILL */
384 #if defined(VEOF)
385         {"eof", C_SH(C_EOF), MD_CHAR},
386 #endif /* VEOF */
387 #if defined(VEOL)
388         {"eol", C_SH(C_EOL), MD_CHAR},
389 #endif /* VEOL */
390 #if defined(VEOL2)
391         {"eol2", C_SH(C_EOL2), MD_CHAR},
392 #endif /* VEOL2 */
393 #if defined(VSWTCH)
394         {"swtch", C_SH(C_SWTCH), MD_CHAR},
395 #endif /* VSWTCH */
396 #if defined(VDSWTCH)
397         {"dswtch", C_SH(C_DSWTCH), MD_CHAR},
398 #endif /* VDSWTCH */
399 #if defined(VERASE2)
400         {"erase2", C_SH(C_ERASE2), MD_CHAR},
401 #endif /* VERASE2 */
402 #if defined(VSTART)
403         {"start", C_SH(C_START), MD_CHAR},
404 #endif /* VSTART */
405 #if defined(VSTOP)
406         {"stop", C_SH(C_STOP), MD_CHAR},
407 #endif /* VSTOP */
408 #if defined(VWERASE)
409         {"werase", C_SH(C_WERASE), MD_CHAR},
410 #endif /* VWERASE */
411 #if defined(VSUSP)
412         {"susp", C_SH(C_SUSP), MD_CHAR},
413 #endif /* VSUSP */
414 #if defined(VDSUSP)
415         {"dsusp", C_SH(C_DSUSP), MD_CHAR},
416 #endif /* VDSUSP */
417 #if defined(VREPRINT)
418         {"reprint", C_SH(C_REPRINT), MD_CHAR},
419 #endif /* VREPRINT */
420 #if defined(VDISCARD)
421         {"discard", C_SH(C_DISCARD), MD_CHAR},
422 #endif /* VDISCARD */
423 #if defined(VLNEXT)
424         {"lnext", C_SH(C_LNEXT), MD_CHAR},
425 #endif /* VLNEXT */
426 #if defined(VSTATUS)
427         {"status", C_SH(C_STATUS), MD_CHAR},
428 #endif /* VSTATUS */
429 #if defined(VPAGE)
430         {"page", C_SH(C_PAGE), MD_CHAR},
431 #endif /* VPAGE */
432 #if defined(VPGOFF)
433         {"pgoff", C_SH(C_PGOFF), MD_CHAR},
434 #endif /* VPGOFF */
435 #if defined(VKILL2)
436         {"kill2", C_SH(C_KILL2), MD_CHAR},
437 #endif /* VKILL2 */
438 #if defined(VBRK)
439         {"brk", C_SH(C_BRK), MD_CHAR},
440 #endif /* VBRK */
441 #if defined(VMIN)
442         {"min", C_SH(C_MIN), MD_CHAR},
443 #endif /* VMIN */
444 #if defined(VTIME)
445         {"time", C_SH(C_TIME), MD_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(struct termios *, unsigned char *);
460 private void    tty__setchar(struct termios *, unsigned char *);
461 private speed_t tty__getspeed(struct termios *);
462 private int     tty_setup(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(EditLine *el)
472 {
473         int rst = 1;
474
475         if (el->el_flags & EDIT_DISABLED)
476                 return (0);
477
478         if (tty_getty(el, &el->el_tty.t_ed) == -1) {
479 #ifdef DEBUG_TTY
480                 (void) fprintf(el->el_errfile,
481                     "tty_setup: tty_getty: %s\n", strerror(errno));
482 #endif /* DEBUG_TTY */
483                 return (-1);
484         }
485         el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed;
486
487         el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex);
488         el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex);
489         el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex);
490
491         el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask;
492         el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][MD_INP].t_setmask;
493
494         el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask;
495         el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][MD_OUT].t_setmask;
496
497         el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask;
498         el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][MD_CTL].t_setmask;
499
500         el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask;
501         el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][MD_LIN].t_setmask;
502
503         /*
504          * Reset the tty chars to reasonable defaults
505          * If they are disabled, then enable them.
506          */
507         if (rst) {
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) fprintf(el->el_errfile,
530                             "tty_setup: tty_setty: %s\n",
531                             strerror(errno));
532 #endif /* DEBUG_TTY */
533                         return (-1);
534                 }
535         } else
536                 tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
537
538         el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask;
539         el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask;
540
541         el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask;
542         el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][MD_OUT].t_setmask;
543
544         el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask;
545         el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][MD_CTL].t_setmask;
546
547         el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask;
548         el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][MD_LIN].t_setmask;
549
550         tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
551         tty_bind_char(el, 1);
552         return (0);
553 }
554
555 protected int
556 tty_init(EditLine *el)
557 {
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) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\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) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\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) fprintf(el->el_errfile,
974                     "tty_cookedmode: tty_setty: %s\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) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\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) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\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) fprintf(el->el_errfile,
1078                             "%s: Unknown switch `%c'.\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) fprintf(el->el_outfile, "%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) fprintf(el->el_outfile, "\n%*s",
1106                                             st, "");
1107                                         len = st + cu;
1108                                 } else
1109                                         len += cu;
1110
1111                                 if (x != '\0')
1112                                         (void) fprintf(el->el_outfile, "%c%s ",
1113                                             x, m->m_name);
1114                                 else
1115                                         (void) fprintf(el->el_outfile, "%s ",
1116                                             m->m_name);
1117                         }
1118                 }
1119                 (void) fprintf(el->el_outfile, "\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) fprintf(el->el_errfile,
1139                             "%s: Invalid argument `%s'.\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) fprintf(el->el_errfile, "%s ^%c ",
1177                             m->m_name, s[i] + 'A' - 1);
1178                 if (i % 5 == 0)
1179                         (void) fprintf(el->el_errfile, "\n");
1180         }
1181         (void) fprintf(el->el_errfile, "\n");
1182 }
1183 #endif /* notyet */
Note: See TracBrowser for help on using the browser.