summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Polstra <jdp@FreeBSD.org>1996-10-29 23:01:55 +0000
committerJohn Polstra <jdp@FreeBSD.org>1996-10-29 23:01:55 +0000
commitd5a92ea9241e6b6b531220df28c2fc1b569388f3 (patch)
treed4e99980d84282a78dcd8c40088cda1fe63a11f8
parentUpgrade to v1.0prerelease-1 (diff)
Split the Modula-3 port into two pieces, creating a new port
"modula-3-lib". It installs only the shared libraries needed for executing Modula-3 programs. This saves a lot of disk space for people who need to run Modula-3 programs but don't need to build them. The original "modula-3" port now depends on this one, and uses it to install the compiler and the rest of the development system. Also, everything is now built with optimization. I have been testing this for at least a month, and haven't seen any problems from it. It makes the libraries and executables substantially smaller. This new port also includes some hooks that will make SOCKS support possible in the near future.
Notes
Notes: svn path=/head/; revision=4188
-rw-r--r--lang/modula-3-lib/Makefile137
-rw-r--r--lang/modula-3-lib/distinfo4
-rw-r--r--lang/modula-3-lib/files/README.distfiles52
-rw-r--r--lang/modula-3-lib/files/T.boot1
-rw-r--r--lang/modula-3-lib/files/T.gcc115
-rw-r--r--lang/modula-3-lib/files/T.m3cc13
-rw-r--r--lang/modula-3-lib/files/T.src42
-rw-r--r--lang/modula-3-lib/files/X.boot3
-rw-r--r--lang/modula-3-lib/files/X.gcc3
-rw-r--r--lang/modula-3-lib/files/X.m3cc3
-rw-r--r--lang/modula-3-lib/files/X.src51
-rw-r--r--lang/modula-3-lib/files/patch-aa18
-rw-r--r--lang/modula-3-lib/files/patch-ab285
-rw-r--r--lang/modula-3-lib/files/patch-ae18
-rw-r--r--lang/modula-3-lib/files/patch-ah210
-rw-r--r--lang/modula-3-lib/files/patch-ai19
-rw-r--r--lang/modula-3-lib/files/patch-aj17
-rw-r--r--lang/modula-3-lib/files/patch-ak515
-rw-r--r--lang/modula-3-lib/files/patch-am97
-rw-r--r--lang/modula-3-lib/files/patch-aq222
-rw-r--r--lang/modula-3-lib/files/patch-ar50
-rw-r--r--lang/modula-3-lib/files/patch-at70
-rw-r--r--lang/modula-3-lib/files/patch-av418
-rw-r--r--lang/modula-3-lib/files/patch-aw44
-rw-r--r--lang/modula-3-lib/files/patch-ax66
-rw-r--r--lang/modula-3-lib/files/patch-ay17
-rw-r--r--lang/modula-3-lib/files/patch-bf32
-rw-r--r--lang/modula-3-lib/files/patch-bg1334
-rw-r--r--lang/modula-3-lib/files/patch-bi39
-rw-r--r--lang/modula-3-lib/files/patch-bj460
-rw-r--r--lang/modula-3-lib/files/patch-bk34
-rw-r--r--lang/modula-3-lib/files/patch-bl25
-rw-r--r--lang/modula-3-lib/files/patch-bm18
-rw-r--r--lang/modula-3-lib/pkg-comment1
-rw-r--r--lang/modula-3-lib/pkg-descr6
-rw-r--r--lang/modula-3-lib/pkg-install74
-rw-r--r--lang/modula-3-lib/pkg-plist42
-rw-r--r--lang/modula-3-lib/scripts/check_files29
-rw-r--r--lang/modula-3-lib/scripts/configure15
-rw-r--r--lang/modula-3-lib/scripts/copy_files16
40 files changed, 4615 insertions, 0 deletions
diff --git a/lang/modula-3-lib/Makefile b/lang/modula-3-lib/Makefile
new file mode 100644
index 000000000000..1054f5826b3b
--- /dev/null
+++ b/lang/modula-3-lib/Makefile
@@ -0,0 +1,137 @@
+# New ports collection makefile for: modula-3-lib
+# Version required: 3.6
+# Date created: 28 Oct 1996
+# Whom: John Polstra <jdp@polstra.com>
+#
+# $Id$
+#
+
+DISTNAME= modula-3-lib-3.6
+CATEGORIES+= lang
+MASTER_SITES= ftp://freefall.FreeBSD.ORG/pub/FreeBSD/LOCAL_PORTS/
+DISTFILES= m3-fbsd-src-3.6.tar.gz m3-fbsd-m3cc-3.6.tar.gz
+# Note: Depending on what is already installed on the system, the code
+# below may add some more DISTFILES.
+
+MAINTAINER= jdp@polstra.com
+
+NO_WRKSUBDIR= yes
+
+# There are two distfiles that may or may not be needed, depending on
+# what is already installed on the system. First, we need an executable
+# for the Modula-3 compiler, in order to compile the new compiler, which
+# is written in Modula-3. Often, there will already be such an executable
+# installed on the system. Second, we need many files from gcc-2.7.2.1.
+# Often, we can find these in the system sources, under "/usr/src/contrib".
+#
+# This code tries to avoid fetching the distfiles, unless necessary.
+# We look on the system to see whether the necessary files are present,
+# and use those if we can. If we cannot find the needed files, we
+# fetch the distfiles.
+
+# For the Modula-3 compiler, we look in ${PREFIX} and in /usr/local.
+.ifdef PREFIX
+have_boot!= /bin/sh scripts/check_files files/T.boot installed ${PREFIX}
+.else
+have_boot=
+.endif
+.if empty(have_boot)
+have_boot!= /bin/sh scripts/check_files files/T.boot installed /usr/local
+.endif
+.if empty(have_boot)
+DISTFILES+= m3-fbsd-boot-3.6.tar.gz
+.endif
+
+# For gcc-2.7.2.1, we look in /usr/src/contrib.
+have_gcc!= /bin/sh scripts/check_files files/T.gcc m3cc /usr/src/contrib
+.if empty(have_gcc)
+DISTFILES+= m3-fbsd-gcc-3.6.tar.gz
+.endif
+
+# Startup script, run at boot time
+startup_dir= ${PREFIX}/etc/rc.d
+startup_script= ${startup_dir}/m3.sh
+
+# The Modula-3 build process insists on installing each individual
+# component immediately after that component is built. To avoid having
+# to do the entire build as root, we arrange for everything to first
+# be "installed" into the following directory, which we own.
+temp_prefix= ${WRKSRC}/installed
+
+post-extract:
+.if !empty(have_boot)
+ @echo "Copying bootstrap modula-3 compiler from ${have_boot}"
+ @/bin/sh ${SCRIPTDIR}/copy_files ${FILESDIR}/T.boot installed \
+ ${have_boot} ${WRKSRC}
+.endif
+.if !empty(have_gcc)
+ @echo "Copying gcc sources from ${have_gcc}"
+ @/bin/sh ${SCRIPTDIR}/copy_files ${FILESDIR}/T.gcc m3cc \
+ ${have_gcc} ${WRKSRC}
+.endif
+ @cd ${WRKSRC}/m3cc/gcc; \
+ chmod +x config.sub configure move-if-change
+
+do-build:
+ @test -d ${temp_prefix}/bin || mkdir -p ${temp_prefix}/bin
+ @test -d ${temp_prefix}/man/man1 || mkdir -p ${temp_prefix}/man/man1
+ @test -d ${temp_prefix}/lib/m3/pkg/m3build/templates || \
+ mkdir -p ${temp_prefix}/lib/m3/pkg/m3build/templates
+ @echo "++++++++++ quake ++++++++++"
+ @test -d ${WRKSRC}/m3/quake/FreeBSD2 || \
+ mkdir -p ${WRKSRC}/m3/quake/FreeBSD2
+ @cd ${WRKSRC}/m3/quake/FreeBSD2; \
+ make -f ../src/makefile TARGET=FreeBSD2 COPT=-O CDEBUG= ; \
+ cp -p quake ${temp_prefix}/bin; \
+ cp -p ../src/quake.1 ${temp_prefix}/man/man1
+ @echo "++++++++++ m3build ++++++++++"
+ @cd ${WRKSRC}/m3/m3build; \
+ PATH=${temp_prefix}/bin:$$PATH ./build FreeBSD2; \
+ cp -p FreeBSD2/m3build FreeBSD2/m3ship FreeBSD2/m3where \
+ ${temp_prefix}/bin; \
+ cp -p FreeBSD2/m3mkdir ${temp_prefix}/lib/m3/FreeBSD2; \
+ cp -p templates/CLEANUP templates/COMMON templates/COMMON.BOOT \
+ templates/FreeBSD2 templates/PLATFORMS templates/POSIX \
+ ${temp_prefix}/lib/m3/pkg/m3build/templates; \
+ cp -p FreeBSD2/m3build.1 FreeBSD2/m3ship.1 FreeBSD2/m3where.1 \
+ ${temp_prefix}/man/man1
+ @echo "++++++++++ m3cc ++++++++++"
+ @test -d ${WRKSRC}/m3cc/FreeBSD2 || mkdir -p ${WRKSRC}/m3cc/FreeBSD2
+ @cd ${WRKSRC}/m3cc/FreeBSD2; \
+ ../gcc/configure i486-unknown-freebsd; \
+ make m3cgc1 CC=cc CFLAGS=-O; \
+ cp -p m3cgc1 ${temp_prefix}/lib/m3/FreeBSD2
+ @echo "++++++++++ everything else ++++++++++"
+ @cd ${WRKSRC}/m3; \
+ LD_LIBRARY_PATH=${temp_prefix}/lib/m3/FreeBSD2:$$LD_LIBRARY_PATH; \
+ PATH=${temp_prefix}/bin:$$PATH; \
+ export LD_LIBRARY_PATH PATH; \
+ m3build
+
+pre-install:
+ @echo "Checking for conflicting shared libraries"
+ @PREFIX=${PREFIX} /bin/sh ${PKGDIR}/INSTALL ${PKGNAME} PRE-INSTALL
+
+do-install:
+ @echo "Installing shared libraries"
+ @cd ${temp_prefix}; \
+ umask 022; \
+ grep '^lib/m3/' ${PKGDIR}/PLIST | \
+ cpio -dump -R ${BINOWN}.${BINGRP} ${PREFIX}
+ @cd ${PREFIX}; \
+ grep '^lib/m3/' ${PKGDIR}/PLIST | xargs chmod go=u-w; \
+ find -X lib/m3 -type d | xargs chown ${BINOWN}.${BINGRP}; \
+ find -X lib/m3 -type d | xargs chmod 755
+ @if [ ! -f ${startup_script} ]; then \
+ echo "Installing ${startup_script} file"; \
+ test -d ${startup_dir} || mkdir -p ${startup_dir}; \
+ echo "#!/bin/sh" > ${startup_script}; \
+ echo "echo -n ' Modula-3'" >> ${startup_script}; \
+ echo "/sbin/ldconfig -m ${PREFIX}/lib/m3/FreeBSD2" \
+ >> ${startup_script}; \
+ chmod 755 ${startup_script}; \
+ fi
+ @echo "Running ldconfig"
+ @/sbin/ldconfig -m ${PREFIX}/lib/m3/FreeBSD2
+
+.include <bsd.port.mk>
diff --git a/lang/modula-3-lib/distinfo b/lang/modula-3-lib/distinfo
new file mode 100644
index 000000000000..9655118b1ed7
--- /dev/null
+++ b/lang/modula-3-lib/distinfo
@@ -0,0 +1,4 @@
+MD5 (m3-fbsd-boot-3.6.tar.gz) = e65eb3d2466957d64989c6aeac1c7264
+MD5 (m3-fbsd-gcc-3.6.tar.gz) = d65a3316d4e3e5d7e901bbd3ef2b53a0
+MD5 (m3-fbsd-m3cc-3.6.tar.gz) = 2b65a26c1199b2871299dba4c4bfac71
+MD5 (m3-fbsd-src-3.6.tar.gz) = 7e8e83ee8444b6d045566a7a90f33ffa
diff --git a/lang/modula-3-lib/files/README.distfiles b/lang/modula-3-lib/files/README.distfiles
new file mode 100644
index 000000000000..9f1c2180e6ab
--- /dev/null
+++ b/lang/modula-3-lib/files/README.distfiles
@@ -0,0 +1,52 @@
+This port uses distfiles that I prepared specially for FreeBSD. The DEC
+SRC release of Modula-3 comes in the form of 3 compressed tar files
+totaling about 16 MB. A small fraction of that is actually needed.
+
+The FreeBSD distfiles are as follows.
+
+ m3-fbsd-src-3.6.tar.gz (required)
+
+ Sources for selected portions of the SRC release. These
+ files are unmodified; however, only a subset is included.
+ Files relating to platforms other than FreeBSD have been
+ omitted. Also, several large but rarely-used packages have
+ been left out.
+
+ m3-fbsd-m3cc-3.6.tar.gz (required)
+
+ Sources for the Modula-3 specific files making up the code
+ generator. As released by SRC, the code generator is a
+ slightly modified version of gcc-2.6.3. I have updated
+ the modifications to work with the newer gcc-2.7.2.1. Only
+ the files which differ from those in the FreeBSD gcc-2.7.2.1
+ sources are included in this distfile.
+
+ m3-fbsd-gcc-3.6.tar.gz (optional)
+
+ Sources for the needed portions of gcc-2.7.2.1 which are
+ identical to those included in the FreeBSD system sources.
+ Many systems have these files online in "/usr/src/contrib/gcc".
+ The Makefile looks for them there first, and uses the online
+ files if they are present. Only if the necessary files
+ are missing is this distfile fetched and used.
+
+ m3-fbsd-boot-3.6.tar.gz (optional)
+
+ A statically-linked FreeBSD executable for the Modula-3
+ compiler. A working compiler is needed, because the compiler
+ is itself written in Modula-3. The Makefile looks for this
+ executable on the system; it may already be present from
+ an earlier version of the port. If found, the version
+ already on the system is used. Otherwise, this distfile
+ is fetched and used.
+
+Also in the current directory are files named "T.*" and "X.*". These
+contain lists of files and wildcards specifying the files to be included
+and excluded from each distfile. For example, "m3-fbsd-src-3.6.tar.gz"
+can be reconstructed using the following commands:
+
+ make extract
+ cd work
+ tar -czvf m3-fbsd-src-3.6.tar.gz -T ../files/T.src -X ../files/X.src
+
+John Polstra <jdp@polstra.com>
diff --git a/lang/modula-3-lib/files/T.boot b/lang/modula-3-lib/files/T.boot
new file mode 100644
index 000000000000..2847aed272f2
--- /dev/null
+++ b/lang/modula-3-lib/files/T.boot
@@ -0,0 +1 @@
+installed/lib/m3/FreeBSD2/m3
diff --git a/lang/modula-3-lib/files/T.gcc b/lang/modula-3-lib/files/T.gcc
new file mode 100644
index 000000000000..d9334028e5d3
--- /dev/null
+++ b/lang/modula-3-lib/files/T.gcc
@@ -0,0 +1,115 @@
+m3cc/gcc/COPYING
+m3cc/gcc/basic-block.h
+m3cc/gcc/bc-emit.c
+m3cc/gcc/bc-emit.h
+m3cc/gcc/bc-optab.c
+m3cc/gcc/bc-optab.h
+m3cc/gcc/bc-typecd.def
+m3cc/gcc/bc-typecd.h
+m3cc/gcc/bi-arity.c
+m3cc/gcc/bi-defs.h
+m3cc/gcc/bi-lexer.c
+m3cc/gcc/bi-opcode.c
+m3cc/gcc/bi-opname.c
+m3cc/gcc/bi-parser.y
+m3cc/gcc/bi-reverse.c
+m3cc/gcc/bi-run.h
+m3cc/gcc/bytecode.def
+m3cc/gcc/bytecode.h
+m3cc/gcc/bytetypes.h
+m3cc/gcc/c-convert.c
+m3cc/gcc/c-pragma.h
+m3cc/gcc/caller-save.c
+m3cc/gcc/conditions.h
+m3cc/gcc/config.sub
+m3cc/gcc/config/i386/bsd.h
+m3cc/gcc/config/i386/gas.h
+m3cc/gcc/config/i386/gstabs.h
+m3cc/gcc/config/i386/i386.c
+m3cc/gcc/config/i386/i386.h
+m3cc/gcc/config/i386/i386.md
+m3cc/gcc/config/i386/perform.h
+m3cc/gcc/config/i386/unix.h
+m3cc/gcc/config/i386/x-freebsd
+m3cc/gcc/config/i386/xm-freebsd.h
+m3cc/gcc/config/i386/xm-i386.h
+m3cc/gcc/config/xm-freebsd.h
+m3cc/gcc/configure
+m3cc/gcc/convert.c
+m3cc/gcc/convert.h
+m3cc/gcc/cp/Make-lang.in
+m3cc/gcc/cp/Makefile.in
+m3cc/gcc/cp/config-lang.in
+m3cc/gcc/cse.c
+m3cc/gcc/dbxout.c
+m3cc/gcc/defaults.h
+m3cc/gcc/dwarf.h
+m3cc/gcc/dwarfout.c
+m3cc/gcc/emit-rtl.c
+m3cc/gcc/explow.c
+m3cc/gcc/expmed.c
+m3cc/gcc/final.c
+m3cc/gcc/flags.h
+m3cc/gcc/flow.c
+m3cc/gcc/fold-const.c
+m3cc/gcc/function.h
+m3cc/gcc/genattr.c
+m3cc/gcc/genattrtab.c
+m3cc/gcc/gencodes.c
+m3cc/gcc/genconfig.c
+m3cc/gcc/genemit.c
+m3cc/gcc/genextract.c
+m3cc/gcc/genflags.c
+m3cc/gcc/genopinit.c
+m3cc/gcc/genoutput.c
+m3cc/gcc/genpeep.c
+m3cc/gcc/genrecog.c
+m3cc/gcc/getpwd.c
+m3cc/gcc/global.c
+m3cc/gcc/gstab.h
+m3cc/gcc/gsyms.h
+m3cc/gcc/hard-reg-set.h
+m3cc/gcc/input.h
+m3cc/gcc/integrate.c
+m3cc/gcc/integrate.h
+m3cc/gcc/jump.c
+m3cc/gcc/local-alloc.c
+m3cc/gcc/loop.c
+m3cc/gcc/loop.h
+m3cc/gcc/machmode.def
+m3cc/gcc/machmode.h
+m3cc/gcc/modemap.def
+m3cc/gcc/move-if-change
+m3cc/gcc/obstack.c
+m3cc/gcc/obstack.h
+m3cc/gcc/optabs.c
+m3cc/gcc/output.h
+m3cc/gcc/print-rtl.c
+m3cc/gcc/real.c
+m3cc/gcc/print-tree.c
+m3cc/gcc/real.h
+m3cc/gcc/recog.c
+m3cc/gcc/recog.h
+m3cc/gcc/reg-stack.c
+m3cc/gcc/regclass.c
+m3cc/gcc/regs.h
+m3cc/gcc/reload.c
+m3cc/gcc/reload.h
+m3cc/gcc/reload1.c
+m3cc/gcc/reorg.c
+m3cc/gcc/rtl.c
+m3cc/gcc/rtl.def
+m3cc/gcc/rtl.h
+m3cc/gcc/rtlanal.c
+m3cc/gcc/sched.c
+m3cc/gcc/stmt.c
+m3cc/gcc/stor-layout.c
+m3cc/gcc/stupid.c
+m3cc/gcc/toplev.c
+m3cc/gcc/tree.c
+m3cc/gcc/typeclass.h
+m3cc/gcc/unroll.c
+m3cc/gcc/varasm.c
+m3cc/gcc/version.c
+m3cc/gcc/xcoffout.c
+m3cc/gcc/xcoffout.h
diff --git a/lang/modula-3-lib/files/T.m3cc b/lang/modula-3-lib/files/T.m3cc
new file mode 100644
index 000000000000..c8163b72b239
--- /dev/null
+++ b/lang/modula-3-lib/files/T.m3cc
@@ -0,0 +1,13 @@
+m3cc/gcc/COPYING
+m3cc/gcc/Makefile.in
+m3cc/gcc/calls.c
+m3cc/gcc/combine.c
+m3cc/gcc/config/i386/freebsd.h
+m3cc/gcc/expr.c
+m3cc/gcc/expr.h
+m3cc/gcc/function.c
+m3cc/gcc/m3.c
+m3cc/gcc/m3.def
+m3cc/gcc/sdbout.c
+m3cc/gcc/tree.def
+m3cc/gcc/tree.h
diff --git a/lang/modula-3-lib/files/T.src b/lang/modula-3-lib/files/T.src
new file mode 100644
index 000000000000..4644cf4dfb66
--- /dev/null
+++ b/lang/modula-3-lib/files/T.src
@@ -0,0 +1,42 @@
+m3/X11R4/src
+m3/coverage/src
+m3/digraph/src
+m3/formsedit/src
+m3/formsvbt/src
+m3/formsvbtpixmaps/src
+m3/images/src
+m3/jvideo/src
+m3/libm3/src
+m3/m3/src
+m3/m3browser/src
+m3/m3build/build
+m3/m3build/src
+m3/m3build/templates
+m3/m3bundle/src
+m3/m3core/src
+m3/m3front/src
+m3/m3linker/src
+m3/m3middle/src
+m3/m3tohtml/src
+m3/m3tools/src
+m3/m3totex/src
+m3/mtex/src
+m3/parseparams/src
+m3/pp/src
+m3/quake/src
+m3/realgeometry/src
+m3/recordheap/src
+m3/replayheap/src
+m3/set/src
+m3/showheap/src
+m3/shownew/src
+m3/showthread/src
+m3/src
+m3/table-list/src
+m3/tcp/src
+m3/tcpextras/src
+m3/tempfiles/src
+m3/ui/src
+m3/vbtkit/src
+m3/videovbt/src
+m3/web/src
diff --git a/lang/modula-3-lib/files/X.boot b/lang/modula-3-lib/files/X.boot
new file mode 100644
index 000000000000..235cd8b5fc4b
--- /dev/null
+++ b/lang/modula-3-lib/files/X.boot
@@ -0,0 +1,3 @@
+*.bak
+*.orig
+*[-~]
diff --git a/lang/modula-3-lib/files/X.gcc b/lang/modula-3-lib/files/X.gcc
new file mode 100644
index 000000000000..235cd8b5fc4b
--- /dev/null
+++ b/lang/modula-3-lib/files/X.gcc
@@ -0,0 +1,3 @@
+*.bak
+*.orig
+*[-~]
diff --git a/lang/modula-3-lib/files/X.m3cc b/lang/modula-3-lib/files/X.m3cc
new file mode 100644
index 000000000000..235cd8b5fc4b
--- /dev/null
+++ b/lang/modula-3-lib/files/X.m3cc
@@ -0,0 +1,3 @@
+*.bak
+*.orig
+*[-~]
diff --git a/lang/modula-3-lib/files/X.src b/lang/modula-3-lib/files/X.src
new file mode 100644
index 000000000000..b5ea687e37eb
--- /dev/null
+++ b/lang/modula-3-lib/files/X.src
@@ -0,0 +1,51 @@
+*.bak
+*.orig
+*/64BITS
+*/AIX386
+*/ALPHA_OSF
+*/AOSF
+*/AP3000
+*/ARM
+*/DS
+*/DS3100
+*/FreeBSD
+*/HP300
+*/HPPA
+*/IBMR2
+*/IBMRT
+*/IEEE-be
+*/IRIX5
+*/LINUX
+*/LINUXELF
+*/NEXT
+*/NT386
+*/NT386-EXT
+*/OKI
+*/SEQUENT
+*/SOLgnu
+*/SOLsun
+*/SPARC
+*/SUN3
+*/SUN386
+*/UMAX
+*/VAX
+*/WIN32
+*/aix-3-2
+*/aix-ps2-1-2
+*/decunix
+*/freebsd-1
+*/hpux-7-0
+*/ibm-4-3
+*/irix-5.2
+*/linux
+*/osf-1.*
+*/osf1
+*/solaris-2-x
+*/sunos-4-x
+*/sysv-4.0
+*/tNT386
+*/ultrix
+*/ultrix-3-1.*
+*/win32
+*/winvbt
+*[-~]
diff --git a/lang/modula-3-lib/files/patch-aa b/lang/modula-3-lib/files/patch-aa
new file mode 100644
index 000000000000..630ea0a0e05a
--- /dev/null
+++ b/lang/modula-3-lib/files/patch-aa
@@ -0,0 +1,18 @@
+Eliminate a compiler warning under FreeBSD.
+
+Index: m3/quake/src/utils.c
+===================================================================
+RCS file: /home/jdp/m3-cvs/m3/quake/src/utils.c,v
+retrieving revision 1.1.1.1
+diff -u -r1.1.1.1 utils.c
+--- utils.c 1996/09/24 05:22:00 1.1.1.1
++++ utils.c 1996/09/24 05:32:34
+@@ -10,7 +10,7 @@
+ */
+
+ #include "quake.h"
+-#if !defined(TARGET_NEXT)
++#if !defined(TARGET_NEXT) && !defined(TARGET_FreeBSD2)
+ #include <malloc.h>
+ #endif
+
diff --git a/lang/modula-3-lib/files/patch-ab b/lang/modula-3-lib/files/patch-ab
new file mode 100644
index 000000000000..20c60dd545e2
--- /dev/null
+++ b/lang/modula-3-lib/files/patch-ab
@@ -0,0 +1,285 @@
+Fix a const-related compiler warning produced by the "execve" wrapper.
+Also, move network related wrappers to separate files, for SOCKS support.
+
+Index: m3/m3core/src/runtime/FreeBSD2/RTHeapDepC.c
+--- RTHeapDepC.c.orig Sat Mar 23 14:52:21 1996
++++ RTHeapDepC.c Tue Oct 8 14:31:15 1996
+@@ -110,20 +110,6 @@
+ /* Unless otherwise noted, all the following wrappers have the same
+ structure. */
+
+-int accept(s, addr, addrlen) /* ok */
+-int s;
+-struct sockaddr *addr;
+-int *addrlen;
+-{ int result;
+-
+- ENTER_CRITICAL;
+- MAKE_WRITABLE(addr);
+- MAKE_WRITABLE(addrlen);
+- result = syscall(SYS_accept, s, addr, addrlen);
+- EXIT_CRITICAL;
+- return result;
+-}
+-
+ int access(path, mode) /* ok */
+ char *path;
+ int mode;
+@@ -228,19 +214,6 @@
+ }
+ */
+
+-int bind(s, name, namelen) /* ok */
+-int s;
+-const struct sockaddr *name;
+-int namelen;
+-{ int result;
+-
+- ENTER_CRITICAL;
+- MAKE_READABLE(name);
+- result = syscall(SYS_bind, s, name, namelen);
+- EXIT_CRITICAL;
+- return result;
+-}
+-
+ /* not implemented
+ int cachectl(addr, nbytes, op)
+ char *addr;
+@@ -314,19 +287,6 @@
+ return result;
+ }
+
+-int connect(s, name, namelen) /* ok */
+-int s;
+-const struct sockaddr *name;
+-int namelen;
+-{ int result;
+-
+- ENTER_CRITICAL;
+- MAKE_READABLE(name);
+- result = syscall(SYS_connect, s, name, namelen);
+- EXIT_CRITICAL;
+- return result;
+-}
+-
+ /* not implemented (obsolete)
+ int creat(name, mode)
+ const char *name;
+@@ -356,8 +316,8 @@
+ result = syscall(SYS_execve, name, argv, envp);
+ if (result == -1 && errno == EFAULT) {
+ MAKE_READABLE(name);
+- { char **a; for (a = argv; *a; a++) MAKE_READABLE(*a); }
+- { char **e; for (e = envp; *e; e++) MAKE_READABLE(*e); }
++ { char * const *a; for (a = argv; *a; a++) MAKE_READABLE(*a); }
++ { char * const *e; for (e = envp; *e; e++) MAKE_READABLE(*e); }
+ } else {
+ return result;
+ }
+@@ -513,20 +473,6 @@
+ }
+ */
+
+-int getpeername(s, name, namelen) /* ok */
+-int s;
+-struct sockaddr *name;
+-int *namelen;
+-{ int result;
+-
+- ENTER_CRITICAL;
+- MAKE_WRITABLE(name);
+- MAKE_WRITABLE(namelen);
+- result = syscall(SYS_getpeername, s, name, namelen);
+- EXIT_CRITICAL;
+- return result;
+-}
+-
+ int getrlimit(resource, rlp) /* ok */
+ int resource;
+ struct rlimit *rlp;
+@@ -551,20 +497,6 @@
+ return result;
+ }
+
+-int getsockname(s, name, namelen) /* ok */
+-int s;
+-struct sockaddr *name;
+-int *namelen;
+-{ int result;
+-
+- ENTER_CRITICAL;
+- MAKE_WRITABLE(name);
+- MAKE_WRITABLE(namelen);
+- result = syscall(SYS_getsockname, s, name, namelen);
+- EXIT_CRITICAL;
+- return result;
+-}
+-
+ int getsockopt(s, level, optname, optval, optlen) /* ok */
+ int s, level, optname;
+ void *optval;
+@@ -821,19 +753,6 @@
+ return result;
+ }
+
+-int read(d, buf, nbytes) /* ok */
+-int d;
+-char *buf;
+-size_t nbytes;
+-{ int result;
+-
+- ENTER_CRITICAL;
+- MAKE_WRITABLE(buf);
+- result = syscall(SYS_read, d, buf, nbytes);
+- EXIT_CRITICAL;
+- return result;
+-}
+-
+ int readlink(path, buf, bufsiz) /* ok */
+ char *path;
+ char *buf;
+@@ -865,46 +784,6 @@
+ return result;
+ }
+
+-int recv(s, buf, len, flags) /* ok */
+-int s;
+-void *buf;
+-#if __FreeBSD__ >=2
+-size_t len;
+-#else
+-int len;
+-#endif
+-int flags;
+-{ int result;
+-
+- ENTER_CRITICAL;
+- MAKE_WRITABLE(buf);
+- result = syscall(SYS_recvfrom, s, buf, len, flags, NULL, 0);
+- EXIT_CRITICAL;
+- return result;
+-}
+-
+-int recvfrom(s, buf, len, flags, from, fromlen) /* ok */
+-int s;
+-void *buf;
+-#if __FreeBSD__ >=2
+-size_t len;
+-#else
+-int len;
+-#endif
+-int flags;
+-struct sockaddr *from;
+-int *fromlen;
+-{ int result;
+-
+- ENTER_CRITICAL;
+- MAKE_WRITABLE(buf);
+- MAKE_WRITABLE(from);
+- MAKE_WRITABLE(fromlen);
+- result = syscall(SYS_recvfrom, s, buf, len, flags, from, fromlen);
+- EXIT_CRITICAL;
+- return result;
+-}
+-
+ int recvmsg(s, msg, flags) /* ok */
+ int s;
+ struct msghdr msg[];
+@@ -950,24 +829,6 @@
+ return result;
+ }
+
+-int select(nfds, readfds, writefds, exceptfds, timeout) /* ok */
+-int nfds;
+-fd_set *readfds;
+-fd_set *writefds;
+-fd_set *exceptfds;
+-struct timeval *timeout;
+-{ int result;
+-
+- ENTER_CRITICAL;
+- MAKE_WRITABLE(readfds);
+- MAKE_WRITABLE(writefds);
+- MAKE_WRITABLE(exceptfds);
+- MAKE_READABLE(timeout);
+- result = syscall(SYS_select, nfds, readfds, writefds, exceptfds, timeout);
+- EXIT_CRITICAL;
+- return result;
+-}
+-
+ int semctl(semid, semnum, cmd, arg) /* ok ? */
+ int semid, cmd;
+ int semnum;
+@@ -1012,24 +873,6 @@
+ return result;
+ }
+
+-int send(s, msg, len, flags) /* ok */
+-int s;
+-const void *msg;
+-#if __FreeBSD__ >=2
+-size_t len;
+-#else
+-int len;
+-#endif
+-int flags;
+-{ int result;
+-
+- ENTER_CRITICAL;
+- MAKE_READABLE(msg);
+- result = syscall(SYS_sendto, s, msg, len, flags, NULL, 0);
+- EXIT_CRITICAL;
+- return result;
+-}
+-
+ int sendmsg(s, msg, flags) /* ok */
+ int s;
+ const struct msghdr msg[];
+@@ -1051,27 +894,6 @@
+ return result;
+ }
+
+-int sendto(s, msg, len, flags, to, tolen) /* ok */
+-int s;
+-const void *msg;
+-#if __FreeBSD__ >=2
+-size_t len;
+-#else
+-int len;
+-#endif
+-int flags;
+-const struct sockaddr *to;
+-int tolen;
+-{ int result;
+-
+- ENTER_CRITICAL;
+- MAKE_READABLE(msg);
+- MAKE_READABLE(to);
+- result = syscall(SYS_sendto, s, msg, len, flags, to, tolen);
+- EXIT_CRITICAL;
+- return result;
+-}
+-
+ int setdomainname(name, namelen) /* ok */
+ char *name;
+ int namelen;
+@@ -1414,19 +1236,6 @@
+ ENTER_CRITICAL;
+ MAKE_WRITABLE(status);
+ result = syscall(SYS_wait4, pid, status, options, NULL);
+- EXIT_CRITICAL;
+- return result;
+-}
+-
+-int write(fd, buf, nbytes) /* ok */
+-int fd;
+-char *buf;
+-int nbytes;
+-{ int result;
+-
+- ENTER_CRITICAL;
+- MAKE_READABLE(buf);
+- result = syscall(SYS_write, fd, buf, nbytes);
+ EXIT_CRITICAL;
+ return result;
+ }
diff --git a/lang/modula-3-lib/files/patch-ae b/lang/modula-3-lib/files/patch-ae
new file mode 100644
index 000000000000..c11eeb2dd374
--- /dev/null
+++ b/lang/modula-3-lib/files/patch-ae
@@ -0,0 +1,18 @@
+Remove an ill-formed C preprocessor construct, which isn't used anyway.
+
+Index: m3/coverage/src/analyze_coverage.c
+===================================================================
+RCS file: /home/jdp/m3-cvs/m3/coverage/src/analyze_coverage.c,v
+retrieving revision 1.1.1.1
+diff -u -r1.1.1.1 analyze_coverage.c
+--- analyze_coverage.c 1996/09/24 05:21:54 1.1.1.1
++++ analyze_coverage.c 1996/09/24 05:32:35
+@@ -15,8 +15,6 @@
+ #endif
+ #include <stdio.h>
+
+-#define MAX_LINES=10000
+-
+ #define TRUE 1
+ #define FALSE 0
+
diff --git a/lang/modula-3-lib/files/patch-ah b/lang/modula-3-lib/files/patch-ah
new file mode 100644
index 000000000000..c0f1f209fcde
--- /dev/null
+++ b/lang/modula-3-lib/files/patch-ah
@@ -0,0 +1,210 @@
+Update the m3build templates for FreeBSD-2.1 and later.
+
+Index: m3/m3build/templates/COMMON
+--- COMMON.orig Fri Feb 9 14:23:04 1996
++++ COMMON Fri Oct 25 13:48:57 1996
+@@ -998,7 +998,7 @@
+ if HAVE_PKGTOOLS
+ _install_file (src, dest, "0755", "T")
+ else
+- local target = format ("%s%s%s%s%s%s%s", PKG_USE, SL, BUILD_PACKAGE,
++ local target = format ("%s%s%s%s%s%s%s", LIB_TO_PKG, SL, BUILD_PACKAGE,
+ SL, BUILD_DIR, SL, src)
+ local link = format ("%s%s%s", dest, SL, src)
+ >> M3SHIP_FILE in
+Index: m3/m3build/templates/FreeBSD2
+--- FreeBSD2.orig Thu Jun 20 12:17:07 1996
++++ FreeBSD2 Fri Oct 25 13:47:16 1996
+@@ -8,8 +8,9 @@
+ % Modified On Thu Apr 8 13:45:49 PDT 1993 by muller
+ %
+ % Sun Nov 27 20:19:31 MET 1994 by ow
++% Fri Feb 2 15:04:50 PST 1996 by jdp@polstra.com
+ %
+-% FreeBSD 2.0 configuration (with shared library support in comments)
++% FreeBSD 2.1 and 2.2 configuration, with shared library support
+ %
+
+ %-------------------------------------------------- compilation environment ---
+@@ -44,6 +45,8 @@
+ MAN_INSTALL = INSTALL_ROOT & "man" % man pages
+ HTML_INSTALL = INSTALL_ROOT & "lib/m3/www" % public hypertext
+
++WDROOT = $HOME & "/m3/pkg" % handy default for overrides
++
+ % The manual pages normally go in subdirectories man{1,...8} of
+ % the MAN_INSTALL directory. If you prefer to have them all in
+ % a single section, define MAN_SECTION to be that section's name.
+@@ -56,7 +59,12 @@
+ LIB_USE = LIB_INSTALL
+ PKG_USE = PKG_INSTALL
+
+-readonly INSTALL_IMPLS = "TRUE"
++% This is a relative path from LIB_USE to PKG_USE, so that we can avoid
++% installing absolute symbolic links. If you cannot support such relative
++% links, then make it the same as PKG_USE.
++LIB_TO_PKG = "../pkg"
++
++readonly INSTALL_IMPLS = ""
+ % "TRUE"
+ % => save all source files during the install
+ % => makes debugging easier and browsing more fruitful
+@@ -90,15 +98,17 @@
+ % "import_TCP" is called from the tcp package.
+
+ readonly proc import_X11R4() is
+- import_lib("Xaw", "/usr/X386/lib")
+- import_lib("Xmu", "/usr/X386/lib")
+- import_lib("Xext", "/usr/X386/lib")
+- import_lib("Xt", "/usr/X386/lib")
+- import_lib("X11", "/usr/X386/lib")
++ import_lib("Xaw", "/usr/X11R6/lib")
++ import_lib("Xmu", "/usr/X11R6/lib")
++ import_lib("Xt", "/usr/X11R6/lib")
++ import_lib("SM", "/usr/X11R6/lib")
++ import_lib("ICE", "/usr/X11R6/lib")
++ import_lib("Xext", "/usr/X11R6/lib")
++ import_lib("X11", "/usr/X11R6/lib")
+ end
+
+ readonly proc import_Motif() is
+- import_lib("Xm", "/usr/X386/lib")
++ import_lib("Xm", "/usr/X11R6/lib")
+ end
+
+ readonly proc import_DECPEX() is
+@@ -128,9 +138,9 @@
+ % entire function. Note, the distributed code assumes gnuemacs version 19
+ % or later.
+
+-readonly proc emacs_compile (el) is
+- exec ("emacs -batch -f batch-byte-compile", el)
+-end
++%readonly proc emacs_compile (el) is
++% exec ("emacs -batch -f batch-byte-compile", el)
++%end
+
+ %---------------------------------------------------- C compiler and linker ---
+ % The following definitions are used to compile and link C modules.
+@@ -142,33 +152,27 @@
+ % The actual definitions must be kept on one line due to finicky details
+ % of the bootstrap process.
+
+-
+-%% The versions of ar and ranlib shipped with FreeBSD 2.0
+-%% definitelty do not work with the Modula-3 archives.
+-%% ar sometimes complains about `too many open files' and
+-%% ranlib often says `inappropriate file type for object'.
+-%% I haven't looked into this further, since newer versions
+-%% of the GNU binutils package work quite well. - Olaf Wagner 2/13/95
+-
+-
+-CC = _ifdef ("CC", CC, [ "gcc" ])
++CC = _ifdef ("CC", CC, [ "cc", "-fpic" ])
+ %--- C compiler with flags for compiling a single ".c" file
+-% ------ FOR SHARED LIBS, add -fPIC
+
+-LINK = _ifdef ("LINK", LINK, [ "gcc" ])
++LINK = _ifdef ("LINK", LINK, [ "ld", "-e", "start", "-dc", "-dp", "/usr/lib/crt0.o" ])
+ %--- C compiler with flags for linking
+-% ------ FOR SHARED LIBS, add -Xlinker -Bdynamic
+
+-MAKELIB = _ifdef ("MAKELIB", MAKELIB, [ "/usr/bin/ar", "cru" ])
++MAKELIB = _ifdef ("MAKELIB", MAKELIB, [ "ar", "cru" ])
+ %--- program to build library archives
+
+ RANLIB = _ifdef ("RANLIB", RANLIB, [ "ranlib" ])
+ %--- program to index libraries
+
+-ASM = _ifdef ("ASM", ASM, [ "/usr/bin/as" ])
++ASM = _ifdef ("ASM", ASM, [ "as", "-k" ])
+ %--- assembler
+-% ------ FOR SHARED LIBS with /usr/bin/as from the FreeBSD distribution,
+-% add -k -W
++
++BOOT_LINK = _ifdef ("BOOT_LINK", BOOT_LINK, [ "cc" ])
++%--- C compiler with flags for linking, used during the bootstrap process.
++% We have to use "cc" for the bootstrap, because the "-z2" option
++% ("libraries systematically linked with all programs") doesn't get used
++% during the bootstrap process. If we use "ld", then the C library isn't
++% linked in.
+
+ %------------------------------------------------------------- GNU variants ---
+ % The two large pieces of GNU software used by the Modula-3 system
+@@ -179,9 +183,9 @@
+ % To use the GNU defaults for CC and CFLAGS, specify "*".
+ %
+
+-GNU_CC = _ifdef ("GNU_CC", GNU_CC, "*")
+-GNU_CFLAGS = _ifdef ("GNU_CFLAGS", GNU_CFLAGS, "*")
+-GNU_MAKE = _ifdef ("GNU_MAKE", GNU_MAKE, "gmake")
++GNU_CC = _ifdef ("GNU_CC", GNU_CC, "cc")
++GNU_CFLAGS = _ifdef ("GNU_CFLAGS", GNU_CFLAGS, "-O")
++GNU_MAKE = _ifdef ("GNU_MAKE", GNU_MAKE, "make")
+
+ %-------------------------------------------------------- Modula-3 compiler ---
+ % The syntax for the values passed to most of the M3_CONFIG options is
+@@ -192,7 +196,8 @@
+ M3 = LIB_USE & "/m3"
+
+ % What are the standard flags?
+-M3OPTIONS = [ "-w1", "-why", "-g" ]
++M3OPTIONS = [ "-w1", "-why", "-O" ]
++% ------ FOR DEBUGGING INFO, add "-g"
+
+ M3_CONFIG = [
+ "-Y1" & _pack_args (CC),
+@@ -201,11 +206,11 @@
+ "-Y4" & _pack_args (RANLIB),
+ "-Y7" & _pack_args (ASM),
+
+- "-Y6@" & LIB_USE & "/m3cgc1@-quiet@",
++ "-Y6@" & LIB_USE & "/m3cgc1@-quiet@-fpic@",
+ % --- the Modula-3 IL to assembly language pass
+- % ------ FOR SHARED LIBS, add -fPIC
+
+- "-z2@-lm@", % --- libraries systematically linked with all programs
++ "-z2@-lm@/usr/lib/libgcc.a@-lc@/usr/lib/libgcc.a@",
++ % --- libraries systematically linked with all programs
+
+ "-z3" & LIB_USE & SL & "report_coverage.o",
+ % --- library linked in programs compiled with "-Z" coverage option
+@@ -248,7 +253,7 @@
+ % passes in a file and then deletes the file, unless "-keep" or
+ % "-verbose" is specified.
+
+- "-zK0",
++ "-zK1",
+ % --- Set the value of "-zK" to "1" if you want the m3 driver to
+ % supply -Bdynamic/-Bstatic options to the linker, "0" otherwise.
+
+@@ -263,9 +268,9 @@
+
+ proc build_standalone() is
+ % --- reset the linker to avoid shared libraries.
+- M3_CONFIG += "-Y2@cc@-static@"
+ M3_CONFIG += "-Y6@" & LIB_USE & "/m3cgc1@-quiet@"
+- M3_CONFIG += "-Y7@/usr/bin/as@"
++ M3_CONFIG += "-Y7@as@"
++ M3_CONFIG += "-Bstatic"
+ end
+
+ proc build_shared() is
+@@ -282,7 +287,7 @@
+
+ proc after_library_hooks(x) is
+ local lib_a = format ("lib%s.a", x)
+- local lib_so = format ("lib%s.so.1.1", x)
++ local lib_so = format ("lib%s.so.4.0", x)
+ local dest = format ("%s%s%s%s%s", PKG_INSTALL, SL, BUILD_PACKAGE,
+ SL, BUILD_DIR)
+
+@@ -291,7 +296,7 @@
+ write ("missing ", lib_a, ": not building ", lib_so, CR)
+ else
+ if stale (lib_so, lib_a)
+- exec ("/usr/bin/ld -Bshareable -assert pure-text -o",
++ exec ("ld -Bshareable -assert pure-text -o",
+ lib_so, COMPILE_OBJECTS)
+ end
+ install_derived (lib_so)
diff --git a/lang/modula-3-lib/files/patch-ai b/lang/modula-3-lib/files/patch-ai
new file mode 100644
index 000000000000..714b48476151
--- /dev/null
+++ b/lang/modula-3-lib/files/patch-ai
@@ -0,0 +1,19 @@
+Fix the mapping from M3 platform to GNU configure target, for FreeBSD.
+This particularly helps with m3gdb.
+
+Index: m3/m3build/templates/PLATFORMS
+===================================================================
+RCS file: /home/jdp/m3-cvs/m3/m3build/templates/PLATFORMS,v
+retrieving revision 1.1.1.2
+diff -u -r1.1.1.2 PLATFORMS
+--- PLATFORMS 1996/09/24 05:28:51 1.1.1.2
++++ PLATFORMS 1996/09/24 05:34:56
+@@ -10,7 +10,7 @@
+ "ARM" : [ "POSIX", "32BITS", "arm--riscos" ],
+ "DS3100" : [ "POSIX", "32BITS", "decstation" ],
+ "FreeBSD" : [ "POSIX", "32BITS", "i486-unknown-bsd" ],
+- "FreeBSD2" : [ "POSIX", "32BITS", "i486-unknown-bsd" ],
++ "FreeBSD2" : [ "POSIX", "32BITS", "i486-unknown-freebsd" ],
+ "HP300" : [ "POSIX", "32BITS", "m68k-hp-hpux" ],
+ "HPPA" : [ "POSIX", "32BITS", "hppa1.1-hp-hpux" ],
+ "IBMR2" : [ "POSIX", "32BITS", "rs6000-ibm-aix3.2" ],
diff --git a/lang/modula-3-lib/files/patch-aj b/lang/modula-3-lib/files/patch-aj
new file mode 100644
index 000000000000..375a0a656593
--- /dev/null
+++ b/lang/modula-3-lib/files/patch-aj
@@ -0,0 +1,17 @@
+Fix an erroneous structure declaration for FreeBSD.
+
+Index: m3/m3core/src/C/FreeBSD2/Cstdio.i3
+===================================================================
+RCS file: /home/jdp/m3-cvs/m3/m3core/src/C/FreeBSD2/Cstdio.i3,v
+retrieving revision 1.1.1.1
+diff -u -r1.1.1.1 Cstdio.i3
+--- Cstdio.i3 1996/09/24 05:21:57 1.1.1.1
++++ Cstdio.i3 1996/09/24 05:32:37
+@@ -55,6 +55,7 @@
+ (* Unix stdio files get aligned to block boundaries on fseek() *)
+ blksize : int; (* stat.st_blksize (may be != _bf._size) *)
+ offset : off_t; (* current lseek offset *)
++ pad1 : int; (* assume high 4 bytes of offset are 0 *)
+
+ END;
+
diff --git a/lang/modula-3-lib/files/patch-ak b/lang/modula-3-lib/files/patch-ak
new file mode 100644
index 000000000000..ab3215393d31
--- /dev/null
+++ b/lang/modula-3-lib/files/patch-ak
@@ -0,0 +1,515 @@
+Changes to what is built by default in the FreeBSD port.
+
+Index: m3/src/m3makefile
+===================================================================
+--- m3makefile.orig Tue Sep 17 16:47:59 1996
++++ m3makefile Wed Sep 25 17:14:37 1996
+@@ -83,6 +83,12 @@
+ % requires:
+ BuildChunk ("m3core")
+
++%--- m3configvars --- library -------------------------------------------------
++% m3configvars is a small library containing various configuration
++% parameters related to this particular installation of Modula-3.
++% requires: m3core
++BuildChunk ("m3configvars")
++
+ %--- libm3 --- library -------------------------------------------------
+ % libm3 is the library that most others need.
+ % requires: m3core
+@@ -99,12 +105,12 @@
+ %--- m3middle --- library -------------------------------------------------
+ % the Modula-3 compiler's IL definition
+ % requires: libm3
+-% BuildChunk ("m3middle") %-- built as part of the bootstrap process
++BuildChunk ("m3middle")
+
+ %--- m3linker --- library -------------------------------------------------
+ % the Modula-3 prelinker
+ % requires: m3middle
+-% BuildChunk ("m3linker") %-- built as part of the bootstrap process
++BuildChunk ("m3linker")
+
+ %--- m3objfile --- library -------------------------------------------------
+ % the Modula-3 object file writers
+@@ -114,7 +120,7 @@
+ %--- m3front --- library -------------------------------------------------
+ % the Modula-3 compiler front-end
+ % requires: m3middle
+-% BuildChunk ("m3front") %-- built as part of the bootstrap process
++BuildChunk ("m3front")
+
+ %--- m3back --- library -------------------------------------------------
+ % the Windows/NT x86 back-end
+@@ -129,7 +135,7 @@
+ %--- m3 --- utility -------------------------------------------------
+ % the Modula-3 compiler (main program)
+ % requires: m3linker, m3front, m3middle, libm3
+-% BuildChunk ("m3") %-- built as part of the bootstrap process
++BuildChunk ("m3")
+
+ %--- m3loader --- utility -------------------------------------------------
+ % an experimental dynamic loader for Windows/NT
+@@ -145,7 +151,7 @@
+
+ %--- m3build2 --- utility ------------------------------------------------
+ % an experimental Modula-3 version of m3build
+-% requires: libm3, m3quake
++% requires: m3configvars, libm3, m3quake
+ % BuildChunk ("m3build2")
+
+ %--- cg-burs --- utility -------------------------------------------------
+@@ -207,7 +213,7 @@
+ %--- slisp --- library -----------------------------------------------
+ % a library containing a small Lisp interpreter
+ % requires: libm3
+-BuildChunk ("slisp")
++% BuildChunk ("slisp")
+
+ %--- tempfiles --- library -----------------------------------------------
+ % a library to build tempfiles
+@@ -229,32 +235,32 @@
+ %--- netobj --- library -------------------------------------------
+ % the network objects runtime library, needed by most distributed applications
+ % requires: tcp
+-BuildChunk ("netobj")
++% BuildChunk ("netobj")
+
+ %--- netobjd --- utility -------------------------------------------
+ % the network objects daemon, needed by all programs using network objects
+ % requires: netobj
+-BuildChunk ("netobjd")
++% BuildChunk ("netobjd")
+
+ %--- m3tk --- library -------------------------------------------
+ % a (large) Modula-3 abstract syntax tree (AST) toolkit, needed by stubgen
+ % requires: libm3
+-BuildChunk ("m3tk")
++% BuildChunk ("m3tk")
+
+ %--- stubgen --- utility -------------------------------------------
+ % the network objects stub generator, needed by programs using network objects
+ % requires: m3tk
+-BuildChunk ("stubgen")
++% BuildChunk ("stubgen")
+
+ %--- stable --- library ---------------------------------------------
+ % A library providing log-based persistent objects
+ % requires: libm3
+-BuildChunk ("stable")
++% BuildChunk ("stable")
+
+ %--- stablegen --- utility -------------------------------------------
+ % a stub generator to make the use of the "stable" library much easier
+ % requires: m3tk, stable
+-BuildChunk ("stablegen")
++% BuildChunk ("stablegen")
+
+ %--- sharedboard --- prototype -------------------------------------------
+ % a prototype shared whiteboard
+@@ -273,7 +279,7 @@
+ % PEX implements a Modula-3 interface to the PEX 3D graphics library.
+ % It is used by all graphical 3D applications
+ % requires: X11R4 and a host PEX implementation
+-if PLATFORM_SUPPORTS_PEX
++if PLATFORM_SUPPORTS_DECPEX
+ BuildChunk ("PEX")
+ end
+
+@@ -289,21 +295,21 @@
+ % motif implements a Modula-3 interface to the X/Motif library.
+ % requires: X11R4
+ if PLATFORM_SUPPORTS_MOTIF
+- BuildChunk ("motif")
++% BuildChunk ("motif")
+ end
+
+ %--- tetris --- game -------------------------------------------------
+ % a Modula-3 version of Tetris
+ % requires: X11R4
+ if PLATFORM_SUPPORTS_X
+- BuildChunk ("tetris")
++% BuildChunk ("tetris")
+ end
+
+ %--- columns --- game -------------------------------------------------
+ % a Modula-3 version of the PC game, columns
+ % requires: X11R4
+ if PLATFORM_SUPPORTS_X
+- BuildChunk ("columns")
++% BuildChunk ("columns")
+ end
+
+ %--- ui --- library -------------------------------------------------
+@@ -316,18 +322,18 @@
+ %--- bicycle --- library -------------------------------------------------
+ % bicycle is a library of playing card images.
+ % requires: ui
+-BuildChunk ("bicycle")
++% BuildChunk ("bicycle")
+
+ %--- solitaire --- game -------------------------------------------------
+ % a Modula-3 version of SeaHaven towers
+ % requires: bicycle
+-BuildChunk ("solitaire")
++% BuildChunk ("solitaire")
+
+ %--- badbricks --- game -------------------------------------------------
+ % a Modula-3 game similar to minesweeper, inspired by the crumbling
+ % facade of SRC's building.
+ % requires: ui
+-BuildChunk ("badbricks")
++% BuildChunk ("badbricks")
+
+ %--- m3tools --- library -------------------------------------------------
+ % a simple Modula-3 scanner, needed by m3tohtml and m3browser
+@@ -336,12 +342,12 @@
+
+ %--- m3tohtml --- utility -------------------------------------------------
+ % a program to convert batches of Modula-3 source to interconnected HTML
+-% requires: libm3, m3tools
++% requires: m3configvars, libm3, m3tools
+ BuildChunk ("m3tohtml")
+
+ %--- m3browser --- utility -------------------------------------------------
+ % an HTTP server that provides WWW browsing of the installed Modula-3 system
+-% requires: libm3, m3tools
++% requires: m3configvars, libm3, m3tools
+ if equal (OS_TYPE, "POSIX")
+ BuildChunk ("m3browser")
+ end
+@@ -370,7 +376,7 @@
+ %--- fours --- game -------------------------------------------------
+ % a collection of Modula-3 variants of the PC game, tetris.
+ % requires: vbtkit
+-BuildChunk ("fours")
++% BuildChunk ("fours")
+
+ %--- showheap --- utility -------------------------------------------------
+ % a program to graphically display in real-time the state of each heap page.
+@@ -442,37 +448,37 @@
+ %--- fisheye --- demo -------------------------------------------------
+ % a demo of "fisheye" views for graph browsing
+ % requires: formsvbt
+-BuildChunk ("fisheye")
++% BuildChunk ("fisheye")
+
+ %--- calculator --- demo -------------------------------------------------
+ % a 10-key calculator using FormsVBT
+ % requires: formsvbt
+-BuildChunk ("calculator")
++% BuildChunk ("calculator")
+
+ %--- cube --- demo -------------------------------------------------
+ % a rotating cube
+ % requires: formsvbt
+-BuildChunk ("cube")
++% BuildChunk ("cube")
+
+ %--- codeview --- library -------------------------------------------
+ % support for animated views of source code, needed by zeus
+ % requires: formsvbt
+-BuildChunk ("codeview")
++% BuildChunk ("codeview")
+
+ %--- rehearsecode --- utility -------------------------------------------
+ % a program to manually test drive source code animations
+ % requires: codeview
+-BuildChunk ("rehearsecode")
++% BuildChunk ("rehearsecode")
+
+ %--- mg --- library -------------------------------------------
+ % the low-level animation support
+ % requires: formsvbt
+-BuildChunk ("mg")
++% BuildChunk ("mg")
+
+ %--- mgkit --- library -------------------------------------------
+ % a collection of easier-to-use animation widgets
+ % requires: m3
+-BuildChunk ("mgkit")
++% BuildChunk ("mgkit")
+
+ %--- anim3D --- library -------------------------------------------
+ % a collection of 3D animation widgets
+@@ -480,118 +486,118 @@
+ % X11R4 and PEX
+ % X11R4 and OpenGL
+ % soon: OpenGL and Windows NT
+-BuildChunk ("anim3D")
++% BuildChunk ("anim3D")
+
+ %--- synloc --- library -------------------------------------------
+ % a low-level library used by the Obliq interpreter
+ % requires: libm3
+-BuildChunk ("synloc")
++% BuildChunk ("synloc")
+
+ %--- synex --- library -------------------------------------------
+ % a low-level "syntax extension" library used by the Obliq interpreter
+ % requires: synloc
+-BuildChunk ("synex")
++% BuildChunk ("synex")
+
+ %--- metasyn --- library -------------------------------------------
+ % a low-level library used by the Obliq interpreter
+ % requires: synex
+-BuildChunk ("metasyn")
++% BuildChunk ("metasyn")
+
+ %--- obliqrt --- library -------------------------------------------
+ % the Obliq interpreter's runtime library
+ % requires: synloc, netobj
+-BuildChunk ("obliqrt")
++% BuildChunk ("obliqrt")
+
+ %--- obliqlibm3 --- library -------------------------------------------
+ % the Obliq interpreter's hooks to the libm3 library
+ % requires: obliqrt, libm3
+-BuildChunk ("obliqlibm3")
++% BuildChunk ("obliqlibm3")
+
+ %--- obliqlibui --- library -------------------------------------------
+ % the Obliq interpreter's hooks to the ui library
+ % requires: obliqrt, formsvbt
+-BuildChunk ("obliqlibui")
++% BuildChunk ("obliqlibui")
+
+ %--- obliqlibanim --- library -------------------------------------------
+ % the Obliq interpreter's hooks to the animation libraries
+ % requires: obliqrt, mgkit
+-BuildChunk ("obliqlibanim")
++% BuildChunk ("obliqlibanim")
+
+ %--- obliqparse --- library -------------------------------------------
+ % the Obliq interpreter's parser
+ % requires: obliqrt
+-BuildChunk ("obliqparse")
++% BuildChunk ("obliqparse")
+
+ %--- obliqprint --- library -------------------------------------------
+ % the Obliq interpreter's value printer
+ % requires: obliqrt
+-BuildChunk ("obliqprint")
++% BuildChunk ("obliqprint")
+
+ %--- obliq --- library -------------------------------------------
+ % the Obliq interpreter
+ % requires: obliqparse, obliqprint, metasyn
+-BuildChunk ("obliq")
++% BuildChunk ("obliq")
+
+ %--- obliqlib3D --- library -------------------------------------------
+ % the Obliq interpreter's hooks to the 3D animation libraries
+ % requires: anim3D, obliqlibanim, obliq
+-BuildChunk ("obliqlib3D")
++% BuildChunk ("obliqlib3D")
+
+ %--- obliqbinmin --- utility -------------------------------------------
+ % the Obliq interpreter with minimal runtime hooks
+ % requires: obliq
+-BuildChunk ("obliqbinmin")
++% BuildChunk ("obliqbinmin")
+
+ %--- obliqbinstd --- utility -------------------------------------------
+ % the Obliq interpreter with the "standard" runtime hooks
+ % requires: obliq, obliqlibm3
+-BuildChunk ("obliqbinstd")
++% BuildChunk ("obliqbinstd")
+
+ %--- obliqbinui --- utility -------------------------------------------
+ % the Obliq interpreter with ui support
+ % requires: obliq, obliqlibm3, obliqlibui
+-BuildChunk ("obliqbinui")
++% BuildChunk ("obliqbinui")
+
+ %--- obliqbinanim --- utility -------------------------------------------
+ % the Obliq interpreter with full animation support
+ % requires: obliq, obliqlibm3, obliqlibui, obliqlibanim
+-BuildChunk ("obliqbinanim")
++% BuildChunk ("obliqbinanim")
+
+ %--- obliqbin3D --- utility -------------------------------------------
+ % the Obliq interpreter with full 3D animation support
+ % requires: obliq, obliqlibm3, obliqlibui, obliqlibanim, obliqlib3D
+-BuildChunk ("obliqbin3D")
++% BuildChunk ("obliqbin3D")
+
+ %--- obliqsrvstd --- utility -------------------------------------------
+ % an Obliq "server" with the standard runtime hooks
+ % requires: obliq, obliqlibm3
+-BuildChunk ("obliqsrvstd")
++% BuildChunk ("obliqsrvstd")
+
+ %--- obliqsrvui --- utility -------------------------------------------
+ % an Obliq "server" with ui support
+ % requires: obliq, obliqlibm3, obliqlibui
+-BuildChunk ("obliqsrvui")
++% BuildChunk ("obliqsrvui")
+
+ %--- m3zume --- utility -------------------------------------------
+ % the "interesting event" preprocessor needed by zeus
+ % requires: formsvbt, stubgen
+-BuildChunk ("m3zume")
++% BuildChunk ("m3zume")
+
+ %--- zeus --- library -------------------------------------------
+ % the algorithm animation toolkit
+ % requires: netobj, codeview, mgkit, m3zume, netobj, stubgen
+-BuildChunk ("zeus")
++% BuildChunk ("zeus")
+
+ %--- mentor --- demo -------------------------------------------------
+ % a collection of algoritm animations
+ % requires: zeus, obliqbinanim
+-BuildChunk ("mentor")
++% BuildChunk ("mentor")
+
+ %--- smalldb --- library -------------------------------------------
+ % an in-memory database library, used by the package tools
+ % requires: libm3
+ if equal (OS_TYPE, "POSIX")
+- BuildChunk ("smalldb")
++% BuildChunk ("smalldb")
+ end
+
+ %
+@@ -644,37 +650,40 @@
+ %--- visualobliq --- demo -------------------------------------------
+ % a prototype of an easy-to-use distributed programming environment
+ % requires: formsvbt, obliq, obliqlibui, obliqlibm3
+-BuildChunk ("visualobliq")
++% BuildChunk ("visualobliq")
+
+ %--- voquery --- demo -------------------------------------------
+ % a simple query program used by vorun
+ % requires: formsvbt
+-BuildChunk ("voquery")
++% BuildChunk ("voquery")
+
+ %--- vorun --- demo -------------------------------------------
+ % a safe visual obliq interpreter suitable for embedding in the WWW.
+ % requires: obliqlibui, obliqlibm3, obliq, voquery, vorun
+ if equal (OS_TYPE, "POSIX")
+- BuildChunk ("vorun")
++% BuildChunk ("vorun")
+ end
+
+ %--- vocgi --- demo -------------------------------------------
+ % an HTML/cgi gateway, required to embed Visual Obliq code in the WWW.
+ % requires: obliqlibm3, obliq
+-BuildChunk ("vocgi")
++% BuildChunk ("vocgi")
+
+ %--- llscan --- utility -------------------------------------------
+ % a little mh program used by Postcard
+ % requires:
+ if equal (OS_TYPE, "POSIX")
+- BuildChunk ("llscan")
++% FreeBSD port: Don't uncomment the following line. This chunk depends
++% upon absolute pathnames. It will be built automatically during the
++% installation process.
++% BuildChunk ("llscan")
+ end
+
+ %--- postcard --- utility -------------------------------------------
+ % an integrated mail/news reader
+ % requires: formsvbt llscan mtex
+ if equal (OS_TYPE, "POSIX")
+- BuildChunk ("postcard")
++% BuildChunk ("postcard")
+ end
+
+ %--- gnuemacs --- library -------------------------------------------------
+@@ -682,67 +691,67 @@
+ % also a program to build Modula-3 tags
+ % requires:
+ if equal (OS_TYPE, "POSIX")
+- BuildChunk ("gnuemacs")
++% BuildChunk ("gnuemacs")
+ end
+
+ %--- webvbt --- library -------------------------------------------------
+ % a library for displaying HTML pages inside a VBT
+ % requires: formsvbt obliqparse obliqlibm3 obliqlibui obliqlibanim
+-BuildChunk ("webvbt")
++% BuildChunk ("webvbt")
+
+ %--- webscape --- utility -------------------------------------------------
+ % a web browser with support for interactive content
+ % requires: webvbt
+-BuildChunk ("webscape")
++% BuildChunk ("webscape")
+
+ %--- deckscape --- utility -------------------------------------------------
+ % a web browser that uses a new metaphor: "decks" of web pages
+ % requires: webvbt
+-BuildChunk ("deckscape")
++% BuildChunk ("deckscape")
+
+ %--- webcard --- utility -------------------------------------------------
+ % an integrated mail/news/web client
+ % requires: webvbt
+ if equal (OS_TYPE, "POSIX")
+- BuildChunk ("webcard")
++% BuildChunk ("webcard")
+ end
+
+ %--- ocr --- library -------------------------------------------------
+ % interface to optical character recognition library (DECstation only)
+ % requires: libm3
+-BuildChunk ("ocr")
++% BuildChunk ("ocr")
+
+ %--- lecterndoc --- library -------------------------------------------------
+ % "lectern" document format
+ % requires: libm3
+-BuildChunk ("lecterndoc")
++% BuildChunk ("lecterndoc")
+
+ %--- lecternclient --- library & utility --------------------------------------
+ % tool for sending requests to Lectern server
+ % requires: libm3, mtex
+-BuildChunk ("lecternclient")
++% BuildChunk ("lecternclient")
+
+ %--- lecterntohtml --- utility ------------------------------------------------
+ % tool for sending requests to Lectern server
+ % requires: lecterndoc, mtex
+ if equal (OS_TYPE, "POSIX")
+- BuildChunk ("lecterntohtml")
++% BuildChunk ("lecterntohtml")
+ end
+
+ %--- lectern --- utility -------------------------------------------------
+ % the "virtual paper" document viewer
+ % requires: formsvbt, images, tempfiles, lecternclient
+-BuildChunk ("lectern")
++% BuildChunk ("lectern")
+
+ %--- buildlectern --- utility -------------------------------------------------
+ % program for building lectern documents
+ % requires: ocr, lecterndoc, tempfiles, images, mtex
+-BuildChunk ("buildlectern")
++% BuildChunk ("buildlectern")
+
+ %--- editlectern --- utility -------------------------------------------------
+ % program for editing lectern documents
+ % requires: formsvbt, lecternclient, lecterndoc
+-BuildChunk ("editlectern")
++% BuildChunk ("editlectern")
+
+ %--- tcpextras --- library -------------------------------------------------
+ % Additions to the tcp library
+@@ -752,9 +761,9 @@
+ %--- http --- library -------------------------------------------------
+ % library for hypertext transfer protocol (HTTP)
+ % requires: tcpextras
+-BuildChunk ("http")
++% BuildChunk ("http")
+
+ %--- webcat --- utility -------------------------------------------------
+ % program that takes a URL and prints out the web document
+ % requires: http
+-BuildChunk ("webcat")
++% BuildChunk ("webcat")
diff --git a/lang/modula-3-lib/files/patch-am b/lang/modula-3-lib/files/patch-am
new file mode 100644
index 000000000000..57085c2bc1b2
--- /dev/null
+++ b/lang/modula-3-lib/files/patch-am
@@ -0,0 +1,97 @@
+Change the font lookup algorithm to prefer non-scalable fonts when they
+are available. The original algorithm came up with some really ugly
+scaled fonts sometimes, even when an equally suitable unscaled
+alternative was available.
+
+Index: m3/ui/src/xvbt/XScrnFont.m3
+===================================================================
+RCS file: /home/jdp/m3-cvs/m3/ui/src/xvbt/XScrnFont.m3,v
+retrieving revision 1.1.1.1
+diff -u -r1.1.1.1 XScrnFont.m3
+--- XScrnFont.m3 1996/09/24 05:22:01 1.1.1.1
++++ XScrnFont.m3 1996/09/24 05:32:38
+@@ -193,12 +193,16 @@
+
+ PROCEDURE FontLookup (orc: FontOracle; name: TEXT): ScrnFont.T
+ RAISES {ScrnFont.Failure, TrestleComm.Failure} =
+- VAR s: Ctypes.char_star;
++ VAR
++ s: Ctypes.char_star;
++ uname: TEXT;
+ BEGIN
+ TRY
+ TrestleOnX.Enter(orc.st.trsl);
+ TRY
+- s := M3toC.TtoS(name);
++ uname := FindUnscaled(orc.st.trsl.dpy, name); (* Prefer unscaled font *)
++ IF uname = NIL THEN uname := name END;
++ s := M3toC.TtoS(uname);
+ VAR xfs := X.XLoadQueryFont(orc.st.trsl.dpy, s);
+ BEGIN
+ IF xfs = NIL THEN RAISE ScrnFont.Failure END;
+@@ -209,6 +213,65 @@
+ END;
+ EXCEPT X.Error => RAISE TrestleComm.Failure END;
+ END FontLookup;
++
++PROCEDURE FindUnscaled(dpy: X.DisplayStar; pat: TEXT): TEXT RAISES {X.Error} =
++ (* Return the first matching unscaled font, if any. Otherwise return NIL. *)
++ VAR
++ s := M3toC.TtoS(pat);
++ xcount: Ctypes.int;
++ fonts := X.XListFonts(dpy, s, 32767, ADR(xcount));
++ fp := fonts;
++ count: INTEGER := xcount;
++ xmatch: Ctypes.char_star := NIL;
++ match: TEXT := NIL;
++ BEGIN
++ IF count = 0 THEN
++ IF fonts # NIL THEN X.XFreeFontNames(fonts) END;
++ RETURN NIL;
++ END;
++
++ FOR i := 0 TO count - 1 DO (* Search for an unscaled font *)
++ IF NOT IsScaled(M3toC.StoT(fp^)) THEN
++ xmatch := fp^;
++ EXIT;
++ END;
++ fp := fp + ADRSIZE(fp^);
++ END;
++
++ IF xmatch # NIL THEN (* Found an unscaled font *)
++ match := M3toC.CopyStoT(xmatch);
++ END;
++ X.XFreeFontNames(fonts);
++ RETURN match;
++ END FindUnscaled;
++
++PROCEDURE IsScaled(name: TEXT): BOOLEAN =
++ (* Return true if font is scaled. *)
++ VAR
++ len := Text.Length(name);
++ fieldNum := 0;
++ found0 := FALSE;
++ hyphenPos: INTEGER;
++ BEGIN
++ (* A font is scaled if:
++ a. it is in canonical form (starts with '-', and all 14 XLFD fields
++ are present), and
++ b. any of the fields pixel size, point size, or average width is 0. *)
++ hyphenPos := Text.FindChar(name, '-', 0);
++ WHILE hyphenPos # -1 DO
++ INC(fieldNum);
++ IF fieldNum = 7 OR fieldNum = 8 OR fieldNum = 12 THEN
++ IF hyphenPos+2 < len AND
++ Text.GetChar(name, hyphenPos+1) = '0' AND
++ Text.GetChar(name, hyphenPos+2) = '-' THEN
++ found0 := TRUE;
++ END;
++ END;
++ hyphenPos := Text.FindChar(name, '-', hyphenPos+1);
++ END;
++
++ RETURN fieldNum = 14 AND Text.GetChar(name, 0) = '-' AND found0;
++ END IsScaled;
+
+ CONST
+ BuiltInNames = ARRAY OF
diff --git a/lang/modula-3-lib/files/patch-aq b/lang/modula-3-lib/files/patch-aq
new file mode 100644
index 000000000000..075abdc346d0
--- /dev/null
+++ b/lang/modula-3-lib/files/patch-aq
@@ -0,0 +1,222 @@
+New package "m3configvars". This does the same thing as "m3config", but
+instead of constants for the configuration parameters, it uses variables
+that are initialized at start up. This makes it much easier to change
+the Modula-3 installation directory, by simply building a new shared
+library for "m3configvars". With this approach, there is no need to
+recompile or even relink applications.
+
+Index: m3/m3configvars/src/COPYRIGHT
+===================================================================
+RCS file: /home/jdp/m3-cvs/m3/m3configvars/src/COPYRIGHT,v
+retrieving revision 1.1.1.1
+diff -u -r1.1.1.1 COPYRIGHT
+--- COPYRIGHT 1996/09/24 05:21:56 1.1.1.1
++++ COPYRIGHT 1996/09/24 05:32:39
+@@ -0,0 +1,93 @@
++
++ Digital License Agreement
++
++ SRC Modula-3
++
++ 1. Grant Of License. Digital Equipment Corporation, having a principal
++ office at 146 Main Street, Maynard, MA 01754 ("DIGITAL") grants to
++ you ("LICENSEE") the non-exclusive, non-transferable, royalty free
++ right to use, modify, reproduce and distribute SRC Modula-3 ("SOFTWARE")
++ subject to the terms set forth herein. Any distribution of SOFTWARE
++ shall include this Digital License Agreement in human readable form.
++
++ 2. Title to Intellectual Property and Software. Subject to the limited
++ rights and licenses granted under this License Agreement, all rights,
++ title and interests including patent, copyright, and trademark rights
++ in SOFTWARE are and shall remain vested in DIGITAL to the exclusion
++ of LICENSEE. DIGITAL represents and warrants that DIGITAL has the
++ legal right to grant such licenses as are expressly granted under
++ this Agreement.
++
++ 3. Copyright. The SOFTWARE is owned by DIGITAL or its suppliers and is
++ protected by United States copyright laws and international treaty
++ provisions. Therefore, you must treat the SOFTWARE like any other
++ copyrighted material (e.g., a book or musical recording) except
++ that you may use the SOFTWARE as provided in this Digital License
++ Agreement.
++
++ 4. Improvements. LICENSEE hereby grants to DIGITAL a non-exclusive,
++ non-transferable, royalty free right to use, modify, reproduce
++ and distribute with the right to sublicense at any tier, any
++ improvements, enhancements, extensions, or modifications that
++ LICENSEE make to SOFTWARE, provided such are returned to DIGITAL
++ by LICENSEE.
++
++ 5. DISCLAIMER OF WARRANTY. Because the SOFTWARE is a research work and
++ not a released product, it is provided "AS IS" WITHOUT WARRANTY OF ANY
++ KIND AND WITHOUT ANY SUPPORT SERVICES. EXCEPT AS SPECIFICALLY PROVIDED
++ ABOVE IN SECTION 2, DIGITAL FURTHER DISCLAIMS ALL OTHER EXPRESS OR
++ IMPLIED WARRANTIES OF MERCHANTABILITY OR OF FITNESS FOR A PARTICULAR
++ PURPOSE. THE ENTIRE RISK ARISING OUT OF THE USE OR PERFORMANCE OF
++ THE SOFTWARE REMAINS WITH YOU.
++
++ 6. Limitation of Liability. IN NO EVENT SHALL DIGITAL OR ITS SUPPLIERS BE
++ LIABLE IN AN AMOUNT THAT EXCEEDS THE LICENSE FEE PAID BY LICENSEE FOR
++ ANY DAMAGES (INCLUDING, WITH LIMITATION, DAMAGES FOR LOSS OF BUSINESS
++ PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER
++ PECUNIARY LOSS), REGARDLESS OF THE FORM OF CLAIM OR ACTIONS, ARISING
++ OUT OF THE USE OF OR INABILITY TO USE THE SOFTWARE OR DOCUMENTATION,
++ EVEN IF DIGITAL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
++ BECAUSE SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY
++ FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE LIMITATION MAY NOT
++ APPLY TO YOU.
++
++ 7. Acknowledgement of Allocation of Risk. LICENSEE acknowledges and agrees
++ that the fees charged by DIGITAL in this Agreement reflect the allocation
++ of risks provided by the foregoing limitation of liability. LICENSEE
++ acknowledges and represents that it has read and understands these
++ allocations of risk limiting the liability of DIGITAL and that it
++ understands that a modification of the allocation of risks set forth
++ in this agreement would affect the fees charged by DIGITAL, and that
++ LICENSEE, in consideration of such fees, agrees to such allocations
++ of risk.
++
++ 8. LICENSEE INDEMNIFICATION. LICENSEE SHALL INDEMNIFY DIGITAL AGAINST
++ ALL COSTS AND DAMAGE JUDGEMENTS, INCLUDING ATTORNEY'S FEES AND COSTS
++ OF DEFENSE, INCURRED BECAUSE OF CLAIMS OF DAMAGE ARISING FROM LICENSEE'S
++ POSSESSION OR USE OR INABILITY TO USE SOFTWARE.
++
++ 9. GOVERNMENT RESTRICTED RIGHTS. The SOFTWARE and documentation are provided
++ with RESTRICTED RIGHTS. Use duplication, or disclosure by the Government
++ is subject restrictions as set forth in subparagraph (c)(1)(ii) of The
++ Rights in Technical Data and Computer Software clause in DFARS
++ 252.227-7013, or subparagraphs (c)(i) and (2) of the Commercial Computer
++ Software -- Restricted Rights at 48 CFR 52.227-19, as applicable.
++ Manufacturer is Digital Equipment Corporation, 130 Lytton Avenue,
++ Palo Alto, CA 94301-1044.
++
++10. Severability. If any provision of the Agreement is held illegal or
++ unenforceable by any court of competent jurisdiction, such provision
++ shall be deemed separable from the remaining provisions of this Agreement
++ and shall not affect or impair the validity or enforceability of the
++ remaining provisions of this Agreement.
++
++11. Governing Law. This Agreement is governed by the laws of the
++ Commonwealth of Massachusetts.
++
++12. Publicity. You my not use the name of DIGITAL in any advertisement,
++ press release or other publicity with reference to SRC Modula-3
++ without prior written consent of DIGITAL.
++
++13. Should you have any questions concerning this Agreement, or if you
++ desire to contact Digital for any reason, please do so via E-mail:
++ M3-REQUEST@SRC.DEC.COM.
+Index: m3/m3configvars/src/M3ConfigVars.i3
+===================================================================
+RCS file: /home/jdp/m3-cvs/m3/m3configvars/src/M3ConfigVars.i3,v
+retrieving revision 1.1.1.1
+diff -u -r1.1.1.1 M3ConfigVars.i3
+--- M3ConfigVars.i3 1996/09/24 05:21:56 1.1.1.1
++++ M3ConfigVars.i3 1996/09/24 05:32:39
+@@ -0,0 +1,41 @@
++(* Copyright (C) 1994, Digital Equipment Corporation *)
++(* All rights reserved. *)
++(* See the file COPYRIGHT for a full description. *)
++
++(* This interface exports the configuration information
++ used by m3build and quake. These constants were defined
++ when Modula-3 was installed. *)
++
++INTERFACE M3ConfigVars;
++
++VAR (* CONST *) (* misc. configuration *)
++ TARGET: TEXT;
++ OS_TYPE: TEXT;
++ WORD_SIZE: TEXT;
++ BUILD_DIR: TEXT;
++ PATH_SEP: TEXT;
++ M3: TEXT;
++
++VAR (* CONST *) (* installation directories *)
++ BIN_INSTALL: TEXT;
++ LIB_INSTALL: TEXT;
++ DOC_INSTALL: TEXT;
++ PKG_INSTALL: TEXT;
++ MAN_INSTALL: TEXT;
++ EMACS_INSTALL: TEXT;
++ HTML_INSTALL: TEXT;
++
++(* On some systems (e.g. AFS) you must install public files
++ in a different place from where you use them. The paths
++ below specify where to find the installed files. *)
++
++VAR (* CONST *)
++ BIN_USE: TEXT;
++ LIB_USE: TEXT;
++ DOC_USE: TEXT;
++ PKG_USE: TEXT;
++ MAN_USE: TEXT;
++ EMACS_USE: TEXT;
++ HTML_USE: TEXT;
++
++END M3ConfigVars.
+Index: m3/m3configvars/src/m3makefile
+===================================================================
+RCS file: /home/jdp/m3-cvs/m3/m3configvars/src/m3makefile,v
+retrieving revision 1.1.1.1
+diff -u -r1.1.1.1 m3makefile
+--- m3makefile 1996/09/24 05:21:56 1.1.1.1
++++ m3makefile 1996/09/24 05:32:39
+@@ -0,0 +1,57 @@
++% Copyright (C) 1994, Digital Equipment Corporation
++% All rights reserved.
++% See the file COPYRIGHT for a full description.
++%
++% Last modified on Wed Jan 31 15:10:00 PST 1996 by jdp@polstra.com
++% modified on Thu Dec 1 09:52:35 PST 1994 by kalsow
++% modified on Mon Jan 18 11:50:18 PST 1993 by muller
++
++readonly M3ConfigVars_body = [
++ "(* Copyright (C) 1994, Digital Equipment Corporation *)",
++ "(* All rights reserved. *)",
++ "(* See the file COPYRIGHT for a full description. *)",
++ "",
++ "MODULE M3ConfigVars;",
++ "",
++ "BEGIN",
++ " (* misc. configuration *)",
++ " TARGET := \"" & escape(TARGET) & "\";",
++ " OS_TYPE := \"" & escape(OS_TYPE) & "\";",
++ " WORD_SIZE := \"" & escape(WORD_SIZE) & "\";",
++ " BUILD_DIR := \"" & escape(DEFAULT_BUILD_DIR) & "\";",
++ " PATH_SEP := \"" & escape(SL) & "\";",
++ " M3 := \"" & escape(M3) & "\";",
++ "",
++ " (* installation directories *)",
++ " BIN_INSTALL := \"" & escape(BIN_INSTALL) & "\";",
++ " LIB_INSTALL := \"" & escape(LIB_INSTALL) & "\";",
++ " DOC_INSTALL := \"" & escape(DOC_INSTALL) & "\";",
++ " PKG_INSTALL := \"" & escape(PKG_INSTALL) & "\";",
++ " MAN_INSTALL := \"" & escape(MAN_INSTALL) & "\";",
++ " EMACS_INSTALL := \"" & escape(EMACS_INSTALL) & "\";",
++ " HTML_INSTALL := \"" & escape(HTML_INSTALL) & "\";",
++ "",
++ " BIN_USE := \"" & escape(BIN_USE) & "\";",
++ " LIB_USE := \"" & escape(LIB_USE) & "\";",
++ " DOC_USE := \"" & escape(DOC_INSTALL) & "\";",
++ " PKG_USE := \"" & escape(PKG_USE) & "\";",
++ " MAN_USE := \"" & escape(MAN_INSTALL) & "\";",
++ " EMACS_USE := \"" & escape(EMACS_INSTALL) & "\";",
++ " HTML_USE := \"" & escape(HTML_INSTALL) & "\";",
++ "END M3ConfigVars."
++]
++
++if defined("_all")
++ > ".M3ConfigVars.m3" in
++ foreach line in M3ConfigVars_body
++ write (line, CR)
++ end
++ end
++ cp_if (".M3ConfigVars.m3", "M3ConfigVars.m3")
++end
++
++import ("m3core")
++interface ("M3ConfigVars")
++derived_implementation ("M3ConfigVars")
++export_interface ("M3ConfigVars")
++library ("m3configvars")
diff --git a/lang/modula-3-lib/files/patch-ar b/lang/modula-3-lib/files/patch-ar
new file mode 100644
index 000000000000..6622237dce1a
--- /dev/null
+++ b/lang/modula-3-lib/files/patch-ar
@@ -0,0 +1,50 @@
+This patch modifies m3browser to use the new "m3configvars" package.
+
+Index: m3/m3browser/src/Main.m3
+===================================================================
+--- Main.m3.orig Mon Feb 5 10:49:57 1996
++++ Main.m3 Tue Sep 24 15:39:45 1996
+@@ -13,13 +13,12 @@
+
+ IMPORT Text, Rd, Wr, TextRd, Thread, Time, Fmt, IntRefTbl, IntList;
+ IMPORT Process, Params, Lex, OS, FloatMode, Word, IntIntTbl, TextIntTbl;
+-IMPORT FileWr, OSError, Atom, FmtTime, M3Config, RTParams, RTCollector;
++IMPORT FileWr, OSError, Atom, FmtTime, M3ConfigVars, RTParams, RTCollector;
+ IMPORT FS, RefList, IntSeq, XFormat, RefSeq, TextRefTbl, CharMap, IP;
+ IMPORT Buf, ID, Wx, MarkUp, CMarkUp, TCPServer, ErrLog, RTutils, RTHeapStats;
+
+ CONST
+ Title_page = "m3browser.html";
+- SLASH = M3Config.PATH_SEP;
+ StartPage = "<HTML>\n<HEAD>\n";
+ StartTitle = "<TITLE>";
+ Body = "<BODY BGCOLOR=\"#ffffff\" VLINK=\"#006633\">\n";
+@@ -28,10 +27,11 @@
+ EndPage = "</BODY>\n</HTML>\n";
+
+ VAR (* configuration *)
+- package_root := M3Config.PKG_USE;
++ SLASH := M3ConfigVars.PATH_SEP;
++ package_root := M3ConfigVars.PKG_USE;
+ server_machine : TEXT; (* initialized in "ParseOptions" *)
+ server_socket := 3829;
+- derived_dirs := IntList.List1 (ID.Add (M3Config.BUILD_DIR));
++ derived_dirs := IntList.List1 (ID.Add (M3ConfigVars.BUILD_DIR));
+ n_workers := 3;
+ refresh_interval := 30.0d0; (* minutes *)
+ start_time := Time.Now ();
+Index: m3/m3browser/src/m3makefile
+===================================================================
+RCS file: /home/jdp/m3-cvs/m3/m3browser/src/m3makefile,v
+retrieving revision 1.1.1.1
+diff -u -r1.1.1.1 m3makefile
+--- m3makefile 1996/09/24 05:21:56 1.1.1.1
++++ m3makefile 1996/09/24 05:32:39
+@@ -6,6 +6,7 @@
+
+ m3_option ("-times")
+
++import ("m3configvars")
+ import ("libm3")
+ import ("tcp")
+ import ("m3tools")
diff --git a/lang/modula-3-lib/files/patch-at b/lang/modula-3-lib/files/patch-at
new file mode 100644
index 000000000000..b17d1961a162
--- /dev/null
+++ b/lang/modula-3-lib/files/patch-at
@@ -0,0 +1,70 @@
+Changes to "m3tohtml" to use the new "m3configvars" package.
+
+Index: m3/m3tohtml/src/Main.m3
+===================================================================
+RCS file: /home/jdp/m3-cvs/m3/m3tohtml/src/Main.m3,v
+retrieving revision 1.1.1.1
+diff -u -r1.1.1.1 Main.m3
+--- Main.m3 1996/09/24 05:22:00 1.1.1.1
++++ Main.m3 1996/09/24 05:32:40
+@@ -7,7 +7,7 @@
+ MODULE Main;
+
+ IMPORT Text, Rd, Wr, Stdio, Thread, Fmt, Time;
+-IMPORT OSError, FileRd, FileWr, Pathname, FS, M3Config;
++IMPORT OSError, FileRd, FileWr, Pathname, FS, M3ConfigVars;
+ IMPORT MarkUp, M3DB, HTMLDir, FilePath, Process;
+ <*FATAL Thread.Alerted*>
+
+@@ -31,8 +31,8 @@
+ WHILE NOT Rd.EOF (rd) DO
+ file := Rd.GetLine (rd);
+ IF Text.GetChar (file, 0) = '$' THEN
+- pkg := Text.Sub (file, 1) & M3Config.PATH_SEP;
+- proj_pkg := M3Config.PKG_USE & M3Config.PATH_SEP & pkg;
++ pkg := Text.Sub (file, 1) & M3ConfigVars.PATH_SEP;
++ proj_pkg := M3ConfigVars.PKG_USE & M3ConfigVars.PATH_SEP & pkg;
+ ELSE
+ INC (n_sources);
+ sources := NEW (Source, next := sources,
+@@ -53,7 +53,7 @@
+ sources := b;
+ END ReadFileList;
+
+-VAR(*CONST*) Build_dir_len := Text.Length (M3Config.BUILD_DIR);
++VAR(*CONST*) Build_dir_len := Text.Length (M3ConfigVars.BUILD_DIR);
+
+ PROCEDURE FixDerived (filename: TEXT): TEXT =
+ VAR i: INTEGER;
+@@ -64,13 +64,14 @@
+
+ i := 0;
+ WHILE (i < Build_dir_len) DO
+- IF Text.GetChar (filename, i) # Text.GetChar (M3Config.BUILD_DIR, i) THEN
++ IF Text.GetChar (filename, i) # Text.GetChar (M3ConfigVars.BUILD_DIR, i)
++ THEN
+ RETURN filename;
+ END;
+ INC (i);
+ END;
+
+- IF Text.GetChar (filename, i) = Text.GetChar (M3Config.PATH_SEP, 0) THEN
++ IF Text.GetChar (filename, i) = Text.GetChar (M3ConfigVars.PATH_SEP, 0) THEN
+ filename := "derived" & Text.Sub (filename, i);
+ END;
+ RETURN filename;
+Index: m3/m3tohtml/src/m3makefile
+===================================================================
+RCS file: /home/jdp/m3-cvs/m3/m3tohtml/src/m3makefile,v
+retrieving revision 1.1.1.2
+diff -u -r1.1.1.2 m3makefile
+--- m3makefile 1996/09/24 05:29:00 1.1.1.2
++++ m3makefile 1996/09/24 05:35:10
+@@ -10,6 +10,7 @@
+ % m3_option ("-Y0@/udir/kalsow/pkg/m3/compiler/DS/m3c@-tDS3100@")
+ % override (m3tools, "/udir/kalsow/pkgs")
+
++import ("m3configvars")
+ import ("libm3")
+ import ("m3tools")
+
diff --git a/lang/modula-3-lib/files/patch-av b/lang/modula-3-lib/files/patch-av
new file mode 100644
index 000000000000..9842019c000c
--- /dev/null
+++ b/lang/modula-3-lib/files/patch-av
@@ -0,0 +1,418 @@
+Fix many incorrect things in the Usocket interface for FreeBSD.
+Also make provisions for using SOCKS.
+
+Index: m3/m3core/src/unix/freebsd-2/Usocket.i3
+--- Usocket.i3.orig Sat Jan 7 14:22:22 1995
++++ Usocket.i3 Thu Oct 24 16:04:43 1996
+@@ -30,28 +30,30 @@
+ (*
+ * Option flags per-socket.
+ *)
+- SO_DEBUG = 1; (* turn on debugging info recording *)
+- SO_REUSEADDR = 2; (* allow local address reuse *)
+- SO_TYPE = 3; (* get socket type *)
+- SO_ERROR = 4; (* get error status and clear *)
+- SO_DONTROUTE = 5; (* just use interface addresses *)
+- SO_BROADCAST = 6; (* permit sending of broadcast msgs *)
+- SO_SNDBUF = 7; (* send buffer size *)
+- SO_RCVBUF = 8; (* receive buffer size *)
+- SO_KEEPALIVE = 9; (* keep connections alive *)
+- SO_OOBINLINE = 10; (* leave received OOB data in line *)
+- SO_NO_CHECK = 11;
+- SO_PRIORITY = 12;
+- SO_LINGER = 13; (* linger on close if data present *)
++ SO_DEBUG = 16_0001; (* turn on debugging info recording *)
++ SO_ACCEPTCONN = 16_0002; (* socket has had listen() *)
++ SO_REUSEADDR = 16_0004; (* allow local address reuse *)
++ SO_KEEPALIVE = 16_0008; (* keep connections alive *)
++ SO_DONTROUTE = 16_0010; (* just use interface addresses *)
++ SO_BROADCAST = 16_0020; (* permit sending of broadcast msgs *)
++ SO_USELOOPBACK = 16_0040; (* bypass hardware when possible *)
++ SO_LINGER = 16_0080; (* linger on close if data present *)
++ SO_OOBINLINE = 16_0100; (* leave received OOB data in line *)
++ SO_REUSEPORT = 16_0200; (* allow local address & port reuse *)
++ SO_TIMESTAMP = 16_0400; (* timestamp received dgram traffic *)
+
+ (*
+ * Additional options, not kept in so_options.
+ *)
+- (* these constants may not be implemented - be careful *)
+- SO_SNDLOWAT = 16_1003; (* send low-water mark *)
+- SO_RCVLOWAT = 16_1004; (* receive low-water mark *)
+- SO_SNDTIMEO = 16_1005; (* send timeout *)
+- SO_RCVTIMEO = 16_1006; (* receive timeout *)
++ SO_SNDBUF = 16_1001; (* send buffer size *)
++ SO_RCVBUF = 16_1002; (* receive buffer size *)
++ SO_SNDLOWAT = 16_1003; (* send low-water mark *)
++ SO_RCVLOWAT = 16_1004; (* receive low-water mark *)
++ SO_SNDTIMEO = 16_1005; (* send timeout *)
++ SO_RCVTIMEO = 16_1006; (* receive timeout *)
++ SO_ERROR = 16_1007; (* get error status and clear *)
++ SO_TYPE = 16_1008; (* get socket type *)
++ SO_PRIVSTATE = 16_1009; (* get/deny privileged state *)
+
+ (*
+ * Structure used for manipulating linger option.
+@@ -67,38 +69,45 @@
+ * Level number for (get/set)sockopt() to apply to socket itself.
+ *)
+ CONST
+- SOL_SOCKET = 1; (* options for socket level *)
++ SOL_SOCKET = 16_ffff; (* options for socket level *)
+
+
+ (*
+ * Address families.
+ *)
+- AF_UNSPEC = 0; (* unspecified *)
+- AF_UNIX = 1; (* local to host (pipes, portals) *)
+- AF_INET = 2; (* internetwork: UDP, TCP, etc. *)
+- AF_AX25 = 3;
+- AF_IPX = 4;
+-
+- AF_MAX = 5;
+-
+-(*****
+- AF_IMPLINK = 3; (* arpanet imp addresses *)
+- AF_PUP = 4; (* pup protocols: e.g. BSP *)
+- AF_CHAOS = 5; (* mit CHAOS protocols *)
+- AF_NS = 6; (* XEROX NS protocols *)
+- AF_NBS = 7; (* nbs protocols *)
+- AF_ECMA = 8; (* european computer manufacturers *)
+- AF_DATAKIT = 9; (* datakit protocols *)
+- AF_CCITT = 10; (* CCITT protocols, X.25 etc *)
+- AF_SNA = 11; (* IBM SNA *)
+- AF_DECnet = 12; (* DECnet *)
+- AF_DLI = 13; (* Direct data link interface *)
+- AF_LAT = 14; (* LAT *)
+- AF_HYLINK = 15; (* NSC Hyperchannel *)
+- AF_APPLETALK = 16; (* Apple talk *)
+- AF_BSC = 17; (* BISYNC 2780/3780 *)
+- AF_DSS = 18; (* Distributed system services *)
+-*******)
++ AF_UNSPEC = 0; (* unspecified *)
++ AF_LOCAL = 1; (* local to host (pipes, portals) *)
++ AF_UNIX = AF_LOCAL; (* backward compatibility *)
++ AF_INET = 2; (* internetwork: UDP, TCP, etc. *)
++ AF_IMPLINK = 3; (* arpanet imp addresses *)
++ AF_PUP = 4; (* pup protocols: e.g. BSP *)
++ AF_CHAOS = 5; (* mit CHAOS protocols *)
++ AF_NS = 6; (* XEROX NS protocols *)
++ AF_ISO = 7; (* ISO protocols *)
++ AF_OSI = AF_ISO;
++ AF_ECMA = 8; (* European computer manufacturers *)
++ AF_DATAKIT = 9; (* datakit protocols *)
++ AF_CCITT = 10; (* CCITT protocols, X.25 etc *)
++ AF_SNA = 11; (* IBM SNA *)
++ AF_DECnet = 12; (* DECnet *)
++ AF_DLI = 13; (* DEC Direct data link interface *)
++ AF_LAT = 14; (* LAT *)
++ AF_HYLINK = 15; (* NSC Hyperchannel *)
++ AF_APPLETALK = 16; (* Apple Talk *)
++ AF_ROUTE = 17; (* Internal Routing Protocol *)
++ AF_LINK = 18; (* Link layer interface *)
++ pseudo_AF_XTP = 19; (* eXpress Transfer Protocol (no AF) *)
++ AF_COIP = 20; (* connection-oriented IP, aka ST II *)
++ AF_CNT = 21; (* Computer Network Technology *)
++ pseudo_AF_RTIP = 22; (* Help Identify RTIP packets *)
++ AF_IPX = 23; (* Novell Internet Protocol *)
++ AF_SIP = 24; (* Simple Internet Protocol *)
++ pseudo_AF_PIP = 25; (* Help Identify PIP packets *)
++ AF_ISDN = 26; (* Integrated Services Digital Network*)
++ AF_E164 = AF_ISDN; (* CCITT E.164 recommendation *)
++ pseudo_AF_KEY = 27; (* Internal key-management function *)
++
++ AF_MAX = 28;
+
+ (*
+ * Structure used by kernel to store most
+@@ -106,9 +115,9 @@
+ *)
+ TYPE
+ struct_sockaddr = RECORD
+- sa_family: Ctypes.unsigned_short; (* address family *)
+- sa_data: ARRAY [0..13] OF Ctypes.char;
+- (* up to 14 bytes of direct address *)
++ sa_len: Ctypes.unsigned_char; (* total length *)
++ sa_family: Ctypes.unsigned_char; (* address family *)
++ sa_data: ARRAY [0..13] OF Ctypes.char; (* address; actually longer *)
+ END;
+
+
+@@ -116,7 +125,6 @@
+ * Structure used by kernel to pass protocol
+ * information in raw sockets.
+ *)
+- (* Can't find this one either .. be careful *)
+ struct_sockproto = RECORD
+ sp_family: Ctypes.unsigned_short; (* address family *)
+ sp_protocol: Ctypes.unsigned_short; (* protocol *)
+@@ -126,75 +134,101 @@
+ * Protocol families, same as address families for now.
+ *)
+ CONST
++ PF_UNSPEC = AF_UNSPEC;
++ PF_LOCAL = AF_LOCAL;
++ PF_UNIX = PF_LOCAL; (* backward compatibility *)
++ PF_INET = AF_INET;
++ PF_IMPLINK = AF_IMPLINK;
++ PF_PUP = AF_PUP;
++ PF_CHAOS = AF_CHAOS;
++ PF_NS = AF_NS;
++ PF_ISO = AF_ISO;
++ PF_OSI = AF_ISO;
++ PF_ECMA = AF_ECMA;
++ PF_DATAKIT = AF_DATAKIT;
++ PF_CCITT = AF_CCITT;
++ PF_SNA = AF_SNA;
++ PF_DECnet = AF_DECnet;
++ PF_DLI = AF_DLI;
++ PF_LAT = AF_LAT;
++ PF_HYLINK = AF_HYLINK;
++ PF_APPLETALK = AF_APPLETALK;
++ PF_ROUTE = AF_ROUTE;
++ PF_LINK = AF_LINK;
++ PF_XTP = pseudo_AF_XTP; (* really just proto family, no AF *)
++ PF_COIP = AF_COIP;
++ PF_CNT = AF_CNT;
++ PF_SIP = AF_SIP;
++ PF_IPX = AF_IPX; (* same format as AF_NS *)
++ PF_RTIP = pseudo_AF_RTIP; (* same format as AF_INET *)
++ PF_PIP = pseudo_AF_PIP;
++ PF_ISDN = AF_ISDN;
++ PF_KEY = pseudo_AF_KEY;
+
+- PF_UNSPEC = AF_UNSPEC;
+- PF_UNIX = AF_UNIX;
+- PF_INET = AF_INET;
+- PF_AX25 = AF_AX25;
+- PF_IPX = AF_IPX;
+-
+- (* NO supported on Linux:
+- PF_IMPLINK = AF_IMPLINK;
+- PF_PUP = AF_PUP;
+- PF_CHAOS = AF_CHAOS;
+- PF_NS = AF_NS;
+- PF_NBS = AF_NBS;
+- PF_ECMA = AF_ECMA;
+- PF_DATAKIT = AF_DATAKIT;
+- PF_CCITT = AF_CCITT;
+- PF_SNA = AF_SNA;
+- PF_DECnet = AF_DECnet;
+- PF_DLI = AF_DLI;
+- PF_LAT = AF_LAT;
+- PF_HYLINK = AF_HYLINK;
+- PF_APPLETALK = AF_APPLETALK;
+- PF_BSC = AF_BSC;
+- PF_DSS = AF_DSS;
+- ************)
+-
+- PF_MAX = AF_MAX;
++ PF_MAX = AF_MAX;
+
+ (*
+ * Maximum queue length specifiable by listen.
+ *)
+- (* Not defined under Linux - be careful *)
+- SOMAXCONN = 5;
++ SOMAXCONN = 128;
+
+ (*
+ * Message header for recvmsg and sendmsg calls.
+ *)
+ TYPE
+- (* Again, I haven't checked this structure *)
+ struct_msghdr = RECORD
+- msg_name: Utypes.caddr_t; (* optional address *)
+- msg_namelen: Ctypes.int; (* size of address *)
+- msg_iov: Uuio.struct_iovec_star; (* scatter/gather array *)
+- msg_iovlen: Ctypes.int; (* # elements in msg_iov *)
+- msg_accrights: Utypes.caddr_t; (* access rights sent/received *)
+- msg_accrightslen: Ctypes.int;
++ msg_name: Utypes.caddr_t; (* optional address *)
++ msg_namelen: Ctypes.unsigned_int; (* size of address *)
++ msg_iov: Uuio.struct_iovec_star; (* scatter/gather array *)
++ msg_iovlen: Ctypes.unsigned_int; (* # elements in msg_iov *)
++ msg_control: Utypes.caddr_t; (* ancillary data, see below *)
++ msg_controllen: Ctypes.unsigned_int; (* ancillary data buffer len *)
++ msg_flags: Ctypes.int; (* flags on received message *)
+ END;
+
+
+ CONST
+- MSG_OOB = 16_1; (* process out-of-band data *)
+- MSG_PEEK = 16_2; (* peek at incoming message *)
+-(* The following aren't defined in /usr/include/linux/socket.h *)
+-(**
+- MSG_DONTROUTE = 16_4; (* send without using routing tables *)
++ MSG_OOB = 16_1; (* process out-of-band data *)
++ MSG_PEEK = 16_2; (* peek at incoming message *)
++ MSG_DONTROUTE = 16_4; (* send without using routing tables *)
++ MSG_EOR = 16_8; (* data completes record *)
++ MSG_TRUNC = 16_10; (* data discarded before delivery *)
++ MSG_CTRUNC = 16_20; (* control data lost before delivery *)
++ MSG_WAITALL = 16_40; (* wait for full request or error *)
++ MSG_DONTWAIT = 16_80; (* this message should be nonblocking *)
++ MSG_EOF = 16_100; (* data completes connection *)
++ MSG_COMPAT = 16_8000; (* used in sendit() *)
++
++(*
++ * Header for ancillary data objects in msg_control buffer.
++ * Used for additional information with/about a datagram
++ * not expressible by flags. The format is a sequence
++ * of message elements headed by cmsghdr structures.
++ *)
++TYPE
++ struct_cmsghdr = RECORD
++ cmsg_len: Ctypes.unsigned_int; (* data byte count, including hdr *)
++ cmsg_level: Ctypes.int; (* originating protocol *)
++ cmsg_type: Ctypes.int; (* protocol-specific type *)
++ (* followed by u_char cmsg_data[]; *)
++ END;
+
+- MSG_MAXIOVLEN = 16;
+-***)
++(* "Socket"-level control message types: *)
++CONST
++ SCM_RIGHTS = 16_01; (* access rights (array of int) *)
++ SCM_TIMESTAMP = 16_02; (* timestamp (struct timeval) *)
+
+ (*
+ * Definitions for UNIX IPC domain.
+ *)
+ TYPE
+ struct_sockaddr_un = RECORD
+- sun_family: Ctypes.unsigned_short; (* AF_UNIX *)
+- sun_path: ARRAY [0..107] OF Ctypes.char; (* path name (gag) *)
++ sun_len: Ctypes.unsigned_char; (* sockaddr len including null *)
++ sun_family: Ctypes.unsigned_char; (* AF_UNIX *)
++ sun_path: ARRAY [0..103] OF Ctypes.char; (* path name (gag) *)
+ END;
+
+-<*EXTERNAL*>
++<*EXTERNAL "m3_accept"*>
+ PROCEDURE accept(
+ s: Ctypes.int;
+ addr: UNTRACED REF struct_sockaddr;
+@@ -202,7 +236,7 @@
+ : Ctypes.int
+ RAISES {};
+
+-<*EXTERNAL*>
++<*EXTERNAL "m3_bind"*>
+ PROCEDURE bind(
+ s: Ctypes.int;
+ name: UNTRACED REF struct_sockaddr;
+@@ -210,7 +244,7 @@
+ : Ctypes.int
+ RAISES {};
+
+-<*EXTERNAL*>
++<*EXTERNAL "m3_connect"*>
+ PROCEDURE connect(
+ s: Ctypes.int;
+ name: UNTRACED REF struct_sockaddr;
+@@ -218,7 +252,7 @@
+ : Ctypes.int
+ RAISES {};
+
+-<*EXTERNAL*>
++<*EXTERNAL "m3_getpeername"*>
+ PROCEDURE getpeername(
+ s: Ctypes.int;
+ name: UNTRACED REF struct_sockaddr;
+@@ -226,7 +260,7 @@
+ : Ctypes.int
+ RAISES {};
+
+-<*EXTERNAL*>
++<*EXTERNAL "m3_getsockname"*>
+ PROCEDURE getsockname(
+ s: Ctypes.int;
+ name: UNTRACED REF struct_sockaddr;
+@@ -237,52 +271,70 @@
+ <*EXTERNAL*>
+ PROCEDURE getsockopt(
+ s, level, optname: Ctypes.int;
+- optval: Ctypes.char_star;
++ optval: Ctypes.void_star;
+ optlen: Ctypes.int_star)
+ : Ctypes.int
+ RAISES {};
+
+-<*EXTERNAL*>
++<*EXTERNAL "m3_listen"*>
+ PROCEDURE listen(s, backlog: Ctypes.int): Ctypes.int RAISES {};
+
+-<*EXTERNAL*>
+-PROCEDURE recv(s: Ctypes.int; buf: Ctypes.char_star; len, flags: Ctypes.int): Ctypes.int RAISES {};
++<*EXTERNAL "m3_recv"*>
++PROCEDURE recv(
++ s: Ctypes.int;
++ buf: Ctypes.void_star;
++ len: Utypes.size_t;
++ flags: Ctypes.int)
++ : Ctypes.int
++ RAISES {};
+
+-<*EXTERNAL*>
++<*EXTERNAL "m3_recvfrom"*>
+ PROCEDURE recvfrom(
+ s: Ctypes.int;
+- buf: Ctypes.char_star;
+- len, flags: Ctypes.int;
++ buf: Ctypes.void_star;
++ len: Utypes.size_t;
++ flags: Ctypes.int;
+ from: UNTRACED REF struct_sockaddr;
+ fromlen: Ctypes.int_star)
+ : Ctypes.int
+ RAISES {};
+
+-<*EXTERNAL*>
+-PROCEDURE send(s: Ctypes.int; msg: Ctypes.char_star; len, flags: Ctypes.int): Ctypes.int RAISES {};
++(* FIXME - recvmsg *)
+
+-<*EXTERNAL*>
++<*EXTERNAL "m3_send"*>
++PROCEDURE send(
++ s: Ctypes.int;
++ msg: Ctypes.const_void_star;
++ len: Utypes.size_t;
++ flags: Ctypes.int)
++ : Ctypes.int
++ RAISES {};
++
++<*EXTERNAL "m3_sendto"*>
+ PROCEDURE sendto(
+ s: Ctypes.int;
+- msg: Ctypes.char_star;
+- len, flags: Ctypes.int;
++ msg: Ctypes.const_void_star;
++ len: Utypes.size_t;
++ flags: Ctypes.int;
+ to: UNTRACED REF struct_sockaddr;
+ tolen: Ctypes.int)
+ : Ctypes.int
+ RAISES {};
+
++(* FIXME - sendmsg *)
++
+ <*EXTERNAL*>
+ PROCEDURE setsockopt(
+ s, level, optname: Ctypes.int;
+- optval: Ctypes.char_star;
++ optval: Ctypes.const_void_star;
+ optlen: Ctypes.int)
+ : Ctypes.int
+ RAISES {};
+
+-<*EXTERNAL*>
++<*EXTERNAL "m3_shutdown"*>
+ PROCEDURE shutdown(s, how: Ctypes.int): Ctypes.int RAISES {};
+
+-<*EXTERNAL*>
++<*EXTERNAL "m3_socket" *>
+ PROCEDURE socket(af, type, protocol: Ctypes.int): Ctypes.int RAISES {};
+
+ <*EXTERNAL*>
diff --git a/lang/modula-3-lib/files/patch-aw b/lang/modula-3-lib/files/patch-aw
new file mode 100644
index 000000000000..59c8ba9c509b
--- /dev/null
+++ b/lang/modula-3-lib/files/patch-aw
@@ -0,0 +1,44 @@
+Fix some things in the Uin interface for FreeBSD. Most important is the
+change to "struct_sockaddr_in".
+
+Index: m3/m3core/src/unix/freebsd-2/Uin.i3
+===================================================================
+RCS file: /home/jdp/m3-cvs/m3/m3core/src/unix/freebsd-2/Uin.i3,v
+retrieving revision 1.1.1.1
+diff -u -r1.1.1.1 Uin.i3
+--- Uin.i3 1996/09/24 05:22:00 1.1.1.1
++++ Uin.i3 1996/09/24 05:32:41
+@@ -8,7 +8,7 @@
+
+ INTERFACE Uin;
+
+-FROM Ctypes IMPORT short, char;
++FROM Ctypes IMPORT char;
+ FROM Utypes IMPORT u_char, u_short, u_long;
+ IMPORT Word;
+
+@@ -25,9 +25,12 @@
+ IPPROTO_PUP = 12; (* pup *)
+ IPPROTO_UDP = 17; (* user datagram protocol *)
+ IPPROTO_IDP = 22; (* xns idp *)
+- IPPROTO_HELLO = 63; (* "hello" routing protocol *)
+- IPPROTO_ND = 77; (* UNOFFICIAL net disk proto *)
++ IPPROTO_TP = 29; (* tp-4 w/ class negotiation *)
++ IPPROTO_RSVP = 46; (* resource reservation *)
++ IPPROTO_EON = 80; (* ISO cnlp *)
++ IPPROTO_ENCAP = 98; (* encapsulation header *)
+
++ IPPROTO_DIVERT = 254; (* divert pseudo-protocol *)
+ IPPROTO_RAW = 255; (* raw IP packet *)
+ IPPROTO_MAX = 256;
+
+@@ -128,7 +131,8 @@
+ (* Socket address, internet style. *)
+ TYPE
+ struct_sockaddr_in = RECORD
+- sin_family: short;
++ sin_len: u_char;
++ sin_family: u_char;
+ sin_port: u_short;
+ sin_addr: struct_in_addr;
+ sin_zero: ARRAY [0..7] OF char;
diff --git a/lang/modula-3-lib/files/patch-ax b/lang/modula-3-lib/files/patch-ax
new file mode 100644
index 000000000000..b0d8d88eb8d5
--- /dev/null
+++ b/lang/modula-3-lib/files/patch-ax
@@ -0,0 +1,66 @@
+Correct some errno declarations for FreeBSD.
+
+Index: m3/m3core/src/unix/freebsd-2/Uerror.i3
+===================================================================
+RCS file: /home/jdp/m3-cvs/m3/m3core/src/unix/freebsd-2/Uerror.i3,v
+retrieving revision 1.1.1.1
+diff -u -r1.1.1.1 Uerror.i3
+--- Uerror.i3 1996/09/24 05:22:00 1.1.1.1
++++ Uerror.i3 1996/09/24 05:32:41
+@@ -23,7 +23,7 @@
+ ENOEXEC = 8; (* Exec format error *)
+ EBADF = 9; (* Bad file number *)
+ ECHILD = 10; (* No children *)
+- EAGAIN = 11; (* No more processes *)
++ EDEADLK = 11; (* Resource deadlock avoided *)
+ ENOMEM = 12; (* Not enough core *)
+ EACCES = 13; (* Permission denied *)
+ EFAULT = 14; (* Bad address *)
+@@ -51,7 +51,8 @@
+ ERANGE = 34; (* Result too large *)
+
+ (* non-blocking and interrupt i/o *)
+- EWOULDBLOCK = 35; (* Operation would block *)
++ EAGAIN = 35; (* Resource temporarily unavailable *)
++ EWOULDBLOCK = EAGAIN; (* Operation would block *)
+ EINPROGRESS = 36; (* Operation now in progress *)
+ EALREADY = 37; (* Operation already in progress *)
+
+@@ -108,29 +109,22 @@
+ EPROCUNAVAIL = 76; (* Bad procedure for program *)
+
+ (* POSIX errnos *)
+- ENOLCK = 77; (* LOCK_MAX exceeded *)
+-
+- (* IPC errors *)
+-
+- (* I don't know about the following codes. ow 02.10.1994 *)
+- ENOMSG = 78; (* No message of desired type *)
+- EIDRM = 79; (* Identifier removed *)
+-
+- (* Alignment error of some type (i.e., cluster, page, block ...) *)
+- EALIGN = 80; (* alignment error *)
+-
+- (* System V mappings from BRL package *)
+- EDEADLK = EWOULDBLOCK; (* resource deadlock would occur *)
++ ENOLCK = 77; (* No locks available *)
++ ENOSYS = 78; (* Function not implemented *)
+
++ EFTYPE = 79; (* Inappropriate file type or format *)
++ EAUTH = 80; (* Authentication error *)
++ ENEEDAUTH = 81; (* Need authenticator *)
++ ELAST = 81; (* Must be equal to the largest errno *)
+
+ <*EXTERNAL*>
+ VAR
+ errno: int;
+
+
+-(* Extention by mjordan *)
++(* Extension by mjordan *)
+ CONST
+- Max = ENOLCK; (* should be exported from Uerror *)
++ Max = ELAST; (* should be exported from Uerror *)
+
+ <*EXTERNAL*> VAR
+ sys_nerr: int;
diff --git a/lang/modula-3-lib/files/patch-ay b/lang/modula-3-lib/files/patch-ay
new file mode 100644
index 000000000000..996146918244
--- /dev/null
+++ b/lang/modula-3-lib/files/patch-ay
@@ -0,0 +1,17 @@
+Bugfix from SRC for uninitialized "FS.DirectoryFileType" variable.
+
+Index: m3/libm3/src/os/Common/m3makefile
+===================================================================
+RCS file: /home/jdp/m3-cvs/m3/libm3/src/os/Common/m3makefile,v
+retrieving revision 1.1.1.1
+diff -u -r1.1.1.1 m3makefile
+--- m3makefile 1996/09/24 05:21:55 1.1.1.1
++++ m3makefile 1996/09/24 05:32:42
+@@ -19,6 +19,7 @@
+ Interface(Terminal)
+
+ /* The following only initialize the File.Type variables: */
++implementation(FS)
+ implementation(Terminal)
+ implementation(RegularFile)
+ implementation(Pipe)
diff --git a/lang/modula-3-lib/files/patch-bf b/lang/modula-3-lib/files/patch-bf
new file mode 100644
index 000000000000..fbdd67167eb5
--- /dev/null
+++ b/lang/modula-3-lib/files/patch-bf
@@ -0,0 +1,32 @@
+Fix incorrect layout for the Udir.dirent structure.
+
+Index: m3/m3core/src/unix/freebsd-2/Udir.i3
+===================================================================
+RCS file: /home/jdp/m3-cvs/m3/m3core/src/unix/freebsd-2/Udir.i3,v
+retrieving revision 1.1.1.1
+diff -u -r1.1.1.1 Udir.i3
+--- Udir.i3 1996/09/24 05:22:00 1.1.1.1
++++ Udir.i3 1996/09/24 05:32:44
+@@ -40,10 +40,10 @@
+ *)
+ TYPE
+ dirent = RECORD (* describes directory entry *)
+- d_fileno: Ctypes.long; (* inode number of entry *)
+- d_reclen: Ctypes.unsigned_char; (* record length in bytes *)
++ d_fileno: Ctypes.unsigned_long; (* inode number of entry *)
++ d_reclen: Ctypes.unsigned_short; (* record length in bytes *)
+ d_type: Ctypes.unsigned_char; (* file types, see above *)
+- d_namelen: Ctypes.unsigned_short; (* name length in bytes *)
++ d_namelen: Ctypes.unsigned_char; (* name length in bytes *)
+ d_name: ARRAY [0..MAXNAMLEN] OF Ctypes.char; (* name *)
+ END;
+
+@@ -53,7 +53,7 @@
+ dd_fd: Ctypes.int; (* file descriptor associated with directory *)
+ dd_loc: Ctypes.long; (* offset in current buffer *)
+ dd_size: Ctypes.long; (* amount of data returned by getdirentries *)
+- dd_buf: UNTRACED REF Ctypes.char; (* data buffer *)
++ dd_buf: Ctypes.char_star; (* data buffer *)
+ dd_len: Ctypes.int; (* size of data buffer *)
+ dd_seek: Ctypes.long (* magic cookie returned by getdirentries *);
+ dd_rewind: Ctypes.long; (* magic cookie for rewinding *)
diff --git a/lang/modula-3-lib/files/patch-bg b/lang/modula-3-lib/files/patch-bg
new file mode 100644
index 000000000000..f690786444b6
--- /dev/null
+++ b/lang/modula-3-lib/files/patch-bg
@@ -0,0 +1,1334 @@
+This inserts a thread-safe version of malloc into the "m3core"
+package. It solves some very obscure problems that were caused by
+back-door entries into malloc from <*EXTERNAL*> procedures, without
+locking the heap. These allowed multiple threads to enter the
+malloc package at once, and led to scribbling in memory and subsequent
+core dumps.
+
+This also adds separate wrapper files for network related functions to the
+m3makefile, for SOCKS support.
+
+Index: m3/m3core/src/runtime/FreeBSD2/m3makefile
+--- m3makefile.orig Tue Sep 17 16:48:03 1996
++++ m3makefile Thu Oct 24 16:11:02 1996
+@@ -13,6 +13,30 @@
+ c_source ("RTThreadC")
+ c_source ("RTHeapDepC")
+ s_source ("_fpsetjmp")
++c_source ("malloc")
++
++% These wrappers were extracted from RTHeapDepC.c and modified slightly,
++% in order to make it possible to support SOCKS.
++c_source ("accept")
++c_source ("bind")
++c_source ("close")
++c_source ("connect")
++c_source ("dup")
++c_source ("dup2")
++c_source ("gethostbyaddr")
++c_source ("gethostbyname")
++c_source ("getpeername")
++c_source ("getsockname")
++c_source ("listen")
++c_source ("read")
++c_source ("recv")
++c_source ("recvfrom")
++c_source ("select")
++c_source ("send")
++c_source ("sendto")
++c_source ("shutdown")
++c_source ("socket")
++c_source ("write")
+
+ %% s_source (RTStackASM)
+
+Index: m3/m3core/src/runtime/FreeBSD2/malloc.c
+--- malloc.c.orig Mon Oct 28 20:16:48 1996
++++ malloc.c Tue Oct 29 08:57:53 1996
+@@ -0,0 +1,1286 @@
++/*
++ * ----------------------------------------------------------------------------
++ * "THE BEER-WARE LICENSE" (Revision 42):
++ * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
++ * can do whatever you want with this stuff. If we meet some day, and you think
++ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
++ * ----------------------------------------------------------------------------
++ *
++ * From FreeBSD: malloc.c,v 1.15 1996/09/25 16:29:15 sos Exp
++ * Modified for Modula-3 thread-safety by jdp@polstra.com (John Polstra).
++ *
++ */
++
++/*
++ * Defining M3_THREAD_SAFE will enable the hooks into the Modula-3 runtime
++ * to permit thread-safe operation with that language system. Do that if
++ * you want to use this malloc as part of the "m3core" package.
++ *
++ * If you define M3_THREAD_SAFE, then do not define _THREAD_SAFE,
++ * which enables the pthreads tie-ins. They are mutually-exclusive.
++ */
++#define M3_THREAD_SAFE
++
++/*
++ * Defining EXTRA_SANITY will enable extra checks which are related
++ * to internal conditions and consistency in malloc.c. This has a
++ * noticeable runtime performance hit, and generally will not do you
++ * any good unless you fiddle with the internals of malloc or want
++ * to catch random pointer corruption as early as possible.
++ */
++#undef EXTRA_SANITY
++
++/*
++ * Defining MALLOC_STATS will enable you to call malloc_dump() and set
++ * the [dD] options in the MALLOC_OPTIONS environment variable.
++ * It has no run-time performance hit.
++ */
++#define MALLOC_STATS
++
++#if defined(EXTRA_SANITY) && !defined(MALLOC_STATS)
++# define MALLOC_STATS /* required for EXTRA_SANITY */
++#endif
++
++/*
++ * What to use for Junk. This is the byte value we use to fill with
++ * when the 'J' option is enabled.
++ */
++#define SOME_JUNK 0xd0 /* as in "Duh" :-) */
++
++/*
++ * If these weren't defined here, they would be calculated on the fly,
++ * with a noticeable performance hit.
++ */
++#if defined(__i386__) && defined(__FreeBSD__)
++# define malloc_pagesize 4096U
++# define malloc_pageshift 12U
++# define malloc_minsize 16U
++# define malloc_maxsize ((malloc_pagesize)>>1)
++#endif /* __i386__ && __FreeBSD__ */
++
++/*
++ * No user serviceable parts behind this point.
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <errno.h>
++#include <sys/types.h>
++#include <sys/mman.h>
++
++#if 0 /* Disable the utrace stuff { */
++#ifdef __FreeBSD__ /* Kludge to find out whether we have utrace() */
++#include <sys/syscall.h>
++#ifdef SYS_utrace
++#define HAVE_UTRACE
++#endif /* SYS_utrace */
++#endif /* __FreeBSD__ */
++#endif /* } 0 */
++
++/*
++ * This structure describes a page worth of chunks.
++ */
++
++struct pginfo {
++ struct pginfo *next; /* next on the free list */
++ void *page; /* Pointer to the page */
++ u_short size; /* size of this page's chunks */
++ u_short shift; /* How far to shift for this size chunks */
++ u_short free; /* How many free chunks */
++ u_short total; /* How many chunk */
++ u_long bits[1]; /* Which chunks are free */
++};
++
++/*
++ * This structure describes a number of free pages.
++ */
++
++struct pgfree {
++ struct pgfree *next; /* next run of free pages */
++ struct pgfree *prev; /* prev run of free pages */
++ void *page; /* pointer to free pages */
++ void *end; /* pointer to end of free pages */
++ u_long size; /* number of bytes free */
++};
++
++/*
++ * How many bits per u_long in the bitmap.
++ * Change only if not 8 bits/byte
++ */
++#define MALLOC_BITS (8*sizeof(u_long))
++
++/*
++ * Magic values to put in the page_directory
++ */
++#define MALLOC_NOT_MINE ((struct pginfo*) 0)
++#define MALLOC_FREE ((struct pginfo*) 1)
++#define MALLOC_FIRST ((struct pginfo*) 2)
++#define MALLOC_FOLLOW ((struct pginfo*) 3)
++#define MALLOC_MAGIC ((struct pginfo*) 4)
++
++/*
++ * The i386 architecture has some very convenient instructions.
++ * We might as well use them. There are C-language backups, but
++ * they are considerably slower.
++ */
++#if defined(__i386__) && defined(__GNUC__)
++#define ffs _ffs
++static __inline__ int
++_ffs(unsigned input)
++{
++ int result;
++ __asm__("bsfl %1, %0" : "=r" (result) : "r" (input));
++ return result+1;
++}
++
++#define fls _fls
++static __inline__ int
++_fls(unsigned input)
++{
++ int result;
++ __asm__("bsrl %1, %0" : "=r" (result) : "r" (input));
++ return result+1;
++}
++
++#define set_bit _set_bit
++static __inline__ void
++_set_bit(struct pginfo *pi, int bit)
++{
++ __asm__("btsl %0, (%1)" :
++ : "r" (bit & (MALLOC_BITS-1)), "r" (pi->bits+(bit/MALLOC_BITS)));
++}
++
++#define clr_bit _clr_bit
++static __inline__ void
++_clr_bit(struct pginfo *pi, int bit)
++{
++ __asm__("btcl %0, (%1)" :
++ : "r" (bit & (MALLOC_BITS-1)), "r" (pi->bits+(bit/MALLOC_BITS)));
++}
++
++#endif /* __i386__ && __GNUC__ */
++
++/*
++ * Set to one when malloc_init has been called
++ */
++static unsigned initialized;
++
++/*
++ * The size of a page.
++ * Must be a integral multiplum of the granularity of mmap(2).
++ * Your toes will curl if it isn't a power of two
++ */
++#ifndef malloc_pagesize
++static unsigned malloc_pagesize;
++#endif /* malloc_pagesize */
++
++/* A mask for the offset inside a page. */
++#define malloc_pagemask ((malloc_pagesize)-1)
++
++#define pageround(foo) (((foo) + (malloc_pagemask))&(~(malloc_pagemask)))
++#define ptr2index(foo) (((u_long)(foo) >> malloc_pageshift)-malloc_origo)
++
++/* malloc_pagesize == 1 << malloc_pageshift */
++#ifndef malloc_pageshift
++static unsigned malloc_pageshift;
++#endif /* malloc_pageshift */
++
++/*
++ * The smallest allocation we bother about.
++ * Must be power of two
++ */
++#ifndef malloc_minsize
++static unsigned malloc_minsize;
++#endif /* malloc_minsize */
++
++/*
++ * The largest chunk we care about.
++ * Must be smaller than pagesize
++ * Must be power of two
++ */
++#ifndef malloc_maxsize
++static unsigned malloc_maxsize;
++#endif /* malloc_maxsize */
++
++/* The minimum size (in pages) of the free page cache. */
++static unsigned malloc_cache = 16;
++
++/* The offset from pagenumber to index into the page directory */
++static u_long malloc_origo;
++
++/* The last index in the page directory we care about */
++static u_long last_index;
++
++/* Pointer to page directory. Allocated "as if with" malloc */
++static struct pginfo **page_dir;
++
++/* How many slots in the page directory */
++static unsigned malloc_ninfo;
++
++/* Free pages line up here */
++static struct pgfree free_list;
++
++/* Abort(), user doesn't handle problems. */
++static int malloc_abort;
++
++/* Are we trying to die ? */
++static int suicide;
++
++#ifdef MALLOC_STATS
++/* dump statistics */
++static int malloc_stats;
++#endif /* MALLOC_STATS */
++
++/* always realloc ? */
++static int malloc_realloc;
++
++/* pass the kernel a hint on free pages ? */
++static int malloc_hint;
++
++/* zero fill ? */
++static int malloc_zero;
++
++/* junk fill ? */
++static int malloc_junk;
++
++#ifdef HAVE_UTRACE
++/* utrace ? */
++static int malloc_utrace;
++
++struct ut { void *p; size_t s; void *r; };
++
++#define UTRACE(a, b, c) \
++ if (malloc_utrace) \
++ {struct ut u; u.p=a; u.s = b; u.r=c; utrace(&u, sizeof u);}
++#else /* !HAVE_UTRACE */
++#define UTRACE(a,b,c)
++#endif /* HAVE_UTRACE */
++
++/* my last break. */
++static void *malloc_brk;
++
++/* one location cache for free-list holders */
++static struct pgfree *px;
++
++/* compile-time options */
++char *malloc_options;
++
++/*
++ * Necessary function declarations
++ */
++static int extend_pgdir(u_long index);
++static void *imalloc(size_t size);
++static void ifree(void *ptr);
++static void *irealloc(void *ptr, size_t size);
++
++#ifdef MALLOC_STATS
++void
++malloc_dump(FILE *fd)
++{
++ struct pginfo **pd;
++ struct pgfree *pf;
++ int j;
++
++ pd = page_dir;
++
++ /* print out all the pages */
++ for(j=0;j<=last_index;j++) {
++ fprintf(fd, "%08lx %5d ", (j+malloc_origo) << malloc_pageshift, j);
++ if (pd[j] == MALLOC_NOT_MINE) {
++ for(j++;j<=last_index && pd[j] == MALLOC_NOT_MINE;j++)
++ ;
++ j--;
++ fprintf(fd, ".. %5d not mine\n", j);
++ } else if (pd[j] == MALLOC_FREE) {
++ for(j++;j<=last_index && pd[j] == MALLOC_FREE;j++)
++ ;
++ j--;
++ fprintf(fd, ".. %5d free\n", j);
++ } else if (pd[j] == MALLOC_FIRST) {
++ for(j++;j<=last_index && pd[j] == MALLOC_FOLLOW;j++)
++ ;
++ j--;
++ fprintf(fd, ".. %5d in use\n", j);
++ } else if (pd[j] < MALLOC_MAGIC) {
++ fprintf(fd, "(%p)\n", pd[j]);
++ } else {
++ fprintf(fd, "%p %d (of %d) x %d @ %p --> %p\n",
++ pd[j], pd[j]->free, pd[j]->total,
++ pd[j]->size, pd[j]->page, pd[j]->next);
++ }
++ }
++
++ for(pf=free_list.next; pf; pf=pf->next) {
++ fprintf(fd, "Free: @%p [%p...%p[ %ld ->%p <-%p\n",
++ pf, pf->page, pf->end, pf->size, pf->prev, pf->next);
++ if (pf == pf->next) {
++ fprintf(fd, "Free_list loops.\n");
++ break;
++ }
++ }
++
++ /* print out various info */
++ fprintf(fd, "Minsize\t%d\n", malloc_minsize);
++ fprintf(fd, "Maxsize\t%d\n", malloc_maxsize);
++ fprintf(fd, "Pagesize\t%d\n", malloc_pagesize);
++ fprintf(fd, "Pageshift\t%d\n", malloc_pageshift);
++ fprintf(fd, "FirstPage\t%ld\n", malloc_origo);
++ fprintf(fd, "LastPage\t%ld %lx\n", last_index+malloc_pageshift,
++ (last_index + malloc_pageshift) << malloc_pageshift);
++ fprintf(fd, "Break\t%ld\n", (u_long)sbrk(0) >> malloc_pageshift);
++}
++#endif /* MALLOC_STATS */
++
++static char *malloc_func;
++
++static void
++wrterror(char *p)
++{
++ char *q = "Malloc error: ";
++ suicide = 1;
++ write(2, q, strlen(q));
++ write(2, malloc_func, strlen(malloc_func));
++ write(2, p, strlen(p));
++#ifdef MALLOC_STATS
++ if (malloc_stats)
++ malloc_dump(stderr);
++#endif /* MALLOC_STATS */
++ abort();
++}
++
++static void
++wrtwarning(char *p)
++{
++ char *q = "Malloc warning: ";
++ if (malloc_abort)
++ wrterror(p);
++ write(2, q, strlen(q));
++ write(2, malloc_func, strlen(malloc_func));
++ write(2, p, strlen(p));
++}
++
++#ifdef EXTRA_SANITY
++static void
++malloc_exit()
++{
++ FILE *fd = fopen("malloc.out", "a");
++ char *q = "malloc() warning: Couldn't dump stats.\n";
++ if (fd) {
++ malloc_dump(fd);
++ fclose(fd);
++ } else
++ write(2, q, strlen(q));
++}
++#endif /* EXTRA_SANITY */
++
++
++/*
++ * Allocate a number of pages from the OS
++ */
++static caddr_t
++map_pages(int pages)
++{
++ caddr_t result, tail;
++
++ result = (caddr_t)pageround((u_long)sbrk(0));
++ tail = result + (pages << malloc_pageshift);
++
++ if (brk(tail)) {
++#ifdef EXTRA_SANITY
++ wrterror("(ES): map_pages fails\n");
++#endif /* EXTRA_SANITY */
++ return 0;
++ }
++
++ last_index = ptr2index(tail) - 1;
++ malloc_brk = tail;
++
++ if ((last_index+1) >= malloc_ninfo && !extend_pgdir(last_index))
++ return 0;;
++
++ return result;
++}
++
++/*
++ * Set a bit in the bitmap
++ */
++#ifndef set_bit
++static __inline__ void
++set_bit(struct pginfo *pi, int bit)
++{
++ pi->bits[bit/MALLOC_BITS] |= 1<<(bit%MALLOC_BITS);
++}
++#endif /* set_bit */
++
++/*
++ * Clear a bit in the bitmap
++ */
++#ifndef clr_bit
++static __inline__ void
++clr_bit(struct pginfo *pi, int bit)
++{
++ pi->bits[bit/MALLOC_BITS] &= ~(1<<(bit%MALLOC_BITS));
++}
++#endif /* clr_bit */
++
++#ifndef tst_bit
++/*
++ * Test a bit in the bitmap
++ */
++static __inline__ int
++tst_bit(struct pginfo *pi, int bit)
++{
++ return pi->bits[bit/MALLOC_BITS] & (1<<(bit%MALLOC_BITS));
++}
++#endif /* tst_bit */
++
++/*
++ * Find last bit
++ */
++#ifndef fls
++static __inline__ int
++fls(int size)
++{
++ int i = 1;
++ while (size >>= 1)
++ i++;
++ return i;
++}
++#endif /* fls */
++
++/*
++ * Extend page directory
++ */
++static int
++extend_pgdir(u_long index)
++{
++ struct pginfo **new, **old;
++ int i, oldlen;
++
++ /* Make it this many pages */
++ i = index * sizeof *page_dir;
++ i /= malloc_pagesize;
++ i += 2;
++
++ /* remember the old mapping size */
++ oldlen = malloc_ninfo * sizeof *page_dir;
++
++ /*
++ * NOTE: we allocate new pages and copy the directory rather than tempt
++ * fate by trying to "grow" the region.. There is nothing to prevent
++ * us from accidently re-mapping space that's been allocated by our caller
++ * via dlopen() or other mmap().
++ *
++ * The copy problem is not too bad, as there is 4K of page index per
++ * 4MB of malloc arena.
++ *
++ * We can totally avoid the copy if we open a file descriptor to associate
++ * the anon mappings with. Then, when we remap the pages at the new
++ * address, the old pages will be "magically" remapped.. But this means
++ * keeping open a "secret" file descriptor.....
++ */
++
++ /* Get new pages */
++ new = (struct pginfo**) mmap(0, i * malloc_pagesize, PROT_READ|PROT_WRITE,
++ MAP_ANON|MAP_PRIVATE, -1, 0);
++ if (new == (struct pginfo **)-1)
++ return 0;
++
++ /* Copy the old stuff */
++ memcpy(new, page_dir,
++ malloc_ninfo * sizeof *page_dir);
++
++ /* register the new size */
++ malloc_ninfo = i * malloc_pagesize / sizeof *page_dir;
++
++ /* swap the pointers */
++ old = page_dir;
++ page_dir = new;
++
++ /* Now free the old stuff */
++ munmap((caddr_t)old, oldlen);
++ return 1;
++}
++
++/*
++ * Initialize the world
++ */
++static void
++malloc_init ()
++{
++ char *p, b[64];
++ int i, j;
++
++
++#ifdef EXTRA_SANITY
++ malloc_junk = 1;
++#endif /* EXTRA_SANITY */
++
++ for (i = 0; i < 3; i++) {
++ if (i == 0) {
++ j = readlink("/etc/malloc.conf", b, sizeof b - 1);
++ if (j <= 0)
++ continue;
++ b[j] = '\0';
++ p = b;
++ } else if (i == 1) {
++ p = getenv("MALLOC_OPTIONS");
++ } else if (i == 2) {
++ p = malloc_options;
++ }
++ for (; p && *p; p++) {
++ switch (*p) {
++ case '>': malloc_cache <<= 1; break;
++ case '<': malloc_cache >>= 1; break;
++ case 'a': malloc_abort = 0; break;
++ case 'A': malloc_abort = 1; break;
++#ifdef MALLOC_STATS
++ case 'd': malloc_stats = 0; break;
++ case 'D': malloc_stats = 1; break;
++#endif /* MALLOC_STATS */
++#ifdef MADV_FREE
++ case 'h': malloc_hint = 0; break;
++ case 'H': malloc_hint = 1; break;
++#endif /* MADV_FREE */
++ case 'r': malloc_realloc = 0; break;
++ case 'R': malloc_realloc = 1; break;
++ case 'j': malloc_junk = 0; break;
++ case 'J': malloc_junk = 1; break;
++#ifdef HAVE_UTRACE
++ case 'u': malloc_utrace = 0; break;
++ case 'U': malloc_utrace = 1; break;
++#endif /* HAVE_UTRACE */
++ case 'z': malloc_zero = 0; break;
++ case 'Z': malloc_zero = 1; break;
++ default:
++ j = malloc_abort;
++ malloc_abort = 0;
++ wrtwarning("unknown char in MALLOC_OPTIONS\n");
++ malloc_abort = j;
++ break;
++ }
++ }
++ }
++
++ UTRACE(0, 0, 0);
++
++ /*
++ * We want junk in the entire allocation, and zero only in the part
++ * the user asked for.
++ */
++ if (malloc_zero)
++ malloc_junk=1;
++
++#ifdef EXTRA_SANITY
++ if (malloc_stats)
++ atexit(malloc_exit);
++#endif /* EXTRA_SANITY */
++
++#ifndef malloc_pagesize
++ /* determine our pagesize */
++ malloc_pagesize = getpagesize();
++#endif /* malloc_pagesize */
++
++#ifndef malloc_maxsize
++ malloc_maxsize = malloc_pagesize >> 1;
++#endif /* malloc_maxsize */
++
++#ifndef malloc_pageshift
++ {
++ int i;
++ /* determine how much we shift by to get there */
++ for (i = malloc_pagesize; i > 1; i >>= 1)
++ malloc_pageshift++;
++ }
++#endif /* malloc_pageshift */
++
++#ifndef malloc_minsize
++ {
++ int i;
++ /*
++ * find the smallest size allocation we will bother about.
++ * this is determined as the smallest allocation that can hold
++ * it's own pginfo;
++ */
++ i = 2;
++ for(;;) {
++ int j;
++
++ /* Figure out the size of the bits */
++ j = malloc_pagesize/i;
++ j /= 8;
++ if (j < sizeof(u_long))
++ j = sizeof (u_long);
++ if (sizeof(struct pginfo) + j - sizeof (u_long) <= i)
++ break;
++ i += i;
++ }
++ malloc_minsize = i;
++ }
++#endif /* malloc_minsize */
++
++ /* Allocate one page for the page directory */
++ page_dir = (struct pginfo **) mmap(0, malloc_pagesize, PROT_READ|PROT_WRITE,
++ MAP_ANON|MAP_PRIVATE, -1, 0);
++ if (page_dir == (struct pginfo **) -1)
++ wrterror("mmap(2) failed, check limits.\n");
++
++ /*
++ * We need a maximum of malloc_pageshift buckets, steal these from the
++ * front of the page_directory;
++ */
++ malloc_origo = ((u_long)pageround((u_long)sbrk(0))) >> malloc_pageshift;
++ malloc_origo -= malloc_pageshift;
++
++ malloc_ninfo = malloc_pagesize / sizeof *page_dir;
++
++ /* Been here, done that */
++ initialized++;
++
++ /*
++ * This is a nice hack from Kaleb Keithly (kaleb@x.org).
++ * We can sbrk(2) further back when we keep this on a low address.
++ */
++ px = (struct pgfree *) imalloc (sizeof *px);
++
++ if (!malloc_cache)
++ malloc_cache++;
++
++ malloc_cache <<= malloc_pageshift;
++}
++
++/*
++ * Allocate a number of complete pages
++ */
++void *
++malloc_pages(size_t size)
++{
++ void *p, *delay_free = 0;
++ int i;
++ struct pgfree *pf;
++ u_long index;
++
++ size = pageround(size);
++
++ p = 0;
++ /* Look for free pages before asking for more */
++ for(pf = free_list.next; pf; pf = pf->next) {
++
++#ifdef EXTRA_SANITY
++ if (pf->size & malloc_pagemask)
++ wrterror("(ES): junk length entry on free_list\n");
++ if (!pf->size)
++ wrterror("(ES): zero length entry on free_list\n");
++ if (pf->page == pf->end)
++ wrterror("(ES): zero entry on free_list\n");
++ if (pf->page > pf->end)
++ wrterror("(ES): sick entry on free_list\n");
++ if ((void*)pf->page >= (void*)sbrk(0))
++ wrterror("(ES): entry on free_list past brk\n");
++ if (page_dir[ptr2index(pf->page)] != MALLOC_FREE)
++ wrterror("(ES): non-free first page on free-list\n");
++ if (page_dir[ptr2index(pf->end)-1] != MALLOC_FREE)
++ wrterror("(ES): non-free last page on free-list\n");
++#endif /* EXTRA_SANITY */
++
++ if (pf->size < size)
++ continue;
++
++ if (pf->size == size) {
++ p = pf->page;
++ if (pf->next)
++ pf->next->prev = pf->prev;
++ pf->prev->next = pf->next;
++ delay_free = pf;
++ break;
++ }
++
++ p = pf->page;
++ pf->page = (char *)pf->page + size;
++ pf->size -= size;
++ break;
++ }
++
++#ifdef EXTRA_SANITY
++ if (p && page_dir[ptr2index(p)] != MALLOC_FREE)
++ wrterror("(ES): allocated non-free page on free-list\n");
++#endif /* EXTRA_SANITY */
++
++ size >>= malloc_pageshift;
++
++ /* Map new pages */
++ if (!p)
++ p = map_pages(size);
++
++ if (p) {
++
++ index = ptr2index(p);
++ page_dir[index] = MALLOC_FIRST;
++ for (i=1;i<size;i++)
++ page_dir[index+i] = MALLOC_FOLLOW;
++
++ if (malloc_junk)
++ memset(p, SOME_JUNK, size << malloc_pageshift);
++ }
++
++ if (delay_free) {
++ if (!px)
++ px = delay_free;
++ else
++ ifree(delay_free);
++ }
++
++ return p;
++}
++
++/*
++ * Allocate a page of fragments
++ */
++
++static __inline__ int
++malloc_make_chunks(int bits)
++{
++ struct pginfo *bp;
++ void *pp;
++ int i, k, l;
++
++ /* Allocate a new bucket */
++ pp = malloc_pages(malloc_pagesize);
++ if (!pp)
++ return 0;
++
++ /* Find length of admin structure */
++ l = sizeof *bp - sizeof(u_long);
++ l += sizeof(u_long) *
++ (((malloc_pagesize >> bits)+MALLOC_BITS-1) / MALLOC_BITS);
++
++ /* Don't waste more than two chunks on this */
++ if ((1<<(bits)) <= l+l) {
++ bp = (struct pginfo *)pp;
++ } else {
++ bp = (struct pginfo *)imalloc(l);
++ if (!bp)
++ return 0;
++ }
++
++ bp->size = (1<<bits);
++ bp->shift = bits;
++ bp->total = bp->free = malloc_pagesize >> bits;
++ bp->page = pp;
++
++ page_dir[ptr2index(pp)] = bp;
++
++ bp->next = page_dir[bits];
++ page_dir[bits] = bp;
++
++ /* set all valid bits in the bits */
++ k = bp->total;
++ i = 0;
++
++ /* Do a bunch at a time */
++ for(;k-i >= MALLOC_BITS; i += MALLOC_BITS)
++ bp->bits[i / MALLOC_BITS] = ~0;
++
++ for(; i < k; i++)
++ set_bit(bp, i);
++
++ if (bp == bp->page) {
++ /* Mark the ones we stole for ourselves */
++ for(i=0;l > 0;i++) {
++ clr_bit(bp, i);
++ bp->free--;
++ bp->total--;
++ l -= (1 << bits);
++ }
++ }
++
++ return 1;
++}
++
++/*
++ * Allocate a fragment
++ */
++static void *
++malloc_bytes(size_t size)
++{
++ int j;
++ struct pginfo *bp;
++ int k;
++ u_long *lp;
++
++ /* Don't bother with anything less than this */
++ if (size < malloc_minsize)
++ size = malloc_minsize;
++
++ /* Find the right bucket */
++ j = fls((size)-1);
++
++ /* If it's empty, make a page more of that size chunks */
++ if (!page_dir[j] && !malloc_make_chunks(j))
++ return 0;
++
++ bp = page_dir[j];
++
++ /* Find first word of bitmap which isn't empty */
++ for (lp = bp->bits; !*lp; lp++)
++ ;
++
++ /* Find that bit, and tweak it */
++ k = ffs(*lp) - 1;
++ *lp ^= 1<<k;
++
++ /* If there are no more free, remove from free-list */
++ if (!--bp->free) {
++ page_dir[j] = bp->next;
++ bp->next = 0;
++ }
++
++ /* Adjust to the real offset of that chunk */
++ k += (lp-bp->bits)*MALLOC_BITS;
++ k <<= bp->shift;
++
++ if (malloc_junk)
++ memset(bp->page + k, SOME_JUNK, bp->size);
++
++ return bp->page + k;
++}
++
++/*
++ * Allocate a piece of memory
++ */
++static void *
++imalloc(size_t size)
++{
++ void *result;
++
++ if (!initialized)
++ malloc_init();
++
++ if (suicide)
++ abort();
++
++ if (size <= malloc_maxsize)
++ result = malloc_bytes(size);
++ else
++ result = malloc_pages(size);
++
++ if (malloc_abort && !result)
++ wrterror("allocation failed.\n");
++
++ if (malloc_zero)
++ memset(result, 0, size);
++
++ return result;
++}
++
++/*
++ * Change the size of an allocation.
++ */
++static void *
++irealloc(void *ptr, size_t size)
++{
++ void *p;
++ u_long osize, index;
++ struct pginfo **mp;
++ int i;
++
++ if (suicide)
++ return 0;
++
++ if (!initialized) {
++ wrtwarning("malloc() has never been called.\n");
++ return 0;
++ }
++
++ index = ptr2index(ptr);
++
++ if (index < malloc_pageshift) {
++ wrtwarning("junk pointer, too low to make sense.\n");
++ return 0;
++ }
++
++ if (index > last_index) {
++ wrtwarning("junk pointer, too high to make sense.\n");
++ return 0;
++ }
++
++ mp = &page_dir[index];
++
++ if (*mp == MALLOC_FIRST) { /* Page allocation */
++
++ /* Check the pointer */
++ if ((u_long)ptr & malloc_pagemask) {
++ wrtwarning("modified (page-) pointer.\n");
++ return 0;
++ }
++
++ /* Find the size in bytes */
++ for (osize = malloc_pagesize; *++mp == MALLOC_FOLLOW;)
++ osize += malloc_pagesize;
++
++ if (!malloc_realloc && /* unless we have to, */
++ size <= osize && /* .. or are too small, */
++ size > (osize - malloc_pagesize)) { /* .. or can free a page, */
++ return ptr; /* don't do anything. */
++ }
++
++ } else if (*mp >= MALLOC_MAGIC) { /* Chunk allocation */
++
++ /* Check the pointer for sane values */
++ if (((u_long)ptr & ((*mp)->size-1))) {
++ wrtwarning("modified (chunk-) pointer.\n");
++ return 0;
++ }
++
++ /* Find the chunk index in the page */
++ i = ((u_long)ptr & malloc_pagemask) >> (*mp)->shift;
++
++ /* Verify that it isn't a free chunk already */
++ if (tst_bit(*mp, i)) {
++ wrtwarning("chunk is already free.\n");
++ return 0;
++ }
++
++ osize = (*mp)->size;
++
++ if (!malloc_realloc && /* Unless we have to, */
++ size < osize && /* ..or are too small, */
++ (size > osize/2 || /* ..or could use a smaller size, */
++ osize == malloc_minsize)) { /* ..(if there is one) */
++ return ptr; /* ..Don't do anything */
++ }
++
++ } else {
++ wrtwarning("pointer to wrong page.\n");
++ return 0;
++ }
++
++ p = imalloc(size);
++
++ if (p) {
++ /* copy the lesser of the two sizes, and free the old one */
++ if (osize < size)
++ memcpy(p, ptr, osize);
++ else
++ memcpy(p, ptr, size);
++ ifree(ptr);
++ }
++ return p;
++}
++
++/*
++ * Free a sequence of pages
++ */
++
++static __inline__ void
++free_pages(void *ptr, int index, struct pginfo *info)
++{
++ int i;
++ struct pgfree *pf, *pt=0;
++ u_long l;
++ void *tail;
++
++ if (info == MALLOC_FREE) {
++ wrtwarning("page is already free.\n");
++ return;
++ }
++
++ if (info != MALLOC_FIRST) {
++ wrtwarning("pointer to wrong page.\n");
++ return;
++ }
++
++ if ((u_long)ptr & malloc_pagemask) {
++ wrtwarning("modified (page-) pointer.\n");
++ return;
++ }
++
++ /* Count how many pages and mark them free at the same time */
++ page_dir[index] = MALLOC_FREE;
++ for (i = 1; page_dir[index+i] == MALLOC_FOLLOW; i++)
++ page_dir[index + i] = MALLOC_FREE;
++
++ l = i << malloc_pageshift;
++
++#ifdef MADV_FREE
++ if (malloc_hint)
++ madvise(ptr, l, MADV_FREE);
++#endif /* MADV_FREE */
++
++ tail = (char *)ptr+l;
++
++ /* add to free-list */
++ if (!px)
++ px = imalloc(sizeof *pt); /* This cannot fail... */
++ px->page = ptr;
++ px->end = tail;
++ px->size = l;
++ if (!free_list.next) {
++
++ /* Nothing on free list, put this at head */
++ px->next = free_list.next;
++ px->prev = &free_list;
++ free_list.next = px;
++ pf = px;
++ px = 0;
++
++ } else {
++
++ /* Find the right spot, leave pf pointing to the modified entry. */
++ tail = (char *)ptr+l;
++
++ for(pf = free_list.next; pf->end < ptr && pf->next; pf = pf->next)
++ ; /* Race ahead here */
++
++ if (pf->page > tail) {
++ /* Insert before entry */
++ px->next = pf;
++ px->prev = pf->prev;
++ pf->prev = px;
++ px->prev->next = px;
++ pf = px;
++ px = 0;
++ } else if (pf->end == ptr ) {
++ /* Append to the previous entry */
++ pf->end = (char *)pf->end + l;
++ pf->size += l;
++ if (pf->next && pf->end == pf->next->page ) {
++ /* And collapse the next too. */
++ pt = pf->next;
++ pf->end = pt->end;
++ pf->size += pt->size;
++ pf->next = pt->next;
++ if (pf->next)
++ pf->next->prev = pf;
++ }
++ } else if (pf->page == tail) {
++ /* Prepend to entry */
++ pf->size += l;
++ pf->page = ptr;
++ } else if (!pf->next) {
++ /* Append at tail of chain */
++ px->next = 0;
++ px->prev = pf;
++ pf->next = px;
++ pf = px;
++ px = 0;
++ } else {
++ wrterror("freelist is destroyed.\n");
++ }
++ }
++
++ /* Return something to OS ? */
++ if (!pf->next && /* If we're the last one, */
++ pf->size > malloc_cache && /* ..and the cache is full, */
++ pf->end == malloc_brk && /* ..and none behind us, */
++ malloc_brk == sbrk(0)) { /* ..and it's OK to do... */
++
++ /*
++ * Keep the cache intact. Notice that the '>' above guarantees that
++ * the pf will always have at least one page afterwards.
++ */
++ pf->end = (char *)pf->page + malloc_cache;
++ pf->size = malloc_cache;
++
++ brk(pf->end);
++ malloc_brk = pf->end;
++
++ index = ptr2index(pf->end);
++ last_index = index - 1;
++
++ for(i=index;i <= last_index;)
++ page_dir[i++] = MALLOC_NOT_MINE;
++
++ /* XXX: We could realloc/shrink the pagedir here I guess. */
++ }
++ if (pt)
++ ifree(pt);
++}
++
++/*
++ * Free a chunk, and possibly the page it's on, if the page becomes empty.
++ */
++
++static __inline__ void
++free_bytes(void *ptr, int index, struct pginfo *info)
++{
++ int i;
++ struct pginfo **mp;
++ void *vp;
++
++ /* Find the chunk number on the page */
++ i = ((u_long)ptr & malloc_pagemask) >> info->shift;
++
++ if (((u_long)ptr & (info->size-1))) {
++ wrtwarning("modified (chunk-) pointer.\n");
++ return;
++ }
++
++ if (tst_bit(info, i)) {
++ wrtwarning("chunk is already free.\n");
++ return;
++ }
++
++ set_bit(info, i);
++ info->free++;
++
++ mp = page_dir + info->shift;
++
++ if (info->free == 1) {
++
++ /* Page became non-full */
++
++ mp = page_dir + info->shift;
++ /* Insert in address order */
++ while (*mp && (*mp)->next && (*mp)->next->page < info->page)
++ mp = &(*mp)->next;
++ info->next = *mp;
++ *mp = info;
++ return;
++ }
++
++ if (info->free != info->total)
++ return;
++
++ /* Find & remove this page in the queue */
++ while (*mp != info) {
++ mp = &((*mp)->next);
++#ifdef EXTRA_SANITY
++ if (!*mp)
++ wrterror("(ES): Not on queue\n");
++#endif /* EXTRA_SANITY */
++ }
++ *mp = info->next;
++
++ /* Free the page & the info structure if need be */
++ page_dir[ptr2index(info->page)] = MALLOC_FIRST;
++ vp = info->page; /* Order is important ! */
++ if(vp != (void*)info)
++ ifree(info);
++ ifree(vp);
++}
++
++static void
++ifree(void *ptr)
++{
++ struct pginfo *info;
++ int index;
++
++ /* This is legal */
++ if (!ptr)
++ return;
++
++ if (!initialized) {
++ wrtwarning("malloc() has never been called.\n");
++ return;
++ }
++
++ /* If we're already sinking, don't make matters any worse. */
++ if (suicide)
++ return;
++
++ index = ptr2index(ptr);
++
++ if (index < malloc_pageshift) {
++ wrtwarning("junk pointer, too low to make sense.\n");
++ return;
++ }
++
++ if (index > last_index) {
++ wrtwarning("junk pointer, too high to make sense.\n");
++ return;
++ }
++
++ info = page_dir[index];
++
++ if (info < MALLOC_MAGIC)
++ free_pages(ptr, index, info);
++ else
++ free_bytes(ptr, index, info);
++ return;
++}
++
++/*
++ * These are the public exported interface routines.
++ */
++
++#ifdef _THREAD_SAFE
++#include <pthread.h>
++#include "pthread_private.h"
++static int malloc_lock;
++#define THREAD_LOCK() _thread_kern_sig_block(&malloc_lock);
++#define THREAD_UNLOCK() _thread_kern_sig_unblock(&malloc_lock);
++#elif defined(M3_THREAD_SAFE)
++extern int RT0u__inCritical; /* Flag set when in a critical region */
++#define THREAD_LOCK() (++RT0u__inCritical)
++#define THREAD_UNLOCK() (--RT0u__inCritical)
++#else
++#define THREAD_LOCK()
++#define THREAD_UNLOCK()
++#endif
++
++static int malloc_active;
++
++void *
++malloc(size_t size)
++{
++ register void *r;
++
++ malloc_func = "malloc():";
++ THREAD_LOCK();
++ if (malloc_active++) {
++ wrtwarning("recursive call.\n");
++ malloc_active--;
++ return (0);
++ }
++ r = imalloc(size);
++ UTRACE(0, size, r);
++ malloc_active--;
++ THREAD_UNLOCK();
++ return (r);
++}
++
++void
++free(void *ptr)
++{
++ malloc_func = "free():";
++ THREAD_LOCK();
++ if (malloc_active++) {
++ wrtwarning("recursive call.\n");
++ malloc_active--;
++ return;
++ }
++ ifree(ptr);
++ UTRACE(ptr, 0, 0);
++ malloc_active--;
++ THREAD_UNLOCK();
++ return;
++}
++
++void *
++realloc(void *ptr, size_t size)
++{
++ register void *r;
++
++ malloc_func = "realloc():";
++ THREAD_LOCK();
++ if (malloc_active++) {
++ wrtwarning("recursive call.\n");
++ malloc_active--;
++ return (0);
++ }
++ if (!ptr) {
++ r = imalloc(size);
++ } else if (ptr && !size) {
++ ifree(ptr);
++ r = 0;
++ } else {
++ r = irealloc(ptr, size);
++ }
++ UTRACE(ptr, size, r);
++ malloc_active--;
++ THREAD_UNLOCK();
++ return (r);
++}
diff --git a/lang/modula-3-lib/files/patch-bi b/lang/modula-3-lib/files/patch-bi
new file mode 100644
index 000000000000..74a018c9ba18
--- /dev/null
+++ b/lang/modula-3-lib/files/patch-bi
@@ -0,0 +1,39 @@
+Bug fix from SRC:
+ bug assigning arrays
+
+ This patch applies to all platforms.
+
+ The Modula-3 language definition says that it is possible to assign
+ one array to another if they have the same shape. There is a bug
+ in the compiler front-end that causes the compiler to report that
+ two array types are not assignable if they have different base
+ indices, even if they have the same size.
+
+Index: m3/m3front/src/types/ArrayType.m3
+--- ArrayType.m3.orig Tue May 23 15:24:27 1995
++++ ArrayType.m3 Mon Sep 30 11:12:31 1996
+@@ -286,7 +286,9 @@
+ a := Reduce (ta); b := Reduce (tb);
+ IF (a = NIL) OR (b = NIL) THEN EXIT END;
+ IF (a.index # b.index) THEN
+- IF Type.Number (a.index) # Type.Number (b.index) THEN RETURN FALSE END;
++ IF NOT TInt.EQ (Type.Number (a.index), Type.Number (b.index)) THEN
++ RETURN FALSE
++ END;
+ END;
+ ta := a.element;
+ tb := b.element;
+Index: m3/m3front/src/types/OpenArrayType.m3
+--- OpenArrayType.m3.orig Tue May 23 15:24:22 1995
++++ OpenArrayType.m3 Mon Sep 30 11:13:12 1996
+@@ -188,7 +188,9 @@
+
+ (* peel off the fixed dimensions as long as the sizes are equal *)
+ WHILE ArrayType.Split (ta, ia, ea) AND ArrayType.Split (tb, ib, eb) DO
+- IF Type.Number (ia) # Type.Number (ib) THEN RETURN FALSE END;
++ IF NOT TInt.EQ (Type.Number (ia), Type.Number (ib)) THEN
++ RETURN FALSE
++ END;
+ ta := ea;
+ tb := eb;
+ END;
diff --git a/lang/modula-3-lib/files/patch-bj b/lang/modula-3-lib/files/patch-bj
new file mode 100644
index 000000000000..598c235deea2
--- /dev/null
+++ b/lang/modula-3-lib/files/patch-bj
@@ -0,0 +1,460 @@
+New wrapper files for network related functions. These are separated so
+that they can be easily overridden when SOCKS support is desired.
+
+Index: m3/m3core/src/runtime/FreeBSD2/accept.c
+--- accept.c.orig Thu Oct 24 13:11:22 1996
++++ accept.c Thu Oct 24 12:47:29 1996
+@@ -0,0 +1,16 @@
++#include "wrap.h"
++#include <sys/types.h>
++#include <sys/socket.h>
++
++int
++m3_accept(int s, struct sockaddr *addr, int *addrlen)
++{
++ int result;
++
++ ENTER_CRITICAL;
++ MAKE_WRITABLE(addr);
++ MAKE_WRITABLE(addrlen);
++ result = accept(s, addr, addrlen);
++ EXIT_CRITICAL;
++ return result;
++}
+Index: m3/m3core/src/runtime/FreeBSD2/bind.c
+--- bind.c.orig Thu Oct 24 13:11:23 1996
++++ bind.c Thu Oct 24 12:48:12 1996
+@@ -0,0 +1,15 @@
++#include "wrap.h"
++#include <sys/types.h>
++#include <sys/socket.h>
++
++int
++m3_bind(int s, const struct sockaddr *name, int namelen)
++{
++ int result;
++
++ ENTER_CRITICAL;
++ MAKE_READABLE(name);
++ result = bind(s, name, namelen);
++ EXIT_CRITICAL;
++ return result;
++}
+Index: m3/m3core/src/runtime/FreeBSD2/close.c
+--- close.c.orig Thu Oct 24 13:11:23 1996
++++ close.c Thu Oct 24 12:48:51 1996
+@@ -0,0 +1,13 @@
++#include "wrap.h"
++#include <unistd.h>
++
++int
++m3_close(int d)
++{
++ int result;
++
++ ENTER_CRITICAL;
++ result = close(d);
++ EXIT_CRITICAL;
++ return result;
++}
+Index: m3/m3core/src/runtime/FreeBSD2/connect.c
+--- connect.c.orig Thu Oct 24 13:11:23 1996
++++ connect.c Thu Oct 24 12:49:40 1996
+@@ -0,0 +1,15 @@
++#include "wrap.h"
++#include <sys/types.h>
++#include <sys/socket.h>
++
++int
++m3_connect(int s, const struct sockaddr *name, int namelen)
++{
++ int result;
++
++ ENTER_CRITICAL;
++ MAKE_READABLE(name);
++ result = connect(s, name, namelen);
++ EXIT_CRITICAL;
++ return result;
++}
+Index: m3/m3core/src/runtime/FreeBSD2/dup.c
+--- dup.c.orig Thu Oct 24 13:11:23 1996
++++ dup.c Thu Oct 24 12:50:09 1996
+@@ -0,0 +1,13 @@
++#include "wrap.h"
++#include <unistd.h>
++
++int
++m3_dup(int oldd)
++{
++ int result;
++
++ ENTER_CRITICAL;
++ result = dup(oldd);
++ EXIT_CRITICAL;
++ return result;
++}
+Index: m3/m3core/src/runtime/FreeBSD2/dup2.c
+--- dup2.c.orig Thu Oct 24 13:11:23 1996
++++ dup2.c Thu Oct 24 12:50:28 1996
+@@ -0,0 +1,13 @@
++#include "wrap.h"
++#include <unistd.h>
++
++int
++m3_dup2(int oldd, int newd)
++{
++ int result;
++
++ ENTER_CRITICAL;
++ result = dup2(oldd, newd);
++ EXIT_CRITICAL;
++ return result;
++}
+Index: m3/m3core/src/runtime/FreeBSD2/gethostbyaddr.c
+--- gethostbyaddr.c.orig Thu Oct 24 16:07:10 1996
++++ gethostbyaddr.c Thu Oct 24 16:10:19 1996
+@@ -0,0 +1,14 @@
++#include "wrap.h"
++#include <netdb.h>
++
++struct hostent *
++m3_gethostbyaddr(const char *addr, int len, int type)
++{
++ struct hostent *result;
++
++ ENTER_CRITICAL;
++ MAKE_READABLE(addr);
++ result = gethostbyaddr(addr, len, type);
++ EXIT_CRITICAL;
++ return result;
++}
+Index: m3/m3core/src/runtime/FreeBSD2/gethostbyname.c
+--- gethostbyname.c.orig Thu Oct 24 13:11:23 1996
++++ gethostbyname.c Thu Oct 24 16:08:41 1996
+@@ -0,0 +1,14 @@
++#include "wrap.h"
++#include <netdb.h>
++
++struct hostent *
++m3_gethostbyname(const char *name)
++{
++ struct hostent *result;
++
++ ENTER_CRITICAL;
++ MAKE_READABLE(name);
++ result = gethostbyname(name);
++ EXIT_CRITICAL;
++ return result;
++}
+Index: m3/m3core/src/runtime/FreeBSD2/getpeername.c
+--- getpeername.c.orig Thu Oct 24 13:11:23 1996
++++ getpeername.c Thu Oct 24 12:52:25 1996
+@@ -0,0 +1,16 @@
++#include "wrap.h"
++#include <sys/types.h>
++#include <sys/socket.h>
++
++int
++m3_getpeername(int s, struct sockaddr *name, int *namelen)
++{
++ int result;
++
++ ENTER_CRITICAL;
++ MAKE_WRITABLE(name);
++ MAKE_WRITABLE(namelen);
++ result = getpeername(s, name, namelen);
++ EXIT_CRITICAL;
++ return result;
++}
+Index: m3/m3core/src/runtime/FreeBSD2/getsockname.c
+--- getsockname.c.orig Thu Oct 24 13:11:23 1996
++++ getsockname.c Thu Oct 24 12:52:56 1996
+@@ -0,0 +1,16 @@
++#include "wrap.h"
++#include <sys/types.h>
++#include <sys/socket.h>
++
++int
++m3_getsockname(int s, struct sockaddr *name, int *namelen)
++{
++ int result;
++
++ ENTER_CRITICAL;
++ MAKE_WRITABLE(name);
++ MAKE_WRITABLE(namelen);
++ result = getsockname(s, name, namelen);
++ EXIT_CRITICAL;
++ return result;
++}
+Index: m3/m3core/src/runtime/FreeBSD2/listen.c
+--- listen.c.orig Thu Oct 24 13:11:23 1996
++++ listen.c Thu Oct 24 12:53:42 1996
+@@ -0,0 +1,14 @@
++#include "wrap.h"
++#include <sys/types.h>
++#include <sys/socket.h>
++
++int
++m3_listen(int s, int backlog)
++{
++ int result;
++
++ ENTER_CRITICAL;
++ result = listen(s, backlog);
++ EXIT_CRITICAL;
++ return result;
++}
+Index: m3/m3core/src/runtime/FreeBSD2/read.c
+--- read.c.orig Thu Oct 24 13:11:23 1996
++++ read.c Thu Oct 24 12:55:56 1996
+@@ -0,0 +1,15 @@
++#include "wrap.h"
++#include <sys/types.h>
++#include <unistd.h>
++
++ssize_t
++m3_read(int d, void *buf, size_t nbytes)
++{
++ int result;
++
++ ENTER_CRITICAL;
++ MAKE_WRITABLE(buf);
++ result = read(d, buf, nbytes);
++ EXIT_CRITICAL;
++ return result;
++}
+Index: m3/m3core/src/runtime/FreeBSD2/recv.c
+--- recv.c.orig Thu Oct 24 13:11:23 1996
++++ recv.c Thu Oct 24 12:56:57 1996
+@@ -0,0 +1,15 @@
++#include "wrap.h"
++#include <sys/types.h>
++#include <sys/socket.h>
++
++ssize_t
++m3_recv(int s, void *buf, size_t len, int flags)
++{
++ int result;
++
++ ENTER_CRITICAL;
++ MAKE_WRITABLE(buf);
++ result = recv(s, buf, len, flags);
++ EXIT_CRITICAL;
++ return result;
++}
+Index: m3/m3core/src/runtime/FreeBSD2/recvfrom.c
+--- recvfrom.c.orig Thu Oct 24 13:11:23 1996
++++ recvfrom.c Thu Oct 24 12:58:10 1996
+@@ -0,0 +1,18 @@
++#include "wrap.h"
++#include <sys/types.h>
++#include <sys/socket.h>
++
++ssize_t
++m3_recvfrom(int s, void *buf, size_t len, int flags,
++ struct sockaddr *from, int *fromlen)
++{
++ int result;
++
++ ENTER_CRITICAL;
++ MAKE_WRITABLE(buf);
++ MAKE_WRITABLE(from);
++ MAKE_WRITABLE(fromlen);
++ result = recvfrom(s, buf, len, flags, from, fromlen);
++ EXIT_CRITICAL;
++ return result;
++}
+Index: m3/m3core/src/runtime/FreeBSD2/select.c
+--- select.c.orig Thu Oct 24 13:11:23 1996
++++ select.c Thu Oct 24 12:59:17 1996
+@@ -0,0 +1,20 @@
++#include "wrap.h"
++#include <sys/types.h>
++#include <sys/time.h>
++#include <unistd.h>
++
++int
++m3_select(int nfds, fd_set *readfds, fd_set *writefds,
++ fd_set *exceptfds, struct timeval *timeout)
++{
++ int result;
++
++ ENTER_CRITICAL;
++ MAKE_WRITABLE(readfds);
++ MAKE_WRITABLE(writefds);
++ MAKE_WRITABLE(exceptfds);
++ MAKE_READABLE(timeout);
++ result = select(nfds, readfds, writefds, exceptfds, timeout);
++ EXIT_CRITICAL;
++ return result;
++}
+Index: m3/m3core/src/runtime/FreeBSD2/send.c
+--- send.c.orig Thu Oct 24 13:11:23 1996
++++ send.c Thu Oct 24 13:00:25 1996
+@@ -0,0 +1,15 @@
++#include "wrap.h"
++#include <sys/types.h>
++#include <sys/socket.h>
++
++ssize_t
++m3_send(int s, const void *msg, size_t len, int flags)
++{
++ int result;
++
++ ENTER_CRITICAL;
++ MAKE_READABLE(msg);
++ result = send(s, msg, len, flags);
++ EXIT_CRITICAL;
++ return result;
++}
+Index: m3/m3core/src/runtime/FreeBSD2/sendto.c
+--- sendto.c.orig Thu Oct 24 13:11:23 1996
++++ sendto.c Thu Oct 24 13:01:18 1996
+@@ -0,0 +1,17 @@
++#include "wrap.h"
++#include <sys/types.h>
++#include <sys/socket.h>
++
++ssize_t
++m3_sendto(int s, const void *msg, size_t len, int flags,
++ const struct sockaddr *to, int tolen)
++{
++ int result;
++
++ ENTER_CRITICAL;
++ MAKE_READABLE(msg);
++ MAKE_READABLE(to);
++ result = sendto(s, msg, len, flags, to, tolen);
++ EXIT_CRITICAL;
++ return result;
++}
+Index: m3/m3core/src/runtime/FreeBSD2/shutdown.c
+--- shutdown.c.orig Thu Oct 24 13:11:23 1996
++++ shutdown.c Thu Oct 24 13:01:40 1996
+@@ -0,0 +1,14 @@
++#include "wrap.h"
++#include <sys/types.h>
++#include <sys/socket.h>
++
++int
++m3_shutdown(int s, int how)
++{
++ int result;
++
++ ENTER_CRITICAL;
++ result = shutdown(s, how);
++ EXIT_CRITICAL;
++ return result;
++}
+Index: m3/m3core/src/runtime/FreeBSD2/socket.c
+--- socket.c.orig Thu Oct 24 16:11:12 1996
++++ socket.c Thu Oct 24 16:12:22 1996
+@@ -0,0 +1,14 @@
++#include "wrap.h"
++#include <sys/types.h>
++#include <sys/socket.h>
++
++int
++m3_socket(int domain, int type, int protocol)
++{
++ int result;
++
++ ENTER_CRITICAL;
++ result = socket(domain, type, protocol);
++ EXIT_CRITICAL;
++ return result;
++}
+Index: m3/m3core/src/runtime/FreeBSD2/socksconf.h
+--- socksconf.h.orig Fri Oct 25 14:05:03 1996
++++ socksconf.h Fri Oct 25 14:05:28 1996
+@@ -0,0 +1,6 @@
++/*
++ * Define 0 or 1 of these, to select the variety of SOCKS support you want.
++ */
++#undef HPSOCKS
++#undef SOCKS4
++#undef SOCKS5
+Index: m3/m3core/src/runtime/FreeBSD2/wrap.h
+--- wrap.h.orig Thu Oct 24 20:50:16 1996
++++ wrap.h Fri Oct 25 14:04:13 1996
+@@ -0,0 +1,61 @@
++#include "socksconf.h"
++
++#if defined(HPSOCKS) /* { */
++ #define accept Raccept
++ #define bind Rxbind
++ #define close Rclose
++ #define connect Rconnect
++ #define dup Rdup
++ #define dup2 Rdup2
++ #define gethostbyaddr Rgethostbyaddr
++ #define gethostbyname Rgethostbyname
++ #define getpeername Rgetpeername
++ #define getsockname Rgetsockname
++ #define listen Rlisten
++ #define recv Rrecv
++ #define recvfrom Rrecvfrom
++ #define send Rsend
++ #define sendto Rsendto
++ #define shutdown Rshutdown
++ #define socket Rsocket
++#elif defined(SOCKS4) /* } { */
++ #define accept Raccept
++ #define bind Rbind
++ #define connect Rconnect
++ #define getpeername Rgetpeername
++ #define getsockname Rgetsockname
++ #define listen Rlisten
++ #define select Rselect
++#elif defined(SOCKS5) /* } { */
++ #define accept SOCKSaccept
++ #define bind SOCKSbind
++ #define close SOCKSclose
++ #define connect SOCKSconnect
++ #define dup SOCKSdup
++ #define dup2 SOCKSdup2
++ #define fclose SOCKSfclose
++ #define gethostbyname SOCKSgethostbyname
++ #define getpeername SOCKSgetpeername
++ #define getsockname SOCKSgetsockname
++ #define listen SOCKSlisten
++ #define read SOCKSread
++ #define recv SOCKSrecv
++ #define recvfrom SOCKSrecvfrom
++ #define rresvport SOCKSrresvport
++ #define select SOCKSselect
++ #define send SOCKSsend
++ #define sendto SOCKSsendto
++ #define shutdown SOCKSshutdown
++ #define write SOCKSwrite
++#endif /* } */
++
++extern int RT0u__inCritical;
++#define ENTER_CRITICAL RT0u__inCritical++
++#define EXIT_CRITICAL RT0u__inCritical--
++
++static char RTHeapDepC__c;
++#define MAKE_READABLE(x) \
++ if ((int)x) { RTHeapDepC__c = *(char*)(x); }
++
++#define MAKE_WRITABLE(x) \
++ if ((int)x) { *(char*)(x) = RTHeapDepC__c = *(char*)(x); }
+Index: m3/m3core/src/runtime/FreeBSD2/write.c
+--- write.c.orig Thu Oct 24 13:11:23 1996
++++ write.c Thu Oct 24 13:02:24 1996
+@@ -0,0 +1,15 @@
++#include "wrap.h"
++#include <sys/types.h>
++#include <unistd.h>
++
++size_t
++m3_write(int fd, const void *buf, int nbytes)
++{
++ int result;
++
++ ENTER_CRITICAL;
++ MAKE_READABLE(buf);
++ result = write(fd, buf, nbytes);
++ EXIT_CRITICAL;
++ return result;
++}
diff --git a/lang/modula-3-lib/files/patch-bk b/lang/modula-3-lib/files/patch-bk
new file mode 100644
index 000000000000..b01ef3e17004
--- /dev/null
+++ b/lang/modula-3-lib/files/patch-bk
@@ -0,0 +1,34 @@
+Support for SOCKS wrappers in Unix.i3.
+
+Index: m3/m3core/src/unix/freebsd-2/Unix.i3
+--- Unix.i3.orig Sat Jan 7 14:41:42 1995
++++ Unix.i3 Tue Oct 8 14:20:50 1996
+@@ -94,7 +94,7 @@
+ (* ok *)
+
+ (*** close - delete a descriptor ***)
+-<*EXTERNAL*> PROCEDURE close (d: int): int;
++<*EXTERNAL "m3_close"*> PROCEDURE close (d: int): int;
+ (* ok *)
+
+ (*** creat - create a new file ***)
+@@ -102,8 +102,8 @@
+ (* ok, but obsolete *)
+
+ (*** dup, dup2 - duplicate an open file descriptor ***)
+-<*EXTERNAL*> PROCEDURE dup (oldd: int): int;
+-<*EXTERNAL*> PROCEDURE dup2 (oldd, newd: int): int;
++<*EXTERNAL "m3_dup"*> PROCEDURE dup (oldd: int): int;
++<*EXTERNAL "m3_dup2"*> PROCEDURE dup2 (oldd, newd: int): int;
+ (* ok *)
+
+ (*** execve - execute a file ***)
+@@ -892,7 +892,7 @@
+ TYPE
+ FDSet = SET OF [0 .. MAX_FDSET - 1];
+
+-<*EXTERNAL*> PROCEDURE select (nfds: int;
++<*EXTERNAL "m3_select"*> PROCEDURE select (nfds: int;
+ readfds, writefds, exceptfds: UNTRACED REF FDSet;
+ timeout: UNTRACED REF struct_timeval): int;
+ (* ok *)
diff --git a/lang/modula-3-lib/files/patch-bl b/lang/modula-3-lib/files/patch-bl
new file mode 100644
index 000000000000..883e43ad7017
--- /dev/null
+++ b/lang/modula-3-lib/files/patch-bl
@@ -0,0 +1,25 @@
+Support for SOCKS wrappers in Uuio.i3.
+
+Index: m3/m3core/src/unix/freebsd-2/Uuio.i3
+--- Uuio.i3.orig Sat Jan 7 14:22:23 1995
++++ Uuio.i3 Tue Oct 8 14:22:15 1996
+@@ -50,13 +50,17 @@
+
+ (*** read, readv(2) - read from a file ***)
+
+-<*EXTERNAL*> PROCEDURE read (d: int; buf: char_star; nbytes: int): int;
++<*EXTERNAL "m3_read"*>
++PROCEDURE read (d: int; buf: char_star; nbytes: int): int;
++
+ <*EXTERNAL*> PROCEDURE readv (d: int; iov: struct_iovec_star;
+ iovcnt: int): int;
+
+ (*** write, writev(2) - write on a file ***)
+
+-<*EXTERNAL*> PROCEDURE write (d: int; buf: char_star; nbytes: int): int;
++<*EXTERNAL "m3_write"*>
++PROCEDURE write (d: int; buf: char_star; nbytes: int): int;
++
+ <*EXTERNAL*> PROCEDURE writev (d: int; iov: struct_iovec_star;
+ ioveclen: int): int;
+
diff --git a/lang/modula-3-lib/files/patch-bm b/lang/modula-3-lib/files/patch-bm
new file mode 100644
index 000000000000..2bc3d92e6654
--- /dev/null
+++ b/lang/modula-3-lib/files/patch-bm
@@ -0,0 +1,18 @@
+Support for SOCKS wrappers in Unetdb.i3.
+
+Index: m3/m3core/src/unix/freebsd-2/Unetdb.i3
+--- Unetdb.i3.orig Sat Jan 7 14:22:19 1995
++++ Unetdb.i3 Thu Oct 24 16:05:40 1996
+@@ -88,10 +88,10 @@
+ (*** gethostent(3n), gethostbyaddr(3n), gethostbyname(3n),
+ sethostent(3n), endhostent(3n) - get network host entry ***)
+
+-<*EXTERNAL*>
++<*EXTERNAL "m3_gethostbyname"*>
+ PROCEDURE gethostbyname (name: char_star): struct_hostent_star;
+
+-<*EXTERNAL*>
++<*EXTERNAL "m3_gethostbyaddr"*>
+ PROCEDURE gethostbyaddr (addr: char_star; len, type: int): struct_hostent_star;
+
+ <*EXTERNAL*>
diff --git a/lang/modula-3-lib/pkg-comment b/lang/modula-3-lib/pkg-comment
new file mode 100644
index 000000000000..7cdc69366dc6
--- /dev/null
+++ b/lang/modula-3-lib/pkg-comment
@@ -0,0 +1 @@
+The shared libraries needed for executing Modula-3 programs.
diff --git a/lang/modula-3-lib/pkg-descr b/lang/modula-3-lib/pkg-descr
new file mode 100644
index 000000000000..266d95a8b317
--- /dev/null
+++ b/lang/modula-3-lib/pkg-descr
@@ -0,0 +1,6 @@
+This is a subset of the Modula-3 port, consisting of the shared
+libraries only. People who don't wish to install the entire Modula-3
+system just so they can execute Modula-3 programs can install this
+package instead.
+
+jdp@freebsd.org
diff --git a/lang/modula-3-lib/pkg-install b/lang/modula-3-lib/pkg-install
new file mode 100644
index 000000000000..07e589ad89d8
--- /dev/null
+++ b/lang/modula-3-lib/pkg-install
@@ -0,0 +1,74 @@
+#! /bin/sh
+#
+# This script determines whether certain earlier versions of the
+# Modula-3 port exist on the system in a place where the linker or
+# dynamic linker would find them. These earlier versions must be
+# removed before installing the current port, because they use higher
+# major version numbers for the shared libraries than this port uses.
+# This situation arose because of an ill-considered choice for the
+# major version numbers in those early ports. I am intentionally
+# breaking the rule that the version number should never be decreased,
+# in order to nip this unfortunate situation in the bud.
+
+if [ x$2 != xPRE-INSTALL ]; then
+ exit 0
+fi
+
+check() {
+ local list i lib_path oldIFS status
+
+ status=0
+
+ # Check the dynamic linker's hints.
+
+ list=$(/sbin/ldconfig -r | grep "libm3\.so\.35[34]\." | sed "s/^.* => //")
+ for file in ${list}; do
+ if [ -f ${file} ]; then # The file actually exists
+ echo $(dirname ${file})
+ status=1
+ fi
+ done
+
+ # Check any directories in LD_LIBRARY_PATH. Also, check the directory
+ # where we intend to install the new libraries.
+
+ lib_path=${PREFIX:-/usr/local}/lib/m3/FreeBSD2:${LD_LIBRARY_PATH}
+ oldIFS=${IFS}; IFS=":"; set ${lib_path}; IFS=${oldIFS}
+ for dir; do
+ if [ x${dir} != x ]; then
+ if echo ${dir}/libm3.so.35[34].* | grep -q "\*"; then # Not found
+ :
+ else # Found
+ echo ${dir}
+ status=1
+ fi
+ fi
+ done
+
+ return ${status}
+}
+
+tmp=/tmp/m3-inst$$a
+trap "rm -f ${tmp}" 1 2 3 15
+touch ${tmp}
+
+if check > ${tmp}; then
+ rm -f ${tmp}
+ exit 0
+else
+ echo "*****************************************************************"
+ echo "* IMPORTANT *"
+ echo "* You currently have an older version of the Modula-3 port on *"
+ echo "* your system. You must remove the older version before you *"
+ echo "* install this one. Otherwise, a problem with the shared *"
+ echo "* libraries in the older version will cause utter confusion. *"
+ echo "* Please remove the older version and try again. *"
+ echo "* *"
+ echo "* Old Modula-3 shared libraries were found in the following *"
+ echo "* directories: *"
+ echo "* *"
+ sort -u ${tmp} | awk '{ printf "* %-59s *\n", $0 }'
+ echo "*****************************************************************"
+ rm -f ${tmp}
+ exit 1
+fi
diff --git a/lang/modula-3-lib/pkg-plist b/lang/modula-3-lib/pkg-plist
new file mode 100644
index 000000000000..36a23286127c
--- /dev/null
+++ b/lang/modula-3-lib/pkg-plist
@@ -0,0 +1,42 @@
+etc/rc.d/m3.sh
+lib/m3/FreeBSD2/libDiGraph.so.4.0
+lib/m3/FreeBSD2/libGeometry.so.4.0
+lib/m3/FreeBSD2/libImages.so.4.0
+lib/m3/FreeBSD2/libTempFiles.so.4.0
+lib/m3/FreeBSD2/libjvideo.so.4.0
+lib/m3/FreeBSD2/libm3.so.4.0
+lib/m3/FreeBSD2/libm3X11R4.so.4.0
+lib/m3/FreeBSD2/libm3core.so.4.0
+lib/m3/FreeBSD2/libm3formsvbt.so.4.0
+lib/m3/FreeBSD2/libm3formsvbtpixmaps.so.4.0
+lib/m3/FreeBSD2/libm3parseparams.so.4.0
+lib/m3/FreeBSD2/libm3tcp.so.4.0
+lib/m3/FreeBSD2/libm3tools.so.4.0
+lib/m3/FreeBSD2/libm3ui.so.4.0
+lib/m3/FreeBSD2/libm3vbtkit.so.4.0
+lib/m3/FreeBSD2/libset.so.4.0
+lib/m3/FreeBSD2/libtable-list.so.4.0
+lib/m3/FreeBSD2/libtcpextras.so.4.0
+lib/m3/FreeBSD2/libvideovbt.so.4.0
+lib/m3/FreeBSD2/libweb.so.4.0
+lib/m3/pkg/X11R4/FreeBSD2/libm3X11R4.so.4.0
+lib/m3/pkg/digraph/FreeBSD2/libDiGraph.so.4.0
+lib/m3/pkg/formsvbt/FreeBSD2/libm3formsvbt.so.4.0
+lib/m3/pkg/formsvbtpixmaps/FreeBSD2/libm3formsvbtpixmaps.so.4.0
+lib/m3/pkg/images/FreeBSD2/libImages.so.4.0
+lib/m3/pkg/jvideo/FreeBSD2/libjvideo.so.4.0
+lib/m3/pkg/libm3/FreeBSD2/libm3.so.4.0
+lib/m3/pkg/m3core/FreeBSD2/libm3core.so.4.0
+lib/m3/pkg/m3tools/FreeBSD2/libm3tools.so.4.0
+lib/m3/pkg/parseparams/FreeBSD2/libm3parseparams.so.4.0
+lib/m3/pkg/realgeometry/FreeBSD2/libGeometry.so.4.0
+lib/m3/pkg/set/FreeBSD2/libset.so.4.0
+lib/m3/pkg/table-list/FreeBSD2/libtable-list.so.4.0
+lib/m3/pkg/tcp/FreeBSD2/libm3tcp.so.4.0
+lib/m3/pkg/tcpextras/FreeBSD2/libtcpextras.so.4.0
+lib/m3/pkg/tempfiles/FreeBSD2/libTempFiles.so.4.0
+lib/m3/pkg/ui/FreeBSD2/libm3ui.so.4.0
+lib/m3/pkg/vbtkit/FreeBSD2/libm3vbtkit.so.4.0
+lib/m3/pkg/videovbt/FreeBSD2/libvideovbt.so.4.0
+lib/m3/pkg/web/FreeBSD2/libweb.so.4.0
+@exec /sbin/ldconfig -m %D/lib/m3/FreeBSD2
diff --git a/lang/modula-3-lib/scripts/check_files b/lang/modula-3-lib/scripts/check_files
new file mode 100644
index 000000000000..2c120f417479
--- /dev/null
+++ b/lang/modula-3-lib/scripts/check_files
@@ -0,0 +1,29 @@
+#! /bin/sh
+#
+# check_files listfile m3dir sysdir
+#
+# The listfile must contain a list of filenames, one per line. It is read,
+# and all leading instances of m3dir are replaced with sysdir. If all
+# the resulting files exist and are readable, then sysdir is echoed to
+# the standard output. Otherwise, nothing is echoed. In any event, the
+# exit status is successful.
+
+if [ $# -ne 3 ]; then
+ echo "Usage: $0 listfile m3dir sysdir" >&2
+ exit 1
+fi
+
+listfile=$1
+m3dir=$2
+sysdir=$3
+
+result=${sysdir}
+for i in $(sed "s,^${m3dir},${sysdir}," ${listfile}); do
+ if [ ! -r $i ]; then
+ result=
+ break
+ fi
+done
+
+echo ${result}
+exit 0
diff --git a/lang/modula-3-lib/scripts/configure b/lang/modula-3-lib/scripts/configure
new file mode 100644
index 000000000000..22a4738fdfee
--- /dev/null
+++ b/lang/modula-3-lib/scripts/configure
@@ -0,0 +1,15 @@
+#! /bin/sh
+#
+# $Id: configure,v 1.2 1996/09/10 05:25:09 jdp Exp $
+
+umask 022
+
+files_to_patch="\
+ ${WRKSRC}/m3/m3build/templates/FreeBSD2"
+temp_prefix=${WRKSRC}/installed
+
+for i in ${files_to_patch}; do
+ test -f ${i}.bak || cp -p ${i} ${i}.bak
+ rm -f ${i}
+ sed -e "s|/usr/local/|${temp_prefix}/|g" ${i}.bak >${i}
+done
diff --git a/lang/modula-3-lib/scripts/copy_files b/lang/modula-3-lib/scripts/copy_files
new file mode 100644
index 000000000000..4c24d4954a2a
--- /dev/null
+++ b/lang/modula-3-lib/scripts/copy_files
@@ -0,0 +1,16 @@
+#! /bin/sh
+#
+# copy_files listfile m3dir sysdir wrkdir
+
+if [ $# -ne 4 ]; then
+ echo "Usage: $0 listfile m3dir sysdir wrkdir" >&2
+ exit 1
+fi
+
+listfile=$1
+m3dir=$2
+sysdir=$3
+wrkdir=$4
+
+sed "s,^${m3dir}/,," ${listfile} |\
+ (cd ${sysdir}; cpio -pdmu ${wrkdir}/${m3dir})