db_input.c revision 4
1209513Simp/*
2209513Simp * Mach Operating System
3209552Simp * Copyright (c) 1991,1990 Carnegie Mellon University
4222528Sbz * All Rights Reserved.
5222528Sbz *
6209513Simp * Permission to use, copy, modify and distribute this software and its
7222528Sbz * documentation is hereby granted, provided that both the copyright
8222528Sbz * notice and this permission notice appear in all copies of the
9222528Sbz * software, derivative works or modified versions, and any portions
10209513Simp * thereof, and that both notices appear in supporting documentation.
11209513Simp *
12209513Simp * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
13209513Simp * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14209513Simp * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15209513Simp *
16209513Simp * Carnegie Mellon requests users of this software to return to
17209513Simp *
18209513Simp *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
19209513Simp *  School of Computer Science
20209513Simp *  Carnegie Mellon University
21209513Simp *  Pittsburgh PA 15213-3890
22209513Simp *
23209513Simp * any improvements or extensions that they make and grant Carnegie the
24209513Simp * rights to redistribute these changes.
25209513Simp */
26209513Simp/*
27209513Simp * HISTORY
28209513Simp * $Log: db_input.c,v $
29209513Simp * Revision 1.1  1992/03/25  21:45:10  pace
30209513Simp * Initial revision
31209513Simp *
32209513Simp * Revision 2.4  91/02/14  14:41:53  mrt
33209513Simp * 	Add input line editing.
34209513Simp * 	[90/11/11            dbg]
35209513Simp *
36209513Simp * Revision 2.3  91/02/05  17:06:32  mrt
37209513Simp * 	Changed to new Mach copyright
38209513Simp * 	[91/01/31  16:18:13  mrt]
39209513Simp *
40209513Simp * Revision 2.2  90/08/27  21:51:03  dbg
41209513Simp * 	Reduce lint.
42209513Simp * 	[90/08/07            dbg]
43209513Simp * 	Created.
44209513Simp * 	[90/07/25            dbg]
45209513Simp *
46209513Simp */
47209513Simp/*
48209513Simp *	Author: David B. Golub, Carnegie Mellon University
49209513Simp *	Date:	7/90
50209513Simp */
51209513Simp
52209513Simp#include "param.h"
53220059Sjpaetzel#include "proc.h"
54220059Sjpaetzel#include <ddb/db_output.h>
55209513Simp
56209513Simp/*
57209513Simp * Character input and editing.
58209513Simp */
59209513Simp
60209513Simp/*
61209513Simp * We don't track output position while editing input,
62217170Sjpaetzel * since input always ends with a new-line.  We just
63209513Simp * reset the line position at the end.
64209513Simp */
65209513Simpchar *	db_lbuf_start;	/* start of input line buffer */
66209513Simpchar *	db_lbuf_end;	/* end of input line buffer */
67209513Simpchar *	db_lc;		/* current character */
68209513Simpchar *	db_le;		/* one past last character */
69209513Simp
70209513Simp#define	CTRL(c)		((c) & 0x1f)
71209513Simp#define	isspace(c)	((c) == ' ' || (c) == '\t')
72209513Simp#define	BLANK		' '
73209513Simp#define	BACKUP		'\b'
74220059Sjpaetzel
75209513Simpvoid
76220059Sjpaetzeldb_putstring(s, count)
77211730Simp	char	*s;
78209513Simp	int	count;
79209513Simp{
80209513Simp	while (--count >= 0)
81209513Simp	    cnputc(*s++);
82220059Sjpaetzel}
83209513Simp
84209513Simpvoid
85209513Simpdb_putnchars(c, count)
86217170Sjpaetzel	int	c;
87217170Sjpaetzel	int	count;
88217170Sjpaetzel{
89209513Simp	while (--count >= 0)
90209513Simp	    cnputc(c);
91209513Simp}
92209513Simp
93209513Simp/*
94209513Simp * Delete N characters, forward or backward
95209513Simp */
96209513Simp#define	DEL_FWD		0
97209513Simp#define	DEL_BWD		1
98209513Simpvoid
99209513Simpdb_delete(n, bwd)
100209513Simp	int	n;
101209513Simp	int	bwd;
102209513Simp{
103220059Sjpaetzel	register char *p;
104209513Simp
105209513Simp	if (bwd) {
106209513Simp	    db_lc -= n;
107232890Sjpaetzel	    db_putnchars(BACKUP, n);
108232890Sjpaetzel	}
109232890Sjpaetzel	for (p = db_lc; p < db_le-n; p++) {
110232890Sjpaetzel	    *p = *(p+n);
111209513Simp	    cnputc(*p);
112209513Simp	}
113220059Sjpaetzel	db_putnchars(BLANK, n);
114209513Simp	db_putnchars(BACKUP, db_le - db_lc);
115209513Simp	db_le -= n;
116209513Simp}
117209513Simp
118209513Simp/* returns TRUE at end-of-line */
119209513Simpint
120209513Simpdb_inputchar(c)
121209513Simp	int	c;
122209513Simp{
123209513Simp	switch (c) {
124217170Sjpaetzel	    case CTRL('b'):
125209513Simp		/* back up one character */
126209513Simp		if (db_lc > db_lbuf_start) {
127217170Sjpaetzel		    cnputc(BACKUP);
128209513Simp		    db_lc--;
129209513Simp		}
130222528Sbz		break;
131222528Sbz	    case CTRL('f'):
132222528Sbz		/* forward one character */
133222528Sbz		if (db_lc < db_le) {
134222528Sbz		    cnputc(*db_lc);
135222528Sbz		    db_lc++;
136222528Sbz		}
137222528Sbz		break;
138222528Sbz	    case CTRL('a'):
139222528Sbz		/* beginning of line */
140222528Sbz		while (db_lc > db_lbuf_start) {
141222528Sbz		    cnputc(BACKUP);
142222528Sbz		    db_lc--;
143222528Sbz		}
144232890Sjpaetzel		break;
145222528Sbz	    case CTRL('e'):
146222528Sbz		/* end of line */
147222528Sbz		while (db_lc < db_le) {
148222528Sbz		    cnputc(*db_lc);
149222528Sbz		    db_lc++;
150222528Sbz		}
151222528Sbz		break;
152232890Sjpaetzel	    case CTRL('h'):
153232890Sjpaetzel	    case 0177:
154232890Sjpaetzel		/* erase previous character */
155232890Sjpaetzel		if (db_lc > db_lbuf_start)
156222528Sbz		    db_delete(1, DEL_BWD);
157232890Sjpaetzel		break;
158222528Sbz	    case CTRL('d'):
159222528Sbz		/* erase next character */
160222528Sbz		if (db_lc < db_le)
161222528Sbz		    db_delete(1, DEL_FWD);
162222528Sbz		break;
163222528Sbz	    case CTRL('k'):
164222528Sbz		/* delete to end of line */
165222528Sbz		if (db_lc < db_le)
166222528Sbz		    db_delete(db_le - db_lc, DEL_FWD);
167222528Sbz		break;
168209513Simp	    case CTRL('t'):
169222528Sbz		/* twiddle last 2 characters */
170222528Sbz		if (db_lc >= db_lbuf_start + 2) {
171222528Sbz		    c = db_lc[-2];
172222528Sbz		    db_lc[-2] = db_lc[-1];
173222528Sbz		    db_lc[-1] = c;
174222528Sbz		    cnputc(BACKUP);
175222528Sbz		    cnputc(BACKUP);
176222528Sbz		    cnputc(db_lc[-2]);
177222528Sbz		    cnputc(db_lc[-1]);
178222528Sbz		}
179222528Sbz		break;
180222528Sbz	    case CTRL('r'):
181222528Sbz		db_putstring("^R\n", 3);
182222528Sbz		if (db_le > db_lbuf_start) {
183222528Sbz		    db_putstring(db_lbuf_start, db_le - db_lbuf_start);
184222528Sbz		    db_putnchars(BACKUP, db_le - db_lc);
185222528Sbz		}
186222528Sbz		break;
187222528Sbz	    case '\n':
188222528Sbz	    case '\r':
189209513Simp		*db_le++ = c;
190209513Simp		return (1);
191209513Simp	    default:
192209513Simp		if (db_le == db_lbuf_end) {
193209513Simp		    cnputc('\007');
194209513Simp		}
195234987Sjpaetzel		else if (c >= ' ' && c <= '~') {
196209513Simp		    register char *p;
197209513Simp
198209513Simp		    for (p = db_le; p > db_lc; p--)
199209513Simp			*p = *(p-1);
200209513Simp		    *db_lc++ = c;
201209513Simp		    db_le++;
202209513Simp		    cnputc(c);
203209513Simp		    db_putstring(db_lc, db_le - db_lc);
204209513Simp		    db_putnchars(BACKUP, db_le - db_lc);
205209513Simp		}
206222528Sbz		break;
207222528Sbz	}
208209513Simp	return (0);
209209513Simp}
210222528Sbz
211222528Sbzint
212222528Sbzdb_readline(lstart, lsize)
213209513Simp	char *	lstart;
214222528Sbz	int	lsize;
215234987Sjpaetzel{
216222528Sbz	db_force_whitespace();	/* synch output position */
217222528Sbz
218222528Sbz	db_lbuf_start = lstart;
219222528Sbz	db_lbuf_end   = lstart + lsize;
220222528Sbz	db_lc = lstart;
221222528Sbz	db_le = lstart;
222222528Sbz
223234987Sjpaetzel	while (!db_inputchar(cngetc()))
224222528Sbz	    continue;
225222528Sbz
226209513Simp	db_putchar('\n');	/* synch output position */
227222528Sbz
228222528Sbz	*db_le = 0;
229222528Sbz	return (db_le - db_lbuf_start);
230209513Simp}
231209513Simp
232209513Simpvoid
233222528Sbzdb_check_interrupt()
234222528Sbz{
235222528Sbz	register int	c;
236222528Sbz
237222528Sbz	c = cnmaygetc();
238222528Sbz	switch (c) {
239222528Sbz	    case -1:		/* no character */
240222528Sbz		return;
241209513Simp
242234987Sjpaetzel	    case CTRL('c'):
243234987Sjpaetzel		db_error((char *)0);
244234987Sjpaetzel		/*NOTREACHED*/
245234987Sjpaetzel
246234987Sjpaetzel	    case CTRL('s'):
247234987Sjpaetzel		do {
248209513Simp		    c = cnmaygetc();
249209513Simp		    if (c == CTRL('c'))
250209513Simp			db_error((char *)0);
251220059Sjpaetzel		} while (c != CTRL('q'));
252209513Simp		break;
253209513Simp
254209513Simp	    default:
255222528Sbz		/* drop on floor */
256222528Sbz		break;
257222528Sbz	}
258222528Sbz}
259222528Sbz
260222528Sbzcnmaygetc ()
261209513Simp{
262234987Sjpaetzel	return (-1);
263234987Sjpaetzel}
264234987Sjpaetzel
265234987Sjpaetzel/* called from kdb_trap in db_interface.c */
266209513Simpcnpollc (flag)
267222528Sbz{
268234987Sjpaetzel}
269234987Sjpaetzel