⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 key.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*- * Copyright (c) 1992, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * Christos Zoulas of Cornell University. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#if !defined(lint) && !defined(SCCSID)static char sccsid[] = "@(#)key.c	8.1 (Berkeley) 6/4/93";#endif /* not lint && not SCCSID *//* * key.c: This module contains the procedures for maintaining *	  the extended-key map. * *      An extended-key (key) is a sequence of keystrokes introduced  *	with an sequence introducer and consisting of an arbitrary  *	number of characters.  This module maintains a map (the el->el_key.map)  *	to convert these extended-key sequences into input strs  *	(XK_STR), editor functions (XK_CMD), or unix commands (XK_EXE). * *      Warning: *	  If key is a substr of some other keys, then the longer *	  keys are lost!!  That is, if the keys "abcd" and "abcef" *	  are in el->el_key.map, adding the key "abc" will cause the first two *	  definitions to be lost. * *      Restrictions: *      ------------- *      1) It is not possible to have one key that is a *	   substr of another. */#include "sys.h"#include <string.h>#include <stdlib.h>#include "el.h"/*  * The Nodes of the el->el_key.map.  The el->el_key.map is a linked list  * of these node elements */struct key_node_t {    char        ch;		/* single character of key 		*/    int         type;		/* node type				*/    key_value_t val; 		/* command code or pointer to str, 	*/				/* if this is a leaf 			*/    struct key_node_t *next;	/* ptr to next char of this key 	*/    struct key_node_t *sibling;	/* ptr to another key with same prefix 	*/};private	int            node_trav	__P((EditLine *, key_node_t *, char *, 					     key_value_t *));private	int            node__try	__P((key_node_t *, char *, 					     key_value_t *, int));private	key_node_t    *node__get	__P((int));private	void	       node__put	__P((key_node_t *));private	int	       node__delete	__P((key_node_t **, char *));private	int	       node_lookup 	__P((EditLine *, char *, key_node_t *,					     int));private	int	       node_enum	__P((EditLine *, key_node_t *, int));private	int	       key__decode_char	__P((char *, int, int));#define KEY_BUFSIZ	EL_BUFSIZ/* key_init(): *	Initialize the key maps */protected intkey_init(el)    EditLine *el;{    el->el_key.buf = (char *) el_malloc(KEY_BUFSIZ);    el->el_key.map = NULL;    key_reset(el);    return 0;} /* key_end(): *	Free the key maps */protected voidkey_end(el)    EditLine *el;{    el_free((ptr_t) el->el_key.buf);    el->el_key.buf = NULL;    /* XXX: provide a function to clear the keys */    el->el_key.map = NULL;} /* key_map_cmd(): *	Associate cmd with a key value */protected key_value_t *key_map_cmd(el, cmd)    EditLine *el;    int cmd;{    el->el_key.val.cmd = (el_action_t) cmd;    return &el->el_key.val;}/* key_map_str(): *	Associate str with a key value */protected key_value_t *key_map_str(el, str)    EditLine *el;    char  *str;{    el->el_key.val.str = str;    return &el->el_key.val;}/* key_reset(): *	Takes all nodes on el->el_key.map and puts them on free list.  Then *	initializes el->el_key.map with arrow keys *	[Always bind the ansi arrow keys?] */protected voidkey_reset(el)    EditLine *el;{    node__put(el->el_key.map);    el->el_key.map = NULL;    return;}/* key_get(): *	Calls the recursive function with entry point el->el_key.map *      Looks up *ch in map and then reads characters until a *      complete match is found or a mismatch occurs. Returns the *      type of the match found (XK_STR, XK_CMD, or XK_EXE). *      Returns NULL in val.str and XK_STR for no match.   *      The last character read is returned in *ch. */protected intkey_get(el, ch, val)    EditLine    *el;    char        *ch;    key_value_t *val;{    return node_trav(el, el->el_key.map, ch, val);}/* key_add(): *      Adds key to the el->el_key.map and associates the value in val with it. *      If key is already is in el->el_key.map, the new code is applied to the *      existing key. Ntype specifies if code is a command, an *      out str or a unix command. */protected voidkey_add(el, key, val, ntype)    EditLine    *el;    char        *key;    key_value_t *val;    int          ntype;{    if (key[0] == '\0') {	(void) fprintf(el->el_errfile, 		       "key_add: Null extended-key not allowed.\n");	return;    }    if (ntype == XK_CMD && val->cmd == ED_SEQUENCE_LEAD_IN) {	(void) fprintf(el->el_errfile,		       "key_add: sequence-lead-in command not allowed\n");	return;    }    if (el->el_key.map == NULL)	/* tree is initially empty.  Set up new node to match key[0] */	el->el_key.map = node__get(key[0]);	/* it is properly initialized */    /* Now recurse through el->el_key.map */    (void) node__try(el->el_key.map, key, val, ntype);	    return;}/* key_clear(): * */protected voidkey_clear(el, map, in)    EditLine *el;    el_action_t *map;    char   *in;{    if ((map[(unsigned char) *in] == ED_SEQUENCE_LEAD_IN) &&	((map == el->el_map.key && 	  el->el_map.alt[(unsigned char) *in] != ED_SEQUENCE_LEAD_IN) ||	 (map == el->el_map.alt && 	  el->el_map.key[(unsigned char) *in] != ED_SEQUENCE_LEAD_IN)))	(void) key_delete(el, in);}/* key_delete(): *      Delete the key and all longer keys staring with key, if *      they exists. */protected intkey_delete(el, key)    EditLine *el;    char   *key;{    if (key[0] == '\0') {	(void) fprintf(el->el_errfile, 		       "key_delete: Null extended-key not allowed.\n");	return -1;    }    if (el->el_key.map == NULL)	return 0;    (void) node__delete(&el->el_key.map, key);    return 0;}/* key_print(): *	Print the binding associated with key key. *	Print entire el->el_key.map if null */protected voidkey_print(el, key)    EditLine *el;    char   *key;{    /* do nothing if el->el_key.map is empty and null key specified */    if (el->el_key.map == NULL && *key == 0)	return;    el->el_key.buf[0] =  '"';    if (node_lookup(el, key, el->el_key.map, 1) <= -1)	/* key is not bound */	(void) fprintf(el->el_errfile, "Unbound extended key \"%s\"\n", key);    return;}/* node_trav(): *	recursively traverses node in tree until match or mismatch is * 	found.  May read in more characters. */private intnode_trav(el, ptr, ch, val)    EditLine     *el;    key_node_t   *ptr;    char         *ch;    key_value_t  *val;{    if (ptr->ch == *ch) {	/* match found */	if (ptr->next) {	    /* key not complete so get next char */	    if (el_getc(el, ch) != 1) {	/* if EOF or error */		val->cmd = ED_END_OF_FILE;		return XK_CMD;/* PWP: Pretend we just read an end-of-file */	    }	    return node_trav(el, ptr->next, ch, val);	}	else {	    *val = ptr->val;	    if (ptr->type != XK_CMD)		*ch = '\0';	    return ptr->type;	}    }    else {	/* no match found here */	if (ptr->sibling) {	    /* try next sibling */	    return node_trav(el, ptr->sibling, ch, val);	}	else {	    /* no next sibling -- mismatch */	    val->str = NULL;	    return XK_STR;	}    }}/* node__try(): * 	Find a node that matches *str or allocate a new one */private intnode__try(ptr, str, val, ntype)    key_node_t   *ptr;    char         *str;    key_value_t  *val;    int           ntype;{    if (ptr->ch != *str) {	key_node_t *xm;	for (xm = ptr; xm->sibling != NULL; xm = xm->sibling)	    if (xm->sibling->ch == *str)		break;	if (xm->sibling == NULL)	    xm->sibling = node__get(*str);	/* setup new node */	ptr = xm->sibling;    }    if (*++str == '\0') {	/* we're there */	if (ptr->next != NULL) {	    node__put(ptr->next);	/* lose longer keys with this prefix */	    ptr->next = NULL;	}	switch (ptr->type) {	case XK_CMD:	case XK_NOD:	    break;	case XK_STR:	case XK_EXE:	    if (ptr->val.str)		el_free((ptr_t) ptr->val.str);	    break;	default:	    abort();	    break;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -