xref: /freebsd/sys/ddb/db_input.c (revision 0c43d89a0d8e976ca494d4837f4c1f3734d2c300)
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  *	$Id: db_input.c,v 1.5 1994/08/13 03:49:19 wollman Exp $
27  */
28 
29 /*
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  */
50 char *	db_lbuf_start;	/* start of input line buffer */
51 char *	db_lbuf_end;	/* end of input line buffer */
52 char *	db_lc;		/* current character */
53 char *	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 
60 void
61 db_putstring(s, count)
62 	char	*s;
63 	int	count;
64 {
65 	while (--count >= 0)
66 	    cnputc(*s++);
67 }
68 
69 void
70 db_putnchars(c, count)
71 	int	c;
72 	int	count;
73 {
74 	while (--count >= 0)
75 	    cnputc(c);
76 }
77 
78 /*
79  * Delete N characters, forward or backward
80  */
81 #define	DEL_FWD		0
82 #define	DEL_BWD		1
83 void
84 db_delete(n, bwd)
85 	int	n;
86 	int	bwd;
87 {
88 	register char *p;
89 
90 	if (bwd) {
91 	    db_lc -= n;
92 	    db_putnchars(BACKUP, n);
93 	}
94 	for (p = db_lc; p < db_le-n; p++) {
95 	    *p = *(p+n);
96 	    cnputc(*p);
97 	}
98 	db_putnchars(BLANK, n);
99 	db_putnchars(BACKUP, db_le - db_lc);
100 	db_le -= n;
101 }
102 
103 /* returns TRUE at end-of-line */
104 int
105 db_inputchar(c)
106 	int	c;
107 {
108 	switch (c) {
109 	    case CTRL('b'):
110 		/* back up one character */
111 		if (db_lc > db_lbuf_start) {
112 		    cnputc(BACKUP);
113 		    db_lc--;
114 		}
115 		break;
116 	    case CTRL('f'):
117 		/* forward one character */
118 		if (db_lc < db_le) {
119 		    cnputc(*db_lc);
120 		    db_lc++;
121 		}
122 		break;
123 	    case CTRL('a'):
124 		/* beginning of line */
125 		while (db_lc > db_lbuf_start) {
126 		    cnputc(BACKUP);
127 		    db_lc--;
128 		}
129 		break;
130 	    case CTRL('e'):
131 		/* end of line */
132 		while (db_lc < db_le) {
133 		    cnputc(*db_lc);
134 		    db_lc++;
135 		}
136 		break;
137 	    case CTRL('h'):
138 	    case 0177:
139 		/* erase previous character */
140 		if (db_lc > db_lbuf_start)
141 		    db_delete(1, DEL_BWD);
142 		break;
143 	    case CTRL('d'):
144 		/* erase next character */
145 		if (db_lc < db_le)
146 		    db_delete(1, DEL_FWD);
147 		break;
148 	    case CTRL('k'):
149 		/* delete to end of line */
150 		if (db_lc < db_le)
151 		    db_delete(db_le - db_lc, DEL_FWD);
152 		break;
153 	    case CTRL('t'):
154 		/* twiddle last 2 characters */
155 		if (db_lc >= db_lbuf_start + 2) {
156 		    c = db_lc[-2];
157 		    db_lc[-2] = db_lc[-1];
158 		    db_lc[-1] = c;
159 		    cnputc(BACKUP);
160 		    cnputc(BACKUP);
161 		    cnputc(db_lc[-2]);
162 		    cnputc(db_lc[-1]);
163 		}
164 		break;
165 	    case CTRL('r'):
166 		db_putstring("^R\n", 3);
167 		if (db_le > db_lbuf_start) {
168 		    db_putstring(db_lbuf_start, db_le - db_lbuf_start);
169 		    db_putnchars(BACKUP, db_le - db_lc);
170 		}
171 		break;
172 	    case '\n':
173 	    case '\r':
174 		*db_le++ = c;
175 		return (1);
176 	    default:
177 		if (db_le == db_lbuf_end) {
178 		    cnputc('\007');
179 		}
180 		else if (c >= ' ' && c <= '~') {
181 		    register char *p;
182 
183 		    for (p = db_le; p > db_lc; p--)
184 			*p = *(p-1);
185 		    *db_lc++ = c;
186 		    db_le++;
187 		    cnputc(c);
188 		    db_putstring(db_lc, db_le - db_lc);
189 		    db_putnchars(BACKUP, db_le - db_lc);
190 		}
191 		break;
192 	}
193 	return (0);
194 }
195 
196 int
197 cnmaygetc (void)
198 {
199 	return (-1);
200 }
201 
202 int
203 db_readline(lstart, lsize)
204 	char *	lstart;
205 	int	lsize;
206 {
207 	db_force_whitespace();	/* synch output position */
208 
209 	db_lbuf_start = lstart;
210 	db_lbuf_end   = lstart + lsize;
211 	db_lc = lstart;
212 	db_le = lstart;
213 
214 	while (!db_inputchar(cngetc()))
215 	    continue;
216 
217 	db_putchar('\n');	/* synch output position */
218 
219 	*db_le = 0;
220 	return (db_le - db_lbuf_start);
221 }
222 
223 void
224 db_check_interrupt()
225 {
226 	register int	c;
227 
228 	c = cnmaygetc();
229 	switch (c) {
230 	    case -1:		/* no character */
231 		return;
232 
233 	    case CTRL('c'):
234 		db_error((char *)0);
235 		/*NOTREACHED*/
236 
237 	    case CTRL('s'):
238 		do {
239 		    c = cnmaygetc();
240 		    if (c == CTRL('c'))
241 			db_error((char *)0);
242 		} while (c != CTRL('q'));
243 		break;
244 
245 	    default:
246 		/* drop on floor */
247 		break;
248 	}
249 }
250 
251 /* called from kdb_trap in db_interface.c */
252 void
253 cnpollc (flag)
254 	int flag;
255 {
256 }
257