]> localhost Git - pldh.git/commitdiff
General refactor of header
authormisomosi <[email protected]>
Tue, 7 May 2024 03:34:35 +0000 (23:34 -0400)
committermisomosi <[email protected]>
Tue, 7 May 2024 03:45:24 +0000 (23:45 -0400)
pld.h

diff --git a/pld.h b/pld.h
index 496b92ad19ff06ffddddbda0cfc385b57c1c5fe8..ce7b7fea161448fec5bae9ab52a39675d591cbf2 100644 (file)
--- a/pld.h
+++ b/pld.h
@@ -19,12 +19,26 @@ static int PLD_Private_strlen(const char *s)
 #define PLDLOG(message, name, err) PLD_Private_Log(message, name, err)\r
 #endif\r
 \r
+// Private dlopen function has platform-specific behavior when name == NULL\r
+// * Windows: Return GetModuleHandleA(NULL)\r
+// * POSIX: Return RTLD_NEXT\r
+//\r
+// Private dlsym function has platform-specific behavior when handle == NULL\r
+// * Windows: Use GetModuleHandleA(NULL) instead\r
+// * POSIX: Use RTLD_NEXT instead\r
 #ifdef _WIN32\r
 \r
 #include <windows.h>\r
+typedef FARPROC PLD_ProcAddress;\r
+typedef HMODULE PLD_LibHandle;\r
 typedef DWORD PLD_ErrCode;\r
 static void PLD_Private_Log(const char *, const char *, PLD_ErrCode);\r
 \r
+static PLD_ErrCode PLD_Private_ErrCode(void)\r
+{\r
+       return GetLastError();\r
+}\r
+\r
 static void PLD_Private_WriteString(const char *s)\r
 {\r
        DWORD dummy;\r
@@ -43,33 +57,21 @@ static void PLD_Private_FormatError(DWORD code, char *s, int len)
                (va_list *)&arg);\r
 }\r
 \r
-static HMODULE PLD_Private_LoadLibrary_wrapper(LPCSTR lpLibFileName)\r
+static PLD_LibHandle PLD_Private_dlopen(const char *name)\r
 {\r
-       HMODULE hModule = GetModuleHandleA(lpLibFileName);\r
-       if (hModule == NULL)\r
-               hModule = LoadLibraryA(lpLibFileName);\r
-       if (hModule == NULL)\r
-               PLDLOG("Failed to load library!", lpLibFileName, GetLastError());\r
-       return hModule;\r
+       PLD_LibHandle handle = GetModuleHandleA(name);\r
+       if (handle == NULL)\r
+               handle = LoadLibraryA(name);\r
+       return handle;\r
 }\r
 \r
-static FARPROC PLD_Private_GetProcAddress_wrapper(HMODULE hModule, LPCSTR lpProcName)\r
+static PLD_ProcAddress PLD_Private_dlsym(PLD_LibHandle handle, const char *name)\r
 {\r
-       FARPROC lpProc = GetProcAddress(hModule, lpProcName);\r
-       if (lpProc == NULL)\r
-               PLDLOG("Failed to load procedure!", lpProcName, GetLastError());\r
-       return lpProc;\r
+       if (handle == NULL)\r
+               handle = GetModuleHandleA(NULL);\r
+       return GetProcAddress(handle, name);\r
 }\r
 \r
-#define PLD(name) \\r
-       static HMODULE PLDH(void) { \\r
-               static HMODULE hModule = NULL; \\r
-               if (hModule == NULL) hModule =  PLD_Private_LoadLibrary_wrapper(name); \\r
-               return hModule; \\r
-       } \\r
-\r
-#define PFN(name) ((PLDTYPEOF(&name))PLD_Private_GetProcAddress_wrapper(PLDH(), #name))\r
-\r
 #else\r
 \r
 #define _GNU_SOURCE\r
