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