Category : OS/2 Files
Archive   : KSH48.ZIP
Filename : EDIT.C

 
Output of file : EDIT.C contained in archive : KSH48.ZIP
/*
* Command line editing - common code
*
*/

#include "config.h"
#if defined(EMACS) || defined(VI)

#ifndef lint
static char *RCSid = "$Id: edit.c,v 1.5 1992/08/10 12:02:25 sjg Exp $";
#endif

#include "stdh.h"
#include
#include
#include
#include
#include
#ifndef NOSTDHDRS
# include
#endif
#include "sh.h"
#include "tty.h"
#define EXTERN
#include "edit.h"
#undef EXTERN

#ifdef _CRAY2
extern unsigned sleep();
#endif


static int x_noecho = 0;

/*
* read an edited command line
*/
int
x_read(fd, buf, len)
int fd; /* not used */
char *buf;
size_t len;
{
static int setup_done = 0;
int i;

if (setup_done != 42)
{
setup_done = 42; /* these get done once only */
x_do_init = 1;
x_col = 0;
ed_erase = -1, ed_kill = -1, ed_werase = -1, ed_intr = -1, ed_quit = -1;
x_adj_ok = 1;
x_adj_done = 0;
}
if (x_do_init)
x_init();

if (x_noecho)
return(read(ttyfd, buf, len));

(void)x_mode(TRUE);
#ifdef EMACS
if (flag[FEMACS])
i = x_emacs(buf, len);
else
#endif
#ifdef VI
if (flag[FVI])
i = x_vi(buf, len);
else
#endif
i = -1; /* internal error */
(void) x_mode(FALSE);
if (i > 4 && strstr(buf, "stty"))
x_do_init = 1;
if (i < 0 && errno == EINTR)
trapsig(SIGINT);
return i;
}

/* tty I/O */

int
x_getc()
{
#ifdef OS2
char c = _read_kbd(0, 1, 0);
return c == 0 ? 0xE0 : c;
#else
char c;

/*
* This allows the arival of a SIGCHLD to not disturb us until
* we are ready.
* BSD and other systems that automatically rety a read after
* an interrupt don't need this but it doesn't do any harm
* either.
*/
retry:
if (read(ttyfd, &c, 1) != 1)
{
if (sigchld_caught) /* just a SIGCHLD ? */
{
goto retry;
}
return -1;
}
return c & 0x7F;
#endif
}

void
x_flush()
{
fflush(stdout);
}


/* NAME:
* x_adjust - redraw the line adjusting starting point etc.
*

* DESCRIPTION:
* This function is called when we have exceeded the bounds
* of the edit window. It increments x_adj_done so that
* functions like x_ins and x_delete know that we have been
* called and can skip the x_bs() stuff which has already
* been done by x_redraw.
*
* RETURN VALUE:
* None
*/

void
x_adjust()
{
x_adj_done++; /* flag the fact that we were called. */
#ifdef EMACS
/*
* we had a promblem if the prompt length > x_cols / 2
*/
if ((xbp = xcp - (x_displen / 2)) < xbuf)
xbp = xbuf;
xlp_valid = FALSE;
x_redraw(x_cols);
#endif
x_flush();
}

void
x_putc(c)
int c;
{
if (c == '\r' || c == '\n')
x_col = 0;
if (x_col < x_cols)
{
putc(c, stdout);
switch(c)
{
case BEL:
break;
case '\r':
case '\n':
break;
case '\b':
x_col--;
break;
default:
x_col++;
break;
}
}
if (x_adj_ok && (x_col < 0 || x_col >= (x_cols - 2)))
{
x_adjust();
}
}

#ifdef DEBUG
int
x_debug_info()
{
x_flush();
printf("\nksh debug:\n");
printf("\tx_col == %d,\t\tx_cols == %d,\tx_displen == %d\n",
x_col, x_cols, x_displen);
printf("\txcp == 0x%lx,\txep == 0x%lx\n", (long) xcp, (long) xep);
printf("\txbp == 0x%lx,\txbuf == 0x%lx\n", (long) xbp, (long) xbuf);
printf("\txlp == 0x%lx\n", (long) xlp);
printf("\txlp == 0x%lx\n", (long) x_lastcp());
printf("\n");
x_redraw(-1);
return 0;
}
#endif

void
x_puts(s)
register char *s;
{
register int adj = x_adj_done;

while (*s && adj == x_adj_done)
x_putc(*s++);
}

