db_input.c revision 15680
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.12 1995/12/10 19:07:59 bde 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
37#include <machine/cons.h>
38
39#include <ddb/ddb.h>
40#include <ddb/db_output.h>
41
42/*
43 * Character input and editing.
44 */
45
46/*
47 * We don't track output position while editing input,
48 * since input always ends with a new-line.  We just
49 * reset the line position at the end.
50 */
51static char *	db_lbuf_start;	/* start of input line buffer */
52static char *	db_lbuf_end;	/* end of input line buffer */
53static char *	db_lc;		/* current character */
54static char *	db_le;		/* one past last character */
55
56#define	CTRL(c)		((c) & 0x1f)
57#define	isspace(c)	((c) == ' ' || (c) == '\t')
58#define	BLANK		' '
59#define	BACKUP		'\b'
60
61static int	cnmaygetc __P((void));
62static void	db_delete __P((int n, int bwd));
63static int	db_inputchar __P((int c));
64static void	db_putnchars __P((int c, int count));
65static void	db_putstring __P((char *s, int count));
66
67void
68db_putstring(s, count)
69	char	*s;
70	int	count;
71{
72	while (--count >= 0)
73	    cnputc(*s++);
74}
75
76void
77db_putnchars(c, count)
78	int	c;
79	int	count;
80{
81	while (--count >= 0)
82	    cnputc(c);
83}
84
85/*
86 * Delete N characters, forward or backward
87 */
88#define	DEL_FWD		0
89#define	DEL_BWD		1
90void
91db_delete(n, bwd)
92	int	n;
93	int	bwd;
94{
95	register char *p;
96
97	if (bwd) {
98	    db_lc -= n;
99	    db_putnchars(BACKUP, n);
100	}
101	for (p = db_lc; p < db_le-n; p++) {
102	    *p = *(p+n);
103	    cnputc(*p);
104	}
105	db_putnchars(BLANK, n);
106	db_putnchars(BACKUP, db_le - db_lc);
107	db_le -= n;
108}
109
110/* returns TRUE at end-of-line */
111int
112db_inputchar(c)
113	int	c;
114{
115	switch (c) {
116	    case CTRL('b'):
117		/* back up one character */
118		if (db_lc > db_lbuf_start) {
119		    cnputc(BACKUP);
120		    db_lc--;
121		}
122		break;
123	    case CTRL('f'):
124		/* forward one character */
125		if (db_lc < db_le) {
126		    cnputc(*db_lc);
127		    db_lc++;
128		}
129		break;
130	    case CTRL('a'):
131		/* beginning of line */
132		while (db_lc > db_lbuf_start) {
133		    cnputc(BACKUP);
134		    db_lc--;
135		}
136		break;
137	    case CTRL('e'):
138		/* end of line */
139		while (db_lc < db_le) {
140		    cnputc(*db_lc);
141		    db_lc++;
142		}
143		break;
144	    case CTRL('h'):
145	    case 0177:
146		/* erase previous character */
147		if (db_lc > db_lbuf_start)
148		    db_delete(1, DEL_BWD);
149		break;
150	    case CTRL('d'):
151		/* erase next character */
152		if (db_lc < db_le)
153		    db_delete(1, DEL_FWD);
154		break;
155	    case CTRL('k'):
156		/* delete to end of line */
157		if (db_lc < db_le)
158		    db_delete(db_le - db_lc, DEL_FWD);
159		break;
160	    case CTRL('t'):
161		/* twiddle last 2 characters */
162		if (db_lc >= db_lbuf_start + 2) {
163		    c = db_lc[-2];
164		    db_lc[-2] = db_lc[-1];
165		    db_lc[-1] = c;
166		    cnputc(BACKUP);
167		    cnputc(BACKUP);
168		    cnputc(db_lc[-2]);
169		    cnputc(db_lc[-1]);
170		}
171		break;
172	    case CTRL('r'):
173		db_putstring("^R\n", 3);
174		if (db_le > db_lbuf_start) {
175		    db_putstring(db_lbuf_start, db_le - db_lbuf_start);
176		    db_putnchars(BACKUP, db_le - db_lc);
177		}
178		break;
179	    case '\n':
180	    case '\r':
181		*db_le++ = c;
182		return (1);
183	    default:
184		if (db_le == db_lbuf_end) {
185		    cnputc('\007');
186		}
187		else if (c >= ' ' && c <= '~') {
188		    register char *p;
189
190		    for (p = db_le; p > db_lc; p--)
191			*p = *(p-1);
192		    *db_lc++ = c;
193		    db_le++;
194		    cnputc(c);
195		    db_putstring(db_lc, db_le - db_lc);
196		    db_putnchars(BACKUP, db_le - db_lc);
197		}
198		break;
199	}
200	return (0);
201}
202
203int
204cnmaygetc()
205{
206	return (-1);
207}
208
209int
210db_readline(lstart, lsize)
211	char *	lstart;
212	int	lsize;
213{
214	db_force_whitespace();	/* synch output position */
215
216	db_lbuf_start = lstart;
217	db_lbuf_end   = lstart + lsize;
218	db_lc = lstart;
219	db_le = lstart;
220
221	while (!db_inputchar(cngetc()))
222	    continue;
223
224	db_printf("\n");	/* synch output position */
225
226	*db_le = 0;
227	return (db_le - db_lbuf_start);
228}
229
230void
231db_check_interrupt()
232{
233	register int	c;
234
235	c = cnmaygetc();
236	switch (c) {
237	    case -1:		/* no character */
238		return;
239
240	    case CTRL('c'):
241		db_error((char *)0);
242		/*NOTREACHED*/
243
244	    case CTRL('s'):
245		do {
246		    c = cnmaygetc();
247		    if (c == CTRL('c'))
248			db_error((char *)0);
249		} while (c != CTRL('q'));
250		break;
251
252	    default:
253		/* drop on floor */
254		break;
255	}
256}
257
258/* called from kdb_trap in db_interface.c */
259void
260cnpollc (flag)
261	int flag;
262{
263}
264