From 1f21335d77ba21a17d4aafbc236b50418322b885 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 28 Jul 2000 10:16:56 -0700
Subject: [PATCH] JUMBOPATCH: dynamic loading now works on Win* !!!! (somewhat
 experimental :)

Rev: src/.cvsignore:1.24
Rev: src/Makefile.in:1.198
Rev: src/aclocal.m4:1.17
Rev: src/array.c:1.79
Rev: src/array.h:1.22
Rev: src/backend.c:1.53
Rev: src/backend.h:1.9
Rev: src/bignum.c:1.17
Rev: src/bignum.h:1.14
Rev: src/builtin_functions.c:1.293
Rev: src/builtin_functions.h:1.14
Rev: src/callback.c:1.20
Rev: src/configure.in:1.387
Rev: src/constants.c:1.22
Rev: src/dynamic_buffer.c:1.10
Rev: src/dynamic_load.c:1.41
Rev: src/error.c:1.56
Rev: src/error.h:1.46
Rev: src/fd_control.c:1.32
Rev: src/fdlib.c:1.37
Rev: src/fdlib.h:1.34
Rev: src/fsort.c:1.13
Rev: src/fsort_template.h:1.7
Rev: src/gc.c:1.110
Rev: src/gc.h:1.57
Rev: src/global.h:1.44
Rev: src/interpret.c:1.158
Rev: src/interpret.h:1.52
Rev: src/main.c:1.94
Rev: src/mapping.c:1.94
Rev: src/mapping.h:1.28
Rev: src/module_magic.h:1.1
Rev: src/module_support.c:1.34
Rev: src/module_support.h:1.7
Rev: src/multiset.c:1.26
Rev: src/object.c:1.137
Rev: src/object.h:1.50
Rev: src/opcodes.c:1.78
Rev: src/operators.c:1.93
Rev: src/operators.h:1.8
Rev: src/pike_macros.h:1.17
Rev: src/pike_memory.c:1.71
Rev: src/pike_memory.h:1.14
Rev: src/pike_types.c:1.132
Rev: src/port.c:1.28
Rev: src/precompile.sh.in:1.2
Rev: src/program.c:1.252
Rev: src/program.h:1.97
Rev: src/signal_handler.c:1.173
Rev: src/stralloc.c:1.85
Rev: src/stralloc.h:1.42
Rev: src/stuff.c:1.11
Rev: src/svalue.c:1.85
Rev: src/svalue.h:1.62
Rev: src/testsuite.in:1.316
Rev: src/threads.c:1.133
Rev: src/threads.h:1.99
---
 src/.cvsignore          |   1 +
 src/.gitignore          |   1 +
 src/Makefile.in         | 147 +++++++++++++++++++++-----------------
 src/aclocal.m4          |   4 +-
 src/array.c             | 100 +++++++++++++-------------
 src/array.h             |  96 ++++++++++++-------------
 src/backend.c           |  30 ++++----
 src/backend.h           |   3 +-
 src/bignum.c            |  24 +++----
 src/bignum.h            |   3 +
 src/builtin_functions.c | 154 ++++++++++++++++++++--------------------
 src/builtin_functions.h | 154 ++++++++++++++++++++--------------------
 src/callback.c          |   8 +--
 src/configure.in        |  48 ++++++++-----
 src/constants.c         |  16 ++---
 src/dynamic_buffer.c    |  38 +++++-----
 src/dynamic_load.c      |  16 ++++-
 src/error.c             |  38 +++++-----
 src/error.h             |  22 +++---
 src/fd_control.c        |   8 +--
 src/fdlib.c             |  46 ++++++------
 src/fdlib.h             |  51 +++++++------
 src/fsort.c             |   3 +-
 src/fsort_template.h    |   7 +-
 src/gc.c                |   6 +-
 src/gc.h                |  27 ++++---
 src/global.h            |  17 ++++-
 src/interpret.c         |  28 ++++----
 src/interpret.h         |  36 +++++-----
 src/main.c              |  24 +++----
 src/mapping.c           |  66 ++++++++---------
 src/mapping.h           |   4 +-
 src/module_magic.h      |  33 +++++++++
 src/module_support.c    |  10 +--
 src/module_support.h    |  13 ++--
 src/multiset.c          |  28 ++++----
 src/object.c            |  40 +++++------
 src/object.h            |  40 +++++------
 src/opcodes.c           |   6 +-
 src/operators.c         |  66 ++++++++---------
 src/operators.h         |  58 +++++++--------
 src/pike_macros.h       |   5 +-
 src/pike_memory.c       |  29 +++++++-
 src/pike_memory.h       |  36 +++++-----
 src/pike_types.c        |  32 ++++-----
 src/port.c              |  36 +++++-----
 src/precompile.sh.in    |  23 ++++--
 src/program.c           |  66 ++++++++---------
 src/program.h           |  57 ++++++++-------
 src/signal_handler.c    |   4 +-
 src/stralloc.c          | 136 +++++++++++++++++------------------
 src/stralloc.h          | 138 ++++++++++++++++++-----------------
 src/stuff.c             |  12 ++--
 src/svalue.c            |  52 +++++++-------
 src/svalue.h            |  61 ++++++++--------
 src/testsuite.in        |   4 +-
 src/threads.c           |  39 +++++-----
 src/threads.h           |  10 +--
 58 files changed, 1211 insertions(+), 1049 deletions(-)
 create mode 100644 src/module_magic.h

diff --git a/src/.cvsignore b/src/.cvsignore
index 91514111f3..474b176e14 100644
--- a/src/.cvsignore
+++ b/src/.cvsignore
@@ -21,6 +21,7 @@ machine.h
 machine.h.in
 make_variables
 master.pike
+module_magic.c
 peep_engine.c
 pike
 pike.tmp
diff --git a/src/.gitignore b/src/.gitignore
index 19af3a805a..a505908062 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -21,6 +21,7 @@
 /machine.h.in
 /make_variables
 /master.pike
+/module_magic.c
 /peep_engine.c
 /pike
 /pike.tmp
diff --git a/src/Makefile.in b/src/Makefile.in
index 787ae8f471..d5c08c339f 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile.in,v 1.197 2000/07/26 16:59:11 nilsson Exp $
+# $Id: Makefile.in,v 1.198 2000/07/28 17:16:54 hubbe Exp $
 #
 
 # This line is needed on some machines.
@@ -143,6 +143,15 @@ OBJ= \
  builtin.o \
  svalue.o @EXTRA_OBJS@
 
+MODULE_REQUIREMENTS= \
+  machine.h \
+  global.h \
+  modules/static_module_makefile \
+  modules/dynamic_module_makefile \
+  $(SRCDIR)/language.h \
+  lib \
+  master.pike @EXTRA_MODULE_REQUIREMENTS@
+  
 
 DEPEND= \
  $(SRCDIR)/language.c \
@@ -267,7 +276,17 @@ hilfe: $(TMP_BINDIR)/hilfe Makefile
 	@echo "Done."
 
 
-.SUFFIXES: .c .o .cmod
+.SUFFIXES: .c .o .cmod .pp .protos
+
+.c.pp:
+	$(CPP) $(PREFLAGS) -DPMOD_EXPORT=PMOD_EXPORT -DPMOD_PROTO=PMOD_PROTO "$<" >"$@"
+
+.c.protos:
+	./precompile.sh fake_dynamic_load.pike "$@" --cpp --protos $(CPP) $(PREFLAGS) -DPMOD_EXPORT=PMOD_EXPORT -DPMOD_PROTO=PMOD_PROTO "$<"
+
+.h.pph:
+	$(CPP) $(PREFLAGS) -DPMOD_EXPORT=PMOD_EXPORT -DPMOD_PROTO=PMOD_PROTO "$<" >"$@"
+
 
 # Several optimizers have problems with interpret.c
 # First try compiling with optimization and if that doesn't work, without.
@@ -289,7 +308,7 @@ hilfe: $(TMP_BINDIR)/hilfe Makefile
 # -Hubbe
 #
 .cmod.c:
-	./precompile.sh "$<" "$@"
+	./precompile.sh precompile.pike "$@" "$<"
 
 force :
 	@:
@@ -312,7 +331,7 @@ install_interactive: pike hilfe pike-module aclocal
 
 # tidy up a bit
 tidy:
-	-rm -f *.o core y.output y.tab.c y.tab.h
+	-rm -f *.o *.pp *.protos core y.output y.tab.c y.tab.h
 	-rm -f $(TMP_BINDIR)/core *.o *.i *.i~ testsuite
 
 # make clean
@@ -322,7 +341,7 @@ clean: tidy
 	-rm -rf test-install test-pike
 	-rm -f TAGS tags yacc.acts yacc.debug yacc.tmp *.debug.log a.out
 	-rm -f hilfe master.pike compiler-warnings
-	-rm -f tpike stamp-tpike-predep
+	-rm -f tpike stamp-tpike-predep import-stamp
 	-find lib/modules/ -type f -name '*.so_pure*' -exec rm -f \{\} \;
 #	-rm -f lib/master.pike
 
@@ -543,7 +562,7 @@ lobotomize_crypto:
 #
 # Pike internal targets
 #
-module_objects: machine.h global.h modules/static_module_makefile modules/dynamic_module_makefile $(SRCDIR)/language.h lib master.pike
+module_objects: $(MODULE_REQUIREMENTS)
 	@( cd modules ; rm remake >/dev/null 2>&1 || : ; \
 	   $(MAKE) $(MAKE_PARALLEL) $(MAKE_FLAGS) || \
 	     ( test -f remake && $(MAKE) $(MAKE_PARALLEL) $(MAKE_FLAGS) ) ) || exit $$?
@@ -576,7 +595,7 @@ $(SRCDIR)/builtin.c: $(SRCDIR)/builtin.cmod ./precompile.sh $(TMP_BINDIR)/precom
 # Internal testing target
 run_yacc: $(SRCDIR)/language.c
 
-modules/modlist.h:
+modules/modlist.h: $(MODULE_REQUIREMENTS)
 	( cd modules && $(MAKE) $(MAKE_FLAGS) )
 
 modules/modlist_headers.h: modules/modlist.h
@@ -633,65 +652,61 @@ uncompress_header: $(SRCDIR)/uncompressor.c header_uncompress
 	test "`wc -c header_uncompress|sed 's/[^0-9]//g'`" = "`wc -c uncompress_header|sed 's/[^0-9]//g'`"
 
 HFILES=						\
