db_input.c revision 1.3 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 * 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