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