-  operators.h					\
-  array.h					\
-  fd_control.h					\
-  peep.h					\
-  backend.h					\
-  fdlib.h					\
-  pike_macros.h					\
-  bignum.h					\
-  fsort.h					\
-  pike_memory.h					\
-  block_alloc.h					\
-  pike_types.h					\
-  block_alloc_h.h				\
-  gc.h						\
-  port.h					\
-  builtin_functions.h				\
-  global.h					\
-  callback.h					\
-  hashtable.h					\
-  program.h					\
-  interpret.h					\
-  program_id.h					\
-  constants.h					\
-  language.h					\
-  queue.h					\
-  cpp.h						\
-  las.h						\
-  rusage.h					\
-  cyclic.h					\
-  lex.h						\
-  security.h					\
-  dmalloc.h					\
-  signal_handler.h				\
-  docode.h					\
-  main.h					\
-  stralloc.h					\
-  mapping.h					\
-  stuff.h					\
-  dynamic_buffer.h				\
-  module.h					\
-  svalue.h					\
-  dynamic_load.h				\
-  module_support.h				\
-  threads.h					\
-  efun.h					\
-  multiset.h					\
-  time_stuff.h					\
-  encode.h					\
-  object.h					\
-  error.h					\
-  opcodes.h					\
-  version.h
-
-
-export_functions.c: $(HFILES)
-	$(TMP_BINDIR)/fake_dynamic_load.pike --cpp='$(CPP)' $(HFILES) 
-
-import_functions.h: export_functions.h
-	@touch import_functions.h
+  operators.protos					\
+  array.protos					\
+  fd_control.protos					\
+  backend.protos					\
+  fdlib.protos					\
+  bignum.protos					\
+  fsort.protos					\
+  pike_memory.protos					\
+  pike_types.protos					\
+  gc.protos						\
+  port.protos					\
+  builtin_functions_t.protos				\
+  callback.protos					\
+  hashtable.protos					\
+  program.protos					\
+  interpret.protos					\
+  constants.protos					\
+  language.protos					\
+  queue.protos					\
+  cpp.protos						\
+  las_t.protos						\
+  peep_t.protos                                     \
+  rusage.protos					\
+  cyclic.protos					\
+  lex.protos						\
+  security.protos					\
+  signal_handler.protos				\
+  docode.protos					\
+  main.protos					\
+  stralloc.protos					\
+  mapping.protos					\
+  stuff.protos					\
+  dynamic_buffer.protos				\
+  svalue.protos					\
+  dynamic_load.protos				\
+  module_support.protos				\
+  threads.protos					\
+  multiset.protos					\
+  encode.protos					\
+  object.protos					\
+  error.protos					\
+  opcodes.protos					\
+  version.protos                                    \
+  builtin.protos
+
+import-stamp: $(HFILES) precompile.sh
+	@./precompile.sh fake_dynamic_load.pike import_functions.tmp $(HFILES)
+	@cmp import_functions.tmp import_functions.h >/dev/null || mv import_functions.tmp import_functions.h
+	@echo hej >import-stamp
+
+import_functions.h: import-stamp
+	test -f import-stamp || ( rm import-stamp ; $(MAKE) import-stamp )
+
+export_functions.c: import_functions.h
+	touch export_functions.c
 
 @dependencies@
 
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index 0fa95a0e4d..4a3e908681 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -104,7 +104,7 @@ rm -rf conftest*])
 
 define([AC_LOW_MODULE_INIT],
 [
-# $Id: aclocal.m4,v 1.16 1999/11/18 07:58:19 hubbe Exp $
+# $Id: aclocal.m4,v 1.17 2000/07/28 17:16:54 hubbe Exp $
 
 MY_AC_PROG_CC
 
@@ -183,6 +183,8 @@ pushdef([AC_OUTPUT],
   AC_SUBST(OPTIMIZE)
   export WARN
   AC_SUBST(WARN)
+  export CCSHARED
+  AC_SUBST(CCSHARED)
 
 ifdef([PIKE_INCLUDE_PATH],
 [
diff --git a/src/array.c b/src/array.c
index 77a8f64ae3..ca59204d73 100644
--- a/src/array.c
+++ b/src/array.c
@@ -23,9 +23,9 @@
 #include "stuff.h"
 #include "bignum.h"
 
-RCSID("$Id: array.c,v 1.78 2000/07/18 05:48:20 mast Exp $");
+RCSID("$Id: array.c,v 1.79 2000/07/28 17:16:54 hubbe Exp $");
 
-struct array empty_array=
+PMOD_EXPORT struct array empty_array=
 {
   1,                     /* Never free */
 #ifdef PIKE_SECURITY
@@ -48,7 +48,7 @@ static struct array *gc_mark_array_pos = 0;
  * NOTE: the new array have zero references
  */
 
-struct array *low_allocate_array(INT32 size,INT32 extra_space)
+PMOD_EXPORT struct array *low_allocate_array(INT32 size,INT32 extra_space)
 {
   struct array *v;
   INT32 e;
@@ -109,7 +109,7 @@ static void array_free_no_free(struct array *v)
 /*
  * Free an array, call this when the array has zero references
  */
-void really_free_array(struct array *v)
+PMOD_EXPORT void really_free_array(struct array *v)
 {
 #ifdef PIKE_DEBUG
   if(v == & empty_array)
@@ -127,7 +127,7 @@ void really_free_array(struct array *v)
   array_free_no_free(v);
 }
 
-void do_free_array(struct array *a)
+PMOD_EXPORT void do_free_array(struct array *a)
 {
   if (a)
     free_array(a);
@@ -136,7 +136,7 @@ void do_free_array(struct array *a)
 /*
  * Extract an svalue from an array
  */
-void array_index_no_free(struct svalue *s,struct array *v,INT32 index)
+PMOD_EXPORT void array_index_no_free(struct svalue *s,struct array *v,INT32 index)
 {
 #ifdef PIKE_DEBUG
   if(index<0 || index>=v->size)
@@ -149,7 +149,7 @@ void array_index_no_free(struct svalue *s,struct array *v,INT32 index)
 /*
  * Extract an svalue from an array
  */
-void array_index(struct svalue *s,struct array *v,INT32 index)
+PMOD_EXPORT void array_index(struct svalue *s,struct array *v,INT32 index)
 {
 #ifdef PIKE_DEBUG
   if(index<0 || index>=v->size)
@@ -161,7 +161,7 @@ void array_index(struct svalue *s,struct array *v,INT32 index)
   free_array(v);
 }
 
-void simple_array_index_no_free(struct svalue *s,
+PMOD_EXPORT void simple_array_index_no_free(struct svalue *s,
 				struct array *a,struct svalue *ind)
 {
   INT32 i;
@@ -208,7 +208,7 @@ void simple_array_index_no_free(struct svalue *s,
 /*
  * Extract an svalue from an array
  */
-void array_free_index(struct array *v,INT32 index)
+PMOD_EXPORT void array_free_index(struct array *v,INT32 index)
 {
 #ifdef PIKE_DEBUG
   if(index<0 || index>=v->size)
@@ -221,7 +221,7 @@ void array_free_index(struct array *v,INT32 index)
 /*
  * Set an index in an array
  */
-void array_set_index(struct array *v,INT32 index, struct svalue *s)
+PMOD_EXPORT void array_set_index(struct array *v,INT32 index, struct svalue *s)
 {
 #ifdef PIKE_DEBUG
   if(index<0 || index>v->size)
@@ -237,7 +237,7 @@ void array_set_index(struct array *v,INT32 index, struct svalue *s)
 }
 
 
-void simple_set_index(struct array *a,struct svalue *ind,struct svalue *s)
+PMOD_EXPORT void simple_set_index(struct array *a,struct svalue *ind,struct svalue *s)
 {
   INT32 i;
   switch (ind->type) {
@@ -281,7 +281,7 @@ void simple_set_index(struct array *a,struct svalue *ind,struct svalue *s)
 /*
  * Insert an svalue into an array, grow the array if nessesary
  */
-struct array *array_insert(struct array *v,struct svalue *s,INT32 index)
+PMOD_EXPORT struct array *array_insert(struct array *v,struct svalue *s,INT32 index)
 {
 #ifdef PIKE_DEBUG
   if(index<0 || index>v->size)
@@ -326,7 +326,7 @@ struct array *array_insert(struct array *v,struct svalue *s,INT32 index)
 /*
  * resize array, resize an array destructively
  */
-struct array *resize_array(struct array *a, INT32 size)
+PMOD_EXPORT struct array *resize_array(struct array *a, INT32 size)
 {
 #ifdef PIKE_DEBUG
   if(d_flag > 1)  array_check_type_field(a);
@@ -367,7 +367,7 @@ struct array *resize_array(struct array *a, INT32 size)
 /*
  * Shrink an array destructively
  */
-struct array *array_shrink(struct array *v,INT32 size)
+PMOD_EXPORT struct array *array_shrink(struct array *v,INT32 size)
 {
   struct array *a;
 
@@ -399,7 +399,7 @@ struct array *array_shrink(struct array *v,INT32 size)
 /*
  * Remove an index from an array and shrink the array
  */
-struct array *array_remove(struct array *v,INT32 index)
+PMOD_EXPORT struct array *array_remove(struct array *v,INT32 index)
 {
   struct array *a;
 
@@ -443,7 +443,7 @@ struct array *array_remove(struct array *v,INT32 index)
  * Search for in svalue in an array.
  * return the index if found, -1 otherwise
  */
-INT32 array_search(struct array *v, struct svalue *s,INT32 start)
+PMOD_EXPORT INT32 array_search(struct array *v, struct svalue *s,INT32 start)
 {
   INT32 e;
 #ifdef PIKE_DEBUG
@@ -485,7 +485,7 @@ INT32 array_search(struct array *v, struct svalue *s,INT32 start)
  * Slice a pice of an array (nondestructively)
  * return an array consisting of v[start..end-1]
  */
-struct array *slice_array(struct array *v,INT32 start,INT32 end)
+PMOD_EXPORT struct array *slice_array(struct array *v,INT32 start,INT32 end)
 {
   struct array *a;
 
@@ -514,7 +514,7 @@ struct array *slice_array(struct array *v,INT32 start,INT32 end)
  * Slice a pice of an array (nondestructively)
  * return an array consisting of v[start..end-1]
  */
-struct array *friendly_slice_array(struct array *v,INT32 start,INT32 end)
+PMOD_EXPORT struct array *friendly_slice_array(struct array *v,INT32 start,INT32 end)
 {
   struct array *a;
 
@@ -536,7 +536,7 @@ struct array *friendly_slice_array(struct array *v,INT32 start,INT32 end)
 /*
  * Copy an array
  */
-struct array *copy_array(struct array *v)
+PMOD_EXPORT struct array *copy_array(struct array *v)
 {
   struct array *a;
 
@@ -551,7 +551,7 @@ struct array *copy_array(struct array *v)
 /*
  * Clean an array from destructed objects
  */
-void check_array_for_destruct(struct array *v)
+PMOD_EXPORT void check_array_for_destruct(struct array *v)
 {
   int e;
   INT16 types;
@@ -588,7 +588,7 @@ void check_array_for_destruct(struct array *v)
  * it could be optimized to search out the object part with a binary 
  * search lookup if the array is mixed
  */
-INT32 array_find_destructed_object(struct array *v)
+PMOD_EXPORT INT32 array_find_destructed_object(struct array *v)
 {
   INT32 e;
   TYPE_FIELD types;
@@ -753,7 +753,7 @@ static int alpha_svalue_cmpfun(struct svalue *a, struct svalue *b)
 #undef ID
 
 
-void sort_array_destructively(struct array *v)
+PMOD_EXPORT void sort_array_destructively(struct array *v)
 {
   if(!v->size) return;
   low_sort_svalues(ITEM(v), ITEM(v)+v->size-1);
@@ -764,7 +764,7 @@ void sort_array_destructively(struct array *v)
 /*
  * return an 'order' suitable for making mappings and multisets
  */
-INT32 *get_set_order(struct array *a)
+PMOD_EXPORT INT32 *get_set_order(struct array *a)
 {
   return get_order(a, set_svalue_cmpfun);
 }
@@ -776,7 +776,7 @@ INT32 *get_set_order(struct array *a)
  * sorting rules for all the types that function allows in multiset
  * and mapping indices.
  */
-INT32 *get_switch_order(struct array *a)
+PMOD_EXPORT INT32 *get_switch_order(struct array *a)
 {
   return get_order(a, switch_svalue_cmpfun);
 }
@@ -785,7 +785,7 @@ INT32 *get_switch_order(struct array *a)
 /*
  * return an 'order' suitable for sorting.
  */
-INT32 *get_alpha_order(struct array *a)
+PMOD_EXPORT INT32 *get_alpha_order(struct array *a)
 {
   return get_order(a, alpha_svalue_cmpfun);
 }
@@ -852,7 +852,7 @@ INT32 switch_lookup(struct array *a, struct svalue *s)
 /*
  * reorganize an array in the order specifyed by 'order'
  */
-struct array *order_array(struct array *v, INT32 *order)
+PMOD_EXPORT struct array *order_array(struct array *v, INT32 *order)
 {
   reorder((char *)ITEM(v),v->size,sizeof(struct svalue),order);
   return v;
@@ -862,7 +862,7 @@ struct array *order_array(struct array *v, INT32 *order)
 /*
  * copy and reorganize an array
  */
-struct array *reorder_and_copy_array(struct array *v, INT32 *order)
+PMOD_EXPORT struct array *reorder_and_copy_array(struct array *v, INT32 *order)
 {
   INT32 e;
   struct array *ret;
@@ -876,7 +876,7 @@ struct array *reorder_and_copy_array(struct array *v, INT32 *order)
 }
 
 /* Maybe I should have a 'clean' flag for this computation */
-void array_fix_type_field(struct array *v)
+PMOD_EXPORT void array_fix_type_field(struct array *v)
 {
   int e;
   TYPE_FIELD t;
@@ -929,7 +929,7 @@ void array_check_type_field(struct array *v)
 }
 #endif
 
-struct array *compact_array(struct array *v) { return v; }
+PMOD_EXPORT struct array *compact_array(struct array *v) { return v; }
 
 /*
  * Get a pointer to the 'union anything' specified IF it is of the specified
@@ -1036,7 +1036,7 @@ INT32 * merge(struct array *a,struct array *b,INT32 opcode)
  * This routine merges two arrays in the order specified by 'zipper'
  * zipper normally produced by merge() above
  */
-struct array *array_zip(struct array *a, struct array *b,INT32 *zipper)
+PMOD_EXPORT struct array *array_zip(struct array *a, struct array *b,INT32 *zipper)
 {
   INT32 size,e;
   struct array *ret;
@@ -1056,7 +1056,7 @@ struct array *array_zip(struct array *a, struct array *b,INT32 *zipper)
   return ret;
 }
 
-struct array *add_arrays(struct svalue *argp, INT32 args)
+PMOD_EXPORT struct array *add_arrays(struct svalue *argp, INT32 args)
 {
   INT32 e, size;
   struct array *v;
@@ -1090,7 +1090,7 @@ struct array *add_arrays(struct svalue *argp, INT32 args)
   return v;
 }
 
-int array_equal_p(struct array *a, struct array *b, struct processing *p)
+PMOD_EXPORT int array_equal_p(struct array *a, struct array *b, struct processing *p)
 {
   struct processing curr;
   INT32 e;
@@ -1162,7 +1162,7 @@ static int array_merge_fun(INT32 *a, INT32 *b)
  * into ordered sets, merging them as sets and then rearranging the zipper
  * before zipping the sets together. 
  */
-struct array *merge_array_with_order(struct array *a, struct array *b,INT32 op)
+PMOD_EXPORT struct array *merge_array_with_order(struct array *a, struct array *b,INT32 op)
 {
   INT32 *zipper;
   struct array *tmpa,*tmpb,*ret;
@@ -1204,7 +1204,7 @@ struct array *merge_array_with_order(struct array *a, struct array *b,INT32 op)
  * into ordered sets, merging them as sets and then rearranging the zipper
  * before zipping the sets together. 
  */
-struct array *merge_array_without_order2(struct array *a, struct array *b,INT32 op)
+PMOD_EXPORT struct array *merge_array_without_order2(struct array *a, struct array *b,INT32 op)
 {
   INT32 ap,bp,i;
   struct svalue *arra,*arrb;
@@ -1277,7 +1277,7 @@ struct array *merge_array_without_order2(struct array *a, struct array *b,INT32
 /* merge two arrays without paying attention to the order
  * the elements has presently
  */
-struct array *merge_array_without_order(struct array *a,
+PMOD_EXPORT struct array *merge_array_without_order(struct array *a,
 					struct array *b,
 					INT32 op)
 {
@@ -1313,7 +1313,7 @@ struct array *merge_array_without_order(struct array *a,
 }
 
 /* subtract an array from another */
-struct array *subtract_arrays(struct array *a, struct array *b)
+PMOD_EXPORT struct array *subtract_arrays(struct array *a, struct array *b)
 {
 #ifdef PIKE_DEBUG
   if(d_flag > 1)
@@ -1337,7 +1337,7 @@ struct array *subtract_arrays(struct array *a, struct array *b)
 }
 
 /* and two arrays */
-struct array *and_arrays(struct array *a, struct array *b)
+PMOD_EXPORT struct array *and_arrays(struct array *a, struct array *b)
 {
 #ifdef PIKE_DEBUG
   if(d_flag > 1)
@@ -1449,7 +1449,7 @@ node *make_node_from_array(struct array *a)
   }
 }
 
-void push_array_items(struct array *a)
+PMOD_EXPORT void push_array_items(struct array *a)
 {
   check_stack(a->size);
   check_array_for_destruct(a);
@@ -1479,7 +1479,7 @@ void describe_array_low(struct array *a, struct processing *p, int indent)
   }
 }
 
-void simple_describe_array(struct array *a)
+PMOD_EXPORT void simple_describe_array(struct array *a)
 {
   char *s;
   init_buf();
@@ -1531,7 +1531,7 @@ void describe_array(struct array *a,struct processing *p,int indent)
   my_strcat("})");
 }
 
-struct array *aggregate_array(INT32 args)
+PMOD_EXPORT struct array *aggregate_array(INT32 args)
 {
   struct array *a;
 
@@ -1543,14 +1543,14 @@ struct array *aggregate_array(INT32 args)
   return a;
 }
 
-struct array *append_array(struct array *a, struct svalue *s)
+PMOD_EXPORT struct array *append_array(struct array *a, struct svalue *s)
 {
   a=resize_array(a,a->size+1);
   array_set_index(a, a->size-1, s);
   return a;
 }
 
-struct array *explode(struct pike_string *str,
+PMOD_EXPORT struct array *explode(struct pike_string *str,
 		       struct pike_string *del)
 {
   INT32 e;
@@ -1626,7 +1626,7 @@ struct array *explode(struct pike_string *str,
   return ret;
 }
 
-struct pike_string *implode(struct array *a,struct pike_string *del)
+PMOD_EXPORT struct pike_string *implode(struct array *a,struct pike_string *del)
 {
   INT32 len,e, inited;
   PCHARP r;
@@ -1669,7 +1669,7 @@ struct pike_string *implode(struct array *a,struct pike_string *del)
   return low_end_shared_string(ret);
 }
 
-struct array *copy_array_recursively(struct array *a,struct processing *p)
+PMOD_EXPORT struct array *copy_array_recursively(struct array *a,struct processing *p)
 {
   struct processing doing;
   struct array *ret;
@@ -1699,7 +1699,7 @@ struct array *copy_array_recursively(struct array *a,struct processing *p)
   return ret;
 }
 
-void apply_array(struct array *a, INT32 args)
+PMOD_EXPORT void apply_array(struct array *a, INT32 args)
 {
   INT32 e;
   struct array *ret;
@@ -1720,7 +1720,7 @@ void apply_array(struct array *a, INT32 args)
   push_array(ret);
 }
 
-struct array *reverse_array(struct array *a)
+PMOD_EXPORT struct array *reverse_array(struct array *a)
 {
   INT32 e;
   struct array *ret;
@@ -1732,7 +1732,7 @@ struct array *reverse_array(struct array *a)
   return ret;
 }
 
-void array_replace(struct array *a,
+PMOD_EXPORT void array_replace(struct array *a,
 		   struct svalue *from,
 		   struct svalue *to)
 {
@@ -1742,7 +1742,7 @@ void array_replace(struct array *a,
 }
 
 #ifdef PIKE_DEBUG
-void check_array(struct array *a)
+PMOD_EXPORT void check_array(struct array *a)
 {
   INT32 e;
 
@@ -2049,7 +2049,7 @@ void count_memory_in_arrays(INT32 *num_, INT32 *size_)
   *size_=size;
 }
 
-struct array *explode_array(struct array *a, struct array *b)
+PMOD_EXPORT struct array *explode_array(struct array *a, struct array *b)
 {
   INT32 e,d,q,start;
   struct array *tmp;
@@ -2092,7 +2092,7 @@ struct array *explode_array(struct array *a, struct array *b)
   return tmp;
 }
 
-struct array *implode_array(struct array *a, struct array *b)
+PMOD_EXPORT struct array *implode_array(struct array *a, struct array *b)
 {
   INT32 e,size;
   struct array *ret;
diff --git a/src/array.h b/src/array.h
index daa5a2d119..bab0f8bfed 100644
--- a/src/array.h
+++ b/src/array.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: array.h,v 1.21 2000/07/18 05:48:20 mast Exp $
+ * $Id: array.h,v 1.22 2000/07/28 17:16:54 hubbe Exp $
  */
 #ifndef ARRAY_H
 #define ARRAY_H
@@ -89,38 +89,38 @@ typedef short_cmpfun (*cmpfun_getter)(TYPE_T);
 
 
 /* Prototypes begin here */
-struct array *low_allocate_array(INT32 size,INT32 extra_space);
+PMOD_EXPORT struct array *low_allocate_array(INT32 size,INT32 extra_space);
 void really_free_array(struct array *v);
-void do_free_array(struct array *a);
-void array_index_no_free(struct svalue *s,struct array *v,INT32 index);
-void array_index(struct svalue *s,struct array *v,INT32 index);
-void simple_array_index_no_free(struct svalue *s,
+PMOD_EXPORT void do_free_array(struct array *a);
+PMOD_EXPORT void array_index_no_free(struct svalue *s,struct array *v,INT32 index);
+PMOD_EXPORT void array_index(struct svalue *s,struct array *v,INT32 index);
+PMOD_EXPORT void simple_array_index_no_free(struct svalue *s,
 				struct array *a,struct svalue *ind);
-void array_free_index(struct array *v,INT32 index);
-void array_set_index(struct array *v,INT32 index, struct svalue *s);
-void simple_set_index(struct array *a,struct svalue *ind,struct svalue *s);
-struct array *array_insert(struct array *v,struct svalue *s,INT32 index);
-struct array *resize_array(struct array *a, INT32 size);
-struct array *array_shrink(struct array *v,INT32 size);
-struct array *array_remove(struct array *v,INT32 index);
-INT32 array_search(struct array *v, struct svalue *s,INT32 start);
-struct array *slice_array(struct array *v,INT32 start,INT32 end);
-struct array *friendly_slice_array(struct array *v,INT32 start,INT32 end);
-struct array *copy_array(struct array *v);
-void check_array_for_destruct(struct array *v);
-INT32 array_find_destructed_object(struct array *v);
+PMOD_EXPORT void array_free_index(struct array *v,INT32 index);
+PMOD_EXPORT void array_set_index(struct array *v,INT32 index, struct svalue *s);
+PMOD_EXPORT void simple_set_index(struct array *a,struct svalue *ind,struct svalue *s);
+PMOD_EXPORT struct array *array_insert(struct array *v,struct svalue *s,INT32 index);
+PMOD_EXPORT struct array *resize_array(struct array *a, INT32 size);
+PMOD_EXPORT struct array *array_shrink(struct array *v,INT32 size);
+PMOD_EXPORT struct array *array_remove(struct array *v,INT32 index);
+PMOD_EXPORT INT32 array_search(struct array *v, struct svalue *s,INT32 start);
+PMOD_EXPORT struct array *slice_array(struct array *v,INT32 start,INT32 end);
+PMOD_EXPORT struct array *friendly_slice_array(struct array *v,INT32 start,INT32 end);
+PMOD_EXPORT struct array *copy_array(struct array *v);
+PMOD_EXPORT void check_array_for_destruct(struct array *v);
+PMOD_EXPORT INT32 array_find_destructed_object(struct array *v);
 INT32 *get_order(struct array *v, cmpfun fun);
-void sort_array_destructively(struct array *v);
-INT32 *get_set_order(struct array *a);
-INT32 *get_switch_order(struct array *a);
-INT32 *get_alpha_order(struct array *a);
+PMOD_EXPORT void sort_array_destructively(struct array *v);
+PMOD_EXPORT INT32 *get_set_order(struct array *a);
+PMOD_EXPORT INT32 *get_switch_order(struct array *a);
+PMOD_EXPORT INT32 *get_alpha_order(struct array *a);
 INT32 set_lookup(struct array *a, struct svalue *s);
 INT32 switch_lookup(struct array *a, struct svalue *s);
-struct array *order_array(struct array *v, INT32 *order);
-struct array *reorder_and_copy_array(struct array *v, INT32 *order);
-void array_fix_type_field(struct array *v);
+PMOD_EXPORT struct array *order_array(struct array *v, INT32 *order);
+PMOD_EXPORT struct array *reorder_and_copy_array(struct array *v, INT32 *order);
+PMOD_EXPORT void array_fix_type_field(struct array *v);
 void array_check_type_field(struct array *v);
-struct array *compact_array(struct array *v);
+PMOD_EXPORT struct array *compact_array(struct array *v);
 union anything *low_array_get_item_ptr(struct array *a,
 				       INT32 ind,
 				       TYPE_T t);
@@ -128,44 +128,44 @@ union anything *array_get_item_ptr(struct array *a,
 				   struct svalue *ind,
 				   TYPE_T t);
 INT32 * merge(struct array *a,struct array *b,INT32 opcode);
-struct array *array_zip(struct array *a, struct array *b,INT32 *zipper);
-struct array *add_arrays(struct svalue *argp, INT32 args);
-int array_equal_p(struct array *a, struct array *b, struct processing *p);
-struct array *merge_array_with_order(struct array *a, struct array *b,INT32 op);
-struct array *merge_array_without_order2(struct array *a, struct array *b,INT32 op);
-struct array *merge_array_without_order(struct array *a,
+PMOD_EXPORT struct array *array_zip(struct array *a, struct array *b,INT32 *zipper);
+PMOD_EXPORT struct array *add_arrays(struct svalue *argp, INT32 args);
+PMOD_EXPORT int array_equal_p(struct array *a, struct array *b, struct processing *p);
+PMOD_EXPORT struct array *merge_array_with_order(struct array *a, struct array *b,INT32 op);
+PMOD_EXPORT struct array *merge_array_without_order2(struct array *a, struct array *b,INT32 op);
+PMOD_EXPORT struct array *merge_array_without_order(struct array *a,
 					struct array *b,
 					INT32 op);
-struct array *subtract_arrays(struct array *a, struct array *b);
-struct array *and_arrays(struct array *a, struct array *b);
+PMOD_EXPORT struct array *subtract_arrays(struct array *a, struct array *b);
+PMOD_EXPORT struct array *and_arrays(struct array *a, struct array *b);
 int check_that_array_is_constant(struct array *a);
 node *make_node_from_array(struct array *a);
-void push_array_items(struct array *a);
+PMOD_EXPORT void push_array_items(struct array *a);
 void describe_array_low(struct array *a, struct processing *p, int indent);
-void simple_describe_array(struct array *a);
+PMOD_EXPORT void simple_describe_array(struct array *a);
 void describe_index(struct array *a,
 		    int e,
 		    struct processing *p,
 		    int indent);
 void describe_array(struct array *a,struct processing *p,int indent);
 struct array *aggregate_array(INT32 args);
-struct array *append_array(struct array *a, struct svalue *s);
-struct array *explode(struct pike_string *str,
+PMOD_EXPORT struct array *append_array(struct array *a, struct svalue *s);
+PMOD_EXPORT struct array *explode(struct pike_string *str,
 		       struct pike_string *del);
-struct pike_string *implode(struct array *a,struct pike_string *del);
-struct array *copy_array_recursively(struct array *a,struct processing *p);
-void apply_array(struct array *a, INT32 args);
-struct array *reverse_array(struct array *a);
-void array_replace(struct array *a,
+PMOD_EXPORT struct pike_string *implode(struct array *a,struct pike_string *del);
+PMOD_EXPORT struct array *copy_array_recursively(struct array *a,struct processing *p);
+PMOD_EXPORT void apply_array(struct array *a, INT32 args);
+PMOD_EXPORT struct array *reverse_array(struct array *a);
+PMOD_EXPORT void array_replace(struct array *a,
 		   struct svalue *from,
 		   struct svalue *to);
-void check_array(struct array *a);
+PMOD_EXPORT void check_array(struct array *a);
 void check_all_arrays(void);
 void gc_mark_array_as_referenced(struct array *a);
+void real_gc_cycle_check_array(struct array *a, int weak);
 unsigned gc_touch_all_arrays(void);
 void gc_check_all_arrays(void);
 void gc_mark_all_arrays(void);
-void real_gc_cycle_check_array(struct array *a, int weak);
 void gc_cycle_check_all_arrays(void);
 void gc_zap_ext_weak_refs_in_arrays(void);
 void gc_free_all_unreferenced_arrays(void);
@@ -173,8 +173,8 @@ void debug_dump_type_field(TYPE_FIELD t);
 void debug_dump_array(struct array *a);
 void zap_all_arrays(void);
 void count_memory_in_arrays(INT32 *num_, INT32 *size_);
-struct array *explode_array(struct array *a, struct array *b);
-struct array *implode_array(struct array *a, struct array *b);
+PMOD_EXPORT struct array *explode_array(struct array *a, struct array *b);
+PMOD_EXPORT struct array *implode_array(struct array *a, struct array *b);
 /* Prototypes end here */
 
 #define gc_cycle_check_array(X, WEAK) \
diff --git a/src/backend.c b/src/backend.c
index c116d3368a..3f3c208b46 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: backend.c,v 1.52 2000/07/11 19:04:06 neotron Exp $");
+RCSID("$Id: backend.c,v 1.53 2000/07/28 17:16:54 hubbe Exp $");
 #include "fdlib.h"
 #include "backend.h"
 #include <errno.h>
@@ -55,7 +55,7 @@ struct fd_datum
 };
 
 struct fd_datum *fds;
-int fds_size = 0;
+PMOD_EXPORT int fds_size = 0;
 
 #define ASSURE_FDS_SIZE(X) do{while(fds_size-1 < X) grow_fds();}while(0)
 
@@ -198,14 +198,14 @@ void switch_poll_set(void)
 
 
 static int max_fd;
-struct timeval current_time;
-struct timeval next_timeout;
+PMOD_EXPORT struct timeval current_time;
+PMOD_EXPORT struct timeval next_timeout;
 static int wakeup_pipe[2];
 static int may_need_wakeup=0;
 
 static struct callback_list backend_callbacks;
 
-struct callback *debug_add_backend_callback(callback_func call,
+PMOD_EXPORT struct callback *debug_add_backend_callback(callback_func call,
 				      void *arg,
 				      callback_func free_func)
 {
@@ -221,7 +221,7 @@ static void wakeup_callback(int fd, void *foo)
 /* This is used by threaded programs and signals to wake up the
  * master 'thread'.
  */
-void wake_up_backend(void)
+PMOD_EXPORT void wake_up_backend(void)
 {
   char foo=0;
   if(may_need_wakeup)
@@ -492,7 +492,7 @@ void set_write_oob_callback(int fd,file_callback cb,void *data)
 }
 #endif /* WITH_OOB */
 
-file_callback query_read_callback(int fd)
+PMOD_EXPORT file_callback query_read_callback(int fd)
 {
 #ifdef PIKE_DEBUG
   if(fd<0)
@@ -502,7 +502,7 @@ file_callback query_read_callback(int fd)
   return fds[fd].read.callback;
 }
 
-file_callback query_write_callback(int fd)
+PMOD_EXPORT file_callback query_write_callback(int fd)
 {
 #ifdef PIKE_DEBUG
   if(fd<0)
@@ -513,7 +513,7 @@ file_callback query_write_callback(int fd)
 }
 
 #ifdef WITH_OOB
-file_callback query_read_oob_callback(int fd)
+PMOD_EXPORT file_callback query_read_oob_callback(int fd)
 {
 #ifdef PIKE_DEBUG
   if(fd<0)
@@ -523,7 +523,7 @@ file_callback query_read_oob_callback(int fd)
   return fds[fd].read_oob.callback;
 }
 
-file_callback query_write_oob_callback(int fd)
+PMOD_EXPORT file_callback query_write_oob_callback(int fd)
 {
 #ifdef PIKE_DEBUG
   if(fd<0)
@@ -535,7 +535,7 @@ file_callback query_write_oob_callback(int fd)
 }
 #endif /* WITH_OOB */
 
-void *query_read_callback_data(int fd)
+PMOD_EXPORT void *query_read_callback_data(int fd)
 {
 #ifdef PIKE_DEBUG
   if(fd<0)
@@ -546,7 +546,7 @@ void *query_read_callback_data(int fd)
   return fds[fd].read.data;
 }
 
-void *query_write_callback_data(int fd)
+PMOD_EXPORT void *query_write_callback_data(int fd)
 {
 #ifdef PIKE_DEBUG
   if(fd<0)
@@ -558,7 +558,7 @@ void *query_write_callback_data(int fd)
 }
 
 #ifdef WITH_OOB
-void *query_read_oob_callback_data(int fd)
+PMOD_EXPORT void *query_read_oob_callback_data(int fd)
 {
 #ifdef PIKE_DEBUG
   if(fd<0)
@@ -569,7 +569,7 @@ void *query_read_oob_callback_data(int fd)
   return fds[fd].read_oob.data;
 }
 
-void *query_write_oob_callback_data(int fd)
+PMOD_EXPORT void *query_write_oob_callback_data(int fd)
 {
 #ifdef PIKE_DEBUG
   if(fd<0)
@@ -1012,7 +1012,7 @@ void backend(void)
   UNSETJMP(back);
 }
 
-int write_to_stderr(char *a, size_t len)
+PMOD_EXPORT int write_to_stderr(char *a, size_t len)
 {
 #ifdef __NT__
   size_t e;
diff --git a/src/backend.h b/src/backend.h
index 7fd2471da5..d52a137c5f 100644
--- a/src/backend.h
+++ b/src/backend.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: backend.h,v 1.8 2000/06/29 16:52:25 grubba Exp $
+ * $Id: backend.h,v 1.9 2000/07/28 17:16:54 hubbe Exp $
  */
 #ifndef BACKEND_H
 #define BACKEND_H
@@ -18,6 +18,7 @@ extern struct timeval current_time;
 extern struct timeval next_timeout;
 typedef void (*file_callback)(int,void *);
 extern struct callback_list do_debug_callbacks;
+extern int fds_size;
 
 /* Prototypes begin here */
 struct selectors;
diff --git a/src/bignum.c b/src/bignum.c
index d5e5b26064..a523566b36 100644
--- a/src/bignum.c
+++ b/src/bignum.c
@@ -10,7 +10,7 @@
 
 struct svalue auto_bignum_program = { T_INT };
 
-int gmp_library_loaded=0;
+PMOD_EXPORT int gmp_library_loaded=0;
 int gmp_library_resolving=0;
 
 static void resolve_auto_bignum_program(void)
@@ -34,13 +34,13 @@ static void resolve_auto_bignum_program(void)
   }
 }
 
-struct program *get_auto_bignum_program(void)
+PMOD_EXPORT struct program *get_auto_bignum_program(void)
 {
   resolve_auto_bignum_program();
   return program_from_function(&auto_bignum_program);
 }
 
-struct program *get_auto_bignum_program_or_zero(void)
+PMOD_EXPORT struct program *get_auto_bignum_program_or_zero(void)
 {
   if(!gmp_library_loaded ||
      gmp_library_resolving  ||
@@ -55,7 +55,7 @@ void exit_auto_bignum(void)
   auto_bignum_program.type=T_INT;
 }
 
-void convert_stack_top_to_bignum(void)
+PMOD_EXPORT void convert_stack_top_to_bignum(void)
 {
   resolve_auto_bignum_program();
   apply_svalue(&auto_bignum_program, 1);
@@ -64,7 +64,7 @@ void convert_stack_top_to_bignum(void)
     error("Gmp.mpz conversion failed.\n");
 }
 
-void convert_stack_top_with_base_to_bignum(void)
+PMOD_EXPORT void convert_stack_top_with_base_to_bignum(void)
 {
   resolve_auto_bignum_program();
   apply_svalue(&auto_bignum_program, 2);
@@ -90,25 +90,25 @@ int is_bignum_object(struct object *o)
   return o->prog == program_from_function(&auto_bignum_program);
 }
 
-int is_bignum_object_in_svalue(struct svalue *sv)
+PMOD_EXPORT int is_bignum_object_in_svalue(struct svalue *sv)
 {
   return sv->type == T_OBJECT && is_bignum_object(sv->u.object);
 }
 
-struct object *make_bignum_object(void)
+PMOD_EXPORT struct object *make_bignum_object(void)
 {
   convert_stack_top_to_bignum();
   return (--sp)->u.object;
 }
 
-struct object *bignum_from_svalue(struct svalue *s)
+PMOD_EXPORT struct object *bignum_from_svalue(struct svalue *s)
 {
   push_svalue(s);
   convert_stack_top_to_bignum();
   return (--sp)->u.object;
 }
 
-struct pike_string *string_from_bignum(struct object *o, int base)
+PMOD_EXPORT struct pike_string *string_from_bignum(struct object *o, int base)
 {
   push_int(base);
   safe_apply(o, "digits", 1);
@@ -119,7 +119,7 @@ struct pike_string *string_from_bignum(struct object *o, int base)
   return (--sp)->u.string;
 }
 
-void convert_svalue_to_bignum(struct svalue *s)
+PMOD_EXPORT void convert_svalue_to_bignum(struct svalue *s)
 {
   push_svalue(s);
   convert_stack_top_to_bignum();
@@ -135,7 +135,7 @@ void convert_svalue_to_bignum(struct svalue *s)
 #define BIGNUM_INT64_MASK  0xffff
 #define BIGNUM_INT64_SHIFT 16
 
-void push_int64(INT64 i)
+PMOD_EXPORT void push_int64(INT64 i)
 {
   if(i == (INT_TYPE)i)
   {
@@ -181,7 +181,7 @@ void push_int64(INT64 i)
   }
 }
 
-int int64_from_bignum(INT64 *i, struct object *bignum)
+PMOD_EXPORT int int64_from_bignum(INT64 *i, struct object *bignum)
 {
   int neg, pos, rshfun, andfun;
 
diff --git a/src/bignum.h b/src/bignum.h
index 44abe990cb..52144e4601 100644
--- a/src/bignum.h
+++ b/src/bignum.h
@@ -5,6 +5,9 @@
 
 #ifdef AUTO_BIGNUM
 
+extern int gmp_library_loaded;
+
+
 /* Note: These functions assume some properties of the CPU. */
 
 #define INT_TYPE_SIGN(x)             ((x) < 0)
diff --git a/src/builtin_functions.c b/src/builtin_functions.c
index 064dc2f63d..9c58f75a20 100644
--- a/src/builtin_functions.c
+++ b/src/builtin_functions.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: builtin_functions.c,v 1.292 2000/07/27 17:47:29 lange Exp $");
+RCSID("$Id: builtin_functions.c,v 1.293 2000/07/28 17:16:54 hubbe Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "pike_macros.h"
@@ -58,7 +58,7 @@ RCSID("$Id: builtin_functions.c,v 1.292 2000/07/27 17:47:29 lange Exp $");
 /* #define DIFF_DEBUG */
 /* #define ENABLE_DYN_DIFF */
 
-void f_equal(INT32 args)
+PMOD_EXPORT void f_equal(INT32 args)
 {
   int i;
   if(args != 2)
@@ -69,7 +69,7 @@ void f_equal(INT32 args)
   push_int(i);
 }
 
-void debug_f_aggregate(INT32 args)
+PMOD_EXPORT void debug_f_aggregate(INT32 args)
 {
   struct array *a;
 #ifdef PIKE_DEBUG
@@ -125,7 +125,7 @@ void f_hash(INT32 args)
   push_int(i);
 }
 
-void f_copy_value(INT32 args)
+PMOD_EXPORT void f_copy_value(INT32 args)
 {
   if(!args)
     SIMPLE_TOO_FEW_ARGS_ERROR("copy_value",1);
@@ -270,7 +270,7 @@ static struct case_info *find_ci_shift0(int c)
    } \
   } while(0)
 
-void f_lower_case(INT32 args)
+PMOD_EXPORT void f_lower_case(INT32 args)
 {
   INT32 i;
   struct pike_string *orig;
@@ -309,7 +309,7 @@ void f_lower_case(INT32 args)
   push_string(end_shared_string(ret));
 }
 
-void f_upper_case(INT32 args)
+PMOD_EXPORT void f_upper_case(INT32 args)
 {
   INT32 i;
   struct pike_string *orig;
@@ -369,7 +369,7 @@ void f_upper_case(INT32 args)
   }
 }
 
-void f_random(INT32 args)
+PMOD_EXPORT void f_random(INT32 args)
 {
   INT_TYPE i;
 
@@ -394,7 +394,7 @@ void f_random(INT32 args)
   push_int(i);
 }
 
-void f_random_string(INT32 args)
+PMOD_EXPORT void f_random_string(INT32 args)
 {
   struct pike_string *ret;
   INT32 e,len;
@@ -405,7 +405,7 @@ void f_random_string(INT32 args)
   push_string(end_shared_string(ret));
 }
 
-void f_random_seed(INT32 args)
+PMOD_EXPORT void f_random_seed(INT32 args)
 {
   INT_TYPE i;
 #ifdef AUTO_BIGNUM
@@ -429,7 +429,7 @@ void f_query_num_arg(INT32 args)
   push_int(Pike_fp ? Pike_fp->args : 0);
 }
 
-void f_search(INT32 args)
+PMOD_EXPORT void f_search(INT32 args)
 {
   INT32 start;
 
@@ -506,7 +506,7 @@ void f_search(INT32 args)
 }
 
 /* int has_prefix(string a, string prefix) */
-void f_has_prefix(INT32 args)
+PMOD_EXPORT void f_has_prefix(INT32 args)
 {
   struct pike_string *a, *b;
 
@@ -562,7 +562,7 @@ void f_has_prefix(INT32 args)
 #undef TWO_SHIFTS
 }
 
-void f_has_index(INT32 args)
+PMOD_EXPORT void f_has_index(INT32 args)
 {
   int t = 0;
   
@@ -625,7 +625,7 @@ void f_has_index(INT32 args)
   }
 }
 
-void f_has_value(INT32 args)
+PMOD_EXPORT void f_has_value(INT32 args)
 {
   if(args != 2)
     PIKE_ERROR("has_value", "Bad number of arguments.\n", Pike_sp, args);
@@ -674,7 +674,7 @@ void f_has_value(INT32 args)
 
 /* Old backtrace */
 
-void f_backtrace(INT32 args)
+PMOD_EXPORT void f_backtrace(INT32 args)
 {
   INT32 frames;
   struct pike_frame *f,*of;
@@ -749,7 +749,7 @@ void f_backtrace(INT32 args)
   a->type_field = BIT_ARRAY | BIT_INT;
 }
 
-void f_add_constant(INT32 args)
+PMOD_EXPORT void f_add_constant(INT32 args)
 {
   CHECK_SECURITY_OR_ERROR(SECURITY_BIT_SECURITY, ("add_constant: permission denied.\n"));
   if(args<1)
@@ -931,7 +931,7 @@ static char *combine_path(char *cwd,char *file)
   return ret;
 }
 
-void f_combine_path(INT32 args)
+PMOD_EXPORT void f_combine_path(INT32 args)
 {
   char *path=0;
   int e,dofree=0;
@@ -966,7 +966,7 @@ void f_combine_path(INT32 args)
   push_string(ret);
 }
 
-void f_function_object(INT32 args)
+PMOD_EXPORT void f_function_object(INT32 args)
 {
   if(args < 1)
     SIMPLE_TOO_FEW_ARGS_ERROR("function_object",1);
@@ -983,7 +983,7 @@ void f_function_object(INT32 args)
   }
 }
 
-void f_function_name(INT32 args)
+PMOD_EXPORT void f_function_name(INT32 args)
 {
   struct pike_string *s;
   if(args < 1)
@@ -1010,7 +1010,7 @@ void f_function_name(INT32 args)
   }
 }
 
-void f_zero_type(INT32 args)
+PMOD_EXPORT void f_zero_type(INT32 args)
 {
   if(args < 1)
     SIMPLE_TOO_FEW_ARGS_ERROR("zero_type",1);
@@ -1037,7 +1037,7 @@ void f_zero_type(INT32 args)
  * Some wide-strings related functions
  */
 
-void f_string_to_unicode(INT32 args)
+PMOD_EXPORT void f_string_to_unicode(INT32 args)
 {
   struct pike_string *in;
   struct pike_string *out = NULL;
@@ -1144,7 +1144,7 @@ void f_string_to_unicode(INT32 args)
   push_string(out);
 }
 
-void f_unicode_to_string(INT32 args)
+PMOD_EXPORT void f_unicode_to_string(INT32 args)
 {
   struct pike_string *in;
   struct pike_string *out = NULL;
@@ -1303,7 +1303,7 @@ void f_string_to_utf8(INT32 args)
   push_string(out);
 }
 
-void f_utf8_to_string(INT32 args)
+PMOD_EXPORT void f_utf8_to_string(INT32 args)
 {
   struct pike_string *in;
   struct pike_string *out;
@@ -1455,13 +1455,13 @@ static void f_parse_pike_type( INT32 args )
   push_string( res );
 }
 
-void f_all_constants(INT32 args)
+PMOD_EXPORT void f_all_constants(INT32 args)
 {
   pop_n_elems(args);
   ref_push_mapping(get_builtin_constants());
 }
 
-void f_allocate(INT32 args)
+PMOD_EXPORT void f_allocate(INT32 args)
 {
   INT32 size;
   struct array *a;
@@ -1534,7 +1534,7 @@ node *fix_this_object_type(node *n)
   return NULL;
 }
 
-void f_throw(INT32 args)
+PMOD_EXPORT void f_throw(INT32 args)
 {
   if(args < 1)
     SIMPLE_TOO_FEW_ARGS_ERROR("throw", 1);
@@ -1544,7 +1544,7 @@ void f_throw(INT32 args)
   pike_throw();
 }
 
-void f_exit(INT32 args)
+PMOD_EXPORT void f_exit(INT32 args)
 {
   static int in_exit=0;
   CHECK_SECURITY_OR_ERROR(SECURITY_BIT_SECURITY, ("exit: permission denied.\n"));
@@ -1574,7 +1574,7 @@ void f__exit(INT32 args)
   exit(Pike_sp[-args].u.integer);
 }
 
-void f_time(INT32 args)
+PMOD_EXPORT void f_time(INT32 args)
 {
   if(!args)
   {
@@ -1596,7 +1596,7 @@ void f_time(INT32 args)
   push_int(current_time.tv_sec);
 }
 
-void f_crypt(INT32 args)
+PMOD_EXPORT void f_crypt(INT32 args)
 {
   char salt[2];
   char *ret, *saltp;
@@ -1650,7 +1650,7 @@ void f_crypt(INT32 args)
   }
 }
 
-void f_destruct(INT32 args)
+PMOD_EXPORT void f_destruct(INT32 args)
 {
   struct object *o;
   if(args)
@@ -1675,7 +1675,7 @@ void f_destruct(INT32 args)
   pop_n_elems(args);
 }
 
-void f_indices(INT32 args)
+PMOD_EXPORT void f_indices(INT32 args)
 {
   INT32 size;
   struct array *a;
@@ -1941,7 +1941,7 @@ static node *fix_aggregate_mapping_type(node *n)
   return NULL;
 }
 
-void f_values(INT32 args)
+PMOD_EXPORT void f_values(INT32 args)
 {
   INT32 size;
   struct array *a;
@@ -2008,7 +2008,7 @@ void f_values(INT32 args)
   push_array(a);
 }
 
-void f_next_object(INT32 args)
+PMOD_EXPORT void f_next_object(INT32 args)
 {
   struct object *o;
   if(args < 1)
@@ -2029,7 +2029,7 @@ void f_next_object(INT32 args)
   }
 }
 
-void f_object_program(INT32 args)
+PMOD_EXPORT void f_object_program(INT32 args)
 {
   if(args < 1)
     SIMPLE_TOO_FEW_ARGS_ERROR("object_program", 1);
@@ -2088,7 +2088,7 @@ node *fix_object_program_type(node *n)
   return NULL;
 }
 
-void f_reverse(INT32 args)
+PMOD_EXPORT void f_reverse(INT32 args)
 {
   if(args < 1)
     SIMPLE_TOO_FEW_ARGS_ERROR("reverse", 1);
@@ -2329,7 +2329,7 @@ static struct pike_string * replace_many(struct pike_string *str,
   return finish_string_builder(&ret);
 }
 
-void f_replace(INT32 args)
+PMOD_EXPORT void f_replace(INT32 args)
 {
   if(args < 3)
     SIMPLE_TOO_FEW_ARGS_ERROR("replace", 3);
@@ -2386,7 +2386,7 @@ void f_replace(INT32 args)
   }
 }
 
-void f_compile(INT32 args)
+PMOD_EXPORT void f_compile(INT32 args)
 {
   struct program *p;
 
@@ -2442,7 +2442,7 @@ void f_set_weak_flag(INT32 args)
 
 
 
-void f_objectp(INT32 args)
+PMOD_EXPORT void f_objectp(INT32 args)
 {
   if(args<1)
     SIMPLE_TOO_FEW_ARGS_ERROR("objectp", 1);
@@ -2460,7 +2460,7 @@ void f_objectp(INT32 args)
   }
 }
 
-void f_functionp(INT32 args)
+PMOD_EXPORT void f_functionp(INT32 args)
 {
   if(args<1)
     SIMPLE_TOO_FEW_ARGS_ERROR("functionp", 1);
@@ -2479,7 +2479,7 @@ void f_functionp(INT32 args)
 #undef HAVE_POLL
 #endif
 
-void f_sleep(INT32 args)
+PMOD_EXPORT void f_sleep(INT32 args)
 {
 #define POLL_SLEEP_LIMIT 0.02
 
@@ -2592,7 +2592,7 @@ void f_gc(INT32 args)
  */
 
 #define TYPEP(ID,NAME,TYPE,TYPE_NAME)				\
-void ID(INT32 args)						\
+PMOD_EXPORT void ID(INT32 args)						\
 {								\
   int t;							\
   if(args<1)							\
@@ -2625,7 +2625,7 @@ void ID(INT32 args) \
 #endif /* AUTO_BIGNUM */
 
 
-void f_programp(INT32 args)
+PMOD_EXPORT void f_programp(INT32 args)
 {
   if(args<1)
     SIMPLE_TOO_FEW_ARGS_ERROR("programp", 1);
@@ -2666,7 +2666,7 @@ TYPEP(f_stringp, "stringp", T_STRING)
 TYPEP(f_floatp, "floatp", T_FLOAT)
 #endif /* AUTO_BIGNUM */
      
-void f_sort(INT32 args)
+PMOD_EXPORT void f_sort(INT32 args)
 {
   INT32 e,*order;
 
@@ -2694,7 +2694,7 @@ void f_sort(INT32 args)
   }
 }
 
-void f_rows(INT32 args)
+PMOD_EXPORT void f_rows(INT32 args)
 {
   INT32 e;
   struct array *a,*tmp;
@@ -2731,7 +2731,7 @@ void f_rows(INT32 args)
 
 
 #ifdef PIKE_DEBUG
-void f__verify_internals(INT32 args)
+PMOD_EXPORT void f__verify_internals(INT32 args)
 {
   INT32 tmp=d_flag;
   CHECK_SECURITY_OR_ERROR(SECURITY_BIT_SECURITY,
@@ -2743,7 +2743,7 @@ void f__verify_internals(INT32 args)
   pop_n_elems(args);
 }
 
-void f__debug(INT32 args)
+PMOD_EXPORT void f__debug(INT32 args)
 {
   INT_TYPE d;
 
@@ -2756,7 +2756,7 @@ void f__debug(INT32 args)
   d_flag = d;
 }
 
-void f__optimizer_debug(INT32 args)
+PMOD_EXPORT void f__optimizer_debug(INT32 args)
 {
   INT_TYPE l;
 
@@ -2771,7 +2771,7 @@ void f__optimizer_debug(INT32 args)
 
 #ifdef YYDEBUG
 
-void f__compiler_trace(INT32 args)
+PMOD_EXPORT void f__compiler_trace(INT32 args)
 {
   extern int yydebug;
   INT_TYPE yyd;
@@ -2813,7 +2813,7 @@ static void encode_struct_tm(struct tm *tm)
 #endif
 
 #ifdef HAVE_GMTIME
-void f_gmtime(INT32 args)
+PMOD_EXPORT void f_gmtime(INT32 args)
 {
   struct tm *tm;
   INT_TYPE tt;
@@ -2833,7 +2833,7 @@ void f_gmtime(INT32 args)
 #endif
 
 #ifdef HAVE_LOCALTIME
-void f_localtime(INT32 args)
+PMOD_EXPORT void f_localtime(INT32 args)
 {
   struct tm *tm;
   INT_TYPE tt;
@@ -2863,7 +2863,7 @@ void f_localtime(INT32 args)
 #endif
 
 #ifdef HAVE_MKTIME
-void f_mktime (INT32 args)
+PMOD_EXPORT void f_mktime (INT32 args)
 {
   INT_TYPE sec, min, hour, mday, mon, year, isdst;
   struct tm date;
@@ -3099,7 +3099,7 @@ static int does_match(struct pike_string *s,int j,
   return j==s->len;
 }
 
-void f_glob(INT32 args)
+PMOD_EXPORT void f_glob(INT32 args)
 {
   INT32 i,matches;
   struct array *a;
@@ -4096,7 +4096,7 @@ static struct array* diff_build(struct array *a,
    return aggregate_array(2);
 }
 
-void f_diff(INT32 args)
+PMOD_EXPORT void f_diff(INT32 args)
 {
    struct array *seq;
    struct array *cmptbl;
@@ -4205,7 +4205,7 @@ struct callback *add_memory_usage_callback(callback_func call,
 }
 
 
-void f__memory_usage(INT32 args)
+PMOD_EXPORT void f__memory_usage(INT32 args)
 {
   INT32 num,size;
   struct svalue *ss;
@@ -4271,7 +4271,7 @@ void f__memory_usage(INT32 args)
   f_aggregate_mapping(Pike_sp-ss);
 }
 
-void f__next(INT32 args)
+PMOD_EXPORT void f__next(INT32 args)
 {
   struct svalue tmp;
 
@@ -4304,7 +4304,7 @@ void f__next(INT32 args)
   }
 }
 
-void f__prev(INT32 args)
+PMOD_EXPORT void f__prev(INT32 args)
 {
   struct svalue tmp;
 
@@ -4335,7 +4335,7 @@ void f__prev(INT32 args)
   }
 }
 
-void f__refs(INT32 args)
+PMOD_EXPORT void f__refs(INT32 args)
 {
   INT32 i;
 
@@ -4356,7 +4356,7 @@ void f__refs(INT32 args)
 /* This function is for debugging *ONLY*
  * do not document please. /Hubbe
  */
-void f__leak(INT32 args)
+PMOD_EXPORT void f__leak(INT32 args)
 {
   INT32 i;
 
@@ -4374,7 +4374,7 @@ void f__leak(INT32 args)
   push_int(i);
 }
 
-void f__typeof(INT32 args)
+PMOD_EXPORT void f__typeof(INT32 args)
 {
   struct pike_string *s;
   if(!args)
@@ -4387,7 +4387,7 @@ void f__typeof(INT32 args)
   Pike_sp[-1].type = T_TYPE;
 }
 
-void f_replace_master(INT32 args)
+PMOD_EXPORT void f_replace_master(INT32 args)
 {
   CHECK_SECURITY_OR_ERROR(SECURITY_BIT_SECURITY,
 			  ("replace_master: permission denied.\n"));
@@ -4411,7 +4411,7 @@ void f_replace_master(INT32 args)
   pop_n_elems(args);
 }
 
-void f_master(INT32 args)
+PMOD_EXPORT void f_master(INT32 args)
 {
   pop_n_elems(args);
   ref_push_object(master());
@@ -4420,13 +4420,13 @@ void f_master(INT32 args)
 #ifdef HAVE_GETHRVTIME
 #include <sys/time.h>
 
-void f_gethrvtime(INT32 args)
+PMOD_EXPORT void f_gethrvtime(INT32 args)
 {
   pop_n_elems(args);
   push_int64(gethrvtime()/1000);
 }
 
-void f_gethrtime(INT32 args)
+PMOD_EXPORT void f_gethrtime(INT32 args)
 {
   pop_n_elems(args);
   if(args)
@@ -4435,7 +4435,7 @@ void f_gethrtime(INT32 args)
     push_int64(gethrtime()/1000);
 }
 #else
-void f_gethrtime(INT32 args)
+PMOD_EXPORT void f_gethrtime(INT32 args)
 {
   struct timeval tv;
   pop_n_elems(args);
@@ -4496,7 +4496,7 @@ static void f_get_prof_info(INT32 args)
 }
 #endif /* PROFILING */
 
-void f_object_variablep(INT32 args)
+PMOD_EXPORT void f_object_variablep(INT32 args)
 {
   struct object *o;
   struct pike_string *s;
@@ -4520,7 +4520,7 @@ void f_object_variablep(INT32 args)
 }
 
 /* uniqify an array while at the same time keeping the order intact */
-void f_uniq_array(INT32 args)
+PMOD_EXPORT void f_uniq_array(INT32 args)
 {
   struct array *a, *b;
   struct mapping *m;
@@ -4548,7 +4548,7 @@ void f_uniq_array(INT32 args)
   push_array(b);
 }
 
-void f_splice(INT32 args)
+PMOD_EXPORT void f_splice(INT32 args)
 {
   struct array *out;
   INT32 size=0x7fffffff;
@@ -4626,7 +4626,7 @@ void f_everynth(INT32 args)
 }
 
 
-void f_transpose(INT32 args)
+PMOD_EXPORT void f_transpose(INT32 args)
 {
   struct array *out;
   struct array *in;
@@ -4698,7 +4698,7 @@ void f_transpose(INT32 args)
 }
 
 #ifdef DEBUG_MALLOC
-void f__reset_dmalloc(INT32 args)
+PMOD_EXPORT void f__reset_dmalloc(INT32 args)
 {
   CHECK_SECURITY_OR_ERROR(SECURITY_BIT_SECURITY,
 			  ("_reset_dmalloc: permission denied.\n"));
@@ -4706,7 +4706,7 @@ void f__reset_dmalloc(INT32 args)
   reset_debug_malloc();
 }
 
-void f__dmalloc_set_name(INT32 args)
+PMOD_EXPORT void f__dmalloc_set_name(INT32 args)
 {
   char *s;
   INT_TYPE i;
@@ -4723,7 +4723,7 @@ void f__dmalloc_set_name(INT32 args)
   pop_n_elems(args);
 }
 
-void f__list_open_fds(INT32 args)
+PMOD_EXPORT void f__list_open_fds(INT32 args)
 {
   extern void list_open_fds(void);
   list_open_fds();
@@ -4731,7 +4731,7 @@ void f__list_open_fds(INT32 args)
 #endif
 
 #ifdef PIKE_DEBUG
-void f__locate_references(INT32 args)
+PMOD_EXPORT void f__locate_references(INT32 args)
 {
   CHECK_SECURITY_OR_ERROR(SECURITY_BIT_SECURITY,
 			  ("_locate_references: permission denied.\n"));
@@ -4740,7 +4740,7 @@ void f__locate_references(INT32 args)
   pop_n_elems(args-1);
 }
 
-void f__describe(INT32 args)
+PMOD_EXPORT void f__describe(INT32 args)
 {
   struct svalue *s;
 
@@ -4753,7 +4753,7 @@ void f__describe(INT32 args)
 
 #endif
 
-void f_map_array(INT32 args)
+PMOD_EXPORT void f_map_array(INT32 args)
 {
   ONERROR tmp;
   INT32 e;
@@ -4785,7 +4785,7 @@ void f_map_array(INT32 args)
   push_array(ret);
 }
 
-void f_map(INT32 args)
+PMOD_EXPORT void f_map(INT32 args)
 {
    /*
      map(arr,fun,extra) => ret
@@ -5120,7 +5120,7 @@ void f_map(INT32 args)
    }      
 }
 
-void f_filter(INT32 args)
+PMOD_EXPORT void f_filter(INT32 args)
 {
    /* filter(mixed arr,mixed fun,mixed ... extra) ->
 
@@ -5460,7 +5460,7 @@ void f_enumerate(INT32 args)
    }
 }
 
-void f_inherit_list(INT32 args)
+PMOD_EXPORT void f_inherit_list(INT32 args)
 {
   struct program *p;
   struct svalue *arg;
@@ -5548,7 +5548,7 @@ void f_inherit_list(INT32 args)
 }
 
 
-void f_function_defined(INT32 args)
+PMOD_EXPORT void f_function_defined(INT32 args)
 {
   check_all_args("Function.defined",args,BIT_FUNCTION, 0);
 
diff --git a/src/builtin_functions.h b/src/builtin_functions.h
index 58b156ee31..960a1623a5 100644
--- a/src/builtin_functions.h
+++ b/src/builtin_functions.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: builtin_functions.h,v 1.13 2000/04/30 11:05:08 grubba Exp $
+ * $Id: builtin_functions.h,v 1.14 2000/07/28 17:16:54 hubbe Exp $
  */
 #ifndef BUILTIN_EFUNS_H
 #define BUILTIN_EFUNS_H
@@ -15,101 +15,101 @@
 #include "callback.h"
 
 /* Prototypes begin here */
-void debug_f_aggregate(INT32 args);
+PMOD_EXPORT void debug_f_aggregate(INT32 args);
 #ifdef DEBUG_MALLOC
 #define f_aggregate(X) do { debug_f_aggregate(X); debug_malloc_touch(Pike_sp[-1].u.refs); } while (0)
 #else
 #define f_aggregate(X) debug_f_aggregate(X)
 #endif
 
-void f_equal(INT32 args);
-void f_trace(INT32 args);
-void f_hash(INT32 args);
-void f_copy_value(INT32 args);
-void f_ctime(INT32 args);
-void f_lower_case(INT32 args);
-void f_upper_case(INT32 args);
-void f_random(INT32 args);
-void f_random_seed(INT32 args);
-void f_query_num_arg(INT32 args);
-void f_search(INT32 args);
-void f_has_index(INT32 args);
-void f_has_value(INT32 args);
-void f_backtrace(INT32 args);
-void f_add_constant(INT32 args);
-void f_combine_path(INT32 args);
-void f_function_object(INT32 args);
-void f_function_name(INT32 args);
-void f_zero_type(INT32 args);
-void f_string_to_unicode(INT32 args);
-void f_unicode_to_string(INT32 args);
-void f_string_to_utf8(INT32 args);
-void f_utf8_to_string(INT32 args);
-void f_all_constants(INT32 args);
-void f_allocate(INT32 args);
-void f_rusage(INT32 args);
-void f_this_object(INT32 args);
-void f_throw(INT32 args);
-void f_exit(INT32 args);
-void f__exit(INT32 args);
-void f_time(INT32 args);
-void f_crypt(INT32 args);
-void f_destruct(INT32 args);
-void f_indices(INT32 args);
-void f_values(INT32 args);
-void f_next_object(INT32 args);
-void f_object_program(INT32 args);
-void f_reverse(INT32 args);
+PMOD_EXPORT void f_equal(INT32 args);
+PMOD_EXPORT void f_trace(INT32 args);
+PMOD_EXPORT void f_hash(INT32 args);
+PMOD_EXPORT void f_copy_value(INT32 args);
+PMOD_EXPORT void f_ctime(INT32 args);
+PMOD_EXPORT void f_lower_case(INT32 args);
+PMOD_EXPORT void f_upper_case(INT32 args);
+PMOD_EXPORT void f_random(INT32 args);
+PMOD_EXPORT void f_random_seed(INT32 args);
+PMOD_EXPORT void f_query_num_arg(INT32 args);
+PMOD_EXPORT void f_search(INT32 args);
+PMOD_EXPORT void f_has_index(INT32 args);
+PMOD_EXPORT void f_has_value(INT32 args);
+PMOD_EXPORT void f_backtrace(INT32 args);
+PMOD_EXPORT void f_add_constant(INT32 args);
+PMOD_EXPORT void f_combine_path(INT32 args);
+PMOD_EXPORT void f_function_object(INT32 args);
+PMOD_EXPORT void f_function_name(INT32 args);
+PMOD_EXPORT void f_zero_type(INT32 args);
+PMOD_EXPORT void f_string_to_unicode(INT32 args);
+PMOD_EXPORT void f_unicode_to_string(INT32 args);
+PMOD_EXPORT void f_string_to_utf8(INT32 args);
+PMOD_EXPORT void f_utf8_to_string(INT32 args);
+PMOD_EXPORT void f_all_constants(INT32 args);
+PMOD_EXPORT void f_allocate(INT32 args);
+PMOD_EXPORT void f_rusage(INT32 args);
+PMOD_EXPORT void f_this_object(INT32 args);
+PMOD_EXPORT void f_throw(INT32 args);
+PMOD_EXPORT void f_exit(INT32 args);
+PMOD_EXPORT void f__exit(INT32 args);
+PMOD_EXPORT void f_time(INT32 args);
+PMOD_EXPORT void f_crypt(INT32 args);
+PMOD_EXPORT void f_destruct(INT32 args);
+PMOD_EXPORT void f_indices(INT32 args);
+PMOD_EXPORT void f_values(INT32 args);
+PMOD_EXPORT void f_next_object(INT32 args);
+PMOD_EXPORT void f_object_program(INT32 args);
+PMOD_EXPORT void f_reverse(INT32 args);
 struct tupel;
-void f_replace(INT32 args);
-void f_compile(INT32 args);
-void f_mkmapping(INT32 args);
-void f_objectp(INT32 args);
-void f_functionp(INT32 args);
-void f_sleep(INT32 args);
-void f_gc(INT32 args);
-void f_programp(INT32 args);
+PMOD_EXPORT void f_replace(INT32 args);
+PMOD_EXPORT void f_compile(INT32 args);
+PMOD_EXPORT void f_mkmapping(INT32 args);
+PMOD_EXPORT void f_objectp(INT32 args);
+PMOD_EXPORT void f_functionp(INT32 args);
+PMOD_EXPORT void f_sleep(INT32 args);
+PMOD_EXPORT void f_gc(INT32 args);
+PMOD_EXPORT void f_programp(INT32 args);
 TYPEP(f_intp, "intpp", PIKE_T_INT)
 TYPEP(f_mappingp, "mappingp", PIKE_T_MAPPING)
 TYPEP(f_arrayp, "arrayp", PIKE_T_ARRAY)
 TYPEP(f_multisetp, "multisetp", PIKE_T_MULTISET)
 TYPEP(f_stringp, "stringp", PIKE_T_STRING)
 TYPEP(f_floatp, "floatp", PIKE_T_FLOAT)
-void f_sort(INT32 args);
-void f_rows(INT32 args);
-void f_column(INT32 args);
-void f__verify_internals(INT32 args);
-void f__debug(INT32 args);
-void f__compiler_trace(INT32 args);
-void f_gmtime(INT32 args);
-void f_localtime(INT32 args);
-void f_glob(INT32 args);
+PMOD_EXPORT void f_sort(INT32 args);
+PMOD_EXPORT void f_rows(INT32 args);
+PMOD_EXPORT void f_column(INT32 args);
+PMOD_EXPORT void f__verify_internals(INT32 args);
+PMOD_EXPORT void f__debug(INT32 args);
+PMOD_EXPORT void f__compiler_trace(INT32 args);
+PMOD_EXPORT void f_gmtime(INT32 args);
+PMOD_EXPORT void f_localtime(INT32 args);
+PMOD_EXPORT void f_glob(INT32 args);
 struct diff_magic_link;
 struct diff_magic_link_pool;
 struct diff_magic_link_head;
-void f_diff(INT32 args);
-void f_diff_compare_table(INT32 args);
-void f_diff_longest_sequence(INT32 args);
-void f_diff_dyn_longest_sequence(INT32 args);
+PMOD_EXPORT void f_diff(INT32 args);
+PMOD_EXPORT void f_diff_compare_table(INT32 args);
+PMOD_EXPORT void f_diff_longest_sequence(INT32 args);
+PMOD_EXPORT void f_diff_dyn_longest_sequence(INT32 args);
 struct callback *add_memory_usage_callback(callback_func call,
 					  void *arg,
 					  callback_func free_func);
-void f__memory_usage(INT32 args);
-void f__next(INT32 args);
-void f__prev(INT32 args);
-void f__refs(INT32 args);
-void f_replace_master(INT32 args);
-void f_master(INT32 args);
-void f_gethrvtime(INT32 args);
-void f_gethrtime(INT32 args);
-void f_gethrtime(INT32 args);
-void f_object_variablep(INT32 args);
-void f_splice(INT32 args);
-void f_everynth(INT32 args);
-void f_transpose(INT32 args);
-void f__reset_dmalloc(INT32 args);
-void f__locate_references(INT32 args);
-void f_map_array(INT32 args);
+PMOD_EXPORT void f__memory_usage(INT32 args);
+PMOD_EXPORT void f__next(INT32 args);
+PMOD_EXPORT void f__prev(INT32 args);
+PMOD_EXPORT void f__refs(INT32 args);
+PMOD_EXPORT void f_replace_master(INT32 args);
+PMOD_EXPORT void f_master(INT32 args);
+PMOD_EXPORT void f_gethrvtime(INT32 args);
+PMOD_EXPORT void f_gethrtime(INT32 args);
+PMOD_EXPORT void f_gethrtime(INT32 args);
+PMOD_EXPORT void f_object_variablep(INT32 args);
+PMOD_EXPORT void f_splice(INT32 args);
+PMOD_EXPORT void f_everynth(INT32 args);
+PMOD_EXPORT void f_transpose(INT32 args);
+PMOD_EXPORT void f__reset_dmalloc(INT32 args);
+PMOD_EXPORT void f__locate_references(INT32 args);
+PMOD_EXPORT void f_map_array(INT32 args);
 void init_builtin_efuns(void);
 /* Prototypes end here */
 
diff --git a/src/callback.c b/src/callback.c
index 362487ccb3..d3b8e67ef1 100644
--- a/src/callback.c
+++ b/src/callback.c
@@ -10,7 +10,7 @@
 #include "error.h"
 #include "block_alloc.h"
 
-RCSID("$Id: callback.c,v 1.19 1999/10/24 13:34:03 grubba Exp $");
+RCSID("$Id: callback.c,v 1.20 2000/07/28 17:16:54 hubbe Exp $");
 
 struct callback_list fork_child_callback;
 
@@ -126,7 +126,7 @@ static void check_callback_chain(struct callback_list *lst)
 /* Traverse a linked list of callbacks and call all the active callbacks
  * in the list. Deactivated callbacks are freed and placed in the free list.
  */
-void call_callback(struct callback_list *lst, void *arg)
+PMOD_EXPORT void call_callback(struct callback_list *lst, void *arg)
 {
   int this_call;
   struct callback *l,**ptr;
@@ -173,7 +173,7 @@ void call_callback(struct callback_list *lst, void *arg)
 }
 
 /* Add a callback to the linked list pointed to by ptr. */
-struct callback *debug_add_to_callback(struct callback_list *lst,
+PMOD_EXPORT struct callback *debug_add_to_callback(struct callback_list *lst,
 				       callback_func call,
 				       void *arg,
 				       callback_func free_func)
@@ -198,7 +198,7 @@ struct callback *debug_add_to_callback(struct callback_list *lst,
 /* This function deactivates a callback.
  * It is not actually freed until next time this callback is "called"
  */
-void *remove_callback(struct callback *l)
+PMOD_EXPORT void *remove_callback(struct callback *l)
 {
   dmalloc_unregister(l,1);
   l->call=0;
diff --git a/src/configure.in b/src/configure.in
index a8b69cc088..749922f1c4 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -1,4 +1,4 @@
-AC_REVISION("$Id: configure.in,v 1.386 2000/07/11 19:04:06 neotron Exp $")
+AC_REVISION("$Id: configure.in,v 1.387 2000/07/28 17:16:54 hubbe Exp $")
 AC_INIT(interpret.c)
 AC_CONFIG_HEADER(machine.h)
 
@@ -454,7 +454,7 @@ else :; fi
 
 
 
-AC_ARG_WITH(dynamic_modules,   [  --without-dynamic-modules        link modules statically],[],[with_dynamic_modules=yes])
+AC_ARG_WITH(dynamic_modules,   [  --without-dynamic-modules        link modules statically],[],[])
 AC_ARG_WITH(static_linking,    [  --with-static-linking            link statically, if possible],[with_static_linking=yes],[])
 AC_ARG_WITH(include-path,[  --with-include-path    A list of paths to search for include files.])
 AC_ARG_WITH(lib-path,    [  --with-lib-path        A list of paths to search for libraries.])
@@ -859,6 +859,9 @@ if test $cflags_is_set = no; then
         AC_SYS_COMPILER_FLAG(-GZ,GZ,WARN)
       fi
     else :; fi
+
+    EXTRA_MODULE_REQUIREMENTS="${EXTRA_MODULE_REQUIREMENTS} import_functions.h"
+    EXTRA_OBJS="${EXTRA_OBJS} export_functions.o"
   ])
 
 dnl
@@ -3561,8 +3564,20 @@ void testfunc2(void) { exit(0); }
 ])
 AC_MSG_RESULT($pike_cv_sys_dynamic_loading)
 
-if test x$pike_cv_sys_dynamic_loading = xno ; then
-  with_dynamic_modules=no
+
+if test "x$with_dynamic_modules" = "x" ; then
+  if test x$pike_cv_sys_dynamic_loading = xno ; then
+    with_dynamic_modules=no
+  else
+    with_dynamic_modules=yes
+    if test x$pike_cv_func_dlopen$ac_cv_func_dld_link$ac_cv_func_shl_load = xnonono;
+    then
+#     Dynamic loading is now WORKING
+#      if test x"$pike_cv_sys_os" != xWindows_NT ; then
+        with_dynamic_modules=no
+#      fi
+    fi
+  fi
 fi
 
 #######################################################################
@@ -3627,6 +3642,16 @@ esac
 if test "x$with_copt" = xno ; then
   OPTIMIZE=
 fi
+
+#############################################################################
+
+if test x$with_dynamic_modules = xyes ; then
+  dmmsrc="modules/dynamic_module_makefile.in"
+  CCSHARED="${CCSHARED} -DDYNAMIC_MODULE"
+else
+  dmmsrc="modules/static_module_makefile.in"
+fi
+
 #############################################################################
 
 echo
@@ -3637,6 +3662,7 @@ echo "Linker:        $LD"
 echo "Shared linker: $LDSHARED"
 echo
 echo "Shared object extension: $SO"
+echo "Dynamic modules: $with_dynamic_modules"
 echo
 echo "CPPFLAGS:      $CPPFLAGS"
 echo "CFLAGS:        $CFLAGS"
@@ -3673,22 +3699,10 @@ AC_SUBST(OPTIMIZE)
 AC_SUBST(EXTRA_OBJS)
 AC_SUBST(RANLIB)
 AC_SUBST(DEBUGDEF)
+AC_SUBST(EXTRA_MODULE_REQUIREMENTS)
 AC_SUBST(ac_configure_args)
 pike_cv_prog_CC="${CC}"
 
-if test x$pike_cv_func_dlopen$ac_cv_func_dld_link$ac_cv_func_shl_load = xnonono;
-then
-  if test x"$pike_cv_sys_os" != xWindows_NT ; then
-    with_dynamic_modules=no
-  fi
-fi
-
-if test x$with_dynamic_modules = xyes ; then
-  dmmsrc="modules/dynamic_module_makefile.in"
-else
-  dmmsrc="modules/static_module_makefile.in"
-fi
-
 AC_SUBST(dmmsrc)
 
 AC_OUTPUT(Makefile modules/static_module_makefile  post_modules/static_module_makefile:modules/static_module_makefile.in modules/dynamic_module_makefile:$dmmsrc post_modules/dynamic_module_makefile:$dmmsrc precompile.sh,[echo foo >stamp-h ; chmod +x precompile.sh])
diff --git a/src/constants.c b/src/constants.c
index 1424c19cae..82f492a89d 100644
--- a/src/constants.c
+++ b/src/constants.c
@@ -16,11 +16,11 @@
 #include "error.h"
 #include "block_alloc.h"
 
-RCSID("$Id: constants.c,v 1.21 2000/04/13 20:14:35 hubbe Exp $");
+RCSID("$Id: constants.c,v 1.22 2000/07/28 17:16:54 hubbe Exp $");
 
 struct mapping *builtin_constants = 0;
 
-struct mapping *get_builtin_constants(void)
+PMOD_EXPORT struct mapping *get_builtin_constants(void)
 {
   if(!builtin_constants)
     builtin_constants=allocate_mapping(20);
@@ -55,7 +55,7 @@ void low_add_constant(char *name, struct svalue *fun)
   free_string(p);
 }
 
-void add_global_program(char *name, struct program *p)
+PMOD_EXPORT void add_global_program(char *name, struct program *p)
 {
   struct svalue s;
   s.type=T_PROGRAM;
@@ -72,7 +72,7 @@ void add_global_program(char *name, struct program *p)
 BLOCK_ALLOC(callable,128)
 
 /* Eats one ref to 'type' and 'name' */
-struct callable *low_make_callable(c_fun fun,
+PMOD_EXPORT struct callable *low_make_callable(c_fun fun,
 				   struct pike_string *name,
 				   struct pike_string *type,
 				   INT16 flags,
@@ -98,7 +98,7 @@ struct callable *low_make_callable(c_fun fun,
   return f;
 }
 
-struct callable *make_callable(c_fun fun,
+PMOD_EXPORT struct callable *make_callable(c_fun fun,
 			       char *name,
 			       char *type,
 			       INT16 flags,
@@ -108,7 +108,7 @@ struct callable *make_callable(c_fun fun,
   return low_make_callable(fun,make_shared_string(name),parse_type(type),flags,optimize,docode);
 }
 
-struct callable *add_efun2(char *name,
+PMOD_EXPORT struct callable *add_efun2(char *name,
 			    c_fun fun,
 			    char *type,
 			    INT16 flags,
@@ -129,12 +129,12 @@ struct callable *add_efun2(char *name,
   return ret;
 }
 
-struct callable *add_efun(char *name, c_fun fun, char *type, INT16 flags)
+PMOD_EXPORT struct callable *add_efun(char *name, c_fun fun, char *type, INT16 flags)
 {
   return add_efun2(name,fun,type,flags,0,0);
 }
 
-struct callable *quick_add_efun(char *name, int name_length,
+PMOD_EXPORT struct callable *quick_add_efun(char *name, int name_length,
 				c_fun fun,
 				char *type, int type_length,
 				INT16 flags,
diff --git a/src/dynamic_buffer.c b/src/dynamic_buffer.c
index cfcc4b2812..057e77b513 100644
--- a/src/dynamic_buffer.c
+++ b/src/dynamic_buffer.c
@@ -9,11 +9,11 @@
 #include "error.h"
 #include "pike_memory.h"
 
-RCSID("$Id: dynamic_buffer.c,v 1.9 1998/11/22 11:02:42 hubbe Exp $");
+RCSID("$Id: dynamic_buffer.c,v 1.10 2000/07/28 17:16:54 hubbe Exp $");
 
 static dynamic_buffer buff;
 
-char *low_make_buf_space(INT32 space, dynamic_buffer *buf)
+PMOD_EXPORT char *low_make_buf_space(INT32 space, dynamic_buffer *buf)
 {
   char *ret;
 #ifdef PIKE_DEBUG
@@ -37,7 +37,7 @@ char *low_make_buf_space(INT32 space, dynamic_buffer *buf)
   return ret;
 }
 
-void low_my_putchar(char b,dynamic_buffer *buf)
+PMOD_EXPORT void low_my_putchar(char b,dynamic_buffer *buf)
 {
 #ifdef PIKE_DEBUG
   if(!buf->s.str)
@@ -46,7 +46,7 @@ void low_my_putchar(char b,dynamic_buffer *buf)
   low_make_buf_space(1,buf)[0]=b;
 }
 
-void low_my_binary_strcat(const char *b,INT32 l,dynamic_buffer *buf)
+PMOD_EXPORT void low_my_binary_strcat(const char *b,INT32 l,dynamic_buffer *buf)
 {
 #ifdef PIKE_DEBUG
   if(!buf->s.str)
@@ -56,14 +56,14 @@ void low_my_binary_strcat(const char *b,INT32 l,dynamic_buffer *buf)
   MEMCPY(low_make_buf_space(l,buf),b,l);
 }
 
-void debug_initialize_buf(dynamic_buffer *buf)
+PMOD_EXPORT void debug_initialize_buf(dynamic_buffer *buf)
 {
   buf->s.str=(char *)xalloc((buf->bufsize=BUFFER_BEGIN_SIZE));
   *(buf->s.str)=0;
   buf->s.len=0;
 }
 
-void low_reinit_buf(dynamic_buffer *buf)
+PMOD_EXPORT void low_reinit_buf(dynamic_buffer *buf)
 {
   if(!buf->s.str)
   {
@@ -74,7 +74,7 @@ void low_reinit_buf(dynamic_buffer *buf)
   }
 }
 
-void low_init_buf_with_string(string s, dynamic_buffer *buf)
+PMOD_EXPORT void low_init_buf_with_string(string s, dynamic_buffer *buf)
 {
   if(buf->s.str) { free(buf->s.str); buf->s.str=NULL; } 
   buf->s=s;
@@ -89,7 +89,7 @@ void low_init_buf_with_string(string s, dynamic_buffer *buf)
 #endif
 }
 
-string complex_free_buf(void)
+PMOD_EXPORT string complex_free_buf(void)
 {
   string tmp;
   if(!buff.s.str) return buff.s;
@@ -100,19 +100,19 @@ string complex_free_buf(void)
   return tmp;
 }
 
-void toss_buffer(dynamic_buffer *buf)
+PMOD_EXPORT void toss_buffer(dynamic_buffer *buf)
 {
   if(buf->s.str) free(buf->s.str);
   buf->s.str=0;
 }
 
-char *simple_free_buf(void)
+PMOD_EXPORT char *simple_free_buf(void)
 {
   if(!buff.s.str) return 0;
   return complex_free_buf().str;
 }
 
-struct pike_string *debug_low_free_buf(dynamic_buffer *buf)
+PMOD_EXPORT struct pike_string *debug_low_free_buf(dynamic_buffer *buf)
 {
   struct pike_string *q;
   if(!buf->s.str) return 0;
@@ -123,14 +123,14 @@ struct pike_string *debug_low_free_buf(dynamic_buffer *buf)
   return q;
 }
 
-struct pike_string *debug_free_buf(void) { return low_free_buf(&buff); }
-char *make_buf_space(INT32 space) { return low_make_buf_space(space,&buff); }
-void my_putchar(char b) { low_my_putchar(b,&buff); }
-void my_binary_strcat(const char *b,INT32 l) { low_my_binary_strcat(b,l,&buff); }
-void my_strcat(const char *b) { my_binary_strcat(b,strlen(b)); }
-void init_buf(void) { low_reinit_buf(&buff); }
-void init_buf_with_string(string s) { low_init_buf_with_string(s,&buff); }
-char *debug_return_buf(void)
+PMOD_EXPORT struct pike_string *debug_free_buf(void) { return low_free_buf(&buff); }
+PMOD_EXPORT char *make_buf_space(INT32 space) { return low_make_buf_space(space,&buff); }
+PMOD_EXPORT void my_putchar(char b) { low_my_putchar(b,&buff); }
+PMOD_EXPORT void my_binary_strcat(const char *b,INT32 l) { low_my_binary_strcat(b,l,&buff); }
+PMOD_EXPORT void my_strcat(const char *b) { my_binary_strcat(b,strlen(b)); }
+PMOD_EXPORT void init_buf(void) { low_reinit_buf(&buff); }
+PMOD_EXPORT void init_buf_with_string(string s) { low_init_buf_with_string(s,&buff); }
+PMOD_EXPORT char *debug_return_buf(void)
 {
   my_putchar(0);
   return buff.s.str;
diff --git a/src/dynamic_load.c b/src/dynamic_load.c
index 901c08fd54..dba154a419 100644
--- a/src/dynamic_load.c
+++ b/src/dynamic_load.c
@@ -8,7 +8,7 @@
 #  include "pike_macros.h"
 #  include "main.h"
 
-RCSID("$Id: dynamic_load.c,v 1.40 2000/06/27 15:15:11 grubba Exp $");
+RCSID("$Id: dynamic_load.c,v 1.41 2000/07/28 17:16:54 hubbe Exp $");
 
 #endif /* !TESTING */
 
@@ -67,6 +67,15 @@ static void *dlopen(const char *foo, int how)
   tmp=convert_string(foo, strlen(foo));
   ret=LoadLibrary(tmp);
   free((char *)tmp);
+  if(ret)
+  {
+    void ** psym=(void **)GetProcAddress(ret, "PikeSymbol");
+    if(psym)
+    {
+      extern void *PikeSymbol[];
+      *psym = PikeSymbol;
+    }
+  }
   return (void *)ret;
 }
 
@@ -214,7 +223,7 @@ static void dlclose(void *module)
 
 #ifndef TESTING
 
-#if defined(HAVE_DLOPEN) || defined(USE_DLD) || defined(USE_HPUX_DL)
+#if defined(HAVE_DLOPEN) || defined(USE_DLD) || defined(USE_HPUX_DL) || defined(USE_LOADLIBRARY)
 
 struct module_list
 {
@@ -319,11 +328,12 @@ void f_load_module(INT32 args)
 
 void init_dynamic_load(void)
 {
-#if defined(HAVE_DLOPEN) || defined(USE_DLD) || defined(USE_HPUX_DL)
+#if defined(HAVE_DLOPEN) || defined(USE_DLD) || defined(USE_HPUX_DL) || defined(USE_LOADLIBRARY)
   dlinit();
 
   
 /* function(string:program) */
+
   ADD_EFUN("load_module",f_load_module,tFunc(tStr,tPrg),OPT_EXTERNAL_DEPEND);
 #endif
 }
diff --git a/src/error.c b/src/error.c
index 31c0341aa8..a88fbf7e83 100644
--- a/src/error.c
+++ b/src/error.c
@@ -21,14 +21,14 @@
 #include "threads.h"
 #include "gc.h"
 
-RCSID("$Id: error.c,v 1.55 2000/07/07 01:46:21 hubbe Exp $");
+RCSID("$Id: error.c,v 1.56 2000/07/28 17:16:54 hubbe Exp $");
 
 #undef ATTRIBUTE
 #define ATTRIBUTE(X)
 
 
 #ifdef PIKE_DEBUG
-void check_recovery_context(void)
+PMOD_EXPORT void check_recovery_context(void)
 {
   char foo;
 #define TESTILITEST ((((char *)Pike_interpreter.recoveries)-((char *)&foo))*STACK_DIRECTION)
@@ -38,12 +38,12 @@ void check_recovery_context(void)
   /* Add more stuff here when required */
 }
 
-void pike_gdb_breakpoint(void) 
+PMOD_EXPORT void pike_gdb_breakpoint(void) 
 {
 }
 #endif
 
-JMP_BUF *init_recovery(JMP_BUF *r DEBUG_LINE_ARGS)
+PMOD_EXPORT JMP_BUF *init_recovery(JMP_BUF *r DEBUG_LINE_ARGS)
 {
   check_recovery_context();
 #ifdef PIKE_DEBUG
@@ -62,7 +62,7 @@ JMP_BUF *init_recovery(JMP_BUF *r DEBUG_LINE_ARGS)
   return r;
 }
 
-void pike_throw(void) ATTRIBUTE((noreturn))
+PMOD_EXPORT void pike_throw(void) ATTRIBUTE((noreturn))
 {
   while(Pike_interpreter.recoveries && throw_severity > Pike_interpreter.recoveries->severity)
   {
@@ -104,7 +104,7 @@ void pike_throw(void) ATTRIBUTE((noreturn))
   longjmp(Pike_interpreter.recoveries->recovery,1);
 }
 
-void push_error(char *description)
+PMOD_EXPORT void push_error(char *description)
 {
   push_text(description);
   f_backtrace(0);
@@ -115,7 +115,7 @@ struct svalue throw_value = { PIKE_T_INT };
 int throw_severity;
 static const char *in_error;
 
-void low_error(char *buf) ATTRIBUTE((noreturn))
+PMOD_EXPORT void low_error(char *buf) ATTRIBUTE((noreturn))
 {
   push_error(buf);
   free_svalue(& throw_value);
@@ -163,7 +163,7 @@ void va_error(const char *fmt, va_list args) ATTRIBUTE((noreturn))
   low_error(buf);
 }
 
-void new_error(const char *name, const char *text, struct svalue *oldsp,
+PMOD_EXPORT void new_error(const char *name, const char *text, struct svalue *oldsp,
 	       INT32 args, const char *file, int line) ATTRIBUTE((noreturn))
 {
   int i;
@@ -223,7 +223,7 @@ void new_error(const char *name, const char *text, struct svalue *oldsp,
   pike_throw();  /* Hope someone is catching, or we will be out of balls. */
 }
 
-void exit_on_error(void *msg)
+PMOD_EXPORT void exit_on_error(void *msg)
 {
   ONERROR tmp;
   SET_ONERROR(tmp,fatal_on_error,"Fatal in exit_on_error!");
@@ -248,7 +248,7 @@ void exit_on_error(void *msg)
   exit(1);
 }
 
-void fatal_on_error(void *msg)
+PMOD_EXPORT void fatal_on_error(void *msg)
 {
 #ifdef PIKE_DEBUG
   dump_backlog();
@@ -257,7 +257,7 @@ void fatal_on_error(void *msg)
   abort();
 }
 
-void error(const char *fmt,...) ATTRIBUTE((noreturn,format (printf, 1, 2)))
+PMOD_EXPORT void error(const char *fmt,...) ATTRIBUTE((noreturn,format (printf, 1, 2)))
 {
   va_list args;
   va_start(args,fmt);
@@ -265,7 +265,7 @@ void error(const char *fmt,...) ATTRIBUTE((noreturn,format (printf, 1, 2)))
   va_end(args);
 }
 
-void debug_fatal(const char *fmt, ...) ATTRIBUTE((noreturn,format (printf, 1, 2)))
+PMOD_EXPORT void debug_fatal(const char *fmt, ...) ATTRIBUTE((noreturn,format (printf, 1, 2)))
 {
   va_list args;
   static int in_fatal = 0;
@@ -463,7 +463,7 @@ void generic_error_va(struct object *o,
   pike_throw();  /* Hope someone is catching, or we will be out of balls. */
 }
 
-void generic_error(
+PMOD_EXPORT void generic_error(
   char *func,
   struct svalue *base_sp,  int args,
   char *desc, ...) ATTRIBUTE((noreturn,format (printf, 4, 5)))
@@ -472,7 +472,7 @@ void generic_error(
   ERROR_DONE(generic);
 }
 
-void index_error(
+PMOD_EXPORT void index_error(
   char *func,
   struct svalue *base_sp,  int args,
   struct svalue *val,
@@ -485,7 +485,7 @@ void index_error(
   ERROR_DONE(generic);
 }
 
-void bad_arg_error(
+PMOD_EXPORT void bad_arg_error(
   char *func,
   struct svalue *base_sp,  int args,
   int which_arg,
@@ -509,7 +509,7 @@ void bad_arg_error(
   ERROR_DONE(generic);
 }
 
-void math_error(
+PMOD_EXPORT void math_error(
   char *func,
   struct svalue *base_sp,  int args,
   struct svalue *number,
@@ -527,7 +527,7 @@ void math_error(
   ERROR_DONE(generic);
 }
 
-void resource_error(
+PMOD_EXPORT void resource_error(
   char *func,
   struct svalue *base_sp,  int args,
   char *resource_type,
@@ -540,7 +540,7 @@ void resource_error(
   ERROR_DONE(generic);
 }
 
-void permission_error(
+PMOD_EXPORT void permission_error(
   char *func,
   struct svalue *base_sp, int args,
   char *permission_type,
@@ -552,7 +552,7 @@ void permission_error(
   ERROR_DONE(generic);
 }
 
-void wrong_number_of_args_error(char *name, int args, int expected)
+PMOD_EXPORT void wrong_number_of_args_error(char *name, int args, int expected)
 {
   char *msg;
   if(expected>args)
diff --git a/src/error.h b/src/error.h
index e4cc9060b1..341171caf7 100644
--- a/src/error.h
+++ b/src/error.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: error.h,v 1.45 2000/07/07 00:21:48 hubbe Exp $
+ * $Id: error.h,v 1.46 2000/07/28 17:16:54 hubbe Exp $
  */
 #ifndef ERROR_H
 #define ERROR_H
@@ -169,18 +169,18 @@ extern int throw_severity;
 
 /* Prototypes begin here */
 void check_recovery_context(void);
-void pike_gdb_breakpoint(void);
-JMP_BUF *init_recovery(JMP_BUF *r DEBUG_LINE_ARGS);
-void pike_throw(void) ATTRIBUTE((noreturn));
-void push_error(char *description);
-void low_error(char *buf) ATTRIBUTE((noreturn));
+PMOD_EXPORT void pike_gdb_breakpoint(void);
+PMOD_EXPORT JMP_BUF *init_recovery(JMP_BUF *r DEBUG_LINE_ARGS);
+PMOD_EXPORT void pike_throw(void) ATTRIBUTE((noreturn));
+PMOD_EXPORT void push_error(char *description);
+PMOD_EXPORT void low_error(char *buf) ATTRIBUTE((noreturn));
 void va_error(const char *fmt, va_list args) ATTRIBUTE((noreturn));
-void new_error(const char *name, const char *text, struct svalue *oldsp,
+PMOD_EXPORT void new_error(const char *name, const char *text, struct svalue *oldsp,
 	       INT32 args, const char *file, int line) ATTRIBUTE((noreturn));
-void exit_on_error(void *msg);
-void fatal_on_error(void *msg);
-void error(const char *fmt,...) ATTRIBUTE((noreturn,format (printf, 1, 2)));
-void debug_fatal(const char *fmt, ...) ATTRIBUTE((noreturn,format (printf, 1, 2)));
+PMOD_EXPORT void exit_on_error(void *msg);
+PMOD_EXPORT void fatal_on_error(void *msg);
+PMOD_EXPORT void error(const char *fmt,...) ATTRIBUTE((noreturn,format (printf, 1, 2)));
+PMOD_EXPORT void debug_fatal(const char *fmt, ...) ATTRIBUTE((noreturn,format (printf, 1, 2)));
 void f_error_cast(INT32 args);
 void f_error_index(INT32 args);
 void f_error_describe(INT32 args);
diff --git a/src/fd_control.c b/src/fd_control.c
index 38ca902e26..2a4910a9fc 100644
--- a/src/fd_control.c
+++ b/src/fd_control.c
@@ -10,7 +10,7 @@
 #include "error.h"
 #include "fdlib.h"
 
-RCSID("$Id: fd_control.c,v 1.31 2000/07/07 15:23:06 grubba Exp $");
+RCSID("$Id: fd_control.c,v 1.32 2000/07/28 17:16:54 hubbe Exp $");
 
 #else /* TESTING */
 
@@ -69,7 +69,7 @@ RCSID("$Id: fd_control.c,v 1.31 2000/07/07 15:23:06 grubba Exp $");
 #endif
 
 
-int set_nonblocking(int fd,int which)
+PMOD_EXPORT int set_nonblocking(int fd,int which)
 {
   int ret;
 #ifdef PIKE_DEBUG
@@ -105,7 +105,7 @@ int set_nonblocking(int fd,int which)
   return ret;
 }
 
-int query_nonblocking(int fd)
+PMOD_EXPORT int query_nonblocking(int fd)
 {
   int ret;
 #ifdef PIKE_DEBUG
@@ -178,7 +178,7 @@ void cleanup_close_on_exec(void)
 }
 #endif /* HAVE_BROKEN_F_SETFD */
 
-int set_close_on_exec(int fd, int which)
+PMOD_EXPORT int set_close_on_exec(int fd, int which)
 {
 #ifndef HAVE_BROKEN_F_SETFD
   int ret;
diff --git a/src/fdlib.c b/src/fdlib.c
index 9450adc9f8..66f3285a57 100644
--- a/src/fdlib.c
+++ b/src/fdlib.c
@@ -3,7 +3,7 @@
 #include "error.h"
 #include <math.h>
 
-RCSID("$Id: fdlib.c,v 1.36 2000/07/02 16:04:07 grubba Exp $");
+RCSID("$Id: fdlib.c,v 1.37 2000/07/28 17:16:55 hubbe Exp $");
 
 #ifdef HAVE_WINSOCK_H
 
@@ -23,7 +23,7 @@ int first_free_handle;
 #define FDDEBUG(X)
 #endif
 
-char *debug_fd_info(int fd)
+PMOD_EXPORT char *debug_fd_info(int fd)
 {
   if(fd<0)
     return "BAD";
@@ -41,7 +41,7 @@ char *debug_fd_info(int fd)
   }
 }
 
-int debug_fd_query_properties(int fd, int guess)
+PMOD_EXPORT int debug_fd_query_properties(int fd, int guess)
 {
   switch(fd_type[fd])
   {
@@ -111,7 +111,7 @@ int debug_fd_stat(char *file, struct stat *buf)
   return stat(file, buf);
 }
 
-FD debug_fd_open(char *file, int open_mode, int create_mode)
+PMOD_EXPORT FD debug_fd_open(char *file, int open_mode, int create_mode)
 {
   HANDLE x;
   FD fd;
@@ -211,7 +211,7 @@ FD debug_fd_open(char *file, int open_mode, int create_mode)
   return fd;
 }
 
-FD debug_fd_socket(int domain, int type, int proto)
+PMOD_EXPORT FD debug_fd_socket(int domain, int type, int proto)
 {
   FD fd;
   SOCKET s;
@@ -245,7 +245,7 @@ FD debug_fd_socket(int domain, int type, int proto)
   return fd;
 }
 
-int debug_fd_pipe(int fds[2] DMALLOC_LINE_ARGS)
+PMOD_EXPORT int debug_fd_pipe(int fds[2] DMALLOC_LINE_ARGS)
 {
   HANDLE files[2];
   mt_lock(&fd_mutex);
@@ -288,7 +288,7 @@ int debug_fd_pipe(int fds[2] DMALLOC_LINE_ARGS)
   return 0;
 }
 
-FD debug_fd_accept(FD fd, struct sockaddr *addr, ACCEPT_SIZE_T *addrlen)
+PMOD_EXPORT FD debug_fd_accept(FD fd, struct sockaddr *addr, ACCEPT_SIZE_T *addrlen)
 {
   FD new_fd;
   SOCKET s;
@@ -332,7 +332,7 @@ FD debug_fd_accept(FD fd, struct sockaddr *addr, ACCEPT_SIZE_T *addrlen)
 
 
 #define SOCKFUN(NAME,X1,X2) \
-int PIKE_CONCAT(debug_fd_,NAME) X1 { SOCKET ret; \
+PMOD_EXPORT int PIKE_CONCAT(debug_fd_,NAME) X1 { SOCKET ret; \
   FDDEBUG(fprintf(stderr, #NAME " on %d (%d)\n",fd,da_handle[fd])); \
   mt_lock(&fd_mutex); \
   if(fd_type[fd] != FD_SOCKET) { \
@@ -376,7 +376,7 @@ SOCKFUN5(sendto,void *,int,int,struct sockaddr *,unsigned int)
 SOCKFUN1(shutdown, int)
 SOCKFUN1(listen, int)
 
-int debug_fd_connect (FD fd, struct sockaddr *a, int len)
+PMOD_EXPORT int debug_fd_connect (FD fd, struct sockaddr *a, int len)
 {
   SOCKET ret;
   mt_lock(&fd_mutex);
@@ -399,7 +399,7 @@ int debug_fd_connect (FD fd, struct sockaddr *a, int len)
   return (int)ret; 
 }
 
-int debug_fd_close(FD fd)
+PMOD_EXPORT int debug_fd_close(FD fd)
 {
   long h;
   int type;
@@ -438,7 +438,7 @@ int debug_fd_close(FD fd)
   return 0;
 }
 
-long debug_fd_write(FD fd, void *buf, long len)
+PMOD_EXPORT long debug_fd_write(FD fd, void *buf, long len)
 {
   DWORD ret;
   long handle;
@@ -484,7 +484,7 @@ long debug_fd_write(FD fd, void *buf, long len)
   }
 }
 
-long debug_fd_read(FD fd, void *to, long len)
+PMOD_EXPORT long debug_fd_read(FD fd, void *to, long len)
 {
   DWORD ret;
   int rret;
@@ -534,7 +534,7 @@ long debug_fd_read(FD fd, void *to, long len)
   }
 }
 
-long debug_fd_lseek(FD fd, long pos, int where)
+PMOD_EXPORT long debug_fd_lseek(FD fd, long pos, int where)
 {
   long ret;
   mt_lock(&fd_mutex);
@@ -564,7 +564,7 @@ long debug_fd_lseek(FD fd, long pos, int where)
   return ret;
 }
 
-long debug_fd_ftruncate(FD fd, long len)
+PMOD_EXPORT long debug_fd_ftruncate(FD fd, long len)
 {
   long ret;
   LONG oldfp_lo, oldfp_hi;
@@ -599,7 +599,7 @@ long debug_fd_ftruncate(FD fd, long len)
   return 0;
 }
 
-int debug_fd_flock(FD fd, int oper)
+PMOD_EXPORT int debug_fd_flock(FD fd, int oper)
 {
   long ret;
   mt_lock(&fd_mutex);
@@ -658,7 +658,7 @@ static long convert_filetime_to_time_t(FILETIME tmp)
   return (long)floor(t);
 }
 
-int debug_fd_fstat(FD fd, struct stat *s)
+PMOD_EXPORT int debug_fd_fstat(FD fd, struct stat *s)
 {
   DWORD x;
 
@@ -738,7 +738,7 @@ static void dump_FDSET(FD_SET *x, int fds)
  * If the backend works correctly, fds is zero when there are no fds.
  * /Hubbe
  */
-int debug_fd_select(int fds, FD_SET *a, FD_SET *b, FD_SET *c, struct timeval *t)
+PMOD_EXPORT int debug_fd_select(int fds, FD_SET *a, FD_SET *b, FD_SET *c, struct timeval *t)
 {
   int ret;
 
@@ -771,7 +771,7 @@ int debug_fd_select(int fds, FD_SET *a, FD_SET *b, FD_SET *c, struct timeval *t)
 }
 
 
-int debug_fd_ioctl(FD fd, int cmd, void *data)
+PMOD_EXPORT int debug_fd_ioctl(FD fd, int cmd, void *data)
 {
   int ret;
   FDDEBUG(fprintf(stderr,"ioctl(%d (%d,%d,%p)\n",fd,da_handle[fd],cmd,data));
@@ -794,7 +794,7 @@ int debug_fd_ioctl(FD fd, int cmd, void *data)
 }
 
 
-FD debug_fd_dup(FD from)
+PMOD_EXPORT FD debug_fd_dup(FD from)
 {
   FD fd;
   HANDLE x,p=GetCurrentProcess();
@@ -819,7 +819,7 @@ FD debug_fd_dup(FD from)
   return fd;
 }
 
-FD debug_fd_dup2(FD from, FD to)
+PMOD_EXPORT FD debug_fd_dup2(FD from, FD to)
 {
   HANDLE x,p=GetCurrentProcess();
   if(!DuplicateHandle(p,(HANDLE)da_handle[from],p,&x,0,0,DUPLICATE_SAME_ACCESS))
@@ -860,7 +860,7 @@ FD debug_fd_dup2(FD from, FD to)
 #endif /* HAVE_WINSOCK_H */
 
 #ifdef EMULATE_DIRECT
-DIR *opendir(char *dir)
+PMOD_EXPORT DIR *opendir(char *dir)
 {
   int len=strlen(dir);
   char *foo;
@@ -890,7 +890,7 @@ DIR *opendir(char *dir)
   return ret;
 }
 
-int readdir_r(DIR *dir, struct direct *tmp ,struct direct **d)
+PMOD_EXPORT int readdir_r(DIR *dir, struct direct *tmp ,struct direct **d)
 {
   if(dir->first)
   {
@@ -908,7 +908,7 @@ int readdir_r(DIR *dir, struct direct *tmp ,struct direct **d)
   }
 }
 
-void closedir(DIR *dir)
+PMOD_EXPORT void closedir(DIR *dir)
 {
   FindClose(dir->h);
   free((char *)dir);
diff --git a/src/fdlib.h b/src/fdlib.h
index c7b2b96941..dc25cbf810 100644
--- a/src/fdlib.h
+++ b/src/fdlib.h
@@ -1,5 +1,5 @@
 /*
- * $Id: fdlib.h,v 1.33 2000/07/07 15:40:25 grubba Exp $
+ * $Id: fdlib.h,v 1.34 2000/07/28 17:16:55 hubbe Exp $
  */
 #ifndef FDLIB_H
 #define FDLIB_H
@@ -69,11 +69,11 @@
 
 typedef int FD;
 
-#define SOCKFUN1(NAME,T1) int PIKE_CONCAT(debug_fd_,NAME) (FD,T1);
-#define SOCKFUN2(NAME,T1,T2) int PIKE_CONCAT(debug_fd_,NAME) (FD,T1,T2);
-#define SOCKFUN3(NAME,T1,T2,T3) int PIKE_CONCAT(debug_fd_,NAME) (FD,T1,T2,T3);
-#define SOCKFUN4(NAME,T1,T2,T3,T4) int PIKE_CONCAT(debug_fd_,NAME) (FD,T1,T2,T3,T4);
-#define SOCKFUN5(NAME,T1,T2,T3,T4,T5) int PIKE_CONCAT(debug_fd_,NAME) (FD,T1,T2,T3,T4,T5);
+#define SOCKFUN1(NAME,T1) PMOD_EXPORT int PIKE_CONCAT(debug_fd_,NAME) (FD,T1);
+#define SOCKFUN2(NAME,T1,T2) PMOD_EXPORT int PIKE_CONCAT(debug_fd_,NAME) (FD,T1,T2);
+#define SOCKFUN3(NAME,T1,T2,T3) PMOD_EXPORT int PIKE_CONCAT(debug_fd_,NAME) (FD,T1,T2,T3);
+#define SOCKFUN4(NAME,T1,T2,T3,T4) PMOD_EXPORT int PIKE_CONCAT(debug_fd_,NAME) (FD,T1,T2,T3,T4);
+#define SOCKFUN5(NAME,T1,T2,T3,T4,T5) PMOD_EXPORT int PIKE_CONCAT(debug_fd_,NAME) (FD,T1,T2,T3,T4,T5);
 
 
 #define fd_info(fd) debug_fd_info(dmalloc_touch_fd(fd))
@@ -116,13 +116,13 @@ char *debug_fd_info(int fd);
 int debug_fd_query_properties(int fd, int guess);
 void fd_init();
 void fd_exit();
-int debug_fd_stat(char *file, struct stat *buf);
-FD debug_fd_open(char *file, int open_mode, int create_mode);
-FD debug_fd_socket(int domain, int type, int proto);
-int debug_fd_pipe(int fds[2] DMALLOC_LINE_ARGS);
-FD debug_fd_accept(FD fd, struct sockaddr *addr, ACCEPT_SIZE_T *addrlen);
+PMOD_EXPORT int debug_fd_stat(char *file, struct stat *buf);
+PMOD_EXPORT FD debug_fd_open(char *file, int open_mode, int create_mode);
+PMOD_EXPORT FD debug_fd_socket(int domain, int type, int proto);
+PMOD_EXPORT int debug_fd_pipe(int fds[2] DMALLOC_LINE_ARGS);
+PMOD_EXPORT FD debug_fd_accept(FD fd, struct sockaddr *addr, ACCEPT_SIZE_T *addrlen);
 SOCKFUN2(bind, struct sockaddr *, int)
-int debug_fd_connect (FD fd, struct sockaddr *a, int len);
+PMOD_EXPORT int debug_fd_connect (FD fd, struct sockaddr *a, int len);
 SOCKFUN4(getsockopt,int,int,void*,ACCEPT_SIZE_T *)
 SOCKFUN4(setsockopt,int,int,void*,int)
 SOCKFUN3(recv,void *,int,int)
@@ -133,17 +133,17 @@ SOCKFUN3(send,void *,int,int)
 SOCKFUN5(sendto,void *,int,int,struct sockaddr *,unsigned int)
 SOCKFUN1(shutdown, int)
 SOCKFUN1(listen, int)
-int debug_fd_close(FD fd);
-long debug_fd_write(FD fd, void *buf, long len);
-long debug_fd_read(FD fd, void *to, long len);
-long debug_fd_lseek(FD fd, long pos, int where);
-long debug_fd_ftruncate(FD fd, long len);
-int debug_fd_flock(FD fd, int oper);
-int debug_fd_fstat(FD fd, struct stat *s);
-int debug_fd_select(int fds, FD_SET *a, FD_SET *b, FD_SET *c, struct timeval *t);
-int debug_fd_ioctl(FD fd, int cmd, void *data);
-FD debug_fd_dup(FD from);
-FD debug_fd_dup2(FD from, FD to);
+PMOD_EXPORT int debug_fd_close(FD fd);
+PMOD_EXPORT long debug_fd_write(FD fd, void *buf, long len);
+PMOD_EXPORT long debug_fd_read(FD fd, void *to, long len);
+PMOD_EXPORT long debug_fd_lseek(FD fd, long pos, int where);
+PMOD_EXPORT long debug_fd_ftruncate(FD fd, long len);
+PMOD_EXPORT int debug_fd_flock(FD fd, int oper);
+PMOD_EXPORT int debug_fd_fstat(FD fd, struct stat *s);
+PMOD_EXPORT int debug_fd_select(int fds, FD_SET *a, FD_SET *b, FD_SET *c, struct timeval *t);
+PMOD_EXPORT int debug_fd_ioctl(FD fd, int cmd, void *data);
+PMOD_EXPORT FD debug_fd_dup(FD from);
+PMOD_EXPORT FD debug_fd_dup2(FD from, FD to);
 /* Prototypes end here */
 
 #undef SOCKFUN1
@@ -409,4 +409,9 @@ typedef struct my_fd_set_s my_fd_set;
 
 #endif /* Don't HAVE_WINSOCK */
 
+PMOD_PROTO extern int pike_make_pipe(int *fds);
+PMOD_PROTO extern int fd_from_object(struct object *o);
+PMOD_PROTO extern void create_proxy_pipe(struct object *o, int for_reading);
+PMOD_PROTO struct object *file_make_object_from_fd(int fd, int mode, int guess);
+
 #endif /* FDLIB_H */
diff --git a/src/fsort.c b/src/fsort.c
index 6b3ed98ec0..ec89719be8 100644
--- a/src/fsort.c
+++ b/src/fsort.c
@@ -9,8 +9,9 @@
 #include "global.h"
 #include "error.h"
 #include "fsort.h"
+#include "main.h"
 
-RCSID("$Id: fsort.c,v 1.12 1999/04/30 07:25:07 hubbe Exp $");
+RCSID("$Id: fsort.c,v 1.13 2000/07/28 17:16:55 hubbe Exp $");
 
 #define CMP(X,Y) ( (*cmpfun)((void *)(X),(void *)(Y)) )
 #define EXTRA_ARGS ,fsortfun cmpfun
diff --git a/src/fsort_template.h b/src/fsort_template.h
index edd0ce2dbb..00b4de1628 100644
--- a/src/fsort_template.h
+++ b/src/fsort_template.h
@@ -1,5 +1,5 @@
 /*
- * $Id: fsort_template.h,v 1.6 1999/05/03 07:04:16 hubbe Exp $
+ * $Id: fsort_template.h,v 1.7 2000/07/28 17:16:55 hubbe Exp $
  */
 
 #ifndef SWAP
@@ -46,10 +46,6 @@ static void MKNAME(_do_sort)(register TYPE *bas,
       if(--max_recursion <= 0)
       {
 	long howmany,x,y,z;
-#ifdef PIKE_DEBUG
-	extern int d_flag;
-#endif
-	
 	howmany=((((char *)last)-((char *)bas))/SIZE)+1;
 	if(howmany<2) return;
 	
@@ -159,7 +155,6 @@ void ID(register TYPE *bas,
 #endif
   )
 {
-  extern int my_log2(unsigned INT32 x);
   MKNAME(_do_sort)(bas,last, my_log2( last-bas ) * 2 XARGS);;
 }
 
diff --git a/src/gc.c b/src/gc.c
index 3f7ce9f40a..b5f2e4b4b7 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -29,7 +29,7 @@ struct callback *gc_evaluator_callback=0;
 
 #include "block_alloc.h"
 
-RCSID("$Id: gc.c,v 1.109 2000/07/18 06:53:58 mast Exp $");
+RCSID("$Id: gc.c,v 1.110 2000/07/28 17:16:55 hubbe Exp $");
 
 /* Run garbage collect approximately every time
  * 20 percent of all arrays, objects and programs is
@@ -96,7 +96,7 @@ RCSID("$Id: gc.c,v 1.109 2000/07/18 06:53:58 mast Exp $");
 INT32 num_objects = 1;		/* Account for empty_array. */
 INT32 num_allocs =0;
 INT32 alloc_threshold = MIN_ALLOC_THRESHOLD;
-int Pike_in_gc = 0;
+PMOD_EXPORT int Pike_in_gc = 0;
 struct pike_queue gc_mark_queue;
 time_t last_gc;
 
@@ -771,7 +771,7 @@ void describe_something(void *a, int t, int indent, int depth, int flags)
   d_flag=tmp;
 }
 
-void describe(void *x)
+PMOD_EXPORT void describe(void *x)
 {
   describe_something(x, attempt_to_identify(x), 0, 2, 0);
 }
diff --git a/src/gc.h b/src/gc.h
index 9f72841d89..b021e5dd78 100644
--- a/src/gc.h
+++ b/src/gc.h
@@ -1,5 +1,5 @@
 /*
- * $Id: gc.h,v 1.56 2000/07/18 06:53:58 mast Exp $
+ * $Id: gc.h,v 1.57 2000/07/28 17:16:55 hubbe Exp $
  */
 #ifndef GC_H
 #define GC_H
@@ -102,22 +102,32 @@ extern size_t gc_ext_weak_refs;
 typedef void gc_cycle_check_cb (void *data, int weak);
 
 /* Prototypes begin here */
+struct gc_frame;
 struct callback *debug_add_gc_callback(callback_func call,
 				 void *arg,
 				 callback_func free_func);
 void dump_gc_info(void);
 TYPE_T attempt_to_identify(void *something);
-void describe_location(void *memblock, int type, void *location,int indent, int depth, int flags);
-void debug_gc_fatal(void *a, int flags, const char *fmt, ...)
-  ATTRIBUTE((format(printf, 3, 4)));
+void describe_location(void *real_memblock,
+		       int real_type,
+		       void *location,
+		       int indent,
+		       int depth,
+		       int flags);
+void debug_gc_fatal(void *a, int flags, const char *fmt, ...);
 void debug_gc_xmark_svalues(struct svalue *s, int num, char *fromwhere);
 void debug_gc_check_svalues(struct svalue *s, int num, TYPE_T t, void *data);
 void debug_gc_check_weak_svalues(struct svalue *s, int num, TYPE_T t, void *data);
 void debug_gc_check_short_svalue(union anything *u, TYPE_T type, TYPE_T t, void *data);
 void debug_gc_check_weak_short_svalue(union anything *u, TYPE_T type, TYPE_T t, void *data);
 int debug_gc_check(void *x, TYPE_T t, void *data);
+void low_describe_something(void *a,
+			    int t,
+			    int indent,
+			    int depth,
+			    int flags);
 void describe_something(void *a, int t, int indent, int depth, int flags);
-void describe(void *x);
+PMOD_EXPORT void describe(void *x);
 void debug_describe_svalue(struct svalue *s);
 void debug_gc_touch(void *a);
 INT32 real_gc_check(void *a);
@@ -127,18 +137,17 @@ void gc_add_extra_ref(void *a);
 void gc_free_extra_ref(void *a);
 int debug_gc_is_referenced(void *a);
 int gc_external_mark3(void *a, void *in, char *where);
+void debug_really_free_gc_frame(struct gc_frame *l);
 int gc_do_weak_free(void *a);
 int gc_mark(void *a);
+void gc_cycle_enqueue(gc_cycle_check_cb *checkfn, void *data, int weak);
+void gc_cycle_run_queue();
 int gc_cycle_push(void *x, struct marker *m, int weak);
-void gc_set_rec_last(struct marker *m);
 void do_gc_recurse_svalues(struct svalue *s, int num);
 void do_gc_recurse_short_svalue(union anything *u, TYPE_T type);
 int gc_do_free(void *a);
-int gc_is_internal(void *a);
 int do_gc(void);
 void f__gc_status(INT32 args);
-void gc_cycle_enqueue(gc_cycle_check_cb *checkfn, void *data, int weak);
-void gc_cycle_run_queue();
 /* Prototypes end here */
 
 #define gc_fatal \
diff --git a/src/global.h b/src/global.h
index 292365da91..072c1183df 100644
--- a/src/global.h
+++ b/src/global.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: global.h,v 1.43 2000/06/24 07:20:27 hubbe Exp $
+ * $Id: global.h,v 1.44 2000/07/28 17:16:55 hubbe Exp $
  */
 #ifndef GLOBAL_H
 #define GLOBAL_H
@@ -281,6 +281,21 @@ typedef struct p_wchar_p
 #define INLINE
 #endif
 
+/* PMOD_EXPORT exports a function / variable vfsh. 
+ * Putting PMOD_PROTO in front of a prototype does nothing.
+ */
+#ifndef PMOD_EXPORT
+#define PMOD_EXPORT
+#endif
+
+
+/* PMOD_PROTO is essentially the same as PMOD_EXPORT, but
+ * it exports the identifier even if it only a prototype.
+ */
+#ifndef PMOD_PROTO
+#define PMOD_PROTO
+#endif
+
 #if defined(PURIFY) || defined(__CHECKER__) || defined(DEBUG_MALLOC)
 #define DO_PIKE_CLEANUP
 #endif
diff --git a/src/interpret.c b/src/interpret.c
index 0fd0a8855a..242f3ca701 100644
--- a/src/interpret.c
+++ b/src/interpret.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: interpret.c,v 1.157 2000/07/07 01:24:14 hubbe Exp $");
+RCSID("$Id: interpret.c,v 1.158 2000/07/28 17:16:55 hubbe Exp $");
 #include "interpret.h"
 #include "object.h"
 #include "program.h"
@@ -62,8 +62,8 @@ RCSID("$Id: interpret.c,v 1.157 2000/07/07 01:24:14 hubbe Exp $");
 /* Pike_sp points to first unused value on stack
  * (much simpler than letting it point at the last used value.)
  */
-struct Pike_interpreter Pike_interpreter;
-int stack_size = EVALUATOR_STACK_SIZE;
+PMOD_EXPORT struct Pike_interpreter Pike_interpreter;
+PMOD_EXPORT int stack_size = EVALUATOR_STACK_SIZE;
 
 
 /* mark stack, used to store markers into the normal stack */
@@ -266,7 +266,7 @@ void lvalue_to_svalue_no_free(struct svalue *to,struct svalue *lval)
   }
 }
 
-void assign_lvalue(struct svalue *lval,struct svalue *from)
+PMOD_EXPORT void assign_lvalue(struct svalue *lval,struct svalue *from)
 {
 #ifdef PIKE_SECURITY
   if(lval->type <= MAX_COMPLEX)
@@ -668,7 +668,7 @@ static
 #endif
 
 
-void mega_apply2(enum apply_type type, INT32 args, void *arg1, void *arg2)
+PMOD_EXPORT void mega_apply2(enum apply_type type, INT32 args, void *arg1, void *arg2)
 {
   struct object *o;
   struct pike_frame *scope=0;
@@ -1182,7 +1182,7 @@ static void restore_creds(struct object *creds)
   Pike_interpreter.current_creds = creds;
 }
 
-void mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2)
+PMOD_EXPORT void mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2)
 {
   ONERROR tmp;
   if(Pike_interpreter.current_creds)
@@ -1229,12 +1229,12 @@ static int o_catch(unsigned char *pc)
   }
 }
 
-void f_call_function(INT32 args)
+PMOD_EXPORT void f_call_function(INT32 args)
 {
   mega_apply(APPLY_STACK,args,0,0);
 }
 
-int apply_low_safe_and_stupid(struct object *o, INT32 offset)
+PMOD_EXPORT int apply_low_safe_and_stupid(struct object *o, INT32 offset)
 {
   JMP_BUF tmp;
   struct pike_frame *new_frame=alloc_pike_frame();
@@ -1279,7 +1279,7 @@ int apply_low_safe_and_stupid(struct object *o, INT32 offset)
   return ret;
 }
 
-void safe_apply_low(struct object *o,int fun,int args)
+PMOD_EXPORT void safe_apply_low(struct object *o,int fun,int args)
 {
   JMP_BUF recovery;
 
@@ -1327,7 +1327,7 @@ void safe_apply_low(struct object *o,int fun,int args)
 }
 
 
-void safe_apply(struct object *o, char *fun ,INT32 args)
+PMOD_EXPORT void safe_apply(struct object *o, char *fun ,INT32 args)
 {
 #ifdef PIKE_DEBUG
   if(!o->prog) fatal("Apply safe on destructed object.\n");
@@ -1335,7 +1335,7 @@ void safe_apply(struct object *o, char *fun ,INT32 args)
   safe_apply_low(o, find_identifier(fun, o->prog), args);
 }
 
-void apply_lfun(struct object *o, int fun, int args)
+PMOD_EXPORT void apply_lfun(struct object *o, int fun, int args)
 {
 #ifdef PIKE_DEBUG
   if(fun < 0 || fun >= NUM_LFUNS)
@@ -1347,20 +1347,20 @@ void apply_lfun(struct object *o, int fun, int args)
   apply_low(o, (int)FIND_LFUN(o->prog,fun), args);
 }
 
-void apply_shared(struct object *o,
+PMOD_EXPORT void apply_shared(struct object *o,
 		  struct pike_string *fun,
 		  int args)
 {
   apply_low(o, find_shared_string_identifier(fun, o->prog), args);
 }
 
-void apply(struct object *o, char *fun, int args)
+PMOD_EXPORT void apply(struct object *o, char *fun, int args)
 {
   apply_low(o, find_identifier(fun, o->prog), args);
 }
 
 
-void apply_svalue(struct svalue *s, INT32 args)
+PMOD_EXPORT void apply_svalue(struct svalue *s, INT32 args)
 {
   if(s->type==T_INT)
   {
diff --git a/src/interpret.h b/src/interpret.h
index 8caa167929..87464f9707 100644
--- a/src/interpret.h
+++ b/src/interpret.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: interpret.h,v 1.51 2000/07/07 15:23:56 grubba Exp $
+ * $Id: interpret.h,v 1.52 2000/07/28 17:16:55 hubbe Exp $
  */
 #ifndef INTERPRET_H
 #define INTERPRET_H
@@ -216,33 +216,35 @@ int pop_sp_mark(void);
 void init_interpreter(void);
 void lvalue_to_svalue_no_free(struct svalue *to,struct svalue *lval);
 void assign_lvalue(struct svalue *lval,struct svalue *from);
-union anything *get_pointer_if_this_type(struct svalue *lval, TYPE_T t);
+PMOD_EXPORT union anything *get_pointer_if_this_type(struct svalue *lval, TYPE_T t);
 void print_return_value(void);
 void reset_evaluator(void);
 struct backlog;
 void dump_backlog(void);
 BLOCK_ALLOC(pike_frame,128)
 
-void mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2);
-void f_call_function(INT32 args);
-int apply_low_safe_and_stupid(struct object *o, INT32 offset);
-void safe_apply_low(struct object *o,int fun,int args);
-void safe_apply(struct object *o, char *fun ,INT32 args);
-void apply_lfun(struct object *o, int fun, int args);
-void apply_shared(struct object *o,
+PMOD_EXPORT void mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2);
+PMOD_EXPORT void f_call_function(INT32 args);
+PMOD_EXPORT int apply_low_safe_and_stupid(struct object *o, INT32 offset);
+PMOD_EXPORT void safe_apply_low(struct object *o,int fun,int args);
+PMOD_EXPORT void safe_apply(struct object *o, char *fun ,INT32 args);
+PMOD_EXPORT void apply_lfun(struct object *o, int fun, int args);
+PMOD_EXPORT void apply_shared(struct object *o,
 		  struct pike_string *fun,
 		  int args);
-void apply(struct object *o, char *fun, int args);
-void apply_svalue(struct svalue *s, INT32 args);
-void slow_check_stack(void);
+PMOD_EXPORT void apply(struct object *o, char *fun, int args);
+PMOD_EXPORT void apply_svalue(struct svalue *s, INT32 args);
+PMOD_EXPORT void slow_check_stack(void);
 void cleanup_interpret(void);
 void really_clean_up_interpret(void);
 /* Prototypes end here */
 
-extern int Pike_stack_size;
-struct callback;
-extern struct callback_list evaluator_callbacks;
-extern void call_callback(struct callback_list *, void *);
+PMOD_EXPORT extern int d_flag; /* really in main.c */
+
+PMOD_EXPORT extern int Pike_stack_size;
+PMOD_EXPORT struct callback;
+PMOD_EXPORT extern struct callback_list evaluator_callbacks;
+PMOD_EXPORT extern void call_callback(struct callback_list *, void *);
 
 /* Things to try:
  * we could reduce thread swapping to a pointer operation if
@@ -255,7 +257,7 @@ extern void call_callback(struct callback_list *, void *);
  * The above define could also be used to facilitate dynamic loading
  * on Win32..
  */
-extern struct Pike_interpreter Pike_interpreter;
+PMOD_EXPORT extern struct Pike_interpreter Pike_interpreter;
 
 #define Pike_sp Pike_interpreter.stack_pointer
 #define Pike_fp Pike_interpreter.frame_pointer
diff --git a/src/main.c b/src/main.c
index e8b5c83880..3616deded7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: main.c,v 1.93 2000/07/07 01:47:05 hubbe Exp $");
+RCSID("$Id: main.c,v 1.94 2000/07/28 17:16:55 hubbe Exp $");
 #include "fdlib.h"
 #include "backend.h"
 #include "module.h"
@@ -64,15 +64,15 @@ int try_use_mmx;
 char *master_file;
 char **ARGV;
 
-int debug_options=0;
-int runtime_options=0;
-int d_flag=0;
-int c_flag=0;
-int t_flag=0;
-int default_t_flag=0;
-int a_flag=0;
-int l_flag=0;
-int p_flag=0;
+PMOD_EXPORT int debug_options=0;
+PMOD_EXPORT int runtime_options=0;
+PMOD_EXPORT int d_flag=0;
+PMOD_EXPORT int c_flag=0;
+PMOD_EXPORT int t_flag=0;
+PMOD_EXPORT int default_t_flag=0;
+PMOD_EXPORT int a_flag=0;
+PMOD_EXPORT int l_flag=0;
+PMOD_EXPORT int p_flag=0;
 #ifdef YYDEBUG
 extern int yydebug;
 #endif /* YYDEBUG */
@@ -97,7 +97,7 @@ static void time_to_exit(struct callback *cb,void *tmp,void *ignored)
 
 static struct callback_list post_master_callbacks;
 
-struct callback *add_post_master_callback(callback_func call,
+PMOD_EXPORT struct callback *add_post_master_callback(callback_func call,
 					  void *arg,
 					  callback_func free_func)
 {
@@ -107,7 +107,7 @@ struct callback *add_post_master_callback(callback_func call,
 
 static struct callback_list exit_callbacks;
 
-struct callback *add_exit_callback(callback_func call,
+PMOD_EXPORT struct callback *add_exit_callback(callback_func call,
 				   void *arg,
 				   callback_func free_func)
 {
diff --git a/src/mapping.c b/src/mapping.c
index 07c7dfa698..f0c96a90cc 100644
--- a/src/mapping.c
+++ b/src/mapping.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: mapping.c,v 1.93 2000/07/18 05:48:20 mast Exp $");
+RCSID("$Id: mapping.c,v 1.94 2000/07/28 17:16:55 hubbe Exp $");
 #include "main.h"
 #include "object.h"
 #include "mapping.h"
@@ -170,7 +170,7 @@ static void init_mapping(struct mapping *m, INT32 size)
 
 /* This function allocates an empty mapping with room for 'size' values
  */
-struct mapping *debug_allocate_mapping(int size)
+PMOD_EXPORT struct mapping *debug_allocate_mapping(int size)
 {
   struct mapping *m;
 
@@ -190,7 +190,7 @@ struct mapping *debug_allocate_mapping(int size)
 }
 
 
-void really_free_mapping_data(struct mapping_data *md)
+PMOD_EXPORT void really_free_mapping_data(struct mapping_data *md)
 {
   INT32 e;
   struct keypair *k;
@@ -210,7 +210,7 @@ void really_free_mapping_data(struct mapping_data *md)
   free((char *) md);
 }
 
-void do_free_mapping(struct mapping *m)
+PMOD_EXPORT void do_free_mapping(struct mapping *m)
 {
   if (m)
     free_mapping(m);
@@ -514,7 +514,7 @@ struct mapping_data *copy_mapping_data(struct mapping_data *md)
  * I only use it when the type fields MUST be correct, which is not
  * very often.
  */
-void mapping_fix_type_field(struct mapping *m)
+PMOD_EXPORT void mapping_fix_type_field(struct mapping *m)
 {
   INT32 e;
   struct keypair *k;
@@ -542,7 +542,7 @@ void mapping_fix_type_field(struct mapping *m)
 /* This function inserts key:val into the mapping m.
  * Same as doing m[key]=val; in pike.
  */
-void low_mapping_insert(struct mapping *m,
+PMOD_EXPORT void low_mapping_insert(struct mapping *m,
 			struct svalue *key,
 			struct svalue *val,
 			int overwrite)
@@ -640,14 +640,14 @@ void low_mapping_insert(struct mapping *m,
 #endif
 }
 
-void mapping_insert(struct mapping *m,
+PMOD_EXPORT void mapping_insert(struct mapping *m,
 		    struct svalue *key,
 		    struct svalue *val)
 {
   low_mapping_insert(m,key,val,1);
 }
 
-union anything *mapping_get_item_ptr(struct mapping *m,
+PMOD_EXPORT union anything *mapping_get_item_ptr(struct mapping *m,
 				     struct svalue *key,
 				     TYPE_T t)
 {
@@ -753,7 +753,7 @@ union anything *mapping_get_item_ptr(struct mapping *m,
   return & ( k->val.u );
 }
 
-void map_delete_no_free(struct mapping *m,
+PMOD_EXPORT void map_delete_no_free(struct mapping *m,
 			struct svalue *key,
 			struct svalue *to)
 {
@@ -834,7 +834,7 @@ void map_delete_no_free(struct mapping *m,
   return;
 }
 
-void check_mapping_for_destruct(struct mapping *m)
+PMOD_EXPORT void check_mapping_for_destruct(struct mapping *m)
 {
   INT32 e;
   struct keypair *k, **prev;
@@ -906,7 +906,7 @@ void check_mapping_for_destruct(struct mapping *m)
   }
 }
 
-struct svalue *low_mapping_lookup(struct mapping *m,
+PMOD_EXPORT struct svalue *low_mapping_lookup(struct mapping *m,
 				  struct svalue *key)
 {
   unsigned INT32 h,h2;
@@ -932,7 +932,7 @@ struct svalue *low_mapping_lookup(struct mapping *m,
   return 0;
 }
 
-struct svalue *low_mapping_string_lookup(struct mapping *m,
+PMOD_EXPORT struct svalue *low_mapping_string_lookup(struct mapping *m,
 					 struct pike_string *p)
 {
   struct svalue tmp;
@@ -941,7 +941,7 @@ struct svalue *low_mapping_string_lookup(struct mapping *m,
   return low_mapping_lookup(m, &tmp);
 }
 
-void mapping_string_insert(struct mapping *m,
+PMOD_EXPORT void mapping_string_insert(struct mapping *m,
 			   struct pike_string *p,
 			   struct svalue *val)
 {
@@ -951,7 +951,7 @@ void mapping_string_insert(struct mapping *m,
   mapping_insert(m, &tmp, val);
 }
 
-void mapping_string_insert_string(struct mapping *m,
+PMOD_EXPORT void mapping_string_insert_string(struct mapping *m,
 				  struct pike_string *p,
 				  struct pike_string *val)
 {
@@ -961,7 +961,7 @@ void mapping_string_insert_string(struct mapping *m,
   mapping_string_insert(m, p, &tmp);
 }
 
-struct svalue *simple_mapping_string_lookup(struct mapping *m,
+PMOD_EXPORT struct svalue *simple_mapping_string_lookup(struct mapping *m,
 					    char *p)
 {
   struct pike_string *tmp;
@@ -970,7 +970,7 @@ struct svalue *simple_mapping_string_lookup(struct mapping *m,
   return 0;
 }
 
-struct svalue *mapping_mapping_lookup(struct mapping *m,
+PMOD_EXPORT struct svalue *mapping_mapping_lookup(struct mapping *m,
 				      struct svalue *key1,
 				      struct svalue *key2,
 				      int create)
@@ -1014,7 +1014,7 @@ struct svalue *mapping_mapping_lookup(struct mapping *m,
 }
 
 
-struct svalue *mapping_mapping_string_lookup(struct mapping *m,
+PMOD_EXPORT struct svalue *mapping_mapping_string_lookup(struct mapping *m,
 				      struct pike_string *key1,
 				      struct pike_string *key2,
 				      int create)
@@ -1029,7 +1029,7 @@ struct svalue *mapping_mapping_string_lookup(struct mapping *m,
 
 
 
-void mapping_index_no_free(struct svalue *dest,
+PMOD_EXPORT void mapping_index_no_free(struct svalue *dest,
 			   struct mapping *m,
 			   struct svalue *key)
 {
@@ -1048,7 +1048,7 @@ void mapping_index_no_free(struct svalue *dest,
   }
 }
 
-struct array *mapping_indices(struct mapping *m)
+PMOD_EXPORT struct array *mapping_indices(struct mapping *m)
 {
   INT32 e;
   struct array *a;
@@ -1075,7 +1075,7 @@ struct array *mapping_indices(struct mapping *m)
   return a;
 }
 
-struct array *mapping_values(struct mapping *m)
+PMOD_EXPORT struct array *mapping_values(struct mapping *m)
 {
   INT32 e;
   struct keypair *k;
@@ -1102,7 +1102,7 @@ struct array *mapping_values(struct mapping *m)
   return a;
 }
 
-struct array *mapping_to_array(struct mapping *m)
+PMOD_EXPORT struct array *mapping_to_array(struct mapping *m)
 {
   INT32 e;
   struct keypair *k;
@@ -1132,7 +1132,7 @@ struct array *mapping_to_array(struct mapping *m)
   return a;
 }
 
-void mapping_replace(struct mapping *m,struct svalue *from, struct svalue *to)
+PMOD_EXPORT void mapping_replace(struct mapping *m,struct svalue *from, struct svalue *to)
 {
   INT32 e;
   struct keypair *k;
@@ -1164,7 +1164,7 @@ void mapping_replace(struct mapping *m,struct svalue *from, struct svalue *to)
 #endif
 }
 
-struct mapping *mkmapping(struct array *ind, struct array *val)
+PMOD_EXPORT struct mapping *mkmapping(struct array *ind, struct array *val)
 {
   struct mapping *m;
   struct svalue *i,*v;
@@ -1184,7 +1184,7 @@ struct mapping *mkmapping(struct array *ind, struct array *val)
 }
 
 #if 0
-struct mapping *copy_mapping(struct mapping *m)
+PMOD_EXPORT struct mapping *copy_mapping(struct mapping *m)
 {
   INT32 e;
   struct mapping *n;
@@ -1205,7 +1205,7 @@ struct mapping *copy_mapping(struct mapping *m)
 #else
 
 /* deferred mapping copy! */
-struct mapping *copy_mapping(struct mapping *m)
+PMOD_EXPORT struct mapping *copy_mapping(struct mapping *m)
 {
   struct mapping *n;
 
@@ -1231,7 +1231,7 @@ struct mapping *copy_mapping(struct mapping *m)
 
 #endif
 
-struct mapping *merge_mappings(struct mapping *a, struct mapping *b, INT32 op)
+PMOD_EXPORT struct mapping *merge_mappings(struct mapping *a, struct mapping *b, INT32 op)
 {
   struct array *ai, *av;
   struct array *bi, *bv;
@@ -1285,7 +1285,7 @@ struct mapping *merge_mappings(struct mapping *a, struct mapping *b, INT32 op)
   return m;
 }
 
-struct mapping *merge_mapping_array_ordered(struct mapping *a, 
+PMOD_EXPORT struct mapping *merge_mapping_array_ordered(struct mapping *a, 
 					    struct array *b, INT32 op)
 {
   struct array *ai, *av;
@@ -1331,7 +1331,7 @@ struct mapping *merge_mapping_array_ordered(struct mapping *a,
   return m;
 }
 
-struct mapping *merge_mapping_array_unordered(struct mapping *a, 
+PMOD_EXPORT struct mapping *merge_mapping_array_unordered(struct mapping *a, 
 					      struct array *b, INT32 op)
 {
   struct array *b_temp;
@@ -1351,7 +1351,7 @@ struct mapping *merge_mapping_array_unordered(struct mapping *a,
   return m;
 }
 
-struct mapping *add_mappings(struct svalue *argp, INT32 args)
+PMOD_EXPORT struct mapping *add_mappings(struct svalue *argp, INT32 args)
 {
   INT32 e,d;
   struct mapping *ret;
@@ -1388,7 +1388,7 @@ struct mapping *add_mappings(struct svalue *argp, INT32 args)
   return ret;
 }
 
-int mapping_equal_p(struct mapping *a, struct mapping *b, struct processing *p)
+PMOD_EXPORT int mapping_equal_p(struct mapping *a, struct mapping *b, struct processing *p)
 {
   struct processing curr;
   struct keypair *k;
@@ -1549,7 +1549,7 @@ node *make_node_from_mapping(struct mapping *m)
   }
 }
 
-void f_aggregate_mapping(INT32 args)
+PMOD_EXPORT void f_aggregate_mapping(INT32 args)
 {
   INT32 e;
   struct keypair *k;
@@ -1569,7 +1569,7 @@ void f_aggregate_mapping(INT32 args)
   push_mapping(m);
 }
 
-struct mapping *copy_mapping_recursively(struct mapping *m,
+PMOD_EXPORT struct mapping *copy_mapping_recursively(struct mapping *m,
 					 struct processing *p)
 {
   struct processing doing;
@@ -1627,7 +1627,7 @@ struct mapping *copy_mapping_recursively(struct mapping *m,
 }
 
 
-void mapping_search_no_free(struct svalue *to,
+PMOD_EXPORT void mapping_search_no_free(struct svalue *to,
 			    struct mapping *m,
 			    struct svalue *look_for,
 			    struct svalue *key /* start */)
diff --git a/src/mapping.h b/src/mapping.h
index b2c3ae334d..0fc1f66352 100644
--- a/src/mapping.h
+++ b/src/mapping.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: mapping.h,v 1.27 2000/07/18 05:48:20 mast Exp $
+ * $Id: mapping.h,v 1.28 2000/07/28 17:16:55 hubbe Exp $
  */
 #ifndef MAPPING_H
 #define MAPPING_H
@@ -75,6 +75,8 @@ extern struct mapping *gc_internal_mapping;
  /* FIXME: What about valrefs & hardlinks? */ \
 }while(0)
 
+PMOD_PROTO void really_free_mapping(struct mapping *md);
+
 /* Prototypes begin here */
 BLOCK_ALLOC(mapping, 511)
 
diff --git a/src/module_magic.h b/src/module_magic.h
new file mode 100644
index 0000000000..580c7bae14
--- /dev/null
+++ b/src/module_magic.h
@@ -0,0 +1,33 @@
+#ifndef MODULE_MAGIC_H
+#define MODULE_MAGIC_H
+
+#ifdef DYNAMIC_MODULE
+
+#ifdef __NT__
+
+/* UGLY - hubbe */
+#undef HIDE_GLOBAL_VARIABLES
+#undef REVEAL_GLOBAL_VARIABLES
+
+#define HIDE_GLOBAL_VARIABLES()
+#define REVEAL_GLOBAL_VARIABLES()
+
+
+#define pike_module_init mYDummyFunctioN1(void); __declspec(dllexport) void **PikeSymbol; __declspec(dllexport) void pike_module_init
+#define pike_module_exit mYDummyFunctioN2(void); __declspec(dllexport) void pike_module_exit
+
+#undef PMOD_EXPORT
+#define PMOD_EXPORT __declspec(dllexport)
+
+#include "import_functions.h"
+
+#endif /* __NT__ */
+#endif /* DYNAMIC_MODULE */
+
+#ifndef PMOD_EXPORT
+#define PMOD_EXPORT
+#endif
+
+#endif /* MODULE_MAGIC_H */
+
+
diff --git a/src/module_support.c b/src/module_support.c
index 5f9683c2d7..91507758a2 100644
--- a/src/module_support.c
+++ b/src/module_support.c
@@ -6,7 +6,7 @@
 #include "pike_types.h"
 #include "error.h"
 
-RCSID("$Id: module_support.c,v 1.33 1999/12/11 10:08:59 mast Exp $");
+RCSID("$Id: module_support.c,v 1.34 2000/07/28 17:16:55 hubbe Exp $");
 
 /* Checks that args_to_check arguments are OK.
  * Returns 1 if everything worked ok, zero otherwise.
@@ -54,7 +54,7 @@ static int va_check_args(struct svalue *s,
  * -X if there were too few arguments
  * or 0 if all arguments were OK.
  */
-int check_args(int args, ...)
+PMOD_EXPORT int check_args(int args, ...)
 {
   va_list arglist;
   struct expect_result tmp;
@@ -70,7 +70,7 @@ int check_args(int args, ...)
 /* This function generates errors if any of the minargs first arguments
  * is not OK.
  */
-void check_all_args(const char *fnname, int args, ... )
+PMOD_EXPORT void check_all_args(const char *fnname, int args, ... )
 {
   va_list arglist;
   struct expect_result tmp;
@@ -290,7 +290,7 @@ int va_get_args(struct svalue *s,
   return ret;
 }
 
-int get_args(struct svalue *s,
+PMOD_EXPORT int get_args(struct svalue *s,
 	     INT32 num_args,
 	     char *fmt, ...)
 {
@@ -304,7 +304,7 @@ int get_args(struct svalue *s,
   return ret;
 }
 
-void get_all_args(char *fname, INT32 args, char *format,  ... )
+PMOD_EXPORT void get_all_args(char *fname, INT32 args, char *format,  ... )
 {
   va_list ptr;
   int ret;
diff --git a/src/module_support.h b/src/module_support.h
index a504bec1d3..db7ca4126e 100644
--- a/src/module_support.h
+++ b/src/module_support.h
@@ -5,12 +5,11 @@
 \*/
 
 /*
- * $Id: module_support.h,v 1.6 1998/03/28 15:09:51 grubba Exp $
+ * $Id: module_support.h,v 1.7 2000/07/28 17:16:55 hubbe Exp $
  */
 #ifndef MODULE_SUPPORT_H
 #include <stdarg.h>
 
-/* Prototypes begin here */
 enum error_type {
   ERR_NONE,
   ERR_TOO_FEW,
@@ -25,16 +24,18 @@ struct expect_result {
   TYPE_T got;               /* What type did we actually receive */
 };
 
-int check_args(int args, ...);
-void check_all_args(const char *fnname, int args, ... );
+
+/* Prototypes begin here */
+PMOD_EXPORT int check_args(int args, ...);
+PMOD_EXPORT void check_all_args(const char *fnname, int args, ... );
 int va_get_args(struct svalue *s,
 		INT32 num_args,
 		char *fmt,
 		va_list ap);
-int get_args(struct svalue *s,
+PMOD_EXPORT int get_args(struct svalue *s,
 	     INT32 num_args,
 	     char *fmt, ...);
-void get_all_args(char *fname, INT32 args, char *format,  ... );
+PMOD_EXPORT void get_all_args(char *fname, INT32 args, char *format,  ... );
 /* Prototypes end here */
 
 #endif
diff --git a/src/multiset.c b/src/multiset.c
index 7041a49da9..2959b9679b 100644
--- a/src/multiset.c
+++ b/src/multiset.c
@@ -16,14 +16,14 @@
 #include "gc.h"
 #include "security.h"
 
-RCSID("$Id: multiset.c,v 1.25 2000/07/18 05:48:20 mast Exp $");
+RCSID("$Id: multiset.c,v 1.26 2000/07/28 17:16:55 hubbe Exp $");
 
 struct multiset *first_multiset;
 
 struct multiset *gc_internal_multiset = 0;
 static struct multiset *gc_mark_multiset_pos = 0;
 
-int multiset_member(struct multiset *l, struct svalue *ind)
+PMOD_EXPORT int multiset_member(struct multiset *l, struct svalue *ind)
 {
   return set_lookup(l->ind, ind) >= 0;
 }
@@ -31,7 +31,7 @@ int multiset_member(struct multiset *l, struct svalue *ind)
 /*
  * allocate and init a new multiset
  */
-struct multiset *allocate_multiset(struct array *ind)
+PMOD_EXPORT struct multiset *allocate_multiset(struct array *ind)
 {
   struct multiset *l;
   l=ALLOC_STRUCT(multiset);
@@ -48,7 +48,7 @@ struct multiset *allocate_multiset(struct array *ind)
 /*
  * free a multiset
  */
-void really_free_multiset(struct multiset *l)
+PMOD_EXPORT void really_free_multiset(struct multiset *l)
 {
 #ifdef PIKE_DEBUG
   if(l->refs)
@@ -70,14 +70,14 @@ void really_free_multiset(struct multiset *l)
   GC_FREE();
 }
 
-void do_free_multiset(struct multiset *l)
+PMOD_EXPORT void do_free_multiset(struct multiset *l)
 {
   if (l)
     free_multiset(l);
 }
 
 
-void order_multiset(struct multiset *l)
+PMOD_EXPORT void order_multiset(struct multiset *l)
 {
   INT32 *order;
   int flags;
@@ -89,7 +89,7 @@ void order_multiset(struct multiset *l)
   free((char *)order);
 }
 
-struct multiset *mkmultiset(struct array *ind)
+PMOD_EXPORT struct multiset *mkmultiset(struct array *ind)
 {
   struct multiset *l;
   l=allocate_multiset(copy_array(ind));
@@ -97,7 +97,7 @@ struct multiset *mkmultiset(struct array *ind)
   return l;
 }
 
-void multiset_insert(struct multiset *l,
+PMOD_EXPORT void multiset_insert(struct multiset *l,
 		 struct svalue *ind)
 {
   INT32 i;
@@ -117,7 +117,7 @@ struct array *multiset_indices(struct multiset *l)
 }
 #endif
 
-void multiset_delete(struct multiset *l,struct svalue *ind)
+PMOD_EXPORT void multiset_delete(struct multiset *l,struct svalue *ind)
 {
   INT32 i;
   i=set_lookup(l->ind, ind);
@@ -130,7 +130,7 @@ void multiset_delete(struct multiset *l,struct svalue *ind)
   }
 }
 
-void check_multiset_for_destruct(struct multiset *l)
+PMOD_EXPORT void check_multiset_for_destruct(struct multiset *l)
 {
 /* Horrifying worst case!!!!! */
   INT32 i;
@@ -140,13 +140,13 @@ void check_multiset_for_destruct(struct multiset *l)
   l->ind->flags = flags;
 }
 
-struct multiset *copy_multiset(struct multiset *tmp)
+PMOD_EXPORT struct multiset *copy_multiset(struct multiset *tmp)
 {
   check_multiset_for_destruct(tmp);
   return allocate_multiset(copy_array(tmp->ind));
 }
 
-struct multiset *merge_multisets(struct multiset *a,
+PMOD_EXPORT struct multiset *merge_multisets(struct multiset *a,
 			  struct multiset *b,
 			  INT32 operator)
 {
@@ -162,7 +162,7 @@ struct multiset *merge_multisets(struct multiset *a,
   return ret;
 }
 
-struct multiset *add_multisets(struct svalue *argp,INT32 args)
+PMOD_EXPORT struct multiset *add_multisets(struct svalue *argp,INT32 args)
 {
   struct multiset *ret,*a,*b;
   switch(args)
@@ -252,7 +252,7 @@ node * make_node_from_multiset(struct multiset *l)
   }
 }
 
-void f_aggregate_multiset(INT32 args)
+PMOD_EXPORT void f_aggregate_multiset(INT32 args)
 {
   struct multiset *l;
   f_aggregate(args);
diff --git a/src/object.c b/src/object.c
index 5bd94cfbf7..407a7d9f2f 100644
--- a/src/object.c
+++ b/src/object.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: object.c,v 1.136 2000/07/18 05:48:20 mast Exp $");
+RCSID("$Id: object.c,v 1.137 2000/07/28 17:16:55 hubbe Exp $");
 #include "object.h"
 #include "dynamic_buffer.h"
 #include "interpret.h"
@@ -70,7 +70,7 @@ RCSID("$Id: object.c,v 1.136 2000/07/18 05:48:20 mast Exp $");
 
 struct object *master_object = 0;
 struct program *master_program =0;
-struct object *first_object;
+PMOD_EXPORT struct object *first_object;
 
 struct object *gc_internal_object = 0;
 static struct object *gc_mark_object_pos = 0;
@@ -253,13 +253,13 @@ static void call_pike_initializers(struct object *o, int args)
   pop_stack();
 }
 
-void do_free_object(struct object *o)
+PMOD_EXPORT void do_free_object(struct object *o)
 {
   if (o)
     free_object(o);
 }
 
-struct object *debug_clone_object(struct program *p, int args)
+PMOD_EXPORT struct object *debug_clone_object(struct program *p, int args)
 {
   ONERROR tmp;
   struct object *o;
@@ -278,7 +278,7 @@ struct object *debug_clone_object(struct program *p, int args)
   return o;
 }
 
-struct object *fast_clone_object(struct program *p, int args)
+PMOD_EXPORT struct object *fast_clone_object(struct program *p, int args)
 {
   ONERROR tmp;
   struct object *o=low_clone(p);
@@ -291,7 +291,7 @@ struct object *fast_clone_object(struct program *p, int args)
   return o;
 }
 
-struct object *parent_clone_object(struct program *p,
+PMOD_EXPORT struct object *parent_clone_object(struct program *p,
 				   struct object *parent,
 				   int parent_identifier,
 				   int args)
@@ -340,7 +340,7 @@ static struct pike_string *low_read_file(char *file)
   return 0;
 }
 
-struct object *get_master(void)
+PMOD_EXPORT struct object *get_master(void)
 {
   extern char *master_file;
   struct pike_string *master_name;
@@ -455,7 +455,7 @@ struct object *get_master(void)
   return master_object;
 }
 
-struct object *debug_master(void)
+PMOD_EXPORT struct object *debug_master(void)
 {
   struct object *o;
   o=get_master();
@@ -611,7 +611,7 @@ void low_destruct(struct object *o,int do_free)
   free_program(p);
 }
 
-void destruct(struct object *o)
+PMOD_EXPORT void destruct(struct object *o)
 {
   low_destruct(o,1);
 }
@@ -624,7 +624,7 @@ static struct callback *destruct_object_evaluator_callback =0;
  * destructed by schedule_really_free_object. It links the object back into the
  * list of objects first. Adds a reference, destructs it and then frees it.
  */
-void destruct_objects_to_destruct(void)
+PMOD_EXPORT void destruct_objects_to_destruct(void)
 {
   struct object *my_list=0;
   struct object *o, *next;
@@ -669,7 +669,7 @@ void destruct_objects_to_destruct(void)
  * a separate list of objects which will be destructed later.
  */
 
-void schedule_really_free_object(struct object *o)
+PMOD_EXPORT void schedule_really_free_object(struct object *o)
 {
 #ifdef PIKE_DEBUG
   if (o->refs)
@@ -756,7 +756,7 @@ void schedule_really_free_object(struct object *o)
 }
 
 
-void low_object_index_no_free(struct svalue *to,
+PMOD_EXPORT void low_object_index_no_free(struct svalue *to,
 			      struct object *o,
 			      INT32 f)
 {
@@ -823,7 +823,7 @@ void low_object_index_no_free(struct svalue *to,
   }
 }
 
-void object_index_no_free2(struct svalue *to,
+PMOD_EXPORT void object_index_no_free2(struct svalue *to,
 			  struct object *o,
 			  struct svalue *index)
 {
@@ -862,7 +862,7 @@ void object_index_no_free2(struct svalue *to,
 
 #define ARROW_INDEX_P(X) ((X)->type==T_STRING && (X)->subtype)
 
-void object_index_no_free(struct svalue *to,
+PMOD_EXPORT void object_index_no_free(struct svalue *to,
 			   struct object *o,
 			   struct svalue *index)
 {
@@ -889,7 +889,7 @@ void object_index_no_free(struct svalue *to,
 }
 
 
-void object_low_set_index(struct object *o,
+PMOD_EXPORT void object_low_set_index(struct object *o,
 			  int f,
 			  struct svalue *from)
 {
@@ -925,7 +925,7 @@ void object_low_set_index(struct object *o,
   }
 }
 
-void object_set_index2(struct object *o,
+PMOD_EXPORT void object_set_index2(struct object *o,
 		      struct svalue *index,
 		      struct svalue *from)
 {
@@ -971,7 +971,7 @@ void object_set_index2(struct object *o,
   }
 }
 
-void object_set_index(struct object *o,
+PMOD_EXPORT void object_set_index(struct object *o,
 		       struct svalue *index,
 		       struct svalue *from)
 {
@@ -1080,7 +1080,7 @@ union anything *object_get_item_ptr(struct object *o,
 }
 
 
-int object_equal_p(struct object *a, struct object *b, struct processing *p)
+PMOD_EXPORT int object_equal_p(struct object *a, struct object *b, struct processing *p)
 {
   struct processing curr;
 
@@ -1154,7 +1154,7 @@ void cleanup_objects(void)
   destruct_objects_to_destruct();
 }
 
-struct array *object_indices(struct object *o)
+PMOD_EXPORT struct array *object_indices(struct object *o)
 {
   struct program *p;
   struct array *a;
@@ -1184,7 +1184,7 @@ struct array *object_indices(struct object *o)
   return a;
 }
 
-struct array *object_values(struct object *o)
+PMOD_EXPORT struct array *object_values(struct object *o)
 {
   struct program *p;
   struct array *a;
diff --git a/src/object.h b/src/object.h
index ae0b8cfdae..b38d7467da 100644
--- a/src/object.h
+++ b/src/object.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: object.h,v 1.49 2000/07/18 05:48:20 mast Exp $
+ * $Id: object.h,v 1.50 2000/07/28 17:16:55 hubbe Exp $
  */
 #ifndef OBJECT_H
 #define OBJECT_H
@@ -56,55 +56,55 @@ extern struct program *magic_set_index_program;
 BLOCK_ALLOC(object, 511)
 struct object *low_clone(struct program *p);
 void call_c_initializers(struct object *o);
-void do_free_object(struct object *o);
-struct object *debug_clone_object(struct program *p, int args);
-struct object *fast_clone_object(struct program *p, int args);
-struct object *parent_clone_object(struct program *p,
+PMOD_EXPORT void do_free_object(struct object *o);
+PMOD_EXPORT struct object *debug_clone_object(struct program *p, int args);
+PMOD_EXPORT struct object *fast_clone_object(struct program *p, int args);
+PMOD_EXPORT struct object *parent_clone_object(struct program *p,
 				   struct object *parent,
 				   int parent_identifier,
 				   int args);
-struct object *get_master(void);
-struct object *debug_master(void);
+PMOD_EXPORT struct object *get_master(void);
+PMOD_EXPORT struct object *debug_master(void);
 struct destroy_called_mark;
 PTR_HASH_ALLOC(destroy_called_mark,128)
+static void call_destroy(struct object *o, int foo);
 void low_destruct(struct object *o,int do_free);
-void destruct(struct object *o);
-void destruct_objects_to_destruct(void);
+PMOD_EXPORT void destruct(struct object *o);
+PMOD_EXPORT void destruct_objects_to_destruct(void);
 void schedule_really_free_object(struct object *o);
-void low_object_index_no_free(struct svalue *to,
+PMOD_EXPORT void low_object_index_no_free(struct svalue *to,
 			      struct object *o,
 			      INT32 f);
-void object_index_no_free2(struct svalue *to,
+PMOD_EXPORT void object_index_no_free2(struct svalue *to,
 			  struct object *o,
 			  struct svalue *index);
-void object_index_no_free(struct svalue *to,
+PMOD_EXPORT void object_index_no_free(struct svalue *to,
 			   struct object *o,
 			   struct svalue *index);
-void object_low_set_index(struct object *o,
+PMOD_EXPORT void object_low_set_index(struct object *o,
 			  int f,
 			  struct svalue *from);
-void object_set_index2(struct object *o,
+PMOD_EXPORT void object_set_index2(struct object *o,
 		      struct svalue *index,
 		      struct svalue *from);
-void object_set_index(struct object *o,
+PMOD_EXPORT void object_set_index(struct object *o,
 		       struct svalue *index,
 		       struct svalue *from);
 union anything *object_get_item_ptr(struct object *o,
 				    struct svalue *index,
 				    TYPE_T type);
-int object_equal_p(struct object *a, struct object *b, struct processing *p);
+PMOD_EXPORT int object_equal_p(struct object *a, struct object *b, struct processing *p);
 void cleanup_objects(void);
-struct array *object_indices(struct object *o);
-struct array *object_values(struct object *o);
+PMOD_EXPORT struct array *object_indices(struct object *o);
+PMOD_EXPORT struct array *object_values(struct object *o);
 void gc_mark_object_as_referenced(struct object *o);
+void real_gc_cycle_check_object(struct object *o, int weak);
 unsigned gc_touch_all_objects(void);
 void gc_check_all_objects(void);
 void gc_mark_all_objects(void);
-void real_gc_cycle_check_object(struct object *o, int weak);
 void gc_cycle_check_all_objects(void);
 void gc_zap_ext_weak_refs_in_objects(void);
 void gc_free_all_unreferenced_objects(void);
-void count_memory_in_objects(INT32 *num_, INT32 *size_);
 struct magic_index_struct;
 void push_magic_index(struct program *type, int inherit_no, int parent_level);
 void init_object(void);
diff --git a/src/opcodes.c b/src/opcodes.c
index 41dcf2faa8..1788a10150 100644
--- a/src/opcodes.c
+++ b/src/opcodes.c
@@ -26,7 +26,7 @@
 #include "bignum.h"
 #include "operators.h"
 
-RCSID("$Id: opcodes.c,v 1.77 2000/07/07 15:31:14 grubba Exp $");
+RCSID("$Id: opcodes.c,v 1.78 2000/07/28 17:16:55 hubbe Exp $");
 
 void index_no_free(struct svalue *to,struct svalue *what,struct svalue *ind)
 {
@@ -616,7 +616,7 @@ void o_cast(struct pike_string *type, INT32 run_time_type)
 }
 
 
-void f_cast(void)
+PMOD_EXPORT void f_cast(void)
 {
 #ifdef PIKE_DEBUG
   struct svalue *save_sp=sp;
@@ -1682,7 +1682,7 @@ void o_sscanf(INT32 args)
   push_int(i);
 }
 
-void f_sscanf(INT32 args)
+PMOD_EXPORT void f_sscanf(INT32 args)
 {
 #ifdef PIKE_DEBUG
   extern int t_flag;
diff --git a/src/operators.c b/src/operators.c
index a461665163..6465d01c2a 100644
--- a/src/operators.c
+++ b/src/operators.c
@@ -6,7 +6,7 @@
 /**/
 #include "global.h"
 #include <math.h>
-RCSID("$Id: operators.c,v 1.92 2000/05/01 03:33:47 hubbe Exp $");
+RCSID("$Id: operators.c,v 1.93 2000/07/28 17:16:55 hubbe Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "multiset.h"
@@ -36,7 +36,7 @@ RCSID("$Id: operators.c,v 1.92 2000/05/01 03:33:47 hubbe Exp $");
      math_error(FUNC, sp-2, 2, 0, "Modulo by zero.\n")
 
 #define COMPARISON(ID,NAME,FUN)			\
-void ID(INT32 args)				\
+PMOD_EXPORT void ID(INT32 args)				\
 {						\
   int i;					\
   switch(args)					\
@@ -57,7 +57,7 @@ void ID(INT32 args)				\
   }						\
 }
 
-void f_ne(INT32 args)
+PMOD_EXPORT void f_ne(INT32 args)
 {
   f_eq(args);
   o_not();
@@ -83,7 +83,7 @@ COMPARISON(f_ge,"`>=",!is_lt)
  sp--; \
  dmalloc_touch_svalue(sp);
 
-void f_add(INT32 args)
+PMOD_EXPORT void f_add(INT32 args)
 {
   INT_TYPE e,size;
   TYPE_FIELD types;
@@ -688,7 +688,7 @@ struct mapping *merge_mapping_array_ordered(struct mapping *a,
 struct mapping *merge_mapping_array_unordered(struct mapping *a, 
 					      struct array *b, INT32 op);
 
-void o_subtract(void)
+PMOD_EXPORT void o_subtract(void)
 {
   if (sp[-2].type != sp[-1].type && !float_promote())
   {
@@ -802,7 +802,7 @@ void o_subtract(void)
   }
 }
 
-void f_minus(INT32 args)
+PMOD_EXPORT void f_minus(INT32 args)
 {
   switch(args)
   {
@@ -842,7 +842,7 @@ static int generate_minus(node *n)
   return 0;
 }
 
-void o_and(void)
+PMOD_EXPORT void o_and(void)
 {
   if(sp[-1].type != sp[-2].type)
   {
@@ -1108,7 +1108,7 @@ static void speedup(INT32 args, void (*func)(void))
   }
 }
 
-void f_and(INT32 args)
+PMOD_EXPORT void f_and(INT32 args)
 {
   switch(args)
   {
@@ -1143,7 +1143,7 @@ static int generate_and(node *n)
   }
 }
 
-void o_or(void)
+PMOD_EXPORT void o_or(void)
 {
   if(sp[-1].type != sp[-2].type)
   {
@@ -1282,7 +1282,7 @@ void o_or(void)
   }
 }
 
-void f_or(INT32 args)
+PMOD_EXPORT void f_or(INT32 args)
 {
   switch(args)
   {
@@ -1318,7 +1318,7 @@ static int generate_or(node *n)
 }
 
 
-void o_xor(void)
+PMOD_EXPORT void o_xor(void)
 {
   if(sp[-1].type != sp[-2].type)
   {
@@ -1461,7 +1461,7 @@ void o_xor(void)
   }
 }
 
-void f_xor(INT32 args)
+PMOD_EXPORT void f_xor(INT32 args)
 {
   switch(args)
   {
@@ -1496,7 +1496,7 @@ static int generate_xor(node *n)
   }
 }
 
-void o_lsh(void)
+PMOD_EXPORT void o_lsh(void)
 {
 #ifdef AUTO_BIGNUM
   if(INT_TYPE_LSH_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer))
@@ -1517,7 +1517,7 @@ void o_lsh(void)
   sp[-1].u.integer = sp[-1].u.integer << sp->u.integer;
 }
 
-void f_lsh(INT32 args)
+PMOD_EXPORT void f_lsh(INT32 args)
 {
   if(args != 2) {
     /* FIXME: Not appropriate if too many args. */
@@ -1537,7 +1537,7 @@ static int generate_lsh(node *n)
   return 0;
 }
 
-void o_rsh(void)
+PMOD_EXPORT void o_rsh(void)
 {
   if(sp[-2].type != T_INT || sp[-1].type != T_INT)
   {
@@ -1562,7 +1562,7 @@ void o_rsh(void)
   sp[-1].u.integer = sp[-1].u.integer >> sp->u.integer;
 }
 
-void f_rsh(INT32 args)
+PMOD_EXPORT void f_rsh(INT32 args)
 {
   if(args != 2) {
     /* FIXME: Not appropriate if too many args. */
@@ -1584,7 +1584,7 @@ static int generate_rsh(node *n)
 
 
 #define TWO_TYPES(X,Y) (((X)<<8)|(Y))
-void o_multiply(void)
+PMOD_EXPORT void o_multiply(void)
 {
   int args = 2;
   switch(TWO_TYPES(sp[-2].type,sp[-1].type))
@@ -1685,7 +1685,7 @@ void o_multiply(void)
   }
 }
 
-void f_multiply(INT32 args)
+PMOD_EXPORT void f_multiply(INT32 args)
 {
   switch(args)
   {
@@ -1720,7 +1720,7 @@ static int generate_multiply(node *n)
   }
 }
 
-void o_divide(void)
+PMOD_EXPORT void o_divide(void)
 {
   if(sp[-2].type!=sp[-1].type && !float_promote())
   {
@@ -1976,7 +1976,7 @@ void o_divide(void)
   }
 }
 
-void f_divide(INT32 args)
+PMOD_EXPORT void f_divide(INT32 args)
 {
   switch(args)
   {
@@ -2010,7 +2010,7 @@ static int generate_divide(node *n)
   return 0;
 }
 
-void o_mod(void)
+PMOD_EXPORT void o_mod(void)
 {
   if(sp[-2].type != sp[-1].type && !float_promote())
   {
@@ -2113,7 +2113,7 @@ void o_mod(void)
   }
 }
 
-void f_mod(INT32 args)
+PMOD_EXPORT void f_mod(INT32 args)
 {
   if(args != 2) {
     /* FIXME: Not appropriate when too many args. */
@@ -2133,7 +2133,7 @@ static int generate_mod(node *n)
   return 0;
 }
 
-void o_not(void)
+PMOD_EXPORT void o_not(void)
 {
   switch(sp[-1].type)
   {
@@ -2160,7 +2160,7 @@ void o_not(void)
   }
 }
 
-void f_not(INT32 args)
+PMOD_EXPORT void f_not(INT32 args)
 {
   if(args != 1) {
     /* FIXME: Not appropriate with too many args. */
@@ -2180,7 +2180,7 @@ static int generate_not(node *n)
   return 0;
 }
 
-void o_compl(void)
+PMOD_EXPORT void o_compl(void)
 {
   switch(sp[-1].type)
   {
@@ -2252,7 +2252,7 @@ void o_compl(void)
   }
 }
 
-void f_compl(INT32 args)
+PMOD_EXPORT void f_compl(INT32 args)
 {
   if(args != 1) {
     /* FIXME: Not appropriate with too many args. */
@@ -2272,7 +2272,7 @@ static int generate_compl(node *n)
   return 0;
 }
 
-void o_negate(void)
+PMOD_EXPORT void o_negate(void)
 {
   switch(sp[-1].type)
   {
@@ -2301,7 +2301,7 @@ void o_negate(void)
   }
 }
 
-void o_range(void)
+PMOD_EXPORT void o_range(void)
 {
   INT32 from,to;
 
@@ -2367,7 +2367,7 @@ void o_range(void)
   }
 }
 
-void f_index(INT32 args)
+PMOD_EXPORT void f_index(INT32 args)
 {
   switch(args)
   {
@@ -2387,7 +2387,7 @@ void f_index(INT32 args)
   }
 }
 
-void f_arrow(INT32 args)
+PMOD_EXPORT void f_arrow(INT32 args)
 {
   switch(args)
   {
@@ -2405,7 +2405,7 @@ void f_arrow(INT32 args)
   }
 }
 
-void f_index_assign(INT32 args)
+PMOD_EXPORT void f_index_assign(INT32 args)
 {
   switch (args) {
     case 0:
@@ -2424,7 +2424,7 @@ void f_index_assign(INT32 args)
   }
 }
 
-void f_arrow_assign(INT32 args)
+PMOD_EXPORT void f_arrow_assign(INT32 args)
 {
   switch (args) {
     case 0:
@@ -2443,7 +2443,7 @@ void f_arrow_assign(INT32 args)
   }
 }
 
-void f_sizeof(INT32 args)
+PMOD_EXPORT void f_sizeof(INT32 args)
 {
   INT32 tmp;
   if(args<1)
diff --git a/src/operators.h b/src/operators.h
index 8f4d2f35b8..28cc41ec74 100644
--- a/src/operators.h
+++ b/src/operators.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: operators.h,v 1.7 1999/03/04 06:19:41 hubbe Exp $
+ * $Id: operators.h,v 1.8 2000/07/28 17:16:55 hubbe Exp $
  */
 #ifndef OPERATORS_H
 #define OPERATORS_H
@@ -29,34 +29,34 @@ COMPARISON(f_le,"`<=",!is_gt)
 COMPARISON(f_gt,"`>" , is_gt)
 COMPARISON(f_ge,"`>=",!is_lt)
 
-void f_add(INT32 args);
-void o_subtract(void);
-void f_minus(INT32 args);
-void o_and(void);
-void f_and(INT32 args);
-void o_or(void);
-void f_or(INT32 args);
-void o_xor(void);
-void f_xor(INT32 args);
-void o_lsh(void);
-void f_lsh(INT32 args);
-void o_rsh(void);
-void f_rsh(INT32 args);
-void o_multiply(void);
-void f_multiply(INT32 args);
-void o_divide(void);
-void f_divide(INT32 args);
-void o_mod(void);
-void f_mod(INT32 args);
-void o_not(void);
-void f_not(INT32 args);
-void o_compl(void);
-void f_compl(INT32 args);
-void o_negate(void);
-void o_range(void);
-void f_index(INT32 args);
-void f_arrow(INT32 args);
-void f_sizeof(INT32 args);
+PMOD_EXPORT void f_add(INT32 args);
+PMOD_EXPORT void o_subtract(void);
+PMOD_EXPORT void f_minus(INT32 args);
+PMOD_EXPORT void o_and(void);
+PMOD_EXPORT void f_and(INT32 args);
+PMOD_EXPORT void o_or(void);
+PMOD_EXPORT void f_or(INT32 args);
+PMOD_EXPORT void o_xor(void);
+PMOD_EXPORT void f_xor(INT32 args);
+PMOD_EXPORT void o_lsh(void);
+PMOD_EXPORT void f_lsh(INT32 args);
+PMOD_EXPORT void o_rsh(void);
+PMOD_EXPORT void f_rsh(INT32 args);
+PMOD_EXPORT void o_multiply(void);
+PMOD_EXPORT void f_multiply(INT32 args);
+PMOD_EXPORT void o_divide(void);
+PMOD_EXPORT void f_divide(INT32 args);
+PMOD_EXPORT void o_mod(void);
+PMOD_EXPORT void f_mod(INT32 args);
+PMOD_EXPORT void o_not(void);
+PMOD_EXPORT void f_not(INT32 args);
+PMOD_EXPORT void o_compl(void);
+PMOD_EXPORT void f_compl(INT32 args);
+PMOD_EXPORT void o_negate(void);
+PMOD_EXPORT void o_range(void);
+PMOD_EXPORT void f_index(INT32 args);
+PMOD_EXPORT void f_arrow(INT32 args);
+PMOD_EXPORT void f_sizeof(INT32 args);
 void init_operators(void);
 void exit_operators(void);
 /* Prototypes end here */
diff --git a/src/pike_macros.h b/src/pike_macros.h
index 103ed075b8..a1e6598e80 100644
--- a/src/pike_macros.h
+++ b/src/pike_macros.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: pike_macros.h,v 1.16 2000/06/27 15:19:33 grubba Exp $
+ * $Id: pike_macros.h,v 1.17 2000/07/28 17:16:55 hubbe Exp $
  */
 #ifndef MACROS_H
 #define MACROS_H
@@ -95,4 +95,7 @@
 }while(0)
 
 
+/* Needed for fsort_template.h */
+int my_log2(unsigned INT32 x);
+
 #endif
diff --git a/src/pike_memory.c b/src/pike_memory.c
index 5ca4e492fc..ca8c9ecf5c 100644
--- a/src/pike_memory.c
+++ b/src/pike_memory.c
@@ -10,7 +10,7 @@
 #include "pike_macros.h"
 #include "gc.h"
 
-RCSID("$Id: pike_memory.c,v 1.70 2000/06/27 15:22:38 grubba Exp $");
+RCSID("$Id: pike_memory.c,v 1.71 2000/07/28 17:16:55 hubbe Exp $");
 
 /* strdup() is used by several modules, so let's provide it */
 #ifndef HAVE_STRDUP
@@ -553,7 +553,7 @@ void *generic_memory_search(struct generic_mem_searcher *s,
 }
 		    
 
-char *my_memmem(char *needle,
+PMOD_EXPORT char *my_memmem(char *needle,
 		SIZE_T needlelen,
 		char *haystack,
 		SIZE_T haystacklen)
@@ -609,7 +609,7 @@ static long softlim_should_be=0;
 #endif
 
 
-char *debug_xalloc(long size)
+PMOD_EXPORT char *debug_xalloc(long size)
 {
   char *ret;
   if(!size) 
@@ -686,6 +686,29 @@ static MUTEX_T debug_malloc_mutex;
 #undef strdup
 #undef main
 
+#ifdef DMALLOC_USE_RTLD_NEXT
+#define malloc(X)  (dl_setup(),real_malloc((X),(Y))
+#define free(X)    (dl_setup(),real_free((X)))
+#define realloc(X,Y) (dl_setup(),real_realloc((X),(Y)))
+#define calloc(X,Y)  (dl_setup(),real_calloc((X),(Y)))
+
+#define dl_setup()  ( real_malloc ? 0 : real_dl_setup() )
+
+void *(*real_malloc)(size_t);
+void (*real_free)(void *);
+void *(*real_realloc)(void *,size_t);
+void *(*real_calloc)(size_t,size_t);
+
+void real_dl_setup()
+{
+  real_malloc=dlsym(RTLD_NEXT,"malloc");
+  real_free=dlsym(RTLD_NEXT,"free");
+  real_realloc=dlsym(RTLD_NEXT,"realloc");
+  real_calloc=dlsym(RTLD_NEXT,"calloc");
+}
+
+#endif
+
 
 #ifdef WRAP
 #define malloc __real_malloc
diff --git a/src/pike_memory.h b/src/pike_memory.h
index a146556c3f..a8421f9c13 100644
--- a/src/pike_memory.h
+++ b/src/pike_memory.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: pike_memory.h,v 1.13 1999/10/24 14:17:41 grubba Exp $
+ * $Id: pike_memory.h,v 1.14 2000/07/28 17:16:55 hubbe Exp $
  */
 #ifndef MEMORY_H
 #define MEMORY_H
@@ -60,43 +60,43 @@ struct generic_mem_searcher
 #define MEMCHR0 MEMCHR
 
 /* Note to self: Prototypes must be updated manually /Hubbe */
-int pcharp_memcmp(PCHARP a, PCHARP b, int sz);
-long pcharp_strlen(PCHARP a);
-INLINE p_wchar1 *MEMCHR1(p_wchar1 *p,p_wchar1 c,INT32 e);
-INLINE p_wchar2 *MEMCHR2(p_wchar2 *p,p_wchar2 c,INT32 e);
-void swap(char *a, char *b, INT32 size);
-void reverse(char *memory, INT32 nitems, INT32 size);
-void reorder(char *memory, INT32 nitems, INT32 size,INT32 *order);
-unsigned INT32 hashmem(const unsigned char *a,INT32 len,INT32 mlen);
-unsigned INT32 hashstr(const unsigned char *str,INT32 maxn);
-unsigned INT32 simple_hashmem(const unsigned char *str,INT32 len, INT32 maxn);
-void init_memsearch(struct mem_searcher *s,
+PMOD_EXPORT int pcharp_memcmp(PCHARP a, PCHARP b, int sz);
+PMOD_EXPORT long pcharp_strlen(PCHARP a);
+PMOD_EXPORT INLINE p_wchar1 *MEMCHR1(p_wchar1 *p,p_wchar1 c,INT32 e);
+PMOD_EXPORT INLINE p_wchar2 *MEMCHR2(p_wchar2 *p,p_wchar2 c,INT32 e);
+PMOD_EXPORT void swap(char *a, char *b, INT32 size);
+PMOD_EXPORT void reverse(char *memory, INT32 nitems, INT32 size);
+PMOD_EXPORT void reorder(char *memory, INT32 nitems, INT32 size,INT32 *order);
+PMOD_EXPORT unsigned INT32 hashmem(const unsigned char *a,INT32 len,INT32 mlen);
+PMOD_EXPORT unsigned INT32 hashstr(const unsigned char *str,INT32 maxn);
+PMOD_EXPORT unsigned INT32 simple_hashmem(const unsigned char *str,INT32 len, INT32 maxn);
+PMOD_EXPORT void init_memsearch(struct mem_searcher *s,
 		    char *needle,
 		    SIZE_T needlelen,
 		    SIZE_T max_haystacklen);
-char *memory_search(struct mem_searcher *s,
+PMOD_EXPORT char *memory_search(struct mem_searcher *s,
 		    char *haystack,
 		    SIZE_T haystacklen);
-void init_generic_memsearcher(struct generic_mem_searcher *s,
+PMOD_EXPORT void init_generic_memsearcher(struct generic_mem_searcher *s,
 			      void *needle,
 			      SIZE_T needlelen,
 			      char needle_shift,
 			      SIZE_T estimated_haystack,
 			      char haystack_shift);
-void *generic_memory_search(struct generic_mem_searcher *s,
+PMOD_EXPORT void *generic_memory_search(struct generic_mem_searcher *s,
 			    void *haystack,
 			    SIZE_T haystacklen,
 			    char haystack_shift);
-char *my_memmem(char *needle,
+PMOD_EXPORT char *my_memmem(char *needle,
 		SIZE_T needlelen,
 		char *haystack,
 		SIZE_T haystacklen);
-void memfill(char *to,
+PMOD_EXPORT void memfill(char *to,
 	     INT32 tolen,
 	     char *from,
 	     INT32 fromlen,
 	     INT32 offset);
-char *debug_xalloc(long size);
+PMOD_EXPORT char *debug_xalloc(long size);
 
 #undef BLOCK_ALLOC
 
diff --git a/src/pike_types.c b/src/pike_types.c
index da86ded49c..0a9eed55f8 100644
--- a/src/pike_types.c
+++ b/src/pike_types.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: pike_types.c,v 1.131 2000/06/24 00:48:13 hubbe Exp $");
+RCSID("$Id: pike_types.c,v 1.132 2000/07/28 17:16:55 hubbe Exp $");
 #include <ctype.h>
 #include "svalue.h"
 #include "pike_types.h"
@@ -66,21 +66,21 @@ static int low_check_indexing(char *type, char *index_type, node *n);
  * Everything except T_VOID matches T_ZERO.
  */
 
-struct pike_string *string_type_string;
-struct pike_string *int_type_string;
-struct pike_string *float_type_string;
-struct pike_string *function_type_string;
-struct pike_string *object_type_string;
-struct pike_string *program_type_string;
-struct pike_string *array_type_string;
-struct pike_string *multiset_type_string;
-struct pike_string *mapping_type_string;
-struct pike_string *type_type_string;
-struct pike_string *mixed_type_string;
-struct pike_string *void_type_string;
-struct pike_string *zero_type_string;
-struct pike_string *any_type_string;
-struct pike_string *weak_type_string;	/* array|mapping|multiset|function */
+PMOD_EXPORT struct pike_string *string_type_string;
+PMOD_EXPORT struct pike_string *int_type_string;
+PMOD_EXPORT struct pike_string *float_type_string;
+PMOD_EXPORT struct pike_string *function_type_string;
+PMOD_EXPORT struct pike_string *object_type_string;
+PMOD_EXPORT struct pike_string *program_type_string;
+PMOD_EXPORT struct pike_string *array_type_string;
+PMOD_EXPORT struct pike_string *multiset_type_string;
+PMOD_EXPORT struct pike_string *mapping_type_string;
+PMOD_EXPORT struct pike_string *type_type_string;
+PMOD_EXPORT struct pike_string *mixed_type_string;
+PMOD_EXPORT struct pike_string *void_type_string;
+PMOD_EXPORT struct pike_string *zero_type_string;
+PMOD_EXPORT struct pike_string *any_type_string;
+PMOD_EXPORT struct pike_string *weak_type_string;	/* array|mapping|multiset|function */
 
 static struct pike_string *a_markers[10],*b_markers[10];
 
diff --git a/src/port.c b/src/port.c
index 6b3c46c743..9b70b99b60 100644
--- a/src/port.c
+++ b/src/port.c
@@ -17,7 +17,7 @@
 #include <float.h>
 #include <string.h>
 
-RCSID("$Id: port.c,v 1.27 2000/07/11 19:05:54 neotron Exp $");
+RCSID("$Id: port.c,v 1.28 2000/07/28 17:16:55 hubbe Exp $");
 
 #ifdef sun
 time_t time PROT((time_t *));
@@ -92,7 +92,7 @@ static void slow_srand(long seed)
 static unsigned long rndbuf[ RNDBUF ];
 static int rnd_index;
 
-void my_srand(long seed)
+PMOD_EXPORT void my_srand(long seed)
 {
   int e;
   unsigned long mask;
@@ -113,7 +113,7 @@ void my_srand(long seed)
   }
 }
 
-unsigned long my_rand(void)
+PMOD_EXPORT unsigned long my_rand(void)
 {
   if( ++rnd_index == RNDBUF) rnd_index=0;
   return rndbuf[rnd_index] += rndbuf[rnd_index+RNDJUMP-(rnd_index<RNDBUF-RNDJUMP?0:RNDBUF)];
@@ -169,7 +169,7 @@ long STRTOL(char *str,char **ptr,int base)
 }
 
 #ifndef HAVE_STRCASECMP
-int STRCASECMP(const char *a,const char *b)
+PMOD_EXPORT int STRCASECMP(const char *a,const char *b)
 {
   int ac, bc;
 
@@ -199,7 +199,7 @@ void *MEMSET(void *s,int c,size_t n)
 #ifdef TRY_USE_MMX
 #include <mmx.h>
 #endif
-void MEMCPY(void *bb,const void *aa,size_t s)
+PMOD_EXPORT void MEMCPY(void *bb,const void *aa,size_t s)
 {
   if(!s) return;
 #ifdef TRY_USE_MMX
@@ -285,7 +285,7 @@ void MEMCPY(void *bb,const void *aa,size_t s)
 #endif
 
 #ifndef HAVE_MEMMOVE
-void MEMMOVE(void *b,const void *aa,size_t s)
+PMOD_EXPORT void MEMMOVE(void *b,const void *aa,size_t s)
 {
   char *t=(char *)b;
   char *a=(char *)aa;
@@ -299,7 +299,7 @@ void MEMMOVE(void *b,const void *aa,size_t s)
 
 
 #ifndef HAVE_MEMCMP
-int MEMCMP(const void *bb,const void *aa,size_t s)
+PMOD_EXPORT int MEMCMP(const void *bb,const void *aa,size_t s)
 {
   char *a=(char *)aa;
   char *b=(char *)bb;
@@ -317,7 +317,7 @@ int MEMCMP(const void *bb,const void *aa,size_t s)
 #endif
 
 #ifndef HAVE_MEMCHR
-void *MEMCHR(const void *p,char c,size_t e)
+PMOD_EXPORT void *MEMCHR(const void *p,char c,size_t e)
 {
   const char *t = p;
   while(e--) if(*(t++)==c) return t-1;
@@ -327,7 +327,7 @@ void *MEMCHR(const void *p,char c,size_t e)
 
 
 #if !defined(HAVE_INDEX) && !defined(HAVE_STRCHR)
-char *STRCHR(char *s,char c)
+PMOD_EXPORT char *STRCHR(char *s,char c)
 {
   for(;*s;s++) if(*s==c) return s;
   return NULL;
@@ -335,7 +335,7 @@ char *STRCHR(char *s,char c)
 #endif
 
 #if !defined(HAVE_RINDEX) && !defined(HAVE_STRRCHR)
-char *STRRCHR(char *s,int c)
+PMOD_EXPORT char *STRRCHR(char *s,int c)
 {
   char *p;
   for(p=NULL;*s;s++) if(*s==c) p=s;
@@ -344,7 +344,7 @@ char *STRRCHR(char *s,int c)
 #endif
 
 #ifndef HAVE_STRSTR
-char *STRSTR(char *s1,const char *s2)
+PMOD_EXPORT char *STRSTR(char *s1,const char *s2)
 {
   for(;*s1;s1++)
   {
@@ -358,7 +358,7 @@ char *STRSTR(char *s1,const char *s2)
 
 #ifndef HAVE_STRTOK
 static char *temporary_for_strtok;
-char *STRTOK(char *s1,char *s2)
+PMOD_EXPORT char *STRTOK(char *s1,char *s2)
 {
   if(s1!=NULL) temporary_for_strtok=s1;
   for(s1=temporary_for_strtok;*s1;s1++)
@@ -382,7 +382,7 @@ char *STRTOK(char *s1,char *s2)
 
 /* Convert NPTR to a double.  If ENDPTR is not NULL, a pointer to the
    character after the last one used in the number is put in *ENDPTR.  */
-double STRTOD(char * nptr, char **endptr)
+PMOD_EXPORT double STRTOD(char * nptr, char **endptr)
 {
   register unsigned char *s;
   short int sign;
@@ -526,7 +526,7 @@ double STRTOD(char * nptr, char **endptr)
 }
 
 #ifndef HAVE_VSPRINTF
-int VSPRINTF(char *buf,char *fmt,va_list args)
+PMOD_EXPORT int VSPRINTF(char *buf,char *fmt,va_list args)
 {
   char *b=buf;
   char *s;
@@ -598,7 +598,7 @@ int VSPRINTF(char *buf,char *fmt,va_list args)
 #endif
 
 #ifndef HAVE_VFPRINTF
-int VFPRINTF(FILE *f,char *s,va_list args)
+PMOD_EXPORT int VFPRINTF(FILE *f,char *s,va_list args)
 {
   int i;
   char buffer[10000];
@@ -612,21 +612,21 @@ int VFPRINTF(FILE *f,char *s,va_list args)
 
 #if defined(PIKE_DEBUG) && !defined(HANDLES_UNALIGNED_MEMORY_ACCESS)
 
-unsigned INT16 EXTRACT_UWORD_(unsigned char *p)
+PMOD_EXPORT unsigned INT16 EXTRACT_UWORD_(unsigned char *p)
 {
   unsigned INT16 a;
   MEMCPY((char *)&a,p,sizeof(a));
   return a;
 }
 
-INT16 EXTRACT_WORD_(unsigned char *p)
+PMOD_EXPORT INT16 EXTRACT_WORD_(unsigned char *p)
 {
   INT16 a;
   MEMCPY((char *)&a,p,sizeof(a));
   return a;
 }
 
-INT32 EXTRACT_INT_(unsigned char *p)
+PMOD_EXPORT INT32 EXTRACT_INT_(unsigned char *p)
 {
   INT32 a;
   MEMCPY((char *)&a,p,sizeof(a));
diff --git a/src/precompile.sh.in b/src/precompile.sh.in
index 177d538c8b..c2fece29b2 100644
--- a/src/precompile.sh.in
+++ b/src/precompile.sh.in
@@ -2,9 +2,19 @@
 
 #set -x
 
+SCRIPT="$1"
+TARGET="$2"
+shift 2
+
 TMP_BUILDDIR="@BUILDDIR@"
 TMP_BINDIR="@BINDIR@"
 LIBDIR_SRC="@LIBDIR@"
+SRCDIR="@srcdir@"
+
+export TMP_BUILDDIR
+export LIBDIR_SRC
+export TMP_BUILDDIR
+export SRCDIR
 
 if test -f "$TMP_BUILDDIR/precompile-method" ; then
   . "$TMP_BUILDDIR/precompile-method"
@@ -69,13 +79,13 @@ esac
 
 #
 # By linking these two files to the current directory I can make
-# precompile.pike work with older versions of Pike - Hubbe
+# $SCRIPT work with older versions of Pike - Hubbe
 #
 
-if test -f ./precompile.pike ; then
+if test -f ./$SCRIPT ; then
   :
 else
-  ln -s "$TMP_BINDIR/precompile.pike"  ./precompile.pike
+  ln -s "$TMP_BINDIR/$SCRIPT"  ./$SCRIPT
 fi
 
 if test -f ./C.pmod ; then
@@ -87,8 +97,8 @@ fi
 
 
 if test "x${RUNPIKE-}" != x ; then
-echo "precompile: $RUNPIKE ./precompile.pike $1 >$2 (method=$method)"
-if $RUNPIKE ./precompile.pike "$1" >"$2" ; then
+echo "precompile: $RUNPIKE ./$SCRIPT $@ >$TARGET (method=$method)"
+if $RUNPIKE ./$SCRIPT "$@" >"$TARGET" ; then
 
 cat > "$TMP_BUILDDIR/precompile-method" <<EOF
 LAST_PIKE=$LAST_PIKE
@@ -104,4 +114,5 @@ retries=.$retries
 
 done # retry
 # Total failure
-rm "$2"
\ No newline at end of file
+rm "$TARGET"
+exit 1
\ No newline at end of file
diff --git a/src/program.c b/src/program.c
index c56866e3af..a087a30b09 100644
--- a/src/program.c
+++ b/src/program.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: program.c,v 1.251 2000/07/18 05:48:20 mast Exp $");
+RCSID("$Id: program.c,v 1.252 2000/07/28 17:16:55 hubbe Exp $");
 #include "program.h"
 #include "object.h"
 #include "dynamic_buffer.h"
@@ -876,7 +876,7 @@ void low_start_new_program(struct program *p,
   debug_malloc_touch(Pike_compiler->fake_object->storage);
 }
 
-void debug_start_new_program(PROGRAM_LINE_ARGS)
+PMOD_EXPORT void debug_start_new_program(PROGRAM_LINE_ARGS)
 {
   CDFPRINTF((stderr,
 	     "th(%ld) start_new_program(): threads_disabled:%d, compilation_depth:%d\n",
@@ -894,7 +894,7 @@ void debug_start_new_program(PROGRAM_LINE_ARGS)
 }
 
 
-void really_free_program(struct program *p)
+PMOD_EXPORT void really_free_program(struct program *p)
 {
   unsigned INT16 e;
 
@@ -1372,7 +1372,7 @@ struct program *end_first_pass(int finish)
 /*
  * Finish this program, returning the newly built program
  */
-struct program *debug_end_program(void)
+PMOD_EXPORT struct program *debug_end_program(void)
 {
   return end_first_pass(1);
 }
@@ -1382,7 +1382,7 @@ struct program *debug_end_program(void)
  * Allocate needed for this program in the object structure.
  * An offset to the data is returned.
  */
-size_t low_add_storage(size_t size, size_t alignment, int modulo_orig)
+PMOD_EXPORT size_t low_add_storage(size_t size, size_t alignment, int modulo_orig)
 {
   long offset;
   int modulo;
@@ -1446,7 +1446,7 @@ size_t low_add_storage(size_t size, size_t alignment, int modulo_orig)
  * set a callback used to initialize clones of this program
  * the init function is called at clone time
  */
-void set_init_callback(void (*init)(struct object *))
+PMOD_EXPORT void set_init_callback(void (*init)(struct object *))
 {
   Pike_compiler->new_program->init=init;
 }
@@ -1455,7 +1455,7 @@ void set_init_callback(void (*init)(struct object *))
  * set a callback used to de-initialize clones of this program
  * the exit function is called at destruct
  */
-void set_exit_callback(void (*exit)(struct object *))
+PMOD_EXPORT void set_exit_callback(void (*exit)(struct object *))
 {
   Pike_compiler->new_program->exit=exit;
 }
@@ -1472,7 +1472,7 @@ void set_exit_callback(void (*exit)(struct object *))
  * during a gc pass. The gc assumes that the references are enumerated
  * in the same order in that case.
  */
-void set_gc_recurse_callback(void (*m)(struct object *))
+PMOD_EXPORT void set_gc_recurse_callback(void (*m)(struct object *))
 {
   Pike_compiler->new_program->gc_recurse_func=m;
 }
@@ -1488,7 +1488,7 @@ void set_gc_recurse_callback(void (*m)(struct object *))
  * to ensure this; it's zero when called the first time for its
  * argument.
  */
-void set_gc_check_callback(void (*m)(struct object *))
+PMOD_EXPORT void set_gc_check_callback(void (*m)(struct object *))
 {
   Pike_compiler->new_program->gc_check_func=m;
 }
@@ -1823,7 +1823,7 @@ void low_inherit(struct program *p,
   }
 }
 
-void do_inherit(struct svalue *s,
+PMOD_EXPORT void do_inherit(struct svalue *s,
 		INT32 flags,
 		struct pike_string *name)
 {
@@ -1998,7 +1998,7 @@ int low_define_variable(struct pike_string *name,
   return n;
 }
 
-int map_variable(char *name,
+PMOD_EXPORT int map_variable(char *name,
 		 char *type,
 		 INT32 flags,
 		 size_t offset,
@@ -2020,7 +2020,7 @@ int map_variable(char *name,
   return ret;
 }
 
-int quick_map_variable(char *name,
+PMOD_EXPORT int quick_map_variable(char *name,
 		       int name_length,
 		       size_t offset,
 		       char *type,
@@ -2161,7 +2161,7 @@ int define_variable(struct pike_string *name,
   return n;
 }
 
-int simple_add_variable(char *name,
+PMOD_EXPORT int simple_add_variable(char *name,
 			char *type,
 			INT32 flags)
 {
@@ -2176,7 +2176,7 @@ int simple_add_variable(char *name,
   return ret;
 }
 
-int add_constant(struct pike_string *name,
+PMOD_EXPORT int add_constant(struct pike_string *name,
 		 struct svalue *c,
 		 INT32 flags)
 {
@@ -2314,7 +2314,7 @@ int add_constant(struct pike_string *name,
   return n;
 }
 
-int simple_add_constant(char *name,
+PMOD_EXPORT int simple_add_constant(char *name,
 			struct svalue *c,
 			INT32 flags)
 {
@@ -2326,7 +2326,7 @@ int simple_add_constant(char *name,
   return ret;
 }
 
-int add_integer_constant(char *name,
+PMOD_EXPORT int add_integer_constant(char *name,
 			 INT32 i,
 			 INT32 flags)
 {
@@ -2337,7 +2337,7 @@ int add_integer_constant(char *name,
   return simple_add_constant(name, &tmp, flags);
 }
 
-int quick_add_integer_constant(char *name,
+PMOD_EXPORT int quick_add_integer_constant(char *name,
 			       int name_length,
 			       INT32 i,
 			       INT32 flags)
@@ -2355,7 +2355,7 @@ int quick_add_integer_constant(char *name,
   return ret;
 }
 
-int add_float_constant(char *name,
+PMOD_EXPORT int add_float_constant(char *name,
 			 double f,
 			 INT32 flags)
 {
@@ -2366,7 +2366,7 @@ int add_float_constant(char *name,
   return simple_add_constant(name, &tmp, flags);
 }
 
-int add_string_constant(char *name,
+PMOD_EXPORT int add_string_constant(char *name,
 			char *str,
 			INT32 flags)
 {
@@ -2380,7 +2380,7 @@ int add_string_constant(char *name,
   return ret;
 }
 
-int add_program_constant(char *name,
+PMOD_EXPORT int add_program_constant(char *name,
 			 struct program *p,
 			 INT32 flags)
 {
@@ -2393,7 +2393,7 @@ int add_program_constant(char *name,
   return ret;
 }
 
-int add_object_constant(char *name,
+PMOD_EXPORT int add_object_constant(char *name,
 			struct object *o,
 			INT32 flags)
 {
@@ -2406,7 +2406,7 @@ int add_object_constant(char *name,
   return ret;
 }
 
-int add_function_constant(char *name, void (*cfun)(INT32), char * type, INT16 flags)
+PMOD_EXPORT int add_function_constant(char *name, void (*cfun)(INT32), char * type, INT16 flags)
 {
   struct svalue s;
   struct pike_string *n;
@@ -2421,7 +2421,7 @@ int add_function_constant(char *name, void (*cfun)(INT32), char * type, INT16 fl
 }
 
 
-int debug_end_class(char *name, int namelen, INT32 flags)
+PMOD_EXPORT int debug_end_class(char *name, int namelen, INT32 flags)
 {
   INT32 ret;
   struct svalue tmp;
@@ -2798,7 +2798,7 @@ int find_shared_string_identifier(struct pike_string *name,
   return low_find_shared_string_identifier(name,prog);
 }
 
-int find_identifier(char *name,struct program *prog)
+PMOD_EXPORT int find_identifier(char *name,struct program *prog)
 {
   struct pike_string *n;
   if(!prog) {
@@ -3079,7 +3079,7 @@ void store_linenumber(INT32 current_line, struct pike_string *current_file)
  * program, and line will be initialized to the line
  * in that file.
  */
-char *get_line(unsigned char *pc,struct program *prog,INT32 *linep)
+PMOD_EXPORT char *get_line(unsigned char *pc,struct program *prog,INT32 *linep)
 {
   static char *file, *cnt;
   static INT32 off,line,pid;
@@ -3318,7 +3318,7 @@ struct program *compile(struct pike_string *prog,
   return p;
 }
 
-int pike_add_function(char *name,void (*cfun)(INT32),char *type,INT16 flags)
+PMOD_EXPORT int pike_add_function(char *name,void (*cfun)(INT32),char *type,INT16 flags)
 {
   int ret;
   struct pike_string *name_tmp,*type_tmp;
@@ -3347,7 +3347,7 @@ int pike_add_function(char *name,void (*cfun)(INT32),char *type,INT16 flags)
   return ret;
 }
 
-int quick_add_function(char *name,
+PMOD_EXPORT int quick_add_function(char *name,
 		       int name_length,
 		       void (*cfun)(INT32),
 		       char *type,
@@ -3892,7 +3892,7 @@ int low_get_storage(struct program *o, struct program *p)
   return offset;
 }
 
-char *get_storage(struct object *o, struct program *p)
+PMOD_EXPORT char *get_storage(struct object *o, struct program *p)
 {
   int offset;
 
@@ -3917,7 +3917,7 @@ struct program *low_program_from_function(struct program *p,
   return f->u.program;
 }
 
-struct program *program_from_function(struct svalue *f)
+PMOD_EXPORT struct program *program_from_function(struct svalue *f)
 {
   struct identifier *id;
   if(f->type != T_FUNCTION) return 0;
@@ -3926,7 +3926,7 @@ struct program *program_from_function(struct svalue *f)
   return low_program_from_function(f->u.object->prog, f->subtype);
 }
 
-struct program *program_from_svalue(struct svalue *s)
+PMOD_EXPORT struct program *program_from_svalue(struct svalue *s)
 {
   switch(s->type)
   {
@@ -4070,7 +4070,7 @@ struct implements_cache_s { INT32 aid, bid, ret; };
 static struct implements_cache_s implements_cache[IMPLEMENTS_CACHE_SIZE];
 
 /* returns 1 if a implements b, but faster */
-int implements(struct program *a, struct program *b)
+PMOD_EXPORT int implements(struct program *a, struct program *b)
 {
   unsigned long hval;
   if(!a || !b) return -1;
@@ -4137,7 +4137,7 @@ static struct implements_cache_s is_compatible_cache[IMPLEMENTS_CACHE_SIZE];
 /* Returns 1 if a is compatible with b
  * ie it's possible to write a hypothetical c that implements both.
  */
-int is_compatible(struct program *a, struct program *b)
+PMOD_EXPORT int is_compatible(struct program *a, struct program *b)
 {
   unsigned long hval;
   unsigned long rhval;
@@ -4238,7 +4238,7 @@ int yyexplain_not_implements(struct program *a, struct program *b, int flags)
   return 1;
 }
 
-void *parent_storage(int depth)
+PMOD_EXPORT void *parent_storage(int depth)
 {
   struct inherit *inherit;
   struct program *p;
diff --git a/src/program.h b/src/program.h
index c0b338d047..8168f9ab6f 100644
--- a/src/program.h
+++ b/src/program.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: program.h,v 1.96 2000/07/18 05:48:20 mast Exp $
+ * $Id: program.h,v 1.97 2000/07/28 17:16:55 hubbe Exp $
  */
 #ifndef PROGRAM_H
 #define PROGRAM_H
@@ -24,6 +24,9 @@
 #define EXTERN
 #include "compilation.h"
 
+/* Needed to support dynamic loading on NT */
+PMOD_PROTO extern struct program_state * Pike_compiler;
+
 
 #ifdef PIKE_DEBUG
 #define PROGRAM_LINE_ARGS int line, char *file
@@ -329,29 +332,31 @@ void ins_int(INT32 i, void (*func)(char tmp));
 void ins_short(INT16 i, void (*func)(char tmp));
 void use_module(struct svalue *s);
 void unuse_modules(INT32 howmany);
-struct node_s *find_module_identifier(struct pike_string *ident, int see_inherit);
+struct node_s *find_module_identifier(struct pike_string *ident,
+				      int see_inherit);
 struct program *parent_compilation(int level);
 struct program *id_to_program(INT32 id);
 void optimize_program(struct program *p);
 int program_function_index_compare(const void *a,const void *b);
+char *find_program_name(struct program *p, INT32 *line);
 void fixate_program(void);
 struct program *low_allocate_program(void);
 void low_start_new_program(struct program *p,
 			   struct pike_string *name,
 			   int flags,
 			   int *idp);
-void debug_start_new_program(PROGRAM_LINE_ARGS);
-void really_free_program(struct program *p);
+PMOD_EXPORT void debug_start_new_program(PROGRAM_LINE_ARGS);
+PMOD_EXPORT void really_free_program(struct program *p);
 void dump_program_desc(struct program *p);
 int sizeof_variable(int run_time_type);
 void check_program(struct program *p);
 struct program *end_first_pass(int finish);
-struct program *debug_end_program(void);
-size_t low_add_storage(size_t size, size_t alignment, int modulo_orig);
-void set_init_callback(void (*init)(struct object *));
-void set_exit_callback(void (*exit)(struct object *));
-void set_gc_recurse_callback(void (*m)(struct object *));
-void set_gc_check_callback(void (*m)(struct object *));
+PMOD_EXPORT struct program *debug_end_program(void);
+PMOD_EXPORT size_t low_add_storage(size_t size, size_t alignment, int modulo_orig);
+PMOD_EXPORT void set_init_callback(void (*init)(struct object *));
+PMOD_EXPORT void set_exit_callback(void (*exit)(struct object *));
+PMOD_EXPORT void set_gc_recurse_callback(void (*m)(struct object *));
+PMOD_EXPORT void set_gc_check_callback(void (*m)(struct object *));
 int low_reference_inherited_identifier(struct program_state *q,
 				       int e,
 				       struct pike_string *name,
@@ -366,7 +371,7 @@ void low_inherit(struct program *p,
 		 int parent_offset,
 		 INT32 flags,
 		 struct pike_string *name);
-void do_inherit(struct svalue *s,
+PMOD_EXPORT void do_inherit(struct svalue *s,
 		INT32 flags,
 		struct pike_string *name);
 void compiler_do_inherit(node *n,
@@ -381,12 +386,12 @@ int low_define_variable(struct pike_string *name,
 			INT32 flags,
 			size_t offset,
 			INT32 run_time_type);
-int map_variable(char *name,
+PMOD_EXPORT int map_variable(char *name,
 		 char *type,
 		 INT32 flags,
 		 size_t offset,
 		 INT32 run_time_type);
-int quick_map_variable(char *name,
+PMOD_EXPORT int quick_map_variable(char *name,
 		       int name_length,
 		       size_t offset,
 		       char *type,
@@ -396,36 +401,36 @@ int quick_map_variable(char *name,
 int define_variable(struct pike_string *name,
 		    struct pike_string *type,
 		    INT32 flags);
-int simple_add_variable(char *name,
+PMOD_EXPORT int simple_add_variable(char *name,
 			char *type,
 			INT32 flags);
-int add_constant(struct pike_string *name,
+PMOD_EXPORT int add_constant(struct pike_string *name,
 		 struct svalue *c,
 		 INT32 flags);
-int simple_add_constant(char *name,
+PMOD_EXPORT int simple_add_constant(char *name,
 			struct svalue *c,
 			INT32 flags);
-int add_integer_constant(char *name,
+PMOD_EXPORT int add_integer_constant(char *name,
 			 INT32 i,
 			 INT32 flags);
-int quick_add_integer_constant(char *name,
+PMOD_EXPORT int quick_add_integer_constant(char *name,
 			       int name_length,
 			       INT32 i,
 			       INT32 flags);
-int add_float_constant(char *name,
+PMOD_EXPORT int add_float_constant(char *name,
 			 double f,
 			 INT32 flags);
-int add_string_constant(char *name,
+PMOD_EXPORT int add_string_constant(char *name,
 			char *str,
 			INT32 flags);
-int add_program_constant(char *name,
+PMOD_EXPORT int add_program_constant(char *name,
 			 struct program *p,
 			 INT32 flags);
-int add_object_constant(char *name,
+PMOD_EXPORT int add_object_constant(char *name,
 			struct object *o,
 			INT32 flags);
-int add_function_constant(char *name, void (*cfun)(INT32), char * type, INT16 flags);
-int debug_end_class(char *name, int namelen, INT32 flags);
+PMOD_EXPORT int add_function_constant(char *name, void (*cfun)(INT32), char * type, INT16 flags);
+PMOD_EXPORT int debug_end_class(char *name, int namelen, INT32 flags);
 INT32 define_function(struct pike_string *name,
 		      struct pike_string *type,
 		      INT16 flags,
@@ -457,7 +462,7 @@ void my_yyerror(char *fmt,...)  ATTRIBUTE((format(printf,1,2)));
 struct program *compile(struct pike_string *prog,
 			struct object *handler);
 int pike_add_function(char *name,void (*cfun)(INT32),char *type,INT16 flags);
-int quick_add_function(char *name,
+PMOD_EXPORT int quick_add_function(char *name,
 		       int name_length,
 		       void (*cfun)(INT32),
 		       char *type,
@@ -468,10 +473,10 @@ void check_all_programs(void);
 void init_program(void);
 void cleanup_program(void);
 void gc_mark_program_as_referenced(struct program *p);
+void real_gc_cycle_check_program(struct program *p, int weak);
 unsigned gc_touch_all_programs(void);
 void gc_check_all_programs(void);
 void gc_mark_all_programs(void);
-void real_gc_cycle_check_program(struct program *p, int weak);
 void gc_cycle_check_all_programs(void);
 void gc_zap_ext_weak_refs_in_programs(void);
 void gc_free_all_unreferenced_programs(void);
diff --git a/src/signal_handler.c b/src/signal_handler.c
index 30c8f83ef3..e6aea6ce58 100644
--- a/src/signal_handler.c
+++ b/src/signal_handler.c
@@ -25,7 +25,7 @@
 #include "main.h"
 #include <signal.h>
 
-RCSID("$Id: signal_handler.c,v 1.172 2000/07/11 17:52:16 neotron Exp $");
+RCSID("$Id: signal_handler.c,v 1.173 2000/07/28 17:16:55 hubbe Exp $");
 
 #ifdef HAVE_PASSWD_H
 # include <passwd.h>
@@ -629,7 +629,7 @@ static int signalling=0;
 
 static void unset_signalling(void *notused) { signalling=0; }
 
-void check_signals(struct callback *foo, void *bar, void *gazonk)
+PMOD_EXPORT void check_signals(struct callback *foo, void *bar, void *gazonk)
 {
   ONERROR ebuf;
 #ifdef PIKE_DEBUG
diff --git a/src/stralloc.c b/src/stralloc.c
index 047f0eef84..73444a008f 100644
--- a/src/stralloc.c
+++ b/src/stralloc.c
@@ -25,7 +25,7 @@
 #define HUGE HUGE_VAL
 #endif /*!HUGE*/
 
-RCSID("$Id: stralloc.c,v 1.84 2000/07/06 23:25:26 mast Exp $");
+RCSID("$Id: stralloc.c,v 1.85 2000/07/28 17:16:55 hubbe Exp $");
 
 #define BEGIN_HASH_SIZE 997
 #define MAX_AVG_LINK_LENGTH 3
@@ -103,7 +103,7 @@ static INLINE unsigned INT32 generic_extract (const void *str, int size, int pos
   return 0;
 }
 
-INLINE unsigned INT32 index_shared_string(struct pike_string *s, int pos)
+PMOD_EXPORT INLINE unsigned INT32 index_shared_string(struct pike_string *s, int pos)
 {
 #ifdef PIKE_DEBUG
   if(pos > s->len || pos<0) {
@@ -117,7 +117,7 @@ INLINE unsigned INT32 index_shared_string(struct pike_string *s, int pos)
   return generic_extract(s->str,s->size_shift,pos);
 }
 
-INLINE void low_set_index(struct pike_string *s, int pos, int value)
+PMOD_EXPORT INLINE void low_set_index(struct pike_string *s, int pos, int value)
 {
 #ifdef PIKE_DEBUG
   if(pos > s->len || pos<0)
@@ -137,7 +137,7 @@ INLINE void low_set_index(struct pike_string *s, int pos, int value)
 }
 
 #ifdef PIKE_DEBUG
-INLINE struct pike_string *debug_check_size_shift(struct pike_string *a,int shift)
+PMOD_EXPORT INLINE struct pike_string *debug_check_size_shift(struct pike_string *a,int shift)
 {
   if(a->size_shift != shift)
     fatal("Wrong STRX macro used!\n");
@@ -160,7 +160,7 @@ CONVERT(2,0)
 CONVERT(2,1)
 
 
-int generic_compare_strings(const void *a,int alen, int asize,
+PMOD_EXPORT int generic_compare_strings(const void *a,int alen, int asize,
 			    const void *b,int blen, int bsize)
 {
 #define TWO_SIZES(X,Y) (((X)<<2)+(Y))
@@ -178,7 +178,7 @@ int generic_compare_strings(const void *a,int alen, int asize,
 }
 
 
-void generic_memcpy(PCHARP to,
+PMOD_EXPORT void generic_memcpy(PCHARP to,
 		    PCHARP from,
 		    int len)
 {
@@ -221,7 +221,7 @@ void generic_memcpy(PCHARP to,
   }
 }
 
-INLINE void pike_string_cpy(PCHARP to,
+PMOD_EXPORT INLINE void pike_string_cpy(PCHARP to,
 			    struct pike_string *from)
 {
   generic_memcpy(to,MKPCHARP_STR(from),from->len);
@@ -334,12 +334,12 @@ static struct pike_string *internal_findstring(const char *s,
   return 0; /* not found */
 }
 
-struct pike_string *binary_findstring(const char *foo, INT32 l)
+PMOD_EXPORT struct pike_string *binary_findstring(const char *foo, INT32 l)
 {
   return internal_findstring(foo, l, 0, StrHash(foo,l));
 }
 
-struct pike_string *findstring(const char *foo)
+PMOD_EXPORT struct pike_string *findstring(const char *foo)
 {
   return binary_findstring(foo, strlen(foo));
 }
@@ -411,7 +411,7 @@ static void rehash(void)
 /* note that begin_shared_string expects the _exact_ size of the string,
  * not the maximum size
  */
-struct pike_string *debug_begin_shared_string(int len)
+PMOD_EXPORT struct pike_string *debug_begin_shared_string(int len)
 {
   struct pike_string *t;
 #ifdef PIKE_DEBUG
@@ -471,7 +471,7 @@ static void link_pike_string(struct pike_string *s, unsigned int h)
 #endif
 }
 
-struct pike_string *debug_begin_wide_shared_string(int len, int shift)
+PMOD_EXPORT struct pike_string *debug_begin_wide_shared_string(int len, int shift)
 {
   struct pike_string *t;
 #ifdef PIKE_DEBUG
@@ -490,7 +490,7 @@ struct pike_string *debug_begin_wide_shared_string(int len, int shift)
  * This function assumes that the shift size is already the minimum it
  * can be.
  */
-struct pike_string *low_end_shared_string(struct pike_string *s)
+PMOD_EXPORT struct pike_string *low_end_shared_string(struct pike_string *s)
 {
   int len,h;
   struct pike_string *s2;
@@ -520,7 +520,7 @@ struct pike_string *low_end_shared_string(struct pike_string *s)
  * This function checks if the shift size can be decreased before
  * entering the string in the shared string table
  */
-struct pike_string *end_shared_string(struct pike_string *s)
+PMOD_EXPORT struct pike_string *end_shared_string(struct pike_string *s)
 {
   struct pike_string *s2;
 
@@ -565,7 +565,7 @@ struct pike_string *end_shared_string(struct pike_string *s)
 }
 
 
-struct pike_string * debug_make_shared_binary_string(const char *str,int len)
+PMOD_EXPORT struct pike_string * debug_make_shared_binary_string(const char *str,int len)
 {
   struct pike_string *s;
   int h=StrHash(str,len);
@@ -583,7 +583,7 @@ struct pike_string * debug_make_shared_binary_string(const char *str,int len)
   return s;
 }
 
-struct pike_string * debug_make_shared_binary_pcharp(const PCHARP str,int len)
+PMOD_EXPORT struct pike_string * debug_make_shared_binary_pcharp(const PCHARP str,int len)
 {
   switch(str.shift)
   {
@@ -600,17 +600,17 @@ struct pike_string * debug_make_shared_binary_pcharp(const PCHARP str,int len)
   return NULL;	/* Keep the compiler happy */
 }
 
-struct pike_string * debug_make_shared_pcharp(const PCHARP str)
+PMOD_EXPORT struct pike_string * debug_make_shared_pcharp(const PCHARP str)
 {
   return debug_make_shared_binary_pcharp(str, pcharp_strlen(str));
 }
 
-struct pike_string * debug_make_shared_binary_string0(const p_wchar0 *str,int len)
+PMOD_EXPORT struct pike_string * debug_make_shared_binary_string0(const p_wchar0 *str,int len)
 {
   return debug_make_shared_binary_string((const char *)str, len);
 }
 
-struct pike_string * debug_make_shared_binary_string1(const p_wchar1 *str,int len)
+PMOD_EXPORT struct pike_string * debug_make_shared_binary_string1(const p_wchar1 *str,int len)
 {
   struct pike_string *s;
   int h;
@@ -638,7 +638,7 @@ struct pike_string * debug_make_shared_binary_string1(const p_wchar1 *str,int le
   return s;
 }
 
-struct pike_string * debug_make_shared_binary_string2(const p_wchar2 *str,int len)
+PMOD_EXPORT struct pike_string * debug_make_shared_binary_string2(const p_wchar2 *str,int len)
 {
   struct pike_string *s;
   int h;
@@ -673,24 +673,24 @@ struct pike_string * debug_make_shared_binary_string2(const p_wchar2 *str,int le
   return s;
 }
 
-struct pike_string *debug_make_shared_string(const char *str)
+PMOD_EXPORT struct pike_string *debug_make_shared_string(const char *str)
 {
   return make_shared_binary_string(str, strlen(str));
 }
 
-struct pike_string *debug_make_shared_string0(const p_wchar0 *str)
+PMOD_EXPORT struct pike_string *debug_make_shared_string0(const p_wchar0 *str)
 {
   return debug_make_shared_string((const char *)str);
 }
 
-struct pike_string *debug_make_shared_string1(const p_wchar1 *str)
+PMOD_EXPORT struct pike_string *debug_make_shared_string1(const p_wchar1 *str)
 {
   INT32 len;
   for(len=0;str[len];len++);
   return debug_make_shared_binary_string1(str,len);
 }
 
-struct pike_string *debug_make_shared_string2(const p_wchar2 *str)
+PMOD_EXPORT struct pike_string *debug_make_shared_string2(const p_wchar2 *str)
 {
   INT32 len;
   for(len=0;str[len];len++);
@@ -699,7 +699,7 @@ struct pike_string *debug_make_shared_string2(const p_wchar2 *str)
 
 /*** Free strings ***/
 
-void unlink_pike_string(struct pike_string *s)
+PMOD_EXPORT void unlink_pike_string(struct pike_string *s)
 {
   unsigned int h=s->hval % htable_size;
   propagate_shared_string(s,h);
@@ -710,13 +710,13 @@ void unlink_pike_string(struct pike_string *s)
   num_strings--;
 }
 
-void do_free_string(struct pike_string *s)
+PMOD_EXPORT void do_free_string(struct pike_string *s)
 {
   if (s)
     free_string(s);
 }
 
-void really_free_string(struct pike_string *s)
+PMOD_EXPORT void really_free_string(struct pike_string *s)
 {
 #ifdef PIKE_DEBUG
   extern int d_flag;
@@ -738,7 +738,7 @@ void really_free_string(struct pike_string *s)
   debug_free((char *)s,DMALLOC_LOCATION(),1);
 }
 
-void debug_free_string(struct pike_string *s)
+PMOD_EXPORT void debug_free_string(struct pike_string *s)
 {
   if(--s->refs<=0)
     really_free_string(s);
@@ -801,7 +801,7 @@ struct pike_string *add_string_status(int verbose)
 /*** PIKE_DEBUG ***/
 #ifdef PIKE_DEBUG
 
-void check_string(struct pike_string *s)
+PMOD_EXPORT void check_string(struct pike_string *s)
 {
   do_hash(s);
   if(full_hash_value != s->hval)
@@ -820,7 +820,7 @@ void check_string(struct pike_string *s)
   }
 }
 
-void verify_shared_strings_tables(void)
+PMOD_EXPORT void verify_shared_strings_tables(void)
 {
   unsigned INT32 e, h, num=0;
   unsigned INT32 orig_full_hash = full_hash_value;
@@ -872,7 +872,7 @@ void verify_shared_strings_tables(void)
   full_hash_value = orig_full_hash;
 }
 
-int safe_debug_findstring(struct pike_string *foo)
+PMOD_EXPORT int safe_debug_findstring(struct pike_string *foo)
 {
   unsigned INT32 e;
   if(!base_table) return 0;
@@ -885,7 +885,7 @@ int safe_debug_findstring(struct pike_string *foo)
   return 0;
 }
 
-struct pike_string *debug_findstring(const struct pike_string *foo)
+PMOD_EXPORT struct pike_string *debug_findstring(const struct pike_string *foo)
 {
   struct pike_string *tmp;
   tmp=propagate_shared_string(foo, foo->hval % htable_size);
@@ -928,7 +928,7 @@ struct pike_string *debug_findstring(const struct pike_string *foo)
   return tmp;
 }
 
-void debug_dump_pike_string(struct pike_string *s, INT32 max)
+PMOD_EXPORT void debug_dump_pike_string(struct pike_string *s, INT32 max)
 {
   INT32 e;
   fprintf(stderr,"0x%p: %ld refs, len=%ld, size_shift=%d, hval=%lux (%lx)\n",
@@ -981,7 +981,7 @@ void dump_stralloc_strings(void)
 /*** String compare functions ***/
 
 /* does not take locale into account */
-int low_quick_binary_strcmp(char *a,INT32 alen,
+PMOD_EXPORT int low_quick_binary_strcmp(char *a,INT32 alen,
 			    char *b,INT32 blen)
 {
   int tmp;
@@ -1001,7 +1001,7 @@ int low_quick_binary_strcmp(char *a,INT32 alen,
 
 
 /* does not take locale into account */
-int generic_quick_binary_strcmp(const char *a,INT32 alen, int asize,
+PMOD_EXPORT int generic_quick_binary_strcmp(const char *a,INT32 alen, int asize,
 				const char *b,INT32 blen, int bsize)
 {
   if(!asize && !bsize)
@@ -1031,14 +1031,14 @@ int generic_quick_binary_strcmp(const char *a,INT32 alen, int asize,
   }
 }
 
-int c_compare_string(struct pike_string *s, char *foo, int len)
+PMOD_EXPORT int c_compare_string(struct pike_string *s, char *foo, int len)
 {
   return s->len == len && s->size_shift == 0 && !MEMCMP(s->str,foo,len);
 }
 
 #ifndef HAVE_STRCOLL
 /* No locale function available */
-static int low_binary_strcmp(char *a,INT32 alen,
+int low_binary_strcmp(char *a,INT32 alen,
 		      char *b,INT32 blen)
 {
   low_quick_binary_strcmp(a,alen,b,blen);
@@ -1068,7 +1068,7 @@ static int low_binary_strcmp(char *a,INT32 alen,
 
 /* Does not take locale into account */
 
-int my_quick_strcmp(struct pike_string *a,struct pike_string *b)
+PMOD_EXPORT int my_quick_strcmp(struct pike_string *a,struct pike_string *b)
 {
   if(a==b) return 0;
 
@@ -1077,7 +1077,7 @@ int my_quick_strcmp(struct pike_string *a,struct pike_string *b)
 }
 
 /* Does take locale into account */
-int my_strcmp(struct pike_string *a,struct pike_string *b)
+PMOD_EXPORT int my_strcmp(struct pike_string *a,struct pike_string *b)
 {
   if(a==b) return 0;
 
@@ -1114,7 +1114,7 @@ int my_strcmp(struct pike_string *a,struct pike_string *b)
   }
 }
 
-struct pike_string *realloc_unlinked_string(struct pike_string *a, INT32 size)
+PMOD_EXPORT struct pike_string *realloc_unlinked_string(struct pike_string *a, INT32 size)
 {
   struct pike_string *r;
   r=(struct pike_string *)realloc((char *)a,
@@ -1134,7 +1134,7 @@ struct pike_string *realloc_unlinked_string(struct pike_string *a, INT32 size)
 }
 
 /* Returns an unlinked string ready for end_shared_string */
-struct pike_string *realloc_shared_string(struct pike_string *a, INT32 size)
+PMOD_EXPORT struct pike_string *realloc_shared_string(struct pike_string *a, INT32 size)
 {
   struct pike_string *r;
   if(a->refs==1)
@@ -1149,7 +1149,7 @@ struct pike_string *realloc_shared_string(struct pike_string *a, INT32 size)
   }
 }
 
-struct pike_string *new_realloc_shared_string(struct pike_string *a, INT32 size, int shift)
+PMOD_EXPORT struct pike_string *new_realloc_shared_string(struct pike_string *a, INT32 size, int shift)
 {
   struct pike_string *r;
   if(shift == a->size_shift) return realloc_shared_string(a,size);
@@ -1168,7 +1168,7 @@ struct pike_string *new_realloc_shared_string(struct pike_string *a, INT32 size,
  * Phew, this function become complicated when I inserted magic for wide
  * characters...
  */
-struct pike_string *modify_shared_string(struct pike_string *a,
+PMOD_EXPORT struct pike_string *modify_shared_string(struct pike_string *a,
 					 INT32 index,
 					 INT32 c)
 {
@@ -1304,7 +1304,7 @@ struct pike_string *modify_shared_string(struct pike_string *a,
 }
 
 /*** Add strings ***/
-struct pike_string *add_shared_strings(struct pike_string *a,
+PMOD_EXPORT struct pike_string *add_shared_strings(struct pike_string *a,
 					 struct pike_string *b)
 {
   struct pike_string *ret;
@@ -1319,7 +1319,7 @@ struct pike_string *add_shared_strings(struct pike_string *a,
   return end_shared_string(ret);
 }
 
-struct pike_string *add_and_free_shared_strings(struct pike_string *a,
+PMOD_EXPORT struct pike_string *add_and_free_shared_strings(struct pike_string *a,
 						struct pike_string *b)
 {
   INT32 alen=a->len;
@@ -1338,7 +1338,7 @@ struct pike_string *add_and_free_shared_strings(struct pike_string *a,
 }
 
 
-int string_search(struct pike_string *haystack,
+PMOD_EXPORT int string_search(struct pike_string *haystack,
 		  struct pike_string *needle,
 		  int start)
 {
@@ -1365,7 +1365,7 @@ int string_search(struct pike_string *haystack,
   return (r-haystack->str)>>haystack->size_shift;
 }
 
-struct pike_string *string_slice(struct pike_string *s,
+PMOD_EXPORT struct pike_string *string_slice(struct pike_string *s,
 				 INT32 start,
 				 INT32 len)
 {
@@ -1398,7 +1398,7 @@ struct pike_string *string_slice(struct pike_string *s,
 }
 
 /*** replace function ***/
-struct pike_string *string_replace(struct pike_string *str,
+PMOD_EXPORT struct pike_string *string_replace(struct pike_string *str,
 				   struct pike_string *del,
 				   struct pike_string *to)
 {
@@ -1585,7 +1585,7 @@ void gc_mark_all_strings(void)
   }
 }
 
-void init_string_builder(struct string_builder *s, int mag)
+PMOD_EXPORT void init_string_builder(struct string_builder *s, int mag)
 {
   s->malloced=256;
   s->s=begin_wide_shared_string(256,mag);
@@ -1619,7 +1619,7 @@ static void string_build_mkspace(struct string_builder *s, int chars, int mag)
   }
 }
 
-void *string_builder_allocate(struct string_builder *s, int chars, int mag)
+PMOD_EXPORT void *string_builder_allocate(struct string_builder *s, int chars, int mag)
 {
   void *ret;
   string_build_mkspace(s,chars,mag);
@@ -1629,7 +1629,7 @@ void *string_builder_allocate(struct string_builder *s, int chars, int mag)
   return ret;
 }
 
-void string_builder_putchar(struct string_builder *s, int ch)
+PMOD_EXPORT void string_builder_putchar(struct string_builder *s, int ch)
 {
   INT32 i;
   string_build_mkspace(s,1,min_magnitude(ch));
@@ -1639,7 +1639,7 @@ void string_builder_putchar(struct string_builder *s, int ch)
 }
 
 
-void string_builder_binary_strcat(struct string_builder *s, char *str, INT32 len)
+PMOD_EXPORT void string_builder_binary_strcat(struct string_builder *s, char *str, INT32 len)
 {
   string_build_mkspace(s,len,0);
   switch(s->s->size_shift)
@@ -1654,7 +1654,7 @@ void string_builder_binary_strcat(struct string_builder *s, char *str, INT32 len
 }
 
 
-void string_builder_append(struct string_builder *s,
+PMOD_EXPORT void string_builder_append(struct string_builder *s,
 			   PCHARP from,
 			   INT32 len)
 {
@@ -1663,7 +1663,7 @@ void string_builder_append(struct string_builder *s,
   s->s->len+=len;
 }
 
-void string_builder_fill(struct string_builder *s,
+PMOD_EXPORT void string_builder_fill(struct string_builder *s,
 			 int howmany,
 			 PCHARP from,
 			 INT32 len,
@@ -1717,12 +1717,12 @@ void string_builder_fill(struct string_builder *s,
   }
 }
 
-void string_builder_strcat(struct string_builder *s, char *str)
+PMOD_EXPORT void string_builder_strcat(struct string_builder *s, char *str)
 {
   string_builder_binary_strcat(s,str,strlen(str));
 }
 
-void string_builder_shared_strcat(struct string_builder *s, struct pike_string *str)
+PMOD_EXPORT void string_builder_shared_strcat(struct string_builder *s, struct pike_string *str)
 {
   string_build_mkspace(s,str->len,str->size_shift);
 
@@ -1732,18 +1732,18 @@ void string_builder_shared_strcat(struct string_builder *s, struct pike_string *
 }
 
 
-void reset_string_builder(struct string_builder *s)
+PMOD_EXPORT void reset_string_builder(struct string_builder *s)
 {
   s->known_shift=0;
   s->s->len=0;
 }
 
-void free_string_builder(struct string_builder *s)
+PMOD_EXPORT void free_string_builder(struct string_builder *s)
 {
   free((char *)s->s);
 }
 
-struct pike_string *finish_string_builder(struct string_builder *s)
+PMOD_EXPORT struct pike_string *finish_string_builder(struct string_builder *s)
 {
   low_set_index(s->s,s->s->len,0);
   if(s->known_shift == s->s->size_shift)
@@ -1751,7 +1751,7 @@ struct pike_string *finish_string_builder(struct string_builder *s)
   return end_shared_string(s->s);
 }
 
-PCHARP MEMCHR_PCHARP(PCHARP ptr, int chr, int len)
+PMOD_EXPORT PCHARP MEMCHR_PCHARP(PCHARP ptr, int chr, int len)
 {
   switch(ptr.shift)
   {
@@ -1767,7 +1767,7 @@ PCHARP MEMCHR_PCHARP(PCHARP ptr, int chr, int len)
 			 WIDE_ISLOWER(x) ? (x) + 10 - 'a' : (x) + 10 - 'A')
 #define MBASE	('z' - 'a' + 1 + 10)
 
-long STRTOL_PCHARP(PCHARP str, PCHARP *ptr, int base)
+PMOD_EXPORT long STRTOL_PCHARP(PCHARP str, PCHARP *ptr, int base)
 {
   register long val;
   register int c;
@@ -1822,7 +1822,7 @@ long STRTOL_PCHARP(PCHARP str, PCHARP *ptr, int base)
   return (neg ? val : -val);
 }
 
-int string_to_svalue_inumber(struct svalue *r,
+PMOD_EXPORT int string_to_svalue_inumber(struct svalue *r,
 			     char * str,
 			     char **ptr,
 			     int base,
@@ -1838,7 +1838,7 @@ int string_to_svalue_inumber(struct svalue *r,
   return ret;
 }
 
-int wide_string_to_svalue_inumber(struct svalue *r,
+PMOD_EXPORT int wide_string_to_svalue_inumber(struct svalue *r,
 				  void * str,
 				  void **ptr,
 				  int base,
@@ -1855,7 +1855,7 @@ int wide_string_to_svalue_inumber(struct svalue *r,
   return ret;
 }
 
-int pcharp_to_svalue_inumber(struct svalue *r,
+PMOD_EXPORT int pcharp_to_svalue_inumber(struct svalue *r,
 			     PCHARP str,
 			     PCHARP *ptr,
 			     int base,
@@ -1990,7 +1990,7 @@ int pcharp_to_svalue_inumber(struct svalue *r,
   return 1;
 }
 
-int convert_stack_top_string_to_inumber(int base)
+PMOD_EXPORT int convert_stack_top_string_to_inumber(int base)
 {
   struct svalue r;
   int i;
@@ -2008,7 +2008,7 @@ int convert_stack_top_string_to_inumber(int base)
 
 /* Convert PCHARP to a double.  If ENDPTR is not NULL, a pointer to the
    character after the last one used in the number is put in *ENDPTR.  */
-double STRTOD_PCHARP(PCHARP nptr, PCHARP *endptr)
+PMOD_EXPORT double STRTOD_PCHARP(PCHARP nptr, PCHARP *endptr)
 {
   register PCHARP s;
   short int sign;
@@ -2156,7 +2156,7 @@ double STRTOD_PCHARP(PCHARP nptr, PCHARP *endptr)
 }
 
 
-p_wchar0 *require_wstring0(struct pike_string *s,
+PMOD_EXPORT p_wchar0 *require_wstring0(struct pike_string *s,
 			   char **to_free)
 {
   switch(s->size_shift)
@@ -2174,7 +2174,7 @@ p_wchar0 *require_wstring0(struct pike_string *s,
   return 0;
 }
 
-p_wchar1 *require_wstring1(struct pike_string *s,
+PMOD_EXPORT p_wchar1 *require_wstring1(struct pike_string *s,
 			   char **to_free)
 {
   switch(s->size_shift)
@@ -2198,7 +2198,7 @@ p_wchar1 *require_wstring1(struct pike_string *s,
 }
 
 
-p_wchar2 *require_wstring2(struct pike_string *s,
+PMOD_EXPORT p_wchar2 *require_wstring2(struct pike_string *s,
 			   char **to_free)
 {
   switch(s->size_shift)
diff --git a/src/stralloc.h b/src/stralloc.h
index 3d2b977bd5..33732a3cbf 100644
--- a/src/stralloc.h
+++ b/src/stralloc.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: stralloc.h,v 1.41 2000/03/20 21:00:04 hubbe Exp $
+ * $Id: stralloc.h,v 1.42 2000/07/28 17:16:55 hubbe Exp $
  */
 #ifndef STRALLOC_H
 #define STRALLOC_H
@@ -147,121 +147,125 @@ INLINE INT32 PIKE_CONCAT4(compare_,FROM,_to_,TO)(const PIKE_CONCAT(p_wchar,TO) *
 
 
 /* Prototypes begin here */
-INLINE unsigned INT32 index_shared_string(struct pike_string *s, int pos);
-INLINE void low_set_index(struct pike_string *s, int pos, int value);
-INLINE struct pike_string *debug_check_size_shift(struct pike_string *a,int shift);
+PMOD_EXPORT INLINE unsigned INT32 index_shared_string(struct pike_string *s, int pos);
+PMOD_EXPORT INLINE void low_set_index(struct pike_string *s, int pos, int value);
+PMOD_EXPORT INLINE struct pike_string *debug_check_size_shift(struct pike_string *a,int shift);
 CONVERT(0,1)
 CONVERT(0,2)
 CONVERT(1,0)
 CONVERT(1,2)
 CONVERT(2,0)
 CONVERT(2,1)
-int generic_compare_strings(const void *a,int alen, int asize,
+PMOD_EXPORT int generic_compare_strings(const void *a,int alen, int asize,
 			    const void *b,int blen, int bsize);
-void generic_memcpy(PCHARP to,
+PMOD_EXPORT void generic_memcpy(PCHARP to,
 		    PCHARP from,
 		    int len);
-INLINE void pike_string_cpy(PCHARP to,
+PMOD_EXPORT INLINE void pike_string_cpy(PCHARP to,
 			    struct pike_string *from);
-struct pike_string *binary_findstring(const char *foo, INT32 l);
-struct pike_string *findstring(const char *foo);
-struct pike_string *debug_begin_shared_string(int len);
-struct pike_string *debug_begin_wide_shared_string(int len, int shift);
-struct pike_string *low_end_shared_string(struct pike_string *s);
-struct pike_string *end_shared_string(struct pike_string *s);
-struct pike_string * debug_make_shared_binary_string(const char *str,int len);
-struct pike_string * debug_make_shared_binary_pcharp(const PCHARP str,int len);
-struct pike_string * debug_make_shared_pcharp(const PCHARP str);
-struct pike_string * debug_make_shared_binary_string0(const p_wchar0 *str,int len);
-struct pike_string * debug_make_shared_binary_string1(const p_wchar1 *str,int len);
-struct pike_string * debug_make_shared_binary_string2(const p_wchar2 *str,int len);
-struct pike_string *debug_make_shared_string(const char *str);
-struct pike_string *debug_make_shared_string0(const p_wchar0 *str);
-struct pike_string *debug_make_shared_string1(const p_wchar1 *str);
-struct pike_string *debug_make_shared_string2(const p_wchar2 *str);
-void unlink_pike_string(struct pike_string *s);
-void do_free_string(struct pike_string *s);
-void really_free_string(struct pike_string *s);
-void debug_free_string(struct pike_string *s);
+PMOD_EXPORT struct pike_string *binary_findstring(const char *foo, INT32 l);
+PMOD_EXPORT struct pike_string *findstring(const char *foo);
+PMOD_EXPORT struct pike_string *debug_begin_shared_string(int len);
+PMOD_EXPORT struct pike_string *debug_begin_wide_shared_string(int len, int shift);
+PMOD_EXPORT struct pike_string *low_end_shared_string(struct pike_string *s);
+PMOD_EXPORT struct pike_string *end_shared_string(struct pike_string *s);
+PMOD_EXPORT struct pike_string * debug_make_shared_binary_string(const char *str,int len);
+PMOD_EXPORT struct pike_string * debug_make_shared_binary_pcharp(const PCHARP str,int len);
+PMOD_EXPORT struct pike_string * debug_make_shared_pcharp(const PCHARP str);
+PMOD_EXPORT struct pike_string * debug_make_shared_binary_string0(const p_wchar0 *str,int len);
+PMOD_EXPORT struct pike_string * debug_make_shared_binary_string1(const p_wchar1 *str,int len);
+PMOD_EXPORT struct pike_string * debug_make_shared_binary_string2(const p_wchar2 *str,int len);
+PMOD_EXPORT struct pike_string *debug_make_shared_string(const char *str);
+PMOD_EXPORT struct pike_string *debug_make_shared_string0(const p_wchar0 *str);
+PMOD_EXPORT struct pike_string *debug_make_shared_string1(const p_wchar1 *str);
+PMOD_EXPORT struct pike_string *debug_make_shared_string2(const p_wchar2 *str);
+PMOD_EXPORT void unlink_pike_string(struct pike_string *s);
+PMOD_EXPORT void do_free_string(struct pike_string *s);
+PMOD_EXPORT void really_free_string(struct pike_string *s);
+PMOD_EXPORT void debug_free_string(struct pike_string *s);
 struct pike_string *add_string_status(int verbose);
-void check_string(struct pike_string *s);
-void verify_shared_strings_tables(void);
-int safe_debug_findstring(struct pike_string *foo);
-struct pike_string *debug_findstring(const struct pike_string *foo);
-void debug_dump_pike_string(struct pike_string *s, INT32 max);
+PMOD_EXPORT void check_string(struct pike_string *s);
+PMOD_EXPORT void verify_shared_strings_tables(void);
+PMOD_EXPORT int safe_debug_findstring(struct pike_string *foo);
+PMOD_EXPORT struct pike_string *debug_findstring(const struct pike_string *foo);
+PMOD_EXPORT void debug_dump_pike_string(struct pike_string *s, INT32 max);
 void dump_stralloc_strings(void);
-int low_quick_binary_strcmp(char *a,INT32 alen,
+PMOD_EXPORT int low_quick_binary_strcmp(char *a,INT32 alen,
 			    char *b,INT32 blen);
-int generic_quick_binary_strcmp(const char *a,INT32 alen, int asize,
+PMOD_EXPORT int generic_quick_binary_strcmp(const char *a,INT32 alen, int asize,
 				const char *b,INT32 blen, int bsize);
-int c_compare_string(struct pike_string *s, char *foo, int len);
-int my_quick_strcmp(struct pike_string *a,struct pike_string *b);
-int my_strcmp(struct pike_string *a,struct pike_string *b);
-struct pike_string *realloc_unlinked_string(struct pike_string *a, INT32 size);
-struct pike_string *realloc_shared_string(struct pike_string *a, INT32 size);
-struct pike_string *new_realloc_shared_string(struct pike_string *a, INT32 size, int shift);
-struct pike_string *modify_shared_string(struct pike_string *a,
+PMOD_EXPORT int c_compare_string(struct pike_string *s, char *foo, int len);
+PMOD_EXPORT static int low_binary_strcmp(char *a,INT32 alen,
+		      char *b,INT32 blen);
+PMOD_EXPORT static int low_binary_strcmp(char *a,INT32 alen,
+			     char *b,INT32 blen);
+PMOD_EXPORT int my_quick_strcmp(struct pike_string *a,struct pike_string *b);
+PMOD_EXPORT int my_strcmp(struct pike_string *a,struct pike_string *b);
+PMOD_EXPORT struct pike_string *realloc_unlinked_string(struct pike_string *a, INT32 size);
+PMOD_EXPORT struct pike_string *realloc_shared_string(struct pike_string *a, INT32 size);
+PMOD_EXPORT struct pike_string *new_realloc_shared_string(struct pike_string *a, INT32 size, int shift);
+PMOD_EXPORT struct pike_string *modify_shared_string(struct pike_string *a,
 					 INT32 index,
 					 INT32 c);
-struct pike_string *add_shared_strings(struct pike_string *a,
+PMOD_EXPORT struct pike_string *add_shared_strings(struct pike_string *a,
 					 struct pike_string *b);
-struct pike_string *add_and_free_shared_strings(struct pike_string *a,
+PMOD_EXPORT struct pike_string *add_and_free_shared_strings(struct pike_string *a,
 						struct pike_string *b);
-int string_search(struct pike_string *haystack,
+PMOD_EXPORT int string_search(struct pike_string *haystack,
 		  struct pike_string *needle,
 		  int start);
-struct pike_string *string_slice(struct pike_string *s,
+PMOD_EXPORT struct pike_string *string_slice(struct pike_string *s,
 				 INT32 start,
 				 INT32 len);
-struct pike_string *string_replace(struct pike_string *str,
+PMOD_EXPORT struct pike_string *string_replace(struct pike_string *str,
 				   struct pike_string *del,
 				   struct pike_string *to);
 void init_shared_string_table(void);
 void cleanup_shared_string_table(void);
 void count_memory_in_strings(INT32 *num, INT32 *size);
 void gc_mark_all_strings(void);
-void init_string_builder(struct string_builder *s, int mag);
-void *string_builder_allocate(struct string_builder *s, int chars, int mag);
-void string_builder_putchar(struct string_builder *s, int ch);
-void string_builder_binary_strcat(struct string_builder *s, char *str, INT32 len);
-void string_builder_append(struct string_builder *s,
+PMOD_EXPORT void init_string_builder(struct string_builder *s, int mag);
+PMOD_EXPORT void *string_builder_allocate(struct string_builder *s, int chars, int mag);
+PMOD_EXPORT void string_builder_putchar(struct string_builder *s, int ch);
+PMOD_EXPORT void string_builder_binary_strcat(struct string_builder *s, char *str, INT32 len);
+PMOD_EXPORT void string_builder_append(struct string_builder *s,
 			   PCHARP from,
 			   INT32 len);
-void string_builder_fill(struct string_builder *s,
+PMOD_EXPORT void string_builder_fill(struct string_builder *s,
 			 int howmany,
 			 PCHARP from,
 			 INT32 len,
 			 INT32 offset);
-void string_builder_strcat(struct string_builder *s, char *str);
-void string_builder_shared_strcat(struct string_builder *s, struct pike_string *str);
-void reset_string_builder(struct string_builder *s);
-void free_string_builder(struct string_builder *s);
-struct pike_string *finish_string_builder(struct string_builder *s);
-PCHARP MEMCHR_PCHARP(PCHARP ptr, int chr, int len);
-long STRTOL_PCHARP(PCHARP str, PCHARP *ptr, int base);
-int string_to_svalue_inumber(struct svalue *r,
+PMOD_EXPORT void string_builder_strcat(struct string_builder *s, char *str);
+PMOD_EXPORT void string_builder_shared_strcat(struct string_builder *s, struct pike_string *str);
+PMOD_EXPORT void reset_string_builder(struct string_builder *s);
+PMOD_EXPORT void free_string_builder(struct string_builder *s);
+PMOD_EXPORT struct pike_string *finish_string_builder(struct string_builder *s);
+PMOD_EXPORT PCHARP MEMCHR_PCHARP(PCHARP ptr, int chr, int len);
+PMOD_EXPORT long STRTOL_PCHARP(PCHARP str, PCHARP *ptr, int base);
+PMOD_EXPORT int string_to_svalue_inumber(struct svalue *r,
 			     char * str,
 			     char **ptr,
 			     int base,
 			     int maxlength);
-int wide_string_to_svalue_inumber(struct svalue *r,
+PMOD_EXPORT int wide_string_to_svalue_inumber(struct svalue *r,
 				  void * str,
 				  void **ptr,
 				  int base,
 				  int maxlength,
 				  int shift);
-int pcharp_to_svalue_inumber(struct svalue *r,
+PMOD_EXPORT int pcharp_to_svalue_inumber(struct svalue *r,
 			     PCHARP str,
 			     PCHARP *ptr,
 			     int base,
 			     int maxlength);
-int convert_stack_top_string_to_inumber(int base);
-double STRTOD_PCHARP(PCHARP nptr, PCHARP *endptr);
-p_wchar0 *require_wstring0(struct pike_string *s,
+PMOD_EXPORT int convert_stack_top_string_to_inumber(int base);
+PMOD_EXPORT double STRTOD_PCHARP(PCHARP nptr, PCHARP *endptr);
+PMOD_EXPORT p_wchar0 *require_wstring0(struct pike_string *s,
 			   char **to_free);
-p_wchar1 *require_wstring1(struct pike_string *s,
+PMOD_EXPORT p_wchar1 *require_wstring1(struct pike_string *s,
 			   char **to_free);
-p_wchar2 *require_wstring2(struct pike_string *s,
+PMOD_EXPORT p_wchar2 *require_wstring2(struct pike_string *s,
 			   char **to_free);
 /* Prototypes end here */
 
diff --git a/src/stuff.c b/src/stuff.c
index d01f3ff64b..f1127707ee 100644
--- a/src/stuff.c
+++ b/src/stuff.c
@@ -5,14 +5,14 @@
 \*/
 
 /*
- * $Id: stuff.c,v 1.10 1999/03/24 16:31:38 grubba Exp $
+ * $Id: stuff.c,v 1.11 2000/07/28 17:16:55 hubbe Exp $
  */
 #include "global.h"
 #include "stuff.h"
 #include "stralloc.h"
 
 /* Not all of these are primes, but they should be adequate */
-INT32 hashprimes[32] =
+PMOD_EXPORT INT32 hashprimes[32] =
 {
   31,        /* ~ 2^0  = 1 */
   31,        /* ~ 2^1  = 2 */
@@ -51,7 +51,7 @@ INT32 hashprimes[32] =
 /* same thing as (int)floor(log((double)x) / log(2.0)) */
 /* Except a bit quicker :) (hopefully) */
 
-int my_log2(unsigned INT32 x)
+PMOD_EXPORT int my_log2(unsigned INT32 x)
 {
   static signed char bit[256] =
   {
@@ -84,7 +84,7 @@ int my_log2(unsigned INT32 x)
 
 
 /* Return the number of bits in a 32-bit integer */
-int count_bits(unsigned INT32 x)
+PMOD_EXPORT int count_bits(unsigned INT32 x)
 {
 #define B(X) X+0,X+1,X+1,X+2,\
              X+1,X+2,X+2,X+3,\
@@ -105,12 +105,12 @@ int count_bits(unsigned INT32 x)
 }
 
 /* Return true for integers with more than one bit set */
-int is_more_than_one_bit(unsigned INT32 x)
+PMOD_EXPORT int is_more_than_one_bit(unsigned INT32 x)
 {
   return !!(x & (x-1));
 }
 
-double my_strtod(char *nptr, char **endptr)
+PMOD_EXPORT double my_strtod(char *nptr, char **endptr)
 {
   double tmp=STRTOD(nptr,endptr);
   if(*endptr>nptr)
diff --git a/src/svalue.c b/src/svalue.c
index 0a401a80c1..443a1730e5 100644
--- a/src/svalue.c
+++ b/src/svalue.c
@@ -24,7 +24,7 @@
 #include "queue.h"
 #include "bignum.h"
 
-RCSID("$Id: svalue.c,v 1.84 2000/07/18 05:48:20 mast Exp $");
+RCSID("$Id: svalue.c,v 1.85 2000/07/28 17:16:55 hubbe Exp $");
 
 struct svalue dest_ob_zero = { T_INT, 0 };
 
@@ -33,7 +33,7 @@ struct svalue dest_ob_zero = { T_INT, 0 };
  * its type.
  */
 
-void really_free_short_svalue(union anything *s, TYPE_T type)
+PMOD_EXPORT void really_free_short_svalue(union anything *s, TYPE_T type)
 {
   union anything tmp=*s;
   s->refs=0; /* Prevent cyclic calls */
@@ -70,7 +70,7 @@ void really_free_short_svalue(union anything *s, TYPE_T type)
   }
 }
 
-void really_free_svalue(struct svalue *s)
+PMOD_EXPORT void really_free_svalue(struct svalue *s)
 {
   int tmp=s->type;
   s->type=T_INT;
@@ -131,7 +131,7 @@ void really_free_svalue(struct svalue *s)
   }
 }
 
-void do_free_svalue(struct svalue *s)
+PMOD_EXPORT void do_free_svalue(struct svalue *s)
 {
   free_svalue(s);
 }
@@ -140,7 +140,7 @@ void do_free_svalue(struct svalue *s)
  * We put this routine here so the compiler can optimize the call
  * inside the loop if it wants to
  */
-void debug_free_svalues(struct svalue *s, size_t num, INT32 type_hint DMALLOC_LINE_ARGS)
+PMOD_EXPORT void debug_free_svalues(struct svalue *s, size_t num, INT32 type_hint DMALLOC_LINE_ARGS)
 {
   switch(type_hint)
   {
@@ -247,7 +247,7 @@ void debug_free_svalues(struct svalue *s, size_t num, INT32 type_hint DMALLOC_LI
   }
 }
 
-void assign_svalues_no_free(struct svalue *to,
+PMOD_EXPORT void assign_svalues_no_free(struct svalue *to,
 			    struct svalue *from,
 			    size_t num,
 			    INT32 type_hint)
@@ -282,7 +282,7 @@ void assign_svalues_no_free(struct svalue *to,
   while(num--) assign_svalue_no_free(to++,from++);
 }
 
-void assign_svalues(struct svalue *to,
+PMOD_EXPORT void assign_svalues(struct svalue *to,
 		    struct svalue *from,
 		    size_t num,
 		    TYPE_FIELD types)
@@ -291,7 +291,7 @@ void assign_svalues(struct svalue *to,
   assign_svalues_no_free(to,from,num,types);
 }
 
-void assign_to_short_svalue(union anything *u,
+PMOD_EXPORT void assign_to_short_svalue(union anything *u,
 			    TYPE_T type,
 			    struct svalue *s)
 {
@@ -320,7 +320,7 @@ void assign_to_short_svalue(union anything *u,
   }
 }
 
-void assign_to_short_svalue_no_free(union anything *u,
+PMOD_EXPORT void assign_to_short_svalue_no_free(union anything *u,
 				    TYPE_T type,
 				    struct svalue *s)
 {
@@ -348,7 +348,7 @@ void assign_to_short_svalue_no_free(union anything *u,
 }
 
 
-void assign_from_short_svalue_no_free(struct svalue *s,
+PMOD_EXPORT void assign_from_short_svalue_no_free(struct svalue *s,
 				      union anything *u,
 				      TYPE_T type)
 {
@@ -374,7 +374,7 @@ void assign_from_short_svalue_no_free(struct svalue *s,
   }
 }
 
-void assign_short_svalue_no_free(union anything *to,
+PMOD_EXPORT void assign_short_svalue_no_free(union anything *to,
 				 union anything *from,
 				 TYPE_T type)
 {
@@ -392,7 +392,7 @@ void assign_short_svalue_no_free(union anything *to,
   }
 }
 
-void assign_short_svalue(union anything *to,
+PMOD_EXPORT void assign_short_svalue(union anything *to,
 			 union anything *from,
 			 TYPE_T type)
 {
@@ -411,7 +411,7 @@ void assign_short_svalue(union anything *to,
   }
 }
 
-unsigned INT32 hash_svalue(struct svalue *s)
+PMOD_EXPORT unsigned INT32 hash_svalue(struct svalue *s)
 {
   unsigned INT32 q;
 
@@ -450,7 +450,7 @@ unsigned INT32 hash_svalue(struct svalue *s)
   return q;
 }
 
-int svalue_is_true(struct svalue *s)
+PMOD_EXPORT int svalue_is_true(struct svalue *s)
 {
   unsigned INT32 q;
   check_type(s->type);
@@ -490,7 +490,7 @@ int svalue_is_true(struct svalue *s)
 
 #define TWO_TYPES(X,Y) (((X)<<8)|(Y))
 
-int is_identical(struct svalue *a, struct svalue *b)
+PMOD_EXPORT int is_identical(struct svalue *a, struct svalue *b)
 {
   if(a->type != b->type) return 0;
   switch(a->type)
@@ -520,7 +520,7 @@ int is_identical(struct svalue *a, struct svalue *b)
 
 }
 
-int is_eq(struct svalue *a, struct svalue *b)
+PMOD_EXPORT int is_eq(struct svalue *a, struct svalue *b)
 {
   check_type(a->type);
   check_type(b->type);
@@ -630,7 +630,7 @@ int is_eq(struct svalue *a, struct svalue *b)
   }
 }
 
-int low_is_equal(struct svalue *a,
+PMOD_EXPORT int low_is_equal(struct svalue *a,
 		 struct svalue *b,
 		 struct processing *p)
 {
@@ -713,7 +713,7 @@ int low_is_equal(struct svalue *a,
   return 1; /* survived */
 }
 
-int low_short_is_equal(const union anything *a,
+PMOD_EXPORT int low_short_is_equal(const union anything *a,
 		       const union anything *b,
 		       TYPE_T type,
 		       struct processing *p)
@@ -749,12 +749,12 @@ int low_short_is_equal(const union anything *a,
   return low_is_equal(&sa,&sb,p);
 }
 
-int is_equal(struct svalue *a,struct svalue *b)
+PMOD_EXPORT int is_equal(struct svalue *a,struct svalue *b)
 {
   return low_is_equal(a,b,0);
 }
 
-int is_lt(struct svalue *a,struct svalue *b)
+PMOD_EXPORT int is_lt(struct svalue *a,struct svalue *b)
 {
   check_type(a->type);
   check_type(b->type);
@@ -883,7 +883,7 @@ int is_lt(struct svalue *a,struct svalue *b)
   }
 }
 
-void describe_svalue(struct svalue *s,int indent,struct processing *p)
+PMOD_EXPORT void describe_svalue(struct svalue *s,int indent,struct processing *p)
 {
   char buf[50];
 
@@ -1103,7 +1103,7 @@ void describe_svalue(struct svalue *s,int indent,struct processing *p)
   }
 }
 
-void print_svalue (FILE *out, struct svalue *s)
+PMOD_EXPORT void print_svalue (FILE *out, struct svalue *s)
 {
   string orig_str;
   string str;
@@ -1117,7 +1117,7 @@ void print_svalue (FILE *out, struct svalue *s)
 }
 
 /* NOTE: Must handle num being negative. */
-void clear_svalues(struct svalue *s, ptrdiff_t num)
+PMOD_EXPORT void clear_svalues(struct svalue *s, ptrdiff_t num)
 {
   struct svalue dum;
   dum.type=T_INT;
@@ -1128,7 +1128,7 @@ void clear_svalues(struct svalue *s, ptrdiff_t num)
 }
 
 /* NOTE: Must handle num being negative. */
-void clear_svalues_undefined(struct svalue *s, ptrdiff_t num)
+PMOD_EXPORT void clear_svalues_undefined(struct svalue *s, ptrdiff_t num)
 {
   struct svalue dum;
   dum.type=T_INT;
@@ -1138,7 +1138,7 @@ void clear_svalues_undefined(struct svalue *s, ptrdiff_t num)
   while(num-- > 0) *(s++)=dum;
 }
 
-void copy_svalues_recursively_no_free(struct svalue *to,
+PMOD_EXPORT void copy_svalues_recursively_no_free(struct svalue *to,
 				      struct svalue *from,
 				      size_t num,
 				      struct processing *p)
@@ -1574,7 +1574,7 @@ int gc_cycle_check_weak_short_svalue(union anything *u, TYPE_T type)
   return freed;
 }
 
-INT32 pike_sizeof(struct svalue *s)
+PMOD_EXPORT INT32 pike_sizeof(struct svalue *s)
 {
   switch(s->type)
   {
diff --git a/src/svalue.h b/src/svalue.h
index fd16834c11..d1e3b61861 100644
--- a/src/svalue.h
+++ b/src/svalue.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: svalue.h,v 1.61 2000/07/04 01:43:34 mast Exp $
+ * $Id: svalue.h,v 1.62 2000/07/28 17:16:55 hubbe Exp $
  */
 #ifndef SVALUE_H
 #define SVALUE_H
@@ -174,6 +174,9 @@ struct svalue
 #define tIfnot(X,Y) tAnd(tNot(X),Y)
 #define tAny tOr(tVoid,tMix)
 
+#define tSimpleCallable tOr3(tArray,tFunction,tObj)
+#define tCallable tOr3(tArr(tSimpleCallable),tFunction,tObj)
+
 #define BIT_ARRAY (1<<PIKE_T_ARRAY)
 #define BIT_MAPPING (1<<PIKE_T_MAPPING)
 #define BIT_MULTISET (1<<PIKE_T_MULTISET)
@@ -326,51 +329,51 @@ extern struct svalue dest_ob_zero;
 #endif
 
 /* Prototypes begin here */
-void really_free_short_svalue(union anything *s, TYPE_T type);
-void really_free_svalue(struct svalue *s);
-void do_free_svalue(struct svalue *s);
-void debug_free_svalues(struct svalue *s, size_t num, INT32 type_hint DMALLOC_LINE_ARGS);
-void assign_svalues_no_free(struct svalue *to,
+PMOD_EXPORT void really_free_short_svalue(union anything *s, TYPE_T type);
+PMOD_EXPORT void really_free_svalue(struct svalue *s);
+PMOD_EXPORT void do_free_svalue(struct svalue *s);
+PMOD_EXPORT void debug_free_svalues(struct svalue *s, size_t num, INT32 type_hint DMALLOC_LINE_ARGS);
+PMOD_EXPORT void assign_svalues_no_free(struct svalue *to,
 			    struct svalue *from,
 			    size_t num,
 			    INT32 type_hint);
-void assign_svalues(struct svalue *to,
+PMOD_EXPORT void assign_svalues(struct svalue *to,
 		    struct svalue *from,
 		    size_t num,
 		    TYPE_FIELD types);
-void assign_to_short_svalue(union anything *u,
+PMOD_EXPORT void assign_to_short_svalue(union anything *u,
 			    TYPE_T type,
 			    struct svalue *s);
-void assign_to_short_svalue_no_free(union anything *u,
+PMOD_EXPORT void assign_to_short_svalue_no_free(union anything *u,
 				    TYPE_T type,
 				    struct svalue *s);
-void assign_from_short_svalue_no_free(struct svalue *s,
+PMOD_EXPORT void assign_from_short_svalue_no_free(struct svalue *s,
 				      union anything *u,
 				      TYPE_T type);
-void assign_short_svalue_no_free(union anything *to,
+PMOD_EXPORT void assign_short_svalue_no_free(union anything *to,
 				 union anything *from,
 				 TYPE_T type);
-void assign_short_svalue(union anything *to,
+PMOD_EXPORT void assign_short_svalue(union anything *to,
 			 union anything *from,
 			 TYPE_T type);
-unsigned INT32 hash_svalue(struct svalue *s);
-int svalue_is_true(struct svalue *s);
-int is_identical(struct svalue *a, struct svalue *b);
-int is_eq(struct svalue *a, struct svalue *b);
-int low_is_equal(struct svalue *a,
+PMOD_EXPORT unsigned INT32 hash_svalue(struct svalue *s);
+PMOD_EXPORT int svalue_is_true(struct svalue *s);
+PMOD_EXPORT int is_identical(struct svalue *a, struct svalue *b);
+PMOD_EXPORT int is_eq(struct svalue *a, struct svalue *b);
+PMOD_EXPORT int low_is_equal(struct svalue *a,
 		 struct svalue *b,
 		 struct processing *p);
-int low_short_is_equal(const union anything *a,
+PMOD_EXPORT int low_short_is_equal(const union anything *a,
 		       const union anything *b,
 		       TYPE_T type,
 		       struct processing *p);
-int is_equal(struct svalue *a,struct svalue *b);
-int is_lt(struct svalue *a,struct svalue *b);
-void describe_svalue(struct svalue *s,int indent,struct processing *p);
-void print_svalue (FILE *out, struct svalue *s);
-void clear_svalues(struct svalue *s, ptrdiff_t num);
-void clear_svalues_undefined(struct svalue *s, ptrdiff_t num);
-void copy_svalues_recursively_no_free(struct svalue *to,
+PMOD_EXPORT int is_equal(struct svalue *a,struct svalue *b);
+PMOD_EXPORT int is_lt(struct svalue *a,struct svalue *b);
+PMOD_EXPORT void describe_svalue(struct svalue *s,int indent,struct processing *p);
+PMOD_EXPORT void print_svalue (FILE *out, struct svalue *s);
+PMOD_EXPORT void clear_svalues(struct svalue *s, ptrdiff_t num);
+PMOD_EXPORT void clear_svalues_undefined(struct svalue *s, ptrdiff_t num);
+PMOD_EXPORT void copy_svalues_recursively_no_free(struct svalue *to,
 				      struct svalue *from,
 				      size_t num,
 				      struct processing *p);
@@ -378,18 +381,18 @@ void check_short_svalue(union anything *u, TYPE_T type);
 void debug_check_svalue(struct svalue *s);
 void real_gc_xmark_svalues(struct svalue *s, ptrdiff_t num);
 void real_gc_check_svalues(struct svalue *s, size_t num);
-void real_gc_check_short_svalue(union anything *u, TYPE_T type);
 void gc_check_weak_svalues(struct svalue *s, size_t num);
+void real_gc_check_short_svalue(union anything *u, TYPE_T type);
 void gc_check_weak_short_svalue(union anything *u, TYPE_T type);
 TYPE_FIELD real_gc_mark_svalues(struct svalue *s, size_t num);
-int real_gc_mark_short_svalue(union anything *u, TYPE_T type);
 TYPE_FIELD gc_mark_weak_svalues(struct svalue *s, size_t num);
+int real_gc_mark_short_svalue(union anything *u, TYPE_T type);
 int gc_mark_weak_short_svalue(union anything *u, TYPE_T type);
 TYPE_FIELD real_gc_cycle_check_svalues(struct svalue *s, size_t num);
-int real_gc_cycle_check_short_svalue(union anything *u, TYPE_T type);
 TYPE_FIELD gc_cycle_check_weak_svalues(struct svalue *s, size_t num);
+int real_gc_cycle_check_short_svalue(union anything *u, TYPE_T type);
 int gc_cycle_check_weak_short_svalue(union anything *u, TYPE_T type);
-INT32 pike_sizeof(struct svalue *s);
+PMOD_EXPORT INT32 pike_sizeof(struct svalue *s);
 /* Prototypes end here */
 
 #define gc_xmark_svalues(S,N) real_gc_xmark_svalues(dmalloc_check_svalue(S,DMALLOC_LOCATION()),N)
diff --git a/src/testsuite.in b/src/testsuite.in
index 4e92687ee2..ff1f0cda9b 100644
--- a/src/testsuite.in
+++ b/src/testsuite.in
@@ -1,4 +1,4 @@
-test_true([["$Id: testsuite.in,v 1.315 2000/07/19 13:10:20 lange Exp $"]]);
+test_true([["$Id: testsuite.in,v 1.316 2000/07/28 17:16:55 hubbe Exp $"]]);
 
 cond([[all_constants()->_verify_internals]],
 [[
@@ -5286,6 +5286,8 @@ test_true(Process.spawn)
 test_true(Process.system)
 test_true(Process.create_process)
 test_equal([[Process.split_quoted_string("test ")]],[[({"test"})]])
+test_equal([[Process.split_quoted_string("'test'")]],[[({"test"})]])
+test_equal([[Process.split_quoted_string("foo 'test' bar")]],[[({"foo","test","bar"})]])
 test_false([[Process.system(RUNPIKE +" -e 'exit(0)'")]])
 test_true([[Process.system(RUNPIKE+" -e 'exit(1)'")]])
 test_any([[object p=Process.create_process(Process.split_quoted_string(RUNPIKE)+({"-e","exit(2)"})); sleep(10); return p->wait()]],2)
diff --git a/src/threads.c b/src/threads.c
index b77b20d828..a1c67b1b52 100644
--- a/src/threads.c
+++ b/src/threads.c
@@ -1,8 +1,8 @@
 #include "global.h"
-RCSID("$Id: threads.c,v 1.132 2000/07/07 01:24:14 hubbe Exp $");
+RCSID("$Id: threads.c,v 1.133 2000/07/28 17:16:55 hubbe Exp $");
 
-int num_threads = 1;
-int threads_disabled = 0;
+PMOD_EXPORT int num_threads = 1;
+PMOD_EXPORT int threads_disabled = 0;
 
 #ifdef _REENTRANT
 #include "threads.h"
@@ -23,10 +23,10 @@ int threads_disabled = 0;
 
 #include <errno.h>
 
-int live_threads = 0;
-COND_T live_threads_change;
-COND_T threads_disabled_change;
-size_t thread_stack_size=1024 * 1204;
+PMOD_EXPORT int live_threads = 0;
+PMOD_EXPORT COND_T live_threads_change;
+PMOD_EXPORT COND_T threads_disabled_change;
+PMOD_EXPORT size_t thread_stack_size=1024 * 1204;
 
 #ifndef HAVE_PTHREAD_ATFORK
 #include "callback.h"
@@ -103,7 +103,7 @@ static int IsValidHandle(HANDLE h)
   return 1;
 }
 
-HANDLE CheckValidHandle(HANDLE h)
+PMOD_EXPORT HANDLE CheckValidHandle(HANDLE h)
 {
   if(!IsValidHandle(h))
     fatal("Invalid handle!\n");
@@ -115,7 +115,7 @@ HANDLE CheckValidHandle(HANDLE h)
 #endif
 
 #ifdef SIMULATE_COND_WITH_EVENT
-int co_wait(COND_T *c, MUTEX_T *m)
+PMOD_EXPORT int co_wait(COND_T *c, MUTEX_T *m)
 {
   struct cond_t_queue me;
   event_init(&me.event);
@@ -146,7 +146,7 @@ int co_wait(COND_T *c, MUTEX_T *m)
   return 0;
 }
 
-int co_signal(COND_T *c)
+PMOD_EXPORT int co_signal(COND_T *c)
 {
   struct cond_t_queue *t;
   mt_lock(& c->lock);
@@ -162,7 +162,7 @@ int co_signal(COND_T *c)
   return 0;
 }
 
-int co_broadcast(COND_T *c)
+PMOD_EXPORT int co_broadcast(COND_T *c)
 {
   struct cond_t_queue *t,*n;
   mt_lock(& c->lock);
@@ -180,7 +180,7 @@ int co_broadcast(COND_T *c)
   return 0;
 }
 
-int co_destroy(COND_T *c)
+PMOD_EXPORT int co_destroy(COND_T *c)
 {
   struct cond_t_queue *t;
   mt_lock(& c->lock);
@@ -204,7 +204,8 @@ int th_running = 0;
 int debug_interpreter_is_locked = 0;
 THREAD_T debug_locking_thread;
 #endif
-MUTEX_T interpreter_lock, thread_table_lock, interleave_lock;
+PMOD_EXPORT MUTEX_T interpreter_lock;
+MUTEX_T thread_table_lock, interleave_lock;
 struct program *mutex_key = 0;
 struct program *thread_id_prog = 0;
 struct program *thread_local_prog = 0;
@@ -212,7 +213,7 @@ struct program *thread_local_prog = 0;
 pthread_attr_t pattr;
 pthread_attr_t small_pattr;
 #endif
-int thread_storage_offset;
+PMOD_EXPORT int thread_storage_offset;
 
 struct thread_starter
 {
@@ -449,7 +450,7 @@ void thread_table_delete(struct object *o)
   mt_unlock( & thread_table_lock );
 }
 
-struct thread_state *thread_state_for_id(THREAD_T tid)
+PMOD_EXPORT struct thread_state *thread_state_for_id(THREAD_T tid)
 {
   unsigned INT32 h = thread_table_hash(&tid);
   struct thread_state *s = NULL;
@@ -500,7 +501,7 @@ struct thread_state *thread_state_for_id(THREAD_T tid)
      as you have the interpreter lock, unless tid == th_self() */
 }
 
-struct object *thread_for_id(THREAD_T tid)
+PMOD_EXPORT struct object *thread_for_id(THREAD_T tid)
 {
   struct thread_state *s = thread_state_for_id(tid);
   return (s == NULL? NULL : THREADSTATE2OBJ(s));
@@ -509,7 +510,7 @@ struct object *thread_for_id(THREAD_T tid)
 }
 
 
-void f_all_threads(INT32 args)
+PMOD_EXPORT void f_all_threads(INT32 args)
 {
   /* Return an unordered array containing all threads that was running
      at the time this function was invoked */
@@ -531,7 +532,7 @@ void f_all_threads(INT32 args)
 }
 
 
-int count_pike_threads(void)
+PMOD_EXPORT int count_pike_threads(void)
 {
   return num_pike_threads;
 }
@@ -1479,7 +1480,7 @@ static struct farmer *new_farmer(void (*fun)(void *), void *args)
   return me;
 }
 
-void th_farm(void (*fun)(void *), void *here)
+PMOD_EXPORT void th_farm(void (*fun)(void *), void *here)
 {
   if(!fun) fatal("The farmers don't known how to handle empty fields\n");
   mt_lock( &rosie );
diff --git a/src/threads.h b/src/threads.h
index b43a0bbfd5..5d73dd276a 100644
--- a/src/threads.h
+++ b/src/threads.h
@@ -1,5 +1,5 @@
 /*
- * $Id: threads.h,v 1.98 2000/07/12 05:57:39 neotron Exp $
+ * $Id: threads.h,v 1.99 2000/07/28 17:16:56 hubbe Exp $
  */
 #ifndef THREADS_H
 #define THREADS_H
@@ -396,8 +396,9 @@ struct thread_state {
 #endif /* VERBOSE_THREADS_DEBUG */
 
 #ifdef THREAD_TRACE
-#define SWAP_OUT_TRACE(_tmp)	do { extern int t_flag; (_tmp)->status.t_flag = t_flag; } while(0)
-#define SWAP_IN_TRACE(_tmp)	do { extern int t_flag; t_flag = (_tmp)->status.t_flag; } while(0)
+extern int t_flag;
+#define SWAP_OUT_TRACE(_tmp)	do { (_tmp)->status.t_flag = t_flag; } while(0)
+#define SWAP_IN_TRACE(_tmp)	do { t_flag = (_tmp)->status.t_flag; } while(0)
 #else /* !THREAD_TRACE */
 #define SWAP_OUT_TRACE(_tmp)
 #define SWAP_IN_TRACE(_tmp)
@@ -459,10 +460,10 @@ struct thread_state {
 
 #define THREADSTATE2OBJ(X) ((X)->state.thread_id)
 
+extern int Pike_in_gc;
 #define THREADS_ALLOW() do { \
      struct thread_state *_tmp=OBJ2THREAD(Pike_interpreter.thread_id); \
      DO_IF_DEBUG({ \
-       extern int Pike_in_gc; \
        if(thread_for_id(th_self()) != Pike_interpreter.thread_id) \
 	 fatal("thread_for_id() (or Pike_interpreter.thread_id) failed!" \
                " %p != %p\n", \
@@ -500,7 +501,6 @@ struct thread_state {
 #define THREADS_ALLOW_UID() do { \
      struct thread_state *_tmp_uid=OBJ2THREAD(Pike_interpreter.thread_id); \
      DO_IF_DEBUG({ \
-       extern int Pike_in_gc; \
        if(thread_for_id(th_self()) != Pike_interpreter.thread_id) \
 	 fatal("thread_for_id() (or Pike_interpreter.thread_id) failed! %p != %p\n",thread_for_id(th_self()),Pike_interpreter.thread_id); \
        if (Pike_in_gc > 50 && Pike_in_gc < 300) \
-- 
GitLab