aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2013-02-11 20:38:17 +0200
committerArnold D. Robbins <arnold@skeeve.com>2013-02-11 20:38:17 +0200
commitba18cde06b1c80426fdc9d5e6dff793d44bb0bc8 (patch)
tree330fcce0c84ae08356d5b4203ade74c5c3a928be
parenta9b8d46450240c20c362c05d2d79c92a04807339 (diff)
downloadegawk-ba18cde06b1c80426fdc9d5e6dff793d44bb0bc8.tar.gz
egawk-ba18cde06b1c80426fdc9d5e6dff793d44bb0bc8.tar.bz2
egawk-ba18cde06b1c80426fdc9d5e6dff793d44bb0bc8.zip
Enable dynamic extensions for MinGW.
-rw-r--r--pc/ChangeLog14
-rw-r--r--pc/Makefile8
-rw-r--r--pc/config.sed4
-rw-r--r--pc/gawkmisc.pc86
4 files changed, 110 insertions, 2 deletions
diff --git a/pc/ChangeLog b/pc/ChangeLog
index 15ce56ec..e7378b5f 100644
--- a/pc/ChangeLog
+++ b/pc/ChangeLog
@@ -1,3 +1,17 @@
+2013-02-09 Eli Zaretskii <eliz@gnu.org>
+
+ * gawkmisc.pc (dlopen, dlerror, dlclose, dlsym) [DYNAMIC]: New
+ functions for _WIN32 build.
+
+ * dlfcn.h: New file.
+
+ * Makefile (pkgextensiondir, DEFLIBPATH, SHLIBEXT): New variables.
+ (AWKOBJS4): New sub-list of object files; add gawkapi$O.
+ (ALLOBJS): Include AWKOBJS4.
+ (CFLAGS): Add -DDEFLIBPATH=$(DEFLIBPATH) -DSHLIBEXT=$(SHLIBEXT).
+
+ * config.sed (DYNAMIC): Define for _WIN32 build.
+
2013-02-07 Scott Deifik <scottd.mail@sbcglobal.net>
* Makefile.tst: Sync with mainline.
diff --git a/pc/Makefile b/pc/Makefile
index 52354f34..71197c53 100644
--- a/pc/Makefile
+++ b/pc/Makefile
@@ -68,6 +68,9 @@ MAK = $(MAKE) $(MAKEFILE)
#prefix =
prefix = c:/gnu
pkgdatadir = $(prefix)/lib/awk
+pkgextensiondir = $(prefix)/lib/gawk
+DEFLIBPATH = "\"$(pkgextensiondir)\""
+SHLIBEXT = "\"dll\""
#
# Define the install method. Method 1 is Unix-like (and requires cat
# and cp); method 2 uses gawk and batch files.
@@ -183,13 +186,14 @@ BIND = EMPTY
PBIND = EMPTY
EMPTY=
-CFLAGS = $(CF) -DGAWK -I. -DHAVE_CONFIG_H
+CFLAGS = $(CF) -DGAWK -I. -DHAVE_CONFIG_H -DDEFLIBPATH=$(DEFLIBPATH) -DSHLIBEXT=$(SHLIBEXT)
# object files
AWKOBJS1 = array$O builtin$O eval$O field$O floatcomp$O gawkmisc$O io$O main$O
AWKOBJS2 = ext$O msg$O node$O profile$O re$O replace$O version$O symbol$O
AWKOBJS3 = debug$O cint_array$O int_array$O mpfr$O str_array$O command$O
-AWKOBJS = $(AWKOBJS1) $(AWKOBJS2) $(AWKOBJS3)
+AWKOBJS4 = gawkapi$O
+AWKOBJS = $(AWKOBJS1) $(AWKOBJS2) $(AWKOBJS3) $(AWKOBJS4)
ALLOBJS = $(AWKOBJS) awkgram$O getid$O $(OBJ)
diff --git a/pc/config.sed b/pc/config.sed
index 5e57e82b..6f76f43e 100644
--- a/pc/config.sed
+++ b/pc/config.sed
@@ -26,6 +26,10 @@
/configh\.in/a\
/* pc/config.h. Generated automatically by pc/config.sed. */
+/^#undef DYNAMIC$\c
+#ifdef _WIN32\
+#define DYNAMIC 1\
+#endif
s/^#undef GETPGRP_VOID *$/#define GETPGRP_VOID 1/
s/^#undef GETGROUPS_T *$/#define GETGROUPS_T gid_t/
/^#undef GETPGRP_VOID$/c\
diff --git a/pc/gawkmisc.pc b/pc/gawkmisc.pc
index e44191cd..5e412d71 100644
--- a/pc/gawkmisc.pc
+++ b/pc/gawkmisc.pc
@@ -609,6 +609,92 @@ int execvp(const char *file, const char *const *argv)
return -1;
}
+
+#ifdef DYNAMIC
+
+#include <dlfcn.h>
+
+static DWORD last_err;
+
+void *
+dlopen (const char *file, int mode)
+{
+ char dllfn[MAX_PATH], *p;
+ HANDLE dllhandle;
+
+ if (mode != RTLD_LAZY)
+ {
+ errno = EINVAL;
+ last_err = ERROR_INVALID_PARAMETER;
+ return NULL;
+ }
+
+ /* MSDN says to be sure to use backslashes in the DLL file name. */
+ strcpy (dllfn, file);
+ for (p = dllfn; *p; p++)
+ if (*p == '/')
+ *p = '\\';
+
+ dllhandle = LoadLibrary (dllfn);
+ if (!dllhandle)
+ last_err = GetLastError ();
+
+ return dllhandle;
+}
+
+char *
+dlerror (void)
+{
+ static char errbuf[1024];
+ DWORD ret;
+
+ if (!last_err)
+ return NULL;
+
+ ret = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, last_err, 0, errbuf, sizeof (errbuf), NULL);
+ while (ret > 0 && (errbuf[ret - 1] == '\n' || errbuf[ret - 1] == '\r'))
+ --ret;
+
+ errbuf[ret] = '\0';
+ if (!ret)
+ sprintf (errbuf, "Error code %lu", last_err);
+
+ last_err = 0;
+ return errbuf;
+}
+
+int
+dlclose (void *handle)
+{
+ if (!handle || handle == INVALID_HANDLE_VALUE)
+ return -1;
+ if (!FreeLibrary (handle))
+ return -1;
+
+ return 0;
+}
+
+void *
+dlsym (void *handle, const char *name)
+{
+ FARPROC addr = NULL;
+
+ if (!handle || handle == INVALID_HANDLE_VALUE)
+ {
+ last_err = ERROR_INVALID_PARAMETER;
+ return NULL;
+ }
+
+ addr = GetProcAddress (handle, name);
+ if (!addr)
+ last_err = GetLastError ();
+
+ return (void *)addr;
+}
+#endif
+
#endif /* __MINGW32__ */
#ifdef __DJGPP__