2 * Mach Operating System
3 * Copyright (c) 1991,1990 Carnegie Mellon University
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.
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.
16 * Carnegie Mellon requests users of this software to return to
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
23 * any improvements or extensions that they make and grant Carnegie the
24 * rights to redistribute these changes.
26 * $FreeBSD: src/sys/ddb/db_input.c,v 1.28.2.1 2002/03/08 16:37:10 yar Exp $
27 * $DragonFly: src/sys/ddb/db_input.c,v 1.4 2003/08/27 10:47:13 rob Exp $
31 * Author: David B. Golub, Carnegie Mellon University
35 #include <sys/param.h>
36 #include <sys/systm.h>
40 #include <ddb/db_output.h>
43 * Character input and editing.
47 * We don't track output position while editing input,
48 * since input always ends with a new-line. We just
49 * reset the line position at the end.
51 static char * db_lbuf_start; /* start of input line buffer */
52 static char * db_lbuf_end; /* end of input line buffer */
53 static char * db_lc; /* current character */
54 static char * db_le; /* one past last character */
57 * Simple input line history support.
59 static char db_lhistory[2048];
60 static int db_lhistlsize, db_lhistidx, db_lhistcur;
61 static int db_lhist_nlines;
63 #define CTRL(c) ((c) & 0x1f)
67 static int cnmaygetc (void);
68 static void db_delete (int n, int bwd);
69 static int db_inputchar (int c);
70 static void db_putnchars (int c, int count);
71 static void db_putstring (char *s, int count);
74 db_putstring(s, count)
83 db_putnchars(c, count)
92 * Delete N characters, forward or backward
105 db_putnchars(BACKUP, n);
107 for (p = db_lc; p < db_le-n; p++) {
111 db_putnchars(BLANK, n);
112 db_putnchars(BACKUP, db_le - db_lc);
116 /* returns TRUE at end-of-line */
124 /* ESC seen, look for [ or O */
125 if (c == '[' || c == 'O')
128 escstate = 0; /* re-init state machine */
130 } else if (escstate == 2) {
133 * If a valid cursor key has been found, translate
134 * into an emacs-style control key, and fall through.
135 * Otherwise, drop off.
144 case 'C': /* right */
160 /* back up one character */
161 if (db_lc > db_lbuf_start) {
167 /* forward one character */
174 /* beginning of line */
175 while (db_lc > db_lbuf_start) {
182 while (db_lc < db_le) {
189 /* erase previous character */
190 if (db_lc > db_lbuf_start)
191 db_delete(1, DEL_BWD);
194 /* erase next character */
196 db_delete(1, DEL_FWD);
199 /* kill entire line: */
200 /* at first, delete to beginning of line */
201 if (db_lc > db_lbuf_start)
202 db_delete(db_lc - db_lbuf_start, DEL_BWD);
205 /* delete to end of line */
207 db_delete(db_le - db_lc, DEL_FWD);
210 /* twiddle last 2 characters */
211 if (db_lc >= db_lbuf_start + 2) {
213 db_lc[-2] = db_lc[-1];
222 db_putstring("^R\n", 3);
224 if (db_le > db_lbuf_start) {
225 db_putstring(db_lbuf_start, db_le - db_lbuf_start);
226 db_putnchars(BACKUP, db_le - db_lc);
230 /* Make previous history line the active one. */
231 if (db_lhistcur >= 0) {
232 bcopy(db_lhistory + db_lhistcur * db_lhistlsize,
233 db_lbuf_start, db_lhistlsize);
239 /* Make next history line the active one. */
240 if (db_lhistcur < db_lhistidx - 1) {
242 bcopy(db_lhistory + db_lhistcur * db_lhistlsize,
243 db_lbuf_start, db_lhistlsize);
246 * ^N through tail of history, reset the
247 * buffer to zero length.
249 *db_lbuf_start = '\0';
250 db_lhistcur = db_lhistidx;
254 db_putnchars(BACKUP, db_le - db_lbuf_start);
255 db_putnchars(BLANK, db_le - db_lbuf_start);
256 db_putnchars(BACKUP, db_le - db_lbuf_start);
257 db_le = index(db_lbuf_start, '\0');
258 if (db_le[-1] == '\r' || db_le[-1] == '\n')
265 * eek! the console returned eof.
266 * probably that means we HAVE no console.. we should try bail
275 if (db_le == db_lbuf_end) {
278 else if (c >= ' ' && c <= '~') {
281 for (p = db_le; p > db_lc; p--)
286 db_putstring(db_lc, db_le - db_lc);
287 db_putnchars(BACKUP, db_le - db_lc);
301 db_readline(lstart, lsize)
305 if (lsize != db_lhistlsize) {
307 * (Re)initialize input line history. Throw away any
310 db_lhist_nlines = sizeof(db_lhistory) / lsize;
311 db_lhistlsize = lsize;
314 db_lhistcur = db_lhistidx;
316 db_force_whitespace(); /* synch output position */
318 db_lbuf_start = lstart;
319 db_lbuf_end = lstart + lsize;
323 while (!db_inputchar(cngetc()))
326 db_printf("\n"); /* synch output position */
329 if (db_le - db_lbuf_start > 1) {
330 /* Maintain input line history for non-empty lines. */
331 if (++db_lhistidx == db_lhist_nlines) {
332 /* Rotate history. */
333 ovbcopy(db_lhistory + db_lhistlsize, db_lhistory,
334 db_lhistlsize * (db_lhist_nlines - 1));
337 bcopy(lstart, db_lhistory + db_lhistidx * db_lhistlsize,
341 return (db_le - db_lbuf_start);
351 case -1: /* no character */
363 } while (c != CTRL('q'));