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