]>
git.saurik.com Git - apple/xnu.git/blob - osfmk/ddb/db_input.c
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
36 * Revision 1.1.1.1 1998/09/22 21:05:48 wsanchez
37 * Import of Mac OS X kernel (~semeria)
39 * Revision 1.1.1.1 1998/03/07 02:26:09 wsanchez
40 * Import of OSF Mach kernel (~mburg)
42 * Revision 1.3.10.2 1994/09/23 01:19:37 ezf
43 * change marker to not FREE
44 * [1994/09/22 21:10:05 ezf]
46 * Revision 1.3.10.1 1994/06/11 21:11:48 bolinger
47 * Merge up to NMK17.2.
48 * [1994/06/11 20:01:41 bolinger]
50 * Revision 1.3.8.2 1994/02/11 14:21:41 paire
51 * Added string.h header file for strlen declaration.
54 * Revision 1.3.8.1 1994/02/08 10:57:55 bernadat
55 * Added db_auto_completion variable.
58 * Added support of symbol completion by typing '\t'.
62 * Revision 1.3.2.4 1993/08/11 20:37:51 elliston
63 * Add ANSI Prototypes. CR #9523.
64 * [1993/08/11 03:33:21 elliston]
66 * Revision 1.3.2.3 1993/07/27 18:27:30 elliston
67 * Add ANSI prototypes. CR #9523.
68 * [1993/07/27 18:12:01 elliston]
70 * Revision 1.3.2.2 1993/06/09 02:20:13 gm
71 * CR9176 - ANSI C violations: trailing tokens on CPP
72 * directives, extra semicolons after decl_ ..., asm keywords
73 * [1993/06/07 18:57:14 jeffc]
75 * Added to OSF/1 R1.3 from NMK15.0.
76 * [1993/06/02 20:56:26 jeffc]
78 * Revision 1.3 1993/04/19 16:02:17 devrcs
79 * Replaced ^R (redraw) with ^L [barbou@gr.osf.org]
81 * Added ^R and ^S commands for history search commands
82 * ^U does not erase end of the line anymore. (only erases
83 * from the beginning of the line to current position).
86 * ^C now erases the entire line. [barbou@gr.osf.org]
89 * Fixed history management: Do not store repeated typed
90 * command. Null terminate current command in case it is a
91 * substring of the last command.
94 * Revision 1.2 1992/11/25 01:04:24 robert
95 * integrate changes for norma_14 below
97 * Philippe Bernadat (bernadat) at gr.osf.org 02-Oct-92
98 * Fixed history management: Do not store repeated typed
99 * command. Null terminate current command in case it is a
100 * substring of the last command.
101 * [1992/11/20 00:56:07 robert]
103 * integrate changes below for norma_14
104 * [1992/11/13 19:21:34 robert]
106 * Revision 1.1 1992/09/30 02:01:08 robert
113 * Revision 2.7.3.2 92/09/15 17:14:26 jeffreyh
114 * Fixed history code. (Only one char. out of 2 was checked to
115 * compare to last command)
116 * [barbou@gr.osf.org]
118 * Revision 2.7.3.1 92/03/03 16:13:30 jeffreyh
119 * Pick up changes from TRUNK
120 * [92/02/26 10:59:36 jeffreyh]
122 * Revision 2.8 92/02/19 15:07:44 elf
123 * Added delete_line (Ctrl-U).
126 * Added command line history. Ctrl-P = previous, Ctrl-N = next. If
127 * DB_HISTORY_SIZE is 0 then command history is disabled.
130 * Revision 2.7 91/10/09 16:00:03 af
131 * Revision 2.6.2.1 91/10/05 13:06:12 jeffreyh
132 * Fixed incorrect db_lbuf_end setting.
135 * Revision 2.6.2.1 91/10/05 13:06:12 jeffreyh
136 * Fixed incorrect db_lbuf_end setting.
139 * Revision 2.6 91/07/09 23:15:49 danner
140 * Add include of machine/db_machdep.h to allow machine-specific
141 * overrides via defines.
144 * Revision 2.5 91/05/14 15:34:03 mrt
145 * Correcting copyright
147 * Revision 2.4 91/02/14 14:41:53 mrt
148 * Add input line editing.
151 * Revision 2.3 91/02/05 17:06:32 mrt
152 * Changed to new Mach copyright
153 * [91/01/31 16:18:13 mrt]
155 * Revision 2.2 90/08/27 21:51:03 dbg
164 * Mach Operating System
165 * Copyright (c) 1991,1990 Carnegie Mellon University
166 * All Rights Reserved.
168 * Permission to use, copy, modify and distribute this software and its
169 * documentation is hereby granted, provided that both the copyright
170 * notice and this permission notice appear in all copies of the
171 * software, derivative works or modified versions, and any portions
172 * thereof, and that both notices appear in supporting documentation.
174 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
175 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
176 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
178 * Carnegie Mellon requests users of this software to return to
180 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
181 * School of Computer Science
182 * Carnegie Mellon University
183 * Pittsburgh PA 15213-3890
185 * any improvements or extensions that they make and grant Carnegie Mellon
186 * the rights to redistribute these changes.
191 * Author: David B. Golub, Carnegie Mellon University
196 #include <mach/boolean.h>
197 #include <machine/db_machdep.h>
198 #include <kern/misc_protos.h>
199 #include <ddb/db_output.h>
200 #include <ddb/db_lex.h>
201 #include <ddb/db_command.h>
202 #include <ddb/db_input.h>
203 #include <ddb/db_sym.h>
205 #ifndef DB_HISTORY_SIZE
206 #define DB_HISTORY_SIZE 4000
207 #endif /* DB_HISTORY_SIZE */
210 * Character input and editing.
214 * We don't track output position while editing input,
215 * since input always ends with a new-line. We just
216 * reset the line position at the end.
218 char * db_lbuf_start
; /* start of input line buffer */
219 char * db_lbuf_end
; /* end of input line buffer */
220 char * db_lc
; /* current character */
221 char * db_le
; /* one past last character */
222 int db_completion
; /* number of incomplete symbols matched */
223 int db_auto_completion
= 10; /* number of line to display without asking */
224 #if DB_HISTORY_SIZE != 0
225 char db_history
[DB_HISTORY_SIZE
]; /* start of history buffer */
226 int db_history_size
= DB_HISTORY_SIZE
;/* size of history buffer */
227 char * db_history_curr
= db_history
; /* start of current line */
228 char * db_history_last
= db_history
; /* start of last line */
229 char * db_history_prev
= (char *) 0; /* start of previous line */
230 int db_hist_unmodified
= 0; /* unmodified line from history */
231 int db_hist_search
= 0; /* are we in hist search mode ? */
232 char db_hist_search_string
[DB_LEX_LINE_SIZE
];/* the string to look for */
233 int db_hist_ignore_dups
= 0; /* don't duplicate commands in hist */
236 #define CTRL(c) ((c) & 0x1f)
237 #define isspace(c) ((c) == ' ' || (c) == '\t')
243 /* Prototypes for functions local to this file. XXX -- should be static!
257 void db_delete_line(void);
259 boolean_t
db_hist_substring(
263 boolean_t
db_inputchar(int c
);
265 extern jmp_buf_t
*db_recover
;
286 * Delete N characters, forward or backward
299 db_putnchars(BACKUP
, n
);
301 for (p
= db_lc
; p
< db_le
-n
; p
++) {
305 db_putnchars(BLANK
, n
);
306 db_putnchars(BACKUP
, db_le
- db_lc
);
313 db_delete(db_le
- db_lc
, DEL_FWD
);
314 db_delete(db_lc
- db_lbuf_start
, DEL_BWD
);
315 db_le
= db_lc
= db_lbuf_start
;
318 #if DB_HISTORY_SIZE != 0
319 #define INC_DB_CURR() \
322 if (db_history_curr > \
323 db_history + db_history_size - 1) \
324 db_history_curr = db_history; \
326 #define DEC_DB_CURR() \
329 if (db_history_curr < db_history) \
330 db_history_curr = db_history + \
331 db_history_size - 1; \
335 /* returs TRUE if "substring" is a substring of "string" */
341 register char *cp1
, *cp2
;
350 while (cp2
> substring
) {
354 while (cp1
>= string
) {
359 while (*cp2
&& *cp2
== *cp3
) {
370 /* returns TRUE at end-of-line */
382 switch(db_completion
) {
385 db_prev
= db_recover
;
386 if (_setjmp(db_recover
= &db_jmpbuf
) == 0 &&
387 (c
== 'y' || c
== ' ' || c
== '\t'))
388 db_print_completion(db_tok_string
);
389 db_recover
= db_prev
;
393 if (db_le
> db_lbuf_start
) {
394 for (start
= db_lbuf_start
; start
< db_le
; start
++)
396 db_putnchars(BACKUP
, db_le
- db_lc
);
405 db_printf("\nThere are %d possibilities. ", db_completion
);
406 db_printf("Do you really wish to see them all [n] ? ");
407 db_force_whitespace();
418 /* symbol completion */
419 if (db_lc
== db_lbuf_start
|| db_auto_completion
== 0)
421 if (db_le
== db_lbuf_end
) {
426 while (start
>= db_lbuf_start
&&
427 ((*start
>= 'A' && *start
<= 'Z') ||
428 (*start
>= 'a' && *start
<= 'z') ||
429 (*start
>= '0' && *start
<= '9') ||
430 *start
== '_' || *start
== ':'))
432 if (start
== db_lc
- 1)
434 if (start
> db_lbuf_start
&& *start
== '$') {
442 } while (start
!= db_lc
&&
443 sym
!= db_tok_string
+ sizeof(db_tok_string
));
444 if (sym
== db_tok_string
+ sizeof(db_tok_string
)) {
449 db_completion
= db_lookup_incomplete(db_tok_string
,
450 sizeof(db_tok_string
));
451 if (db_completion
== 0) {
457 len
= strlen(db_tok_string
) - (start
- restart
);
458 if (db_completion
== 1 &&
460 (db_le
> db_lc
) && *db_lc
!= ' '))
462 for (p
= db_le
- 1; p
>= db_lc
; p
--)
465 for (sym
= &db_tok_string
[start
- restart
];
469 if (db_completion
== 1 || db_completion
> db_auto_completion
) {
470 for (sym
= &db_tok_string
[start
- restart
];
473 if (db_completion
== 1) {
474 if (db_le
== db_lc
||
475 (db_le
> db_lc
) && *db_lc
!= ' ') {
481 db_putstring(db_lc
, db_le
- db_lc
);
482 db_putnchars(BACKUP
, db_le
- db_lc
);
485 if (db_completion
> 1) {
487 if (db_completion
<= db_auto_completion
) {
489 db_print_completion(db_tok_string
);
493 if (db_le
> db_lbuf_start
) {
494 for (start
= db_lbuf_start
; start
< db_le
; start
++)
496 db_putnchars(BACKUP
, db_le
- db_lc
);
503 /* back up one character */
504 if (db_lc
> db_lbuf_start
) {
510 /* forward one character */
517 /* beginning of line */
518 while (db_lc
> db_lbuf_start
) {
525 while (db_lc
< db_le
) {
532 /* erase previous character */
533 if (db_lc
> db_lbuf_start
)
534 db_delete(1, DEL_BWD
);
537 /* erase next character */
539 db_delete(1, DEL_FWD
);
542 /* delete to end of line */
544 db_delete(db_le
- db_lc
, DEL_FWD
);
547 /* delete to beginning of line */
548 if (db_lc
> db_lbuf_start
)
549 db_delete(db_lc
- db_lbuf_start
, DEL_BWD
);
552 /* twiddle last 2 characters */
553 if (db_lc
>= db_lbuf_start
+ 2) {
555 db_lc
[-2] = db_lc
[-1];
566 #if DB_HISTORY_SIZE != 0
567 db_history_curr
= db_history_last
;
568 if (c
== CTRL('g') && db_hist_search
) {
570 for (p
= db_hist_search_string
, db_le
= db_lbuf_start
;
576 db_putstring(db_lbuf_start
, db_le
- db_lbuf_start
);
580 #if DB_HISTORY_SIZE != 0
582 if (db_hist_search
++ == 0) {
583 /* starting an history lookup */
584 register char *cp1
, *cp2
;
585 for (cp1
= db_lbuf_start
, cp2
= db_hist_search_string
;
595 char * old_history_curr
= db_history_curr
;
597 if (db_hist_unmodified
++ == 0)
598 db_hist_unmodified
++;
600 while (db_history_curr
!= db_history_last
) {
602 if (*db_history_curr
== '\0') {
604 if (db_hist_search
<= 1) {
605 if (*db_history_curr
== '\0')
611 if (*db_history_curr
== '\0') {
613 db_history_curr
= old_history_curr
;
617 if (db_history_curr
!= db_history_last
&&
618 db_hist_substring(db_history_curr
,
619 db_hist_search_string
)) {
626 if (db_history_curr
== db_history_last
) {
628 db_history_curr
= old_history_curr
;
633 for (p
= db_history_curr
, db_le
= db_lbuf_start
;
636 if (p
== db_history
+ db_history_size
) {
642 db_putstring(db_lbuf_start
, db_le
- db_lbuf_start
);
647 if (db_hist_search
++ == 0) {
648 /* starting an history lookup */
649 register char *cp1
, *cp2
;
650 for (cp1
= db_lbuf_start
, cp2
= db_hist_search_string
;
660 char *old_history_curr
= db_history_curr
;
662 if (db_hist_unmodified
++ == 0)
663 db_hist_unmodified
++;
664 while (db_history_curr
!= db_history_last
) {
665 if (*db_history_curr
== '\0') {
666 if (db_hist_search
<= 1)
669 if (db_history_curr
!= db_history_last
&&
670 db_hist_substring(db_history_curr
,
671 db_hist_search_string
)) {
679 if (db_history_curr
!= db_history_last
) {
681 if (db_history_curr
!= db_history_last
) {
684 for (p
= db_history_curr
,
685 db_le
= db_lbuf_start
; *p
;) {
687 if (p
== db_history
+
694 db_putstring(db_lbuf_start
,
695 db_le
- db_lbuf_start
);
698 db_history_curr
= old_history_curr
;
702 db_history_curr
= old_history_curr
;
707 /* refresh the command line */
709 db_putstring("^L\n", 3);
710 if (db_le
> db_lbuf_start
) {
711 db_putstring(db_lbuf_start
, db_le
- db_lbuf_start
);
712 db_putnchars(BACKUP
, db_le
- db_lc
);
717 #if DB_HISTORY_SIZE != 0
718 /* Check if it same than previous line */
719 if (db_history_prev
) {
720 register char *pp
, *pc
;
722 /* Is it unmodified */
723 for (p
= db_history_prev
, pc
= db_lbuf_start
;
724 pc
!= db_le
&& *p
;) {
727 if (++p
== db_history
+ db_history_size
) {
730 if (++pc
== db_history
+ db_history_size
) {
734 if (!*p
&& pc
== db_le
) {
735 /* Repeted previous line, not saved */
736 db_history_curr
= db_history_last
;
739 db_hist_unmodified
= 0;
743 if (db_le
!= db_lbuf_start
&&
744 (db_hist_unmodified
== 0 || !db_hist_ignore_dups
)) {
745 db_history_prev
= db_history_last
;
746 for (p
= db_lbuf_start
; p
!= db_le
; p
++) {
747 *db_history_last
++ = *p
;
748 if (db_history_last
== db_history
+
750 db_history_last
= db_history
;
753 *db_history_last
++ = '\0';
755 db_history_curr
= db_history_last
;
759 db_hist_unmodified
= 0;
762 if (db_le
== db_lbuf_end
) {
765 else if (c
>= ' ' && c
<= '~') {
766 for (p
= db_le
; p
> db_lc
; p
--)
771 db_putstring(db_lc
, db_le
- db_lc
);
772 db_putnchars(BACKUP
, db_le
- db_lc
);
778 if (db_hist_unmodified
)
779 db_hist_unmodified
--;
788 db_force_whitespace(); /* synch output position */
790 db_lbuf_start
= lstart
;
791 db_lbuf_end
= lstart
+ lsize
- 1;
795 while (!db_inputchar(cngetc()))
798 db_putchar('\n'); /* synch output position */
801 return (db_le
- db_lbuf_start
);
805 db_check_interrupt(void)
811 case -1: /* no character */
823 } while (c
!= CTRL('q'));