mirror of
https://github.com/ZoiteChat/zoitechat.git
synced 2026-07-08 12:59:24 +00:00
110 lines
3.4 KiB
Python
Executable File
110 lines
3.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import sys
|
|
import cffi
|
|
|
|
builder = cffi.FFI()
|
|
|
|
with open(sys.argv[1]) as f:
|
|
output = []
|
|
eat_until_endif = 0
|
|
for line in f:
|
|
if line.startswith('#define'):
|
|
continue
|
|
elif line.endswith('ZOITECHAT_PLUGIN_H\n'):
|
|
continue
|
|
elif 'time.h' in line:
|
|
output.append('typedef int... time_t;')
|
|
elif line.startswith('#if'):
|
|
eat_until_endif += 1
|
|
elif line.startswith('#endif'):
|
|
eat_until_endif -= 1
|
|
elif eat_until_endif and '_zoitechat_context' not in line:
|
|
continue
|
|
else:
|
|
output.append(line)
|
|
builder.cdef(''.join(output))
|
|
|
|
builder.embedding_api('''
|
|
extern "Python" int _on_py_command(char **, char **, void *);
|
|
extern "Python" int _on_load_command(char **, char **, void *);
|
|
extern "Python" int _on_unload_command(char **, char **, void *);
|
|
extern "Python" int _on_reload_command(char **, char **, void *);
|
|
extern "Python" int _on_say_command(char **, char **, void *);
|
|
|
|
extern "Python" int _on_command_hook(char **, char **, void *);
|
|
extern "Python" int _on_print_hook(char **, void *);
|
|
extern "Python" int _on_print_attrs_hook(char **, zoitechat_event_attrs *, void *);
|
|
extern "Python" int _on_server_hook(char **, char **, void *);
|
|
extern "Python" int _on_server_attrs_hook(char **, char **, zoitechat_event_attrs *, void *);
|
|
extern "Python" int _on_timer_hook(void *);
|
|
|
|
extern "Python" int _on_plugin_init(char **, char **, char **, char *, char *);
|
|
extern "Python" int _on_plugin_deinit(void);
|
|
|
|
static zoitechat_plugin *ph;
|
|
''')
|
|
|
|
builder.set_source('_zoitechat_embedded', '''
|
|
/* Python's header defines these.. */
|
|
#undef HAVE_MEMRCHR
|
|
#undef HAVE_STRINGS_H
|
|
|
|
#include "config.h"
|
|
#include "zoitechat-plugin.h"
|
|
|
|
#ifdef _WIN32
|
|
#ifndef WIN32_LEAN_AND_MEAN
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#endif
|
|
#ifndef NOMINMAX
|
|
#define NOMINMAX
|
|
#endif
|
|
#include <windows.h>
|
|
#endif
|
|
|
|
static zoitechat_plugin *ph;
|
|
CFFI_DLLEXPORT int _on_plugin_init(char **, char **, char **, char *, char *);
|
|
CFFI_DLLEXPORT int _on_plugin_deinit(void);
|
|
|
|
int zoitechat_plugin_init(zoitechat_plugin *plugin_handle,
|
|
char **name_out, char **description_out,
|
|
char **version_out, char *arg)
|
|
{
|
|
#ifdef _WIN32
|
|
/* CPython cannot be removed from a process once Py_Initialize has run.
|
|
If the embedded interpreter fails to start (e.g. _cffi_backend is
|
|
missing), the host responds to our 0 return by g_module_close()ing
|
|
this plugin, which would also drop the last reference to pythonXY.dll
|
|
and unload it mid-flight; the leftover process-global state then
|
|
crashes the process later, e.g. when a server connection spawns the
|
|
next thread. Pin this module so FreeLibrary can never unload it. */
|
|
HMODULE self_handle;
|
|
GetModuleHandleExW (GET_MODULE_HANDLE_EX_FLAG_PIN |
|
|
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
|
|
(LPCWSTR)&zoitechat_plugin_init, &self_handle);
|
|
#endif
|
|
|
|
if (ph != NULL)
|
|
{
|
|
puts ("Python plugin already loaded\\n");
|
|
return 0; /* Prevent loading twice */
|
|
}
|
|
|
|
ph = plugin_handle;
|
|
return _on_plugin_init(name_out, description_out, version_out, arg, ZOITECHATLIBDIR);
|
|
}
|
|
|
|
int zoitechat_plugin_deinit(void)
|
|
{
|
|
int ret = _on_plugin_deinit();
|
|
ph = NULL;
|
|
return ret;
|
|
}
|
|
''')
|
|
|
|
with open(sys.argv[2]) as f:
|
|
builder.embedding_init_code(f.read())
|
|
|
|
builder.emit_c_code(sys.argv[3])
|