+++ /dev/null
-/* $OpenBSD: extend.c,v 1.53 2012/05/25 04:56:58 lum Exp $ */
-
-/* This file is in the public domain. */
-
-/*
- * Extended (M-X) commands, rebinding, and startup file processing.
- */
-#include "chrdef.h"
-#include "def.h"
-#include "kbd.h"
-#include "funmap.h"
-
-#include <sys/types.h>
-#include <ctype.h>
-
-#include "macro.h"
-
-#ifdef FKEYS
-#include "key.h"
-#ifndef BINDKEY
-#define BINDKEY /* bindkey is used by FKEYS startup code */
-#endif /* !BINDKEY */
-#endif /* FKEYS */
-
-#include <ctype.h>
-
-static int remap(KEYMAP *, int, PF, KEYMAP *);
-static KEYMAP *reallocmap(KEYMAP *);
-static void fixmap(KEYMAP *, KEYMAP *, KEYMAP *);
-static int dobind(KEYMAP *, const char *, int);
-static char *skipwhite(char *);
-static char *parsetoken(char *);
-#ifdef BINDKEY
-static int bindkey(KEYMAP **, const char *, KCHAR *, int);
-#endif /* BINDKEY */
-
-/*
- * Insert a string, mainly for use from macros (created by selfinsert).
- */
-/* ARGSUSED */
-int
-insert(int f, int n)
-{
- char buf[128], *bufp, *cp;
- int count, c;
-
- if (inmacro) {
- while (--n >= 0) {
- for (count = 0; count < maclcur->l_used; count++) {
- if ((((c = maclcur->l_text[count]) == '\n')
- ? lnewline() : linsert(1, c)) != TRUE)
- return (FALSE);
- }
- }
- maclcur = maclcur->l_fp;
- return (TRUE);
- }
- if (n == 1)
- /* CFINS means selfinsert can tack on the end */
- thisflag |= CFINS;
-
- if ((bufp = eread("Insert: ", buf, sizeof(buf), EFNEW)) == NULL)
- return (ABORT);
- else if (bufp[0] == '\0')
- return (FALSE);
- while (--n >= 0) {
- cp = buf;
- while (*cp) {
- if (((*cp == '\n') ? lnewline() : linsert(1, *cp))
- != TRUE)
- return (FALSE);
- cp++;
- }
- }
- return (TRUE);
-}
-
-/*
- * Bind a key to a function. Cases range from the trivial (replacing an
- * existing binding) to the extremely complex (creating a new prefix in a
- * map_element that already has one, so the map_element must be split,
- * but the keymap doesn't have enough room for another map_element, so
- * the keymap is reallocated). No attempt is made to reclaim space no
- * longer used, if this is a problem flags must be added to indicate
- * malloced versus static storage in both keymaps and map_elements.
- * Structure assignments would come in real handy, but K&R based compilers
- * don't have them. Care is taken so running out of memory will leave
- * the keymap in a usable state.
- * Parameters are:
- * curmap: pointer to the map being changed
- * c: character being changed
- * funct: function being changed to
- * pref_map: if funct==NULL, map to bind to or NULL for new
- */
-static int
-remap(KEYMAP *curmap, int c, PF funct, KEYMAP *pref_map)
-{
- int i, n1, n2, nold;
- KEYMAP *mp, *newmap;
- PF *pfp;
- struct map_element *mep;
-
- if (ele >= &curmap->map_element[curmap->map_num] || c < ele->k_base) {
- if (ele > &curmap->map_element[0] && (funct != NULL ||
- (ele - 1)->k_prefmap == NULL))
- n1 = c - (ele - 1)->k_num;
- else
- n1 = HUGE;
- if (ele < &curmap->map_element[curmap->map_num] &&
- (funct != NULL || ele->k_prefmap == NULL))
- n2 = ele->k_base - c;
- else
- n2 = HUGE;
- if (n1 <= MAPELEDEF && n1 <= n2) {
- ele--;
- if ((pfp = calloc(c - ele->k_base + 1,
- sizeof(PF))) == NULL) {
- ewprintf("Out of memory");
- return (FALSE);
- }
- nold = ele->k_num - ele->k_base + 1;
- for (i = 0; i < nold; i++)
- pfp[i] = ele->k_funcp[i];
- while (--n1)
- pfp[i++] = curmap->map_default;
- pfp[i] = funct;
- ele->k_num = c;
- ele->k_funcp = pfp;
- } else if (n2 <= MAPELEDEF) {
- if ((pfp = calloc(ele->k_num - c + 1,
- sizeof(PF))) == NULL) {
- ewprintf("Out of memory");
- return (FALSE);
- }
- nold = ele->k_num - ele->k_base + 1;
- for (i = 0; i < nold; i++)
- pfp[i + n2] = ele->k_funcp[i];
- while (--n2)
- pfp[n2] = curmap->map_default;
- pfp[0] = funct;
- ele->k_base = c;
- ele->k_funcp = pfp;
- } else {
- if (curmap->map_num >= curmap->map_max) {
- if ((newmap = reallocmap(curmap)) == NULL)
- return (FALSE);
- curmap = newmap;
- }
- if ((pfp = malloc(sizeof(PF))) == NULL) {
- ewprintf("Out of memory");
- return (FALSE);
- }
- pfp[0] = funct;
- for (mep = &curmap->map_element[curmap->map_num];
- mep > ele; mep--) {
- mep->k_base = (mep - 1)->k_base;
- mep->k_num = (mep - 1)->k_num;
- mep->k_funcp = (mep - 1)->k_funcp;
- mep->k_prefmap = (mep - 1)->k_prefmap;
- }
- ele->k_base = c;
- ele->k_num = c;
- ele->k_funcp = pfp;
- ele->k_prefmap = NULL;
- curmap->map_num++;
- }
- if (funct == NULL) {
- if (pref_map != NULL)
- ele->k_prefmap = pref_map;
- else {
- if ((mp = malloc(sizeof(KEYMAP) +
- (MAPINIT - 1) * sizeof(struct map_element))) == NULL) {
- ewprintf("Out of memory");
- ele->k_funcp[c - ele->k_base] =
- curmap->map_default;
- return (FALSE);
- }
- mp->map_num = 0;
- mp->map_max = MAPINIT;
- mp->map_default = rescan;
- ele->k_prefmap = mp;
- }
- }
- } else {
- n1 = c - ele->k_base;
- if (ele->k_funcp[n1] == funct && (funct != NULL ||
- pref_map == NULL || pref_map == ele->k_prefmap))
- /* no change */
- return (TRUE);
- if (funct != NULL || ele->k_prefmap == NULL) {
- if (ele->k_funcp[n1] == NULL)
- ele->k_prefmap = NULL;
- /* easy case */
- ele->k_funcp[n1] = funct;
- if (funct == NULL) {
- if (pref_map != NULL)
- ele->k_prefmap = pref_map;
- else {
- if ((mp = malloc(sizeof(KEYMAP) +
- (MAPINIT - 1) *
- sizeof(struct map_element))) == NULL) {
- ewprintf("Out of memory");
- ele->k_funcp[c - ele->k_base] =
- curmap->map_default;
- return (FALSE);
- }
- mp->map_num = 0;
- mp->map_max = MAPINIT;
- mp->map_default = rescan;
- ele->k_prefmap = mp;
- }
- }
- } else {
- /*
- * This case is the splits.
- * Determine which side of the break c goes on
- * 0 = after break; 1 = before break
- */
- n2 = 1;
- for (i = 0; n2 && i < n1; i++)
- n2 &= ele->k_funcp[i] != NULL;
- if (curmap->map_num >= curmap->map_max) {
- if ((newmap = reallocmap(curmap)) == NULL)
- return (FALSE);
- curmap = newmap;
- }
- if ((pfp = calloc(ele->k_num - c + !n2,
- sizeof(PF))) == NULL) {
- ewprintf("Out of memory");
- return (FALSE);
- }
- ele->k_funcp[n1] = NULL;
- for (i = n1 + n2; i <= ele->k_num - ele->k_base; i++)
- pfp[i - n1 - n2] = ele->k_funcp[i];
- for (mep = &curmap->map_element[curmap->map_num];
- mep > ele; mep--) {
- mep->k_base = (mep - 1)->k_base;
- mep->k_num = (mep - 1)->k_num;
- mep->k_funcp = (mep - 1)->k_funcp;
- mep->k_prefmap = (mep - 1)->k_prefmap;
- }
- ele->k_num = c - !n2;
- (ele + 1)->k_base = c + n2;
- (ele + 1)->k_funcp = pfp;
- ele += !n2;
- ele->k_prefmap = NULL;
- curmap->map_num++;
- if (pref_map == NULL) {
- if ((mp = malloc(sizeof(KEYMAP) + (MAPINIT - 1)
- * sizeof(struct map_element))) == NULL) {
- ewprintf("Out of memory");
- ele->k_funcp[c - ele->k_base] =
- curmap->map_default;
- return (FALSE);
- }
- mp->map_num = 0;
- mp->map_max = MAPINIT;
- mp->map_default = rescan;
- ele->k_prefmap = mp;
- } else
- ele->k_prefmap = pref_map;
- }
- }
- return (TRUE);
-}
-
-/*
- * Reallocate a keymap. Returns NULL (without trashing the current map)
- * on failure.
- */
-static KEYMAP *
-reallocmap(KEYMAP *curmap)
-{
- struct maps_s *mps;
- KEYMAP *mp;
- int i;
-
- if (curmap->map_max > SHRT_MAX - MAPGROW) {
- ewprintf("keymap too large");
- return (NULL);
- }
- if ((mp = malloc(sizeof(KEYMAP) + (curmap->map_max + (MAPGROW - 1)) *
- sizeof(struct map_element))) == NULL) {
- ewprintf("Out of memory");
- return (NULL);
- }
- mp->map_num = curmap->map_num;
- mp->map_max = curmap->map_max + MAPGROW;
- mp->map_default = curmap->map_default;
- for (i = curmap->map_num; i--;) {
- mp->map_element[i].k_base = curmap->map_element[i].k_base;
- mp->map_element[i].k_num = curmap->map_element[i].k_num;
- mp->map_element[i].k_funcp = curmap->map_element[i].k_funcp;
- mp->map_element[i].k_prefmap = curmap->map_element[i].k_prefmap;
- }
- for (mps = maps; mps != NULL; mps = mps->p_next) {
- if (mps->p_map == curmap)
- mps->p_map = mp;
- else
- fixmap(curmap, mp, mps->p_map);
- }
- ele = &mp->map_element[ele - &curmap->map_element[0]];
- return (mp);
-}
-
-/*
- * Fix references to a reallocated keymap (recursive).
- */
-static void
-fixmap(KEYMAP *curmap, KEYMAP *mp, KEYMAP *mt)
-{
- int i;
-
- for (i = mt->map_num; i--;) {
- if (mt->map_element[i].k_prefmap != NULL) {
- if (mt->map_element[i].k_prefmap == curmap)
- mt->map_element[i].k_prefmap = mp;
- else
- fixmap(curmap, mp, mt->map_element[i].k_prefmap);
- }
- }
-}
-
-/*
- * Do the input for local-set-key, global-set-key and define-key
- * then call remap to do the work.
- */
-static int
-dobind(KEYMAP *curmap, const char *p, int unbind)
-{
- KEYMAP *pref_map = NULL;
- PF funct;
- char bprompt[80], *bufp, *pep;
- int c, s, n;
-
- if (macrodef) {
- /*
- * Keystrokes aren't collected. Not hard, but pretty useless.
- * Would not work for function keys in any case.
- */
- ewprintf("Can't rebind key in macro");
- return (FALSE);
- }
- if (inmacro) {
- for (s = 0; s < maclcur->l_used - 1; s++) {
- if (doscan(curmap, c = CHARMASK(maclcur->l_text[s]), &curmap)
- != NULL) {
- if (remap(curmap, c, NULL, NULL)
- != TRUE)
- return (FALSE);
- }
- }
- (void)doscan(curmap, c = maclcur->l_text[s], NULL);
- maclcur = maclcur->l_fp;
- } else {
- n = strlcpy(bprompt, p, sizeof(bprompt));
- if (n >= sizeof(bprompt))
- n = sizeof(bprompt) - 1;
- pep = bprompt + n;
- for (;;) {
- ewprintf("%s", bprompt);
- pep[-1] = ' ';
- pep = getkeyname(pep, sizeof(bprompt) -
- (pep - bprompt), c = getkey(FALSE));
- if (doscan(curmap, c, &curmap) != NULL)
- break;
- *pep++ = '-';
- *pep = '\0';
- }
- }
- if (unbind)
- funct = rescan;
- else {
- if ((bufp = eread("%s to command: ", bprompt, sizeof(bprompt),
- EFFUNC | EFNEW, bprompt)) == NULL)
- return (ABORT);
- else if (bufp[0] == '\0')
- return (FALSE);
- if (((funct = name_function(bprompt)) == NULL) ?
- (pref_map = name_map(bprompt)) == NULL : funct == NULL) {
- ewprintf("[No match]");
- return (FALSE);
- }
- }
- return (remap(curmap, c, funct, pref_map));
-}
-
-/*
- * bindkey: bind key sequence to a function in the specified map. Used by
- * excline so it can bind function keys. To close to release to change
- * calling sequence, should just pass KEYMAP *curmap rather than
- * KEYMAP **mapp.
- */
-#ifdef BINDKEY
-static int
-bindkey(KEYMAP **mapp, const char *fname, KCHAR *keys, int kcount)
-{
- KEYMAP *curmap = *mapp;
- KEYMAP *pref_map = NULL;
- PF funct;
- int c;
-
- if (fname == NULL)
- funct = rescan;
- else if (((funct = name_function(fname)) == NULL) ?
- (pref_map = name_map(fname)) == NULL : funct == NULL) {
- ewprintf("[No match: %s]", fname);
- return (FALSE);
- }
- while (--kcount) {
- if (doscan(curmap, c = *keys++, &curmap) != NULL) {
- if (remap(curmap, c, NULL, NULL) != TRUE)
- return (FALSE);
- /*
- * XXX - Bizzarreness. remap creates an empty KEYMAP
- * that the last key is supposed to point to.
- */
- curmap = ele->k_prefmap;
- }
- }
- (void)doscan(curmap, c = *keys, NULL);
- return (remap(curmap, c, funct, pref_map));
-}
-
-#ifdef FKEYS
-/*
- * Wrapper for bindkey() that converts escapes.
- */
-int
-dobindkey(KEYMAP *map, const char *func, const char *str)
-{
- int i;
-
- for (i = 0; *str && i < MAXKEY; i++) {
- /* XXX - convert numbers w/ strol()? */
- if (*str == '^' && *(str + 1) != '\0') {
- key.k_chars[i] = CCHR(toupper(*++str));
- } else if (*str == '\\' && *(str + 1) != '\0') {
- switch (*++str) {
- case '^':
- key.k_chars[i] = '^';
- break;
- case 't':
- case 'T':
- key.k_chars[i] = '\t';
- break;
- case 'n':
- case 'N':
- key.k_chars[i] = '\n';
- break;
- case 'r':
- case 'R':
- key.k_chars[i] = '\r';
- break;
- case 'e':
- case 'E':
- key.k_chars[i] = CCHR('[');
- break;
- case '\\':
- key.k_chars[i] = '\\';
- break;
- }
- } else
- key.k_chars[i] = *str;
- str++;
- }
- key.k_count = i;
- return (bindkey(&map, func, key.k_chars, key.k_count));
-}
-#endif /* FKEYS */
-#endif /* BINDKEY */
-
-/*
- * This function modifies the fundamental keyboard map.
- */
-/* ARGSUSED */
-int
-bindtokey(int f, int n)
-{
- return (dobind(fundamental_map, "Global set key: ", FALSE));
-}
-
-/*
- * This function modifies the current mode's keyboard map.
- */
-/* ARGSUSED */
-int
-localbind(int f, int n)
-{
- return (dobind(curbp->b_modes[curbp->b_nmodes]->p_map,
- "Local set key: ", FALSE));
-}
-
-/*
- * This function redefines a key in any keymap.
- */
-/* ARGSUSED */
-int
-redefine_key(int f, int n)
-{
- static char buf[48];
- char tmp[32], *bufp;
- KEYMAP *mp;
-
- (void)strlcpy(buf, "Define key map: ", sizeof(buf));
- if ((bufp = eread(buf, tmp, sizeof(tmp), EFNEW)) == NULL)
- return (ABORT);
- else if (bufp[0] == '\0')
- return (FALSE);
- (void)strlcat(buf, tmp, sizeof(buf));
- if ((mp = name_map(tmp)) == NULL) {
- ewprintf("Unknown map %s", tmp);
- return (FALSE);
- }
- if (strlcat(buf, "key: ", sizeof(buf)) >= sizeof(buf))
- return (FALSE);
-
- return (dobind(mp, buf, FALSE));
-}
-
-/* ARGSUSED */
-int
-unbindtokey(int f, int n)
-{
- return (dobind(fundamental_map, "Global unset key: ", TRUE));
-}
-
-/* ARGSUSED */
-int
-localunbind(int f, int n)
-{
- return (dobind(curbp->b_modes[curbp->b_nmodes]->p_map,
- "Local unset key: ", TRUE));
-}
-
-/*
- * Extended command. Call the message line routine to read in the command
- * name and apply autocompletion to it. When it comes back, look the name
- * up in the symbol table and run the command if it is found. Print an
- * error if there is anything wrong.
- */
-int
-extend(int f, int n)
-{
- PF funct;
- char xname[NXNAME], *bufp;
-
- if (!(f & FFARG))
- bufp = eread("M-x ", xname, NXNAME, EFNEW | EFFUNC);
- else
- bufp = eread("%d M-x ", xname, NXNAME, EFNEW | EFFUNC, n);
- if (bufp == NULL)
- return (ABORT);
- else if (bufp[0] == '\0')
- return (FALSE);
- if ((funct = name_function(bufp)) != NULL) {
- if (macrodef) {
- struct line *lp = maclcur;
- macro[macrocount - 1].m_funct = funct;
- maclcur = lp->l_bp;
- maclcur->l_fp = lp->l_fp;
- free(lp);
- }
- return ((*funct)(f, n));
- }
- ewprintf("[No match]");
- return (FALSE);
-}
-
-/*
- * Define the commands needed to do startup-file processing.
- * This code is mostly a kludge just so we can get startup-file processing.
- *
- * If you're serious about having this code, you should rewrite it.
- * To wit:
- * It has lots of funny things in it to make the startup-file look
- * like a GNU startup file; mostly dealing with parens and semicolons.
- * This should all vanish.
- *
- * We define eval-expression because it's easy. It can make
- * *-set-key or define-key set an arbitrary key sequence, so it isn't
- * useless.
- */
-
-/*
- * evalexpr - get one line from the user, and run it.
- */
-/* ARGSUSED */
-int
-evalexpr(int f, int n)
-{
- char exbuf[128], *bufp;
-
- if ((bufp = eread("Eval: ", exbuf, sizeof(exbuf),
- EFNEW | EFCR)) == NULL)
- return (ABORT);
- else if (bufp[0] == '\0')
- return (FALSE);
- return (excline(exbuf));
-}
-
-/*
- * evalbuffer - evaluate the current buffer as line commands. Useful for
- * testing startup files.
- */
-/* ARGSUSED */
-int
-evalbuffer(int f, int n)
-{
- struct line *lp;
- struct buffer *bp = curbp;
- int s;
- static char excbuf[128];
-
- for (lp = bfirstlp(bp); lp != bp->b_headp; lp = lforw(lp)) {
- if (llength(lp) >= 128)
- return (FALSE);
- (void)strncpy(excbuf, ltext(lp), llength(lp));
-
- /* make sure it's terminated */
- excbuf[llength(lp)] = '\0';
- if ((s = excline(excbuf)) != TRUE)
- return (s);
- }
- return (TRUE);
-}
-
-/*
- * evalfile - go get a file and evaluate it as line commands. You can
- * go get your own startup file if need be.
- */
-/* ARGSUSED */
-int
-evalfile(int f, int n)
-{
- char fname[NFILEN], *bufp;
-
- if ((bufp = eread("Load file: ", fname, NFILEN,
- EFNEW | EFCR)) == NULL)
- return (ABORT);
- else if (bufp[0] == '\0')
- return (FALSE);
- return (load(fname));
-}
-
-/*
- * load - go load the file name we got passed.
- */
-int
-load(const char *fname)
-{
- int s = TRUE, line;
- int nbytes = 0;
- char excbuf[128];
- FILE *ffp;
-
- if ((fname = adjustname(fname, TRUE)) == NULL)
- /* just to be careful */
- return (FALSE);
-
- if (ffropen(&ffp, fname, NULL) != FIOSUC)
- return (FALSE);
-
- line = 0;
- while ((s = ffgetline(ffp, excbuf, sizeof(excbuf) - 1, &nbytes))
- == FIOSUC) {
- line++;
- excbuf[nbytes] = '\0';
- if (excline(excbuf) != TRUE) {
- s = FIOERR;
- ewprintf("Error loading file %s at line %d", fname, line);
- break;
- }
- }
- (void)ffclose(ffp, NULL);
- excbuf[nbytes] = '\0';
- if (s != FIOEOF || (nbytes && excline(excbuf) != TRUE))
- return (FALSE);
- return (TRUE);
-}
-
-/*
- * excline - run a line from a load file or eval-expression. If FKEYS is
- * defined, duplicate functionality of dobind so function key values don't
- * have to fit in type char.
- */
-int
-excline(char *line)
-{
- PF fp;
- struct line *lp, *np;
- int status, c, f, n;
- char *funcp, *tmp;
- char *argp = NULL;
- long nl;
-#ifdef FKEYS
- int bind;
- KEYMAP *curmap;
-#define BINDARG 0 /* this arg is key to bind (local/global set key) */
-#define BINDNO 1 /* not binding or non-quoted BINDARG */
-#define BINDNEXT 2 /* next arg " (define-key) */
-#define BINDDO 3 /* already found key to bind */
-#define BINDEXT 1 /* space for trailing \0 */
-#else /* FKEYS */
-#define BINDEXT 0
-#endif /* FKEYS */
-
- lp = NULL;
-
- if (macrodef || inmacro) {
- ewprintf("Not now!");
- return (FALSE);
- }
- f = 0;
- n = 1;
- funcp = skipwhite(line);
- if (*funcp == '\0')
- return (TRUE); /* No error on blank lines */
- line = parsetoken(funcp);
- if (*line != '\0') {
- *line++ = '\0';
- line = skipwhite(line);
- if (ISDIGIT(*line) || *line == '-') {
- argp = line;
- line = parsetoken(line);
- }
- }
- if (argp != NULL) {
- f = FFARG;
- nl = strtol(argp, &tmp, 10);
- if (*tmp != '\0')
- return (FALSE);
- if (nl >= INT_MAX || nl <= INT_MIN)
- return (FALSE);
- n = (int)nl;
- }
- if ((fp = name_function(funcp)) == NULL) {
- ewprintf("Unknown function: %s", funcp);
- return (FALSE);
- }
-#ifdef FKEYS
- if (fp == bindtokey || fp == unbindtokey) {
- bind = BINDARG;
- curmap = fundamental_map;
- } else if (fp == localbind || fp == localunbind) {
- bind = BINDARG;
- curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
- } else if (fp == redefine_key)
- bind = BINDNEXT;
- else
- bind = BINDNO;
-#endif /* FKEYS */
- /* Pack away all the args now... */
- if ((np = lalloc(0)) == FALSE)
- return (FALSE);
- np->l_fp = np->l_bp = maclcur = np;
- while (*line != '\0') {
- argp = skipwhite(line);
- if (*argp == '\0')
- break;
- line = parsetoken(argp);
- if (*argp != '"') {
- if (*argp == '\'')
- ++argp;
- if ((lp = lalloc((int) (line - argp) + BINDEXT)) ==
- NULL) {
- status = FALSE;
- goto cleanup;
- }
- bcopy(argp, ltext(lp), (int)(line - argp));
-#ifdef FKEYS
- /* don't count BINDEXT */
- lp->l_used--;
- if (bind == BINDARG)
- bind = BINDNO;
-#endif /* FKEYS */
- } else {
- /* quoted strings are special */
- ++argp;
-#ifdef FKEYS
- if (bind != BINDARG) {
-#endif /* FKEYS */
- lp = lalloc((int)(line - argp) + BINDEXT);
- if (lp == NULL) {
- status = FALSE;
- goto cleanup;
- }
- lp->l_used = 0;
-#ifdef FKEYS
- } else
- key.k_count = 0;
-#endif /* FKEYS */
- while (*argp != '"' && *argp != '\0') {
- if (*argp != '\\')
- c = *argp++;
- else {
- switch (*++argp) {
- case 't':
- case 'T':
- c = CCHR('I');
- break;
- case 'n':
- case 'N':
- c = CCHR('J');
- break;
- case 'r':
- case 'R':
- c = CCHR('M');
- break;
- case 'e':
- case 'E':
- c = CCHR('[');
- break;
- case '^':
- /*
- * split into two statements
- * due to bug in OSK cpp
- */
- c = CHARMASK(*++argp);
- c = ISLOWER(c) ?
- CCHR(TOUPPER(c)) : CCHR(c);
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- c = *argp - '0';
- if (argp[1] <= '7' &&
- argp[1] >= '0') {
- c <<= 3;
- c += *++argp - '0';
- if (argp[1] <= '7' &&
- argp[1] >= '0') {
- c <<= 3;
- c += *++argp
- - '0';
- }
- }
- break;
-#ifdef FKEYS
- case 'f':
- case 'F':
- c = *++argp - '0';
- if (ISDIGIT(argp[1])) {
- c *= 10;
- c += *++argp - '0';
- }
- c += KFIRST;
- break;
-#endif /* FKEYS */
- default:
- c = CHARMASK(*argp);
- break;
- }
- argp++;
- }
-#ifdef FKEYS
- if (bind == BINDARG)
- key.k_chars[key.k_count++] = c;
- else
-#endif /* FKEYS */
- lp->l_text[lp->l_used++] = c;
- }
- if (*line)
- line++;
- }
-#ifdef FKEYS
- switch (bind) {
- case BINDARG:
- bind = BINDDO;
- break;
- case BINDNEXT:
- lp->l_text[lp->l_used] = '\0';
- if ((curmap = name_map(lp->l_text)) == NULL) {
- ewprintf("No such mode: %s", lp->l_text);
- status = FALSE;
- free(lp);
- goto cleanup;
- }
- free(lp);
- bind = BINDARG;
- break;
- default:
-#endif /* FKEYS */
- lp->l_fp = np->l_fp;
- lp->l_bp = np;
- np->l_fp = lp;
- np = lp;
-#ifdef FKEYS
- }
-#endif /* FKEYS */
- }
-#ifdef FKEYS
- switch (bind) {
- default:
- ewprintf("Bad args to set key");
- status = FALSE;
- break;
- case BINDDO:
- if (fp != unbindtokey && fp != localunbind) {
- lp->l_text[lp->l_used] = '\0';
- status = bindkey(&curmap, lp->l_text, key.k_chars,
- key.k_count);
- } else
- status = bindkey(&curmap, NULL, key.k_chars,
- key.k_count);
- break;
- case BINDNO:
-#endif /* FKEYS */
- inmacro = TRUE;
- maclcur = maclcur->l_fp;
- status = (*fp)(f, n);
- inmacro = FALSE;
-#ifdef FKEYS
- }
-#endif /* FKEYS */
-cleanup:
- lp = maclcur->l_fp;
- while (lp != maclcur) {
- np = lp->l_fp;
- free(lp);
- lp = np;
- }
- free(lp);
- return (status);
-}
-
-/*
- * a pair of utility functions for the above
- */
-static char *
-skipwhite(char *s)
-{
- while (*s == ' ' || *s == '\t' || *s == ')' || *s == '(')
- s++;
- if (*s == ';')
- *s = '\0';
- return (s);
-}
-
-static char *
-parsetoken(char *s)
-{
- if (*s != '"') {
- while (*s && *s != ' ' && *s != '\t' && *s != ')' && *s != '(')
- s++;
- if (*s == ';')
- *s = '\0';
- } else
- do {
- /*
- * Strings get special treatment.
- * Beware: You can \ out the end of the string!
- */
- if (*s == '\\')
- ++s;
- } while (*++s != '"' && *s != '\0');
- return (s);
-}