db_input.c revision 12720
18876Srgrimes/*
24Srgrimes * Mach Operating System
34Srgrimes * Copyright (c) 1991,1990 Carnegie Mellon University
44Srgrimes * All Rights Reserved.
58876Srgrimes *
64Srgrimes * Permission to use, copy, modify and distribute this software and its
74Srgrimes * documentation is hereby granted, provided that both the copyright
84Srgrimes * notice and this permission notice appear in all copies of the
94Srgrimes * software, derivative works or modified versions, and any portions
104Srgrimes * thereof, and that both notices appear in supporting documentation.
118876Srgrimes *
128876Srgrimes * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
134Srgrimes * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
144Srgrimes * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
158876Srgrimes *
164Srgrimes * Carnegie Mellon requests users of this software to return to
178876Srgrimes *
184Srgrimes *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
194Srgrimes *  School of Computer Science
204Srgrimes *  Carnegie Mellon University
214Srgrimes *  Pittsburgh PA 15213-3890
228876Srgrimes *
234Srgrimes * any improvements or extensions that they make and grant Carnegie the
244Srgrimes * rights to redistribute these changes.
254Srgrimes *
2612720Sphk *	$Id: db_input.c,v 1.10 1995/12/07 12:44:51 davidg Exp $
274Srgrimes */
28623Srgrimes
294Srgrimes/*
304Srgrimes *	Author: David B. Golub, Carnegie Mellon University
314Srgrimes *	Date:	7/90
324Srgrimes */
334Srgrimes
342056Swollman#include <sys/param.h>
352056Swollman#include <sys/systm.h>
362056Swollman#include <sys/proc.h>
3712662Sdg#include <vm/vm_param.h>
382056Swollman#include <ddb/ddb.h>
392056Swollman#include <ddb/db_output.h>
402056Swollman#include <machine/cons.h>
414Srgrimes
424Srgrimes/*
434Srgrimes * Character input and editing.
444Srgrimes */
454Srgrimes
464Srgrimes/*
474Srgrimes * We don't track output position while editing input,
484Srgrimes * since input always ends with a new-line.  We just
494Srgrimes * reset the line position at the end.
504Srgrimes */
5112720Sphkstatic char *	db_lbuf_start;	/* start of input line buffer */
5212720Sphkstatic char *	db_lbuf_end;	/* end of input line buffer */
5312720Sphkstatic char *	db_lc;		/* current character */
5412720Sphkstatic char *	db_le;		/* one past last character */
554Srgrimes
564Srgrimes#define	CTRL(c)		((c) & 0x1f)
574Srgrimes#define	isspace(c)	((c) == ' ' || (c) == '\t')
584Srgrimes#define	BLANK		' '
594Srgrimes#define	BACKUP		'\b'
604Srgrimes
6112515Sphkstatic int	cnmaygetc __P((void));
6212515Sphkstatic void	db_delete __P((int n, int bwd));
6312515Sphkstatic int	db_inputchar __P((int c));
6412515Sphkstatic void	db_putnchars __P((int c, int count));
6512515Sphkstatic void	db_putstring __P((char *s, int count));
6612473Sbde
674Srgrimesvoid
684Srgrimesdb_putstring(s, count)
694Srgrimes	char	*s;
704Srgrimes	int	count;
714Srgrimes{
724Srgrimes	while (--count >= 0)
734Srgrimes	    cnputc(*s++);
744Srgrimes}
754Srgrimes
764Srgrimesvoid
774Srgrimesdb_putnchars(c, count)
784Srgrimes	int	c;
794Srgrimes	int	count;
804Srgrimes{
814Srgrimes	while (--count >= 0)
824Srgrimes	    cnputc(c);
834Srgrimes}
844Srgrimes
854Srgrimes/*
864Srgrimes * Delete N characters, forward or backward
874Srgrimes */
884Srgrimes#define	DEL_FWD		0
894Srgrimes#define	DEL_BWD		1
904Srgrimesvoid
914Srgrimesdb_delete(n, bwd)
924Srgrimes	int	n;
934Srgrimes	int	bwd;
944Srgrimes{
954Srgrimes	register char *p;
964Srgrimes
974Srgrimes	if (bwd) {
984Srgrimes	    db_lc -= n;
994Srgrimes	    db_putnchars(BACKUP, n);
1004Srgrimes	}
1014Srgrimes	for (p = db_lc; p < db_le-n; p++) {
1024Srgrimes	    *p = *(p+n);
1034Srgrimes	    cnputc(*p);
1044Srgrimes	}
1054Srgrimes	db_putnchars(BLANK, n);
1064Srgrimes	db_putnchars(BACKUP, db_le - db_lc);
1074Srgrimes	db_le -= n;
1084Srgrimes}
1094Srgrimes
1104Srgrimes/* returns TRUE at end-of-line */
1114Srgrimesint
1124Srgrimesdb_inputchar(c)
1134Srgrimes	int	c;
1144Srgrimes{
1154Srgrimes	switch (c) {
1164Srgrimes	    case CTRL('b'):
1174Srgrimes		/* back up one character */
1184Srgrimes		if (db_lc > db_lbuf_start) {
1194Srgrimes		    cnputc(BACKUP);
1204Srgrimes		    db_lc--;
1214Srgrimes		}
1224Srgrimes		break;
1234Srgrimes	    case CTRL('f'):
1244Srgrimes		/* forward one character */
1254Srgrimes		if (db_lc < db_le) {
1264Srgrimes		    cnputc(*db_lc);
1274Srgrimes		    db_lc++;
1284Srgrimes		}
1294Srgrimes		break;
1304Srgrimes	    case CTRL('a'):
1314Srgrimes		/* beginning of line */
1324Srgrimes		while (db_lc > db_lbuf_start) {
1334Srgrimes		    cnputc(BACKUP);
1344Srgrimes		    db_lc--;
1354Srgrimes		}
1364Srgrimes		break;
1374Srgrimes	    case CTRL('e'):
1384Srgrimes		/* end of line */
1394Srgrimes		while (db_lc < db_le) {
1404Srgrimes		    cnputc(*db_lc);
1414Srgrimes		    db_lc++;
1424Srgrimes		}
1434Srgrimes		break;
1444Srgrimes	    case CTRL('h'):
1454Srgrimes	    case 0177:
1464Srgrimes		/* erase previous character */
1474Srgrimes		if (db_lc > db_lbuf_start)
1484Srgrimes		    db_delete(1, DEL_BWD);
1494Srgrimes		break;
1504Srgrimes	    case CTRL('d'):
1514Srgrimes		/* erase next character */
1524Srgrimes		if (db_lc < db_le)
1534Srgrimes		    db_delete(1, DEL_FWD);
1544Srgrimes		break;
1554Srgrimes	    case CTRL('k'):
1564Srgrimes		/* delete to end of line */
1574Srgrimes		if (db_lc < db_le)
1584Srgrimes		    db_delete(db_le - db_lc, DEL_FWD);
1594Srgrimes		break;
1604Srgrimes	    case CTRL('t'):
1614Srgrimes		/* twiddle last 2 characters */
1624Srgrimes		if (db_lc >= db_lbuf_start + 2) {
1634Srgrimes		    c = db_lc[-2];
1644Srgrimes		    db_lc[-2] = db_lc[-1];
1654Srgrimes		    db_lc[-1] = c;
1664Srgrimes		    cnputc(BACKUP);
1674Srgrimes		    cnputc(BACKUP);
1684Srgrimes		    cnputc(db_lc[-2]);
1694Srgrimes		    cnputc(db_lc[-1]);
1704Srgrimes		}
1714Srgrimes		break;
1724Srgrimes	    case CTRL('r'):
1734Srgrimes		db_putstring("^R\n", 3);
1744Srgrimes		if (db_le > db_lbuf_start) {
1754Srgrimes		    db_putstring(db_lbuf_start, db_le - db_lbuf_start);
1764Srgrimes		    db_putnchars(BACKUP, db_le - db_lc);
1774Srgrimes		}
1784Srgrimes		break;
1794Srgrimes	    case '\n':
1804Srgrimes	    case '\r':
1814Srgrimes		*db_le++ = c;
1824Srgrimes		return (1);
1834Srgrimes	    default:
1844Srgrimes		if (db_le == db_lbuf_end) {
1854Srgrimes		    cnputc('\007');
1864Srgrimes		}
1874Srgrimes		else if (c >= ' ' && c <= '~') {
1884Srgrimes		    register char *p;
1894Srgrimes
1904Srgrimes		    for (p = db_le; p > db_lc; p--)
1914Srgrimes			*p = *(p-1);
1924Srgrimes		    *db_lc++ = c;
1934Srgrimes		    db_le++;
1944Srgrimes		    cnputc(c);
1954Srgrimes		    db_putstring(db_lc, db_le - db_lc);
1964Srgrimes		    db_putnchars(BACKUP, db_le - db_lc);
1974Srgrimes		}
1984Srgrimes		break;
1994Srgrimes	}
2004Srgrimes	return (0);
2014Srgrimes}
2024Srgrimes
2034Srgrimesint
20412473Sbdecnmaygetc()
2052112Swollman{
2062112Swollman	return (-1);
2072112Swollman}
2082112Swollman
2092112Swollmanint
2104Srgrimesdb_readline(lstart, lsize)
2114Srgrimes	char *	lstart;
2124Srgrimes	int	lsize;
2134Srgrimes{
2144Srgrimes	db_force_whitespace();	/* synch output position */
2154Srgrimes
2164Srgrimes	db_lbuf_start = lstart;
2174Srgrimes	db_lbuf_end   = lstart + lsize;
2184Srgrimes	db_lc = lstart;
2194Srgrimes	db_le = lstart;
2204Srgrimes
2214Srgrimes	while (!db_inputchar(cngetc()))
2224Srgrimes	    continue;
2234Srgrimes
2244Srgrimes	db_putchar('\n');	/* synch output position */
2254Srgrimes
2264Srgrimes	*db_le = 0;
2274Srgrimes	return (db_le - db_lbuf_start);
2284Srgrimes}
2294Srgrimes
2304Srgrimesvoid
2314Srgrimesdb_check_interrupt()
2324Srgrimes{
2334Srgrimes	register int	c;
2344Srgrimes
2354Srgrimes	c = cnmaygetc();
2364Srgrimes	switch (c) {
2374Srgrimes	    case -1:		/* no character */
2384Srgrimes		return;
2394Srgrimes
2404Srgrimes	    case CTRL('c'):
2414Srgrimes		db_error((char *)0);
2424Srgrimes		/*NOTREACHED*/
2434Srgrimes
2444Srgrimes	    case CTRL('s'):
2454Srgrimes		do {
2464Srgrimes		    c = cnmaygetc();
2474Srgrimes		    if (c == CTRL('c'))
2484Srgrimes			db_error((char *)0);
2494Srgrimes		} while (c != CTRL('q'));
2504Srgrimes		break;
2514Srgrimes
2524Srgrimes	    default:
2534Srgrimes		/* drop on floor */
2544Srgrimes		break;
2554Srgrimes	}
2564Srgrimes}
2574Srgrimes
2584Srgrimes/* called from kdb_trap in db_interface.c */
259798Swollmanvoid
2604Srgrimescnpollc (flag)
261798Swollman	int flag;
2624Srgrimes{
2638876Srgrimes}
264