key.c (148900) | key.c (167457) |
---|---|
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 * | 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.17 2005/08/08 14:05:37 christos Exp $ | 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> | 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 148900 2005-08-09 13:37:59Z stefanf $"); | 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); | 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); |
91private int key__decode_char(char *, int, int); | |
92 93#define KEY_BUFSIZ EL_BUFSIZ 94 95 96/* key_init(): 97 * Initialize the key maps 98 */ 99protected int --- 389 unchanged lines hidden (view full) --- 489 if (*str == 0) { 490 /* no more chars in str. node_enum from here. */ 491 (void) node_enum(el, ptr, cnt); 492 return (0); 493 } else { 494 /* If match put this char into el->el_key.buf. Recurse */ 495 if (ptr->ch == *str) { 496 /* match found */ | 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 */ |
497 ncnt = key__decode_char(el->el_key.buf, cnt, | 496 ncnt = key__decode_char(el->el_key.buf, KEY_BUFSIZ, cnt, |
498 (unsigned char) ptr->ch); 499 if (ptr->next != NULL) 500 /* not yet at leaf */ 501 return (node_lookup(el, str + 1, ptr->next, 502 ncnt + 1)); 503 else { 504 /* next node is null so key should be complete */ 505 if (str[1] == 0) { --- 37 unchanged lines hidden (view full) --- 543 if (ptr == NULL) { 544#ifdef DEBUG_EDIT 545 (void) fprintf(el->el_errfile, 546 "node_enum: BUG!! Null ptr passed\n!"); 547#endif 548 return (-1); 549 } 550 /* put this char at end of str */ | 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 */ |
551 ncnt = key__decode_char(el->el_key.buf, cnt, (unsigned char) ptr->ch); | 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: | 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) fprintf(el->el_outfile, fmt, key, 583 key__decode_str(val->str, unparsbuf, 584 ntype == XK_STR ? "\"\"" : "[]")); | 582 (void) key__decode_str(val->str, unparsbuf, 583 sizeof(unparsbuf), 584 ntype == XK_STR ? "\"\"" : "[]"); 585 (void) fprintf(el->el_outfile, fmt, key, unparsbuf); |
585 break; 586 case XK_CMD: 587 for (fp = el->el_map.help; fp->name; fp++) 588 if (val->cmd == fp->func) { 589 (void) fprintf(el->el_outfile, fmt, 590 key, fp->name); 591 break; 592 } --- 8 unchanged lines hidden (view full) --- 601 EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype)); 602 break; 603 } 604 else 605 (void) fprintf(el->el_outfile, fmt, key, "no input"); 606} 607 608 | 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++ |
|
609/* key__decode_char(): 610 * Put a printable form of char in buf. 611 */ | 615/* key__decode_char(): 616 * Put a printable form of char in buf. 617 */ |
612private int 613key__decode_char(char *buf, int cnt, int ch) | 618protected int 619key__decode_char(char *buf, int cnt, int off, int ch) |
614{ | 620{ |
615 ch = (unsigned char)ch; | 621 char *sb = buf + off; 622 char *eb = buf + cnt; 623 char *b = sb; |
616 | 624 |
625 ch = (unsigned char)ch; |
|
617 if (ch == 0) { | 626 if (ch == 0) { |
618 buf[cnt++] = '^'; 619 buf[cnt] = '@'; 620 return (cnt); | 627 ADDC('^'); 628 ADDC('@'); 629 return b - sb; |
621 } 622 if (iscntrl(ch)) { | 630 } 631 if (iscntrl(ch)) { |
623 buf[cnt++] = '^'; 624 if (ch == 0177) 625 buf[cnt] = '?'; | 632 ADDC('^'); 633 if (ch == '\177') 634 ADDC('?'); |
626 else | 635 else |
627 buf[cnt] = toascii(ch) | 0100; | 636 ADDC(toascii(ch) | 0100); |
628 } else if (ch == '^') { | 637 } else if (ch == '^') { |
629 buf[cnt++] = '\\'; 630 buf[cnt] = '^'; | 638 ADDC('\\'); 639 ADDC('^'); |
631 } else if (ch == '\\') { | 640 } else if (ch == '\\') { |
632 buf[cnt++] = '\\'; 633 buf[cnt] = '\\'; | 641 ADDC('\\'); 642 ADDC('\\'); |
634 } else if (ch == ' ' || (isprint(ch) && !isspace(ch))) { | 643 } else if (ch == ' ' || (isprint(ch) && !isspace(ch))) { |
635 buf[cnt] = ch; | 644 ADDC(ch); |
636 } else { | 645 } else { |
637 buf[cnt++] = '\\'; 638 buf[cnt++] = (((unsigned int) ch >> 6) & 7) + '0'; 639 buf[cnt++] = (((unsigned int) ch >> 3) & 7) + '0'; 640 buf[cnt] = (ch & 7) + '0'; | 646 ADDC('\\'); 647 ADDC((((unsigned int) ch >> 6) & 7) + '0'); 648 ADDC((((unsigned int) ch >> 3) & 7) + '0'); 649 ADDC((ch & 7) + '0'); |
641 } | 650 } |
642 return (cnt); | 651 return b - sb; |
643} 644 645 646/* key__decode_str(): 647 * Make a printable version of the ey 648 */ | 652} 653 654 655/* key__decode_str(): 656 * Make a printable version of the ey 657 */ |
649protected char * 650key__decode_str(const char *str, char *buf, const char *sep) | 658protected int 659key__decode_str(const char *str, char *buf, int len, const char *sep) |
651{ | 660{ |
652 char *b; | 661 char *b = buf, *eb = b + len; |
653 const char *p; 654 655 b = buf; | 662 const char *p; 663 664 b = buf; |
656 if (sep[0] != '\0') 657 *b++ = sep[0]; 658 if (*str == 0) { 659 *b++ = '^'; 660 *b++ = '@'; 661 if (sep[0] != '\0' && sep[1] != '\0') 662 *b++ = sep[1]; 663 *b++ = 0; 664 return (buf); | 665 if (sep[0] != '\0') { 666 ADDC(sep[0]); |
665 } | 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 } |
|
666 for (p = str; *p != 0; p++) { 667 if (iscntrl((unsigned char) *p)) { | 676 for (p = str; *p != 0; p++) { 677 if (iscntrl((unsigned char) *p)) { |
668 *b++ = '^'; 669 if (*p == '\177') 670 *b++ = '?'; 671 else 672 *b++ = toascii(*p) | 0100; | 678 ADDC('^'); 679 if (*p == '\177') { 680 ADDC('?'); 681 } else { 682 ADDC(toascii(*p) | 0100); 683 } |
673 } else if (*p == '^' || *p == '\\') { | 684 } else if (*p == '^' || *p == '\\') { |
674 *b++ = '\\'; 675 *b++ = *p; | 685 ADDC('\\'); 686 ADDC(*p); |
676 } else if (*p == ' ' || (isprint((unsigned char) *p) && 677 !isspace((unsigned char) *p))) { | 687 } else if (*p == ' ' || (isprint((unsigned char) *p) && 688 !isspace((unsigned char) *p))) { |
678 *b++ = *p; | 689 ADDC(*p); |
679 } else { | 690 } else { |
680 *b++ = '\\'; 681 *b++ = (((unsigned int) *p >> 6) & 7) + '0'; 682 *b++ = (((unsigned int) *p >> 3) & 7) + '0'; 683 *b++ = (*p & 7) + '0'; | 691 ADDC('\\'); 692 ADDC((((unsigned int) *p >> 6) & 7) + '0'); 693 ADDC((((unsigned int) *p >> 3) & 7) + '0'); 694 ADDC((*p & 7) + '0'); |
684 } 685 } | 695 } 696 } |
686 if (sep[0] != '\0' && sep[1] != '\0') 687 *b++ = sep[1]; 688 *b++ = 0; 689 return (buf); /* should check for overflow */ | 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; |
690} | 705} |