1/*- 2 * Copyright (c) 1992, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Christos Zoulas of Cornell University. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 15 unchanged lines hidden (view full) --- 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * |
32 * $NetBSD: key.c,v 1.19 2006/03/23 20:22:51 christos Exp $ |
33 */ 34 35#if !defined(lint) && !defined(SCCSID) 36static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93"; 37#endif /* not lint && not SCCSID */ 38#include <sys/cdefs.h> |
39__FBSDID("$FreeBSD: head/lib/libedit/key.c 167457 2007-03-11 18:30:22Z stefanf $"); |
40 41/* 42 * key.c: This module contains the procedures for maintaining 43 * the extended-key map. 44 * 45 * An extended-key (key) is a sequence of keystrokes introduced 46 * with a sequence introducer and consisting of an arbitrary 47 * number of characters. This module maintains a map (the el->el_key.map) --- 35 unchanged lines hidden (view full) --- 83 key_value_t *, int); 84private key_node_t *node__get(int); 85private void node__free(key_node_t *); 86private void node__put(EditLine *, key_node_t *); 87private int node__delete(EditLine *, key_node_t **, const char *); 88private int node_lookup(EditLine *, const char *, key_node_t *, 89 int); 90private int node_enum(EditLine *, key_node_t *, int); |
91 92#define KEY_BUFSIZ EL_BUFSIZ 93 94 95/* key_init(): 96 * Initialize the key maps 97 */ 98protected int --- 389 unchanged lines hidden (view full) --- 488 if (*str == 0) { 489 /* no more chars in str. node_enum from here. */ 490 (void) node_enum(el, ptr, cnt); 491 return (0); 492 } else { 493 /* If match put this char into el->el_key.buf. Recurse */ 494 if (ptr->ch == *str) { 495 /* match found */ |
496 ncnt = key__decode_char(el->el_key.buf, KEY_BUFSIZ, cnt, |
497 (unsigned char) ptr->ch); 498 if (ptr->next != NULL) 499 /* not yet at leaf */ 500 return (node_lookup(el, str + 1, ptr->next, 501 ncnt + 1)); 502 else { 503 /* next node is null so key should be complete */ 504 if (str[1] == 0) { --- 37 unchanged lines hidden (view full) --- 542 if (ptr == NULL) { 543#ifdef DEBUG_EDIT 544 (void) fprintf(el->el_errfile, 545 "node_enum: BUG!! Null ptr passed\n!"); 546#endif 547 return (-1); 548 } 549 /* put this char at end of str */ |
550 ncnt = key__decode_char(el->el_key.buf, KEY_BUFSIZ, cnt, 551 (unsigned char)ptr->ch); |
552 if (ptr->next == NULL) { 553 /* print this key and function */ 554 el->el_key.buf[ncnt + 1] = '"'; 555 el->el_key.buf[ncnt + 2] = '\0'; 556 key_kprint(el, el->el_key.buf, &ptr->val, ptr->type); 557 } else 558 (void) node_enum(el, ptr->next, ncnt + 1); 559 --- 14 unchanged lines hidden (view full) --- 574 el_bindings_t *fp; 575 char unparsbuf[EL_BUFSIZ]; 576 static const char fmt[] = "%-15s-> %s\n"; 577 578 if (val != NULL) 579 switch (ntype) { 580 case XK_STR: 581 case XK_EXE: |
582 (void) key__decode_str(val->str, unparsbuf, 583 sizeof(unparsbuf), 584 ntype == XK_STR ? "\"\"" : "[]"); 585 (void) fprintf(el->el_outfile, fmt, key, unparsbuf); |
586 break; 587 case XK_CMD: 588 for (fp = el->el_map.help; fp->name; fp++) 589 if (val->cmd == fp->func) { 590 (void) fprintf(el->el_outfile, fmt, 591 key, fp->name); 592 break; 593 } --- 8 unchanged lines hidden (view full) --- 602 EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype)); 603 break; 604 } 605 else 606 (void) fprintf(el->el_outfile, fmt, key, "no input"); 607} 608 609 |
610#define ADDC(c) \ 611 if (b < eb) \ 612 *b++ = c; \ 613 else \ 614 b++ |
615/* key__decode_char(): 616 * Put a printable form of char in buf. 617 */ |
618protected int 619key__decode_char(char *buf, int cnt, int off, int ch) |
620{ |
621 char *sb = buf + off; 622 char *eb = buf + cnt; 623 char *b = sb; |
624 |
625 ch = (unsigned char)ch; |
626 if (ch == 0) { |
627 ADDC('^'); 628 ADDC('@'); 629 return b - sb; |
630 } 631 if (iscntrl(ch)) { |
632 ADDC('^'); 633 if (ch == '\177') 634 ADDC('?'); |
635 else |
636 ADDC(toascii(ch) | 0100); |
637 } else if (ch == '^') { |
638 ADDC('\\'); 639 ADDC('^'); |
640 } else if (ch == '\\') { |
641 ADDC('\\'); 642 ADDC('\\'); |
643 } else if (ch == ' ' || (isprint(ch) && !isspace(ch))) { |
644 ADDC(ch); |
645 } else { |
646 ADDC('\\'); 647 ADDC((((unsigned int) ch >> 6) & 7) + '0'); 648 ADDC((((unsigned int) ch >> 3) & 7) + '0'); 649 ADDC((ch & 7) + '0'); |
650 } |
651 return b - sb; |
652} 653 654 655/* key__decode_str(): 656 * Make a printable version of the ey 657 */ |
658protected int 659key__decode_str(const char *str, char *buf, int len, const char *sep) |
660{ |
661 char *b = buf, *eb = b + len; |
662 const char *p; 663 664 b = buf; |
665 if (sep[0] != '\0') { 666 ADDC(sep[0]); |
667 } |
668 if (*str == '\0') { 669 ADDC('^'); 670 ADDC('@'); 671 if (sep[0] != '\0' && sep[1] != '\0') { 672 ADDC(sep[1]); 673 } 674 goto done; 675 } |
676 for (p = str; *p != 0; p++) { 677 if (iscntrl((unsigned char) *p)) { |
678 ADDC('^'); 679 if (*p == '\177') { 680 ADDC('?'); 681 } else { 682 ADDC(toascii(*p) | 0100); 683 } |
684 } else if (*p == '^' || *p == '\\') { |
685 ADDC('\\'); 686 ADDC(*p); |
687 } else if (*p == ' ' || (isprint((unsigned char) *p) && 688 !isspace((unsigned char) *p))) { |
689 ADDC(*p); |
690 } else { |
691 ADDC('\\'); 692 ADDC((((unsigned int) *p >> 6) & 7) + '0'); 693 ADDC((((unsigned int) *p >> 3) & 7) + '0'); 694 ADDC((*p & 7) + '0'); |
695 } 696 } |
697 if (sep[0] != '\0' && sep[1] != '\0') { 698 ADDC(sep[1]); 699 } 700done: 701 ADDC('\0'); 702 if (b - buf >= len) 703 buf[len - 1] = '\0'; 704 return b - buf; |
705} |