db_input.c revision 1.4 1 /* $NetBSD: db_input.c,v 1.4 1994/06/29 06:31:08 cgd Exp $ */
2
3 /*
4 * Mach Operating System
5 * Copyright (c) 1991,1990 Carnegie Mellon University
6 * All Rights Reserved.
7 *
8 * Permission to use, copy, modify and distribute this software and its
9 * documentation is hereby granted, provided that both the copyright
10 * notice and this permission notice appear in all copies of the
11 * software, derivative works or modified versions, and any portions
12 * thereof, and that both notices appear in supporting documentation.
13 *
14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
15 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
16 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17 *
18 * Carnegie Mellon requests users of this software to return to
19 *
20 * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU
21 * School of Computer Science
22 * Carnegie Mellon University
23 * Pittsburgh PA 15213-3890
24 *
25 * any improvements or extensions that they make and grant Carnegie the
26 * rights to redistribute these changes.
27 *
28 * Author: David B. Golub, Carnegie Mellon University
29 * Date: 7/90
30 */
31
32 #include <sys/param.h>
33 #include <sys/proc.h>
34
35 #include <ddb/db_output.h>
36
37 /*
38 * Character input and editing.
39 */
40
41 /*
42 * We don't track output position while editing input,
43 * since input always ends with a new-line. We just
44 * reset the line position at the end.
45 */
46 char * db_lbuf_start; /* start of input line buffer */
47 char * db_lbuf_end; /* end of input line buffer */
48 char * db_lc; /* current character */
49 char * db_le; /* one past last character */
50
51 #define CTRL(c) ((c) & 0x1f)
52 #define isspace(c) ((c) == ' ' || (c) == '\t')
53 #define BLANK ' '
54 #define BACKUP '\b'
55
56 void
57 db_putstring(s, count)
58 char *s;
59 int count;
60 {
61 while (--count >= 0)
62 cnputc(*s++);
63 }
64
65 void
66 db_putnchars(c, count)
67 int c;
68 int count;
69 {
70 while (--count >= 0)
71 cnputc(c);
72 }
73
74 /*
75 * Delete N characters, forward or backward
76 */
77 #define DEL_FWD 0
78 #define DEL_BWD 1
79 void
80 db_delete(n, bwd)
81 int n;
82 int bwd;
83 {
84 register char *p;
85
86 if (bwd) {
87 db_lc -= n;
88 db_putnchars(BACKUP, n);
89 }
90 for (p = db_lc; p < db_le-n; p++) {
91 *p = *(p+n);
92 cnputc(*p);
93 }
94 db_putnchars(BLANK, n);
95 db_putnchars(BACKUP, db_le - db_lc);
96 db_le -= n;
97 }
98
99 /* returns TRUE at end-of-line */
100 int
101 db_inputchar(c)
102 int c;
103 {
104 switch (c) {
105 case CTRL('b'):
106 /* back up one character */
107 if (db_lc > db_lbuf_start) {
108 cnputc(BACKUP);
109 db_lc--;
110 }
111 break;
112 case CTRL('f'):
113 /* forward one character */
114 if (db_lc < db_le) {
115 cnputc(*db_lc);
116 db_lc++;
117 }
118 break;
119 case CTRL('a'):
120 /* beginning of line */
121 while (db_lc > db_lbuf_start) {
122 cnputc(BACKUP);
123 db_lc--;
124 }
125 break;
126 case CTRL('e'):
127 /* end of line */
128 while (db_lc < db_le) {
129 cnputc(*db_lc);
130 db_lc++;
131 }
132 break;
133 case CTRL('h'):
134 case 0177:
135 /* erase previous character */
136 if (db_lc > db_lbuf_start)
137 db_delete(1, DEL_BWD);
138 break;
139 case CTRL('d'):
140 /* erase next character */
141 if (db_lc < db_le)
142 db_delete(1, DEL_FWD);
143 break;
144 case CTRL('k'):
145 /* delete to end of line */
146 if (db_lc < db_le)
147 db_delete(db_le - db_lc, DEL_FWD);
148 break;
149 case CTRL('t'):
150 /* twiddle last 2 characters */
151 if (db_lc >= db_lbuf_start + 2) {
152 c = db_lc[-2];
153 db_lc[-2] = db_lc[-1];
154 db_lc[-1] = c;
155 cnputc(BACKUP);
156 cnputc(BACKUP);
157 cnputc(db_lc[-2]);
158 cnputc(db_lc[-1]);
159 }
160 break;
161 case CTRL('r'):
162 db_putstring("^R\n", 3);
163 if (db_le > db_lbuf_start) {
164 db_putstring(db_lbuf_start, db_le - db_lbuf_start);
165 db_putnchars(BACKUP, db_le - db_lc);
166 }
167 break;
168 case '\n':
169 case '\r':
170 *db_le++ = c;
171 return (1);
172 default:
173 if (db_le == db_lbuf_end) {
174 cnputc('\007');
175 }
176 else if (c >= ' ' && c <= '~') {
177 register char *p;
178
179 for (p = db_le; p > db_lc; p--)
180 *p = *(p-1);
181 *db_lc++ = c;
182 db_le++;
183 cnputc(c);
184 db_putstring(db_lc, db_le - db_lc);
185 db_putnchars(BACKUP, db_le - db_lc);
186 }
187 break;
188 }
189 return (0);
190 }
191
192 int
193 db_readline(lstart, lsize)
194 char * lstart;
195 int lsize;
196 {
197 db_force_whitespace(); /* synch output position */
198
199 db_lbuf_start = lstart;
200 db_lbuf_end = lstart + lsize;
201 db_lc = lstart;
202 db_le = lstart;
203
204 while (!db_inputchar(cngetc()))
205 continue;
206
207 db_putchar('\n'); /* synch output position */
208
209 *db_le = 0;
210 return (db_le - db_lbuf_start);
211 }
212
213 void
214 db_check_interrupt()
215 {
216 register int c;
217
218 c = cnmaygetc();
219 switch (c) {
220 case -1: /* no character */
221 return;
222
223 case CTRL('c'):
224 db_error((char *)0);
225 /*NOTREACHED*/
226
227 case CTRL('s'):
228 do {
229 c = cnmaygetc();
230 if (c == CTRL('c'))
231 db_error((char *)0);
232 } while (c != CTRL('q'));
233 break;
234
235 default:
236 /* drop on floor */
237 break;
238 }
239 }
240
241 cnmaygetc ()
242 {
243 return (-1);
244 }
245
246 /* called from kdb_trap in db_interface.c */
247 cnpollc (flag)
248 {
249 }
250