]>
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_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
28 * Revision 1.1.1.1 1998/09/22 21:05:48 wsanchez
29 * Import of Mac OS X kernel (~semeria)
31 * Revision 1.1.1.1 1998/03/07 02:26:09 wsanchez
32 * Import of OSF Mach kernel (~mburg)
34 * Revision 1.3.10.2 1994/09/23 01:19:37 ezf
35 * change marker to not FREE
36 * [1994/09/22 21:10:05 ezf]
38 * Revision 1.3.10.1 1994/06/11 21:11:48 bolinger
39 * Merge up to NMK17.2.
40 * [1994/06/11 20:01:41 bolinger]
42 * Revision 1.3.8.2 1994/02/11 14:21:41 paire
43 * Added string.h header file for strlen declaration.
46 * Revision 1.3.8.1 1994/02/08 10:57:55 bernadat
47 * Added db_auto_completion variable.
50 * Added support of symbol completion by typing '\t'.
54 * Revision 1.3.2.4 1993/08/11 20:37:51 elliston
55 * Add ANSI Prototypes. CR #9523.
56 * [1993/08/11 03:33:21 elliston]
58 * Revision 1.3.2.3 1993/07/27 18:27:30 elliston
59 * Add ANSI prototypes. CR #9523.
60 * [1993/07/27 18:12:01 elliston]
62 * Revision 1.3.2.2 1993/06/09 02:20:13 gm
63 * CR9176 - ANSI C violations: trailing tokens on CPP
64 * directives, extra semicolons after decl_ ..., asm keywords
65 * [1993/06/07 18:57:14 jeffc]
67 * Added to OSF/1 R1.3 from NMK15.0.
68 * [1993/06/02 20:56:26 jeffc]
70 * Revision 1.3 1993/04/19 16:02:17 devrcs
71 * Replaced ^R (redraw) with ^L [barbou@gr.osf.org]
73 * Added ^R and ^S commands for history search commands
74 * ^U does not erase end of the line anymore. (only erases
75 * from the beginning of the line to current position).
78 * ^C now erases the entire line. [barbou@gr.osf.org]
81 * Fixed history management: Do not store repeated typed
82 * command. Null terminate current command in case it is a
83 * substring of the last command.
86 * Revision 1.2 1992/11/25 01:04:24 robert
87 * integrate changes for norma_14 below
89 * Philippe Bernadat (bernadat) at gr.osf.org 02-Oct-92
90 * Fixed history management: Do not store repeated typed
91 * command. Null terminate current command in case it is a
92 * substring of the last command.
93 * [1992/11/20 00:56:07 robert]
95 * integrate changes below for norma_14
96 * [1992/11/13 19:21:34 robert]
98 * Revision 1.1 1992/09/30 02:01:08 robert
105 * Revision 2.7.3.2 92/09/15 17:14:26 jeffreyh
106 * Fixed history code. (Only one char. out of 2 was checked to
107 * compare to last command)
108 * [barbou@gr.osf.org]
110 * Revision 2.7.3.1 92/03/03 16:13:30 jeffreyh
111 * Pick up changes from TRUNK
112 * [92/02/26 10:59:36 jeffreyh]
114 * Revision 2.8 92/02/19 15:07:44 elf
115 * Added delete_line (Ctrl-U).
118 * Added command line history. Ctrl-P = previous, Ctrl-N = next. If
119 * DB_HISTORY_SIZE is 0 then command history is disabled.
122 * Revision 2.7 91/10/09 16:00:03 af
123 * Revision 2.6.2.1 91/10/05 13:06:12 jeffreyh
124 * Fixed incorrect db_lbuf_end setting.
127 * Revision 2.6.2.1 91/10/05 13:06:12 jeffreyh
128 * Fixed incorrect db_lbuf_end setting.
131 * Revision 2.6 91/07/09 23:15:49 danner
132 * Add include of machine/db_machdep.h to allow machine-specific
133 * overrides via defines.
136 * Revision 2.5 91/05/14 15:34:03 mrt
137 * Correcting copyright
139 * Revision 2.4 91/02/14 14:41:53 mrt
140 * Add input line editing.
143 * Revision 2.3 91/02/05 17:06:32 mrt
144 * Changed to new Mach copyright
145 * [91/01/31 16:18:13 mrt]
147 * Revision 2.2 90/08/27 21:51:03 dbg
156 * Mach Operating System
157 * Copyright (c) 1991,1990 Carnegie Mellon University
158 * All Rights Reserved.
160 * Permission to use, copy, modify and distribute this software and its
161 * documentation is hereby granted, provided that both the copyright
162 * notice and this permission notice appear in all copies of the
163 * software, derivative works or modified versions, and any portions
164 * thereof, and that both notices appear in supporting documentation.
166 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
167 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
168 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
170 * Carnegie Mellon requests users of this software to return to
172 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
173 * School of Computer Science
174 * Carnegie Mellon University
175 * Pittsburgh PA 15213-3890
177 * any improvements or extensions that they make and grant Carnegie Mellon
178 * the rights to redistribute these changes.
183 * Author: David B. Golub, Carnegie Mellon University
188 #include <mach/boolean.h>
189 #include <machine/db_machdep.h>
190 #include <kern/misc_protos.h>
191 #include <ddb/db_output.h>
192 #include <ddb/db_lex.h>
193 #include <ddb/db_command.h>
194 #include <ddb/db_input.h>
195 #include <ddb/db_sym.h>
197 #ifndef DB_HISTORY_SIZE
198 #define DB_HISTORY_SIZE 4000
199 #endif /* DB_HISTORY_SIZE */
202 * Character input and editing.
206 * We don't track output position while editing input,
207 * since input always ends with a new-line. We just
208 * reset the line position at the end.
210 char * db_lbuf_start
; /* start of input line buffer */
211 char * db_lbuf_end
; /* end of input line buffer */
212 char * db_lc
; /* current character */
213 char * db_le
; /* one past last character */
214 int db_completion
; /* number of incomplete symbols matched */
215 int db_auto_completion
= 10; /* number of line to display without asking */
216 #if DB_HISTORY_SIZE != 0
217 char db_history
[DB_HISTORY_SIZE
]; /* start of history buffer */
218 int db_history_size
= DB_HISTORY_SIZE
;/* size of history buffer */
219 char * db_history_curr
= db_history
; /* start of current line */
220 char * db_history_last
= db_history
; /* start of last line */
221 char * db_history_prev
= (char *) 0; /* start of previous line */
222 int db_hist_unmodified
= 0; /* unmodified line from history */
223 int db_hist_search
= 0; /* are we in hist search mode ? */
224 char db_hist_search_string
[DB_LEX_LINE_SIZE
];/* the string to look for */
225 int db_hist_ignore_dups
= 0; /* don't duplicate commands in hist */
228 #define CTRL(c) ((c) & 0x1f)
229 #define isspace(c) ((c) == ' ' || (c) == '\t')
235 /* Prototypes for functions local to this file. XXX -- should be static!
249 void db_delete_line(void);
251 boolean_t
db_hist_substring(
255 boolean_t
db_inputchar(int c
);
257 extern jmp_buf_t
*db_recover
;
278 * Delete N characters, forward or backward
291 db_putnchars(BACKUP
, n
);
293 for (p
= db_lc
; p
< db_le
-n
; p
++) {
297 db_putnchars(BLANK
, n
);
298 db_putnchars(BACKUP
, db_le
- db_lc
);
305 db_delete(db_le
- db_lc
, DEL_FWD
);
306 db_delete(db_lc
- db_lbuf_start
, DEL_BWD
);
307 db_le
= db_lc
= db_lbuf_start
;
310 #if DB_HISTORY_SIZE != 0
311 #define INC_DB_CURR() \
314 if (db_history_curr > \
315 db_history + db_history_size - 1) \
316 db_history_curr = db_history; \
318 #define DEC_DB_CURR() \
321 if (db_history_curr < db_history) \
322 db_history_curr = db_history + \
323 db_history_size - 1; \
327 /* returs TRUE if "substring" is a substring of "string" */
333 register char *cp1
, *cp2
;
342 while (cp2
> substring
) {
346 while (cp1
>= string
) {
351 while (*cp2
&& *cp2
== *cp3
) {
362 /* returns TRUE at end-of-line */
374 switch(db_completion
) {
377 db_prev
= db_recover
;
378 if (_setjmp(db_recover
= &db_jmpbuf
) == 0 &&
379 (c
== 'y' || c
== ' ' || c
== '\t'))
380 db_print_completion(db_tok_string
);
381 db_recover
= db_prev
;
385 if (db_le
> db_lbuf_start
) {
386 for (start
= db_lbuf_start
; start
< db_le
; start
++)
388 db_putnchars(BACKUP
, db_le
- db_lc
);
397 db_printf("\nThere are %d possibilities. ", db_completion
);
398 db_printf("Do you really wish to see them all [n] ? ");
399 db_force_whitespace();
410 /* symbol completion */
411 if (db_lc
== db_lbuf_start
|| db_auto_completion
== 0)
413 if (db_le
== db_lbuf_end
) {
418 while (start
>= db_lbuf_start
&&
419 ((*start
>= 'A' && *start
<= 'Z') ||
420 (*start
>= 'a' && *start
<= 'z') ||
421 (*start
>= '0' && *start
<= '9') ||
422 *start
== '_' || *start
== ':'))
424 if (start
== db_lc
- 1)
426 if (start
> db_lbuf_start
&& *start
== '$') {
434 } while (start
!= db_lc
&&
435 sym
!= db_tok_string
+ sizeof(db_tok_string
));
436 if (sym
== db_tok_string
+ sizeof(db_tok_string
)) {
441 db_completion
= db_lookup_incomplete(db_tok_string
,
442 sizeof(db_tok_string
));
443 if (db_completion
== 0) {
449 len
= strlen(db_tok_string
) - (start
- restart
);
450 if (db_completion
== 1 &&
452 (db_le
> db_lc
) && *db_lc
!= ' '))
454 for (p
= db_le
- 1; p
>= db_lc
; p
--)
457 for (sym
= &db_tok_string
[start
- restart
];
461 if (db_completion
== 1 || db_completion
> db_auto_completion
) {
462 for (sym
= &db_tok_string
[start
- restart
];
465 if (db_completion
== 1) {
466 if (db_le
== db_lc
||
467 (db_le
> db_lc
) && *db_lc
!= ' ') {
473 db_putstring(db_lc
, db_le
- db_lc
);
474 db_putnchars(BACKUP
, db_le
- db_lc
);
477 if (db_completion
> 1) {
479 if (db_completion
<= db_auto_completion
) {
481 db_print_completion(db_tok_string
);
485 if (db_le
> db_lbuf_start
) {
486 for (start
= db_lbuf_start
; start
< db_le
; start
++)
488 db_putnchars(BACKUP
, db_le
- db_lc
);
495 /* back up one character */
496 if (db_lc
> db_lbuf_start
) {
502 /* forward one character */
509 /* beginning of line */
510 while (db_lc
> db_lbuf_start
) {
517 while (db_lc
< db_le
) {
524 /* erase previous character */
525 if (db_lc
> db_lbuf_start
)
526 db_delete(1, DEL_BWD
);
529 /* erase next character */
531 db_delete(1, DEL_FWD
);
534 /* delete to end of line */
536 db_delete(db_le
- db_lc
, DEL_FWD
);
539 /* delete to beginning of line */
540 if (db_lc
> db_lbuf_start
)
541 db_delete(db_lc
- db_lbuf_start
, DEL_BWD
);
544 /* twiddle last 2 characters */
545 if (db_lc
>= db_lbuf_start
+ 2) {
547 db_lc
[-2] = db_lc
[-1];
558 #if DB_HISTORY_SIZE != 0
559 db_history_curr
= db_history_last
;
560 if (c
== CTRL('g') && db_hist_search
) {
562 for (p
= db_hist_search_string
, db_le
= db_lbuf_start
;
568 db_putstring(db_lbuf_start
, db_le
- db_lbuf_start
);
572 #if DB_HISTORY_SIZE != 0
574 if (db_hist_search
++ == 0) {
575 /* starting an history lookup */
576 register char *cp1
, *cp2
;
577 for (cp1
= db_lbuf_start
, cp2
= db_hist_search_string
;
587 char * old_history_curr
= db_history_curr
;
589 if (db_hist_unmodified
++ == 0)
590 db_hist_unmodified
++;
592 while (db_history_curr
!= db_history_last
) {
594 if (*db_history_curr
== '\0') {
596 if (db_hist_search
<= 1) {
597 if (*db_history_curr
== '\0')
603 if (*db_history_curr
== '\0') {
605 db_history_curr
= old_history_curr
;
609 if (db_history_curr
!= db_history_last
&&
610 db_hist_substring(db_history_curr
,
611 db_hist_search_string
)) {
618 if (db_history_curr
== db_history_last
) {
620 db_history_curr
= old_history_curr
;
625 for (p
= db_history_curr
, db_le
= db_lbuf_start
;
628 if (p
== db_history
+ db_history_size
) {
634 db_putstring(db_lbuf_start
, db_le
- db_lbuf_start
);
639 if (db_hist_search
++ == 0) {
640 /* starting an history lookup */
641 register char *cp1
, *cp2
;
642 for (cp1
= db_lbuf_start
, cp2
= db_hist_search_string
;
652 char *old_history_curr
= db_history_curr
;
654 if (db_hist_unmodified
++ == 0)
655 db_hist_unmodified
++;
656 while (db_history_curr
!= db_history_last
) {
657 if (*db_history_curr
== '\0') {
658 if (db_hist_search
<= 1)
661 if (db_history_curr
!= db_history_last
&&
662 db_hist_substring(db_history_curr
,
663 db_hist_search_string
)) {
671 if (db_history_curr
!= db_history_last
) {
673 if (db_history_curr
!= db_history_last
) {
676 for (p
= db_history_curr
,
677 db_le
= db_lbuf_start
; *p
;) {
679 if (p
== db_history
+
686 db_putstring(db_lbuf_start
,
687 db_le
- db_lbuf_start
);
690 db_history_curr
= old_history_curr
;
694 db_history_curr
= old_history_curr
;
699 /* refresh the command line */
701 db_putstring("^L\n", 3);
702 if (db_le
> db_lbuf_start
) {
703 db_putstring(db_lbuf_start
, db_le
- db_lbuf_start
);
704 db_putnchars(BACKUP
, db_le
- db_lc
);
709 #if DB_HISTORY_SIZE != 0
710 /* Check if it same than previous line */
711 if (db_history_prev
) {
712 register char *pp
, *pc
;
714 /* Is it unmodified */
715 for (p
= db_history_prev
, pc
= db_lbuf_start
;
716 pc
!= db_le
&& *p
;) {
719 if (++p
== db_history
+ db_history_size
) {
722 if (++pc
== db_history
+ db_history_size
) {
726 if (!*p
&& pc
== db_le
) {
727 /* Repeted previous line, not saved */
728 db_history_curr
= db_history_last
;
731 db_hist_unmodified
= 0;
735 if (db_le
!= db_lbuf_start
&&
736 (db_hist_unmodified
== 0 || !db_hist_ignore_dups
)) {
737 db_history_prev
= db_history_last
;
738 for (p
= db_lbuf_start
; p
!= db_le
; p
++) {
739 *db_history_last
++ = *p
;
740 if (db_history_last
== db_history
+
742 db_history_last
= db_history
;
745 *db_history_last
++ = '\0';
747 db_history_curr
= db_history_last
;
751 db_hist_unmodified
= 0;
754 if (db_le
== db_lbuf_end
) {
757 else if (c
>= ' ' && c
<= '~') {
758 for (p
= db_le
; p
> db_lc
; p
--)
763 db_putstring(db_lc
, db_le
- db_lc
);
764 db_putnchars(BACKUP
, db_le
- db_lc
);
770 if (db_hist_unmodified
)
771 db_hist_unmodified
--;
780 db_force_whitespace(); /* synch output position */
782 db_lbuf_start
= lstart
;
783 db_lbuf_end
= lstart
+ lsize
- 1;
787 while (!db_inputchar(cngetc()))
790 db_putchar('\n'); /* synch output position */
793 return (db_le
- db_lbuf_start
);
797 db_check_interrupt(void)
803 case -1: /* no character */
815 } while (c
!= CTRL('q'));