Cache the result of function to name mapping lookup when doing keycode to function mapping lookup.

This commit is contained in:
Renaud 2021-07-20 17:34:35 +08:00
parent 4f90e847f8
commit c093b7064b
9 changed files with 254 additions and 259 deletions

168
bind.c
View File

@ -10,6 +10,7 @@
* Modified by Petri Kutvonen
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -36,7 +37,7 @@ static int buildlist( char *mstring) ;
static void cmdstr( int c, char *seq) ;
static unsigned int getckey( int mflag) ;
static unsigned int stock( char *keyname) ;
static int unbindchar( unsigned c) ;
static boolean unbindchar( unsigned c) ;
static const char *getfname( unsigned keycode, char *failmsg) ;
@ -105,47 +106,39 @@ int deskey( int f, int n) {
*
* int f, n; command arguments [IGNORED]
*/
int bindtokey(int f, int n)
{
unsigned int c; /* command key to bind */
fnp_t kfunc; /* ptr to the requested function to bind to */
struct key_tab *ktp; /* pointer into the command table */
int found; /* matched command flag */
char outseq[80]; /* output buffer for keystroke sequence */
int bindtokey(int f, int n) {
key_tab *ktp ; /* pointer into the command table */
char outseq[ 80] ; /* output buffer for keystroke sequence */
/* prompt the user to type in a key to bind */
/* prompt the user to type in a key to bind */
mlwrite(": bind-to-key ");
/* get the function name to bind it to */
kfunc = getname()->n_func ;
if (kfunc == NULL) {
mlwrite("(No such function)");
return FALSE;
/* get the function name to bind it to */
fnp_t kfunc = getname()->n_func ;
if( kfunc == NULL) {
mlwrite( "(No such function)") ;
return FALSE ;
}
ostring(" ");
/* get the command sequence to bind */
c = getckey((kfunc == metafn) || (kfunc == cex) ||
(kfunc == unarg) || (kfunc == ctrlg));
ostring( " ") ;
/* change it to something we can print as well */
cmdstr(c, &outseq[0]);
/* get the command sequence to bind */
boolean prefix_f = (kfunc == metafn) || (kfunc == cex) ||
(kfunc == unarg) || (kfunc == ctrlg) ;
unsigned c = getckey( prefix_f) ;
/* and dump it out */
ostring(outseq);
/* change it to something we can print as well */
cmdstr( c, outseq) ;
/* if the function is a prefix key */
if (kfunc == metafn || kfunc == cex ||
kfunc == unarg || kfunc == ctrlg) {
/* and dump it out */
ostring( outseq) ;
/* search for an existing binding for the prefix key */
ktp = &keytab[0];
found = FALSE;
while (ktp->k_fp != NULL) {
if (ktp->k_fp == kfunc)
unbindchar(ktp->k_code);
++ktp;
}
/* if the function is a prefix key */
if( prefix_f) {
/* search for an existing binding for the prefix key */
for( ktp = keytab ; ktp->k_fp != NULL ; ktp++)
if( ktp->k_fp == kfunc)
unbindchar( ktp->k_code) ;
/* reset the appropriate global prefix variable */
if (kfunc == metafn)
@ -158,32 +151,31 @@ int bindtokey(int f, int n)
abortc = c;
}
/* search the table to see if it exists */
ktp = &keytab[0];
found = FALSE;
while (ktp->k_fp != NULL) {
if (ktp->k_code == c) {
found = TRUE;
break;
/* search the table to see if it exists */
for( ktp = keytab ; ktp->k_fp != NULL ; ktp++) {
if( ktp->k_code == c) {
/* it exists, just change it then */
ktp->k_fp = kfunc ;
ktp->k_nbp = NULL ;
return TRUE ;
}
++ktp;
}
if (found) { /* it exists, just change it then */
ktp->k_fp = kfunc;
} else { /* otherwise we need to add it to the end */
/* if we run out of binding room, bitch */
if (ktp >= &keytab[NBINDS]) {
mlwrite("Binding table FULL!");
return FALSE;
}
ktp->k_code = c; /* add keycode */
ktp->k_fp = kfunc; /* and the function pointer */
++ktp; /* and make sure the next is null */
ktp->k_code = 0;
ktp->k_fp = NULL;
/* otherwise we need to add it to the end */
/* if we run out of binding room, bitch */
if( ktp >= &keytab[ NBINDS]) {
mlwrite( "Binding table FULL!") ;
return FALSE ;
}
ktp->k_code = c; /* add keycode */
ktp->k_fp = kfunc; /* and the function pointer */
ktp->k_nbp = NULL ;
++ktp; /* and make sure the next is null */
ktp->k_code = 0;
ktp->k_fp = NULL;
ktp->k_nbp = NULL ;
return TRUE;
}
@ -224,40 +216,31 @@ int unbindkey(int f, int n)
*
* int c; command key to unbind
*/
static int unbindchar( unsigned c) {
struct key_tab *ktp; /* pointer into the command table */
struct key_tab *sktp; /* saved pointer into the command table */
int found; /* matched command flag */
static boolean unbindchar( unsigned c) {
key_tab *ktp ; /* pointer into the command table */
/* search the table to see if the key exists */
ktp = &keytab[0];
found = FALSE;
while (ktp->k_fp != NULL) {
/* search the table to see if the key exists */
for( ktp = keytab ; ktp->k_fp != NULL ; ktp++) {
if (ktp->k_code == c) {
found = TRUE;
break;
/* save the pointer and scan to the end of the table */
key_tab *sktp = ktp ;
while( (++ktp)->k_fp != NULL) ;
ktp -= 1 ; /* backup to the last legit entry */
/* copy the last entry to the current one */
sktp->k_code = ktp->k_code ;
sktp->k_fp = ktp->k_fp ;
sktp->k_nbp = ktp->k_nbp ;
/* null out the last one */
ktp->k_code = 0 ;
ktp->k_fp = NULL ;
ktp->k_nbp = NULL ;
return TRUE ;
}
++ktp;
}
/* if it isn't bound, bitch */
if (!found)
return FALSE;
/* save the pointer and scan to the end of the table */
sktp = ktp;
while (ktp->k_fp != NULL)
++ktp;
--ktp; /* backup to the last legit entry */
/* copy the last entry to the current one */
sktp->k_code = ktp->k_code;
sktp->k_fp = ktp->k_fp;
/* null out the last one */
ktp->k_code = 0;
ktp->k_fp = NULL;
return TRUE;
return FALSE ;
}
#if APROP
@ -505,24 +488,29 @@ static void cmdstr( int c, char *seq) {
*
* int c; key to find what is bound to it
*/
fnp_t getbind( unsigned c) {
key_tab *getkeybind( unsigned c) {
struct key_tab *ktp ;
for( ktp = keytab ; ktp->k_fp != NULL ; ktp++)
if (ktp->k_code == c)
return ktp->k_fp ;
break ;
/* no such binding */
return NULL ;
return ktp ;
}
static const char *getfname( unsigned keycode, char *failmsg) {
/* takes a key code and gets the name of the function bound to it */
fnp_t func = getbind( keycode) ;
key_tab *kbp = getkeybind( keycode) ;
fnp_t func = kbp->k_fp ;
if( func == NULL)
return failmsg ;
const char *found = getfncname( func) ;
if( kbp->k_nbp == NULL)
kbp->k_nbp = getfncnb( func) ;
assert( func == kbp->k_nbp->n_func) ;
const char *found = bind_name( kbp->k_nbp) ;
assert( *found) ;
return *found ? found : failmsg ;
}

10
bind.h
View File

@ -1,7 +1,7 @@
#ifndef _BIND_H_
#define _BIND_H_
#include "fnp_t.h"
#include "ebind.h"
#define APROP 1 /* Add code for Apropos command */
@ -9,13 +9,17 @@
int apro( int f, int n) ;
#endif
/* uEMACS functions */
int help( int f, int n) ;
int deskey( int f, int n) ;
int bindtokey( int f, int n) ;
int unbindkey( int f, int n) ;
int desbind( int f, int n) ;
int startup( const char *fname) ;
fnp_t getbind( unsigned keycode) ;
const char *transbind( char *skey) ;
/* find a key to function association in the key to function mapping table */
key_tab *getkeybind( unsigned keycode) ; /* by key code */
const char *transbind( char *skey) ; /* by string representation of key */
#endif

286
ebind.c
View File

@ -35,329 +35,329 @@
* control-X commands.
*/
key_tab keytab[ NBINDS] = {
{CONTROL | '?', backdel},
{CONTROL | 'A', (fnp_t) gotobol}
{CONTROL | '?', backdel, NULL},
{CONTROL | 'A', (fnp_t) gotobol, NULL}
,
{CONTROL | 'B', (fnp_t) backchar}
{CONTROL | 'B', (fnp_t) backchar, NULL}
,
{CONTROL | 'C', insspace}
{CONTROL | 'C', insspace, NULL}
,
{CONTROL | 'D', forwdel}
{CONTROL | 'D', forwdel, NULL}
,
{CONTROL | 'E', (fnp_t) gotoeol}
{CONTROL | 'E', (fnp_t) gotoeol, NULL}
,
{CONTROL | 'F', (fnp_t) forwchar}
{CONTROL | 'F', (fnp_t) forwchar, NULL}
,
{CONTROL | 'G', ctrlg}
{CONTROL | 'G', ctrlg, NULL}
,
{CONTROL | 'H', backdel}
{CONTROL | 'H', backdel, NULL}
,
{CONTROL | 'I', insert_tab}
{CONTROL | 'I', insert_tab, NULL}
,
{CONTROL | 'J', indent}
{CONTROL | 'J', indent, NULL}
,
{CONTROL | 'K', killtext}
{CONTROL | 'K', killtext, NULL}
,
{CONTROL | 'L', redraw}
{CONTROL | 'L', redraw, NULL}
,
{CONTROL | 'M', insert_newline}
{CONTROL | 'M', insert_newline, NULL}
,
{CONTROL | 'N', (fnp_t) forwline}
{CONTROL | 'N', (fnp_t) forwline, NULL}
,
{CONTROL | 'O', openline}
{CONTROL | 'O', openline, NULL}
,
{CONTROL | 'P', (fnp_t) backline}
{CONTROL | 'P', (fnp_t) backline, NULL}
,
{CONTROL | 'Q', quote}
{CONTROL | 'Q', quote, NULL}
,
{CONTROL | 'R', backsearch}
{CONTROL | 'R', backsearch, NULL}
,
{CONTROL | 'S', forwsearch}
{CONTROL | 'S', forwsearch, NULL}
,
{CONTROL | 'T', (fnp_t) twiddle}
{CONTROL | 'T', (fnp_t) twiddle, NULL}
,
{CONTROL | 'U', unarg}
{CONTROL | 'U', unarg, NULL}
,
{CONTROL | 'V', (fnp_t) forwpage}
{CONTROL | 'V', (fnp_t) forwpage, NULL}
,
{CONTROL | 'W', killregion}
{CONTROL | 'W', killregion, NULL}
,
{CONTROL | 'X', cex}
{CONTROL | 'X', cex, NULL}
,
{CONTROL | 'Y', yank}
{CONTROL | 'Y', yank, NULL}
,
{CONTROL | 'Z', (fnp_t) backpage}
{CONTROL | 'Z', (fnp_t) backpage, NULL}
,
{CONTROL | ']', metafn}
{CONTROL | ']', metafn, NULL}
,
{CTLX | CONTROL | 'B', listbuffers}
{CTLX | CONTROL | 'B', listbuffers, NULL}
,
{CTLX | CONTROL | 'C', quit}
{CTLX | CONTROL | 'C', quit, NULL}
, /* Hard quit. */
#if PKCODE & AEDIT
{CTLX | CONTROL | 'A', detab}
{CTLX | CONTROL | 'A', detab, NULL}
,
#endif
#if PKCODE
{CTLX | CONTROL | 'D', filesave}
{CTLX | CONTROL | 'D', filesave, NULL}
, /* alternative */
#else
#if AEDIT
{CTLX | CONTROL | 'D', detab}
{CTLX | CONTROL | 'D', detab, NULL}
,
#endif
#endif
#if AEDIT
{CTLX | CONTROL | 'E', entab}
{CTLX | CONTROL | 'E', entab, NULL}
,
#endif
{CTLX | CONTROL | 'F', filefind}
{CTLX | CONTROL | 'F', filefind, NULL}
,
{CTLX | CONTROL | 'I', insfile}
{CTLX | CONTROL | 'I', insfile, NULL}
,
{CTLX | CONTROL | 'L', lowerregion}
{CTLX | CONTROL | 'L', lowerregion, NULL}
,
{CTLX | CONTROL | 'M', delmode}
{CTLX | CONTROL | 'M', delmode, NULL}
,
{CTLX | CONTROL | 'N', mvdnwind}
{CTLX | CONTROL | 'N', mvdnwind, NULL}
,
{CTLX | CONTROL | 'O', deblank}
{CTLX | CONTROL | 'O', deblank, NULL}
,
{CTLX | CONTROL | 'P', mvupwind}
{CTLX | CONTROL | 'P', mvupwind, NULL}
,
{CTLX | CONTROL | 'R', fileread}
{CTLX | CONTROL | 'R', fileread, NULL}
,
{CTLX | CONTROL | 'S', filesave}
{CTLX | CONTROL | 'S', filesave, NULL}
,
#if AEDIT
{CTLX | CONTROL | 'T', trim}
{CTLX | CONTROL | 'T', trim, NULL}
,
#endif
{CTLX | CONTROL | 'U', upperregion}
{CTLX | CONTROL | 'U', upperregion, NULL}
,
{CTLX | CONTROL | 'V', viewfile}
{CTLX | CONTROL | 'V', viewfile, NULL}
,
{CTLX | CONTROL | 'W', filewrite}
{CTLX | CONTROL | 'W', filewrite, NULL}
,
{CTLX | CONTROL | 'X', (fnp_t) swapmark}
{CTLX | CONTROL | 'X', (fnp_t) swapmark, NULL}
,
{CTLX | CONTROL | 'Z', shrinkwind}
{CTLX | CONTROL | 'Z', shrinkwind, NULL}
,
{CTLX | '?', deskey}
{CTLX | '?', deskey, NULL}
,
{CTLX | '!', spawn}
{CTLX | '!', spawn, NULL}
,
{CTLX | '@', pipecmd}
{CTLX | '@', pipecmd, NULL}
,
{CTLX | '#', filter_buffer}
{CTLX | '#', filter_buffer, NULL}
,
{CTLX | '$', execprg}
{CTLX | '$', execprg, NULL}
,
{CTLX | '=', showcpos}
{CTLX | '=', showcpos, NULL}
,
{CTLX | '(', ctlxlp}
{CTLX | '(', ctlxlp, NULL}
,
{CTLX | ')', ctlxrp}
{CTLX | ')', ctlxrp, NULL}
,
{CTLX | '^', enlargewind}
{CTLX | '^', enlargewind, NULL}
,
{CTLX | '0', delwind}
{CTLX | '0', delwind, NULL}
,
{CTLX | '1', onlywind}
{CTLX | '1', onlywind, NULL}
,
{CTLX | '2', splitwind}
{CTLX | '2', splitwind, NULL}
,
{CTLX | 'A', setvar}
{CTLX | 'A', setvar, NULL}
,
{CTLX | 'B', usebuffer}
{CTLX | 'B', usebuffer, NULL}
,
{CTLX | 'C', spawncli}
{CTLX | 'C', spawncli, NULL}
,
#if BSD | SVR4
{CTLX | 'D', bktoshell}
{CTLX | 'D', bktoshell, NULL}
,
#endif
{CTLX | 'E', ctlxe}
{CTLX | 'E', ctlxe, NULL}
,
{CTLX | 'F', setfillcol}
{CTLX | 'F', setfillcol, NULL}
,
{CTLX | 'K', killbuffer}
{CTLX | 'K', killbuffer, NULL}
,
{CTLX | 'M', setemode}
{CTLX | 'M', setemode, NULL}
,
{CTLX | 'N', filename}
{CTLX | 'N', filename, NULL}
,
{CTLX | 'O', nextwind}
{CTLX | 'O', nextwind, NULL}
,
{CTLX | 'P', prevwind}
{CTLX | 'P', prevwind, NULL}
,
#if PKCODE
{CTLX | 'Q', quote}
{CTLX | 'Q', quote, NULL}
, /* alternative */
#endif
#if ISRCH
{CTLX | 'R', risearch}
{CTLX | 'R', risearch, NULL}
,
{CTLX | 'S', fisearch}
{CTLX | 'S', fisearch, NULL}
,
#endif
{CTLX | 'W', resize}
{CTLX | 'W', resize, NULL}
,
{CTLX | 'X', nextbuffer}
{CTLX | 'X', nextbuffer, NULL}
,
{CTLX | 'Z', enlargewind}
{CTLX | 'Z', enlargewind, NULL}
,
{META | CONTROL | '?', delbword},
{META | CONTROL | '?', delbword, NULL},
#if WORDPRO
{META | CONTROL | 'C', wordcount}
{META | CONTROL | 'C', wordcount, NULL}
,
#endif
#if PKCODE
{META | CONTROL | 'D', newsize}
{META | CONTROL | 'D', newsize, NULL}
,
#endif
#if PROC
{META | CONTROL | 'E', execproc}
{META | CONTROL | 'E', execproc, NULL}
,
#endif
#if CFENCE
{META | CONTROL | 'F', getfence}
{META | CONTROL | 'F', getfence, NULL}
,
#endif
{META | CONTROL | 'H', delbword}
{META | CONTROL | 'H', delbword, NULL}
,
{META | CONTROL | 'K', unbindkey}
{META | CONTROL | 'K', unbindkey, NULL}
,
{META | CONTROL | 'L', reposition}
{META | CONTROL | 'L', reposition, NULL}
,
{META | CONTROL | 'M', delgmode}
{META | CONTROL | 'M', delgmode, NULL}
,
{META | CONTROL | 'N', namebuffer}
{META | CONTROL | 'N', namebuffer, NULL}
,
{META | CONTROL | 'R', qreplace}
{META | CONTROL | 'R', qreplace, NULL}
,
{META | CONTROL | 'S', newsize}
{META | CONTROL | 'S', newsize, NULL}
,
{META | CONTROL | 'T', newwidth}
{META | CONTROL | 'T', newwidth, NULL}
,
{META | CONTROL | 'V', scrnextdw}
{META | CONTROL | 'V', scrnextdw, NULL}
,
#if WORDPRO
{META | CONTROL | 'W', killpara}
{META | CONTROL | 'W', killpara, NULL}
,
#endif
{META | CONTROL | 'Z', scrnextup}
{META | CONTROL | 'Z', scrnextup, NULL}
,
{META | ' ', (fnp_t) setmark}
{META | ' ', (fnp_t) setmark, NULL}
,
{META | '?', help}
{META | '?', help, NULL}
,
{META | '!', reposition}
{META | '!', reposition, NULL}
,
{META | '.', (fnp_t) setmark}
{META | '.', (fnp_t) setmark, NULL}
,
{META | '>', (fnp_t) gotoeob}
{META | '>', (fnp_t) gotoeob, NULL}
,
{META | '<', (fnp_t) gotobob}
{META | '<', (fnp_t) gotobob, NULL}
,
{META | '~', unmark}
{META | '~', unmark, NULL}
,
#if APROP
{META | 'A', apro}
{META | 'A', apro, NULL}
,
#endif
{META | 'B', backword}
{META | 'B', backword, NULL}
,
{META | 'C', capword}
{META | 'C', capword, NULL}
,
{META | 'D', delfword}
{META | 'D', delfword, NULL}
,
{META | 'F', forwword}
{META | 'F', forwword, NULL}
,
{META | 'G', gotoline}
{META | 'G', gotoline, NULL}
,
#if PKCODE
#if WORDPRO
{META | 'J', justpara}
{META | 'J', justpara, NULL}
,
#endif
#endif
{META | 'K', bindtokey}
{META | 'K', bindtokey, NULL}
,
{META | 'L', lowerword}
{META | 'L', lowerword, NULL}
,
{META | 'M', setgmode}
{META | 'M', setgmode, NULL}
,
#if WORDPRO
{META | 'N', gotoeop}
{META | 'N', gotoeop, NULL}
,
{META | 'P', gotobop}
{META | 'P', gotobop, NULL}
,
{META | 'Q', fillpara}
{META | 'Q', fillpara, NULL}
,
#endif
{META | 'R', sreplace}
{META | 'R', sreplace, NULL}
,
#if PKCODE
{META | 'S', forwhunt}
{META | 'S', forwhunt, NULL}
,
#else
#if BSD
{META | 'S', bktoshell}
{META | 'S', bktoshell, NULL}
,
#endif
#endif
{META | 'U', upperword}
{META | 'U', upperword, NULL}
,
{META | 'V', (fnp_t) backpage}
{META | 'V', (fnp_t) backpage, NULL}
,
{META | 'W', copyregion}
{META | 'W', copyregion, NULL}
,
{META | 'X', namedcmd}
{META | 'X', namedcmd, NULL}
,
{META | 'Z', quickexit}
{META | 'Z', quickexit, NULL}
,
#if VT220
{SPEC | '1', (fnp_t) gotobob /* fisearch */}
{SPEC | '1', (fnp_t) gotobob /* fisearch */, NULL}
, /* VT220 keys */
{SPEC | '2', yank}
{SPEC | '2', yank, NULL}
,
{SPEC | '3', forwdel /* killregion */}
{SPEC | '3', forwdel /* killregion */, NULL}
,
{SPEC | '4', (fnp_t) gotoeob /* setmark */}
{SPEC | '4', (fnp_t) gotoeob /* setmark */, NULL}
,
{SPEC | '5', (fnp_t) backpage}
{SPEC | '5', (fnp_t) backpage, NULL}
,
{SPEC | '6', (fnp_t) forwpage}
{SPEC | '6', (fnp_t) forwpage, NULL}
,
{SPEC | 'A', (fnp_t) backline}
{SPEC | 'A', (fnp_t) backline, NULL}
,
{SPEC | 'B', (fnp_t) forwline}
{SPEC | 'B', (fnp_t) forwline, NULL}
,
{SPEC | 'C', (fnp_t) forwchar}
{SPEC | 'C', (fnp_t) forwchar, NULL}
,
{SPEC | 'D', (fnp_t) backchar}
{SPEC | 'D', (fnp_t) backchar, NULL}
,
{SPEC | 'c', metafn}
{SPEC | 'c', metafn, NULL}
,
{SPEC | 'd', (fnp_t) backchar}
{SPEC | 'd', (fnp_t) backchar, NULL}
,
{SPEC | 'e', (fnp_t) forwline}
{SPEC | 'e', (fnp_t) forwline, NULL}
,
{SPEC | 'f', (fnp_t) gotobob}
{SPEC | 'f', (fnp_t) gotobob, NULL}
,
{SPEC | 'h', help}
{SPEC | 'h', help, NULL}
,
{SPEC | 'i', cex}
{SPEC | 'i', cex, NULL}
,
#endif
/* special internal bindings */
{ SPEC | META | 'W', wrapword }, /* called on word wrap */
{ SPEC | META | 'C', nullproc }, /* every command input */
{ SPEC | META | 'R', nullproc }, /* on file read */
{ SPEC | META | 'X', nullproc }, /* on window change P.K. */
{ SPEC | META | 'W', wrapword , NULL}, /* called on word wrap */
{ SPEC | META | 'C', nullproc , NULL}, /* every command input */
{ SPEC | META | 'R', nullproc , NULL}, /* on file read */
{ SPEC | META | 'X', nullproc , NULL}, /* on window change P.K. */
{0, NULL}
{0, NULL, NULL}
};

10
ebind.h
View File

@ -1,14 +1,16 @@
#ifndef _EBIND_H_
#define _EBIND_H_
#include "fnp_t.h"
#include "names.h"
/* Structure for the table of initial key bindings. */
/* Structure for the key bindings table. */
typedef struct key_tab {
unsigned k_code ; /* Key code */
fnp_t k_fp ; /* Routine to handle it */
unsigned k_code ; /* Key code */
fnp_t k_fp ; /* Routine to handle it */
const name_bind *k_nbp ; /* entry in name to function map table */
} key_tab ;
/* keycode to function mapping table */
#define NBINDS 256 /* max # of bound keys */
extern key_tab keytab[ NBINDS] ; /* key bind to functions table */

View File

@ -3,6 +3,7 @@
#define CLRMSG 0 /* space clears the message line with no insert */
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
@ -212,11 +213,16 @@ int execute( int c, int f, int n) {
int status ;
/* if the keystroke is a bound function...do it */
fnp_t execfunc = getbind( c) ;
key_tab *ktp = getkeybind( c) ;
fnp_t execfunc = ktp->k_fp ;
if( execfunc != NULL) {
thisflag = 0 ;
const char *sp = getfncname( execfunc) ;
if( (sp[ -1] & 1) && (curbp->b_mode & MDVIEW))
if( ktp->k_nbp == NULL)
ktp->k_nbp = getfncnb( execfunc) ;
assert( ktp->k_nbp->n_func == execfunc) ;
char tag = bind_tag( ktp->k_nbp) ;
if( (tag & 1) && (curbp->b_mode & MDVIEW))
status = rdonly() ;
else
status = execfunc( f, n) ;
@ -337,7 +343,7 @@ void kbd_loop( void) {
fnp_t execfunc ;
if( c == newc
&& (execfunc = getbind( c)) != NULL
&& (execfunc = getkeybind( c)->k_fp) != NULL
&& execfunc != insert_newline
&& execfunc != insert_tab)
newc = getcmd() ;

View File

@ -1,7 +0,0 @@
#ifndef __FNP_T_H__
#define __FNP_T_H__
/* Generic uEMACS function pointer type */
typedef int (*fnp_t)( int, int) ;
#endif

View File

@ -175,7 +175,7 @@ const name_bind *fncmatch( char *fname) {
}
const char *getfncname( fnp_t func) {
const name_bind *getfncnb( fnp_t func) {
const name_bind *nptr ; /* pointer into the name binding table */
/* skim through the table, looking for a match */
@ -183,7 +183,7 @@ const char *getfncname( fnp_t func) {
if (nptr->n_func == func)
break ;
return bind_name( nptr) ;
return nptr ;
}
/*

View File

@ -3,10 +3,11 @@
#include "names.h"
typedef enum {
STOP, PLAY, RECORD
} kbdstate ;
extern kbdstate kbdmode ; /* current keyboard macro mode */
extern int lastkey ; /* last keystoke */
extern int kbdrep ; /* number of repetitions */
@ -28,9 +29,9 @@ int newmlargt( char **outbufref, const char *prompt, int size) ;
int ectoc( int c) ;
/* Look up in names to function association table */
const name_bind *fncmatch( char *) ;
const name_bind *getname( void) ;
const char *getfncname( fnp_t func) ;
const name_bind *fncmatch( char *name) ; /* by name */
const name_bind *getname( void) ; /* interactively */
const name_bind *getfncnb( fnp_t func) ; /* by function */
int tgetc( void) ;
int get1key( void) ;

View File

@ -1,7 +1,8 @@
#ifndef _NAMES_H_
#define _NAMES_H_
#include "fnp_t.h"
/* Generic uEMACS function pointer type */
typedef int (*fnp_t)( int, int) ;
/* Structure for the name binding table. */
typedef struct name_bind {
@ -12,6 +13,6 @@ typedef struct name_bind {
#define bind_name( p) (&(p)->n_name[ 1])
#define bind_tag( p) (p)->n_name[ 0]
extern const name_bind names[] ; /* name to function table */
extern const name_bind names[] ; /* name to function mapping table */
#endif