#include "plugins.hpp" #include "pk.h" #include #include #include #ifdef WIN32 // TODO #else #include #endif pk_arr_t LoadedPkePlugins{}; pk_arr_t pkePluginCallbacks{}; pk_arr_t sortedSignatures{}; void PkePlugin_Load(const char *path) { if (path == nullptr || path == CAFE_BABE(const char)) { return; } void *extension = dlopen(path, RTLD_NOW); char *err = dlerror(); if (!extension) { fprintf(stderr, "Given plugin library (%s) failed to load: %s\n", path, err); return; } PKEPluginInterface *interface = reinterpret_cast(dlsym(extension, "pkePluginInterface")); err = dlerror(); if (err != NULL) { fprintf(stderr, "Given plugin library (%s) did not contain 'pkePluginInterface': %s\n", path, err); dlclose(extension); return; } interface->pluginHandle = extension; pk_arr_append(&LoadedPkePlugins, interface); } PkeCallback *PkePlugin_FindSignature(const CallbackSignature &sig) { for (long i = 0; i < pkePluginCallbacks.next; ++i) { if (strncmp(sig, pkePluginCallbacks[i].name, 16) == 0) { return &pkePluginCallbacks[i]; } } return nullptr; } void PkePlugin_SetSignatureFunc(PkeCallback *sig) { assert(sig != nullptr); if (sig->name[0] == '\0') { return; } auto *registeredSig = PkePlugin_FindSignature(sig->name); if (registeredSig == nullptr) { fprintf(stdout, "[WARN] [PkePlugin_SetSignatureFunc] Failed to find configured signature: '%s'\n", sig->name); return; } sig->func = registeredSig->func; } int pstrncmp(const void* a, const void* b) { return strncmp(static_cast(a)[0], static_cast(b)[0], 16); } CallbackSignature *PkePlugin_GetSortedSignatures(long &count) { if (sortedSignatures.next != pkePluginCallbacks.next) { while (sortedSignatures.next != pkePluginCallbacks.next) { pk_arr_append(&sortedSignatures, pkePluginCallbacks[sortedSignatures.next].name); } qsort(sortedSignatures.data, sortedSignatures.next, sizeof(CallbackSignature), pstrncmp); } count = sortedSignatures.next; return reinterpret_cast(sortedSignatures.data); } void PkePlugin_Teardown() { pk_arr_reset(&sortedSignatures); pk_arr_reset(&pkePluginCallbacks); pk_arr_reset(&LoadedPkePlugins); }