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