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