db_input.c revision 12734
1218887Sdim/*
2218887Sdim * Mach Operating System
3218887Sdim * Copyright (c) 1991,1990 Carnegie Mellon University
4218887Sdim * All Rights Reserved.
5218887Sdim *
6218887Sdim * Permission to use, copy, modify and distribute this software and its
7218887Sdim * documentation is hereby granted, provided that both the copyright
8218887Sdim * notice and this permission notice appear in all copies of the
9218887Sdim * software, derivative works or modified versions, and any portions
10218887Sdim * thereof, and that both notices appear in supporting documentation.
11218887Sdim *
12218887Sdim * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
13249423Sdim * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14249423Sdim * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15249423Sdim *
16218887Sdim * Carnegie Mellon requests users of this software to return to
17218887Sdim *
18239462Sdim *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
19218887Sdim *  School of Computer Science
20218887Sdim *  Carnegie Mellon University
21263508Sdim *  Pittsburgh PA 15213-3890
22218887Sdim *
23218887Sdim * any improvements or extensions that they make and grant Carnegie the
24218887Sdim * rights to redistribute these changes.
25218887Sdim *
26218887Sdim *	$Id: db_input.c,v 1.11 1995/12/10 13:32:37 phk Exp $
27218887Sdim */
28218887Sdim
29218887Sdim/*
30218887Sdim *	Author: David B. Golub, Carnegie Mellon University
31218887Sdim *	Date:	7/90
32218887Sdim */
33218887Sdim
34218887Sdim#include <sys/param.h>
35218887Sdim#include <sys/systm.h>
36218887Sdim
37226633Sdim#include <machine/cons.h>
38218887Sdim
39239462Sdim#include <ddb/ddb.h>
40239462Sdim#include <ddb/db_output.h>
41218887Sdim
42218887Sdim/*
43226633Sdim * Character input and editing.
44239462Sdim */
45218887Sdim
46218887Sdim/*
47218887Sdim * We don't track output position while editing input,
48218887Sdim * since input always ends with a new-line.  We just
49218887Sdim * reset the line position at the end.
50218887Sdim */
51218887Sdimstatic char *	db_lbuf_start;	/* start of input line buffer */
52218887Sdimstatic char *	db_lbuf_end;	/* end of input line buffer */
53218887Sdimstatic char *	db_lc;		/* current character */
54218887Sdimstatic char *	db_le;		/* one past last character */
55218887Sdim
56218887Sdim#define	CTRL(c)		((c) & 0x1f)
57218887Sdim#define	isspace(c)	((c) == ' ' || (c) == '\t')
58218887Sdim#define	BLANK		' '
59218887Sdim#define	BACKUP		'\b'
60218887Sdim
61218887Sdimstatic int	cnmaygetc __P((void));
62218887Sdimstatic void	db_delete __P((int n, int bwd));
63218887Sdimstatic int	db_inputchar __P((int c));
64218887Sdimstatic void	db_putnchars __P((int c, int count));
65218887Sdimstatic void	db_putstring __P((char *s, int count));
66218887Sdim
67218887Sdimvoid
68218887Sdimdb_putstring(s, count)
69218887Sdim	char	*s;
70218887Sdim	int	count;
71218887Sdim{
72218887Sdim	while (--count >= 0)
73218887Sdim	    cnputc(*s++);
74218887Sdim}
75218887Sdim
76218887Sdimvoid
77218887Sdimdb_putnchars(c, count)
78218887Sdim	int	c;
79218887Sdim	int	count;
80218887Sdim{
81218887Sdim	while (--count >= 0)
82218887Sdim	    cnputc(c);
83218887Sdim}
84218887Sdim
85218887Sdim/*
86218887Sdim * Delete N characters, forward or backward
87218887Sdim */
88218887Sdim#define	DEL_FWD		0
89218887Sdim#define	DEL_BWD		1
90218887Sdimvoid
91234353Sdimdb_delete(n, bwd)
92234353Sdim	int	n;
93234353Sdim	int	bwd;
94234353Sdim{
95234353Sdim	register char *p;
96234353Sdim
97234353Sdim	if (bwd) {
98234353Sdim	    db_lc -= n;
99234353Sdim	    db_putnchars(BACKUP, n);
100234353Sdim	}
101234353Sdim	for (p = db_lc; p < db_le-n; p++) {
102234353Sdim	    *p = *(p+n);
103234353Sdim	    cnputc(*p);
104234353Sdim	}
105234353Sdim	db_putnchars(BLANK, n);
106234353Sdim	db_putnchars(BACKUP, db_le - db_lc);
107218887Sdim	db_le -= n;
108218887Sdim}
109218887Sdim
110218887Sdim/* returns TRUE at end-of-line */
111218887Sdimint
112218887Sdimdb_inputchar(c)
113218887Sdim	int	c;
114239462Sdim{
115239462Sdim	switch (c) {
116239462Sdim	    case CTRL('b'):
117218887Sdim		/* back up one character */
118239462Sdim		if (db_lc > db_lbuf_start) {
119218887Sdim		    cnputc(BACKUP);
120218887Sdim		    db_lc--;
121218887Sdim		}
122218887Sdim		break;
123218887Sdim	    case CTRL('f'):
124239462Sdim		/* forward one character */
125218887Sdim		if (db_lc < db_le) {
126218887Sdim		    cnputc(*db_lc);
127218887Sdim		    db_lc++;
128218887Sdim		}
129218887Sdim		break;
130218887Sdim	    case CTRL('a'):
131218887Sdim		/* beginning of line */
132218887Sdim		while (db_lc > db_lbuf_start) {
133239462Sdim		    cnputc(BACKUP);
134239462Sdim		    db_lc--;
135239462Sdim		}
136218887Sdim		break;
137218887Sdim	    case CTRL('e'):
138218887Sdim		/* end of line */
139218887Sdim		while (db_lc < db_le) {
140218887Sdim		    cnputc(*db_lc);
141218887Sdim		    db_lc++;
142218887Sdim		}
143218887Sdim		break;
144239462Sdim	    case CTRL('h'):
145218887Sdim	    case 0177:
146218887Sdim		/* erase previous character */
147239462Sdim		if (db_lc > db_lbuf_start)
148218887Sdim		    db_delete(1, DEL_BWD);
149218887Sdim		break;
150218887Sdim	    case CTRL('d'):
151218887Sdim		/* erase next character */
152218887Sdim		if (db_lc < db_le)
153218887Sdim		    db_delete(1, DEL_FWD);
154218887Sdim		break;
155218887Sdim	    case CTRL('k'):
156218887Sdim		/* delete to end of line */
157218887Sdim		if (db_lc < db_le)
158218887Sdim		    db_delete(db_le - db_lc, DEL_FWD);
159218887Sdim		break;
160218887Sdim	    case CTRL('t'):
161218887Sdim		/* twiddle last 2 characters */
162218887Sdim		if (db_lc >= db_lbuf_start + 2) {
163218887Sdim		    c = db_lc[-2];
164218887Sdim		    db_lc[-2] = db_lc[-1];
165239462Sdim		    db_lc[-1] = c;
166239462Sdim		    cnputc(BACKUP);
167239462Sdim		    cnputc(BACKUP);
168239462Sdim		    cnputc(db_lc[-2]);
169239462Sdim		    cnputc(db_lc[-1]);
170239462Sdim		}
171239462Sdim		break;
172239462Sdim	    case CTRL('r'):
173239462Sdim		db_putstring("^R\n", 3);
174239462Sdim		if (db_le > db_lbuf_start) {
175239462Sdim		    db_putstring(db_lbuf_start, db_le - db_lbuf_start);
176239462Sdim		    db_putnchars(BACKUP, db_le - db_lc);
177239462Sdim		}
178239462Sdim		break;
179239462Sdim	    case '\n':
180239462Sdim	    case '\r':
181239462Sdim		*db_le++ = c;
182239462Sdim		return (1);
183263508Sdim	    default:
184263508Sdim		if (db_le == db_lbuf_end) {
185263508Sdim		    cnputc('\007');
186263508Sdim		}
187239462Sdim		else if (c >= ' ' && c <= '~') {
188239462Sdim		    register char *p;
189263508Sdim
190263508Sdim		    for (p = db_le; p > db_lc; p--)
191239462Sdim			*p = *(p-1);
192239462Sdim		    *db_lc++ = c;
193239462Sdim		    db_le++;
194239462Sdim		    cnputc(c);
195239462Sdim		    db_putstring(db_lc, db_le - db_lc);
196239462Sdim		    db_putnchars(BACKUP, db_le - db_lc);
197218887Sdim		}
198218887Sdim		break;
199218887Sdim	}
200218887Sdim	return (0);
201218887Sdim}
202239462Sdim
203234353Sdimint
204234353Sdimcnmaygetc()
205234353Sdim{
206234353Sdim	return (-1);
207239462Sdim}
208239462Sdim
209239462Sdimint
210239462Sdimdb_readline(lstart, lsize)
211239462Sdim	char *	lstart;
212239462Sdim	int	lsize;
213239462Sdim{
214239462Sdim	db_force_whitespace();	/* synch output position */
215239462Sdim
216239462Sdim	db_lbuf_start = lstart;
217239462Sdim	db_lbuf_end   = lstart + lsize;
218239462Sdim	db_lc = lstart;
219239462Sdim	db_le = lstart;
220234353Sdim
221226633Sdim	while (!db_inputchar(cngetc()))
222226633Sdim	    continue;
223218887Sdim
224218887Sdim	db_putchar('\n');	/* synch output position */
225218887Sdim
226218887Sdim	*db_le = 0;
227218887Sdim	return (db_le - db_lbuf_start);
228218887Sdim}
229221345Sdim
230218887Sdimvoid
231218887Sdimdb_check_interrupt()
232218887Sdim{
233218887Sdim	register int	c;
234218887Sdim
235218887Sdim	c = cnmaygetc();
236218887Sdim	switch (c) {
237218887Sdim	    case -1:		/* no character */
238218887Sdim		return;
239218887Sdim
240218887Sdim	    case CTRL('c'):
241234353Sdim		db_error((char *)0);
242218887Sdim		/*NOTREACHED*/
243234353Sdim
244218887Sdim	    case CTRL('s'):
245234353Sdim		do {
246218887Sdim		    c = cnmaygetc();
247234353Sdim		    if (c == CTRL('c'))
248218887Sdim			db_error((char *)0);
249218887Sdim		} while (c != CTRL('q'));
250218887Sdim		break;
251218887Sdim
252239462Sdim	    default:
253218887Sdim		/* drop on floor */
254218887Sdim		break;
255218887Sdim	}
256218887Sdim}
257218887Sdim
258218887Sdim/* called from kdb_trap in db_interface.c */
259218887Sdimvoid
260218887Sdimcnpollc (flag)
261218887Sdim	int flag;
262218887Sdim{
263218887Sdim}
264226633Sdim