#ifdef _BSD
static struct sgttyb cb, cborig;
#ifdef TIOCGATC
static struct ttychars lchars, lcharsorig;
#else
static struct tchars tchars, tcharsorig;
#ifdef TIOCGLTC
static struct ltchars ltchars, ltcharsorig;
#endif
#endif
#else
#ifdef _POSIX_TERM
static struct termios cb, cborig;
#else
static struct termio cb, cborig;
#endif
#endif

/* initialize editing mode */
void
x_init()
{
x_do_init = 0;
#ifdef _BSD
(void)ioctl(ttyfd, TIOCGETP, &cborig);
if ((cborig.sg_flags & ECHO) == 0)
x_noecho = 1;
cb = cborig;
ed_erase = cb.sg_erase;
ed_kill = cb.sg_kill;
cb.sg_flags &= ~ECHO;
cb.sg_flags |= CBREAK;
#ifdef TIOCGATC
(void)ioctl(ttyfd, TIOCGATC, &lcharsorig);
lchars = lcharsorig;
ed_werase = lchars.tc_werasc;
lchars.tc_suspc = -1;
lchars.tc_dsuspc = -1;
lchars.tc_lnextc = -1;
lchars.tc_statc = -1;
lchars.tc_intrc = -1;
lchars.tc_quitc = -1;
lchars.tc_rprntc = -1;
#else
(void)ioctl(ttyfd, TIOCGETC, &tcharsorig);
#ifdef TIOCGLTC
(void)ioctl(ttyfd, TIOCGLTC, <charsorig);
#endif
tchars = tcharsorig;
#ifdef TIOCGLTC
ltchars = ltcharsorig;
ed_werase = ltchars.t_werasc;
ltchars = ltcharsorig;
ltchars.t_suspc = -1;
ltchars.t_dsuspc = -1;
ltchars.t_lnextc = -1;
#endif
tchars.t_intrc = -1;
tchars.t_quitc = -1;
#ifdef TIOCGLTC
ltchars.t_rprntc = -1;
#endif
#endif
#else /* !_BSD */
#ifdef _POSIX_TERM
(void) tcgetattr(ttyfd, &cborig);
#else
(void)ioctl(ttyfd, TCGETA, &cborig);
#endif
if ((cborig.c_lflag & ECHO) == 0)
x_noecho = 1;
cb = cborig;
ed_erase = cb.c_cc[VERASE]; /* TODO */
ed_kill = cb.c_cc[VKILL]; /* TODO */
ed_intr = cb.c_cc[VINTR];
ed_quit = cb.c_cc[VQUIT];
#ifdef _CRAY2 /* brain-damaged terminal handler */
cb.c_lflag &= ~(ICANON|ECHO);
/* rely on print routine to map '\n' to CR,LF */
#else
cb.c_iflag &= ~(INLCR|ICRNL);
#ifdef _BSD_SYSV /* need to force CBREAK instead of RAW (need CRMOD on output) */
cb.c_lflag &= ~(ICANON|ECHO);
#else
#ifdef SWTCH /* need CBREAK to handle swtch char */
cb.c_lflag &= ~(ICANON|ECHO);
cb.c_lflag |= ISIG;
cb.c_cc[VINTR] = 0377;
cb.c_cc[VQUIT] = 0377;
#else
cb.c_lflag &= ~(ISIG|ICANON|ECHO);
#endif
#endif
cb.c_cc[VTIME] = 0;
cb.c_cc[VMIN] = 1;
#endif /* _CRAY2 */
#endif
#ifdef EMACS
x_emacs_keys(ed_erase, ed_kill, ed_werase, ed_intr, ed_quit);
#endif
}

static bool_t x_cur_mode = FALSE;

/* set/clear tty cbreak mode */

#ifdef _BSD
bool_t
x_mode(onoff)
bool_t onoff;
{
bool_t prev;

if (x_cur_mode == onoff) return x_cur_mode;
prev = x_cur_mode;
x_cur_mode = onoff;
if (onoff) {
(void)ioctl(ttyfd, TIOCSETN, &cb);
#ifdef TIOCGATC
(void)ioctl(ttyfd, TIOCSATC, &lchars);
#else
(void)ioctl(ttyfd, TIOCSETC, &tchars);
#ifdef TIOCGLTC
(void)ioctl(ttyfd, TIOCSLTC, <chars);
#endif
#endif
}
else {
(void)ioctl(ttyfd, TIOCSETN, &cborig);
#ifdef TIOCGATC
(void)ioctl(ttyfd, TIOCSATC, &lcharsorig);
#else
(void)ioctl(ttyfd, TIOCSETC, &tcharsorig);
#ifdef TIOCGLTC
(void)ioctl(ttyfd, TIOCSLTC, <charsorig);
#endif
#endif
}
return prev;
}

