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