From dcfe6758a687c3e319b9f3827fd34466842f7e7d Mon Sep 17 00:00:00 2001 From: Leland Lucius Date: Sun, 15 Dec 2019 22:57:40 -0600 Subject: [PATCH] Reapply e6d069787bb0c010c7afb55841754fb85dd123e0 and a1dc8305f0a369b97b6a9f44d4e97197f1983872 Author: Paul Licameli Date: Thu Feb 22 01:02:15 2018 -0500 Fix mistake in commit a1dc830 and add a comment Author: Paul Licameli Date: Wed Feb 21 15:46:18 2018 -0500 A function to extend XLisp's table of function bindings dynamically --- lib-src/libnyquist/nyquist/xlisp/xlftab.c | 30 ++++++++++++++++++++-- lib-src/libnyquist/nyquist/xlisp/xlimage.c | 2 +- lib-src/libnyquist/nyquist/xlisp/xlinit.c | 2 +- lib-src/libnyquist/nyquist/xlisp/xlisp.h | 7 +++++ lib-src/libnyquist/nyquist/xlisp/xlobj.c | 2 +- lib-src/libnyquist/nyquist/xlisp/xlprin.c | 2 +- lib-src/libnyquist/nyquist/xlisp/xlread.c | 2 +- 7 files changed, 40 insertions(+), 7 deletions(-) diff --git a/lib-src/libnyquist/nyquist/xlisp/xlftab.c b/lib-src/libnyquist/nyquist/xlisp/xlftab.c index 9c7a1e12e..211199001 100644 --- a/lib-src/libnyquist/nyquist/xlisp/xlftab.c +++ b/lib-src/libnyquist/nyquist/xlisp/xlftab.c @@ -12,6 +12,7 @@ HISTORY */ +#include /* for memcpy */ #include "switches.h" #include "xlisp.h" #ifndef NO_PROTOTYPES_IN_XLISP_H @@ -114,7 +115,7 @@ LVAL xstoprecordio(void); #endif /* the function table */ -FUNDEF funtab[] = { +FUNDEF init_funtab[] = { /* read macro functions */ { NULL, S, rmhash }, /* 0 */ @@ -499,7 +500,32 @@ FUNDEF funtab[] = { {0,0,0} /* end of table marker */ -}; +}; + +FUNDEF *funtab = init_funtab; +static size_t szfuntab = sizeof(init_funtab) / sizeof(*init_funtab); + +int xlbindfunctions(FUNDEF *functions, size_t nfunctions) +{ + /* This is written very generally, imposing no fixed upper limit on the + growth of the table. But perhaps a lightweight alternative with such a + limit could be conditionally compiled. + */ + + /* malloc, not realloc, to leave old table unchanged in case of failure */ + FUNDEF *newfuntab = malloc((szfuntab + nfunctions) * sizeof(FUNDEF)); + if (!newfuntab) + return FALSE; + memcpy(newfuntab, funtab, (szfuntab - 1) * sizeof(FUNDEF)); + memcpy(newfuntab + szfuntab - 1, functions, nfunctions * sizeof(FUNDEF)); + FUNDEF sentinel = { 0, 0, 0 }; + newfuntab[szfuntab + nfunctions - 1] = sentinel; + funtab = newfuntab; + szfuntab += nfunctions; + return TRUE; + + /* To do: deallocate funtab when XLisp runtime shuts down */ +} /* xnotimp does not return anything on purpose, so disable * "no return value" warning diff --git a/lib-src/libnyquist/nyquist/xlisp/xlimage.c b/lib-src/libnyquist/nyquist/xlisp/xlimage.c index a4e793323..e4ec77027 100644 --- a/lib-src/libnyquist/nyquist/xlisp/xlimage.c +++ b/lib-src/libnyquist/nyquist/xlisp/xlimage.c @@ -182,7 +182,7 @@ int xlisave(const char *fname) /* xlirestore - restore a saved memory image */ int xlirestore(const char *fname) { - extern FUNDEF funtab[]; + extern FUNDEF *funtab; char fullname[STRMAX+1]; unsigned char *cp; int n,i,max,type; diff --git a/lib-src/libnyquist/nyquist/xlisp/xlinit.c b/lib-src/libnyquist/nyquist/xlisp/xlinit.c index eea279989..889f6ef78 100644 --- a/lib-src/libnyquist/nyquist/xlisp/xlinit.c +++ b/lib-src/libnyquist/nyquist/xlisp/xlinit.c @@ -41,7 +41,7 @@ extern LVAL a_fixnum,a_flonum,a_string,a_stream,a_object; extern LVAL a_vector,a_closure,a_char,a_ustream,a_extern; extern LVAL s_gcflag,s_gchook; extern LVAL s_search_path; -extern FUNDEF funtab[]; +extern FUNDEF *funtab; /* forward declarations */ FORWARD LOCAL void initwks(); diff --git a/lib-src/libnyquist/nyquist/xlisp/xlisp.h b/lib-src/libnyquist/nyquist/xlisp/xlisp.h index d83deb7d7..da9f80357 100644 --- a/lib-src/libnyquist/nyquist/xlisp/xlisp.h +++ b/lib-src/libnyquist/nyquist/xlisp/xlisp.h @@ -672,6 +672,13 @@ void xlinit(void); void xlsymbols(void); +/* xlftab.c */ +/* returns true on success, + false if table limits would be exceeded and the table remains unchanged + Call this, any number of times, before calling xlisp_main_init + */ +int xlbindfunctions(FUNDEF *functions, size_t nfunctions); + /* xlio.c */ int xlgetc(LVAL fptr); diff --git a/lib-src/libnyquist/nyquist/xlisp/xlobj.c b/lib-src/libnyquist/nyquist/xlisp/xlobj.c index e5164107f..6713849f3 100644 --- a/lib-src/libnyquist/nyquist/xlisp/xlobj.c +++ b/lib-src/libnyquist/nyquist/xlisp/xlobj.c @@ -88,7 +88,7 @@ void xladdivar(LVAL cls, const char *var) /* xladdmsg - add a message to a class */ void xladdmsg(LVAL cls, const char *msg, int offset) { - extern FUNDEF funtab[]; + extern FUNDEF *funtab; LVAL mptr; /* enter the message selector */ diff --git a/lib-src/libnyquist/nyquist/xlisp/xlprin.c b/lib-src/libnyquist/nyquist/xlisp/xlprin.c index 181d09164..0c69dd1d3 100644 --- a/lib-src/libnyquist/nyquist/xlisp/xlprin.c +++ b/lib-src/libnyquist/nyquist/xlisp/xlprin.c @@ -21,7 +21,7 @@ /* external variables */ extern LVAL s_printcase,k_downcase,k_const,k_nmacro; extern LVAL s_ifmt,s_ffmt; -extern FUNDEF funtab[]; +extern FUNDEF *funtab; extern char buf[]; LOCAL void putsymbol(LVAL fptr, char *str, int escflag); diff --git a/lib-src/libnyquist/nyquist/xlisp/xlread.c b/lib-src/libnyquist/nyquist/xlisp/xlread.c index 6ee519504..03ac55806 100644 --- a/lib-src/libnyquist/nyquist/xlisp/xlread.c +++ b/lib-src/libnyquist/nyquist/xlisp/xlread.c @@ -925,7 +925,7 @@ int xlisnumber(char *str, LVAL *pval) /* defmacro - define a read macro */ void defmacro(int ch, LVAL type, int offset) { - extern FUNDEF funtab[]; + extern FUNDEF *funtab; LVAL subr; subr = cvsubr(funtab[offset].fd_subr,funtab[offset].fd_type,offset); setelement(getvalue(s_rtable),ch,cons(type,subr));