X-Git-Url: https://pd.if.org/git/?p=pd_readline;a=blobdiff_plain;f=mg%2Fextend.c;fp=mg%2Fextend.c;h=0000000000000000000000000000000000000000;hp=2f47de6b5fbd944aae198179bdfc7cd80d798b9f;hb=4bb27266f935c9aafad6870ffc8847fc65c8120f;hpb=3f771e17236364ded86e96ee64f99344337991f8 diff --git a/mg/extend.c b/mg/extend.c deleted file mode 100644 index 2f47de6..0000000 --- a/mg/extend.c +++ /dev/null @@ -1,963 +0,0 @@ -/* $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 -#include - -#include "macro.h" - -#ifdef FKEYS -#include "key.h" -#ifndef BINDKEY -#define BINDKEY /* bindkey is used by FKEYS startup code */ -#endif /* !BINDKEY */ -#endif /* FKEYS */ - -#include - -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); -}