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