change python config, add jupyter and ein

This commit is contained in:
2024-05-05 20:36:39 +02:00
parent b18d02d8d5
commit 8b80ceda39
168 changed files with 177127 additions and 46 deletions

322
lisp/zmq/src/emacs-zmq.c Normal file
View File

@@ -0,0 +1,322 @@
#include "emacs-zmq.h"
#include <assert.h>
#include <signal.h>
int plugin_is_GPL_compatible;
typedef struct {
char *name;
void *fun;
char const * doc;
ptrdiff_t minarity;
ptrdiff_t maxarity;
} ezmq_fun_t;
emacs_env *env = NULL;
emacs_value Qzmq_error, Qt, Qnil, Qnth, Qlist,
Qwrong_type_argument, Qargs_out_of_range,
Qcons, Qstring, Qvector, Qcar, Qcdr, Qlength, Qinteger, Qequal,
Qzmq_POLLIN, Qzmq_POLLPRI, Qzmq_POLLERR, Qzmq_POLLOUT,
Izmq_POLLIN, Izmq_POLLPRI, Izmq_POLLERR, Izmq_POLLOUT;
EZMQ_DOC(ezmq_cleanup_globrefs, "",
"Free global references flagged for release.\n"
"Internally, ZMQ keeps references to Emacs objects that are still in use.\n"
"Most notably, a `zmq-poller' object keeps track of all the sockets added to it\n"
"so that they do not get cleaned up by garbage collection if they go out of scope\n"
"while a poller is still using them.");
static emacs_value
ezmq_cleanup_globrefs()
{
emacs_value val;
while((val = ezmq_pop_globref())) {
FREE_GLOBREF(val);
}
return Qnil;
}
#define EZMQ_MAXARGS 5
static emacs_value _fargs[EZMQ_MAXARGS];
/**
Dispatch to the intended C function from a call to a ZMQ function in Emacs.
CURRENT_ENV is the current Emacs environment for the dispatch call. NARGS is
the number of arguments for this call whose values are contained in ARGS.
INFO is the ezmq_fun_t* which holds the function to dispatch to.
*/
static emacs_value
ezmq_dispatch(emacs_env *current_env, ptrdiff_t nargs, emacs_value args[], void *info)
{
// Set the global environment for this dispatch call.
env = current_env;
// Ensure the number of arguments are within range
emacs_value ret = Qnil;
if(nargs > EZMQ_MAXARGS) {
// Better error
ezmq_signal(Qargs_out_of_range, 2, INT(nargs), INT(EZMQ_MAXARGS));
return ret;
}
// Extract the function information
void *fun = ((ezmq_fun_t *)info)->fun;
ptrdiff_t maxargs = ((ezmq_fun_t *)info)->maxarity;
if(nargs < maxargs) {
// Fill in nil values for optional arguments
int i;
for(i = (maxargs - 1); i >= nargs; i--) {
_fargs[i] = Qnil;
}
for(i = 0; i < nargs; i++) {
_fargs[i] = args[i];
}
args = _fargs;
nargs = maxargs;
}
// Dispatch based on number of arguments
switch(nargs) {
case 0:
ret = ((emacs_value(*)(void))fun)();
break;
case 1:
ret = ((emacs_value(*)(emacs_value))fun)(args[0]);
break;
case 2:
ret = ((emacs_value(*)(emacs_value, emacs_value))fun)(args[0], args[1]);
break;
case 3:
ret = ((emacs_value(*)(emacs_value, emacs_value,
emacs_value))fun)(args[0], args[1],
args[2]);
break;
// Currently unused
case 4:
ret = ((emacs_value(*)(emacs_value, emacs_value,
emacs_value, emacs_value))fun)(args[0], args[1],
args[2], args[3]);
break;
case EZMQ_MAXARGS:
ret = ((emacs_value(*)(emacs_value, emacs_value,
emacs_value, emacs_value,
emacs_value))fun)(args[0], args[1],
args[2], args[3],
args[4]);
break;
}
// Cleanup global references flagged for deletion
ezmq_cleanup_globrefs();
return ret;
}
static void
ezmq_bind_function(ezmq_fun_t *fun)
{
// Make a copy of the function information. Used by ezmq_dispatch.
ezmq_fun_t *info = ezmq_malloc(sizeof(ezmq_fun_t));
if(NONLOCAL_EXIT()) return;
memcpy(info, fun, sizeof(ezmq_fun_t));
emacs_value Sfun = env->make_function(env,
fun->minarity, fun->maxarity,
&ezmq_dispatch,
fun->doc,
info);
// Use defalias here so that at least we get a link to zmq.el when examining
// the documentation for a zmq function.
FUNCALL(INTERN("defalias"), 2, ((emacs_value []){INTERN(fun->name), Sfun}));
}
static void
ezmq_provide(const char *feature)
{
FUNCALL(INTERN("provide"), 1, ((emacs_value []){ INTERN(feature) }));
}
#define EZMQ_DEFERR(err) \
args[0] = INTERN("zmq-"#err); \
args[1] = STRING(#err, sizeof(#err) - 1); \
FUNCALL(Qdefine_error, 3, args) \
/**
Make error symbols for common C errors used by ZMQ. Each error symbol is the
C error with a zmq- prefix. So EAGAIN becomes zmq-EAGAIN in Emacs.
*/
static void
ezmq_make_error_symbols()
{
emacs_value Qdefine_error = INTERN("define-error");
const char *msg = "An error occured in ZMQ";
emacs_value args[3];
// Define the root error symbol for ZMQ errors
args[0] = Qzmq_error;
args[1] = STRING(msg, strlen(msg));
args[2] = INTERN("error");
FUNCALL(Qdefine_error, 3, args);
// Set zmq-ERROR as the root error for all errors defined below
args[2] = Qzmq_error;
// Define common errors as symbols
// Also see zmq_signal_error
EZMQ_DEFERR(EINVAL);
EZMQ_DEFERR(EPROTONOSUPPORT);
EZMQ_DEFERR(ENOCOMPATPROTO);
EZMQ_DEFERR(EADDRINUSE);
EZMQ_DEFERR(EADDRNOTAVAIL);
EZMQ_DEFERR(ENODEV);
EZMQ_DEFERR(ETERM);
EZMQ_DEFERR(ENOTSOCK);
EZMQ_DEFERR(EMTHREAD);
EZMQ_DEFERR(EFAULT);
EZMQ_DEFERR(EINTR);
EZMQ_DEFERR(ENOTSUP);
EZMQ_DEFERR(ENOENT);
EZMQ_DEFERR(ENOMEM);
EZMQ_DEFERR(EAGAIN);
EZMQ_DEFERR(EFSM);
EZMQ_DEFERR(EHOSTUNREACH);
EZMQ_DEFERR(EMFILE);
}
#define EZMQ_DEFUN(ename, cfun, argmin, argmax) \
do { \
_info.name = ename; \
_info.fun = cfun; \
_info.minarity = argmin; \
_info.maxarity = argmax; \
_info.doc = __zmq_doc_##cfun; \
ezmq_bind_function(&_info); \
} while (0)
static void
ezmq_define_functions()
{
ezmq_fun_t _info;
// Define garbage collection functions for freeing global references
EZMQ_DEFUN("zmq--cleanup-globrefs", ezmq_cleanup_globrefs, 0, 0);
EZMQ_DEFUN("zmq-socket", ezmq_socket, 2, 2);
EZMQ_DEFUN("zmq-send", ezmq_send, 2, 3);
EZMQ_DEFUN("zmq-recv", ezmq_recv, 1, 3);
EZMQ_DEFUN("zmq-bind", ezmq_bind, 2, 2);
EZMQ_DEFUN("zmq-connect", ezmq_connect, 2, 2);
EZMQ_DEFUN("zmq-join", ezmq_join, 2, 2);
EZMQ_DEFUN("zmq-unbind", ezmq_unbind, 2, 2);
EZMQ_DEFUN("zmq-disconnect", ezmq_disconnect, 2, 2);
EZMQ_DEFUN("zmq-leave", ezmq_leave, 2, 2);
EZMQ_DEFUN("zmq-close", ezmq_close, 1, 1);
EZMQ_DEFUN("zmq-proxy", ezmq_proxy, 2, 3);
EZMQ_DEFUN("zmq-proxy-steerable", ezmq_proxy_steerable, 2, 4);
EZMQ_DEFUN("zmq-socket-monitor", ezmq_socket_monitor, 3, 3);
EZMQ_DEFUN("zmq-socket-set", ezmq_setsockopt, 3, 3);
EZMQ_DEFUN("zmq-socket-get", ezmq_getsockopt, 2, 2);
EZMQ_DEFUN("zmq-context", ezmq_context, 0, 0);
EZMQ_DEFUN("zmq-context-terminate", ezmq_ctx_term, 1, 1);
EZMQ_DEFUN("zmq-context-shutdown", ezmq_ctx_shutdown, 1, 1);
EZMQ_DEFUN("zmq-context-get", ezmq_ctx_get, 2, 2);
EZMQ_DEFUN("zmq-context-set", ezmq_ctx_set, 3, 3);
EZMQ_DEFUN("zmq-message", ezmq_message, 0, 1);
EZMQ_DEFUN("zmq-message-size", ezmq_message_size, 1, 1);
EZMQ_DEFUN("zmq-message-data", ezmq_message_data, 1, 1);
EZMQ_DEFUN("zmq-message-more-p", ezmq_message_more, 1, 1);
EZMQ_DEFUN("zmq-message-copy", ezmq_message_copy, 1, 1);
EZMQ_DEFUN("zmq-message-move", ezmq_message_move, 2, 2);
EZMQ_DEFUN("zmq-message-close", ezmq_message_close, 1, 1);
EZMQ_DEFUN("zmq-message-set", ezmq_message_set, 3, 3);
EZMQ_DEFUN("zmq-message-get", ezmq_message_get, 2, 2);
EZMQ_DEFUN("zmq-message-recv", ezmq_message_recv, 2, 3);
EZMQ_DEFUN("zmq-message-send", ezmq_message_send, 2, 3);
EZMQ_DEFUN("zmq-message-gets", ezmq_message_gets, 2, 2);
EZMQ_DEFUN("zmq-message-routing-id", ezmq_message_routing_id, 1, 1);
EZMQ_DEFUN("zmq-message-set-routing-id", ezmq_message_set_routing_id, 2, 2);
EZMQ_DEFUN("zmq-message-group", ezmq_message_group, 1, 1);
EZMQ_DEFUN("zmq-message-set-group", ezmq_message_set_group, 2, 2);
EZMQ_DEFUN("zmq-poll", ezmq_poll, 2, 2);
EZMQ_DEFUN("zmq-poller", ezmq_poller_new, 0, 0);
EZMQ_DEFUN("zmq-poller-add", ezmq_poller_add, 3, 3);
EZMQ_DEFUN("zmq-poller-modify", ezmq_poller_modify, 3, 3);
EZMQ_DEFUN("zmq-poller-remove", ezmq_poller_remove, 2, 2);
EZMQ_DEFUN("zmq-poller-destroy", ezmq_poller_destroy, 1, 1);
EZMQ_DEFUN("zmq-poller-wait", ezmq_poller_wait, 2, 2);
EZMQ_DEFUN("zmq-poller-wait-all", ezmq_poller_wait_all, 3, 3);
EZMQ_DEFUN("zmq-version", ezmq_version, 0, 0);
EZMQ_DEFUN("zmq-has", ezmq_has, 1, 1);
EZMQ_DEFUN("zmq-z85-decode", ezmq_z85_decode, 1, 1);
EZMQ_DEFUN("zmq-z85-encode", ezmq_z85_encode, 1, 1);
EZMQ_DEFUN("zmq-curve-keypair", ezmq_curve_keypair, 0, 0);
EZMQ_DEFUN("zmq-curve-public", ezmq_curve_public, 1, 1);
EZMQ_DEFUN("zmq-equal", ezmq_equal, 2, 2);
EZMQ_DEFUN("zmq-message-p", ezmq_message_p, 1, 1);
EZMQ_DEFUN("zmq-socket-p", ezmq_socket_p, 1, 1);
EZMQ_DEFUN("zmq-context-p", ezmq_context_p, 1, 1);
EZMQ_DEFUN("zmq-poller-p", ezmq_poller_p, 1, 1);
}
static bool initialized = false;
int
emacs_module_init(struct emacs_runtime *ert)
{
if(initialized)
return 0;
// From https://phst.eu/emacs-modules
/* Fail if Emacs is too old. */
assert (ert->size > 0);
if ((size_t) ert->size < sizeof *ert)
return 1;
// Retrieve the current emacs environment
env = ert->get_environment(ert);
// From https://phst.eu/emacs-modules
if ((size_t) env->size < sizeof *env)
return 2;
/* Prevent Emacss dangerous stack overflow recovery. */
if (signal (SIGSEGV, SIG_DFL) == SIG_ERR)
return 3;
Qt = GLOBREF(INTERN("t"));
Qnil = GLOBREF(INTERN("nil"));
Qnth = GLOBREF(INTERN("nth"));
Qwrong_type_argument = GLOBREF(INTERN("wrong-type-argument"));
Qargs_out_of_range = GLOBREF(INTERN("args-out-of-range"));
Qlist = GLOBREF(INTERN("list"));
Qstring = GLOBREF(INTERN("string"));
Qvector = GLOBREF(INTERN("vector"));
Qcons = GLOBREF(INTERN("cons"));
Qcar = GLOBREF(INTERN("car"));
Qcdr = GLOBREF(INTERN("cdr"));
Qequal = GLOBREF(INTERN("equal"));
Qinteger = GLOBREF(INTERN("integer"));
Qlength = GLOBREF(INTERN("length"));
Qzmq_error = GLOBREF(INTERN("zmq-ERROR"));
ezmq_make_error_symbols();
ezmq_expose_constants();
Qzmq_POLLIN = GLOBREF(INTERN("zmq-POLLIN"));
Qzmq_POLLPRI = GLOBREF(INTERN("zmq-POLLPRI"));
Qzmq_POLLOUT = GLOBREF(INTERN("zmq-POLLOUT"));
Qzmq_POLLERR = GLOBREF(INTERN("zmq-POLLERR"));
emacs_value Qsval = INTERN("symbol-value");
Izmq_POLLIN = GLOBREF(FUNCALL(Qsval, 1, &Qzmq_POLLIN));
Izmq_POLLPRI = GLOBREF(FUNCALL(Qsval, 1, &Qzmq_POLLPRI));
Izmq_POLLOUT = GLOBREF(FUNCALL(Qsval, 1, &Qzmq_POLLOUT));
Izmq_POLLERR = GLOBREF(FUNCALL(Qsval, 1, &Qzmq_POLLERR));
ezmq_define_functions();
ezmq_provide("zmq-core");
if(!NONLOCAL_EXIT()) initialized = true;
return 0;
}