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