db_input.c revision 2056
197403Sobrien/*
297403Sobrien * Mach Operating System
397403Sobrien * Copyright (c) 1991,1990 Carnegie Mellon University
497403Sobrien * All Rights Reserved.
597403Sobrien *
697403Sobrien * Permission to use, copy, modify and distribute this software and its
797403Sobrien * documentation is hereby granted, provided that both the copyright
897403Sobrien * notice and this permission notice appear in all copies of the
997403Sobrien * software, derivative works or modified versions, and any portions
1097403Sobrien * thereof, and that both notices appear in supporting documentation.
1197403Sobrien *
1297403Sobrien * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
1397403Sobrien * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
1497403Sobrien * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
1597403Sobrien *
1697403Sobrien * Carnegie Mellon requests users of this software to return to
1797403Sobrien *
18169691Skan *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
1997403Sobrien *  School of Computer Science
2097403Sobrien *  Carnegie Mellon University
2197403Sobrien *  Pittsburgh PA 15213-3890
2297403Sobrien *
2397403Sobrien * any improvements or extensions that they make and grant Carnegie the
2497403Sobrien * rights to redistribute these changes.
2597403Sobrien *
2697403Sobrien *	$Id: db_input.c,v 1.4 1993/12/19 00:49:44 wollman Exp $
2797403Sobrien */
2897403Sobrien
2997403Sobrien/*
3097403Sobrien *	Author: David B. Golub, Carnegie Mellon University
3197403Sobrien *	Date:	7/90
3297403Sobrien */
3397403Sobrien
3497403Sobrien#include <sys/param.h>
3597403Sobrien#include <sys/systm.h>
3697403Sobrien#include <sys/proc.h>
3797403Sobrien#include <ddb/ddb.h>
3897403Sobrien#include <ddb/db_output.h>
3997403Sobrien#include <machine/cons.h>
4097403Sobrien
4197403Sobrien/*
4297403Sobrien * Character input and editing.
4397403Sobrien */
4497403Sobrien
4597403Sobrien/*
4697403Sobrien * We don't track output position while editing input,
4797403Sobrien * since input always ends with a new-line.  We just
4897403Sobrien * reset the line position at the end.
4997403Sobrien */
5097403Sobrienchar *	db_lbuf_start;	/* start of input line buffer */
5197403Sobrienchar *	db_lbuf_end;	/* end of input line buffer */
5297403Sobrienchar *	db_lc;		/* current character */
5397403Sobrienchar *	db_le;		/* one past last character */
5497403Sobrien
5597403Sobrien#define	CTRL(c)		((c) & 0x1f)
56169691Skan#define	isspace(c)	((c) == ' ' || (c) == '\t')
57169691Skan#define	BLANK		' '
5897403Sobrien#define	BACKUP		'\b'
5997403Sobrien
60132720Skanvoid
61132720Skandb_putstring(s, count)
6297403Sobrien	char	*s;
6397403Sobrien	int	count;
6497403Sobrien{
6597403Sobrien	while (--count >= 0)
6697403Sobrien	    cnputc(*s++);
6797403Sobrien}
6897403Sobrien
69132720Skanvoid
70132720Skandb_putnchars(c, count)
71132720Skan	int	c;
7297403Sobrien	int	count;
73132720Skan{
74	while (--count >= 0)
75	    cnputc(c);
76}
77
78/*
79 * Delete N characters, forward or backward
80 */
81#define	DEL_FWD		0
82#define	DEL_BWD		1
83void
84db_delete(n, bwd)
85	int	n;
86	int	bwd;
87{
88	register char *p;
89
90	if (bwd) {
91	    db_lc -= n;
92	    db_putnchars(BACKUP, n);
93	}
94	for (p = db_lc; p < db_le-n; p++) {
95	    *p = *(p+n);
96	    cnputc(*p);
97	}
98	db_putnchars(BLANK, n);
99	db_putnchars(BACKUP, db_le - db_lc);
100	db_le -= n;
101}
102
103/* returns TRUE at end-of-line */
104int
105db_inputchar(c)
106	int	c;
107{
108	switch (c) {
109	    case CTRL('b'):
110		/* back up one character */
111		if (db_lc > db_lbuf_start) {
112		    cnputc(BACKUP);
113		    db_lc--;
114		}
115		break;
116	    case CTRL('f'):
117		/* forward one character */
118		if (db_lc < db_le) {
119		    cnputc(*db_lc);
120		    db_lc++;
121		}
122		break;
123	    case CTRL('a'):
124		/* beginning of line */
125		while (db_lc > db_lbuf_start) {
126		    cnputc(BACKUP);
127		    db_lc--;
128		}
129		break;
130	    case CTRL('e'):
131		/* end of line */
132		while (db_lc < db_le) {
133		    cnputc(*db_lc);
134		    db_lc++;
135		}
136		break;
137	    case CTRL('h'):
138	    case 0177:
139		/* erase previous character */
140		if (db_lc > db_lbuf_start)
141		    db_delete(1, DEL_BWD);
142		break;
143	    case CTRL('d'):
144		/* erase next character */
145		if (db_lc < db_le)
146		    db_delete(1, DEL_FWD);
147		break;
148	    case CTRL('k'):
149		/* delete to end of line */
150		if (db_lc < db_le)
151		    db_delete(db_le - db_lc, DEL_FWD);
152		break;
153	    case CTRL('t'):
154		/* twiddle last 2 characters */
155		if (db_lc >= db_lbuf_start + 2) {
156		    c = db_lc[-2];
157		    db_lc[-2] = db_lc[-1];
158		    db_lc[-1] = c;
159		    cnputc(BACKUP);
160		    cnputc(BACKUP);
161		    cnputc(db_lc[-2]);
162		    cnputc(db_lc[-1]);
163		}
164		break;
165	    case CTRL('r'):
166		db_putstring("^R\n", 3);
167		if (db_le > db_lbuf_start) {
168		    db_putstring(db_lbuf_start, db_le - db_lbuf_start);
169		    db_putnchars(BACKUP, db_le - db_lc);
170		}
171		break;
172	    case '\n':
173	    case '\r':
174		*db_le++ = c;
175		return (1);
176	    default:
177		if (db_le == db_lbuf_end) {
178		    cnputc('\007');
179		}
180		else if (c >= ' ' && c <= '~') {
181		    register char *p;
182
183		    for (p = db_le; p > db_lc; p--)
184			*p = *(p-1);
185		    *db_lc++ = c;
186		    db_le++;
187		    cnputc(c);
188		    db_putstring(db_lc, db_le - db_lc);
189		    db_putnchars(BACKUP, db_le - db_lc);
190		}
191		break;
192	}
193	return (0);
194}
195
196int
197db_readline(lstart, lsize)
198	char *	lstart;
199	int	lsize;
200{
201	db_force_whitespace();	/* synch output position */
202
203	db_lbuf_start = lstart;
204	db_lbuf_end   = lstart + lsize;
205	db_lc = lstart;
206	db_le = lstart;
207
208	while (!db_inputchar(cngetc()))
209	    continue;
210
211	db_putchar('\n');	/* synch output position */
212
213	*db_le = 0;
214	return (db_le - db_lbuf_start);
215}
216
217void
218db_check_interrupt()
219{
220	register int	c;
221
222	c = cnmaygetc();
223	switch (c) {
224	    case -1:		/* no character */
225		return;
226
227	    case CTRL('c'):
228		db_error((char *)0);
229		/*NOTREACHED*/
230
231	    case CTRL('s'):
232		do {
233		    c = cnmaygetc();
234		    if (c == CTRL('c'))
235			db_error((char *)0);
236		} while (c != CTRL('q'));
237		break;
238
239	    default:
240		/* drop on floor */
241		break;
242	}
243}
244
245int
246cnmaygetc (void)
247{
248	return (-1);
249}
250
251/* called from kdb_trap in db_interface.c */
252void
253cnpollc (flag)
254	int flag;
255{
256}
257