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