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