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