#ifndef COOL_PLD_H\r
#define COOL_PLD_H\r
\r
+// Always define GNU sources\r
+#ifndef _GNU_SOURCE\r
+#define _GNU_SOURCE\r
+#endif\r
+\r
#ifdef _MSC_VER\r
#define PLDTYPEOF(x) __typeof__(x)\r
#else\r
#define PLDTYPEOF(x) typeof(x)\r
#endif\r
\r
+// Allow users to provide their own logging\r
+// This may also help to reduce headers and\r
+// imports to allow for more easy preloads.\r
+#ifndef PLDLOG\r
+#define PLD_PRIVATE_LOG_INCLUDED\r
static int PLD_Private_strlen(const char *s)\r
{\r
int len = 0;\r
return len - 1;\r
}\r
\r
-#ifndef PLDLOG\r
-#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
+static void *PLD_Private_ErrCode(void)\r
{\r
- return GetLastError();\r
+ return (void *)(DWORD_PTR)GetLastError();\r
}\r
-\r
static void PLD_Private_WriteString(const char *s)\r
{\r
DWORD dummy;\r
WriteFile(GetStdHandle(STD_ERROR_HANDLE), s, PLD_Private_strlen(s), &dummy, NULL);\r
}\r
-\r
-static void PLD_Private_FormatError(DWORD code, char *s, int len)\r
+static void PLD_Private_FormatError(void *code, char *s, int len, const char *name)\r
{\r
- DWORD_PTR arg = (DWORD_PTR)s;\r
+ DWORD_PTR arg = (DWORD_PTR)name;\r
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,\r
NULL,\r
- code,\r
+ (DWORD_PTR)code,\r
MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),\r
s,\r
len,\r
(va_list *)&arg);\r
}\r
+#else // _WIN32\r
+#include <unistd.h>\r
+#include <dlfcn.h>\r
+static void *PLD_Private_ErrCode(void)\r
+{\r
+ return dlerror();\r
+}\r
+static void PLD_Private_WriteString(const char *s)\r
+{\r
+ write(2, s, PLD_Private_strlen(s));\r
+}\r
+static void PLD_Private_FormatError(void *code, char *s, int len, const char *name)\r
+{\r
+ (void)name;\r
+ if (len == 0)\r
+ return;\r
+ const char *dlerr = (const char *)code;\r
+ while (--len && (*s++ = *dlerr++))\r
+ ;\r
+ *s = 0;\r
+}\r
+#endif // _WIN32\r
+\r
+// When code is 0, output nothing\r
+static void PLD_Private_FormatError_wrapper(void *code, char *s, int len, const char *name) {\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 // _WIN32\r
+ return;\r
+ }\r
+ PLD_Private_FormatError(code, s, len, name);\r
+}\r
+\r
+\r
+static void PLD_Private_Log(const char *message, const char *name, void *err)\r
+{\r
+ PLD_Private_WriteString(message);\r
+ PLD_Private_WriteString(" ");\r
+ PLD_Private_WriteString(name);\r
+#ifdef _WIN32\r
+ PLD_Private_WriteString("\r\n");\r
+#else\r
+ PLD_Private_WriteString("\n");\r
+#endif // _WIN32\r
+ char errtext[256];\r
+ PLD_Private_FormatError_wrapper(err, errtext, sizeof(errtext), name);\r
+ PLD_Private_WriteString(errtext);\r
+\r
+ // An extra newline because dlerror doesn't append one\r
+#ifndef _WIN32\r
+ PLD_Private_WriteString("\n");\r
+#endif\r
+}\r
+\r
+#define PLDLOG(message, name, err) PLD_Private_Log(message, name, err)\r
+#endif // PLDLOG\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
+// Optimization to not include Windows twice\r
+// when defining our own PLDLOG\r
+#ifndef PLD_PRIVATE_LOG_INCLUDED\r
+#include <windows.h>\r
+#endif\r
+\r
+typedef HMODULE PLD_LibHandle;\r
+typedef FARPROC PLD_ProcAddress;\r
\r
static PLD_LibHandle PLD_Private_dlopen(const char *name)\r
{\r
return GetProcAddress(handle, name);\r
}\r
\r
-#else\r
+#else // _WIN32\r
\r
-#define _GNU_SOURCE\r
-#include <unistd.h>\r
-#include <errno.h>\r
-#include <stdint.h>\r
-#include <string.h>\r
+#ifndef PLD_PRIVATE_LOG_INCLUDED\r
#include <dlfcn.h>\r
+#endif\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
-}\r
-\r
-static void PLD_Private_FormatError(intptr_t code, char *s, int len)\r
-{\r
- *s = 0;\r
- strncat(s, (const char *)code, len);\r
-}\r
+typedef void *PLD_ProcAddress;\r
\r
static PLD_LibHandle PLD_Private_dlopen(const char *name)\r
{\r
return dlsym(handle, name);\r
}\r
\r
-\r
-#endif\r
+#endif // _WIN32\r
\r
static PLD_ProcAddress PLD_Private_dlsym_wrapper(PLD_LibHandle handle, const char *name)\r
{\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
- PLD_Private_WriteString(message);\r
- PLD_Private_WriteString(" ");\r
- PLD_Private_WriteString(name);\r
-#ifdef _WIN32\r
- PLD_Private_WriteString("\r\n");\r
-#else\r
- PLD_Private_WriteString("\n");\r
-#endif\r
- char errtext[256];\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
-#ifndef _WIN32\r
- PLD_Private_WriteString("\n");\r
-#endif\r
-}\r
-\r
#endif // COOL_PLD_H\r