* Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * This library 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 * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see <https://www.gnu.org/licenses/>. #include "gplugin-tcc-loader.h" #include <glib/gi18n-lib.h> #include "gplugin-tcc-plugin.h" struct _GPluginTccLoader { /****************************************************************************** * GPluginLoaderInterface API *****************************************************************************/ gplugin_tcc_loader_supported_extensions(G_GNUC_UNUSED GPluginLoader *l) return g_slist_append(NULL, "c"); gplugin_tcc_loader_query( GPluginPlugin *plugin = NULL; GPluginPluginInfo *info = NULL; gpointer memneeded = NULL; GPluginTccPluginQueryFunc gplugin_query = NULL; tcc_set_output_type(s, TCC_OUTPUT_MEMORY); if(tcc_add_file(s, filename) == -1) { /* copy code into memory */ if((memsize = tcc_relocate(s, NULL)) < 0) { "couldn't work out how much memory is needed"); memneeded = g_malloc0(memsize); if(tcc_relocate(s, memneeded) < 0) { "could not relocate plugin into memory"); (GPluginTccPluginQueryFunc)tcc_get_symbol(s, "gplugin_query"); if(gplugin_query == NULL) { "no gplugin_query function found"); info = gplugin_query(error); G_GNUC_UNUSED GPluginLoader *loader, GPluginTccPluginLoadFunc gplugin_load = NULL; TCCState *s = gplugin_tcc_plugin_get_state(GPLUGIN_TCC_PLUGIN(plugin)); gplugin_load = (GPluginTccPluginLoadFunc)tcc_get_symbol(s, "gplugin_load"); if(gplugin_load == NULL) { g_set_error(error, GPLUGIN_DOMAIN, 0, "no gplugin_load function found"); return gplugin_load(GPLUGIN_NATIVE_PLUGIN(plugin), error); gplugin_tcc_loader_unload( G_GNUC_UNUSED GPluginLoader *loader, GPluginTccPluginLoadFunc gplugin_unload = NULL; TCCState *s = gplugin_tcc_plugin_get_state(GPLUGIN_TCC_PLUGIN(plugin)); (GPluginTccPluginUnloadFunc)tcc_get_symbol(s, "gplugin_unload"); if(gplugin_unload == NULL) { "no gplugin_unload function found"); return gplugin_unload(GPLUGIN_NATIVE_PLUGIN(plugin), error); /****************************************************************************** *****************************************************************************/ gplugin_tcc_loader_init(G_GNUC_UNUSED GPluginTccLoader *loader) gplugin_tcc_loader_class_finalize(G_GNUC_UNUSED GPluginTccLoaderClass *klass) gplugin_tcc_loader_class_init(GPluginTccLoaderClass *klass) GPluginLoaderClass *loader_class = GPLUGIN_LOADER_CLASS(klass); loader_class->supported_extensions = gplugin_tcc_loader_supported_extensions; loader_class->query = gplugin_tcc_loader_query; loader_class->load = gplugin_tcc_loader_load; loader_class->unload = gplugin_tcc_loader_unload; /****************************************************************************** *****************************************************************************/ gplugin_tcc_loader_register(GPluginNativePlugin *plugin) gplugin_tcc_loader_register_type(G_TYPE_MODULE(plugin)); gplugin_tcc_loader_new(void) return GPLUGIN_LOADER(g_object_new(