diff options
Diffstat (limited to 'contrib/tcsh/ed.xmap.c')
-rw-r--r-- | contrib/tcsh/ed.xmap.c | 844 |
1 files changed, 0 insertions, 844 deletions
diff --git a/contrib/tcsh/ed.xmap.c b/contrib/tcsh/ed.xmap.c deleted file mode 100644 index d4d9bd657665f..0000000000000 --- a/contrib/tcsh/ed.xmap.c +++ /dev/null @@ -1,844 +0,0 @@ -/* $Header: /src/pub/tcsh/ed.xmap.c,v 3.21 1999/06/01 20:01:32 christos Exp $ */ -/* - * ed.xmap.c: This module contains the procedures for maintaining - * the extended-key map. - * - * An extended-key (Xkey) is a sequence of keystrokes - * introduced with an sequence introducer and consisting - * of an arbitrary number of characters. This module maintains - * a map (the Xmap) to convert these extended-key sequences - * into input strings (XK_STR), editor functions (XK_CMD), or - * unix commands (XK_EXE). It contains the - * following externally visible functions. - * - * int GetXkey(ch,val); - * CStr *ch; - * XmapVal *val; - * - * 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. - * - * void AddXkey(Xkey, val, ntype); - * CStr *Xkey; - * XmapVal *val; - * int ntype; - * - * Adds Xkey to the Xmap and associates the value in val with it. - * If Xkey is already is in Xmap, the new code is applied to the - * existing Xkey. Ntype specifies if code is a command, an - * out string or a unix command. - * - * int DeleteXkey(Xkey); - * CStr *Xkey; - * - * Delete the Xkey and all longer Xkeys staring with Xkey, if - * they exists. - * - * Warning: - * If Xkey is a substring of some other Xkeys, then the longer - * Xkeys are lost!! That is, if the Xkeys "abcd" and "abcef" - * are in Xmap, adding the key "abc" will cause the first two - * definitions to be lost. - * - * void ResetXmap(); - * - * Removes all entries from Xmap and resets the defaults. - * - * void PrintXkey(Xkey); - * CStr *Xkey; - * - * Prints all extended keys prefixed by Xkey and their associated - * commands. - * - * Restrictions: - * ------------- - * 1) It is not possible to have one Xkey that is a - * substring of another. - */ -/*- - * Copyright (c) 1980, 1991 The Regents of the University of California. - * All rights reserved. - * - * 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. - */ -#include "sh.h" - -RCSID("$Id: ed.xmap.c,v 3.21 1999/06/01 20:01:32 christos Exp $") - -#include "ed.h" -#include "ed.defns.h" - -#ifndef NULL -#define NULL 0 -#endif - -/* Internal Data types and declarations */ - -/* The Nodes of the Xmap. The Xmap is a linked list of these node - * elements - */ -typedef struct Xmapnode { - Char ch; /* single character of Xkey */ - int type; - XmapVal val; /* command code or pointer to string, if this - * is a leaf */ - struct Xmapnode *next; /* ptr to next char of this Xkey */ - struct Xmapnode *sibling; /* ptr to another Xkey with same prefix */ -} XmapNode; - -static XmapNode *Xmap = NULL; /* the current Xmap */ -#define MAXXKEY 100 /* max length of a Xkey for print putposes */ -static Char printbuf[MAXXKEY]; /* buffer for printing */ - - -/* Some declarations of procedures */ -static int TraverseMap __P((XmapNode *, CStr *, XmapVal *)); -static int TryNode __P((XmapNode *, CStr *, XmapVal *, int)); -static XmapNode *GetFreeNode __P((CStr *)); -static void PutFreeNode __P((XmapNode *)); -static int TryDeleteNode __P((XmapNode **, CStr *)); -static int Lookup __P((CStr *, XmapNode *, int)); -static int Enumerate __P((XmapNode *, int)); -static int unparsech __P((int, Char *)); - - -XmapVal * -XmapCmd(cmd) - int cmd; -{ - static XmapVal xm; - xm.cmd = (KEYCMD) cmd; - return &xm; -} - -XmapVal * -XmapStr(str) - CStr *str; -{ - static XmapVal xm; - xm.str.len = str->len; - xm.str.buf = str->buf; - return &xm; -} - -/* ResetXmap(): - * Takes all nodes on Xmap and puts them on free list. Then - * initializes Xmap with arrow keys - */ -void -ResetXmap() -{ - PutFreeNode(Xmap); - Xmap = NULL; - - DefaultArrowKeys(); - return; -} - - -/* GetXkey(): - * Calls the recursive function with entry point Xmap - */ -int -GetXkey(ch, val) - CStr *ch; - XmapVal *val; -{ - return (TraverseMap(Xmap, ch, val)); -} - -/* TraverseMap(): - * recursively traverses node in tree until match or mismatch is - * found. May read in more characters. - */ -static int -TraverseMap(ptr, ch, val) - XmapNode *ptr; - CStr *ch; - XmapVal *val; -{ - Char tch; - - if (ptr->ch == *(ch->buf)) { - /* match found */ - if (ptr->next) { - /* Xkey not complete so get next char */ - if (GetNextChar(&tch) != 1) { /* if EOF or error */ - val->cmd = F_SEND_EOF; - return XK_CMD;/* PWP: Pretend we just read an end-of-file */ - } - *(ch->buf) = tch; - return (TraverseMap(ptr->next, ch, val)); - } - else { - *val = ptr->val; - if (ptr->type != XK_CMD) - *(ch->buf) = '\0'; - return ptr->type; - } - } - else { - /* no match found here */ - if (ptr->sibling) { - /* try next sibling */ - return (TraverseMap(ptr->sibling, ch, val)); - } - else { - /* no next sibling -- mismatch */ - val->str.buf = NULL; - val->str.len = 0; - return XK_STR; - } - } -} - -void -AddXkey(Xkey, val, ntype) - CStr *Xkey; - XmapVal *val; - int ntype; -{ - CStr cs; - cs.buf = Xkey->buf; - cs.len = Xkey->len; - if (Xkey->len == 0) { - xprintf(CGETS(9, 1, "AddXkey: Null extended-key not allowed.\n")); - return; - } - - if (ntype == XK_CMD && val->cmd == F_XKEY) { - xprintf(CGETS(9, 2, "AddXkey: sequence-lead-in command not allowed\n")); - return; - } - - if (Xmap == NULL) - /* tree is initially empty. Set up new node to match Xkey[0] */ - Xmap = GetFreeNode(&cs); /* it is properly initialized */ - - /* Now recurse through Xmap */ - (void) TryNode(Xmap, &cs, val, ntype); - return; -} - -static int -TryNode(ptr, str, val, ntype) - XmapNode *ptr; - CStr *str; - XmapVal *val; - int ntype; -{ - /* - * Find a node that matches *string or allocate a new one - */ - if (ptr->ch != *(str->buf)) { - XmapNode *xm; - - for (xm = ptr; xm->sibling != NULL; xm = xm->sibling) - if (xm->sibling->ch == *(str->buf)) - break; - if (xm->sibling == NULL) - xm->sibling = GetFreeNode(str); /* setup new node */ - ptr = xm->sibling; - } - - str->buf++; - str->len--; - if (str->len == 0) { - /* we're there */ - if (ptr->next != NULL) { - PutFreeNode(ptr->next); /* lose longer Xkeys with this prefix */ - ptr->next = NULL; - } - - switch (ptr->type) { - case XK_STR: - case XK_EXE: - if (ptr->val.str.buf != NULL) - xfree((ptr_t) ptr->val.str.buf); - ptr->val.str.len = 0; - break; - case XK_NOD: - case XK_CMD: - break; - default: - abort(); - break; - } - - switch (ptr->type = ntype) { - case XK_CMD: - ptr->val = *val; - break; - case XK_STR: - case XK_EXE: - ptr->val.str.len = (val->str.len + 1) * sizeof(Char); - ptr->val.str.buf = (Char *) xmalloc((size_t) ptr->val.str.len); - (void) memmove((ptr_t) ptr->val.str.buf, (ptr_t) val->str.buf, - (size_t) ptr->val.str.len); - ptr->val.str.len = val->str.len; - break; - default: - abort(); - break; - } - } - else { - /* still more chars to go */ - if (ptr->next == NULL) - ptr->next = GetFreeNode(str); /* setup new node */ - (void) TryNode(ptr->next, str, val, ntype); - } - return (0); -} - -void -ClearXkey(map, in) - KEYCMD *map; - CStr *in; -{ - unsigned char c = (unsigned char) *(in->buf); - if ((map[c] == F_XKEY) && - ((map == CcKeyMap && CcAltMap[c] != F_XKEY) || - (map == CcAltMap && CcKeyMap[c] != F_XKEY))) - (void) DeleteXkey(in); -} - -int -DeleteXkey(Xkey) - CStr *Xkey; -{ - if (Xkey->len == 0) { - xprintf(CGETS(9, 3, "DeleteXkey: Null extended-key not allowed.\n")); - return (-1); - } - - if (Xmap == NULL) - return (0); - - (void) TryDeleteNode(&Xmap, Xkey); - return (0); -} - -static int -TryDeleteNode(inptr, str) - XmapNode **inptr; - CStr *str; -{ - XmapNode *ptr; - XmapNode *prev_ptr = NULL; - - ptr = *inptr; - /* - * Find a node that matches *string or allocate a new one - */ - if (ptr->ch != *(str->buf)) { - XmapNode *xm; - - for (xm = ptr; xm->sibling != NULL; xm = xm->sibling) - if (xm->sibling->ch == *(str->buf)) - break; - if (xm->sibling == NULL) - return (0); - prev_ptr = xm; - ptr = xm->sibling; - } - - str->buf++; - str->len--; - - if (str->len == 0) { - /* we're there */ - if (prev_ptr == NULL) - *inptr = ptr->sibling; - else - prev_ptr->sibling = ptr->sibling; - ptr->sibling = NULL; - PutFreeNode(ptr); - return (1); - } - else if (ptr->next != NULL && TryDeleteNode(&ptr->next, str) == 1) { - if (ptr->next != NULL) - return (0); - if (prev_ptr == NULL) - *inptr = ptr->sibling; - else - prev_ptr->sibling = ptr->sibling; - ptr->sibling = NULL; - PutFreeNode(ptr); - return (1); - } - else { - return (0); - } -} - -/* PutFreeNode(): - * Puts a tree of nodes onto free list using free(3). - */ -static void -PutFreeNode(ptr) - XmapNode *ptr; -{ - if (ptr == NULL) - return; - - if (ptr->next != NULL) { - PutFreeNode(ptr->next); - ptr->next = NULL; - } - - PutFreeNode(ptr->sibling); - - switch (ptr->type) { - case XK_CMD: - case XK_NOD: - break; - case XK_EXE: - case XK_STR: - if (ptr->val.str.buf != NULL) - xfree((ptr_t) ptr->val.str.buf); - break; - default: - abort(); - break; - } - xfree((ptr_t) ptr); -} - - -/* GetFreeNode(): - * Returns pointer to an XmapNode for ch. - */ -static XmapNode * -GetFreeNode(ch) - CStr *ch; -{ - XmapNode *ptr; - - ptr = (XmapNode *) xmalloc((size_t) sizeof(XmapNode)); - ptr->ch = ch->buf[0]; - ptr->type = XK_NOD; - ptr->val.str.buf = NULL; - ptr->val.str.len = 0; - ptr->next = NULL; - ptr->sibling = NULL; - return (ptr); -} - - -/* PrintXKey(): - * Print the binding associated with Xkey key. - * Print entire Xmap if null - */ -void -PrintXkey(key) - CStr *key; -{ - CStr cs; - - if (key) { - cs.buf = key->buf; - cs.len = key->len; - } - else { - cs.buf = STRNULL; - cs.len = 0; - } - /* do nothing if Xmap is empty and null key specified */ - if (Xmap == NULL && cs.len == 0) - return; - - printbuf[0] = '"'; - if (Lookup(&cs, Xmap, 1) <= -1) - /* key is not bound */ - xprintf(CGETS(9, 4, "Unbound extended key \"%S\"\n"), cs.buf); - return; -} - -/* Lookup(): - * look for the string starting at node ptr. - * Print if last node - */ -static int -Lookup(str, ptr, cnt) - CStr *str; - XmapNode *ptr; - int cnt; -{ - int ncnt; - - if (ptr == NULL) - return (-1); /* cannot have null ptr */ - - if (str->len == 0) { - /* no more chars in string. Enumerate from here. */ - (void) Enumerate(ptr, cnt); - return (0); - } - else { - /* If match put this char into printbuf. Recurse */ - if (ptr->ch == *(str->buf)) { - /* match found */ - ncnt = unparsech(cnt, &ptr->ch); - if (ptr->next != NULL) { - /* not yet at leaf */ - CStr tstr; - tstr.buf = str->buf + 1; - tstr.len = str->len - 1; - return (Lookup(&tstr, ptr->next, ncnt + 1)); - } - else { - /* next node is null so key should be complete */ - if (str->len == 1) { - CStr pb; - printbuf[ncnt + 1] = '"'; - printbuf[ncnt + 2] = '\0'; - pb.buf = printbuf; - pb.len = ncnt + 2; - (void) printOne(&pb, &ptr->val, ptr->type); - return (0); - } - else - return (-1);/* mismatch -- string still has chars */ - } - } - else { - /* no match found try sibling */ - if (ptr->sibling) - return (Lookup(str, ptr->sibling, cnt)); - else - return (-1); - } - } -} - -static int -Enumerate(ptr, cnt) - XmapNode *ptr; - int cnt; -{ - int ncnt; - - if (cnt >= MAXXKEY - 5) { /* buffer too small */ - printbuf[++cnt] = '"'; - printbuf[++cnt] = '\0'; - xprintf(CGETS(9, 5, - "Some extended keys too long for internal print buffer")); - xprintf(" \"%S...\"\n", printbuf); - return (0); - } - - if (ptr == NULL) { -#ifdef DEBUG_EDIT - xprintf(CGETS(9, 6, "Enumerate: BUG!! Null ptr passed\n!")); -#endif - return (-1); - } - - ncnt = unparsech(cnt, &ptr->ch); /* put this char at end of string */ - if (ptr->next == NULL) { - CStr pb; - /* print this Xkey and function */ - printbuf[++ncnt] = '"'; - printbuf[++ncnt] = '\0'; - pb.buf = printbuf; - pb.len = ncnt; - (void) printOne(&pb, &ptr->val, ptr->type); - } - else - (void) Enumerate(ptr->next, ncnt + 1); - - /* go to sibling if there is one */ - if (ptr->sibling) - (void) Enumerate(ptr->sibling, cnt); - return (0); -} - - -/* PrintOne(): - * Print the specified key and its associated - * function specified by val - */ -int -printOne(key, val, ntype) - CStr *key; - XmapVal *val; - int ntype; -{ - struct KeyFuncs *fp; - unsigned char unparsbuf[200]; - static char *fmt = "%s\n"; - - xprintf("%-15S-> ", key->buf); - if (val != NULL) - switch (ntype) { - case XK_STR: - case XK_EXE: - xprintf(fmt, unparsestring(&val->str, unparsbuf, - ntype == XK_STR ? STRQQ : STRBB)); - break; - case XK_CMD: - for (fp = FuncNames; fp->name; fp++) - if (val->cmd == fp->func) - xprintf(fmt, fp->name); - break; - default: - abort(); - break; - } - else - xprintf(fmt, key, CGETS(9, 7, "no input")); - return (0); -} - -static int -unparsech(cnt, ch) - int cnt; - Char *ch; -{ - if (ch == 0) { - printbuf[cnt++] = '^'; - printbuf[cnt] = '@'; - return cnt; - } - - if (Iscntrl(*ch)) { -#ifndef _OSD_POSIX - printbuf[cnt++] = '^'; - if (*ch == CTL_ESC('\177')) - printbuf[cnt] = '?'; - else - printbuf[cnt] = *ch | 0100; -#else /*_OSD_POSIX*/ - if (*ch == CTL_ESC('\177')) - { - printbuf[cnt++] = '^'; - printbuf[cnt] = '?'; - } - else if (Isupper(_toebcdic[_toascii[*ch]|0100]) - || strchr("@[\\]^_", _toebcdic[_toascii[*ch]|0100]) != NULL) - { - printbuf[cnt++] = '^'; - printbuf[cnt] = _toebcdic[_toascii[*ch]|0100]; - } - else - { - printbuf[cnt++] = '\\'; - printbuf[cnt++] = ((*ch >> 6) & 7) + '0'; - printbuf[cnt++] = ((*ch >> 3) & 7) + '0'; - printbuf[cnt] = (*ch & 7) + '0'; - } -#endif /*_OSD_POSIX*/ - } - else if (*ch == '^') { - printbuf[cnt++] = '\\'; - printbuf[cnt] = '^'; - } - else if (*ch == '\\') { - printbuf[cnt++] = '\\'; - printbuf[cnt] = '\\'; - } - else if (*ch == ' ' || (Isprint(*ch) && !Isspace(*ch))) { - printbuf[cnt] = *ch; - } - else { - printbuf[cnt++] = '\\'; - printbuf[cnt++] = ((*ch >> 6) & 7) + '0'; - printbuf[cnt++] = ((*ch >> 3) & 7) + '0'; - printbuf[cnt] = (*ch & 7) + '0'; - } - return cnt; -} - -int -parseescape(ptr) - const Char **ptr; -{ - const Char *p; - Char c; - - p = *ptr; - - if ((p[1] & CHAR) == 0) { - xprintf(CGETS(9, 8, "Something must follow: %c\n"), *p); - return -1; - } - if ((*p & CHAR) == '\\') { - p++; - switch (*p & CHAR) { - case 'a': - c = CTL_ESC('\007'); /* Bell */ - break; - case 'b': - c = CTL_ESC('\010'); /* Backspace */ - break; - case 'e': - c = CTL_ESC('\033'); /* Escape */ - break; - case 'f': - c = CTL_ESC('\014'); /* Form Feed */ - break; - case 'n': - c = CTL_ESC('\012'); /* New Line */ - break; - case 'r': - c = CTL_ESC('\015'); /* Carriage Return */ - break; - case 't': - c = CTL_ESC('\011'); /* Horizontal Tab */ - break; - case 'v': - c = CTL_ESC('\013'); /* Vertical Tab */ - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - { - register int cnt, val, ch; - - for (cnt = 0, val = 0; cnt < 3; cnt++) { - ch = *p++ & CHAR; - if (ch < '0' || ch > '7') { - p--; - break; - } - val = (val << 3) | (ch - '0'); - } - if ((val & 0xffffff00) != 0) { - xprintf(CGETS(9, 9, - "Octal constant does not fit in a char.\n")); - return 0; - } -#ifdef _OSD_POSIX - if (CTL_ESC(val) != val && adrof(STRwarnebcdic)) - xprintf(/*CGETS(9, 9, no NLS-String yet!*/ - "Warning: Octal constant \\%3.3o is interpreted as EBCDIC value.\n", val/*)*/); -#endif - c = (Char) val; - --p; - } - break; - default: - c = *p; - break; - } - } - else if ((*p & CHAR) == '^' && (Isalpha(p[1] & CHAR) || - strchr("@^_?\\|[{]}", p[1] & CHAR))) { - p++; -#ifndef _OSD_POSIX - c = ((*p & CHAR) == '?') ? CTL_ESC('\177') : ((*p & CHAR) & 0237); -#else /*_OSD_POSIX*/ - c = ((*p & CHAR) == '?') ? CTL_ESC('\177') : _toebcdic[_toascii[*p & CHAR] & 0237]; - if (adrof(STRwarnebcdic)) - xprintf(/*CGETS(9, 9, no NLS-String yet!*/ - "Warning: Control character ^%c may be interpreted differently in EBCDIC.\n", *p & CHAR /*)*/); -#endif /*_OSD_POSIX*/ - } - else - c = *p; - *ptr = p; - return (c); -} - - -unsigned char * -unparsestring(str, buf, sep) - CStr *str; - unsigned char *buf; - Char *sep; -{ - unsigned char *b; - Char p; - int l; - - b = buf; - if (sep[0]) -#ifndef WINNT - *b++ = sep[0]; -#else /* WINNT */ - *b++ = CHAR & sep[0]; -#endif /* !WINNT */ - - for (l = 0; l < str->len; l++) { - p = str->buf[l]; - if (Iscntrl(p)) { -#ifndef _OSD_POSIX - *b++ = '^'; - if (p == CTL_ESC('\177')) - *b++ = '?'; - else - *b++ = (unsigned char) (p | 0100); -#else /*_OSD_POSIX*/ - if (_toascii[p] == '\177' || Isupper(_toebcdic[_toascii[p]|0100]) - || strchr("@[\\]^_", _toebcdic[_toascii[p]|0100]) != NULL) - { - *b++ = '^'; - *b++ = (_toascii[p] == '\177') ? '?' : _toebcdic[_toascii[p]|0100]; - } - else - { - *b++ = '\\'; - *b++ = ((p >> 6) & 7) + '0'; - *b++ = ((p >> 3) & 7) + '0'; - *b++ = (p & 7) + '0'; - } -#endif /*_OSD_POSIX*/ - } - else if (p == '^' || p == '\\') { - *b++ = '\\'; - *b++ = (unsigned char) p; - } - else if (p == ' ' || (Isprint(p) && !Isspace(p))) { - *b++ = (unsigned char) p; - } - else { - *b++ = '\\'; - *b++ = ((p >> 6) & 7) + '0'; - *b++ = ((p >> 3) & 7) + '0'; - *b++ = (p & 7) + '0'; - } - } - if (sep[0] && sep[1]) -#ifndef WINNT - *b++ = sep[1]; -#else /* WINNT */ - *b++ = CHAR & sep[1]; -#endif /* !WINNT */ - *b++ = 0; - return buf; /* should check for overflow */ -} |