2 * ed.init.c: Editor initializations
5 * Copyright (c) 1980, 1991 The Regents of the University of California.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTS_ION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 /* ed.init.c -- init routines for the line editor */
38 /* #define DEBUG_TTY */
40 int Tty_raw_mode = 0; /* Last tty change was to raw mode */
41 int MacroLvl = -1; /* pointer to current macro nesting level; */
43 static int Tty_quote_mode = 0; /* Last tty change was to quote mode */
44 static unsigned char vdisable; /* The value of _POSIX_VDISABLE from
47 int Tty_eight_bit = -1; /* does the tty handle eight bits */
49 extern int GotTermCaps;
51 static ttydata_t extty, edtty, tstty;
54 #define SHTTY (insource ? OLDSTD : SHIN)
56 #define uc unsigned char
57 static unsigned char ttychars[NN_IO][C_NCC] = {
59 (uc)CINTR, (uc)CQUIT, (uc)CERASE, (uc)CKILL,
60 (uc)CEOF, (uc)CEOL, (uc)CEOL2, (uc)CSWTCH,
61 (uc)CDSWTCH, (uc)CERASE2, (uc)CSTART, (uc)CSTOP,
62 (uc)CWERASE, (uc)CSUSP, (uc)CDSUSP, (uc)CREPRINT,
63 (uc)CDISCARD, (uc)CLNEXT, (uc)CSTATUS, (uc)CPAGE,
64 (uc)CPGOFF, (uc)CKILL2, (uc)CBRK, (uc)CMIN,
68 CINTR, CQUIT, CERASE, CKILL,
69 _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
70 _POSIX_VDISABLE, CERASE2, CSTART, CSTOP,
71 _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
72 CDISCARD, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
73 _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1,
89 check_window_size(int force)
93 /* don't want to confuse things here */
95 cleanup_push(&pintr_disabled, disabled_cleanup);
97 * From: bret@shark.agps.lanl.gov (Bret Thaeler) Avoid sunview bug, where a
98 * partially hidden window gets a SIG_WINDOW every time the text is
101 if (GetSize(&lins, &cols) || force) {
107 ChangeSize(lins, cols);
111 ChangeSize(lins, cols);
114 cleanup_until(&pintr_disabled); /* can change it again */
119 window_change(int snum)
125 #endif /* SIG_WINDOW */
128 ed_set_tty_eight_bit(void)
130 if (tty_getty(SHTTY, &extty) == -1) {
132 xprintf("ed_set_tty_eight_bit: tty_getty: %s\n", strerror(errno));
133 #endif /* DEBUG_TTY */
136 Tty_eight_bit = tty_geteightbit(&extty);
143 static int havesetup = 0;
144 struct varent *imode;
146 if (havesetup) /* if we have never been called */
149 #if defined(POSIX) && defined(_PC_VDISABLE) && !defined(BSD4_4) && \
150 !defined(WINNT_NATIVE)
154 if ((pcret = fpathconf(SHTTY, _PC_VDISABLE)) == -1L)
155 vdisable = (unsigned char) _POSIX_VDISABLE;
157 vdisable = (unsigned char) pcret;
158 if (vdisable != (unsigned char) _POSIX_VDISABLE && rst != 0)
159 for (rst = 0; rst < C_NCC; rst++) {
160 if (ttychars[ED_IO][rst] == (unsigned char) _POSIX_VDISABLE)
161 ttychars[ED_IO][rst] = vdisable;
162 if (ttychars[EX_IO][rst] == (unsigned char) _POSIX_VDISABLE)
163 ttychars[EX_IO][rst] = vdisable;
166 #else /* ! POSIX || !_PC_VDISABLE || BSD4_4 || WINNT_NATIVE */
167 vdisable = (unsigned char) _POSIX_VDISABLE;
168 #endif /* POSIX && _PC_VDISABLE && !BSD4_4 && !WINNT_NATIVE */
170 if ((imode = adrof(STRinputmode)) != NULL && imode->vec != NULL) {
171 if (!Strcmp(*(imode->vec), STRinsert))
172 inputmode = MODE_INSERT;
173 else if (!Strcmp(*(imode->vec), STRoverwrite))
174 inputmode = MODE_REPLACE;
177 inputmode = MODE_INSERT;
181 SetKillRing(getn(varval(STRkillring)));
184 if (tty_getty(SHTTY, &extty) == -1) {
186 xprintf("ed_Setup: tty_getty: %s\n", strerror(errno));
187 # endif /* DEBUG_TTY */
191 tstty = edtty = extty;
193 T_Speed = tty_getspeed(&extty);
194 T_Tabs = tty_gettabs(&extty);
195 Tty_eight_bit = tty_geteightbit(&extty);
197 # if defined(POSIX) || defined(TERMIO)
198 extty.d_t.c_iflag &= ~ttylist[EX_IO][M_INPUT].t_clrmask;
199 extty.d_t.c_iflag |= ttylist[EX_IO][M_INPUT].t_setmask;
201 extty.d_t.c_oflag &= ~ttylist[EX_IO][M_OUTPUT].t_clrmask;
202 extty.d_t.c_oflag |= ttylist[EX_IO][M_OUTPUT].t_setmask;
204 extty.d_t.c_cflag &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
205 extty.d_t.c_cflag |= ttylist[EX_IO][M_CONTROL].t_setmask;
207 extty.d_t.c_lflag &= ~ttylist[EX_IO][M_LINED].t_clrmask;
208 extty.d_t.c_lflag |= ttylist[EX_IO][M_LINED].t_setmask;
210 # if defined(IRIX3_3) && SYSVREL < 4
211 extty.d_t.c_line = NTTYDISC;
212 # endif /* IRIX3_3 && SYSVREL < 4 */
214 # else /* GSTTY */ /* V7, Berkeley style tty */
216 if (T_Tabs) { /* order of &= and |= is important to XTABS */
217 extty.d_t.sg_flags &= ~(ttylist[EX_IO][M_CONTROL].t_clrmask|XTABS);
218 extty.d_t.sg_flags |= ttylist[EX_IO][M_CONTROL].t_setmask;
221 extty.d_t.sg_flags &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
222 extty.d_t.sg_flags |= (ttylist[EX_IO][M_CONTROL].t_setmask|XTABS);
225 extty.d_lb &= ~ttylist[EX_IO][M_LOCAL].t_clrmask;
226 extty.d_lb |= ttylist[EX_IO][M_LOCAL].t_setmask;
230 * Reset the tty chars to reasonable defaults
231 * If they are disabled, then enable them.
234 if (tty_cooked_mode(&tstty)) {
235 tty_getchar(&tstty, ttychars[TS_IO]);
237 * Don't affect CMIN and CTIME for the editor mode
239 for (rst = 0; rst < C_NCC - 2; rst++)
240 if (ttychars[TS_IO][rst] != vdisable &&
241 ttychars[ED_IO][rst] != vdisable)
242 ttychars[ED_IO][rst] = ttychars[TS_IO][rst];
243 for (rst = 0; rst < C_NCC; rst++)
244 if (ttychars[TS_IO][rst] != vdisable &&
245 ttychars[EX_IO][rst] != vdisable)
246 ttychars[EX_IO][rst] = ttychars[TS_IO][rst];
248 tty_setchar(&extty, ttychars[EX_IO]);
249 if (tty_setty(SHTTY, &extty) == -1) {
251 xprintf("ed_Setup: tty_setty: %s\n", strerror(errno));
252 # endif /* DEBUG_TTY */
257 tty_setchar(&extty, ttychars[EX_IO]);
262 (void)signal(SIG_WINDOW, window_change); /* for window systems */
264 sigaddset(&set, SIG_WINDOW);
265 (void)sigprocmask(SIG_UNBLOCK, &set, NULL);
268 #else /* WINNT_NATIVE */
271 xprintf("rst received in ed_Setup() %d\n", rst);
273 #endif /* WINNT_NATIVE */
281 ResetInLine(1); /* reset the input pointers */
282 GettingInput = 0; /* just in case */
284 /* XXX This code was here before the kill ring:
285 LastKill = KillBuf; / * no kill buffer * /
286 If there was any reason for that other than to make sure LastKill
287 was initialized, the code below should go in here instead - but
288 it doesn't seem reasonable to lose the entire kill ring (which is
289 "self-initializing") just because you set $term or whatever, so
290 presumably this whole '#ifdef notdef' should just be taken out. */
292 { /* no kill ring - why? */
294 for (i = 0; i < KillRingMax; i++) {
295 xfree(KillRing[i].buf);
296 KillRing[i].buf = NULL;
299 YankPos = KillPos = 0;
305 CheckMaps(); /* do a little error checking on key maps */
308 if (ed_Setup(0) == -1)
312 * if we have been called before but GotTermCaps isn't set, our TERM has
313 * changed, so get new termcaps and try again
317 GetTermCaps(); /* does the obvious, but gets term type each
321 # if defined(TERMIO) || defined(POSIX)
322 edtty.d_t.c_iflag &= ~ttylist[ED_IO][M_INPUT].t_clrmask;
323 edtty.d_t.c_iflag |= ttylist[ED_IO][M_INPUT].t_setmask;
325 edtty.d_t.c_oflag &= ~ttylist[ED_IO][M_OUTPUT].t_clrmask;
326 edtty.d_t.c_oflag |= ttylist[ED_IO][M_OUTPUT].t_setmask;
328 edtty.d_t.c_cflag &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
329 edtty.d_t.c_cflag |= ttylist[ED_IO][M_CONTROL].t_setmask;
331 edtty.d_t.c_lflag &= ~ttylist[ED_IO][M_LINED].t_clrmask;
332 edtty.d_t.c_lflag |= ttylist[ED_IO][M_LINED].t_setmask;
335 # if defined(IRIX3_3) && SYSVREL < 4
336 edtty.d_t.c_line = NTTYDISC;
337 # endif /* IRIX3_3 && SYSVREL < 4 */
341 if (T_Tabs) { /* order of &= and |= is important to XTABS */
342 edtty.d_t.sg_flags &= ~(ttylist[ED_IO][M_CONTROL].t_clrmask | XTABS);
343 edtty.d_t.sg_flags |= ttylist[ED_IO][M_CONTROL].t_setmask;
346 edtty.d_t.sg_flags &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
347 edtty.d_t.sg_flags |= (ttylist[ED_IO][M_CONTROL].t_setmask | XTABS);
350 edtty.d_lb &= ~ttylist[ED_IO][M_LOCAL].t_clrmask;
351 edtty.d_lb |= ttylist[ED_IO][M_LOCAL].t_setmask;
352 # endif /* POSIX || TERMIO */
354 tty_setchar(&edtty, ttychars[ED_IO]);
355 #endif /* WINNT_NATIVE */
359 * Check and re-init the line. set the terminal into 1 char at a time mode.
369 #else /* !WINNT_NATIVE */
371 tty_setdisc(SHTTY, ED_IO);
374 if (tty_getty(SHTTY, &tstty) == -1) {
376 xprintf("Rawmode: tty_getty: %s\n", strerror(errno));
377 # endif /* DEBUG_TTY */
382 * We always keep up with the eight bit setting and the speed of the
383 * tty. But only we only believe changes that are made to cooked mode!
385 # if defined(POSIX) || defined(TERMIO)
386 Tty_eight_bit = tty_geteightbit(&tstty);
387 T_Speed = tty_getspeed(&tstty);
391 * Fix from: Steven (Steve) B. Green <xrsbg@charney.gsfc.nasa.gov>
392 * Speed was not being set up correctly under POSIX.
394 if (tty_getspeed(&extty) != T_Speed || tty_getspeed(&edtty) != T_Speed) {
395 (void) cfsetispeed(&extty.d_t, T_Speed);
396 (void) cfsetospeed(&extty.d_t, T_Speed);
397 (void) cfsetispeed(&edtty.d_t, T_Speed);
398 (void) cfsetospeed(&edtty.d_t, T_Speed);
403 T_Speed = tty_getspeed(&tstty);
404 Tty_eight_bit = tty_geteightbit(&tstty);
406 if (extty.d_t.sg_ispeed != tstty.d_t.sg_ispeed) {
407 extty.d_t.sg_ispeed = tstty.d_t.sg_ispeed;
408 edtty.d_t.sg_ispeed = tstty.d_t.sg_ispeed;
411 if (extty.d_t.sg_ospeed != tstty.d_t.sg_ospeed) {
412 extty.d_t.sg_ospeed = tstty.d_t.sg_ospeed;
413 edtty.d_t.sg_ospeed = tstty.d_t.sg_ospeed;
415 # endif /* POSIX || TERMIO */
417 if (tty_cooked_mode(&tstty)) {
419 * re-test for some things here (like maybe the user typed
422 if (tty_gettabs(&tstty) == 0)
427 # if defined(POSIX) || defined(TERMIO)
428 extty.d_t.c_cflag = tstty.d_t.c_cflag;
429 extty.d_t.c_cflag &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
430 extty.d_t.c_cflag |= ttylist[EX_IO][M_CONTROL].t_setmask;
432 edtty.d_t.c_cflag = tstty.d_t.c_cflag;
433 edtty.d_t.c_cflag &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
434 edtty.d_t.c_cflag |= ttylist[ED_IO][M_CONTROL].t_setmask;
436 extty.d_t.c_lflag = tstty.d_t.c_lflag;
437 extty.d_t.c_lflag &= ~ttylist[EX_IO][M_LINED].t_clrmask;
438 extty.d_t.c_lflag |= ttylist[EX_IO][M_LINED].t_setmask;
440 edtty.d_t.c_lflag = tstty.d_t.c_lflag;
441 edtty.d_t.c_lflag &= ~ttylist[ED_IO][M_LINED].t_clrmask;
442 edtty.d_t.c_lflag |= ttylist[ED_IO][M_LINED].t_setmask;
444 extty.d_t.c_iflag = tstty.d_t.c_iflag;
445 extty.d_t.c_iflag &= ~ttylist[EX_IO][M_INPUT].t_clrmask;
446 extty.d_t.c_iflag |= ttylist[EX_IO][M_INPUT].t_setmask;
448 edtty.d_t.c_iflag = tstty.d_t.c_iflag;
449 edtty.d_t.c_iflag &= ~ttylist[ED_IO][M_INPUT].t_clrmask;
450 edtty.d_t.c_iflag |= ttylist[ED_IO][M_INPUT].t_setmask;
452 extty.d_t.c_oflag = tstty.d_t.c_oflag;
453 extty.d_t.c_oflag &= ~ttylist[EX_IO][M_OUTPUT].t_clrmask;
454 extty.d_t.c_oflag |= ttylist[EX_IO][M_OUTPUT].t_setmask;
456 edtty.d_t.c_oflag = tstty.d_t.c_oflag;
457 edtty.d_t.c_oflag &= ~ttylist[ED_IO][M_OUTPUT].t_clrmask;
458 edtty.d_t.c_oflag |= ttylist[ED_IO][M_OUTPUT].t_setmask;
462 extty.d_t.sg_flags = tstty.d_t.sg_flags;
464 extty.d_t.sg_flags &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
465 extty.d_t.sg_flags |= ttylist[EX_IO][M_CONTROL].t_setmask;
467 if (T_Tabs) /* order of &= and |= is important to XTABS */
468 extty.d_t.sg_flags &= ~XTABS;
470 extty.d_t.sg_flags |= XTABS;
472 extty.d_lb = tstty.d_lb;
473 extty.d_lb &= ~ttylist[EX_IO][M_LOCAL].t_clrmask;
474 extty.d_lb |= ttylist[EX_IO][M_LOCAL].t_setmask;
476 edtty.d_t.sg_flags = extty.d_t.sg_flags;
477 if (T_Tabs) { /* order of &= and |= is important to XTABS */
478 edtty.d_t.sg_flags &=
479 ~(ttylist[ED_IO][M_CONTROL].t_clrmask|XTABS);
480 edtty.d_t.sg_flags |= ttylist[ED_IO][M_CONTROL].t_setmask;
483 edtty.d_t.sg_flags &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
484 edtty.d_t.sg_flags |=
485 (ttylist[ED_IO][M_CONTROL].t_setmask|XTABS);
488 edtty.d_lb = tstty.d_lb;
489 edtty.d_lb &= ~ttylist[ED_IO][M_LOCAL].t_clrmask;
490 edtty.d_lb |= ttylist[ED_IO][M_LOCAL].t_setmask;
492 # endif /* TERMIO || POSIX */
497 tty_getchar(&tstty, ttychars[TS_IO]);
499 * Check if the user made any changes.
500 * If he did, then propagate the changes to the
501 * edit and execute data structures.
503 for (i = 0; i < C_NCC; i++)
504 if (ttychars[TS_IO][i] != ttychars[EX_IO][i])
507 if (i != C_NCC || didsetty) {
510 * Propagate changes only to the unprotected chars
511 * that have been modified just now.
513 for (i = 0; i < C_NCC; i++) {
514 if (!((ttylist[ED_IO][M_CHAR].t_setmask & C_SH(i))) &&
515 (ttychars[TS_IO][i] != ttychars[EX_IO][i]))
516 ttychars[ED_IO][i] = ttychars[TS_IO][i];
517 if (ttylist[ED_IO][M_CHAR].t_clrmask & C_SH(i))
518 ttychars[ED_IO][i] = vdisable;
520 tty_setchar(&edtty, ttychars[ED_IO]);
522 for (i = 0; i < C_NCC; i++) {
523 if (!((ttylist[EX_IO][M_CHAR].t_setmask & C_SH(i))) &&
524 (ttychars[TS_IO][i] != ttychars[EX_IO][i]))
525 ttychars[EX_IO][i] = ttychars[TS_IO][i];
526 if (ttylist[EX_IO][M_CHAR].t_clrmask & C_SH(i))
527 ttychars[EX_IO][i] = vdisable;
529 tty_setchar(&extty, ttychars[EX_IO]);
534 if (tty_setty(SHTTY, &edtty) == -1) {
536 xprintf("Rawmode: tty_setty: %s\n", strerror(errno));
537 # endif /* DEBUG_TTY */
540 #endif /* WINNT_NATIVE */
542 flush(); /* flush any buffered output */
548 { /* set tty in normal setup */
556 tty_setdisc(SHTTY, EX_IO);
562 /* hold this for reseting tty */
564 sigaddset(&set, SIGINT);
565 (void)sigprocmask(SIG_BLOCK, &set, &oset);
566 cleanup_push(&oset, sigprocmask_cleanup);
567 res = tty_setty(SHTTY, &extty);
568 cleanup_until(&oset);
571 xprintf("Cookedmode: tty_setty: %s\n", strerror(errno));
572 # endif /* DEBUG_TTY */
575 #endif /* WINNT_NATIVE */
582 ResetInLine(int macro)
584 Cursor = InputBuf; /* reset cursor */
586 InputLim = &InputBuf[INBUFSIZE - 2];/*FIXBUF*/
590 CurrentKeyMap = CcKeyMap;
595 LastCmd = F_UNASSIGNED; /* previous command executed */
598 MacroLvl = -1; /* no currently active macros */
602 Load_input_line(void)
604 static Char *Input_Line = NULL;
609 * *Everyone* else has an int, but SunOS wants long!
610 * This breaks where int != long (alpha)
622 #if defined(FIONREAD) && !defined(OREO)
623 (void) ioctl(SHIN, FIONREAD, (ioctl_t) &chrs);
627 chrs = xread(SHIN, buf, min(chrs, BUFSIZE - 1));
630 Input_Line = Strsave(str2short(buf));
631 PushMacro(Input_Line);
634 /* need to print errno message in case file is migrated */
636 stderror(ERR_SYSTEM, progname, strerror(errno));
639 #endif /* FIONREAD && !OREO */
644 * Bugfix (in Swedish) by:
646 * SICS, PO Box 1263, S-163 13 SPANGA, SWEDEN
647 * {mcvax,munnari,cernvax,diku,inria,prlb2,penet,ukc,unido}!enea!sics.se!jw
648 * Internet: jw@sics.se
650 * (via Hans J Albertsson (thanks))
661 #if defined(TERMIO) || defined(POSIX)
662 qutty.d_t.c_iflag &= ~ttylist[QU_IO][M_INPUT].t_clrmask;
663 qutty.d_t.c_iflag |= ttylist[QU_IO][M_INPUT].t_setmask;
665 qutty.d_t.c_oflag &= ~ttylist[QU_IO][M_OUTPUT].t_clrmask;
666 qutty.d_t.c_oflag |= ttylist[QU_IO][M_OUTPUT].t_setmask;
668 qutty.d_t.c_cflag &= ~ttylist[QU_IO][M_CONTROL].t_clrmask;
669 qutty.d_t.c_cflag |= ttylist[QU_IO][M_CONTROL].t_setmask;
671 qutty.d_t.c_lflag &= ~ttylist[QU_IO][M_LINED].t_clrmask;
672 qutty.d_t.c_lflag |= ttylist[QU_IO][M_LINED].t_setmask;
674 qutty.d_t.sg_flags &= ~ttylist[QU_IO][M_CONTROL].t_clrmask;
675 qutty.d_t.sg_flags |= ttylist[QU_IO][M_CONTROL].t_setmask;
676 qutty.d_lb &= ~ttylist[QU_IO][M_LOCAL].t_clrmask;
677 qutty.d_lb |= ttylist[QU_IO][M_LOCAL].t_setmask;
679 #endif /* TERMIO || POSIX */
680 if (tty_setty(SHTTY, &qutty) == -1) {
682 xprintf("QuoteModeOn: tty_setty: %s\n", strerror(errno));
683 #endif /* DEBUG_TTY */
686 #endif /* !WINNT_NATIVE */
697 if (tty_setty(SHTTY, &edtty) == -1) {
699 xprintf("QuoteModeOff: tty_setty: %s\n", strerror(errno));
700 #endif /* DEBUG_TTY */