@@ -79,9 +81,16 @@ static FARPROC PLD_Private_GetProcAddress_wrapper(HMODULE hModule, LPCSTR lpProc
 #include <string.h>\r
 #include <dlfcn.h>\r
 \r
+typedef void *PLD_ProcAddress;\r
+typedef void *PLD_LibHandle;\r
 typedef intptr_t PLD_ErrCode;\r
 static void PLD_Private_Log(const char *, const char *, PLD_ErrCode);\r
 \r
+static PLD_ErrCode PLD_Private_ErrCode(void)\r
+{\r
+       return (intptr_t)dlerror();\r
+}\r
+\r
 static void PLD_Private_WriteString(const char *s)\r
 {\r
        write(2, s, PLD_Private_strlen(s));\r
@@ -93,36 +102,79 @@ static void PLD_Private_FormatError(intptr_t code, char *s, int len)
        strncat(s, (const char *)code, len);\r
 }\r
 \r
-static void *PLD_Private_dlopen_wrapper(const char *name)\r
+static PLD_LibHandle PLD_Private_dlopen(const char *name)\r
 {\r
        if (name == NULL)\r
-               return (void *)RTLD_NEXT;\r
+               return (PLD_LibHandle)RTLD_NEXT;\r
        void *handle = dlopen(name, RTLD_NOLOAD);\r
        if (handle == NULL)\r
                handle = dlopen(name, RTLD_LAZY);\r
-       if (handle == NULL)\r
-               PLDLOG("Failed to load library!", name, (intptr_t)dlerror());\r
        return handle;\r
 }\r
 \r
-static void *PLD_Private_dlsym_wrapper(void *handle, const char *name)\r
+static PLD_ProcAddress PLD_Private_dlsym(PLD_LibHandle handle, const char *name)\r
 {\r
-       void *sym = dlsym(handle, name);\r
+       if (handle == NULL)\r
+               handle = (PLD_LibHandle)RTLD_NEXT;\r
+       return dlsym(handle, name);\r
+}\r
+\r
+\r
+#endif\r
+\r
+static PLD_ProcAddress PLD_Private_dlsym_wrapper(PLD_LibHandle handle, const char *name)\r
+{\r
+       if (name == NULL) {\r
+               PLDLOG("NULL name provided for procedure!", "???", 0);\r
+               return NULL;\r
+       }\r
+       if (handle == NULL)\r
+               handle = PLD_Private_dlopen(NULL);\r
+       PLD_ProcAddress sym = PLD_Private_dlsym(handle, name);\r
        if (sym == NULL)\r
-               PLDLOG("Failed to load procedure!", name, (intptr_t)dlerror());\r
+               PLDLOG("Failed to load procedure!", name, PLD_Private_ErrCode());\r
        return sym;\r
 }\r
 \r
+static PLD_LibHandle PLD_Private_dlopen_wrapper(const char *name)\r
+{\r
+       // On Linux, RTLD_NEXT is NULL, so check if the\r
+       // name is NULL before concluding it's an error\r
+       PLD_LibHandle handle = PLD_Private_dlopen(name);\r
+       if (handle == NULL && name != NULL)\r
+               PLDLOG("Failed to load library!", name, PLD_Private_ErrCode());\r
+       return handle;\r
+}\r
+\r
+\r
 #define PLD(name) \\r
-       static void *PLDH(void) { \\r
-               static void *handle = NULL; \\r
+       PLD_LibHandle PLDH(void) { \\r
+               static PLD_LibHandle handle = NULL; \\r
                if (handle == NULL) handle = PLD_Private_dlopen_wrapper(name); \\r
                return handle; \\r
        } \\r
 \r
-#define PFN(name) ((PLDTYPEOF(&name))PLD_Private_dlsym_wrapper(PLDH(), #name))\r
+// For importing by ordinal on Windows or just using\r
+// another name in a library for whatever reason\r
+#define PFNALT(name, alt) ((PLDTYPEOF(&name))PLD_Private_dlsym_wrapper(PLDH(), alt))\r
+#define PFN(name) PFNALT(name, #name)\r
 \r
+// When code is 0, output nothing\r
+static void PLD_Private_FormatError_wrapper(intptr_t code, char *s, int len) {\r
+       // Add an extra newline only on Windows to mimic FormatMessageA\r
+       if (code == 0) {\r
+#ifdef _WIN32\r
+               s[0] = '\r';\r
+               s[1] = '\n';\r
+               s[2] = 0;\r
+#else\r
+               *s = 0;\r
 #endif\r
+               return;\r
+       }\r
+       PLD_Private_FormatError(code, s, len);\r
+}\r
+\r
 \r
 static void PLD_Private_Log(const char *message, const char *name, PLD_ErrCode err)\r
 {\r
@@ -135,7 +187,7 @@ static void PLD_Private_Log(const char *message, const char *name, PLD_ErrCode e
        PLD_Private_WriteString("\n");\r
 #endif\r
        char errtext[256];\r
-       PLD_Private_FormatError(err, errtext, sizeof(errtext));\r
+       PLD_Private_FormatError_wrapper(err, errtext, sizeof(errtext));\r
        PLD_Private_WriteString(errtext);\r
 \r
        // An extra newline because dlerror doesn't append one\r