db_input.c revision 2112
1/*
2 * Mach Operating System
3 * Copyright (c) 1991,1990 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
13 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
19 *  School of Computer Science
20 *  Carnegie Mellon University
21 *  Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie the
24 * rights to redistribute these changes.
25 *
26 *	$Id: db_input.c,v 1.5 1994/08/13 03:49:19 wollman Exp $
27 */
28
29/*
30 *	Author: David B. Golub, Carnegie Mellon University
31 *	Date:	7/90
32 */
33
34#include <sys/param.h>
35#include <sys/systm.h>
36#include <sys/proc.h>
37#include <ddb/ddb.h>
38#include <ddb/db_output.h>
39#include <machine/cons.h>
40
41/*
42 * Character input and editing.
43 */
44
45/*
46 * We don't track output position while editing input,
47 * since input always ends with a new-line.  We just
48 * reset the line position at the end.
49 */
50char *	db_lbuf_start;	/* start of input line buffer */
51char *	db_lbuf_end;	/* end of input line buffer */
52char *	db_lc;		/* current character */
53char *	db_le;		/* one past last character */
54
55#define	CTRL(c)		((c) & 0x1f)
56#define	isspace(c)	((c) == ' ' || (c) == '\t')
57#define	BLANK		' '
58#define	BACKUP		'\b'
59
60void
61db_putstring(s, count)
62	char	*s;
63	int	count;
64{
65	while (--count >= 0)
66	    cnputc(*s++);
67}
68
69void
70db_putnchars(c, count)
71	int	c;
72	int	count;
73{
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
197cnmaygetc (void)
198{
199	return (-1);
200}
201
202int
203db_readline(lstart, lsize)
204	char *	lstart;
205	int	lsize;
206{
207	db_force_whitespace();	/* synch output position */
208
209	db_lbuf_start = lstart;
210	db_lbuf_end   = lstart + lsize;
211	db_lc = lstart;
212	db_le = lstart;
213
214	while (!db_inputchar(cngetc()))
215	    continue;
216
217	db_putchar('\n');	/* synch output position */
218
219	*db_le = 0;
220	return (db_le - db_lbuf_start);
221}
222
223void
224db_check_interrupt()
225{
226	register int	c;
227
228	c = cnmaygetc();
229	switch (c) {
230	    case -1:		/* no character */
231		return;
232
233	    case CTRL('c'):
234		db_error((char *)0);
235		/*NOTREACHED*/
236
237	    case CTRL('s'):
238		do {
239		    c = cnmaygetc();
240		    if (c == CTRL('c'))
241			db_error((char *)0);
242		} while (c != CTRL('q'));
243		break;
244
245	    default:
246		/* drop on floor */
247		break;
248	}
249}
250
251/* called from kdb_trap in db_interface.c */
252void
253cnpollc (flag)
254	int flag;
255{
256}
257