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