summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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})