mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-21 06:55:39 +00:00
Add dynamic module module support
* configure.ac: Add '--with-modules' option. Conditionally add dynlib.o and module.o to the list of objects. Add any system specific flags to the linker flags to support dynamic libraries. * m4/ax_gcc_var_attribute.m4: Add autoconf extension to test gcc attributes. * src/Makefile.in: Conditionally add module objects and linker flags. * src/alloc.c (garbage_collect_1): protect module local values from GC. * src/lisp.h: Add 'module_init' and 'syms_of_module' prototypes. * src/emacs_module.h: New header file included by modules. Public module API. * src/module.c: New module implementation file. Co-authored-by: Philipp Stephani <phst@google.com>
This commit is contained in:
parent
f69cd6bfa1
commit
307e76c799
49
configure.ac
49
configure.ac
@ -353,6 +353,7 @@ OPTION_DEFAULT_ON([gsettings],[don't compile with GSettings support])
|
||||
OPTION_DEFAULT_ON([selinux],[don't compile with SELinux support])
|
||||
OPTION_DEFAULT_ON([gnutls],[don't use -lgnutls for SSL/TLS support])
|
||||
OPTION_DEFAULT_ON([zlib],[don't compile with zlib decompression support])
|
||||
OPTION_DEFAULT_OFF([modules],[compile with dynamic modules support])
|
||||
|
||||
AC_ARG_WITH([file-notification],[AS_HELP_STRING([--with-file-notification=LIB],
|
||||
[use a file notification library (LIB one of: yes, gfile, inotify, w32, no)])],
|
||||
@ -2191,6 +2192,9 @@ LIBS="$LIBS_SYSTEM $LIBS"
|
||||
dnl FIXME replace main with a function we actually want from this library.
|
||||
AC_CHECK_LIB(Xbsd, main, LD_SWITCH_X_SITE="$LD_SWITCH_X_SITE -lXbsd")
|
||||
|
||||
dnl Check for C11 threads.
|
||||
AC_CHECK_HEADERS_ONCE(threads.h)
|
||||
|
||||
dnl Check for the POSIX thread library.
|
||||
LIB_PTHREAD=
|
||||
AC_CHECK_HEADERS_ONCE(pthread.h)
|
||||
@ -3285,6 +3289,48 @@ if test "${HAVE_ZLIB}" = "yes"; then
|
||||
fi
|
||||
AC_SUBST(LIBZ)
|
||||
|
||||
### Dynamic modules support
|
||||
LIBMODULES=
|
||||
HAVE_MODULES=no
|
||||
MODULES_OBJ=
|
||||
MODULES_SUFFIX=
|
||||
if test "${with_modules}" != "no"; then
|
||||
if test "$opsys" = "gnu-linux"; then
|
||||
LIBMODULES="-ldl"
|
||||
MODULES_SUFFIX=".so"
|
||||
HAVE_MODULES=yes
|
||||
elif test "$opsys" = "cygwin"; then
|
||||
# XXX: not tested
|
||||
LIBMODULES="-lcygwin"
|
||||
MODULES_SUFFIX=".dll"
|
||||
HAVE_MODULES=yes
|
||||
elif test "$opsys" = "darwin"; then
|
||||
MODULES_SUFFIX=".so"
|
||||
HAVE_MODULES=yes
|
||||
elif test "$opsys" = "mingw32"; then
|
||||
MODULES_SUFFIX=".dll"
|
||||
HAVE_MODULES=yes
|
||||
else
|
||||
# BSD system have dlopen in the libc
|
||||
AC_CHECK_FUNC(dlopen, [MODULES_SUFFIX=".so"]
|
||||
[HAVE_MODULES=yes], [])
|
||||
fi
|
||||
|
||||
if test "${HAVE_MODULES}" = no; then
|
||||
AC_MSG_ERROR([Dynamic modules are not supported on your system])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "${HAVE_MODULES}" = yes; then
|
||||
MODULES_OBJ="dynlib.o module.o"
|
||||
AC_DEFINE(HAVE_MODULES, 1, [Define to 1 if dynamic modules are enabled])
|
||||
AC_DEFINE_UNQUOTED(MODULES_SUFFIX, "$MODULES_SUFFIX", [System extension for dynamic libraries])
|
||||
fi
|
||||
AC_SUBST(MODULES_OBJ)
|
||||
AC_SUBST(LIBMODULES)
|
||||
AX_GCC_VAR_ATTRIBUTE(cleanup)
|
||||
AC_CHECK_FUNCS(dladdr)
|
||||
|
||||
### Use -lpng if available, unless '--with-png=no'.
|
||||
HAVE_PNG=no
|
||||
LIBPNG=
|
||||
@ -5175,7 +5221,7 @@ optsep=
|
||||
emacs_config_features=
|
||||
for opt in XAW3D XPM JPEG TIFF GIF PNG RSVG CAIRO IMAGEMAGICK SOUND GPM DBUS \
|
||||
GCONF GSETTINGS NOTIFY ACL LIBSELINUX GNUTLS LIBXML2 FREETYPE M17N_FLT \
|
||||
LIBOTF XFT ZLIB TOOLKIT_SCROLL_BARS X_TOOLKIT X11 NS; do
|
||||
LIBOTF XFT ZLIB TOOLKIT_SCROLL_BARS X_TOOLKIT X11 NS MODULES; do
|
||||
|
||||
case $opt in
|
||||
NOTIFY|ACL) eval val=\${${opt}_SUMMARY} ;;
|
||||
@ -5223,6 +5269,7 @@ AS_ECHO([" Does Emacs use -lXaw3d? ${HAVE_XAW3D
|
||||
Does Emacs use -lotf? ${HAVE_LIBOTF}
|
||||
Does Emacs use -lxft? ${HAVE_XFT}
|
||||
Does Emacs directly use zlib? ${HAVE_ZLIB}
|
||||
Does Emacs has dynamic modules support? ${HAVE_MODULES}
|
||||
Does Emacs use toolkit scroll bars? ${USE_TOOLKIT_SCROLL_BARS}
|
||||
"])
|
||||
|
||||
|
141
m4/ax_gcc_var_attribute.m4
Normal file
141
m4/ax_gcc_var_attribute.m4
Normal file
@ -0,0 +1,141 @@
|
||||
# ===========================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_gcc_var_attribute.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_GCC_VAR_ATTRIBUTE(ATTRIBUTE)
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This macro checks if the compiler supports one of GCC's variable
|
||||
# attributes; many other compilers also provide variable attributes with
|
||||
# the same syntax. Compiler warnings are used to detect supported
|
||||
# attributes as unsupported ones are ignored by default so quieting
|
||||
# warnings when using this macro will yield false positives.
|
||||
#
|
||||
# The ATTRIBUTE parameter holds the name of the attribute to be checked.
|
||||
#
|
||||
# If ATTRIBUTE is supported define HAVE_VAR_ATTRIBUTE_<ATTRIBUTE>.
|
||||
#
|
||||
# The macro caches its result in the ax_cv_have_var_attribute_<attribute>
|
||||
# variable.
|
||||
#
|
||||
# The macro currently supports the following variable attributes:
|
||||
#
|
||||
# aligned
|
||||
# cleanup
|
||||
# common
|
||||
# nocommon
|
||||
# deprecated
|
||||
# mode
|
||||
# packed
|
||||
# tls_model
|
||||
# unused
|
||||
# used
|
||||
# vector_size
|
||||
# weak
|
||||
# dllimport
|
||||
# dllexport
|
||||
# init_priority
|
||||
#
|
||||
# Unsuppored variable attributes will be tested against a global integer
|
||||
# variable and without any arguments given to the attribute itself; the
|
||||
# result of this check might be wrong or meaningless so use with care.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2013 Gabriele Svelto <gabriele.svelto@gmail.com>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 3
|
||||
|
||||
AC_DEFUN([AX_GCC_VAR_ATTRIBUTE], [
|
||||
AS_VAR_PUSHDEF([ac_var], [ax_cv_have_var_attribute_$1])
|
||||
|
||||
AC_CACHE_CHECK([for __attribute__(($1))], [ac_var], [
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([
|
||||
m4_case([$1],
|
||||
[aligned], [
|
||||
int foo __attribute__(($1(32)));
|
||||
],
|
||||
[cleanup], [
|
||||
int bar(int *t) { return *t; };
|
||||
],
|
||||
[common], [
|
||||
int foo __attribute__(($1));
|
||||
],
|
||||
[nocommon], [
|
||||
int foo __attribute__(($1));
|
||||
],
|
||||
[deprecated], [
|
||||
int foo __attribute__(($1)) = 0;
|
||||
],
|
||||
[mode], [
|
||||
long foo __attribute__(($1(word)));
|
||||
],
|
||||
[packed], [
|
||||
struct bar {
|
||||
int baz __attribute__(($1));
|
||||
};
|
||||
],
|
||||
[tls_model], [
|
||||
__thread int bar1 __attribute__(($1("global-dynamic")));
|
||||
__thread int bar2 __attribute__(($1("local-dynamic")));
|
||||
__thread int bar3 __attribute__(($1("initial-exec")));
|
||||
__thread int bar4 __attribute__(($1("local-exec")));
|
||||
],
|
||||
[unused], [
|
||||
int foo __attribute__(($1));
|
||||
],
|
||||
[used], [
|
||||
int foo __attribute__(($1));
|
||||
],
|
||||
[vector_size], [
|
||||
int foo __attribute__(($1(16)));
|
||||
],
|
||||
[weak], [
|
||||
int foo __attribute__(($1));
|
||||
],
|
||||
[dllimport], [
|
||||
int foo __attribute__(($1));
|
||||
],
|
||||
[dllexport], [
|
||||
int foo __attribute__(($1));
|
||||
],
|
||||
[init_priority], [
|
||||
struct bar { bar() {} ~bar() {} };
|
||||
bar b __attribute__(($1(65535/2)));
|
||||
],
|
||||
[
|
||||
m4_warn([syntax], [Unsupported attribute $1, the test may fail])
|
||||
int foo __attribute__(($1));
|
||||
]
|
||||
)], [
|
||||
m4_case([$1],
|
||||
[cleanup], [
|
||||
int foo __attribute__(($1(bar))) = 0;
|
||||
foo = foo + 1;
|
||||
],
|
||||
[]
|
||||
)])
|
||||
],
|
||||
dnl GCC doesn't exit with an error if an unknown attribute is
|
||||
dnl provided but only outputs a warning, so accept the attribute
|
||||
dnl only if no warning were issued.
|
||||
[AS_IF([test -s conftest.err],
|
||||
[AS_VAR_SET([ac_var], [no])],
|
||||
[AS_VAR_SET([ac_var], [yes])])],
|
||||
[AS_VAR_SET([ac_var], [no])])
|
||||
])
|
||||
|
||||
AS_IF([test yes = AS_VAR_GET([ac_var])],
|
||||
[AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_VAR_ATTRIBUTE_$1), 1,
|
||||
[Define to 1 if the system has the `$1' variable attribute])], [])
|
||||
|
||||
AS_VAR_POPDEF([ac_var])
|
||||
])
|
@ -230,6 +230,11 @@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
|
||||
|
||||
LIBZ = @LIBZ@
|
||||
|
||||
## system-specific libs for dynamic modules, else empty
|
||||
LIBMODULES = @LIBMODULES@
|
||||
## dynlib.o module.o if modules enabled, else empty
|
||||
MODULES_OBJ = @MODULES_OBJ@
|
||||
|
||||
XRANDR_LIBS = @XRANDR_LIBS@
|
||||
XRANDR_CFLAGS = @XRANDR_CFLAGS@
|
||||
|
||||
@ -377,7 +382,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
|
||||
minibuf.o fileio.o dired.o \
|
||||
cmds.o casetab.o casefiddle.o indent.o search.o regex.o undo.o \
|
||||
alloc.o data.o doc.o editfns.o callint.o \
|
||||
eval.o floatfns.o fns.o font.o print.o lread.o \
|
||||
eval.o floatfns.o fns.o font.o print.o lread.o $(MODULES_OBJ) \
|
||||
syntax.o $(UNEXEC_OBJ) bytecode.o \
|
||||
process.o gnutls.o callproc.o \
|
||||
region-cache.o sound.o atimer.o \
|
||||
@ -468,7 +473,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \
|
||||
$(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \
|
||||
$(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \
|
||||
$(LIBGNUTLS_LIBS) $(LIB_PTHREAD) \
|
||||
$(GFILENOTIFY_LIBS) $(LIB_MATH) $(LIBZ)
|
||||
$(GFILENOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBMODULES)
|
||||
|
||||
$(leimdir)/leim-list.el: bootstrap-emacs$(EXEEXT)
|
||||
$(MAKE) -C ../leim leim-list.el EMACS="$(bootstrap_exe)"
|
||||
|
@ -5574,6 +5574,10 @@ garbage_collect_1 (void *end)
|
||||
mark_fringe_data ();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MODULES
|
||||
mark_modules ();
|
||||
#endif
|
||||
|
||||
/* Everything is now marked, except for the data in font caches,
|
||||
undo lists, and finalizers. The first two are compacted by
|
||||
removing an items which aren't reachable otherwise. */
|
||||
|
@ -776,6 +776,10 @@ main (int argc, char **argv)
|
||||
|
||||
atexit (close_output_streams);
|
||||
|
||||
#ifdef HAVE_MODULES
|
||||
module_init ();
|
||||
#endif
|
||||
|
||||
sort_args (argc, argv);
|
||||
argc = 0;
|
||||
while (argv[argc]) argc++;
|
||||
@ -1450,6 +1454,11 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
|
||||
syms_of_terminal ();
|
||||
syms_of_term ();
|
||||
syms_of_undo ();
|
||||
|
||||
#ifdef HAVE_MODULES
|
||||
syms_of_module ();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SOUND
|
||||
syms_of_sound ();
|
||||
#endif
|
||||
|
230
src/emacs_module.h
Normal file
230
src/emacs_module.h
Normal file
@ -0,0 +1,230 @@
|
||||
/*
|
||||
emacs_module.h - Module API
|
||||
Copyright (C) 2015 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GNU Emacs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef EMACS_MODULE_H
|
||||
#define EMACS_MODULE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EMACS_EXTERN_C_BEGIN extern "C" {
|
||||
#define EMACS_EXTERN_C_END }
|
||||
#else
|
||||
#define EMACS_EXTERN_C_BEGIN
|
||||
#define EMACS_EXTERN_C_END
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus) && __cplusplus >= 201103L
|
||||
#define EMACS_NOEXCEPT noexcept
|
||||
#else
|
||||
#define EMACS_NOEXCEPT
|
||||
#endif
|
||||
|
||||
EMACS_EXTERN_C_BEGIN
|
||||
|
||||
/* Current environement */
|
||||
typedef struct emacs_env_25 emacs_env;
|
||||
|
||||
/* Opaque structure pointer representing an Emacs Lisp value */
|
||||
typedef struct emacs_value_tag* emacs_value;
|
||||
|
||||
enum emacs_arity {
|
||||
emacs_variadic_function = -2
|
||||
};
|
||||
|
||||
/* Struct passed to a module init function (emacs_module_init) */
|
||||
struct emacs_runtime {
|
||||
/* Structure size (for version checking) */
|
||||
size_t size;
|
||||
|
||||
/* Private data; users should not touch this */
|
||||
struct emacs_runtime_private *private_members;
|
||||
|
||||
/* Returns an environment pointer. */
|
||||
emacs_env* (*get_environment)(struct emacs_runtime *ert);
|
||||
};
|
||||
|
||||
|
||||
/* Function prototype for the module init function */
|
||||
typedef int (*emacs_init_function)(struct emacs_runtime *ert);
|
||||
|
||||
/* Function prototype for the module Lisp functions */
|
||||
typedef emacs_value (*emacs_subr)(emacs_env *env,
|
||||
int nargs,
|
||||
emacs_value args[],
|
||||
void *data);
|
||||
|
||||
/* Function prototype for module user-pointer finalizers */
|
||||
typedef void (*emacs_finalizer_function)(void*);
|
||||
|
||||
/* Possible Emacs function call outcomes. */
|
||||
enum emacs_funcall_exit {
|
||||
/* Function has returned normally. */
|
||||
emacs_funcall_exit_return = 0,
|
||||
/* Function has signaled an error using `signal'. */
|
||||
emacs_funcall_exit_signal = 1,
|
||||
/* Function has exit using `throw'. */
|
||||
emacs_funcall_exit_throw = 2,
|
||||
};
|
||||
|
||||
struct emacs_env_25 {
|
||||
/*
|
||||
* Structure size (for version checking)
|
||||
*/
|
||||
|
||||
size_t size;
|
||||
|
||||
/* Private data; users should not touch this */
|
||||
struct emacs_env_private *private_members;
|
||||
|
||||
/*
|
||||
* Memory management
|
||||
*/
|
||||
|
||||
|
||||
emacs_value (*make_global_ref)(emacs_env *env,
|
||||
emacs_value any_reference);
|
||||
|
||||
void (*free_global_ref)(emacs_env *env,
|
||||
emacs_value global_reference);
|
||||
|
||||
/*
|
||||
* Non-local exit handling
|
||||
*/
|
||||
|
||||
enum emacs_funcall_exit (*non_local_exit_check)(emacs_env *env);
|
||||
|
||||
void (*non_local_exit_clear)(emacs_env *env);
|
||||
|
||||
enum emacs_funcall_exit (*non_local_exit_get)(emacs_env *env,
|
||||
emacs_value *non_local_exit_symbol_out,
|
||||
emacs_value *non_local_exit_data_out);
|
||||
|
||||
void (*non_local_exit_signal)(emacs_env *env,
|
||||
emacs_value non_local_exit_symbol,
|
||||
emacs_value non_local_exit_data);
|
||||
|
||||
void (*non_local_exit_throw)(emacs_env *env,
|
||||
emacs_value tag,
|
||||
emacs_value value);
|
||||
|
||||
/*
|
||||
* Function registration
|
||||
*/
|
||||
|
||||
emacs_value (*make_function)(emacs_env *env,
|
||||
int min_arity,
|
||||
int max_arity,
|
||||
emacs_value (*function)(emacs_env*, int, emacs_value*, void*) EMACS_NOEXCEPT,
|
||||
const char *documentation,
|
||||
void *data);
|
||||
|
||||
emacs_value (*funcall)(emacs_env *env,
|
||||
emacs_value function,
|
||||
int nargs,
|
||||
emacs_value args[]);
|
||||
|
||||
emacs_value (*intern)(emacs_env *env,
|
||||
const char *symbol_name);
|
||||
|
||||
/*
|
||||
* Type conversion
|
||||
*/
|
||||
|
||||
emacs_value (*type_of)(emacs_env *env,
|
||||
emacs_value value);
|
||||
|
||||
bool (*is_not_nil)(emacs_env *env, emacs_value value);
|
||||
|
||||
bool (*eq)(emacs_env *env, emacs_value a, emacs_value b);
|
||||
|
||||
int64_t (*extract_integer)(emacs_env *env,
|
||||
emacs_value value);
|
||||
|
||||
emacs_value (*make_integer)(emacs_env *env,
|
||||
int64_t value);
|
||||
|
||||
double (*extract_float)(emacs_env *env,
|
||||
emacs_value value);
|
||||
|
||||
emacs_value (*make_float)(emacs_env *env,
|
||||
double value);
|
||||
|
||||
/*
|
||||
* Copy the content of the lisp string VALUE to BUFFER as an utf8
|
||||
* null-terminated string.
|
||||
*
|
||||
* SIZE must point to the total size of the buffer. If BUFFER is
|
||||
* NULL or if SIZE is not big enough, write the required buffer size
|
||||
* to SIZE and return false.
|
||||
*
|
||||
* Note that SIZE must include the last null byte (e.g. "abc" needs
|
||||
* a buffer of size 4).
|
||||
*
|
||||
* Returns true if the string was successfully copied.
|
||||
*/
|
||||
|
||||
bool (*copy_string_contents)(emacs_env *env,
|
||||
emacs_value value,
|
||||
char *buffer,
|
||||
size_t *size_inout);
|
||||
|
||||
/*
|
||||
* Create a lisp string from a utf8 encoded string.
|
||||
*/
|
||||
emacs_value (*make_string)(emacs_env *env,
|
||||
const char *contents, size_t length);
|
||||
|
||||
/*
|
||||
* Embedded pointer type
|
||||
*/
|
||||
emacs_value (*make_user_ptr)(emacs_env *env,
|
||||
void (*fin)(void *) EMACS_NOEXCEPT,
|
||||
void *ptr);
|
||||
|
||||
void* (*get_user_ptr)(emacs_env *env, emacs_value uptr);
|
||||
void (*set_user_ptr)(emacs_env *env, emacs_value uptr, void *ptr);
|
||||
|
||||
void (*(*get_user_finalizer)(emacs_env *env, emacs_value uptr))(void *) EMACS_NOEXCEPT;
|
||||
void (*set_user_finalizer)(emacs_env *env,
|
||||
emacs_value uptr,
|
||||
void (*fin)(void *) EMACS_NOEXCEPT);
|
||||
|
||||
/*
|
||||
* Vector functions
|
||||
*/
|
||||
emacs_value (*vec_get) (emacs_env *env,
|
||||
emacs_value vec,
|
||||
size_t i);
|
||||
|
||||
void (*vec_set) (emacs_env *env,
|
||||
emacs_value vec,
|
||||
size_t i,
|
||||
emacs_value val);
|
||||
|
||||
size_t (*vec_size) (emacs_env *env,
|
||||
emacs_value vec);
|
||||
};
|
||||
|
||||
EMACS_EXTERN_C_END
|
||||
|
||||
#endif /* EMACS_MODULE_H */
|
@ -3916,6 +3916,10 @@ extern bool let_shadows_global_binding_p (Lisp_Object symbol);
|
||||
/* Defined in alloc.c. */
|
||||
extern Lisp_Object make_user_ptr (void (*finalizer) (void*), void *p);
|
||||
|
||||
/* Defined in module.c. */
|
||||
extern void module_init (void);
|
||||
extern void mark_modules (void);
|
||||
extern void syms_of_module (void);
|
||||
#endif
|
||||
|
||||
/* Defined in editfns.c. */
|
||||
|
1185
src/module.c
Normal file
1185
src/module.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user