1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
#include "plugins.hpp"
#include "pk.h"
#include <cassert>
#include <cstdio>
#include <cstring>
#ifdef WIN32
// TODO
#else
#include <dlfcn.h>
#endif
pk_arr_t<PKEPluginInterface> LoadedPkePlugins{};
pk_arr_t<PkeCallback> pkePluginCallbacks{};
pk_arr_t<CallbackSignature> 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<PKEPluginInterface *>(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<const CallbackSignature *>(a)[0], static_cast<const CallbackSignature *>(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<CallbackSignature*>(sortedSignatures.data);
}
void PkePlugin_Teardown() {
pk_arr_reset(&sortedSignatures);
pk_arr_reset(&pkePluginCallbacks);
pk_arr_reset(&LoadedPkePlugins);
}
|