db_input.c revision 1.6
1/*	$NetBSD: db_input.c,v 1.6 1994/10/26 17:57:50 mycroft Exp $	*/
2
3/*
4 * Mach Operating System
5 * Copyright (c) 1991,1990 Carnegie Mellon University
6 * All Rights Reserved.
7 *
8 * Permission to use, copy, modify and distribute this software and its
9 * documentation is hereby granted, provided that both the copyright
10 * notice and this permission notice appear in all copies of the
11 * software, derivative works or modified versions, and any portions
12 * thereof, and that both notices appear in supporting documentation.
13 *
14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
15 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
16 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17 *
18 * Carnegie Mellon requests users of this software to return to
19 *
20 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
21 *  School of Computer Science
22 *  Carnegie Mellon University
23 *  Pittsburgh PA 15213-3890
24 *
25 * any improvements or extensions that they make and grant Carnegie the
26 * rights to redistribute these changes.
27 *
28 *	Author: David B. Golub, Carnegie Mellon University
29 *	Date:	7/90
30 */
31
32#include <sys/param.h>
33#include <sys/proc.h>
34
35#include <ddb/db_output.h>
36
37/*
38 * Character input and editing.
39 */
40
41/*
42 * We don't track output position while editing input,
43 * since input always ends with a new-line.  We just
44 * reset the line position at the end.
45 */
46char *	db_lbuf_start;	/* start of input line buffer */
47char *	db_lbuf_end;	/* end of input line buffer */
48char *	db_lc;		/* current character */
49char *	db_le;		/* one past last character */
50
51#define	CTRL(c)		((c) & 0x1f)
52#define	isspace(c)	((c) == ' ' || (c) == '\t')
53#define	BLANK		' '
54#define	BACKUP		'\b'
55
56void
57db_putstring(s, count)
58	char	*s;
59	int	count;
60{
61	while (--count >= 0)
62	    cnputc(*s++);
63}
64
65void
66db_putnchars(c, count)
67	int	c;
68	int	count;
69{
70	while (--count >= 0)
71	    cnputc(c);
72}
73
74/*
75 * Delete N characters, forward or backward
76 */
77#define	DEL_FWD		0
78#define	DEL_BWD		1
79void
80db_delete(n, bwd)
81	int	n;
82	int	bwd;
83{
84	register char *p;
85
86	if (bwd) {
87	    db_lc -= n;
88	    db_putnchars(BACKUP, n);
89	}
90	for (p = db_lc; p < db_le-n; p++) {
91	    *p = *(p+n);
92	    cnputc(*p);
93	}
94	db_putnchars(BLANK, n);
95	db_putnchars(BACKUP, db_le - db_lc);
96	db_le -= n;
97}
98
99/* returns TRUE at end-of-line */
100int
101db_inputchar(c)
102	int	c;
103{
104	switch (c) {
105	    case CTRL('b'):
106		/* back up one character */
107		if (db_lc > db_lbuf_start) {
108		    cnputc(BACKUP);
109		    db_lc--;
110		}
111		break;
112	    case CTRL('f'):
113		/* forward one character */
114		if (db_lc < db_le) {
115		    cnputc(*db_lc);
116		    db_lc++;
117		}
118		break;
119	    case CTRL('a'):
120		/* beginning of line */
121		while (db_lc > db_lbuf_start) {
122		    cnputc(BACKUP);
123		    db_lc--;
124		}
125		break;
126	    case CTRL('e'):
127		/* end of line */
128		while (db_lc < db_le) {
129		    cnputc(*db_lc);
130		    db_lc++;
131		}
132		break;
133	    case CTRL('h'):
134	    case 0177:
135		/* erase previous character */
136		if (db_lc > db_lbuf_start)
137		    db_delete(1, DEL_BWD);
138		break;
139	    case CTRL('d'):
140		/* erase next character */
141		if (db_lc < db_le)
142		    db_delete(1, DEL_FWD);
143		break;
144	    case CTRL('k'):
145		/* delete to end of line */
146		if (db_lc < db_le)
147		    db_delete(db_le - db_lc, DEL_FWD);
148		break;
149	    case CTRL('t'):
150		/* twiddle last 2 characters */
151		if (db_lc >= db_lbuf_start + 2) {
152		    c = db_lc[-2];
153		    db_lc[-2] = db_lc[-1];
154		    db_lc[-1] = c;
155		    cnputc(BACKUP);
156		    cnputc(BACKUP);
157		    cnputc(db_lc[-2]);
158		    cnputc(db_lc[-1]);
159		}
160		break;
161	    case CTRL('r'):
162		db_putstring("^R\n", 3);
163		if (db_le > db_lbuf_start) {
164		    db_putstring(db_lbuf_start, db_le - db_lbuf_start);
165		    db_putnchars(BACKUP, db_le - db_lc);
166		}
167		break;
168	    case '\n':
169	    case '\r':
170		*db_le++ = c;
171		return (1);
172	    default:
173		if (db_le == db_lbuf_end) {
174		    cnputc('\007');
175		}
176		else if (c >= ' ' && c <= '~') {
177		    register char *p;
178
179		    for (p = db_le; p > db_lc; p--)
180			*p = *(p-1);
181		    *db_lc++ = c;
182		    db_le++;
183		    cnputc(c);
184		    db_putstring(db_lc, db_le - db_lc);
185		    db_putnchars(BACKUP, db_le - db_lc);
186		}
187		break;
188	}
189	return (0);
190}
191
192int
193db_readline(lstart, lsize)
194	char *	lstart;
195	int	lsize;
196{
197	db_force_whitespace();	/* synch output position */
198
199	db_lbuf_start = lstart;
200	db_lbuf_end   = lstart + lsize;
201	db_lc = lstart;
202	db_le = lstart;
203
204	while (!db_inputchar(cngetc()))
205	    continue;
206
207	db_putchar('\n');	/* synch output position */
208
209	*db_le = 0;
210	return (db_le - db_lbuf_start);
211}
212
213void
214db_check_interrupt()
215{
216	register int	c;
217
218	c = cnmaygetc();
219	switch (c) {
220	    case -1:		/* no character */
221		return;
222
223	    case CTRL('c'):
224		db_error((char *)0);
225		/*NOTREACHED*/
226
227	    case CTRL('s'):
228		do {
229		    c = cnmaygetc();
230		    if (c == CTRL('c')) {
231			db_error((char *)0);
232			/*NOTREACHED*/
233		    }
234		} while (c != CTRL('q'));
235		break;
236
237	    default:
238		/* drop on floor */
239		break;
240	}
241}
242
243cnmaygetc ()
244{
245	return (-1);
246}
247