#else /* !_BSD */

#ifdef OS2

bool_t
x_mode(onoff)
bool_t onoff;
{
bool_t prev;
if (x_cur_mode == onoff)
return x_cur_mode;
prev = x_cur_mode;
x_cur_mode = onoff;

/* setkbdmode(onoff); */

return prev;
}

#else

bool_t
x_mode(onoff)
bool_t onoff;
{
bool_t prev;

if (x_cur_mode == onoff) return x_cur_mode;
prev = x_cur_mode;
x_cur_mode = onoff;

if (onoff) {
#ifdef _POSIX_TERM
(void) tcsetattr(ttyfd, TCSADRAIN, &cb);
#else
#ifndef TCSETAW /* e.g. Cray-2 */
/* first wait for output to drain */
#ifdef TCSBRK
(void)ioctl(ttyfd, TCSBRK, 1);
#else /* the following kludge is minimally intrusive, but sometimes fails */
(void)sleep((unsigned)1); /* fake it */
#endif
#endif
#if defined(_BSD_SYSV) || !defined(TCSETAW)
/* _BSD_SYSV needs to force TIOCSETN instead of TIOCSETP (preserve type-ahead) */
(void)ioctl(ttyfd, TCSETA, &cb);
#else
(void)ioctl(ttyfd, TCSETAW, &cb);
#endif
#endif
}
else {
#ifdef _POSIX_TERM
(void) tcsetattr(ttyfd, TCSADRAIN, &cborig);
#else
#ifndef TCSETAW /* e.g. Cray-2 */
/* first wait for output to drain */
#ifdef TCSBRK
(void)ioctl(ttyfd, TCSBRK, 1);
#else
/* doesn't seem to be necessary when leaving xmode */
/* (void)sleep((unsigned)1); /* fake it */
#endif
#endif
#if defined(_BSD_SYSV) || !defined(TCSETAW)
/* _BSD_SYSV needs to force TIOCSETN instead of TIOCSETP (preserve type-ahead) */
(void)ioctl(ttyfd, TCSETA, &cborig);
#else
(void)ioctl(ttyfd, TCSETAW, &cborig);
#endif
#endif
}
return prev;
}
#endif /* OS2 */
#endif /* _BSD */


/* NAME:
* promptlen - calculate the length of PS1 etc.
*
* DESCRIPTION:
* This function is based on a fix from [email protected]
* It fixes a bug in that if PS1 contains '!', the length
* given by strlen() is probably wrong.
*
* RETURN VALUE:
* length
*/

int
promptlen(cp)
register char *cp;
{
register int count = 0;

while (*cp)
{
if ( *cp++ != '!' )
count++;
else
if ( *cp == '!' )
{
cp++;
count++;
}
else if ( *cp == '.' )
{
cp++;
count += strlen(strval(global("PWD")));
}
else
{
register int i = source->line;

do
{
count ++;
}
while( ( i /= 10 ) > 0 );
}
}
return count;
}


/*
* this function check the environment
* for FCEDIT,EDITOR or VISUAL
* as a hint to what edit mode is desired.
*/
init_editmode()
{
static char *ev[] = { "FCEDIT", "EDITOR", "VISUAL", NULL };
register int i;
register char *rcp;

for (i = 0; ev[i]; i++)
{
#ifdef DEBUG
(void) fprintf(stderr, "check %s\n", ev[i]);
#endif
if ((rcp = strval(global(ev[i]))) && *rcp)
break;
}
if (ev[i] && rcp)
{
set_editmode(rcp);
}
return 0;
}

void
set_editmode(ed)
char *ed;
{
register char *rcp;

#ifdef DEBUG
(void) fprintf(stderr, "set_editmode(%s)\n", ed);
#endif
if (rcp = strrchr(ed, '/'))
ed = ++rcp;
#ifdef EMACS
if (strstr(ed, "emacs"))
{
flag[FVI] = 0;
flag[FEMACS] = 1;
}
#endif
#if defined(EMACS) && defined(VI)
else
#endif
#ifdef VI
if (strstr(ed, "vi"))
{
flag[FVI] = 1;
flag[FEMACS] = 0;
}
#endif
}
#endif


  3 Responses to “Category : OS/2 Files
Archive   : KSH48.ZIP
Filename : EDIT.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/