da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
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* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * edit.c - common routines for vi and emacs one line editors in shell
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * David Korn P.D. Sullivan
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Labs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Coded April 1983.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ast.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <errno.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ccode.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "FEATURE/options"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "FEATURE/time"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "FEATURE/cmds"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef _hdr_utime
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# include <utime.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# include <ls.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if KSHELL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# include "defs.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# include "variables.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# include <ctype.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin extern char ed_errbuf[];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char e_version[] = "\n@(#)$Id: Editlib version 1993-12-28 r $\0\n";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* KSHELL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "io.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "terminal.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "history.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "edit.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char CURSOR_UP[20] = { ESC, '[', 'A', 0 };
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define is_cntrl(c) ((c<=STRIP) && iscntrl(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define is_print(c) ((c&~STRIP) || isprint(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define is_cntrl(c) iscntrl(c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define is_print(c) isprint(c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if (CC_NATIVE == CC_ASCII)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define printchar(c) ((c) ^ ('A'-cntl('A')))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static int printchar(int c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('A'): return('A');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('B'): return('B');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('C'): return('C');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('D'): return('D');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('E'): return('E');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('F'): return('F');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('G'): return('G');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('H'): return('H');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('I'): return('I');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('J'): return('J');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('K'): return('K');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('L'): return('L');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('M'): return('M');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('N'): return('N');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('O'): return('O');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('P'): return('P');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('Q'): return('Q');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('R'): return('R');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('S'): return('S');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('T'): return('T');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('U'): return('U');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('V'): return('V');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('W'): return('W');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('X'): return('X');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('Y'): return('Y');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('Z'): return('Z');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl(']'): return(']');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case cntl('['): return('[');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return('?');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MINWINDOW 15 /* minimum width window */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define DFLTWINDOW 80 /* default window width */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define RAWMODE 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ALTMODE 2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ECHOMODE 3
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SYSERR -1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_OLDTERMIO
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# undef tcgetattr
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# undef tcsetattr
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_OLDTERMIO */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef RT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define VENIX 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* RT */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef _hdr_sgtty
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef TIOCGETP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static int l_mask;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static struct tchars l_ttychars;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static struct ltchars l_chars;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char l_changed; /* set if mode bits changed */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define L_CHARS 4
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define T_CHARS 2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define L_MASK 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* TIOCGETP */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _hdr_sgtty */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if KSHELL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static int keytrap(Edit_t *,char*, int, int, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Edit_t editb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* KSHELL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef _POSIX_DISABLE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define _POSIX_DISABLE 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef future
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static int compare(const char*, const char*, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* future */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_VSH || SHOPT_ESH
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define ttyparm (ep->e_ttyparm)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define nttyparm (ep->e_nttyparm)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static const char bellchr[] = "\a"; /* bell char */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_VSH || SHOPT_ESH */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This routine returns true if fd refers to a terminal
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This should be equivalent to isatty
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint tty_check(int fd)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Edit_t *ep = (Edit_t*)(sh_getinterp()->ed_context);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct termios tty;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_savefd = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(tty_get(fd,&tty)==0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
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()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint tty_get(register int fd, register struct termios *tty)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Edit_t *ep = (Edit_t*)(sh_getinterp()->ed_context);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd == ep->e_savefd)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *tty = ep->e_savetty;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(tcgetattr(fd,tty) == SYSERR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(errno !=EINTR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(SYSERR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* save terminal settings if in cannonical state */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->e_raw==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_savetty = *tty;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_savefd = fd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Set the terminal attributes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If fd<0, then current attributes are invalidated
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint tty_set(int fd, int action, struct termios *tty)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Edit_t *ep = (Edit_t*)(sh_getinterp()->ed_context);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd >=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef future
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->e_savefd>=0 && compare(&ep->e_savetty,tty,sizeof(struct termios)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(tcsetattr(fd, action, tty) == SYSERR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(errno !=EINTR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(SYSERR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_savetty = *tty;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_savefd = fd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_ESH || SHOPT_VSH
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*{ TTY_COOKED( fd )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This routine will set the tty in cooked mode.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * It is also called by error.done().
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid tty_cooked(register int fd)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Edit_t *ep = (Edit_t*)(sh_getinterp()->ed_context);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->e_raw==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = ep->e_savefd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef L_MASK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* restore flags */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(l_changed&L_MASK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ioctl(fd,TIOCLSET,&l_mask);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(l_changed&T_CHARS)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* restore alternate break character */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ioctl(fd,TIOCSETC,&l_ttychars);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(l_changed&L_CHARS)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* restore alternate break character */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ioctl(fd,TIOCSLTC,&l_chars);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin l_changed = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* L_MASK */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*** don't do tty_set unless ttyparm has valid data ***/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tty_set(fd, TCSANOW, &ttyparm) == SYSERR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_raw = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*{ TTY_RAW( fd )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This routine will set the tty in raw mode.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint tty_raw(register int fd, int echomode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int echo = echomode;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef L_MASK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ltchars lchars;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* L_MASK */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Edit_t *ep = (Edit_t*)(sh_getinterp()->ed_context);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->e_raw==RAWMODE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(echo?-1:0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(ep->e_raw==ECHOMODE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(echo?0:-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if !SHOPT_RAWONLY
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->e_raw != ALTMODE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_RAWONLY */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tty_get(fd,&ttyparm) == SYSERR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if L_MASK || VENIX
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ttyparm.sg_flags&LCASE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(ttyparm.sg_flags&ECHO))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!echomode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin echo = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm = ttyparm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!echo)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.sg_flags &= ~(ECHO | TBDELAY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef CBREAK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.sg_flags |= CBREAK;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.sg_flags |= RAW;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* CBREAK */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_erase = ttyparm.sg_erase;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_kill = ttyparm.sg_kill;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_eof = cntl('D');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_werase = cntl('W');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_lnext = cntl('V');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if( tty_set(fd, TCSADRAIN, &nttyparm) == SYSERR )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_ttyspeed = (ttyparm.sg_ospeed>=B1200?FAST:SLOW);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef TIOCGLTC
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* try to remove effect of ^V and ^Y and ^O */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ioctl(fd,TIOCGLTC,&l_chars) != SYSERR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lchars = l_chars;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lchars.t_lnextc = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lchars.t_flushc = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lchars.t_dsuspc = -1; /* no delayed stop process signal */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ioctl(fd,TIOCSLTC,&lchars) != SYSERR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin l_changed |= L_CHARS;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* TIOCGLTC */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(ttyparm.c_lflag & ECHO ))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!echomode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin echo = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef FLUSHO
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ttyparm.c_lflag &= ~FLUSHO;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* FLUSHO */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm = ttyparm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifndef u370
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_iflag &= ~(IGNPAR|PARMRK|INLCR|IGNCR|ICRNL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_iflag |= BRKINT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_iflag &=
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ~(IGNBRK|PARMRK|INLCR|IGNCR|ICRNL|INPCK);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_iflag |= (BRKINT|IGNPAR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* u370 */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(echo)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_lflag &= ~ICANON;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_lflag &= ~(ICANON|ECHO|ECHOK);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_cc[VTIME] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_cc[VMIN] = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef VREPRINT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_cc[VREPRINT] = _POSIX_DISABLE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* VREPRINT */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef VDISCARD
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_cc[VDISCARD] = _POSIX_DISABLE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* VDISCARD */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef VDSUSP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_cc[VDSUSP] = _POSIX_DISABLE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* VDSUSP */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef VWERASE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ttyparm.c_cc[VWERASE] == _POSIX_DISABLE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_werase = cntl('W');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_werase = nttyparm.c_cc[VWERASE];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_cc[VWERASE] = _POSIX_DISABLE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_werase = cntl('W');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* VWERASE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef VLNEXT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ttyparm.c_cc[VLNEXT] == _POSIX_DISABLE )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_lnext = cntl('V');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_lnext = nttyparm.c_cc[VLNEXT];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_cc[VLNEXT] = _POSIX_DISABLE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_lnext = cntl('V');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* VLNEXT */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_eof = ttyparm.c_cc[VEOF];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_erase = ttyparm.c_cc[VERASE];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_kill = ttyparm.c_cc[VKILL];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if( tty_set(fd, TCSADRAIN, &nttyparm) == SYSERR )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_ttyspeed = (cfgetospeed(&ttyparm)>=B1200?FAST:SLOW);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_raw = (echomode?ECHOMODE:RAWMODE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if !SHOPT_RAWONLY
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Get tty parameters and make ESC and '\r' wakeup characters.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef TIOCGETC
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint tty_alt(register int fd)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Edit_t *ep = (Edit_t*)(sh_getinterp()->ed_context);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int mask;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct tchars ttychars;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(ep->e_raw)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ECHOMODE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ALTMODE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case RAWMODE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tty_cooked(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin l_changed = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if( ep->e_ttyspeed == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((tty_get(fd,&ttyparm) != SYSERR))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_ttyspeed = (ttyparm.sg_ospeed>=B1200?FAST:SLOW);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_raw = ALTMODE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ioctl(fd,TIOCGETC,&l_ttychars) == SYSERR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ioctl(fd,TIOCLGET,&l_mask)==SYSERR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ttychars = l_ttychars;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mask = LCRTBS|LCRTERA|LCTLECH|LPENDIN|LCRTKIL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((l_mask|mask) != l_mask)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin l_changed = L_MASK;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ioctl(fd,TIOCLBIS,&mask)==SYSERR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ttychars.t_brkc!=ESC)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ttychars.t_brkc = ESC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin l_changed |= T_CHARS;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ioctl(fd,TIOCSETC,&ttychars) == SYSERR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifndef PENDIN
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define PENDIN 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* PENDIN */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifndef IEXTEN
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define IEXTEN 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* IEXTEN */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint tty_alt(register int fd)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Edit_t *ep = (Edit_t*)(sh_getinterp()->ed_context);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(ep->e_raw)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ECHOMODE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ALTMODE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case RAWMODE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tty_cooked(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((tty_get(fd, &ttyparm)==SYSERR) || (!(ttyparm.c_lflag&ECHO)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef FLUSHO
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ttyparm.c_lflag &= ~FLUSHO;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* FLUSHO */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm = ttyparm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_eof = ttyparm.c_cc[VEOF];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef ECHOCTL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* escape character echos as ^[ */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_lflag |= (ECHOE|ECHOK|ECHOCTL|PENDIN|IEXTEN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_cc[VEOL] = ESC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* switch VEOL2 and EOF, since EOF isn't echo'd by driver */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_lflag |= (ECHOE|ECHOK);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_cc[VEOF] = ESC; /* make ESC the eof char */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef VEOL2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_iflag &= ~(IGNCR|ICRNL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_iflag |= INLCR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_cc[VEOL] = '\r'; /* make CR an eol char */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_cc[VEOL2] = ep->e_eof; /* make EOF an eol char */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_cc[VEOL] = ep->e_eof; /* make EOF an eol char */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* VEOL2 */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* ECHOCTL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef VREPRINT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_cc[VREPRINT] = _POSIX_DISABLE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* VREPRINT */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef VDISCARD
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_cc[VDISCARD] = _POSIX_DISABLE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* VDISCARD */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef VWERASE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ttyparm.c_cc[VWERASE] == _POSIX_DISABLE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_cc[VWERASE] = cntl('W');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_werase = nttyparm.c_cc[VWERASE];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_werase = cntl('W');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* VWERASE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef VLNEXT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ttyparm.c_cc[VLNEXT] == _POSIX_DISABLE )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nttyparm.c_cc[VLNEXT] = cntl('V');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_lnext = nttyparm.c_cc[VLNEXT];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_lnext = cntl('V');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* VLNEXT */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_erase = ttyparm.c_cc[VERASE];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_kill = ttyparm.c_cc[VKILL];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if( tty_set(fd, TCSADRAIN, &nttyparm) == SYSERR )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_ttyspeed = (cfgetospeed(&ttyparm)>=B1200?FAST:SLOW);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_raw = ALTMODE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* TIOCGETC */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_RAWONLY */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * ED_WINDOW()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return the window size
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint ed_window(void)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int rows,cols;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp = nv_getval(COLUMNS);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cols = (int)strtol(cp, (char**)0, 10)-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin astwinsize(2,&rows,&cols);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(--cols <0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cols = DFLTWINDOW-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cols < MINWINDOW)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cols = MINWINDOW;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(cols > MAXWINDOW)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cols = MAXWINDOW;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(cols);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* E_FLUSH()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Flush the output buffer.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid ed_flush(Edit_t *ep)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n = ep->e_outptr-ep->e_outbase;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int fd = ERRIO;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n<=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin write(fd,ep->e_outbase,(unsigned)n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_outptr = ep->e_outbase;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * send the bell character ^G to the terminal
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid ed_ringbell(void)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin write(ERRIO,bellchr,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * send a carriage return line feed to the terminal
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid ed_crlf(register Edit_t *ep)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef cray
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ed_putchar(ep,'\r');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* cray */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef u370
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ed_putchar(ep,'\r');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* u370 */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef VENIX
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ed_putchar(ep,'\r');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* VENIX */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ed_putchar(ep,'\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ed_flush(ep);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* ED_SETUP( max_prompt_size )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
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 */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid ed_setup(register Edit_t *ep, int fd, int reedit)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = ep->sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *pp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register char *last, *prev;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *ppmax;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int myquote = 0, n;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int qlen = 1, qwid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char inquote = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_fd = fd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_multiline = sh_isoption(SH_MULTILINE)!=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef SIGWINCH
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(shp->sigflag[SIGWINCH]&SH_SIGFAULT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin signal(SIGWINCH,sh_fault);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sigflag[SIGWINCH] |= SH_SIGFAULT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pp = shp->st.trapcom[SIGWINCH];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.trapcom[SIGWINCH] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_fault(SIGWINCH);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.trapcom[SIGWINCH] = pp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ep->sh->winch = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if KSHELL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_stkptr = stakptr(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_stkoff = staktell();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(last = shp->prompt))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin last = "";
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->prompt = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin last = ep->e_prbuff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* KSHELL */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->hist_ptr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register History_t *hp = shp->hist_ptr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_hismax = hist_max(hp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_hismin = hist_min(hp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_hismax = ep->e_hismin = ep->e_hloff = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_hline = ep->e_hismax;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!sh_isoption(SH_VI) && !sh_isoption(SH_EMACS) && !sh_isoption(SH_GMACS))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_wsize = MAXLINE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_wsize = ed_window()-2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_winsz = ep->e_wsize+2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_crlf = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_plen = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = ep->e_prompt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppmax = pp+PRSIZE-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *pp++ = '\r';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(prev = last, c = mbchar(last)) switch(c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ESC:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int skip=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_crlf = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *pp++ = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(n=1; c = *last++; n++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp < ppmax)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *pp++ = c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c=='\a' || c==ESC || c=='\r')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(skip || (c>='0' && c<='9'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n>1 && c==';')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin skip = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(n>2 || (c!= '[' && c!= ']'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c==0 || c==ESC || c=='\r')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin last--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin qlen += (n+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\b':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp>ep->e_prompt+1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\r':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp == (ep->e_prompt+2)) /* quote char */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin myquote = *(pp-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\n':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* start again */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_crlf = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin qlen = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inquote = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = ep->e_prompt+1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\t':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* expand tabs */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((pp-ep->e_prompt)%TABSIZE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp >= ppmax)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *pp++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\a':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* cut out bells */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==myquote)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin qlen += inquote;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inquote ^= 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp < ppmax)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(inquote)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin qlen++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(!is_print(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_crlf = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((qwid = last - prev) > 1)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin qlen += qwid - mbwidth(c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(prev < last && pp < ppmax)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *pp++ = *prev++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp-ep->e_prompt > qlen)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_plen = pp - ep->e_prompt - qlen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *pp = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!ep->e_multiline && (ep->e_wsize -= ep->e_plen) < 7)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int shift = 7-ep->e_wsize;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_wsize = 7;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = ep->e_prompt+1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(pp,pp+shift);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_plen -= shift;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin last[-ep->e_plen-2] = '\r';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsync(sfstderr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd == sffileno(sfstderr))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* can't use output buffer when reading from stderr */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char *buff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!buff)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin buff = (char*)malloc(MAXLINE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_outbase = ep->e_outptr = buff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_outlast = ep->e_outptr + MAXLINE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin qlen = sfset(sfstderr,SF_READ,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* make sure SF_READ not on */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_outbase = ep->e_outptr = (char*)sfreserve(sfstderr,SF_UNBOUND,SF_LOCKR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_outlast = ep->e_outptr + sfvalue(sfstderr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(qlen)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfset(sfstderr,SF_READ,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(sfstderr,ep->e_outptr,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_eol = reedit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->e_multiline)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef _cmd_tput
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *term;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!ep->e_term)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ep->e_term = nv_search("TERM",shp->var_tree,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->e_term && (term=nv_getval(ep->e_term)) && strlen(term)<sizeof(ep->e_termname) && strcmp(term,ep->e_termname))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_trap(".sh.subscript=$(tput cuu1 2>/dev/null)",0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp=nv_getval(SH_SUBSCRNOD))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strncpy(CURSOR_UP,pp,sizeof(CURSOR_UP)-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_unset(SH_SUBSCRNOD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(ep->e_termname,term);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ep->e_wsize = MAXLINE - (ep->e_plen+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->e_default && (pp = nv_getval(ep->e_default)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = strlen(pp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n > LOOKAHEAD)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = LOOKAHEAD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_lookahead = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(n-- > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_lbuf[n] = *pp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_default = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void ed_putstring(register Edit_t *ep, const char *str)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(c = *str++)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ed_putchar(ep,c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void ed_nputchar(register Edit_t *ep, int n, int c)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(n-->0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ed_putchar(ep,c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
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()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint ed_read(void *context, int fd, char *buff, int size, int reedit)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Edit_t *ep = (Edit_t*)context;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int rv= -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int delim = (ep->e_raw==RAWMODE?'\r':'\n');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = ep->sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int mode = -1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int (*waitevent)(int,long,int) = shp->waitevent;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->e_raw==ALTMODE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(size < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = -size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_TTYWAIT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = EINTR;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->waitevent = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(rv<0 && errno==EINTR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->trapnote&(SH_SIGSET|SH_SIGTRAP))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(ep->sh->winch && sh_isstate(SH_INTERACTIVE) && (sh_isoption(SH_VI) || sh_isoption(SH_EMACS)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Edpos_t lastpos;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int n, rows, newsize;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* move cursor to start of first line */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ed_putchar(ep,'\r');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ed_flush(ep);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin astwinsize(2,&rows,&newsize);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = (ep->e_plen+ep->e_cur)/++ep->e_winsz;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(n--)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ed_putstring(ep,CURSOR_UP);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(ep->e_multiline && newsize>ep->e_winsz && (lastpos.line=(ep->e_plen+ep->e_peol)/ep->e_winsz))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* clear the current command line */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = lastpos.line;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(lastpos.line--)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ed_nputchar(ep,ep->e_winsz,' ');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ed_putchar(ep,'\n');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ed_nputchar(ep,ep->e_winsz,' ');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(n--)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ed_putstring(ep,CURSOR_UP);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ep->sh->winch = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ed_flush(ep);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_delay(.05);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin astwinsize(2,&rows,&newsize);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ep->e_winsz = newsize-1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!ep->e_multiline && ep->e_wsize < MAXLINE)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ep->e_wsize = ep->e_winsz-2;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ep->e_nocrnl=1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(*ep->e_vi_insert)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin buff[0] = ESC;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin buff[1] = cntl('L');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin buff[2] = 'a';
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(3);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(sh_isoption(SH_EMACS) || sh_isoption(SH_VI))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz buff[0] = cntl('L');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz ep->sh->winch = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* an interrupt that should be ignored */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!waitevent || (rv=(*waitevent)(fd,-1L,0))>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rv = sfpkrd(fd,buff,size,delim,-1L,mode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(rv < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef _hdr_utime
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define fixtime() if(isdevtty)utime(ep->e_tty,&utimes)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int isdevtty=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat statb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct utimbuf utimes;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(errno==0 && !ep->e_tty)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((ep->e_tty=ttyname(fd)) && stat(ep->e_tty,&statb)>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_tty_ino = statb.st_ino;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_tty_dev = statb.st_dev;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
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 {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin utimes.actime = statb.st_atime;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin utimes.modtime = statb.st_mtime;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin isdevtty=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define fixtime()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _hdr_utime */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rv = read(fd,buff,size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(rv>=0 || errno!=EINTR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->trapnote&(SH_SIGSET|SH_SIGTRAP))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* an interrupt that should be ignored */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fixtime();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(rv>=0 && mode>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rv = read(fd,buff,rv>0?rv:1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindone:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->waitevent = waitevent;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_TTYWAIT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(rv);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
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
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int putstack(Edit_t *ep,char string[], register int nbyte, int type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *endp, *p=string;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int size, offset = ep->e_lookahead + nbyte;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *(endp = &p[nbyte]) = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin endp = &p[nbyte];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = (int)((*p) & STRIP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c< 0x80 && c!='<')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = -c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifndef CBREAK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c == '\0')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*** user break key ***/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_lookahead = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if KSHELL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_fault(SIGINT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin siglongjmp(ep->e_env, UINTR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* KSHELL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* CBREAK */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin again:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c=mbchar(p)) >=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p--; /* incremented below */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = -c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef EILSEQ
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(errno == EILSEQ)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if((endp-p) < mbmax())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((c=ed_read(ep,ep->e_fd,endp, 1,0)) == 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *++endp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto again;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ed_ringbell();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = -(int)((*p) & STRIP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin offset += mbmax()-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_lbuf[--offset] = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (p < endp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* shift lookahead buffer if necessary */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(offset -= ep->e_lookahead)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(size=offset;size < nbyte;size++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_lbuf[ep->e_lookahead+size-offset] = ep->e_lbuf[ep->e_lookahead+size];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_lookahead += nbyte-offset;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (nbyte > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = string[--nbyte] & STRIP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_lbuf[ep->e_lookahead++] = (type?-c:c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifndef CBREAK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if( c == '\0' )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*** user break key ***/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_lookahead = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if KSHELL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_fault(SIGINT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin siglongjmp(ep->e_env, UINTR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* KSHELL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* CBREAK */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
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 */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint ed_getchar(register Edit_t *ep,int mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n, c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char readin[LOOKAHEAD+1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!ep->e_lookahead)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ed_flush(ep);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_inmacro = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* The while is necessary for reads of partial multbyte chars */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *ep->e_vi_insert = (mode==-2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((n=ed_read(ep,ep->e_fd,readin,-LOOKAHEAD,0)) > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = putstack(ep,readin,n,1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *ep->e_vi_insert = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->e_lookahead)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for possible key mapping */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c = ep->e_lbuf[--ep->e_lookahead]) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mode<=0 && ep->sh->st.trap[SH_KEYTRAP])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((readin[0]= -c) == ESC)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!ep->e_lookahead)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c=sfpkrd(ep->e_fd,readin+n,1,'\r',(mode?400L:-1L),0))>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin putstack(ep,readin+n,c,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!ep->e_lookahead)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c=ep->e_lbuf[--ep->e_lookahead])>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_lookahead++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = -c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin readin[n++] = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c>='0' && c<='9' && n>2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n>2 || (c!= '[' && c!= 'O'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n=keytrap(ep,readin,n,LOOKAHEAD-n,mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin putstack(ep,readin,n,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = ep->e_lbuf[--ep->e_lookahead];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = ed_getchar(ep,mode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = -c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*** map '\r' to '\n' ***/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c == '\r' && mode!=2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '\n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->e_tabcount && !(c=='\t'||c==ESC || c=='\\' || c=='=' || c==cntl('L') || isdigit(c)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_tabcount = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin siglongjmp(ep->e_env,(n==0?UEOF:UINTR));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid ed_ungetchar(Edit_t *ep,register int c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep->e_lookahead < LOOKAHEAD)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_lbuf[ep->e_lookahead++] = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * put a character into the output buffer
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid ed_putchar(register Edit_t *ep,register int c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char buf[8];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *dp = ep->e_outptr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int i,size=1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!dp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin buf[0] = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for place holder */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c == MARKER)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((size = mbconv(buf, (wchar_t)c)) > 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i < (size-1); i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = buf[i];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = buf[i];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin buf[0] = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (buf[0] == '_' && size==1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = '\b';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp = '\0';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dp >= ep->e_outlast)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ed_flush(ep);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_outptr = dp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
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
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinEdpos_t ed_curpos(Edit_t *ep,genchar *phys, int off, int cur, Edpos_t curpos)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register genchar *sp=phys;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c=1, col=ep->e_plen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Edpos_t pos;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char p[16];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cur && off>=cur)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp += cur;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off -= cur;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pos = curpos;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin col = pos.col;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pos.line = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(col > ep->e_winsz)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pos.line++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin col -= (ep->e_winsz+1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(off-->0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *sp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c && (mbconv(p, (wchar_t)c))==1 && p[0]=='\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin col = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin col++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(col > ep->e_winsz)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin col = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(col==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pos.line++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pos.col = col;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(pos);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint ed_setcursor(register Edit_t *ep,genchar *physical,register int old,register int new,int first)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static int oldline;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int delta;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int clear = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Edpos_t newpos;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin delta = new - old;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(first < 0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin first = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin clear = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if( delta == 0 && !clear)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(new);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->e_multiline)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
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)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ed_nputchar(ep,clear,' ');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ed_nputchar(ep,clear,'\b');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(new);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
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 ed_putstring(ep,"\r\n");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin oldline = newpos.line;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->e_curpos.line > newpos.line)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int n,pline,plen=ep->e_plen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(;ep->e_curpos.line > newpos.line; ep->e_curpos.line--)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ed_putstring(ep,CURSOR_UP);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pline = plen/(ep->e_winsz+1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(newpos.line <= pline)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin plen -= pline*(ep->e_winsz+1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin plen = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((n=plen- ep->e_curpos.col)>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_curpos.col += n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ed_putchar(ep,'\r');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!ep->e_crlf && pline==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ed_putstring(ep,ep->e_prompt);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int m = ep->e_winsz+1-plen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ed_putchar(ep,'\n');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = plen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(m < ed_genlen(physical))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(physical[m] && n-->0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ed_putchar(ep,physical[m++]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ed_nputchar(ep,n,' ');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ed_putstring(ep,CURSOR_UP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(ep->e_curpos.line < newpos.line)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ed_nputchar(ep, newpos.line-ep->e_curpos.line,'\n');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ep->e_curpos.line = newpos.line;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ed_putchar(ep,'\r');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_curpos.col = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin delta = newpos.col - ep->e_curpos.col;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin old = new - delta;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newpos.line=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(delta<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int bs= newpos.line && ep->e_plen>ep->e_winsz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*** move to left ***/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin delta = -delta;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*** attempt to optimize cursor movement ***/
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!ep->e_crlf || bs || (2*delta <= ((old-first)+(newpos.line?0:ep->e_plen))) )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ed_nputchar(ep,delta,'\b');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin delta = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(newpos.line==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ed_putstring(ep,ep->e_prompt);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin first = 1+(newpos.line*ep->e_winsz - ep->e_plen);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ed_putchar(ep,'\r');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin old = first;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin delta = new-first;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(delta-->0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ed_putchar(ep,physical[old++]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(new);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * copy virtual to physical and return the index for cursor in physical buffer
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint ed_virt_to_phys(Edit_t *ep,genchar *virt,genchar *phys,int cur,int voff,int poff)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register genchar *sp = virt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register genchar *dp = phys;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin genchar *curp = sp + cur;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin genchar *dpmax = phys+MAXLINE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int d, r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp += voff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp += poff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(r=poff;c= *sp;sp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(curp == sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = dp - phys;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = mbwidth((wchar_t)c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(d==1 && is_cntrl(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(d>1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* multiple width character put in place holders */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(--d >0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = MARKER;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* in vi mode the cursor is at the last character */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dp>=dpmax)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = (is_cntrl(c)?-1:1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(d<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='\t')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = dp-phys;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_VI))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c += ep->e_plen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = TABSIZE - c%TABSIZE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(--c>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = '^';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = printchar(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* in vi mode the cursor is at the last character */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(curp == sp && sh_isoption(SH_VI))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = dp - phys;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dp>=dpmax)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ep->e_peol = dp-phys;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(r);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
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 */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint ed_internal(const char *src, genchar *dest)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const unsigned char *cp = (unsigned char *)src;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register wchar_t *dp = (wchar_t*)dest;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dest == (genchar*)roundof(cp-(unsigned char*)0,sizeof(genchar)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin genchar buffer[MAXLINE];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = ed_internal(src,buffer);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ed_gencpy((genchar*)dp,buffer);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = mbchar(cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(dp-(wchar_t*)dest);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
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 */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint ed_external(const genchar *src, char *dest)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register genchar wc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c,size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *dp = dest;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *dpmax = dp+sizeof(genchar)*MAXLINE-2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((char*)src == dp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char buffer[MAXLINE*sizeof(genchar)];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = ed_external(src,buffer);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef _lib_wcscpy
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin wcscpy((wchar_t *)dest,(const wchar_t *)buffer);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(dest,buffer);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((wc = *src++) && dp<dpmax)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((size = mbconv(dp, wc)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* copy the character as is */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp = wc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp += size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(dp-dest);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * copy <sp> to <dp>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid ed_gencpy(genchar *dp,const genchar *sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp = (genchar*)roundof((char*)dp-(char*)0,sizeof(genchar));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = (const genchar*)roundof((char*)sp-(char*)0,sizeof(genchar));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*dp++ = *sp++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * copy at most <n> items from <sp> to <dp>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid ed_genncpy(register genchar *dp,register const genchar *sp, int n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp = (genchar*)roundof((char*)dp-(char*)0,sizeof(genchar));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = (const genchar*)roundof((char*)sp-(char*)0,sizeof(genchar));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(n-->0 && (*dp++ = *sp++));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * find the string length of <str>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint ed_genlen(register const genchar *str)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const genchar *sp = str;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = (const genchar*)roundof((char*)sp-(char*)0,sizeof(genchar));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*sp++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sp-str-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_ESH || SHOPT_VSH */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef future
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns 1 when <n> bytes starting at <a> and <b> are equal
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int compare(register const char *a,register const char *b,register int n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(n-->0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*a++ != *b++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_OLDTERMIO
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# include <sys/termio.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef ECHOCTL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define ECHOCTL 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* !ECHOCTL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ott ep->e_ott
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * For backward compatibility only
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This version will use termios when possible, otherwise termio
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinint tcgetattr(int fd, struct termios *tt)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Edit_t *ep = (Edit_t*)(sh_getinterp()->ed_context);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int r,i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_tcgeta = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_echoctl = (ECHOCTL!=0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((r=ioctl(fd,TCGETS,tt))>=0 || errno!=EINVAL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(r);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((r=ioctl(fd,TCGETA,&ott)) >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tt->c_lflag = ott.c_lflag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tt->c_oflag = ott.c_oflag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tt->c_iflag = ott.c_iflag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tt->c_cflag = ott.c_cflag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(i=0; i<NCC; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tt->c_cc[i] = ott.c_cc[i];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_tcgeta++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_echoctl = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(r);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinint tcsetattr(int fd,int mode,struct termios *tt)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Edit_t *ep = (Edit_t*)(sh_getinterp()->ed_context);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->e_tcgeta)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ott.c_lflag = tt->c_lflag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ott.c_oflag = tt->c_oflag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ott.c_iflag = tt->c_iflag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ott.c_cflag = tt->c_cflag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(i=0; i<NCC; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ott.c_cc[i] = tt->c_cc[i];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tt->c_lflag&ECHOCTL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ott.c_lflag &= ~(ECHOCTL|IEXTEN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ott.c_iflag &= ~(IGNCR|ICRNL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ott.c_iflag |= INLCR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ott.c_cc[VEOF]= ESC; /* ESC -> eof char */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ott.c_cc[VEOL] = '\r'; /* CR -> eol char */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ott.c_cc[VEOL2] = tt->c_cc[VEOF]; /* EOF -> eol char */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TCSANOW:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = TCSETA;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TCSADRAIN:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = TCSETAW;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TCSAFLUSH:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = TCSETAF;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(ioctl(fd,mode,&ott));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(ioctl(fd,mode,tt));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_OLDTERMIO */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if KSHELL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Execute keyboard trap on given buffer <inbuff> of given size <isize>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * <mode> < 0 for vi insert mode
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int keytrap(Edit_t *ep,char *inbuff,register int insize, int bufsize, int mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int savexit;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = ep->sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char buff[MAXLINE];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ed_external(ep->e_inbuf,cp=buff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = ep->e_inbuf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inbuff[insize] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_col = ep->e_cur;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode== -2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_col++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ep->e_vi_insert = ESC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ep->e_vi_insert = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(ED_CHRNOD,inbuff,NV_NOFREE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(ED_COLNOD,(char*)&ep->e_col,NV_NOFREE|NV_INTEGER);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(ED_TXTNOD,(char*)cp,NV_NOFREE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(ED_MODENOD,ep->e_vi_insert,NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin savexit = shp->savexit;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_trap(shp->st.trap[SH_KEYTRAP],0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->savexit = savexit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((cp = nv_getval(ED_CHRNOD)) == inbuff)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_unset(ED_CHRNOD);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(bufsize>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strncpy(inbuff,cp,bufsize);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin inbuff[bufsize-1]='\0';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin insize = strlen(inbuff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin insize = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_unset(ED_TXTNOD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(insize);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* KSHELL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid *ed_open(Shell_t *shp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Edit_t *ed = newof(0,Edit_t,1,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ed->sh = shp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(ed->e_macro,"_??");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((void*)ed);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}