db_input.c revision 2112
1156136Sdavidxu/*
2156136Sdavidxu * Mach Operating System
3156136Sdavidxu * Copyright (c) 1991,1990 Carnegie Mellon University
4156136Sdavidxu * All Rights Reserved.
5156136Sdavidxu *
6156136Sdavidxu * Permission to use, copy, modify and distribute this software and its
7156136Sdavidxu * documentation is hereby granted, provided that both the copyright
8156136Sdavidxu * notice and this permission notice appear in all copies of the
9156136Sdavidxu * software, derivative works or modified versions, and any portions
10156136Sdavidxu * thereof, and that both notices appear in supporting documentation.
11156136Sdavidxu *
12156136Sdavidxu * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
13156136Sdavidxu * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14156136Sdavidxu * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15156136Sdavidxu *
16156136Sdavidxu * Carnegie Mellon requests users of this software to return to
17156136Sdavidxu *
18156136Sdavidxu *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
19156136Sdavidxu *  School of Computer Science
20156136Sdavidxu *  Carnegie Mellon University
21156136Sdavidxu *  Pittsburgh PA 15213-3890
22156136Sdavidxu *
23156136Sdavidxu * any improvements or extensions that they make and grant Carnegie the
24156136Sdavidxu * rights to redistribute these changes.
25156136Sdavidxu *
26156136Sdavidxu *	$Id: db_input.c,v 1.5 1994/08/13 03:49:19 wollman Exp $
27156136Sdavidxu */
28156136Sdavidxu
29156136Sdavidxu/*
30156136Sdavidxu *	Author: David B. Golub, Carnegie Mellon University
31156136Sdavidxu *	Date:	7/90
32156136Sdavidxu */
33156136Sdavidxu
34156136Sdavidxu#include <sys/param.h>
35156136Sdavidxu#include <sys/systm.h>
36156136Sdavidxu#include <sys/proc.h>
37156136Sdavidxu#include <ddb/ddb.h>
38156136Sdavidxu#include <ddb/db_output.h>
39156136Sdavidxu#include <machine/cons.h>
40156136Sdavidxu
41156136Sdavidxu/*
42156136Sdavidxu * Character input and editing.
43156136Sdavidxu */
44156136Sdavidxu
45156136Sdavidxu/*
46156136Sdavidxu * We don't track output position while editing input,
47156136Sdavidxu * since input always ends with a new-line.  We just
48156136Sdavidxu * reset the line position at the end.
49156136Sdavidxu */
50156136Sdavidxuchar *	db_lbuf_start;	/* start of input line buffer */
51156136Sdavidxuchar *	db_lbuf_end;	/* end of input line buffer */
52156136Sdavidxuchar *	db_lc;		/* current character */
53156136Sdavidxuchar *	db_le;		/* one past last character */
54156136Sdavidxu
55156136Sdavidxu#define	CTRL(c)		((c) & 0x1f)
56156136Sdavidxu#define	isspace(c)	((c) == ' ' || (c) == '\t')
57156136Sdavidxu#define	BLANK		' '
58156136Sdavidxu#define	BACKUP		'\b'
59156136Sdavidxu
60156136Sdavidxuvoid
61156136Sdavidxudb_putstring(s, count)
62156136Sdavidxu	char	*s;
63156136Sdavidxu	int	count;
64156136Sdavidxu{
65156142Sdavidxu	while (--count >= 0)
66156142Sdavidxu	    cnputc(*s++);
67156142Sdavidxu}
68156142Sdavidxu
69156142Sdavidxuvoid
70156142Sdavidxudb_putnchars(c, count)
71156142Sdavidxu	int	c;
72156142Sdavidxu	int	count;
73156142Sdavidxu{
74156142Sdavidxu	while (--count >= 0)
75156142Sdavidxu	    cnputc(c);
76156142Sdavidxu}
77156142Sdavidxu
78156142Sdavidxu/*
79156142Sdavidxu * Delete N characters, forward or backward
80156136Sdavidxu */
81156136Sdavidxu#define	DEL_FWD		0
82156136Sdavidxu#define	DEL_BWD		1
83156136Sdavidxuvoid
84156136Sdavidxudb_delete(n, bwd)
85156136Sdavidxu	int	n;
86156136Sdavidxu	int	bwd;
87156136Sdavidxu{
88156136Sdavidxu	register char *p;
89156136Sdavidxu
90156136Sdavidxu	if (bwd) {
91156136Sdavidxu	    db_lc -= n;
92156136Sdavidxu	    db_putnchars(BACKUP, n);
93156136Sdavidxu	}
94156136Sdavidxu	for (p = db_lc; p < db_le-n; p++) {
95156136Sdavidxu	    *p = *(p+n);
96156136Sdavidxu	    cnputc(*p);
97156136Sdavidxu	}
98156136Sdavidxu	db_putnchars(BLANK, n);
99156136Sdavidxu	db_putnchars(BACKUP, db_le - db_lc);
100156136Sdavidxu	db_le -= n;
101156136Sdavidxu}
102156136Sdavidxu
103156136Sdavidxu/* returns TRUE at end-of-line */
104156136Sdavidxuint
105156136Sdavidxudb_inputchar(c)
106156136Sdavidxu	int	c;
107156136Sdavidxu{
108156136Sdavidxu	switch (c) {
109156136Sdavidxu	    case CTRL('b'):
110156136Sdavidxu		/* back up one character */
111156136Sdavidxu		if (db_lc > db_lbuf_start) {
112156136Sdavidxu		    cnputc(BACKUP);
113156136Sdavidxu		    db_lc--;
114156136Sdavidxu		}
115156136Sdavidxu		break;
116156136Sdavidxu	    case CTRL('f'):
117156136Sdavidxu		/* forward one character */
118156136Sdavidxu		if (db_lc < db_le) {
119156136Sdavidxu		    cnputc(*db_lc);
120156136Sdavidxu		    db_lc++;
121156136Sdavidxu		}
122156136Sdavidxu		break;
123156136Sdavidxu	    case CTRL('a'):
124156136Sdavidxu		/* beginning of line */
125156136Sdavidxu		while (db_lc > db_lbuf_start) {
126156136Sdavidxu		    cnputc(BACKUP);
127156136Sdavidxu		    db_lc--;
128156136Sdavidxu		}
129156136Sdavidxu		break;
130156136Sdavidxu	    case CTRL('e'):
131156136Sdavidxu		/* end of line */
132156136Sdavidxu		while (db_lc < db_le) {
133156136Sdavidxu		    cnputc(*db_lc);
134156136Sdavidxu		    db_lc++;
135156136Sdavidxu		}
136156136Sdavidxu		break;
137156136Sdavidxu	    case CTRL('h'):
138156136Sdavidxu	    case 0177:
139156136Sdavidxu		/* erase previous character */
140156136Sdavidxu		if (db_lc > db_lbuf_start)
141156136Sdavidxu		    db_delete(1, DEL_BWD);
142156136Sdavidxu		break;
143156136Sdavidxu	    case CTRL('d'):
144156136Sdavidxu		/* erase next character */
145156136Sdavidxu		if (db_lc < db_le)
146156136Sdavidxu		    db_delete(1, DEL_FWD);
147156136Sdavidxu		break;
148156136Sdavidxu	    case CTRL('k'):
149156136Sdavidxu		/* delete to end of line */
150156136Sdavidxu		if (db_lc < db_le)
151156136Sdavidxu		    db_delete(db_le - db_lc, DEL_FWD);
152156136Sdavidxu		break;
153156136Sdavidxu	    case CTRL('t'):
154156136Sdavidxu		/* twiddle last 2 characters */
155156136Sdavidxu		if (db_lc >= db_lbuf_start + 2) {
156156136Sdavidxu		    c = db_lc[-2];
157156136Sdavidxu		    db_lc[-2] = db_lc[-1];
158156136Sdavidxu		    db_lc[-1] = c;
159156136Sdavidxu		    cnputc(BACKUP);
160156136Sdavidxu		    cnputc(BACKUP);
161156136Sdavidxu		    cnputc(db_lc[-2]);
162156136Sdavidxu		    cnputc(db_lc[-1]);
163156136Sdavidxu		}
164156136Sdavidxu		break;
165156136Sdavidxu	    case CTRL('r'):
166156136Sdavidxu		db_putstring("^R\n", 3);
167156136Sdavidxu		if (db_le > db_lbuf_start) {
168156136Sdavidxu		    db_putstring(db_lbuf_start, db_le - db_lbuf_start);
169156136Sdavidxu		    db_putnchars(BACKUP, db_le - db_lc);
170156136Sdavidxu		}
171156136Sdavidxu		break;
172156136Sdavidxu	    case '\n':
173156136Sdavidxu	    case '\r':
174156136Sdavidxu		*db_le++ = c;
175156136Sdavidxu		return (1);
176156136Sdavidxu	    default:
177156136Sdavidxu		if (db_le == db_lbuf_end) {
178156136Sdavidxu		    cnputc('\007');
179156136Sdavidxu		}
180156136Sdavidxu		else if (c >= ' ' && c <= '~') {
181156136Sdavidxu		    register char *p;
182156136Sdavidxu
183156136Sdavidxu		    for (p = db_le; p > db_lc; p--)
184156136Sdavidxu			*p = *(p-1);
185156136Sdavidxu		    *db_lc++ = c;
186156136Sdavidxu		    db_le++;
187156136Sdavidxu		    cnputc(c);
188156136Sdavidxu		    db_putstring(db_lc, db_le - db_lc);
189156136Sdavidxu		    db_putnchars(BACKUP, db_le - db_lc);
190156136Sdavidxu		}
191156136Sdavidxu		break;
192156136Sdavidxu	}
193156136Sdavidxu	return (0);
194156136Sdavidxu}
195156136Sdavidxu
196156136Sdavidxuint
197156136Sdavidxucnmaygetc (void)
198156136Sdavidxu{
199156136Sdavidxu	return (-1);
200156136Sdavidxu}
201156136Sdavidxu
202156136Sdavidxuint
203156136Sdavidxudb_readline(lstart, lsize)
204156136Sdavidxu	char *	lstart;
205156136Sdavidxu	int	lsize;
206156136Sdavidxu{
207156136Sdavidxu	db_force_whitespace();	/* synch output position */
208156136Sdavidxu
209156136Sdavidxu	db_lbuf_start = lstart;
210156136Sdavidxu	db_lbuf_end   = lstart + lsize;
211156136Sdavidxu	db_lc = lstart;
212156136Sdavidxu	db_le = lstart;
213156136Sdavidxu
214156136Sdavidxu	while (!db_inputchar(cngetc()))
215156136Sdavidxu	    continue;
216156136Sdavidxu
217156136Sdavidxu	db_putchar('\n');	/* synch output position */
218156136Sdavidxu
219156136Sdavidxu	*db_le = 0;
220156136Sdavidxu	return (db_le - db_lbuf_start);
221156136Sdavidxu}
222156136Sdavidxu
223156136Sdavidxuvoid
224156136Sdavidxudb_check_interrupt()
225156136Sdavidxu{
226156136Sdavidxu	register int	c;
227156136Sdavidxu
228156136Sdavidxu	c = cnmaygetc();
229156136Sdavidxu	switch (c) {
230156136Sdavidxu	    case -1:		/* no character */
231156136Sdavidxu		return;
232156136Sdavidxu
233156136Sdavidxu	    case CTRL('c'):
234156136Sdavidxu		db_error((char *)0);
235156136Sdavidxu		/*NOTREACHED*/
236156136Sdavidxu
237156136Sdavidxu	    case CTRL('s'):
238156136Sdavidxu		do {
239156136Sdavidxu		    c = cnmaygetc();
240156136Sdavidxu		    if (c == CTRL('c'))
241156136Sdavidxu			db_error((char *)0);
242156136Sdavidxu		} while (c != CTRL('q'));
243156136Sdavidxu		break;
244156136Sdavidxu
245156136Sdavidxu	    default:
246156136Sdavidxu		/* drop on floor */
247156136Sdavidxu		break;
248156136Sdavidxu	}
249156136Sdavidxu}
250156136Sdavidxu
251156136Sdavidxu/* called from kdb_trap in db_interface.c */
252156136Sdavidxuvoid
253156136Sdavidxucnpollc (flag)
254156136Sdavidxu	int flag;
255156136Sdavidxu{
256156136Sdavidxu}
257156136Sdavidxu