da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1982-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * edit.c - common routines for vi and emacs one line editors in shell
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * David Korn P.D. Sullivan
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Labs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Coded April 1983.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# include <ls.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin extern char ed_errbuf[];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char e_version[] = "\n@(#)$Id: Editlib version 1993-12-28 r $\0\n";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* KSHELL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return('?');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_OLDTERMIO */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* RT */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* TIOCGETP */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _hdr_sgtty */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* KSHELL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static int compare(const char*, const char*, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* future */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_VSH || SHOPT_ESH */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This routine returns true if fd refers to a terminal
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This should be equivalent to isatty
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Edit_t *ep = (Edit_t*)(sh_getinterp()->ed_context);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Get the current terminal attributes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This routine remembers the attributes and just returns them if it
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * is called again without an intervening tty_set()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint tty_get(register int fd, register struct termios *tty)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Edit_t *ep = (Edit_t*)(sh_getinterp()->ed_context);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* save terminal settings if in cannonical state */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Set the terminal attributes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If fd<0, then current attributes are invalidated
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Edit_t *ep = (Edit_t*)(sh_getinterp()->ed_context);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->e_savefd>=0 && compare(&ep->e_savetty,tty,sizeof(struct termios)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*{ TTY_COOKED( fd )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This routine will set the tty in cooked mode.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * It is also called by error.done().
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Edit_t *ep = (Edit_t*)(sh_getinterp()->ed_context);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* restore flags */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* restore alternate break character */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* restore alternate break character */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* L_MASK */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*** don't do tty_set unless ttyparm has valid data ***/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*{ TTY_RAW( fd )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This routine will set the tty in raw mode.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* L_MASK */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Edit_t *ep = (Edit_t*)(sh_getinterp()->ed_context);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_RAWONLY */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* CBREAK */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* try to remove effect of ^V and ^Y and ^O */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lchars.t_dsuspc = -1; /* no delayed stop process signal */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* TIOCGLTC */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* FLUSHO */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_iflag &= ~(IGNPAR|PARMRK|INLCR|IGNCR|ICRNL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* u370 */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* VREPRINT */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* VDISCARD */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* VDSUSP */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* VWERASE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* VLNEXT */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_ttyspeed = (cfgetospeed(&ttyparm)>=B1200?FAST:SLOW);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Get tty parameters and make ESC and '\r' wakeup characters.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Edit_t *ep = (Edit_t*)(sh_getinterp()->ed_context);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* PENDIN */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* IEXTEN */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Edit_t *ep = (Edit_t*)(sh_getinterp()->ed_context);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((tty_get(fd, &ttyparm)==SYSERR) || (!(ttyparm.c_lflag&ECHO)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* FLUSHO */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* escape character echos as ^[ */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_lflag |= (ECHOE|ECHOK|ECHOCTL|PENDIN|IEXTEN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* switch VEOL2 and EOF, since EOF isn't echo'd by driver */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_cc[VEOL2] = ep->e_eof; /* make EOF an eol char */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_cc[VEOL] = ep->e_eof; /* make EOF an eol char */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* VEOL2 */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* ECHOCTL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* VREPRINT */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* VDISCARD */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* VWERASE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* VLNEXT */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_ttyspeed = (cfgetospeed(&ttyparm)>=B1200?FAST:SLOW);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* TIOCGETC */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_RAWONLY */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * ED_WINDOW()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return the window size
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* E_FLUSH()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Flush the output buffer.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * send the bell character ^G to the terminal
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * send a carriage return line feed to the terminal
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* cray */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* u370 */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* VENIX */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* ED_SETUP( max_prompt_size )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This routine sets up the prompt string
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The following is an unadvertised feature.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Escape sequences in the prompt can be excluded from the calculated
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * prompt length. This is accomplished as follows:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * - if the prompt string starts with "%\r, or contains \r%\r", where %
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * represents any char, then % is taken to be the quote character.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * - strings enclosed by this quote character, and the quote character,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * are not counted as part of the prompt length.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* KSHELL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!sh_isoption(SH_VI) && !sh_isoption(SH_EMACS) && !sh_isoption(SH_GMACS))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\b':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\r':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\n':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* start again */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\t':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* expand tabs */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\a':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* cut out bells */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!ep->e_multiline && (ep->e_wsize -= ep->e_plen) < 7)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* can't use output buffer when reading from stderr */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* make sure SF_READ not on */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_outbase = ep->e_outptr = (char*)sfreserve(sfstderr,SF_UNBOUND,SF_LOCKR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->e_term && (term=nv_getval(ep->e_term)) && strlen(term)<sizeof(ep->e_termname) && strcmp(term,ep->e_termname))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(n-- > 0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void ed_putstring(register Edit_t *ep, const char *str)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(c = *str++)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void ed_nputchar(register Edit_t *ep, int n, int c)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(n-->0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Do read, restart on interrupt unless SH_SIGSET or SH_SIGTRAP is set
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Use sfpkrd() to poll() or select() to wait for input if possible
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Unfortunately, systems that get interrupted from slow reads update
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * this access time for for the terminal (in violation of POSIX).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The fixtime() macro, resets the time to the time at entry in
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * this case. This is not necessary for systems that can handle
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * sfpkrd() correctly (i,e., those that support poll() or select()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint ed_read(void *context, int fd, char *buff, int size, int reedit)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(ep->sh->winch && sh_isstate(SH_INTERACTIVE) && (sh_isoption(SH_VI) || sh_isoption(SH_EMACS)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* move cursor to start of first line */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(ep->e_multiline && newsize>ep->e_winsz && (lastpos.line=(ep->e_plen+ep->e_peol)/ep->e_winsz))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* clear the current command line */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(sh_isoption(SH_EMACS) || sh_isoption(SH_VI))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* an interrupt that should be ignored */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((ep->e_tty=ttyname(fd)) && stat(ep->e_tty,&statb)>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->e_tty_ino && fstat(fd,&statb)>=0 && statb.st_ino==ep->e_tty_ino && statb.st_dev==ep->e_tty_dev)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _hdr_utime */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* an interrupt that should be ignored */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * put <string> of length <nbyte> onto lookahead stack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if <type> is non-zero, the negation of the character is put
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * onto the stack so that it can be checked for KEYTRAP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * putstack() returns 1 except when in the middle of a multi-byte char
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int putstack(Edit_t *ep,char string[], register int nbyte, int type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = (int)((*p) & STRIP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c == '\0')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*** user break key ***/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* KSHELL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* CBREAK */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c=mbchar(p)) >=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p--; /* incremented below */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = -(int)((*p) & STRIP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (p < endp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* shift lookahead buffer if necessary */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_lbuf[ep->e_lookahead+size-offset] = ep->e_lbuf[ep->e_lookahead+size];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (nbyte > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if( c == '\0' )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*** user break key ***/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* KSHELL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* CBREAK */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * routine to perform read from terminal for vi and emacs mode
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * <mode> can be one of the following:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * -2 vi insert mode - key binding is in effect
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * -1 vi control mode - key binding is in effect
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 0 normal command mode - key binding is in effect
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 1 edit keys not mapped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 2 Next key is literal
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n, c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* The while is necessary for reads of partial multbyte chars */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for possible key mapping */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c=sfpkrd(ep->e_fd,readin+n,1,'\r',(mode?400L:-1L),0))>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*** map '\r' to '\n' ***/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->e_tabcount && !(c=='\t'||c==ESC || c=='\\' || c=='=' || c==cntl('L') || isdigit(c)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * put a character into the output buffer
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for place holder */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns the line and column corresponding to offset <off> in the physical buffer
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if <cur> is non-zero and <= <off>, then correspodning <curpos> will start the search
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinEdpos_t ed_curpos(Edit_t *ep,genchar *phys, int off, int cur, Edpos_t curpos)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char p[16];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(off-->0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint ed_setcursor(register Edit_t *ep,genchar *physical,register int old,register int new,int first)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_curpos = ed_curpos(ep, physical, old,0,ep->e_curpos);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(clear && old>=ep->e_peol && (clear=ep->e_winsz-ep->e_curpos.col)>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newpos = ed_curpos(ep, physical, new,old,ep->e_curpos);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->e_curpos.col==0 && ep->e_curpos.line>0 && oldline<ep->e_curpos.line && delta<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(;ep->e_curpos.line > newpos.line; ep->e_curpos.line--)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(physical[m] && n-->0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ed_nputchar(ep, newpos.line-ep->e_curpos.line,'\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*** move to left ***/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*** attempt to optimize cursor movement ***/
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!ep->e_crlf || bs || (2*delta <= ((old-first)+(newpos.line?0:ep->e_plen))) )
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin first = 1+(newpos.line*ep->e_winsz - ep->e_plen);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * copy virtual to physical and return the index for cursor in physical buffer
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint ed_virt_to_phys(Edit_t *ep,genchar *virt,genchar *phys,int cur,int voff,int poff)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* multiple width character put in place holders */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(--d >0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* in vi mode the cursor is at the last character */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='\t')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(--c>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* in vi mode the cursor is at the last character */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(r);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * convert external representation <src> to an array of genchars <dest>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * <src> and <dest> can be the same
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns number of chars in dest
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const unsigned char *cp = (unsigned char *)src;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dest == (genchar*)roundof(cp-(unsigned char*)0,sizeof(genchar)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * convert internal representation <src> into character array <dest>.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The <src> and <dest> may be the same.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns number of chars in dest.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* copy the character as is */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * copy <sp> to <dp>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp = (genchar*)roundof((char*)dp-(char*)0,sizeof(genchar));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = (const genchar*)roundof((char*)sp-(char*)0,sizeof(genchar));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * copy at most <n> items from <sp> to <dp>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid ed_genncpy(register genchar *dp,register const genchar *sp, int n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp = (genchar*)roundof((char*)dp-(char*)0,sizeof(genchar));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = (const genchar*)roundof((char*)sp-(char*)0,sizeof(genchar));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * find the string length of <str>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = (const genchar*)roundof((char*)sp-(char*)0,sizeof(genchar));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*sp++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_ESH || SHOPT_VSH */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns 1 when <n> bytes starting at <a> and <b> are equal
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int compare(register const char *a,register const char *b,register int n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(n-->0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*a++ != *b++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* !ECHOCTL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * For backward compatibility only
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This version will use termios when possible, otherwise termio
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Edit_t *ep = (Edit_t*)(sh_getinterp()->ed_context);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int r,i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(r);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(i=0; i<NCC; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(r);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Edit_t *ep = (Edit_t*)(sh_getinterp()->ed_context);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(i=0; i<NCC; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ott.c_cc[VEOL2] = tt->c_cc[VEOF]; /* EOF -> eol char */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_OLDTERMIO */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Execute keyboard trap on given buffer <inbuff> of given size <isize>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * <mode> < 0 for vi insert mode
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int keytrap(Edit_t *ep,char *inbuff,register int insize, int bufsize, int mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(ED_COLNOD,(char*)&ep->e_col,NV_NOFREE|NV_INTEGER);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* KSHELL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((void*)ed);