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