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 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. |
16 * 3. Neither the name of the University nor the names of its contributors |
17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 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.16 2005/07/06 21:13:02 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 148834 2005-08-07 20:55:59Z 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) --- 6 unchanged lines hidden (view full) --- 54 * are in el->el_key.map, adding the key "abc" will cause the first two 55 * definitions to be lost. 56 * 57 * Restrictions: 58 * ------------- 59 * 1) It is not possible to have one key that is a 60 * substr of another. 61 */ |
62#include <string.h> 63#include <stdlib.h> 64 65#include "el.h" 66 67/* 68 * The Nodes of the el->el_key.map. The el->el_key.map is a linked list 69 * of these node elements --- 7 unchanged lines hidden (view full) --- 77 struct key_node_t *sibling; /* ptr to another key with same prefix*/ 78}; 79 80private int node_trav(EditLine *, key_node_t *, char *, 81 key_value_t *); 82private int node__try(EditLine *, key_node_t *, const char *, 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 --- 5 unchanged lines hidden (view full) --- 103 el->el_key.buf = (char *) el_malloc(KEY_BUFSIZ); 104 if (el->el_key.buf == NULL) 105 return (-1); 106 el->el_key.map = NULL; 107 key_reset(el); 108 return (0); 109} 110 |
111/* key_end(): 112 * Free the key maps 113 */ 114protected void 115key_end(EditLine *el) 116{ 117 118 el_free((ptr_t) el->el_key.buf); 119 el->el_key.buf = NULL; |
120 node__free(el->el_key.map); |
121} 122 123 124/* key_map_cmd(): 125 * Associate cmd with a key value 126 */ 127protected key_value_t * 128key_map_cmd(EditLine *el, int cmd) --- 77 unchanged lines hidden (view full) --- 206 return; 207} 208 209 210/* key_clear(): 211 * 212 */ 213protected void |
214key_clear(EditLine *el, el_action_t *map, const char *in) |
215{ 216 217 if ((map[(unsigned char)*in] == ED_SEQUENCE_LEAD_IN) && 218 ((map == el->el_map.key && 219 el->el_map.alt[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN) || 220 (map == el->el_map.alt && 221 el->el_map.key[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN))) 222 (void) key_delete(el, in); 223} 224 225 226/* key_delete(): 227 * Delete the key and all longer keys staring with key, if 228 * they exists. 229 */ 230protected int |
231key_delete(EditLine *el, const char *key) |
232{ 233 234 if (key[0] == '\0') { 235 (void) fprintf(el->el_errfile, 236 "key_delete: Null extended-key not allowed.\n"); 237 return (-1); 238 } 239 if (el->el_key.map == NULL) --- 4 unchanged lines hidden (view full) --- 244} 245 246 247/* key_print(): 248 * Print the binding associated with key key. 249 * Print entire el->el_key.map if null 250 */ 251protected void |
252key_print(EditLine *el, const char *key) |
253{ 254 255 /* do nothing if el->el_key.map is empty and null key specified */ 256 if (el->el_key.map == NULL && *key == 0) 257 return; 258 259 el->el_key.buf[0] = '"'; 260 if (node_lookup(el, key, el->el_key.map, 1) <= -1) --- 82 unchanged lines hidden (view full) --- 343 } 344 345 switch (ptr->type = ntype) { 346 case XK_CMD: 347 ptr->val = *val; 348 break; 349 case XK_STR: 350 case XK_EXE: |
351 if ((ptr->val.str = el_strdup(val->str)) == NULL) 352 return -1; |
353 break; 354 default: 355 EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype)); 356 break; 357 } 358 } else { 359 /* still more chars to go */ 360 if (ptr->next == NULL) 361 ptr->next = node__get(*str); /* setup new node */ 362 (void) node__try(el, ptr->next, str, val, ntype); 363 } 364 return (0); 365} 366 367 368/* node__delete(): 369 * Delete node that matches str 370 */ 371private int |
372node__delete(EditLine *el, key_node_t **inptr, const char *str) |
373{ 374 key_node_t *ptr; 375 key_node_t *prev_ptr = NULL; 376 377 ptr = *inptr; 378 379 if (ptr->ch != *str) { 380 key_node_t *xm; --- 78 unchanged lines hidden (view full) --- 459 ptr->ch = ch; 460 ptr->type = XK_NOD; 461 ptr->val.str = NULL; 462 ptr->next = NULL; 463 ptr->sibling = NULL; 464 return (ptr); 465} 466 |
467private void 468node__free(key_node_t *k) 469{ 470 if (k == NULL) 471 return; 472 node__free(k->sibling); 473 node__free(k->next); 474 el_free((ptr_t) k); 475} |
476 |
477/* node_lookup(): 478 * look for the str starting at node ptr. 479 * Print if last node 480 */ 481private int |
482node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt) |
483{ 484 int ncnt; 485 486 if (ptr == NULL) 487 return (-1); /* cannot have null ptr */ 488 489 if (*str == 0) { 490 /* no more chars in str. node_enum from here. */ --- 73 unchanged lines hidden (view full) --- 564} 565 566 567/* key_kprint(): 568 * Print the specified key and its associated 569 * function specified by val 570 */ 571protected void |
572key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype) |
573{ 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: --- 56 unchanged lines hidden (view full) --- 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'; 641 } 642 return (cnt); 643} 644 |
645 |
646/* key__decode_str(): 647 * Make a printable version of the ey 648 */ 649protected char * |
650key__decode_str(const char *str, char *buf, const char *sep) |
651{ |
652 char *b; 653 const char *p; |
654 655 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') --- 29 unchanged lines hidden --- |