db_input.c revision 2056
1193323Sed/*
2193323Sed * Mach Operating System
3193323Sed * Copyright (c) 1991,1990 Carnegie Mellon University
4193323Sed * All Rights Reserved.
5193323Sed *
6193323Sed * Permission to use, copy, modify and distribute this software and its
7193323Sed * documentation is hereby granted, provided that both the copyright
8193323Sed * notice and this permission notice appear in all copies of the
9193323Sed * software, derivative works or modified versions, and any portions
10193323Sed * thereof, and that both notices appear in supporting documentation.
11193323Sed *
12193323Sed * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
13193323Sed * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14193323Sed * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15193323Sed *
16193323Sed * Carnegie Mellon requests users of this software to return to
17193323Sed *
18218893Sdim *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
19193323Sed *  School of Computer Science
20193323Sed *  Carnegie Mellon University
21193323Sed *  Pittsburgh PA 15213-3890
22193323Sed *
23193323Sed * any improvements or extensions that they make and grant Carnegie the
24193323Sed * rights to redistribute these changes.
25193323Sed *
26193323Sed *	$Id: db_input.c,v 1.4 1993/12/19 00:49:44 wollman Exp $
27193323Sed */
28193323Sed
29193323Sed/*
30193323Sed *	Author: David B. Golub, Carnegie Mellon University
31193323Sed *	Date:	7/90
32193323Sed */
33193323Sed
34193323Sed#include <sys/param.h>
35193323Sed#include <sys/systm.h>
36193323Sed#include <sys/proc.h>
37193323Sed#include <ddb/ddb.h>
38193323Sed#include <ddb/db_output.h>
39193323Sed#include <machine/cons.h>
40193323Sed
41198892Srdivacky/*
42193323Sed * Character input and editing.
43193323Sed */
44193323Sed
45193323Sed/*
46193323Sed * We don't track output position while editing input,
47193323Sed * since input always ends with a new-line.  We just
48193323Sed * reset the line position at the end.
49193323Sed */
50193323Sedchar *	db_lbuf_start;	/* start of input line buffer */
51193323Sedchar *	db_lbuf_end;	/* end of input line buffer */
52193323Sedchar *	db_lc;		/* current character */
53198090Srdivackychar *	db_le;		/* one past last character */
54198090Srdivacky
55193323Sed#define	CTRL(c)		((c) & 0x1f)
56198090Srdivacky#define	isspace(c)	((c) == ' ' || (c) == '\t')
57198090Srdivacky#define	BLANK		' '
58198090Srdivacky#define	BACKUP		'\b'
59193323Sed
60198090Srdivackyvoid
61193323Seddb_putstring(s, count)
62198090Srdivacky	char	*s;
63193323Sed	int	count;
64193323Sed{
65193323Sed	while (--count >= 0)
66193323Sed	    cnputc(*s++);
67193323Sed}
68193323Sed
69193323Sedvoid
70193323Seddb_putnchars(c, count)
71193323Sed	int	c;
72193323Sed	int	count;
73193323Sed{
74193323Sed	while (--count >= 0)
75193323Sed	    cnputc(c);
76193323Sed}
77193323Sed
78193323Sed/*
79193323Sed * Delete N characters, forward or backward
80193323Sed */
81193323Sed#define	DEL_FWD		0
82#define	DEL_BWD		1
83void
84db_delete(n, bwd)
85	int	n;
86	int	bwd;
87{
88	register char *p;
89
90	if (bwd) {
91	    db_lc -= n;
92	    db_putnchars(BACKUP, n);
93	}
94	for (p = db_lc; p < db_le-n; p++) {
95	    *p = *(p+n);
96	    cnputc(*p);
97	}
98	db_putnchars(BLANK, n);
99	db_putnchars(BACKUP, db_le - db_lc);
100	db_le -= n;
101}
102
103/* returns TRUE at end-of-line */
104int
105db_inputchar(c)
106	int	c;
107{
108	switch (c) {
109	    case CTRL('b'):
110		/* back up one character */
111		if (db_lc > db_lbuf_start) {
112		    cnputc(BACKUP);
113		    db_lc--;
114		}
115		break;
116	    case CTRL('f'):
117		/* forward one character */
118		if (db_lc < db_le) {
119		    cnputc(*db_lc);
120		    db_lc++;
121		}
122		break;
123	    case CTRL('a'):
124		/* beginning of line */
125		while (db_lc > db_lbuf_start) {
126		    cnputc(BACKUP);
127		    db_lc--;
128		}
129		break;
130	    case CTRL('e'):
131		/* end of line */
132		while (db_lc < db_le) {
133		    cnputc(*db_lc);
134		    db_lc++;
135		}
136		break;
137	    case CTRL('h'):
138	    case 0177:
139		/* erase previous character */
140		if (db_lc > db_lbuf_start)
141		    db_delete(1, DEL_BWD);
142		break;
143	    case CTRL('d'):
144		/* erase next character */
145		if (db_lc < db_le)
146		    db_delete(1, DEL_FWD);
147		break;
148	    case CTRL('k'):
149		/* delete to end of line */
150		if (db_lc < db_le)
151		    db_delete(db_le - db_lc, DEL_FWD);
152		break;
153	    case CTRL('t'):
154		/* twiddle last 2 characters */
155		if (db_lc >= db_lbuf_start + 2) {
156		    c = db_lc[-2];
157		    db_lc[-2] = db_lc[-1];
158		    db_lc[-1] = c;
159		    cnputc(BACKUP);
160		    cnputc(BACKUP);
161		    cnputc(db_lc[-2]);
162		    cnputc(db_lc[-1]);
163		}
164		break;
165	    case CTRL('r'):
166		db_putstring("^R\n", 3);
167		if (db_le > db_lbuf_start) {
168		    db_putstring(db_lbuf_start, db_le - db_lbuf_start);
169		    db_putnchars(BACKUP, db_le - db_lc);
170		}
171		break;
172	    case '\n':
173	    case '\r':
174		*db_le++ = c;
175		return (1);
176	    default:
177		if (db_le == db_lbuf_end) {
178		    cnputc('\007');
179		}
180		else if (c >= ' ' && c <= '~') {
181		    register char *p;
182
183		    for (p = db_le; p > db_lc; p--)
184			*p = *(p-1);
185		    *db_lc++ = c;
186		    db_le++;
187		    cnputc(c);
188		    db_putstring(db_lc, db_le - db_lc);
189		    db_putnchars(BACKUP, db_le - db_lc);
190		}
191		break;
192	}
193	return (0);
194}
195
196int
197db_readline(lstart, lsize)
198	char *	lstart;
199	int	lsize;
200{
201	db_force_whitespace();	/* synch output position */
202
203	db_lbuf_start = lstart;
204	db_lbuf_end   = lstart + lsize;
205	db_lc = lstart;
206	db_le = lstart;
207
208	while (!db_inputchar(cngetc()))
209	    continue;
210
211	db_putchar('\n');	/* synch output position */
212
213	*db_le = 0;
214	return (db_le - db_lbuf_start);
215}
216
217void
218db_check_interrupt()
219{
220	register int	c;
221
222	c = cnmaygetc();
223	switch (c) {
224	    case -1:		/* no character */
225		return;
226
227	    case CTRL('c'):
228		db_error((char *)0);
229		/*NOTREACHED*/
230
231	    case CTRL('s'):
232		do {
233		    c = cnmaygetc();
234		    if (c == CTRL('c'))
235			db_error((char *)0);
236		} while (c != CTRL('q'));
237		break;
238
239	    default:
240		/* drop on floor */
241		break;
242	}
243}
244
245int
246cnmaygetc (void)
247{
248	return (-1);
249}
250
251/* called from kdb_trap in db_interface.c */
252void
253cnpollc (flag)
254	int flag;
255{
256}
257