public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Modula-2: merge proposal/review: 3/9  03.patch-set-03  v2
@ 2022-05-18 19:11 Gaius Mulley
  0 siblings, 0 replies; only message in thread
From: Gaius Mulley @ 2022-05-18 19:11 UTC (permalink / raw)
  To: gcc-patches

Hello,

this email contains v2 of the libgm2 (apologies, corrected gnu coding
standard comments).

3.  the top level /libgm2 contents.

-----------------------------
New file: ./libm2log/Break.c
-----------------------------
/* Break.c implements an interrupt handler for SIGINT.

Copyright (C) 2004-2022 Free Software Foundation, Inc.
Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.

This file is part of GNU Modula-2.

GNU Modula-2 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GNU Modula-2 is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

#include <config.h>

#if defined(HAVE_STDIO_H)
#include <stdio.h>
#endif

#if defined(HAVE_STDARG_H)
#include <stdarg.h>
#endif

#if defined(HAVE_STDLIB_H)
#include <stdlib.h>
#endif

#if defined(HAVE_MALLOC_H)
#include <malloc.h>
#endif

typedef void (*PROC) (void);

#if defined(HAVE_SIGNAL_H)
#include <signal.h>

struct plist
{
  PROC proc;
  struct plist *next;
};

static struct plist *head = NULL;

/* localHandler - dismisses the parameter, p, and invokes the GNU
   Modula-2 handler.  */

static void
localHandler (int p)
{
  if (head != NULL)
    head->proc ();
}

/* EnableBreak - enable the current break handler.  */

void
Break_EnableBreak (void)
{
  signal (SIGINT, localHandler);
}

/* DisableBreak - disable the current break handler (and all
   installed handlers).  */

void
Break_DisableBreak (void)
{
  signal (SIGINT, SIG_IGN);
}

/* InstallBreak - installs a procedure, p, to be invoked when a
   ctrl-c is caught.  Any number of these procedures may be stacked.
   Only the top procedure is run when ctrl-c is caught.  */

void
Break_InstallBreak (PROC p)
{
  struct plist *q = (struct plist *)malloc (sizeof (struct plist));

  if (q == NULL)
    {
      perror ("out of memory error in module Break");
      exit (1);
    }
  q->next = head;
  head = q;
  head->proc = p;
}

/* UnInstallBreak - pops the break handler stack.  */

void
Break_UnInstallBreak (void)
{
  struct plist *q = head;

  if (head != NULL)
    {
      head = head->next;
      free (q);
    }
}
#else
void
Break_EnableBreak (void)
{
}
void
Break_DisableBreak (void)
{
}
void
Break_InstallBreak (PROC *p)
{
}
void
Break_UnInstallBreak (void)
{
}
#endif
-----------------------------
New file: ./libm2log/Makefile.am
-----------------------------
# Makefile for libm2log.
#   Copyright 2013-2022  Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING3.  If not see
# <http://www.gnu.org/licenses/>.

SUFFIXES = .c .mod .def .o .obj .lo .a .la

ACLOCAL_AMFLAGS = -I . -I .. -I ../config

VPATH = . @srcdir@ @srcdir@/../../gcc/m2/gm2-libs-pim

# Multilib support.
MAKEOVERRIDES=

version := $(shell $(CC) -dumpversion)

# Directory in which the compiler finds libraries etc.
libsubdir = $(libdir)/gcc/$(target_alias)/$(version)
# Used to install the shared libgcc.
slibdir = @slibdir@

toolexeclibdir=@toolexeclibdir@
toolexecdir=@toolexecdir@

MULTIDIR := $(shell $(CC) $(CFLAGS) -print-multi-directory)
MULTIOSDIR := $(shell $(CC) $(CFLAGS) -print-multi-os-directory)

MULTIOSSUBDIR := $(shell if test x$(MULTIOSDIR) != x.; then echo /$(MULTIOSDIR); fi)
inst_libdir = $(libsubdir)$(MULTISUBDIR)
inst_slibdir = $(slibdir)$(MULTIOSSUBDIR)


# Work around what appears to be a GNU make bug handling MAKEFLAGS
# values defined in terms of make variables, as is the case for CC and
# friends when we are called from the top level Makefile.
AM_MAKEFLAGS = \
        "GCC_DIR=$(GCC_DIR)" \
        "GM2_SRC=$(GM2_SRC)" \
	"AR_FLAGS=$(AR_FLAGS)" \
	"CC_FOR_BUILD=$(CC_FOR_BUILD)" \
	"CC_FOR_TARGET=$(CC_FOR_TARGET)" \
	"GM2_FOR_TARGET=$(GM2_FOR_TARGET)" \
	"CFLAGS=$(CFLAGS)" \
	"CXXFLAGS=$(CXXFLAGS)" \
	"CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
	"CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
	"INSTALL=$(INSTALL)" \
	"INSTALL_DATA=$(INSTALL_DATA)" \
	"INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
	"INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
	"LDFLAGS=$(LDFLAGS)" \
	"LIBCFLAGS=$(LIBCFLAGS)" \
	"LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
	"MAKE=$(MAKE)" \
	"MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
        "MULTISUBDIR=$(MULTISUBDIR)" \
        "MULTIOSDIR=$(MULTIOSDIR)" \
        "MULTIBUILDTOP=$(MULTIBUILDTOP)" \
        "MULTIFLAGS=$(MULTIFLAGS)" \
	"PICFLAG=$(PICFLAG)" \
	"PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
	"SHELL=$(SHELL)" \
	"RUNTESTFLAGS=$(RUNTESTFLAGS)" \
	"exec_prefix=$(exec_prefix)" \
	"infodir=$(infodir)" \
	"libdir=$(libdir)" \
	"includedir=$(includedir)" \
	"prefix=$(prefix)" \
	"tooldir=$(tooldir)" \
        "toolexeclibdir=$(toolexeclibdir)" \
        "toolexecdir=$(toolexecdir)" \
	"gxx_include_dir=$(gxx_include_dir)" \
	"AR=$(AR)" \
	"AS=$(AS)" \
	"LD=$(LD)" \
	"RANLIB=$(RANLIB)" \
	"NM=$(NM)" \
	"NM_FOR_BUILD=$(NM_FOR_BUILD)" \
	"NM_FOR_TARGET=$(NM_FOR_TARGET)" \
	"DESTDIR=$(DESTDIR)" \
	"WERROR=$(WERROR)" \
        "TARGET_LIB_PATH_libgm2=$(TARGET_LIB_PATH_libgm2)"

# Subdir rules rely on $(FLAGS_TO_PASS)
FLAGS_TO_PASS = $(AM_MAKEFLAGS)


if BUILD_LOGLIB
M2DEFS = BitBlockOps.def  BitByteOps.def \
         BitWordOps.def  BlockOps.def \
         Break.def  CardinalIO.def \
         Conversions.def  DebugPMD.def \
         DebugTrace.def  Delay.def \
         Display.def  ErrorCode.def \
         FileSystem.def  FloatingUtilities.def \
         InOut.def  Keyboard.def \
         LongIO.def  NumberConversion.def \
         Random.def  RealConversions.def \
         RealInOut.def  Strings.def \
         Termbase.def  Terminal.def \
         TimeDate.def

M2MODS = BitBlockOps.mod  BitByteOps.mod \
         BitWordOps.mod  BlockOps.mod \
         CardinalIO.mod  Conversions.mod \
         DebugPMD.mod  DebugTrace.mod \
         Delay.mod  Display.mod \
         ErrorCode.mod  FileSystem.mod \
         FloatingUtilities.mod  InOut.mod \
         Keyboard.mod  LongIO.mod \
         NumberConversion.mod  Random.mod \
         RealConversions.mod  RealInOut.mod \
         Strings.mod  Termbase.mod \
         Terminal.mod  TimeDate.mod


libm2logdir = libm2log
toolexeclib_LTLIBRARIES = libm2log.la
libm2log_la_SOURCES = $(M2MODS) Break.c

libm2log_la_DEPENDENCIES = ../libm2pim/SYSTEM.def $(addsuffix .lo, $(basename $(libm2log_la_SOURCES)))
libm2log_la_CFLAGS = -I. -DBUILD_GM2_LIBS -I@srcdir@/../
libm2log_la_M2FLAGS = -I../libm2pim -I$(GM2_SRC)/gm2-libs-pim -I$(GM2_SRC)/gm2-libs -I$(GM2_SRC)/gm2-libs-iso
libm2log_la_LINK = $(LINK) -version-info $(libtool_VERSION)
BUILT_SOURCES = ../libm2pim/SYSTEM.def

M2LIBDIR = /m2/m2log/

../libm2pim/SYSTEM.def: ../libm2pim/Makefile
	cd ../libm2pim ; $(MAKE) $(AM_MAKEFLAGS) SYSTEM.def

.mod.lo:
	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(GM2_FOR_TARGET) -c $(CFLAGS_FOR_TARGET) $(LIBCFLAGS) $(libm2log_la_M2FLAGS) $< -o $@

install-data-local: force
	mkdir -p $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)
	$(INSTALL_DATA) .libs/libm2log.la $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)
	chmod 644 $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)libm2log.la
	$(INSTALL_DATA) .libs/libm2log.a $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)
	chmod 644 $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)libm2log.a
	$(RANLIB) $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)libm2log.a
	for i in $(M2DEFS) $(M2MODS) ; do \
           if [ -f $$i ] ; then \
              $(INSTALL_DATA) $$i '$(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)'; \
           elif [ -f @srcdir@/../../gcc/m2/gm2-libs-pim/$$i ] ; then \
              $(INSTALL_DATA) @srcdir@/../../gcc/m2/gm2-libs-pim/$$i '$(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)'; \
           else \
              echo "cannot find $$i" ; exit 1 ; \
           fi ; \
           chmod 644 $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)$$i ; \
	done

force:

endif
-----------------------------
New file: ./ChangeLog
-----------------------------
2022-05-18  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* Corrected dates on all source files.
	* libm2pim/Selective.c: Reformatted comments.
	* libm2pim/SysExceptions.c: Reformatted comments.
	* libm2pim/dtoa.c: Reformatted comments.
	* libm2pim/ldtoa.c: Reformatted comments.
	* libm2pim/sckt.c: Reformatted comments.
	* libm2pim/termios.c: Reformatted comments.
	* libm2pim/wrapc.c: Reformatted comments.
	* libm2pim/termios.c: Reformatted comments within enum.
	* libm2pim/Selective.c: Correct spelling.
	* libm2pim/termios.c: Use GNU comment formatting.

2022-05-17  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* Corrected dates on all source files.

2022-03-02  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* libm2pim/sckt.c (tcpServerEstablishPort): Corrected spelling.
	(tcpServerEstablish) Corrected spelling.

2021-06-27  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* Makefile.am: renamed getopt.c to cgetopt.c.

2021-05-29  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* Makefile.in: (rebuilt).
	* aclocal.m4: (rebuilt).
	* configure: (rebuilt).
	* configure.ac: tidied up messages.  Removed android
	from the list of supported hosts.  Corrected a comment
	* libm2pim/Makefile.am: Conditionally build.
	* libm2cor/Makefile.am: Conditionally build.
	* libm2log/Makefile.am: Conditionally build.
	* libm2iso/Makefile.am: Conditionally build.
	* libm2cor/Makefile.in: (Rebuilt).
	* libm2iso/Makefile.in: (Rebuilt).
	* libm2log/Makefile.in: (Rebuilt).
	* libm2min/Makefile.in: (Rebuilt).
	* libm2pim/Makefile.in: (Rebuilt).

2021-05-28  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* Makefile.in: (Rebuilt).
	* aclocal.m4: (Rebuilt).
	* configure: (Rebuilt).
	* configure.ac: Introduce checks for supported host
	operating system and also known detect target architectures
	which are currently restricted to minimal runtime libraries.
	* libm2cor/Makefile.in: (Rebuilt).
	* libm2iso/Makefile.in: (Rebuilt).
	* libm2log/Makefile.in: (Rebuilt).
	* libm2min/Makefile.in: (Rebuilt).
	* libm2pim/Makefile.in: (Rebuilt).

2021-02-12  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* libm2iso/RTco.c: (threadSem) new declaration
        and implmentation of thread semaphores used internally by
        the m2 runtime system.

2021-01-13  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* Makefile.am: Updated dates.
	* aclocal.m4: (Rebuilt).
	* autogen.sh: Updated dates.
	* configure: (Rebuilt).
	* configure.ac: Updated dates.
	* libm2cor/KeyBoardLEDs.c: Updated dates.
	* libm2cor/Makefile.am: Updated dates.
	* libm2iso/ChanConsts.h: Updated dates.
	* libm2iso/ErrnoCategory.c: Updated dates.
	* libm2iso/Makefile.am: Updated dates.
	* libm2iso/RTco.c: Updated dates.
	* libm2iso/wrapsock.c: Updated dates.
	* libm2iso/wraptime.c: Updated dates.
	* libm2log/Break.c: Updated dates.
	* libm2log/Makefile.am: Updated dates.
	* libm2min/Makefile.am: Updated dates.
	* libm2min/libc.c: Updated dates.
	* libm2pim/Makefile.am: Updated dates.
	* libm2pim/Selective.c: Updated dates.
	* libm2pim/SysExceptions.c: Updated dates.
	* libm2pim/UnixArgs.c: Updated dates.
	* libm2pim/dtoa.c: Updated dates.
	* libm2pim/errno.c: Updated dates.
	* libm2pim/getopt.c: Updated dates.
	* libm2pim/ldtoa.c: Updated dates.
	* libm2pim/sckt.c: Updated dates.
	* libm2pim/target.c: Updated dates.
	* libm2pim/termios.c: Updated dates.
	* libm2pim/wrapc.c: Updated dates.

2020-11-20  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* Makefile.in: (Rebuilt).
	* aclocal.m4: (Rebuilt).
	* configure: (Rebuilt).
	* configure.ac: (libtool_VERSION=17.0.0)

2020-06-18  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* Makefile.in: (Rebuilt).
	* aclocal.m4: (Rebuilt).
	* autogen.sh: Execute automake including dependencies.
	* configure: (Rebuilt).
	* libm2cor/Makefile.in: (Rebuilt).
	* libm2iso/Makefile.in: (Rebuilt).
	* libm2log/Makefile.am: SYSTEM.def is a dependency using
	  BUILT_SOURCES.
	* libm2log/Makefile.in: (Rebuilt).
	* libm2min/Makefile.in: (Rebuilt).
	* libm2pim/Makefile.in: (Rebuilt).

2020-06-15  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* libm2pim/Makefile.am: Added SYSTEM.def as a dependency.
	* libm2log/Makefile.am: Added SYSTEM.def as a dependency.

2020-06-11  Matthias Klose  <doko@ubuntu.com>

	* Makefile.am: Reordered libraries.
	* Makefile.in: (Rebuilt).
	* libm2pim/Makefile.am: (libm2pim_la_LIBADD) Added
          definition.
	* libm2pim/Makefile.in: (Rebuilt).

2020-05-01  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* libm2cor/KeyBoardLEDs.c: Include sys/ioctl.h
          and stdio.h to fix implicit declarations of ioctl and
	  perror.
	* libm2iso/RTco.c: Include <sys/select.h>.
	* libm2pim/SysExceptions.c: (HAVE_STDIO_H) Checked
	  and stdio.h included to fix perror implicit declaration.

2020-04-29  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* libm2pim/wrapc.c: (HAVE_SYS_TYPES_H) checked to include
          sys/types.h.  (HAVE_TIME_H) checked to include time.h.
          Fixes missing prototype errors.  (HAVE_UNISTD_H) checked
	  to include unistd.h to fix getuid missing prototype.

2020-01-08  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* libm2min/libc.c: (exit) noreturn added.
	  (abort) noreturn added.

2019-12-10  Matthias Klose  <doko@ubuntu.com>

	* libm2cor/Makefile.am: (libsubdir) Corrected using
	  target_alias.
	* libm2iso/Makefile.am: (libsubdir) Corrected using
	  target_alias.
	* libm2log/Makefile.am: (libsubdir) Corrected using
	  target_alias.
	* libm2min/Makefile.am: (libsubdir) Corrected using
	  target_alias.
	* libm2pim/Makefile.am: (libsubdir) Corrected using
	  target_alias.
	* libm2cor/Makefile.in: Regenerated.
	* libm2iso/Makefile.in: Regenerated.
	* libm2log/Makefile.in: Regenerated.
	* libm2min/Makefile.in: Regenerated.
	* libm2pim/Makefile.in: Regenerated.

2019-12-10  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* libm2iso/RTco.c: Corrected include files
          for target building.

2019-12-09  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* configure.ac: Remove reference to config dir.
          (ACX_NONCANONICAL_TARGET) Removed.
	* libm2cor/Makefile.in: Regenerated.
	* libm2iso/Makefile.in: Regenerated.
	* libm2log/Makefile.in: Regenerated.
	* libm2min/Makefile.in: Regenerated.
	* libm2pim/Makefile.in: Regenerated.
	* configure.ac: (LT_INIT) Used instead of AM_PROG_LIBTOOL.
	* libm2cor/Makefile.in: Regenerated.
	* libm2iso/Makefile.in: Regenerated.
	* libm2log/Makefile.in: Regenerated.
	* libm2min/Makefile.in: Regenerated.
	* libm2pim/Makefile.in: Regenerated.

2019-12-04  Matthias Klose  <doko@ubuntu.com>

	* Makefile.in: Regenerated.
	* aclocal.m4: Regenerated from automake-1.15.1.
	* libm2cor/Makefile.am: Added -version-info.
	* libm2cor/Makefile.in: Regenerated.
	* libm2iso/Makefile.am: Added -version-info.
	* libm2iso/Makefile.in: Regenerated.
	* libm2log/Makefile.am: Added -version-info.
	* libm2log/Makefile.in: Regenerated.
	* libm2min/Makefile.am: Added -version-info.
	* libm2min/Makefile.in: Regenerated.
	* libm2pim/Makefile.am: Added -version-info.
	* libm2pim/Makefile.in: Regenerated.

2019-12-03  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* libm2min/Makefile.am: (M2LIBDIR) Corrected
          destination directory to m2/m2min.

2019-11-19  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* multilib fixes
	* Makefile.am: (MULTIBUILDTOP) propagate.
	* Makefile.in: (Regenerated).
	* configure: (Regenerated).
	* configure.ac: (ACX_NONCANONICAL_TARGET) Removed.
	* libm2cor/Makefile.am: (MULTIBUILDTOP) Propagate.
	* libm2cor/Makefile.in: (Regenerated).
	* libm2iso/Makefile.am: (MULTIBUILDTOP) Propagate.
	* libm2iso/Makefile.in: (Regenerated).
	* libm2log/Makefile.am: (MULTIBUILDTOP) Propagate.
	* libm2log/Makefile.in: (Regenerated).
	* libm2min/Makefile.am: (MULTIBUILDTOP) Propagate.
	* libm2min/Makefile.in: (Regenerated).
	* libm2pim/Makefile.am: (MULTIBUILDTOP) Propagate.
	* libm2pim/Makefile.in: (Regenerated).

2019-11-18  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* configure: (Regenerated).
	* configure.ac: (libtool_VERSION=15.0.0).
	Place AM_ENABLE_MULTILIB above GCC_NO_EXECUTABLES.

2019-11-13  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* libm2pim/Selective.c: Changed to GPL3+ and fixed
	  formatting.
	* libm2pim/SysExceptions.c: Changed to GPL3+ and fixed
	  formatting.
	* libm2pim/UnixArgs.c: Changed to GPL3+ and fixed
	  formatting.
	* libm2pim/dtoa.c: Changed to GPL3+ and fixed
	  formatting.
	* libm2pim/errno.c: Changed to GPL3+ and fixed
	  formatting.
	* libm2pim/getopt.c: Changed to GPL3+ and fixed
	  formatting.
	* libm2pim/ldtoa.c: Changed to GPL3+ and fixed
	  formatting.
	* libm2pim/sckt.c: Changed to GPL3+ and fixed
	  formatting.
	* libm2pim/target.c: Changed to GPL3+ and fixed
	  formatting.
	* libm2pim/termios.c: Changed to GPL3+ and fixed
	  formatting.
	* libm2pim/wrapc.c: Changed to GPL3+ and fixed
	  formatting.

2019-11-12  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* libm2cor/KeyBoardLEDs.c: GPLv3 and reformatted.
	* libm2iso/ChanConsts.h: GPLv3 and reformatted.
	* libm2iso/ErrnoCategory.c: GPLv3 and reformatted.
	* libm2iso/RTco.c: GPLv3 and reformatted.
	* libm2iso/wrapsock.c: GPLv3 and reformatted.
	* libm2iso/wraptime.c: GPLv3 and reformatted.
	* libm2cor/Makefile.am: GPLv3.
	* libm2iso/Makefile.am: GPLv3.
	* libm2log/Makefile.am: GPLv3.
	* libm2min/Makefile.am: GPLv3.
	* libm2pim/Makefile.am: GPLv3.
	* libm2log/Break.c: GPLv3 and reformatted.
	* libm2min/libc.c: GPLv3 and reformatted.

2019-11-04  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* libcor/Makefile.am: (MULTIOSSUBDIR) quote test.
	* libiso/Makefile.am: (MULTIOSSUBDIR) quote test.
	* libpim/Makefile.am: (MULTIOSSUBDIR) quote test.
	* liblog/Makefile.am: (MULTIOSSUBDIR) quote test.
	* libmin/Makefile.am: (MULTIOSSUBDIR) quote test.
	* libulm/Makefile.am: (MULTIOSSUBDIR) quote test.
	* libpth/Makefile.am: (MULTIOSSUBDIR) quote test.
	* libcor/Makefile.in: Regenerated.
	* libiso/Makefile.in: Regenerated.
	* libpim/Makefile.in: Regenerated.
	* liblog/Makefile.in: Regenerated.
	* libmin/Makefile.in: Regenerated.
	* libulm/Makefile.in: Regenerated.
	* libpth/Makefile.in: Regenerated.

2019-10-25  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* libcor/Makefile.am: Added -fm2-g -g.
	* libiso/Makefile.am: Added -fm2-g -g and include
          path to include ../
	* libiso/RTco.c: Call HALT if the thread fails to
          find itself.  Place initialized inside critical region.
	* libpim/Makefile.am: Added -fm2-g -g.

2019-09-27  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* libulm: Removed.
	* Makefile.am: Removed Ulm libaraies.
	* configure.ac: Removed Ulm libaraies.

2019-08-01  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* libpim/Makefile.am: (M2MODS) added GetOpt.mod
          and OptLib.mod.  (M2DEFS) added GetOpt.def,
          OptLib.def and getopt.def.  (libgm2_la_SOURCES)
          added wrapc.c and getopt.c.

2019-07-10  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* libpth/Makefile.am: Use $(MAKE) rather than make.
	* libcor/KeyBoardLEDs.c: Reformatted to GNU coding
          standards.  Also added/corrected empty functions for non
	  linux targets.  Fixed the GPL comment.

2019-07-09  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	* Makefile.am: (multilib.am) Included.

2019-04-03  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* Makefile.in: Regenerated.
	* aclocal.m4: Regenerated.
	* autogen.sh: Removed version numbers.
	* config/libtool.m4: New version of the file
	  taken from libgo/config.
	* configure: Regenerated.
	* configure.ac: Updated version numbers.
	* libcor/Makefile.in: Regenerated.
	* libiso/Makefile.in: Regenerated.
	* liblog/Makefile.in: Regenerated.
	* libmin/Makefile.in: Regenerated.
	* libpim/Makefile.in: Regenerated.
	* libulm/Makefile.in: Regenerated.

2019-03-29  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* configure: Regenerated.
	* configure.ac: Implement --enable-libpth-m2
	* libpth/Makefile.am: Pass FLAGS_TO_PASS to make.
          move install rules into pth subdirectory.
	* libpth/pth/Makefile.am: Added install rules.

2018-11-27  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* libpim/wrapc.c: Reformatted according to GNU
          coding standards.  Also defended against macro omissions.
	* libiso/wraptime.c: Fixed function declaration
	  and erroneous return value.

2018-04-16  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* Makefile.am: Specify the libtool location.
	* Makefile.in: Regenerated.
	* aclocal.m4: Regenerated.
	* autogen.sh: Corrected script to regenerate
          using the correct macros and versions of autoconf tools.
	* configure: Regenerated.
	* configure.ac: Regenerated.
	* libcor/Makefile.in: Regenerated.
	* libiso/Makefile.in: Regenerated.
	* liblog/Makefile.in: Regenerated.
	* libmin/Makefile.in: Regenerated.
	* libpim/Makefile.in: Regenerated.
	* libulm/Makefile.in: Regenerated.

2018-04-14  Gaius Mulley  <gaius.mulley@southwales.ac.uk>

	* Makefile.am: Changed to reference the config directory.
	* Makefile.in: Regenerated.
	* aclocal.m4: Regenerated.
	* autogen.sh: Added new script.
	* config.h.in: Regenerated.
	* configure: Regenerated.
	* configure.ac: Minor corrections.
	* libcor/Makefile.am: Use $(LIBTOOL).
	* libcor/Makefile.in: Regenerated.
	* libiso/Makefile.am: Use $(LIBTOOL).
	* libiso/Makefile.in: Regenerated.
	* liblog/Makefile.am: Use $(LIBTOOL).
	* liblog/Makefile.in: Regenerated.
	* libmin/Makefile.am: Use $(LIBTOOL).
	* libmin/Makefile.in: Regenerated.
	* libpim/Makefile.am: Use $(LIBTOOL).
	* libpim/Makefile.in: Regenerated.
	* libulm/Makefile.am: Use $(LIBTOOL).
	* libulm/Makefile.in: Regenerated.

2018-04-10  Gaius Mulley  <gaius@gnu.org>

	* configure.ac: Added test to AM_ENABLE_MULTILIB.
	* Makefile.in: Regenerated.
	* aclocal.m4: Regenerated.
	* autogen.sh: Updated.
	* config.h.in: Regenerated.
	* configure: Regenerated.
	* libcor/Makefile.in: Regenerated.
	* libiso/Makefile.in: Regenerated.
	* liblog/Makefile.in: Regenerated.
	* libmin/Makefile.am: Added -fno-m2-plugin
	* libmin/Makefile.in: Regenerated.
	* libpim/Makefile.in: Regenerated.
	* libulm/Makefile.in: Regenerated.

2017-12-27  Gaius Mulley  <gaius@gnu.org>

	* libpim/wrapc.c: (wrapc_isfinite) New function.

2016-06-09  Gaius Mulley  <gaius@gnu.org>

	* libpim/dtoa.c: Use memmove instead of memcpy.

2016-03-14  Gaius Mulley  <gaius@gnu.org>

	* libpim/wrapc.c: Corrected spacing.

2014-12-24  Gaius Mulley  <gaius@gnu.org>

	* sckt.c: Added conditional import of
	  stdio.h as reported by Christoph Schlegel.

2014-12-23  Gaius Mulley  <gaius@gnu.org>

	* libulm/Makefile.am: Added pim libs to the
	  path on the createUlmSys command.

2014-12-22  Gaius Mulley  <gaius@gnu.org>

	* libulm/Makefile.am: Added rule to build
	  SYSTEM.def as a built source.

2014-12-06  Gaius Mulley  <gaius@gnu.org>

	* libcor/Makefile.in: Add .la to list of SUFFIXES.
	  install .la archive.
	* libcor/Makefile.am: Install .la archive.
	* libiso/Makefile.in: Install .la archive.
	* libiso/Makefile.am: Install .la archive.
	* liblog/Makefile.am: Install .la archive.
	* liblog/Makefile.in: Install .la archive.
	* libmin/Makefile.am: Install .la archive.
	* libmin/Makefile.in: Install .la archive.
	* libpim/Makefile.am: Install .la archive.
	* libpim/Makefile.in: Install .la archive.
	* libulm/Makefile.am: Install .la archive.
	* libulm/Makefile.in: Install .la archive.

2014-12-05  Gaius Mulley  <gaius@gnu.org>

	* libmin/Makefile.am: Add .la to the list of SUFFIXES.
	* libulm/Makefile.am: Add .la to the list of SUFFIXES.
	* libpim/Makefile.am: Add .la to the list of SUFFIXES.
	* libcor/Makefile.am: Add .la to the list of SUFFIXES.
	* liblog/Makefile.am: Add .la to the list of SUFFIXES.
	* libiso/Makefile.am: Add .la to the list of SUFFIXES.

2014-07-11  Gaius Mulley  <gaius@gnu.org>

	* complete rewrite and restructuring of libgm2.
	* gcc-versionno/libgm2/aclocal.m4: (Rebuilt)
	* gcc-versionno/libgm2/autogen.sh: (Rebuilt)
	* gcc-versionno/libgm2/config.h.in: (New file)
	* gcc-versionno/libgm2/configure: (Rebuilt)
	* gcc-versionno/libgm2/configure.ac: (New file)
	* gcc-versionno/libgm2/libcor: (New directory)
	* gcc-versionno/libgm2/libiso: (New directory)
	* gcc-versionno/libgm2/liblog: (New directory)
	* gcc-versionno/libgm2/libmin: (New directory)
	* gcc-versionno/libgm2/libpim: (New directory)
	* gcc-versionno/libgm2/libulm: (New directory)
	* gcc-versionno/libgm2/Makefile.am: (New file)
	* gcc-versionno/libgm2/Makefile.in: (rebuilt)
	* gcc-versionno/libgm2/p2c: (New directory)

2013-12-06  Gaius Mulley  <gaius@gnu.org>

	* gcc-versionno/gcc/gm2/Make-lang.in: Changed flag to -fpim
	and changed path appropriately.

2013-12-05  Gaius Mulley  <gaius@gnu.org>

	* gm2/libgm2/Makefile.in: Build coroutine version of SYSTEM.def.

2013-10-17  Gaius Mulley  <gaius@gnu.org>

	* gm2/libgm2/Makefile.in: Corrected install of iso SYSTEM.def.
	Ensure that we copy form the object directory and avoid the
	template version in the source directory.

2013-09-14  Gaius Mulley  <gaius@gnu.org>

	* gm2/libgm2/Makefile.in: Many changes to allow more libraries
	to build and also build SYSTEM.def for the pim, iso and min
	libraries.

2013-07-08  Gaius Mulley  <gaius@gnu.org>

	* gm2/ChangeLog: (New file).
	* gm2/libgm2/Makefile.in: Added install rules.  Many of which
	were adapted from gcc/gm2/Make-file.in.
-----------------------------
New file: ./libm2min/Makefile.am
-----------------------------
# Makefile for libm2min.
#   Copyright 2013-2022  Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING3.  If not see
# <http://www.gnu.org/licenses/>.

SUFFIXES = .c .mod .def .o .obj .lo .a .la

ACLOCAL_AMFLAGS = -I . -I .. -I ../config

VPATH = . @srcdir@/../../gcc/m2/gm2-libs-min

# Multilib support.
MAKEOVERRIDES=

version := $(shell $(CC) -dumpversion)

# Directory in which the compiler finds libraries etc.
libsubdir = $(libdir)/gcc/$(target_alias)/$(version)
# Used to install the shared libgcc.
slibdir = @slibdir@

toolexeclibdir=@toolexeclibdir@
toolexecdir=@toolexecdir@

MULTIDIR := $(shell $(CC) $(CFLAGS) -print-multi-directory)
MULTIOSDIR := $(shell $(CC) $(CFLAGS) -print-multi-os-directory)

MULTIOSSUBDIR := $(shell if test x$(MULTIOSDIR) != x.; then echo /$(MULTIOSDIR); fi)
inst_libdir = $(libsubdir)$(MULTISUBDIR)
inst_slibdir = $(slibdir)$(MULTIOSSUBDIR)


# Work around what appears to be a GNU make bug handling MAKEFLAGS
# values defined in terms of make variables, as is the case for CC and
# friends when we are called from the top level Makefile.
AM_MAKEFLAGS = \
        "GCC_DIR=$(GCC_DIR)" \
        "GM2_SRC=$(GM2_SRC)" \
	"AR_FLAGS=$(AR_FLAGS)" \
	"CC_FOR_BUILD=$(CC_FOR_BUILD)" \
	"CC_FOR_TARGET=$(CC_FOR_TARGET)" \
	"GM2_FOR_TARGET=$(GM2_FOR_TARGET)" \
	"CFLAGS=$(CFLAGS)" \
	"CXXFLAGS=$(CXXFLAGS)" \
	"CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
	"CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
	"INSTALL=$(INSTALL)" \
	"INSTALL_DATA=$(INSTALL_DATA)" \
	"INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
	"INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
	"LDFLAGS=$(LDFLAGS)" \
	"LIBCFLAGS=$(LIBCFLAGS)" \
	"LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
	"MAKE=$(MAKE)" \
	"MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
        "MULTISUBDIR=$(MULTISUBDIR)" \
        "MULTIOSDIR=$(MULTIOSDIR)" \
        "MULTIBUILDTOP=$(MULTIBUILDTOP)" \
        "MULTIFLAGS=$(MULTIFLAGS)" \
	"PICFLAG=$(PICFLAG)" \
	"PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
	"SHELL=$(SHELL)" \
	"RUNTESTFLAGS=$(RUNTESTFLAGS)" \
	"exec_prefix=$(exec_prefix)" \
	"infodir=$(infodir)" \
	"libdir=$(libdir)" \
	"includedir=$(includedir)" \
	"prefix=$(prefix)" \
	"tooldir=$(tooldir)" \
        "toolexeclibdir=$(toolexeclibdir)" \
        "toolexecdir=$(toolexecdir)" \
	"gxx_include_dir=$(gxx_include_dir)" \
	"AR=$(AR)" \
	"AS=$(AS)" \
	"LD=$(LD)" \
	"RANLIB=$(RANLIB)" \
	"NM=$(NM)" \
	"NM_FOR_BUILD=$(NM_FOR_BUILD)" \
	"NM_FOR_TARGET=$(NM_FOR_TARGET)" \
	"DESTDIR=$(DESTDIR)" \
	"WERROR=$(WERROR)" \
        "TARGET_LIB_PATH_libgm2=$(TARGET_LIB_PATH_libgm2)"

# Subdir rules rely on $(FLAGS_TO_PASS)
FLAGS_TO_PASS = $(AM_MAKEFLAGS)

M2DEFS = libc.def  M2RTS.def \
         SYSTEM.def

M2MODS = M2RTS.mod  SYSTEM.mod

libm2mindir = libm2min
toolexeclib_LTLIBRARIES = libm2min.la
libm2min_la_SOURCES = $(M2MODS) libc.c
libm2min_la_DEPENDENCIES = SYSTEM.def $(addsuffix .lo, $(basename $(libm2min_la_SOURCES)))
libm2min_la_CFLAGS = -I. -I$(GM2_SRC)/gm2-libs-min -I$(GM2_SRC)/gm2-libs
libm2min_la_M2FLAGS = -I. -I$(GM2_SRC)/gm2-libs-min -I$(GM2_SRC)/gm2-libs -fno-exceptions -fno-m2-plugin
libm2min_la_LINK = $(LINK) -version-info $(libtool_VERSION)
BUILT_SOURCES = SYSTEM.def
CLEANFILES = SYSTEM.def

M2LIBDIR = /m2/m2min/

.mod.lo:
	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(GM2_FOR_TARGET) -c $(CFLAGS_FOR_TARGET) $(LIBCFLAGS) $(libm2min_la_M2FLAGS) $< -o $@

libc.o: $(GM2_SRC)/gm2-libs-min/libc.c


SYSTEM.def: Makefile
	echo "CC = $(CC_FOR_BUILD)  CC_FOR_TARGET = $(CC_FOR_TARGET)  GM2 = $(GM2)  GM2_FOR_TARGET = $(GM2_FOR_TARGET) GM2_FOR_BUILD = $(GM2_FOR_BUILD)"
	bash $(GM2_SRC)/tools-src/makeSystem -fpim \
             $(GM2_SRC)/gm2-libs-min/SYSTEM.def \
             $(GM2_SRC)/gm2-libs-min/SYSTEM.mod \
             -I$(GM2_SRC)/gm2-libs-min:$(GM2_SRC)/gm2-libs \
             "$(GM2_FOR_TARGET) -fno-exceptions" $@

install-data-local: force
	mkdir -p $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)
	$(INSTALL_DATA) .libs/libm2min.la $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)
	chmod 644 $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)libm2min.la
	$(INSTALL_DATA) .libs/libm2min.a $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)
	chmod 644 $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)libm2min.a
	$(RANLIB) $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)libm2min.a
	for i in $(M2DEFS) $(M2MODS) ; do \
           if [ -f $$i ] ; then \
              $(INSTALL_DATA) $$i '$(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)'; \
           elif [ -f @srcdir@/../../gcc/m2/gm2-libs-min/$$i ] ; then \
              $(INSTALL_DATA) @srcdir@/../../gcc/m2/gm2-libs-min/$$i '$(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)'; \
           else \
              echo "cannot find $$i" ; exit 1 ; \
           fi ; \
           chmod 644 $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)$$i ; \
	done

force:
-----------------------------
New file: ./libm2min/libc.c
-----------------------------
/* libc.c provides minimal stubs for expected symbols used by the rts.

Copyright (C) 2010-2022 Free Software Foundation, Inc.
Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.

This file is part of GNU Modula-2.

GNU Modula-2 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GNU Modula-2 is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

void abort (void) __attribute__ ((noreturn));
void exit (int) __attribute__ ((noreturn));

void abort (void)
{
  /* you should add your system dependant code here.  */
  __builtin_unreachable ();
}

void exit (int i)
{
  /* you should add your system dependant code here.  */
  __builtin_unreachable ();
}
-----------------------------
New file: ./Makefile.am
-----------------------------
# Makefile for libgm2.
#   Copyright 2013-2022  Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING3.  If not see
# <http://www.gnu.org/licenses/>.
#
#
# if this file is changed then you need to run
#
# autoreconf2.64
#
# Modula-2 support.
AUTOMAKE_OPTIONS = 1.8 foreign

SUFFIXES = .c .mod .def .o .obj .lo .a

ACLOCAL_AMFLAGS = -I . -I .. -I ../config

# Multilib support.
MAKEOVERRIDES=

AM_CFLAGS = -I $(srcdir)/../libgcc -I $(MULTIBUILDTOP)../../gcc/include

gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
TOP_GCCDIR := $(shell cd $(top_srcdir) && cd .. && pwd)

GCC_DIR = $(TOP_GCCDIR)/gcc
GM2_SRC = $(GCC_DIR)/m2

toolexeclibdir=@toolexeclibdir@
toolexecdir=@toolexecdir@

SUBDIRS = libm2min libm2log libm2cor libm2iso libm2pim
GM2_BUILDDIR := $(shell pwd)


# Work around what appears to be a GNU make bug handling MAKEFLAGS
# values defined in terms of make variables, as is the case for CC and
# friends when we are called from the top level Makefile.
AM_MAKEFLAGS = \
        "GCC_DIR=$(GCC_DIR)" \
        "GM2_SRC=$(GM2_SRC)" \
	"AR_FLAGS=$(AR_FLAGS)" \
	"CC_FOR_BUILD=$(CC_FOR_BUILD)" \
	"CC_FOR_TARGET=$(CC_FOR_TARGET)" \
	"GM2_FOR_TARGET=$(GM2_FOR_TARGET)" \
	"CFLAGS=$(CFLAGS)" \
	"CXXFLAGS=$(CXXFLAGS)" \
	"CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
	"CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
	"INSTALL=$(INSTALL)" \
	"INSTALL_DATA=$(INSTALL_DATA)" \
	"INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
	"INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
	"LDFLAGS=$(LDFLAGS)" \
	"LIBCFLAGS=$(LIBCFLAGS)" \
	"LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
	"MAKE=$(MAKE)" \
	"MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
        "MULTIBUILDTOP=$(MULTIBUILDTOP)" \
        "MULTISUBDIR=$(MULTISUBDIR)" \
        "MULTIOSDIR=$(MULTIDIR)" \
        "MULTIFLAGS=$(MULTIFLAGS)" \
	"PICFLAG=$(PICFLAG)" \
	"PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
	"SHELL=$(SHELL)" \
	"RUNTESTFLAGS=$(RUNTESTFLAGS)" \
	"exec_prefix=$(exec_prefix)" \
	"infodir=$(infodir)" \
	"libdir=$(libdir)" \
	"includedir=$(includedir)" \
	"prefix=$(prefix)" \
	"tooldir=$(tooldir)" \
        "toolexeclibdir=$(toolexeclibdir)" \
        "toolexecdir=$(toolexecdir)" \
	"gxx_include_dir=$(gxx_include_dir)" \
	"AR=$(AR)" \
	"AS=$(AS)" \
	"LD=$(LD)" \
	"RANLIB=$(RANLIB)" \
	"NM=$(NM)" \
	"NM_FOR_BUILD=$(NM_FOR_BUILD)" \
	"NM_FOR_TARGET=$(NM_FOR_TARGET)" \
	"DESTDIR=$(DESTDIR)" \
	"WERROR=$(WERROR)" \
        "TARGET_LIB_PATH=$(TARGET_LIB_PATH)" \
        "TARGET_LIB_PATH_libgm2=$(TARGET_LIB_PATH_libgm2)" \
	"LIBTOOL=$(GM2_BUILDDIR)/libtool"

# Subdir rules rely on $(FLAGS_TO_PASS)
FLAGS_TO_PASS = $(AM_MAKEFLAGS)

include $(top_srcdir)/../multilib.am
-----------------------------
New file: ./libm2cor/KeyBoardLEDs.c
-----------------------------
/* KeyBoardLEDs.c provide access to the keyboard LEDs.

Copyright (C) 2005-2022 Free Software Foundation, Inc.
Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.

This file is part of GNU Modula-2.

GNU Modula-2 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GNU Modula-2 is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

#if defined(linux)

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/kd.h>
#include <sys/ioctl.h>
#include <stdio.h>

#if !defined(TRUE)
#   define TRUE (1==1)
#endif
#if !defined(FALSE)
#   define FALSE (1==0)
#endif

#include <stdlib.h>

static int fd;
static int initialized = FALSE;


void
KeyBoardLEDs_SwitchScroll (int scrolllock)
{
  unsigned char leds;
  int r = ioctl (fd, KDGETLED, &leds);
  if (scrolllock)
    leds = leds | LED_SCR;
  else
    leds = leds & (~ LED_SCR);
  r = ioctl (fd, KDSETLED, leds);
}

void
KeyBoardLEDs_SwitchNum (int numlock)
{
  unsigned char leds;
  int r = ioctl (fd, KDGETLED, &leds);
  if (numlock)
    leds = leds | LED_NUM;
  else
    leds = leds & (~ LED_NUM);
  r = ioctl (fd, KDSETLED, leds);
}

void
KeyBoardLEDs_SwitchCaps (int capslock)
{
  unsigned char leds;
  int r = ioctl (fd, KDGETLED, &leds);
  if (capslock)
    leds = leds | LED_CAP;
  else
    leds = leds & (~ LED_CAP);
  r = ioctl (fd, KDSETLED, leds);
}

void
KeyBoardLEDs_SwitchLeds (int numlock, int capslock, int scrolllock)
{
  KeyBoardLEDs_SwitchScroll (scrolllock);
  KeyBoardLEDs_SwitchNum (numlock);
  KeyBoardLEDs_SwitchCaps (capslock);
}

void
_M2_KeyBoardLEDs_init (void)
{
  if (! initialized)
    {
      initialized = TRUE;
      fd = open ("/dev/tty", O_RDONLY);
      if (fd == -1)
	{
	  perror ("unable to open /dev/tty");
	  exit (1);
	}
    }
}

#else
void
KeyBoardLEDs_SwitchLeds (int numlock, int capslock, int scrolllock)
{
}

void
KeyBoardLEDs_SwitchScroll (int scrolllock)
{
}

void
KeyBoardLEDs_SwitchNum (int numlock)
{
}

void
KeyBoardLEDs_SwitchCaps (int capslock)
{
}

void
_M2_KeyBoardLEDs_init (void)
{
}

#endif

void
_M2_KeyBoardLEDs_finish (void)
{
}
-----------------------------
New file: ./libm2cor/Makefile.am
-----------------------------
# Makefile for libm2cor.
#   Copyright 2013-2022  Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING3.  If not see
# <http://www.gnu.org/licenses/>.

SUFFIXES = .c .mod .def .o .obj .lo .a .la

ACLOCAL_AMFLAGS = -I . -I .. -I ../config

VPATH = . @srcdir@ @srcdir@/../../gcc/m2/gm2-libs-coroutines

# Multilib support.
MAKEOVERRIDES=

version := $(shell $(CC) -dumpversion)

# Directory in which the compiler finds libraries etc.
libsubdir = $(libdir)/gcc/$(target_alias)/$(version)
# Used to install the shared libgcc.
slibdir = @slibdir@

toolexeclibdir=@toolexeclibdir@
toolexecdir=@toolexecdir@

MULTIDIR := $(shell $(CC) $(CFLAGS) -print-multi-directory)
MULTIOSDIR := $(shell $(CC) $(CFLAGS) -print-multi-os-directory)

MULTIOSSUBDIR := $(shell if test x$(MULTIOSDIR) != x.; then echo /$(MULTIOSDIR); fi)
inst_libdir = $(libsubdir)$(MULTISUBDIR)
inst_slibdir = $(slibdir)$(MULTIOSSUBDIR)


# Work around what appears to be a GNU make bug handling MAKEFLAGS
# values defined in terms of make variables, as is the case for CC and
# friends when we are called from the top level Makefile.
AM_MAKEFLAGS = \
        "GCC_DIR=$(GCC_DIR)" \
        "GM2_SRC=$(GM2_SRC)" \
	"AR_FLAGS=$(AR_FLAGS)" \
	"CC_FOR_BUILD=$(CC_FOR_BUILD)" \
	"CC_FOR_TARGET=$(CC_FOR_TARGET)" \
	"GM2_FOR_TARGET=$(GM2_FOR_TARGET)" \
	"CFLAGS=$(CFLAGS)" \
	"CXXFLAGS=$(CXXFLAGS)" \
	"CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
	"CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
	"INSTALL=$(INSTALL)" \
	"INSTALL_DATA=$(INSTALL_DATA)" \
	"INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
	"INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
	"LDFLAGS=$(LDFLAGS)" \
	"LIBCFLAGS=$(LIBCFLAGS)" \
	"LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
	"MAKE=$(MAKE)" \
	"MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
        "MULTIBUILDTOP=$(MULTIBUILDTOP)" \
        "MULTISUBDIR=$(MULTISUBDIR)" \
        "MULTIOSDIR=$(MULTIOSDIR)" \
        "MULTIFLAGS=$(MULTIFLAGS)" \
	"PICFLAG=$(PICFLAG)" \
	"PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
	"SHELL=$(SHELL)" \
	"RUNTESTFLAGS=$(RUNTESTFLAGS)" \
	"exec_prefix=$(exec_prefix)" \
	"infodir=$(infodir)" \
	"libdir=$(libdir)" \
	"includedir=$(includedir)" \
	"prefix=$(prefix)" \
	"tooldir=$(tooldir)" \
        "toolexeclibdir=$(toolexeclibdir)" \
        "toolexecdir=$(toolexecdir)" \
	"gxx_include_dir=$(gxx_include_dir)" \
	"AR=$(AR)" \
	"AS=$(AS)" \
	"LD=$(LD)" \
	"RANLIB=$(RANLIB)" \
	"NM=$(NM)" \
	"NM_FOR_BUILD=$(NM_FOR_BUILD)" \
	"NM_FOR_TARGET=$(NM_FOR_TARGET)" \
	"DESTDIR=$(DESTDIR)" \
	"WERROR=$(WERROR)" \
        "TARGET_LIB_PATH_libgm2=$(TARGET_LIB_PATH_libgm2)"

# Subdir rules rely on $(FLAGS_TO_PASS)
FLAGS_TO_PASS = $(AM_MAKEFLAGS)


if BUILD_CORLIB
M2DEFS = Debug.def  Executive.def \
         KeyBoardLEDs.def  SYSTEM.def \
         TimerHandler.def

M2MODS = Debug.mod  Executive.mod \
         SYSTEM.mod  TimerHandler.mod

toolexeclib_LTLIBRARIES = libm2cor.la

libm2cor_la_SOURCES = $(M2MODS) KeyBoardLEDs.c

nodist_EXTRA_libm2cor_la_SOURCES = dummy.c  ## forces automake to generate the LINK definition

libm2cordir = libm2cor
libm2cor_la_DEPENDENCIES = SYSTEM.def $(addsuffix .lo, $(basename $(libm2cor_la_SOURCES)))
libm2cor_la_M2FLAGS = -I. -I$(GM2_SRC)/gm2-libs-coroutines -I$(GM2_SRC)/gm2-libs -I$(GM2_SRC)/gm2-libs-iso -fm2-g -g
libm2cor_la_LINK = $(LINK) -version-info $(libtool_VERSION)
BUILT_SOURCES = SYSTEM.def
CLEANFILES = SYSTEM.def

M2LIBDIR = /m2/m2cor/

SYSTEM.def: Makefile
	bash $(GM2_SRC)/tools-src/makeSystem -fpim \
             $(GM2_SRC)/gm2-libs-coroutines/SYSTEM.def \
             $(GM2_SRC)/gm2-libs-coroutines/SYSTEM.mod \
             -I$(GM2_SRC)/gm2-libs-coroutines:$(GM2_SRC)/gm2-libs:$(GM2_SRC)/gm2-libs-iso \
             "$(GM2_FOR_TARGET)" $@

.mod.lo:
	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(GM2_FOR_TARGET) -c $(CFLAGS_FOR_TARGET) $(LIBCFLAGS) $(libm2cor_la_M2FLAGS) $< -o $@

install-data-local: force
	mkdir -p $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)
	$(INSTALL_DATA) .libs/libm2cor.la $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)
	chmod 644 $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)libm2cor.la
	$(INSTALL_DATA) .libs/libm2cor.a $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)
	chmod 644 $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)libm2cor.a
	$(RANLIB) $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)libm2cor.a
	for i in $(M2DEFS) $(M2MODS) ; do \
           if [ -f $$i ] ; then \
              $(INSTALL_DATA) $$i '$(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)'; \
           elif [ -f @srcdir@/../../gcc/m2/gm2-libs-coroutines/$$i ] ; then \
              $(INSTALL_DATA) @srcdir@/../../gcc/m2/gm2-libs-coroutines/$$i '$(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)'; \
           else \
              echo "cannot find $$i" ; exit 1 ; \
           fi ; \
           chmod 644 $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)$$i ; \
	done

force:

endif
-----------------------------
New file: ./libm2pim/dtoa.c
-----------------------------
/* dtoa.c convert double to ascii and visa versa.

Copyright (C) 2009-2022 Free Software Foundation, Inc.
Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.

This file is part of GNU Modula-2.

GNU Modula-2 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GNU Modula-2 is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

#define GM2

#include <config.h>

#if defined(HAVE_STRINGS)
#include <strings.h>
#endif

#if defined(HAVE_STRING)
#include <string.h>
#endif

#if defined(HAVE_STDDEF_H)
/* Obtain a definition for NULL.  */
#include <stddef.h>
#endif

#if defined(HAVE_STDIO_H)
/* Obtain a definition for NULL.  */
#include <stdio.h>
#endif

#if defined(HAVE_TIME_H)
/* Obtain a definition for NULL.  */
#include <time.h>
#endif

#if defined(HAVE_STRING_H)
/* Obtain a definition for NULL.  */
#include <string.h>
#endif

#if defined(HAVE_WCHAR_H)
/* Obtain a definition for NULL.  */
#include <wchar.h>
#endif

#if defined(HAVE_STDLIB_H)
/* Obtain a prototype for free and malloc.  */
#include <stdlib.h>
#endif

#if !defined(NULL)
#define NULL (void *)0
#endif

#if !defined(TRUE)
#define TRUE (1 == 1)
#endif
#if !defined(FALSE)
#define FALSE (1 == 0)
#endif

#if defined(HAVE_STDLIB_H)
#if !defined(_ISOC99_SOURCE)
#define _ISOC99_SOURCE
#endif
#include <stdlib.h>
#endif

#if defined(HAVE_ERRNO_H)
#include <errno.h>
#endif

#if defined(HAVE_SYS_ERRNO_H)
#include <sys/errno.h>
#endif

#if defined(HAVE_STRING_H)

#define MAX_FP_DIGITS 500

typedef enum Mode { maxsignicant, decimaldigits } Mode;

/* maxsignicant:  return a string containing max(1,ndigits) significant
   digits.  The return string contains the string produced by ecvt.

   decimaldigits: return a string produced by fcvt.  The string will
   contain ndigits past the decimal point (ndigits may be negative).  */

double
dtoa_strtod (const char *s, int *error)
{
  char *endp;
  double d;

#if defined(HAVE_ERRNO_H)
  errno = 0;
#endif
  d = strtod (s, &endp);
  if (endp != NULL && (*endp == '\0'))
#if defined(HAVE_ERRNO_H)
    *error = (errno != 0);
#else
    *error = FALSE;
#endif
  else
    *error = TRUE;
  return d;
}

/* dtoa_calcmaxsig calculates the position of the decimal point
   it also removes the decimal point and exponent from string, p.  */

int
dtoa_calcmaxsig (char *p, int ndigits)
{
  char *e;
  char *o;
  int x;

  e = index (p, 'E');
  if (e == NULL)
    x = 0;
  else
    {
      *e = (char)0;
      x = atoi (e + 1);
    }

  o = index (p, '.');
  if (o == NULL)
    return strlen (p) + x;
  else
    {
      memmove (o, o + 1, ndigits - (o - p));
      return o - p + x;
    }
}

/* dtoa_calcdecimal calculates the position of the decimal point
   it also removes the decimal point and exponent from string, p.
   It truncates the digits in p accordingly to ndigits.
   Ie ndigits is the number of digits after the '.'.  */

int
dtoa_calcdecimal (char *p, int str_size, int ndigits)
{
  char *e;
  char *o;
  int x;
  int l;

  e = index (p, 'E');
  if (e == NULL)
    x = 0;
  else
    {
      *e = (char)0;
      x = atoi (e + 1);
    }

  l = strlen (p);
  o = index (p, '.');
  if (o == NULL)
    x += strlen (p);
  else
    {
      int m = strlen (o);
      memmove (o, o + 1, l - (o - p));
      if (m > 0)
        o[m - 1] = '0';
      x += o - p;
    }
  if ((x + ndigits >= 0) && (x + ndigits < str_size))
    p[x + ndigits] = (char)0;
  return x;
}

int
dtoa_calcsign (char *p, int str_size)
{
  if (p[0] == '-')
    {
      memmove (p, p + 1, str_size - 1);
      return TRUE;
    }
  else
    return FALSE;
}

char *
dtoa_dtoa (double d, int mode, int ndigits, int *decpt, int *sign)
{
  char format[50];
  char *p;
  int r;
  switch (mode)
    {

    case maxsignicant:
      ndigits += 20; /* Enough for exponent.  */
      p = malloc (ndigits);
      snprintf (format, 50, "%s%d%s", "%.", ndigits - 20, "E");
      snprintf (p, ndigits, format, d);
      *sign = dtoa_calcsign (p, ndigits);
      *decpt = dtoa_calcmaxsig (p, ndigits);
      return p;
    case decimaldigits:
      p = malloc (MAX_FP_DIGITS + 20);
      snprintf (format, 50, "%s%d%s", "%.", MAX_FP_DIGITS, "E");
      snprintf (p, MAX_FP_DIGITS + 20, format, d);
      *sign = dtoa_calcsign (p, MAX_FP_DIGITS + 20);
      *decpt = dtoa_calcdecimal (p, MAX_FP_DIGITS + 20, ndigits);
      return p;
    default:
      abort ();
    }
}

#endif

#if defined(GM2)
/* GNU Modula-2 linking hooks.  */

void
_M2_dtoa_init (void)
{
}
void
_M2_dtoa_finish (void)
{
}
#endif
-----------------------------
New file: ./libm2pim/Selective.c
-----------------------------
/* Selective.c provide access to timeval and select.

Copyright (C) 2009-2022 Free Software Foundation, Inc.
Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.

This file is part of GNU Modula-2.

GNU Modula-2 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GNU Modula-2 is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

#include <config.h>

#if defined(HAVE_STDDEF_H)
/* Obtain a definition for NULL.  */
#include <stddef.h>
#endif

#if defined(HAVE_STDIO_H)
/* Obtain a definition for NULL.  */
#include <stdio.h>
#endif

#if defined(HAVE_SYS_TIME_H)
#include <sys/time.h>
#endif

#if defined(HAVE_TIME_H)
/* Obtain a definition for NULL.  */
#include <time.h>
#endif

#if defined(HAVE_STRING_H)
/* Obtain a definition for NULL.  */
#include <string.h>
#endif

#if defined(HAVE_WCHAR_H)
/* Obtain a definition for NULL.  */
#include <wchar.h>
#endif

#if defined(HAVE_STDLIB_H)
/* Obtain a prototype for free and malloc.  */
#include <stdlib.h>
#endif

#if defined(HAVE_SYS_TYPES_H)
#include <sys/types.h>
#endif

#if defined(HAVE_UNISTD_H)
#include <unistd.h>
#endif

#if !defined(NULL)
#define NULL (void *)0
#endif

#if defined(HAVE_SELECT)
#define FDSET_T fd_set
#else
#define FDSET_T void
#endif

/* Select wrap a call to the C select.  */

#if defined(HAVE_STRUCT_TIMEVAL)
int
Selective_Select (int nooffds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout)
{
  return select (nooffds, readfds, writefds, exceptfds, timeout);
}
#else
int
Selective_Select (int nooffds, void *readfds, void *writefds, void *exceptfds,
                  void *timeout)
{
  return 0;
}
#endif

/* InitTime initializes a timeval structure and returns a pointer to it.  */

#if defined(HAVE_STRUCT_TIMEVAL)
struct timeval *
Selective_InitTime (unsigned int sec, unsigned int usec)
{
  struct timeval *t = (struct timeval *)malloc (sizeof (struct timeval));

  t->tv_sec = (long int)sec;
  t->tv_usec = (long int)usec;
  return t;
}

void
Selective_GetTime (struct timeval *t, unsigned int *sec, unsigned int *usec)
{
  *sec = (unsigned int)t->tv_sec;
  *usec = (unsigned int)t->tv_usec;
}

void
Selective_SetTime (struct timeval *t, unsigned int sec, unsigned int usec)
{
  t->tv_sec = sec;
  t->tv_usec = usec;
}

/* KillTime frees the timeval structure and returns NULL.  */

struct timeval *
Selective_KillTime (struct timeval *t)
{
#if defined(HAVE_STDLIB_H)
  free (t);
#endif
  return NULL;
}

/* InitSet returns a pointer to a FD_SET.  */

FDSET_T *
Selective_InitSet (void)
{
#if defined(HAVE_STDLIB_H)
  FDSET_T *s = (FDSET_T *)malloc (sizeof (FDSET_T));

  return s;
#else
  return NULL
#endif
}

/* KillSet frees the FD_SET and returns NULL.  */

FDSET_T *
Selective_KillSet (FDSET_T *s)
{
#if defined(HAVE_STDLIB_H)
  free (s);
#endif
  return NULL;
}

/* FdZero generate an empty set.  */

void
Selective_FdZero (FDSET_T *s)
{
  FD_ZERO (s);
}

/* FS_Set include an element, fd, into set, s.  */

void
Selective_FdSet (int fd, FDSET_T *s)
{
  FD_SET (fd, s);
}

/* FdClr exclude an element, fd, from the set, s.  */

void
Selective_FdClr (int fd, FDSET_T *s)
{
  FD_CLR (fd, s);
}

/* FdIsSet return TRUE if, fd, is present in set, s.  */

int
Selective_FdIsSet (int fd, FDSET_T *s)
{
  return FD_ISSET (fd, s);
}

/* GetTimeOfDay fills in a record, Timeval, filled in with the
   current system time in seconds and microseconds.
   It returns zero (see man 3p gettimeofday).  */

int
Selective_GetTimeOfDay (struct timeval *t)
{
  return gettimeofday (t, NULL);
}
#else

void *
Selective_InitTime (unsigned int sec, unsigned int usec)
{
  return NULL;
}

void *
Selective_KillTime (void *t)
{
  return NULL;
}

void
Selective_GetTime (void *t, unsigned int *sec, unsigned int *usec)
{
}

void
Selective_SetTime (void *t, unsigned int sec, unsigned int usec)
{
}

FDSET_T *
Selective_InitSet (void)
{
  return NULL;
}

FDSET_T *
Selective_KillSet (void)
{
  return NULL;
}

void
Selective_FdZero (void *s)
{
}

void
Selective_FdSet (int fd, void *s)
{
}

void
Selective_FdClr (int fd, void *s)
{
}

int
Selective_FdIsSet (int fd, void *s)
{
  return 0;
}

int
Selective_GetTimeOfDay (void *t)
{
  return -1;
}
#endif

/* MaxFdsPlusOne returns max (a + 1, b + 1).  */

int
Selective_MaxFdsPlusOne (int a, int b)
{
  if (a > b)
    return a + 1;
  else
    return b + 1;
}

/* WriteCharRaw writes a single character to the file descriptor.  */

void
Selective_WriteCharRaw (int fd, char ch)
{
  write (fd, &ch, 1);
}

/* ReadCharRaw read and return a single char from file descriptor, fd.  */

char
Selective_ReadCharRaw (int fd)
{
  char ch;

  read (fd, &ch, 1);
  return ch;
}

void
_M2_Selective_init ()
{
}

void
_M2_Selective_finish ()
{
}
-----------------------------
New file: ./libm2pim/termios.c
-----------------------------
/* termios.c provide access to the terminal.

Copyright (C) 2010-2022 Free Software Foundation, Inc.
Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.

This file is part of GNU Modula-2.

GNU Modula-2 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GNU Modula-2 is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

#include <config.h>

#if defined(HAVE_STDIO_H)
#include <stdio.h>
#endif
#if defined(HAVE_STDARG_H)
#include <stdarg.h>
#endif
#if defined(HAVE_STDLIB_H)
#include <stdlib.h>
#endif
#if defined(HAVE_STRING_H)
#include <string.h>
#endif
#if defined(HAVE_STRINGS_H)
#include <strings.h>
#endif

#ifdef TERMIOS_NEEDS_XOPEN_SOURCE
#define _XOPEN_SOURCE
#endif

#if defined(HAVE_SYS_TYPES_H)
#include <sys/types.h>
#endif

#if defined(HAVE_TERMIOS_H)
#include <termios.h>
#endif

void _M2_termios_init (void);
void _M2_termios_finish (void);

#if defined(HAVE_TERMIOS_H)

#define EXPORT(X) termios##_##X

typedef enum {
  vintr,
  vquit,
  verase,
  vkill,
  veof,
  vtime,
  vmin,
  vswtc,
  vstart,
  vstop,
  vsusp,
  veol,
  vreprint,
  vdiscard,
  vwerase,
  vlnext,
  veol2
} ControlChar;

typedef enum {
  /* Input flag bits.  */
  ignbrk,
  ibrkint,
  ignpar,
  iparmrk,
  inpck,
  istrip,
  inlcr,
  igncr,
  icrnl,
  iuclc,
  ixon,
  ixany,
  ixoff,
  imaxbel,
  /* Output flag bits.  */
  opost,
  olcuc,
  onlcr,
  ocrnl,
  onocr,
  onlret,
  ofill,
  ofdel,
  onl0,
  onl1,
  ocr0,
  ocr1,
  ocr2,
  ocr3,
  otab0,
  otab1,
  otab2,
  otab3,
  obs0,
  obs1,
  off0,
  off1,
  ovt0,
  ovt1,
  /* Baud rate.  */
  b0,
  b50,
  b75,
  b110,
  b135,
  b150,
  b200,
  b300,
  b600,
  b1200,
  b1800,
  b2400,
  b4800,
  b9600,
  b19200,
  b38400,
  b57600,
  b115200,
  b240400,
  b460800,
  b500000,
  b576000,
  b921600,
  b1000000,
  b1152000,
  b1500000,
  b2000000,
  b2500000,
  b3000000,
  b3500000,
  b4000000,
  maxbaud,
  crtscts,
  /* Character size.  */
  cs5,
  cs6,
  cs7,
  cs8,
  cstopb,
  cread,
  parenb,
  parodd,
  hupcl,
  clocal,
  /* Local flags.  */
  lisig,
  licanon,
  lxcase,
  lecho,
  lechoe,
  lechok,
  lechonl,
  lnoflsh,
  ltopstop,
  lechoctl,
  lechoprt,
  lechoke,
  lflusho,
  lpendin,
  liexten
} Flag;

/* Prototypes.  */
void *EXPORT (InitTermios) (void);
void *EXPORT (KillTermios) (struct termios *p);
int EXPORT (cfgetospeed) (struct termios *t);
int EXPORT (cfgetispeed) (struct termios *t);
int EXPORT (cfsetospeed) (struct termios *t, unsigned int b);
int EXPORT (cfsetispeed) (struct termios *t, unsigned int b);
int EXPORT (cfsetspeed) (struct termios *t, unsigned int b);
int EXPORT (tcgetattr) (int fd, struct termios *t);
int EXPORT (tcsetattr) (int fd, int option, struct termios *t);
void EXPORT (cfmakeraw) (struct termios *t);
int EXPORT (tcsendbreak) (int fd, int duration);
int EXPORT (tcdrain) (int fd);
int EXPORT (tcflushi) (int fd);
int EXPORT (tcflusho) (int fd);
int EXPORT (tcflushio) (int fd);
int EXPORT (tcflowoni) (int fd);
int EXPORT (tcflowoffi) (int fd);
int EXPORT (tcflowono) (int fd);
int EXPORT (tcflowoffo) (int fd);
int EXPORT (GetFlag) (struct termios *t, Flag f, int *b);
int EXPORT (SetFlag) (struct termios *t, Flag f, int b);
int EXPORT (GetChar) (struct termios *t, ControlChar c, char *ch);
int EXPORT (SetChar) (struct termios *t, ControlChar c, char ch);
int EXPORT (tcsnow) (void);
int EXPORT (tcsflush) (void);
int EXPORT (tcsdrain) (void);
int doSetUnset (unsigned int *bitset, unsigned int mask, int value);

/* InitTermios new data structure.   */

void *EXPORT (InitTermios) (void)
{
  struct termios *p = (struct termios *)malloc (sizeof (struct termios));

  memset (p, 0, sizeof (struct termios));
  return p;
}

/* KillTermios delete data structure.  */

void *EXPORT (KillTermios) (struct termios *p)
{
  free (p);
  return NULL;
}

/* tcsnow return the value of TCSANOW.  */

int EXPORT (tcsnow) (void) { return TCSANOW; }

/* tcsdrain return the value of TCSADRAIN.  */

int EXPORT (tcsdrain) (void) { return TCSADRAIN; }

/* tcsflush return the value of TCSAFLUSH.  */

int EXPORT (tcsflush) (void) { return TCSAFLUSH; }

/* cfgetospeed return output baud rate.  */

int EXPORT (cfgetospeed) (struct termios *t) { return cfgetospeed (t); }

/* cfgetispeed return input baud rate.  */

int EXPORT (cfgetispeed) (struct termios *t) { return cfgetispeed (t); }

/* cfsetospeed set output baud rate.  */

int EXPORT (cfsetospeed) (struct termios *t, unsigned int b)
{
  return cfsetospeed (t, b);
}

/* cfsetispeed set input baud rate.  */

int EXPORT (cfsetispeed) (struct termios *t, unsigned int b)
{
  return cfsetispeed (t, b);
}

/* cfsetspeed set input and output baud rate.  */

int EXPORT (cfsetspeed) (struct termios *t, unsigned int b)
{
  int val = cfsetispeed (t, b);
  if (val == 0)
    return cfsetospeed (t, b);
  cfsetospeed (t, b);
  return val;
}

/* tcgetattr get state of, fd, into, t.  */

int EXPORT (tcgetattr) (int fd, struct termios *t)
{
  return tcgetattr (fd, t);
}

/* tcsetattr set state of, fd, to, t, using option.  */

int EXPORT (tcsetattr) (int fd, int option, struct termios *t)
{
  return tcsetattr (fd, option, t);
}

/* cfmakeraw sets the terminal to raw mode.  */

void EXPORT (cfmakeraw) (struct termios *t)
{
#if defined(HAVE_CFMAKERAW)
  return cfmakeraw (t);
#endif
}

/* tcsendbreak send zero bits for duration.  */

int EXPORT (tcsendbreak) (int fd, int duration)
{
  return tcsendbreak (fd, duration);
}

/* tcdrain waits for pending output to be written on, fd.  */

int EXPORT (tcdrain) (int fd) { return tcdrain (fd); }

/* tcflushi flush input.  */

int EXPORT (tcflushi) (int fd)
{
#if defined(TCIFLUSH)
  return tcflush (fd, TCIFLUSH);
#else
  return 1;
#endif
}

/* tcflusho flush output.  */

int EXPORT (tcflusho) (int fd)
{
#if defined(TCOFLUSH)
  return tcflush (fd, TCOFLUSH);
#else
  return 1;
#endif
}

/* tcflushio flush input and output.  */

int EXPORT (tcflushio) (int fd)
{
#if defined(TCIOFLUSH)
  return tcflush (fd, TCIOFLUSH);
#else
  return 1;
#endif
}

/* tcflowoni restart input on, fd.  */

int EXPORT (tcflowoni) (int fd)
{
#if defined(TCION)
  return tcflow (fd, TCION);
#else
  return 1;
#endif
}

/* tcflowoffi stop input on, fd.  */

int EXPORT (tcflowoffi) (int fd)
{
#if defined(TCIOFF)
  return tcflow (fd, TCIOFF);
#else
  return 1;
#endif
}

/* tcflowono restart output on, fd.  */

int EXPORT (tcflowono) (int fd)
{
#if defined(TCOON)
  return tcflow (fd, TCOON);
#else
  return 1;
#endif
}

/* tcflowoffo stop output on, fd.  */

int EXPORT (tcflowoffo) (int fd)
{
#if defined(TCOOFF)
  return tcflow (fd, TCOOFF);
#else
  return 1;
#endif
}

/* doSetUnset applies mask or undoes mask depending upon value.  */

int
doSetUnset (unsigned int *bitset, unsigned int mask, int value)
{
  if (value)
    (*bitset) |= mask;
  else
    (*bitset) &= (~mask);
  return 1;
}

/* GetFlag sets a flag value from, t, in, b, and returns TRUE
   if, t, supports, f.  */

int EXPORT (GetFlag) (struct termios *t, Flag f, int *b)
{
  switch (f)
    {

    case ignbrk:
#if defined(IGNBRK)
      *b = ((t->c_iflag & IGNBRK) == IGNBRK);
      return 1;
#else
      return 0;
#endif
    case ibrkint:
#if defined(BRKINT)
      *b = ((t->c_iflag & BRKINT) == BRKINT);
      return 1;
#else
      return 0;
#endif
    case ignpar:
#if defined(IGNPAR)
      *b = ((t->c_iflag & IGNPAR) == IGNPAR);
      return 1;
#else
      return 0;
#endif
    case iparmrk:
#if defined(PARMRK)
      *b = ((t->c_iflag & PARMRK) == PARMRK);
      return 1;
#else
      return 0;
#endif
    case inpck:
#if defined(INPCK)
      *b = ((t->c_iflag & INPCK) == INPCK);
      return 1;
#else
      return 0;
#endif
    case istrip:
#if defined(ISTRIP)
      *b = ((t->c_iflag & ISTRIP) == ISTRIP);
      return 1;
#else
      return 0;
#endif
    case inlcr:
#if defined(INLCR)
      *b = ((t->c_iflag & INLCR) == INLCR);
      return 1;
#else
      return 0;
#endif
    case igncr:
#if defined(IGNCR)
      *b = ((t->c_iflag & IGNCR) == IGNCR);
      return 1;
#else
      return 0;
#endif
    case icrnl:
#if defined(ICRNL)
      *b = ((t->c_iflag & ICRNL) == ICRNL);
      return 1;
#else
      return 0;
#endif
    case iuclc:
#if defined(IUCLC)
      *b = ((t->c_iflag & IUCLC) == IUCLC);
      return 1;
#else
      return 0;
#endif
    case ixon:
#if defined(IXON)
      *b = ((t->c_iflag & IXON) == IXON);
      return 1;
#else
      return 0;
#endif
    case ixany:
#if defined(IXANY)
      *b = ((t->c_iflag & IXANY) == IXANY);
      return 1;
#else
      return 0;
#endif
    case ixoff:
#if defined(IXOFF)
      *b = ((t->c_iflag & IXOFF) == IXOFF);
      return 1;
#else
      return 0;
#endif
    case imaxbel:
#if defined(IMAXBEL)
      *b = ((t->c_iflag & IMAXBEL) == IMAXBEL);
      return 1;
#else
      return 0;
#endif
    case opost:
#if defined(OPOST)
      *b = ((t->c_oflag & OPOST) == OPOST);
      return 1;
#else
      return 0;
#endif
    case olcuc:
#if defined(OLCUC)
      *b = ((t->c_oflag & OLCUC) == OLCUC);
      return 1;
#else
      return 0;
#endif
    case onlcr:
#if defined(ONLCR)
      *b = ((t->c_oflag & ONLCR) == ONLCR);
      return 1;
#else
      return 0;
#endif
    case ocrnl:
#if defined(OCRNL)
      *b = ((t->c_oflag & OCRNL) == OCRNL);
      return 1;
#else
      return 0;
#endif
    case onocr:
#if defined(ONOCR)
      *b = ((t->c_oflag & ONOCR) == ONOCR);
      return 1;
#else
      return 0;
#endif
    case onlret:
#if defined(ONLRET)
      *b = ((t->c_oflag & ONLRET) == ONLRET);
      return 1;
#else
      return 0;
#endif
    case ofill:
#if defined(OFILL)
      *b = ((t->c_oflag & OFILL) == OFILL);
      return 1;
#else
      return 0;
#endif
    case ofdel:
#if defined(OFDEL)
      *b = ((t->c_oflag & OFDEL) == OFDEL);
      return 1;
#else
      return 0;
#endif
    case onl0:
#if defined(NL0)
      *b = ((t->c_oflag & NL0) == NL0);
      return 1;
#else
      return 0;
#endif
    case onl1:
#if defined(NL1)
      *b = ((t->c_oflag & NL1) == NL1);
      return 1;
#else
      return 0;
#endif
    case ocr0:
#if defined(CR0)
      *b = ((t->c_oflag & CR0) == CR0);
      return 1;
#else
      return 0;
#endif
    case ocr1:
#if defined(CR1)
      *b = ((t->c_oflag & CR1) == CR1);
      return 1;
#else
      return 0;
#endif
    case ocr2:
#if defined(CR2)
      *b = ((t->c_oflag & CR2) == CR2);
      return 1;
#else
      return 0;
#endif
    case ocr3:
#if defined(CR3)
      *b = ((t->c_oflag & CR3) == CR3);
      return 1;
#else
      return 0;
#endif
    case otab0:
#if defined(TAB0)
      *b = ((t->c_oflag & TAB0) == TAB0);
      return 1;
#else
      return 0;
#endif
    case otab1:
#if defined(TAB1)
      *b = ((t->c_oflag & TAB1) == TAB1);
      return 1;
#else
      return 0;
#endif
    case otab2:
#if defined(TAB2)
      *b = ((t->c_oflag & TAB2) == TAB2);
      return 1;
#else
      return 0;
#endif
    case otab3:
#if defined(TAB3)
      *b = ((t->c_oflag & TAB3) == TAB3);
      return 1;
#else
      return 0;
#endif
    case obs0:
#if defined(BS0)
      *b = ((t->c_oflag & BS0) == BS0);
      return 1;
#else
      return 0;
#endif
    case obs1:
#if defined(BS1)
      *b = ((t->c_oflag & BS1) == BS1);
      return 1;
#else
      return 0;
#endif
    case off0:
#if defined(FF0)
      *b = ((t->c_oflag & FF0) == FF0);
      return 1;
#else
      return 0;
#endif
    case off1:
#if defined(FF1)
      *b = ((t->c_oflag & FF1) == FF1);
      return 1;
#else
      return 0;
#endif
    case ovt0:
#if defined(VT0)
      *b = ((t->c_oflag & VT0) == VT0);
      return 1;
#else
      return 0;
#endif
    case ovt1:
#if defined(VT1)
      *b = ((t->c_oflag & VT1) == VT1);
      return 1;
#else
      return 0;
#endif
    case b0:
#if defined(B0)
      *b = ((t->c_cflag & B0) == B0);
      return 1;
#else
      return 0;
#endif
    case b50:
#if defined(B50)
      *b = ((t->c_cflag & B50) == B50);
      return 1;
#else
      return 0;
#endif
    case b75:
#if defined(B75)
      *b = ((t->c_cflag & B75) == B75);
      return 1;
#else
      return 0;
#endif
    case b110:
#if defined(B110)
      *b = ((t->c_cflag & B110) == B110);
      return 1;
#else
      return 0;
#endif
    case b135:
#if defined(B134)
      *b = ((t->c_cflag & B134) == B134);
      return 1;
#else
      return 0;
#endif
    case b150:
#if defined(B150)
      *b = ((t->c_cflag & B150) == B150);
      return 1;
#else
      return 0;
#endif
    case b200:
#if defined(B200)
      *b = ((t->c_cflag & B200) == B200);
      return 1;
#else
      return 0;
#endif
    case b300:
#if defined(B300)
      *b = ((t->c_cflag & B300) == B300);
      return 1;
#else
      return 0;
#endif
    case b600:
#if defined(B600)
      *b = ((t->c_cflag & B600) == B600);
      return 1;
#else
      return 0;
#endif
    case b1200:
#if defined(B1200)
      *b = ((t->c_cflag & B1200) == B1200);
      return 1;
#else
      return 0;
#endif
    case b1800:
#if defined(B1800)
      *b = ((t->c_cflag & B1800) == B1800);
      return 1;
#else
      return 0;
#endif
    case b2400:
#if defined(B2400)
      *b = ((t->c_cflag & B2400) == B2400);
      return 1;
#else
      return 0;
#endif
    case b4800:
#if defined(B4800)
      *b = ((t->c_cflag & B4800) == B4800);
      return 1;
#else
      return 0;
#endif
    case b9600:
#if defined(B9600)
      *b = ((t->c_cflag & B9600) == B9600);
      return 1;
#else
      return 0;
#endif
    case b19200:
#if defined(B19200)
      *b = ((t->c_cflag & B19200) == B19200);
      return 1;
#else
      return 0;
#endif
    case b38400:
#if defined(B38400)
      *b = ((t->c_cflag & B38400) == B38400);
      return 1;
#else
      return 0;
#endif
    case b57600:
#if defined(B57600)
      *b = ((t->c_cflag & B57600) == B57600);
      return 1;
#else
      return 0;
#endif
    case b115200:
#if defined(B115200)
      *b = ((t->c_cflag & B115200) == B115200);
      return 1;
#else
      return 0;
#endif
    case b240400:
#if defined(B230400)
      *b = ((t->c_cflag & B230400) == B230400);
      return 1;
#else
      return 0;
#endif
    case b460800:
#if defined(B460800)
      *b = ((t->c_cflag & B460800) == B460800);
      return 1;
#else
      return 0;
#endif
    case b500000:
#if defined(B500000)
      *b = ((t->c_cflag & B500000) == B500000);
      return 1;
#else
      return 0;
#endif
    case b576000:
#if defined(B576000)
      *b = ((t->c_cflag & B576000) == B576000);
      return 1;
#else
      return 0;
#endif
    case b921600:
#if defined(B921600)
      *b = ((t->c_cflag & B921600) == B921600);
      return 1;
#else
      return 0;
#endif
    case b1000000:
#if defined(B1000000)
      *b = ((t->c_cflag & B1000000) == B1000000);
      return 1;
#else
      return 0;
#endif
    case b1152000:
#if defined(B1152000)
      *b = ((t->c_cflag & B1152000) == B1152000);
      return 1;
#else
      return 0;
#endif
    case b1500000:
#if defined(B1500000)
      *b = ((t->c_cflag & B1500000) == B1500000);
      return 1;
#else
      return 0;
#endif
    case b2000000:
#if defined(B2000000)
      *b = ((t->c_cflag & B2000000) == B2000000);
      return 1;
#else
      return 0;
#endif
    case b2500000:
#if defined(B2500000)
      *b = ((t->c_cflag & B2500000) == B2500000);
      return 1;
#else
      return 0;
#endif
    case b3000000:
#if defined(B3000000)
      *b = ((t->c_cflag & B3000000) == B3000000);
      return 1;
#else
      return 0;
#endif
    case b3500000:
#if defined(B3500000)
      *b = ((t->c_cflag & B3500000) == B3500000);
      return 1;
#else
      return 0;
#endif
    case b4000000:
#if defined(B4000000)
      *b = ((t->c_cflag & B4000000) == B4000000);
      return 1;
#else
      return 0;
#endif
    case maxbaud:
#if defined(MAX)
      *b = ((t->c_cflag & __MAX_BAUD) == __MAX_BAUD);
      return 1;
#else
      return 0;
#endif
    case crtscts:
#if defined(CRTSCTS)
      *b = ((t->c_cflag & CRTSCTS) == CRTSCTS);
      return 1;
#else
      return 0;
#endif
    case cs5:
#if defined(CS5)
      *b = ((t->c_cflag & CS5) == CS5);
      return 1;
#else
      return 0;
#endif
    case cs6:
#if defined(CS6)
      *b = ((t->c_cflag & CS6) == CS6);
      return 1;
#else
      return 0;
#endif
    case cs7:
#if defined(CS7)
      *b = ((t->c_cflag & CS7) == CS7);
      return 1;
#else
      return 0;
#endif
    case cs8:
#if defined(CS8)
      *b = ((t->c_cflag & CS8) == CS8);
      return 1;
#else
      return 0;
#endif
    case cstopb:
#if defined(CSTOPB)
      *b = ((t->c_cflag & CSTOPB) == CSTOPB);
      return 1;
#else
      return 0;
#endif
    case cread:
#if defined(CREAD)
      *b = ((t->c_cflag & CREAD) == CREAD);
      return 1;
#else
      return 0;
#endif
    case parenb:
#if defined(PARENB)
      *b = ((t->c_cflag & PARENB) == PARENB);
      return 1;
#else
      return 0;
#endif
    case parodd:
#if defined(PARODD)
      *b = ((t->c_cflag & PARODD) == PARODD);
      return 1;
#else
      return 0;
#endif
    case hupcl:
#if defined(HUPCL)
      *b = ((t->c_cflag & HUPCL) == HUPCL);
      return 1;
#else
      return 0;
#endif
    case clocal:
#if defined(CLOCAL)
      *b = ((t->c_cflag & CLOCAL) == CLOCAL);
      return 1;
#else
      return 0;
#endif
    case lisig:
#if defined(ISIG)
      *b = ((t->c_lflag & ISIG) == ISIG);
      return 1;
#else
      return 0;
#endif
    case licanon:
#if defined(ICANON)
      *b = ((t->c_lflag & ICANON) == ICANON);
      return 1;
#else
      return 0;
#endif
    case lxcase:
#if defined(XCASE)
      *b = ((t->c_lflag & XCASE) == XCASE);
      return 1;
#else
      return 0;
#endif
    case lecho:
#if defined(ECHO)
      *b = ((t->c_lflag & ECHO) == ECHO);
      return 1;
#else
      return 0;
#endif
    case lechoe:
#if defined(ECHOE)
      *b = ((t->c_lflag & ECHOE) == ECHOE);
      return 1;
#else
      return 0;
#endif
    case lechok:
#if defined(ECHOK)
      *b = ((t->c_lflag & ECHOK) == ECHOK);
      return 1;
#else
      return 0;
#endif
    case lechonl:
#if defined(ECHONL)
      *b = ((t->c_lflag & ECHONL) == ECHONL);
      return 1;
#else
      return 0;
#endif
    case lnoflsh:
#if defined(NOFLSH)
      *b = ((t->c_lflag & NOFLSH) == NOFLSH);
      return 1;
#else
      return 0;
#endif
    case ltopstop:
#if defined(TOSTOP)
      *b = ((t->c_lflag & TOSTOP) == TOSTOP);
      return 1;
#else
      return 0;
#endif
    case lechoctl:
#if defined(ECHOCTL)
      *b = ((t->c_lflag & ECHOCTL) == ECHOCTL);
      return 1;
#else
      return 0;
#endif
    case lechoprt:
#if defined(ECHOPRT)
      *b = ((t->c_lflag & ECHOPRT) == ECHOPRT);
      return 1;
#else
      return 0;
#endif
    case lechoke:
#if defined(ECHOKE)
      *b = ((t->c_lflag & ECHOKE) == ECHOKE);
      return 1;
#else
      return 0;
#endif
    case lflusho:
#if defined(FLUSHO)
      *b = ((t->c_lflag & FLUSHO) == FLUSHO);
      return 1;
#else
      return 0;
#endif
    case lpendin:
#if defined(PENDIN)
      *b = ((t->c_lflag & PENDIN) == PENDIN);
      return 1;
#else
      return 0;
#endif
    case liexten:
#if defined(IEXTEN)
      *b = ((t->c_lflag & IEXTEN) == IEXTEN);
      return 1;
#else
      return 0;
#endif
    }
  return 0;
}

/* SetFlag sets a flag value in, t, to, b, and returns TRUE if
   this flag value is supported.  */

int EXPORT (SetFlag) (struct termios *t, Flag f, int b)
{
  switch (f)
    {

    case ignbrk:
#if defined(IGNBRK)
      return doSetUnset (&t->c_iflag, IGNBRK, b);
#else
      return 0;
#endif
    case ibrkint:
#if defined(BRKINT)
      return doSetUnset (&t->c_iflag, BRKINT, b);
#else
      return 0;
#endif
    case ignpar:
#if defined(IGNPAR)
      return doSetUnset (&t->c_iflag, IGNPAR, b);
#else
      return 0;
#endif
    case iparmrk:
#if defined(PARMRK)
      return doSetUnset (&t->c_iflag, PARMRK, b);
#else
      return 0;
#endif
    case inpck:
#if defined(INPCK)
      return doSetUnset (&t->c_iflag, INPCK, b);
#else
      return 0;
#endif
    case istrip:
#if defined(ISTRIP)
      return doSetUnset (&t->c_iflag, ISTRIP, b);
#else
      return 0;
#endif
    case inlcr:
#if defined(INLCR)
      return doSetUnset (&t->c_iflag, INLCR, b);
#else
      return 0;
#endif
    case igncr:
#if defined(IGNCR)
      return doSetUnset (&t->c_iflag, IGNCR, b);
#else
      return 0;
#endif
    case icrnl:
#if defined(ICRNL)
      return doSetUnset (&t->c_iflag, ICRNL, b);
#else
      return 0;
#endif
    case iuclc:
#if defined(IUCLC)
      return doSetUnset (&t->c_iflag, IUCLC, b);
#else
      return 0;
#endif
    case ixon:
#if defined(IXON)
      return doSetUnset (&t->c_iflag, IXON, b);
#else
      return 0;
#endif
    case ixany:
#if defined(IXANY)
      return doSetUnset (&t->c_iflag, IXANY, b);
#else
      return 0;
#endif
    case ixoff:
#if defined(IXOFF)
      return doSetUnset (&t->c_iflag, IXOFF, b);
#else
      return 0;
#endif
    case imaxbel:
#if defined(IMAXBEL)
      return doSetUnset (&t->c_iflag, IMAXBEL, b);
#else
      return 0;
#endif
    case opost:
#if defined(OPOST)
      return doSetUnset (&t->c_oflag, OPOST, b);
#else
      return 0;
#endif
    case olcuc:
#if defined(OLCUC)
      return doSetUnset (&t->c_oflag, OLCUC, b);
#else
      return 0;
#endif
    case onlcr:
#if defined(ONLCR)
      return doSetUnset (&t->c_oflag, ONLCR, b);
#else
      return 0;
#endif
    case ocrnl:
#if defined(OCRNL)
      return doSetUnset (&t->c_oflag, OCRNL, b);
#else
      return 0;
#endif
    case onocr:
#if defined(ONOCR)
      return doSetUnset (&t->c_oflag, ONOCR, b);
#else
      return 0;
#endif
    case onlret:
#if defined(ONLRET)
      return doSetUnset (&t->c_oflag, ONLRET, b);
#else
      return 0;
#endif
    case ofill:
#if defined(OFILL)
      return doSetUnset (&t->c_oflag, OFILL, b);
#else
      return 0;
#endif
    case ofdel:
#if defined(OFDEL)
      return doSetUnset (&t->c_oflag, OFDEL, b);
#else
      return 0;
#endif
    case onl0:
#if defined(NL0)
      return doSetUnset (&t->c_oflag, NL0, b);
#else
      return 0;
#endif
    case onl1:
#if defined(NL1)
      return doSetUnset (&t->c_oflag, NL1, b);
#else
      return 0;
#endif
    case ocr0:
#if defined(CR0)
      return doSetUnset (&t->c_oflag, CR0, b);
#else
      return 0;
#endif
    case ocr1:
#if defined(CR1)
      return doSetUnset (&t->c_oflag, CR1, b);
#else
      return 0;
#endif
    case ocr2:
#if defined(CR2)
      return doSetUnset (&t->c_oflag, CR2, b);
#else
      return 0;
#endif
    case ocr3:
#if defined(CR3)
      return doSetUnset (&t->c_oflag, CR3, b);
#else
      return 0;
#endif
    case otab0:
#if defined(TAB0)
      return doSetUnset (&t->c_oflag, TAB0, b);
#else
      return 0;
#endif
    case otab1:
#if defined(TAB1)
      return doSetUnset (&t->c_oflag, TAB1, b);
#else
      return 0;
#endif
    case otab2:
#if defined(TAB2)
      return doSetUnset (&t->c_oflag, TAB2, b);
#else
      return 0;
#endif
    case otab3:
#if defined(TAB3)
      return doSetUnset (&t->c_oflag, TAB3, b);
#else
      return 0;
#endif
    case obs0:
#if defined(BS0)
      return doSetUnset (&t->c_oflag, BS0, b);
#else
      return 0;
#endif
    case obs1:
#if defined(BS1)
      return doSetUnset (&t->c_oflag, BS1, b);
#else
      return 0;
#endif
    case off0:
#if defined(FF0)
      return doSetUnset (&t->c_oflag, FF0, b);
#else
      return 0;
#endif
    case off1:
#if defined(FF1)
      return doSetUnset (&t->c_oflag, FF1, b);
#else
      return 0;
#endif
    case ovt0:
#if defined(VT0)
      return doSetUnset (&t->c_oflag, VT0, b);
#else
      return 0;
#endif
    case ovt1:
#if defined(VT1)
      return doSetUnset (&t->c_oflag, VT1, b);
#else
      return 0;
#endif
    case b0:
#if defined(B0)
      return doSetUnset (&t->c_cflag, B0, b);
#else
      return 0;
#endif
    case b50:
#if defined(B50)
      return doSetUnset (&t->c_cflag, B50, b);
#else
      return 0;
#endif
    case b75:
#if defined(B75)
      return doSetUnset (&t->c_cflag, B75, b);
#else
      return 0;
#endif
    case b110:
#if defined(B110)
      return doSetUnset (&t->c_cflag, B110, b);
#else
      return 0;
#endif
    case b135:
#if defined(B134)
      return doSetUnset (&t->c_cflag, B134, b);
#else
      return 0;
#endif
    case b150:
#if defined(B150)
      return doSetUnset (&t->c_cflag, B150, b);
#else
      return 0;
#endif
    case b200:
#if defined(B200)
      return doSetUnset (&t->c_cflag, B200, b);
#else
      return 0;
#endif
    case b300:
#if defined(B300)
      return doSetUnset (&t->c_cflag, B300, b);
#else
      return 0;
#endif
    case b600:
#if defined(B600)
      return doSetUnset (&t->c_cflag, B600, b);
#else
      return 0;
#endif
    case b1200:
#if defined(B1200)
      return doSetUnset (&t->c_cflag, B1200, b);
#else
      return 0;
#endif
    case b1800:
#if defined(B1800)
      return doSetUnset (&t->c_cflag, B1800, b);
#else
      return 0;
#endif
    case b2400:
#if defined(B2400)
      return doSetUnset (&t->c_cflag, B2400, b);
#else
      return 0;
#endif
    case b4800:
#if defined(B4800)
      return doSetUnset (&t->c_cflag, B4800, b);
#else
      return 0;
#endif
    case b9600:
#if defined(B9600)
      return doSetUnset (&t->c_cflag, B9600, b);
#else
      return 0;
#endif
    case b19200:
#if defined(B19200)
      return doSetUnset (&t->c_cflag, B19200, b);
#else
      return 0;
#endif
    case b38400:
#if defined(B38400)
      return doSetUnset (&t->c_cflag, B38400, b);
#else
      return 0;
#endif
    case b57600:
#if defined(B57600)
      return doSetUnset (&t->c_cflag, B57600, b);
#else
      return 0;
#endif
    case b115200:
#if defined(B115200)
      return doSetUnset (&t->c_cflag, B115200, b);
#else
      return 0;
#endif
    case b240400:
#if defined(B230400)
      return doSetUnset (&t->c_cflag, B230400, b);
#else
      return 0;
#endif
    case b460800:
#if defined(B460800)
      return doSetUnset (&t->c_cflag, B460800, b);
#else
      return 0;
#endif
    case b500000:
#if defined(B500000)
      return doSetUnset (&t->c_cflag, B500000, b);
#else
      return 0;
#endif
    case b576000:
#if defined(B576000)
      return doSetUnset (&t->c_cflag, B576000, b);
#else
      return 0;
#endif
    case b921600:
#if defined(B921600)
      return doSetUnset (&t->c_cflag, B921600, b);
#else
      return 0;
#endif
    case b1000000:
#if defined(B1000000)
      return doSetUnset (&t->c_cflag, B1000000, b);
#else
      return 0;
#endif
    case b1152000:
#if defined(B1152000)
      return doSetUnset (&t->c_cflag, B1152000, b);
#else
      return 0;
#endif
    case b1500000:
#if defined(B1500000)
      return doSetUnset (&t->c_cflag, B1500000, b);
#else
      return 0;
#endif
    case b2000000:
#if defined(B2000000)
      return doSetUnset (&t->c_cflag, B2000000, b);
#else
      return 0;
#endif
    case b2500000:
#if defined(B2500000)
      return doSetUnset (&t->c_cflag, B2500000, b);
#else
      return 0;
#endif
    case b3000000:
#if defined(B3000000)
      return doSetUnset (&t->c_cflag, B3000000, b);
#else
      return 0;
#endif
    case b3500000:
#if defined(B3500000)
      return doSetUnset (&t->c_cflag, B3500000, b);
#else
      return 0;
#endif
    case b4000000:
#if defined(B4000000)
      return doSetUnset (&t->c_cflag, B4000000, b);
#else
      return 0;
#endif
    case maxbaud:
#if defined(__MAX_BAUD)
      return doSetUnset (&t->c_cflag, __MAX_BAUD, b);
#else
      return 0;
#endif
    case crtscts:
#if defined(CRTSCTS)
      return doSetUnset (&t->c_cflag, CRTSCTS, b);
#else
      return 0;
#endif
    case cs5:
#if defined(CS5)
      return doSetUnset (&t->c_cflag, CS5, b);
#else
      return 0;
#endif
    case cs6:
#if defined(CS6)
      return doSetUnset (&t->c_cflag, CS6, b);
#else
      return 0;
#endif
    case cs7:
#if defined(CS7)
      return doSetUnset (&t->c_cflag, CS7, b);
#else
      return 0;
#endif
    case cs8:
#if defined(CS8)
      return doSetUnset (&t->c_cflag, CS8, b);
#else
      return 0;
#endif
    case cstopb:
#if defined(CSTOPB)
      return doSetUnset (&t->c_cflag, CSTOPB, b);
#else
      return 0;
#endif
    case cread:
#if defined(CREAD)
      return doSetUnset (&t->c_cflag, CREAD, b);
#else
      return 0;
#endif
    case parenb:
#if defined(PARENB)
      return doSetUnset (&t->c_cflag, PARENB, b);
#else
      return 0;
#endif
    case parodd:
#if defined(PARODD)
      return doSetUnset (&t->c_cflag, PARODD, b);
#else
      return 0;
#endif
    case hupcl:
#if defined(HUPCL)
      return doSetUnset (&t->c_cflag, HUPCL, b);
#else
      return 0;
#endif
    case clocal:
#if defined(CLOCAL)
      return doSetUnset (&t->c_cflag, CLOCAL, b);
#else
      return 0;
#endif
    case lisig:
#if defined(ISIG)
      return doSetUnset (&t->c_lflag, ISIG, b);
#else
      return 0;
#endif
    case licanon:
#if defined(ICANON)
      return doSetUnset (&t->c_lflag, ICANON, b);
#else
      return 0;
#endif
    case lxcase:
#if defined(XCASE)
      return doSetUnset (&t->c_lflag, XCASE, b);
#else
      return 0;
#endif
    case lecho:
#if defined(ECHO)
      return doSetUnset (&t->c_lflag, ECHO, b);
#else
      return 0;
#endif
    case lechoe:
#if defined(ECHOE)
      return doSetUnset (&t->c_lflag, ECHOE, b);
#else
      return 0;
#endif
    case lechok:
#if defined(ECHOK)
      return doSetUnset (&t->c_lflag, ECHOK, b);
#else
      return 0;
#endif
    case lechonl:
#if defined(ECHONL)
      return doSetUnset (&t->c_lflag, ECHONL, b);
#else
      return 0;
#endif
    case lnoflsh:
#if defined(NOFLSH)
      return doSetUnset (&t->c_lflag, NOFLSH, b);
#else
      return 0;
#endif
    case ltopstop:
#if defined(TOSTOP)
      return doSetUnset (&t->c_lflag, TOSTOP, b);
#else
      return 0;
#endif
    case lechoctl:
#if defined(ECHOCTL)
      return doSetUnset (&t->c_lflag, ECHOCTL, b);
#else
      return 0;
#endif
    case lechoprt:
#if defined(ECHOPRT)
      return doSetUnset (&t->c_lflag, ECHOPRT, b);
#else
      return 0;
#endif
    case lechoke:
#if defined(ECHOKE)
      return doSetUnset (&t->c_lflag, ECHOKE, b);
#else
      return 0;
#endif
    case lflusho:
#if defined(FLUSHO)
      return doSetUnset (&t->c_lflag, FLUSHO, b);
#else
      return 0;
#endif
    case lpendin:
#if defined(PENDIN)
      return doSetUnset (&t->c_lflag, PENDIN, b);
#else
      return 0;
#endif
    case liexten:
#if defined(IEXTEN)
      return doSetUnset (&t->c_lflag, IEXTEN, b);
#else
      return 0;
#endif
    }
  return 0;
}

/* GetChar sets a CHAR, ch, value from, t, and returns TRUE if
   this value is supported.  */

int EXPORT (GetChar) (struct termios *t, ControlChar c, char *ch)
{
  switch (c)
    {

    case vintr:
#if defined(VINTR)
      *ch = t->c_cc[VINTR];
      return 1;
#else
      return 0;
#endif
    case vquit:
#if defined(VQUIT)
      *ch = t->c_cc[VQUIT];
      return 1;
#else
      return 0;
#endif
    case verase:
#if defined(VERASE)
      *ch = t->c_cc[VERASE];
      return 1;
#else
      return 0;
#endif
    case vkill:
#if defined(VKILL)
      *ch = t->c_cc[VKILL];
      return 1;
#else
      return 0;
#endif
    case veof:
#if defined(VEOF)
      *ch = t->c_cc[VEOF];
      return 1;
#else
      return 0;
#endif
    case vtime:
#if defined(VTIME)
      *ch = t->c_cc[VTIME];
      return 1;
#else
      return 0;
#endif
    case vmin:
#if defined(VMIN)
      *ch = t->c_cc[VMIN];
      return 1;
#else
      return 0;
#endif
    case vswtc:
#if defined(VSWTC)
      *ch = t->c_cc[VSWTC];
      return 1;
#else
      return 0;
#endif
    case vstart:
#if defined(VSTART)
      *ch = t->c_cc[VSTART];
      return 1;
#else
      return 0;
#endif
    case vstop:
#if defined(VSTOP)
      *ch = t->c_cc[VSTOP];
      return 1;
#else
      return 0;
#endif
    case vsusp:
#if defined(VSUSP)
      *ch = t->c_cc[VSUSP];
      return 1;
#else
      return 0;
#endif
    case veol:
#if defined(VEOL)
      *ch = t->c_cc[VEOL];
      return 1;
#else
      return 0;
#endif
    case vreprint:
#if defined(VREPRINT)
      *ch = t->c_cc[VREPRINT];
      return 1;
#else
      return 0;
#endif
    case vdiscard:
#if defined(VDISCARD)
      *ch = t->c_cc[VDISCARD];
      return 1;
#else
      return 0;
#endif
    case vwerase:
#if defined(VWERASE)
      *ch = t->c_cc[VWERASE];
      return 1;
#else
      return 0;
#endif
    case vlnext:
#if defined(VLNEXT)
      *ch = t->c_cc[VLNEXT];
      return 1;
#else
      return 0;
#endif
    case veol2:
#if defined(VEOL2)
      *ch = t->c_cc[VEOL2];
      return 1;
#else
      return 0;
#endif
    default:
      return 0;
    }
}

/* SetChar sets a CHAR value in, t, and returns TRUE if, c,
   is supported.  */

int EXPORT (SetChar) (struct termios *t, ControlChar c, char ch)
{
  switch (c)
    {

    case vintr:
#if defined(VINTR)
      t->c_cc[VINTR] = ch;
      return 1;
#else
      return 0;
#endif
    case vquit:
#if defined(VQUIT)
      t->c_cc[VQUIT] = ch;
      return 1;
#else
      return 0;
#endif
    case verase:
#if defined(VERASE)
      t->c_cc[VERASE] = ch;
      return 1;
#else
      return 0;
#endif
    case vkill:
#if defined(VKILL)
      t->c_cc[VKILL] = ch;
      return 1;
#else
      return 0;
#endif
    case veof:
#if defined(VEOF)
      t->c_cc[VEOF] = ch;
      return 1;
#else
      return 0;
#endif
    case vtime:
#if defined(VTIME)
      t->c_cc[VTIME] = ch;
      return 1;
#else
      return 0;
#endif
    case vmin:
#if defined(VMIN)
      t->c_cc[VMIN] = ch;
      return 1;
#else
      return 0;
#endif
    case vswtc:
#if defined(VSWTC)
      t->c_cc[VSWTC] = ch;
      return 1;
#else
      return 0;
#endif
    case vstart:
#if defined(VSTART)
      t->c_cc[VSTART] = ch;
      return 1;
#else
      return 0;
#endif
    case vstop:
#if defined(VSTOP)
      t->c_cc[VSTOP] = ch;
      return 1;
#else
      return 0;
#endif
    case vsusp:
#if defined(VSUSP)
      t->c_cc[VSUSP] = ch;
      return 1;
#else
      return 0;
#endif
    case veol:
#if defined(VEOL)
      t->c_cc[VEOL] = ch;
      return 1;
#else
      return 0;
#endif
    case vreprint:
#if defined(VREPRINT)
      t->c_cc[VREPRINT] = ch;
      return 1;
#else
      return 0;
#endif
    case vdiscard:
#if defined(VDISCARD)
      t->c_cc[VDISCARD] = ch;
      return 1;
#else
      return 0;
#endif
    case vwerase:
#if defined(VWERASE)
      t->c_cc[VWERASE] = ch;
      return 1;
#else
      return 0;
#endif
    case vlnext:
#if defined(VLNEXT)
      t->c_cc[VLNEXT] = ch;
      return 1;
#else
      return 0;
#endif
    case veol2:
#if defined(VEOL2)
      t->c_cc[VEOL2] = ch;
      return 1;
#else
      return 0;
#endif
    default:
      return 0;
    }
}
#endif

void
_M2_termios_init (void)
{
}

void
_M2_termios_finish (void)
{
}
-----------------------------
New file: ./libm2pim/target.c
-----------------------------
/* target.c provide access to miscellaneous math functions.

Copyright (C) 2005-2022 Free Software Foundation, Inc.
Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.

This file is part of GNU Modula-2.

GNU Modula-2 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GNU Modula-2 is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

#include <config.h>

#if defined(HAVE_MATH_H)
#include <math.h>
#endif

#if !defined(HAVE_EXP10)
#if defined(M_LN10)
double
exp10 (double x)
{
  return exp (x * M_LN10);
}
#endif
#endif

#if !defined(HAVE_EXP10F)
#if defined(M_LN10)
float
exp10f (float x)
{
  return expf (x * M_LN10);
}
#endif
#endif

#if !defined(HAVE_EXP10L)
#if defined(M_LN10)
long double
exp10l (long double x)
{
  return expl (x * M_LN10);
}
#endif
#endif
-----------------------------
New file: ./libm2pim/UnixArgs.c
-----------------------------
/* UnixArgs.c record argc, argv as global variables.

Copyright (C) 2009-2022 Free Software Foundation, Inc.
Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.

This file is part of GNU Modula-2.

GNU Modula-2 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GNU Modula-2 is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

int UnixArgs_ArgC;
char **UnixArgs_ArgV;

void
_M2_UnixArgs_init (int argc, char *argv[])
{
  UnixArgs_ArgC = argc;
  UnixArgs_ArgV = argv;
}

void
_M2_UnixArgs_finish (int argc, char *argv[])
{
}
-----------------------------
New file: ./libm2pim/wrapc.c
-----------------------------
/* wrapc.c provide access to miscellaneous C library functions.

Copyright (C) 2005-2022 Free Software Foundation, Inc.
Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.

This file is part of GNU Modula-2.

GNU Modula-2 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GNU Modula-2 is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

#include <config.h>

#if defined(HAVE_MATH_H)
#include <math.h>
#endif

#if defined(HAVE_STDLIB_H)
#include <stdlib.h>
#endif

#if defined(HAVE_UNISTD_H)
#include <unistd.h>
#endif

#if defined(HAVE_SYS_STAT_H)
#include <sys/stat.h>
#endif

#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif

#if defined(HAVE_SYS_TYPES_H)
#include <sys/types.h>
#endif

#if defined(HAVE_TIME_H)
#include <time.h>
#endif

/* Define FALSE if one hasn't already been defined.  */

#if !defined(FALSE)
#define FALSE (1 == 0)
#endif

/* Define a generic NULL if one hasn't already been defined.  */

#if !defined(NULL)
#define NULL 0
#endif

/* strtime returns the address of a string which describes the
   local time.  */

char *
wrapc_strtime (void)
{
#if defined(HAVE_CTIME)
  time_t clock = time ((void *)0);
  char *string = ctime (&clock);

  string[24] = (char)0;

  return string;
#else
  return "";
#endif
}

int
wrapc_filesize (int f, unsigned int *low, unsigned int *high)
{
#if defined(HAVE_SYS_STAT_H) && defined(HAVE_STRUCT_STAT)
  struct stat s;
  int res = fstat (f, (struct stat *)&s);

  if (res == 0)
    {
      *low = (unsigned int)s.st_size;
      *high = (unsigned int)(s.st_size >> (sizeof (unsigned int) * 8));
    }
  return res;
#else
  return -1;
#endif
}

/* filemtime returns the mtime of a file, f.  */

int
wrapc_filemtime (int f)
{
#if defined(HAVE_SYS_STAT_H) && defined(HAVE_STRUCT_STAT)
  struct stat s;

  if (fstat (f, (struct stat *)&s) == 0)
    return s.st_mtime;
  else
    return -1;
#else
  return -1;
#endif
}

/* fileinode returns the inode associated with a file, f.  */

#if defined(HAVE_SYS_STAT_H) && defined(HAVE_STRUCT_STAT)
ino_t
wrapc_fileinode (int f, unsigned int *low, unsigned int *high)
{
  struct stat s;

  if (fstat (f, (struct stat *)&s) == 0)
    {
      *low = (unsigned int)s.st_ino;
      *high = (unsigned int)(s.st_ino >> (sizeof (unsigned int) * 8));
      return 0;
    }
  else
    return -1;
}
#else
int
wrapc_fileinode (int f, unsigned int *low, unsigned int *high)
{
  *low = 0;
  *high = 0;
  return -1;
}
#endif

/* getrand returns a random number between 0..n-1.  */

int
wrapc_getrand (int n)
{
  return rand () % n;
}

#if defined(HAVE_PWD_H)
#include <pwd.h>

char *
wrapc_getusername (void)
{
  return getpwuid (getuid ())->pw_gecos;
}

/* getnameuidgid fills in the, uid, and, gid, which represents
   user, name.  */

void
wrapc_getnameuidgid (char *name, int *uid, int *gid)
{
  struct passwd *p = getpwnam (name);

  if (p == NULL)
    {
      *uid = -1;
      *gid = -1;
    }
  else
    {
      *uid = p->pw_uid;
      *gid = p->pw_gid;
    }
}
#else
char *
wrapc_getusername (void)
{
  return "unknown";
}

void
wrapc_getnameuidgid (char *name, int *uid, int *gid)
{
  *uid = -1;
  *gid = -1;
}
#endif

int
wrapc_signbit (double r)
{
#if defined(HAVE_SIGNBIT)

  /* signbit is a macro which tests its argument against sizeof(float),
     sizeof(double).  */
  return signbit (r);
#else
  return FALSE;
#endif
}

int
wrapc_signbitl (long double r)
{
#if defined(HAVE_SIGNBITL)

  /* signbit is a macro which tests its argument against sizeof(float),
     sizeof(double).  */
  return signbitl (r);
#else
  return FALSE;
#endif
}

int
wrapc_signbitf (float r)
{
#if defined(HAVE_SIGNBITF)

  /* signbit is a macro which tests its argument against sizeof(float),
     sizeof(double).  */
  return signbitf (r);
#else
  return FALSE;
#endif
}

/* isfinite provide non builtin alternative to the gcc builtin
   isfinite.  Returns 1 if x is finite and 0 if it is not.  */

int
wrapc_isfinite (double x)
{
#if defined(FP_NAN) && defined(FP_INFINITE)
  return (fpclassify (x) != FP_NAN && fpclassify (x) != FP_INFINITE);
#else
  return FALSE;
#endif
}

/* isfinitel provide non builtin alternative to the gcc builtin
   isfinite.  Returns 1 if x is finite and 0 if it is not.  */

int
wrapc_isfinitel (long double x)
{
#if defined(FP_NAN) && defined(FP_INFINITE)
  return (fpclassify (x) != FP_NAN && fpclassify (x) != FP_INFINITE);
#else
  return FALSE;
#endif
}

/* isfinitef provide non builtin alternative to the gcc builtin
   isfinite.  Returns 1 if x is finite and 0 if it is not.  */

int
wrapc_isfinitef (float x)
{
#if defined(FP_NAN) && defined(FP_INFINITE)
  return (fpclassify (x) != FP_NAN && fpclassify (x) != FP_INFINITE);
#else
  return FALSE;
#endif
}

/* init/finish are GNU Modula-2 linking fodder.  */

void
_M2_wrapc_init ()
{
}

void
_M2_wrapc_finish ()
{
}
-----------------------------
New file: ./libm2pim/Makefile.am
-----------------------------
# Makefile for libm2pim.
#   Copyright 2013-2022  Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING3.  If not see
# <http://www.gnu.org/licenses/>.

SUFFIXES = .c .mod .def .o .obj .lo .a .la

ACLOCAL_AMFLAGS = -I . -I .. -I ../config

VPATH = . @srcdir@ @srcdir@/../../gcc/m2/gm2-libs

# Multilib support.
MAKEOVERRIDES=

version := $(shell $(CC) -dumpversion)

# Directory in which the compiler finds libraries etc.
libsubdir = $(libdir)/gcc/$(target_alias)/$(version)
# Used to install the shared libgcc.
slibdir = @slibdir@

toolexeclibdir=@toolexeclibdir@
toolexecdir=@toolexecdir@

MULTIDIR := $(shell $(CC) $(CFLAGS) -print-multi-directory)
MULTIOSDIR := $(shell $(CC) $(CFLAGS) -print-multi-os-directory)

MULTIOSSUBDIR := $(shell if test x$(MULTIOSDIR) != x.; then echo /$(MULTIOSDIR); fi)
inst_libdir = $(libsubdir)$(MULTISUBDIR)
inst_slibdir = $(slibdir)$(MULTIOSSUBDIR)


# Work around what appears to be a GNU make bug handling MAKEFLAGS
# values defined in terms of make variables, as is the case for CC and
# friends when we are called from the top level Makefile.
AM_MAKEFLAGS = \
        "GCC_DIR=$(GCC_DIR)" \
        "GM2_SRC=$(GM2_SRC)" \
	"AR_FLAGS=$(AR_FLAGS)" \
	"CC_FOR_BUILD=$(CC_FOR_BUILD)" \
	"CC_FOR_TARGET=$(CC_FOR_TARGET)" \
	"GM2_FOR_TARGET=$(GM2_FOR_TARGET)" \
	"CFLAGS=$(CFLAGS)" \
	"CXXFLAGS=$(CXXFLAGS)" \
	"CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
	"CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
	"INSTALL=$(INSTALL)" \
	"INSTALL_DATA=$(INSTALL_DATA)" \
	"INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
	"INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
	"LDFLAGS=$(LDFLAGS)" \
	"LIBCFLAGS=$(LIBCFLAGS)" \
	"LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
	"MAKE=$(MAKE)" \
	"MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
        "MULTISUBDIR=$(MULTISUBDIR)" \
        "MULTIOSDIR=$(MULTIOSDIR)" \
        "MULTIBUILDTOP=$(MULTIBUILDTOP)" \
        "MULTIFLAGS=$(MULTIFLAGS)" \
	"PICFLAG=$(PICFLAG)" \
	"PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
	"SHELL=$(SHELL)" \
	"RUNTESTFLAGS=$(RUNTESTFLAGS)" \
	"exec_prefix=$(exec_prefix)" \
	"infodir=$(infodir)" \
	"libdir=$(libdir)" \
	"includedir=$(includedir)" \
	"prefix=$(prefix)" \
	"tooldir=$(tooldir)" \
        "toolexeclibdir=$(toolexeclibdir)" \
        "toolexecdir=$(toolexecdir)" \
	"gxx_include_dir=$(gxx_include_dir)" \
	"AR=$(AR)" \
	"AS=$(AS)" \
	"LD=$(LD)" \
	"RANLIB=$(RANLIB)" \
	"NM=$(NM)" \
	"NM_FOR_BUILD=$(NM_FOR_BUILD)" \
	"NM_FOR_TARGET=$(NM_FOR_TARGET)" \
	"DESTDIR=$(DESTDIR)" \
	"WERROR=$(WERROR)" \
        "TARGET_LIB_PATH_libgm2=$(TARGET_LIB_PATH_libgm2)"

# Subdir rules rely on $(FLAGS_TO_PASS)
FLAGS_TO_PASS = $(AM_MAKEFLAGS)

if BUILD_PIMLIB
toolexeclib_LTLIBRARIES = libm2pim.la

M2MODS = ASCII.mod IO.mod \
       Args.mod M2RTS.mod \
       Assertion.mod NumberIO.mod \
       Break.mod SYSTEM.mod \
       CmdArgs.mod Scan.mod \
       StrCase.mod FIO.mod \
       StrIO.mod StrLib.mod \
       TimeString.mod Environment.mod \
       FpuIO.mod Debug.mod \
       SysStorage.mod Storage.mod \
       StdIO.mod SEnvironment.mod \
       DynamicStrings.mod SFIO.mod \
       SArgs.mod SCmdArgs.mod \
       PushBackInput.mod \
       StringConvert.mod FormatStrings.mod \
       Builtins.mod MathLib0.mod \
       M2EXCEPTION.mod RTExceptions.mod \
       SMathLib0.mod RTint.mod \
       COROUTINES.mod Indexing.mod \
       LMathLib0.mod LegacyReal.mod \
       MemUtils.mod gdbif.mod \
       GetOpt.mod OptLib.mod

M2DEFS = Args.def   ASCII.def \
         Assertion.def  Break.def \
         Builtins.def  cbuiltin.def \
         CmdArgs.def  COROUTINES.def \
         cxxabi.def  Debug.def \
         dtoa.def  DynamicStrings.def \
         Environment.def  errno.def \
         FIO.def  FormatStrings.def \
         FpuIO.def  gdbif.def \
         Indexing.def \
         IO.def  ldtoa.def \
         LegacyReal.def  libc.def \
         libm.def  LMathLib0.def \
         M2EXCEPTION.def  M2RTS.def \
         MathLib0.def  MemUtils.def \
         NumberIO.def  PushBackInput.def \
         RTExceptions.def  RTint.def \
         SArgs.def  SCmdArgs.def \
         Scan.def \
         sckt.def  Selective.def \
         SEnvironment.def  SFIO.def \
         SMathLib0.def  StdIO.def \
         Storage.def  StrCase.def \
         StringConvert.def  StrIO.def \
         StrLib.def  SysExceptions.def \
         SysStorage.def  SYSTEM.def \
         termios.def  TimeString.def \
         UnixArgs.def  wrapc.def  \
         GetOpt.def OptLib.def \
         cgetopt.def

libm2pim_la_SOURCES = $(M2MODS) \
                      UnixArgs.c \
                      Selective.c sckt.c \
                      errno.c dtoa.c \
                      ldtoa.c termios.c \
                      SysExceptions.c target.c \
                      wrapc.c cgetopt.c

libm2pimdir = libm2pim
libm2pim_la_DEPENDENCIES = SYSTEM.def $(addsuffix .lo, $(basename $(libm2pim_la_SOURCES)))
libm2pim_la_CFLAGS = -I. -I$(GM2_SRC)/gm2-libs -I$(GM2_SRC)/gm2-libs-iso -DBUILD_GM2_LIBS -I@srcdir@/../
libm2pim_la_M2FLAGS = -I. -I$(GM2_SRC)/gm2-libs -I$(GM2_SRC)/gm2-libs-iso -fm2-g -g
libm2pim_la_LINK = $(LINK) -version-info $(libtool_VERSION)
BUILT_SOURCES = SYSTEM.def
CLEANFILES = SYSTEM.def

M2LIBDIR = /m2/m2pim/

SYSTEM.def: Makefile
	bash $(GM2_SRC)/tools-src/makeSystem -fpim \
             $(GM2_SRC)/gm2-libs/SYSTEM.def \
             $(GM2_SRC)/gm2-libs/SYSTEM.mod \
             -I$(GM2_SRC)/gm2-libs \
             "$(GM2_FOR_TARGET)" $@

.mod.lo: SYSTEM.def
	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(GM2_FOR_TARGET) -c $(CFLAGS_FOR_TARGET) $(LIBCFLAGS) $(libm2pim_la_M2FLAGS) $< -o $@

install-data-local: force
	mkdir -p $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)
	$(INSTALL_DATA) .libs/libm2pim.la $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)
	chmod 644 $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)libm2pim.la
	$(INSTALL_DATA) .libs/libm2pim.a $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)
	$(RANLIB) $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)libm2pim.a
	for i in $(M2DEFS) $(M2MODS) ; do \
           if [ -f $$i ] ; then \
              $(INSTALL_DATA) $$i '$(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)'; \
           elif [ -f @srcdir@/../../gcc/m2/gm2-libs/$$i ] ; then \
              $(INSTALL_DATA) @srcdir@/../../gcc/m2/gm2-libs/$$i '$(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)'; \
           else \
              echo "cannot find $$i" ; exit 1 ; \
           fi ; \
           chmod 644 $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)$$i ; \
	done

force:

endif
-----------------------------
New file: ./libm2pim/errno.c
-----------------------------
/* errno.c provide access to the errno value.

Copyright (C) 2009-2022 Free Software Foundation, Inc.
Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.

This file is part of GNU Modula-2.

GNU Modula-2 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GNU Modula-2 is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

#include <config.h>

#if defined(HAVE_SYS_ERRNO_H)
#include <sys/errno.h>
#endif

#if defined(HAVE_ERRNO_H)
#include <errno.h>
#endif

int
errno_geterrno (void)
{
#if defined(HAVE_ERRNO_H) || defined(HAVE_SYS_ERRNO_H)
  return errno;
#else
  return -1;
#endif
}

void
_M2_errno_init (void)
{
}

void
_M2_errno_finish (void)
{
}
-----------------------------
New file: ./libm2pim/ldtoa.c
-----------------------------
/* ldtoa.c convert long double to ascii and visa versa.

Copyright (C) 2009-2022 Free Software Foundation, Inc.
Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.

This file is part of GNU Modula-2.

GNU Modula-2 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GNU Modula-2 is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

#define GM2

#include <config.h>

#if defined(HAVE_STRINGS)
#include <strings.h>
#endif

#if defined(HAVE_STRING)
#include <string.h>
#endif

#if defined(HAVE_STDDEF_H)
/* Obtain a definition for NULL.  */
#include <stddef.h>
#endif

#if defined(HAVE_STDIO_H)
/* Obtain a definition for NULL.  */
#include <stdio.h>
#endif

#if defined(HAVE_TIME_H)
/* Obtain a definition for NULL.  */
#include <time.h>
#endif

#if defined(HAVE_STRING_H)
/* Obtain a definition for NULL.  */
#include <string.h>
#endif

#if defined(HAVE_WCHAR_H)
/* Obtain a definition for NULL.  */
#include <wchar.h>
#endif

#if defined(HAVE_STDLIB_H)
#if !defined(_ISOC99_SOURCE)
#define _ISOC99_SOURCE
#endif
#include <stdlib.h>
#endif

#if defined(HAVE_ERRNO_H)
#include <errno.h>
#endif

#if defined(HAVE_SYS_ERRNO_H)
#include <sys/errno.h>
#endif

#if defined(HAVE_STDLIB_H)
/* Obtain a prototype for free and malloc.  */
#include <stdlib.h>
#endif

#if !defined(NULL)
#define NULL (void *)0
#endif

#if !defined(TRUE)
#define TRUE (1 == 1)
#endif
#if !defined(FALSE)
#define FALSE (1 == 0)
#endif

#define MAX_FP_DIGITS 500

typedef enum Mode { maxsignicant, decimaldigits } Mode;

extern int dtoa_calcmaxsig (char *p, int ndigits);
extern int dtoa_calcdecimal (char *p, int str_size, int ndigits);
extern int dtoa_calcsign (char *p, int str_size);

/* maxsignicant return a string containing max(1,ndigits) significant
   digits.  The return string contains the string produced by snprintf.

   decimaldigits: return a string produced by fcvt.  The string will
   contain ndigits past the decimal point (ndigits may be negative).  */

long double
ldtoa_strtold (const char *s, int *error)
{
  char *endp;
  long double d;

#if defined(HAVE_ERRNO_H)
  errno = 0;
#endif
#if defined(HAVE_STRTOLD)
  d = strtold (s, &endp);
#else
  /* Fall back to using strtod.  */
  d = (long double)strtod (s, &endp);
#endif
  if (endp != NULL && (*endp == '\0'))
#if defined(HAVE_ERRNO_H)
    *error = (errno != 0);
#else
    *error = FALSE;
#endif
  else
    *error = TRUE;
  return d;
}

char *
ldtoa_ldtoa (long double d, int mode, int ndigits, int *decpt, int *sign)
{
  char format[50];
  char *p;
  int r;
  switch (mode)
    {

    case maxsignicant:
      ndigits += 20; /* Enough for exponent.  */
      p = malloc (ndigits);
      snprintf (format, 50, "%s%d%s", "%.", ndigits - 20, "LE");
      snprintf (p, ndigits, format, d);
      *sign = dtoa_calcsign (p, ndigits);
      *decpt = dtoa_calcmaxsig (p, ndigits);
      return p;
    case decimaldigits:
      p = malloc (MAX_FP_DIGITS + 20);
      snprintf (format, 50, "%s%d%s", "%.", MAX_FP_DIGITS, "LE");
      snprintf (p, MAX_FP_DIGITS + 20, format, d);
      *sign = dtoa_calcsign (p, MAX_FP_DIGITS + 20);
      *decpt = dtoa_calcdecimal (p, MAX_FP_DIGITS + 20, ndigits);
      return p;
    default:
      abort ();
    }
}

#if defined(GM2)
/* GNU Modula-2 linking hooks.  */

void
_M2_ldtoa_init (void)
{
}
void
_M2_ldtoa_finish (void)
{
}
#endif
-----------------------------
New file: ./libm2pim/SysExceptions.c
-----------------------------
/* SysExceptions.c configure the signals to create m2 exceptions.

Copyright (C) 2009-2022 Free Software Foundation, Inc.
Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.

This file is part of GNU Modula-2.

GNU Modula-2 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GNU Modula-2 is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

#include <config.h>

#if defined(HAVE_SIGNAL_H)
#include <signal.h>
#endif

#if defined(HAVE_ERRNO_H)
#include <errno.h>
#endif

#if defined(HAVE_SYS_ERRNO_H)
#include <sys/errno.h>
#endif

#if defined(HAVE_STDIO_H)
#include <stdio.h>
#endif


#if 0
/* Signals.  */
#define SIGHUP 1       /* Hangup (POSIX).  */
#define SIGINT 2       /* Interrupt (ANSI).  */
#define SIGQUIT 3      /* Quit (POSIX).  */
#define SIGILL 4       /* Illegal instruction (ANSI).  */
#define SIGTRAP 5      /* Trace trap (POSIX).  */
#define SIGABRT 6      /* Abort (ANSI).  */
#define SIGIOT 6       /* IOT trap (4.2 BSD).  */
#define SIGBUS 7       /* BUS error (4.2 BSD).  */
#define SIGFPE 8       /* Floating-point exception (ANSI).  */
#define SIGKILL 9      /* Kill, unblockable (POSIX).  */
#define SIGUSR1 10     /* User-defined signal 1 (POSIX).  */
#define SIGSEGV 11     /* Segmentation violation (ANSI).  */
#define SIGUSR2 12     /* User-defined signal 2 (POSIX).  */
#define SIGPIPE 13     /* Broken pipe (POSIX).  */
#define SIGALRM 14     /* Alarm clock (POSIX).  */
#define SIGTERM 15     /* Termination (ANSI).  */
#define SIGSTKFLT 16   /* Stack fault.  */
#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V).  */
#define SIGCHLD 17     /* Child status has changed (POSIX).  */
#define SIGCONT 18     /* Continue (POSIX).  */
#define SIGSTOP 19     /* Stop, unblockable (POSIX).  */
#define SIGTSTP 20     /* Keyboard stop (POSIX).  */
#define SIGTTIN 21     /* Background read from tty (POSIX).  */
#define SIGTTOU 22     /* Background write to tty (POSIX).  */
#define SIGURG 23      /* Urgent condition on socket (4.2 BSD).  */
#define SIGXCPU 24     /* CPU limit exceeded (4.2 BSD).  */
#define SIGXFSZ 25     /* File size limit exceeded (4.2 BSD).  */
#define SIGVTALRM 26   /* Virtual alarm clock (4.2 BSD).  */
#define SIGPROF 27     /* Profiling alarm clock (4.2 BSD).  */
#define SIGWINCH 28    /* Window size change (4.3 BSD, Sun).  */
#define SIGPOLL SIGIO  /* Pollable event occurred (System V).  */
#define SIGIO 29       /* I/O now possible (4.2 BSD).  */
#define SIGPWR 30      /* Power failure restart (System V).  */
#define SIGSYS 31      /* Bad system call.  */
#define SIGUNUSED 31

/* The list of Modula-2 exceptions is shown below */

    (indexException,     rangeException,         caseSelectException,  invalidLocation,
     functionException,  wholeValueException,    wholeDivException,    realValueException,
     realDivException,   complexValueException,  complexDivException,  protException,
     sysException,       coException,            exException
    );

#endif

/* Note:

    o  wholeDivException and realDivException are caught by SIGFPE and
       depatched to the appropriate Modula-2 runtime routine upon testing
       FPE_INTDIV or FPE_FLTDIV.
    o  realValueException is also caught by SIGFPE and dispatched by
       testing FFE_FLTOVF or FPE_FLTUND or FPE_FLTRES or FPE_FLTINV.
    o  indexException is caught by SIGFPE and dispatched by FPE_FLTSUB.  */

#if defined(HAVE_SIGNAL_H)
static struct sigaction sigbus;
static struct sigaction sigfpe;
static struct sigaction sigsegv;

static void (*indexProc) (void *);
static void (*rangeProc) (void *);
static void (*assignmentrangeProc) (void *);
static void (*caseProc) (void *);
static void (*invalidlocProc) (void *);
static void (*functionProc) (void *);
static void (*wholevalueProc) (void *);
static void (*wholedivProc) (void *);
static void (*realvalueProc) (void *);
static void (*realdivProc) (void *);
static void (*complexvalueProc) (void *);
static void (*complexdivProc) (void *);
static void (*protectionProc) (void *);
static void (*systemProc) (void *);
static void (*coroutineProc) (void *);
static void (*exceptionProc) (void *);

static void
sigbusDespatcher (int signum, siginfo_t *info, void *ucontext)
{
  switch (signum)
    {

    case SIGSEGV:
    case SIGBUS:
      if (info)
        (*invalidlocProc) (info->si_addr);
      break;
    default:
      perror ("not expecting to arrive here with this signal");
    }
}

static void
sigfpeDespatcher (int signum, siginfo_t *info, void *ucontext)
{
  switch (signum)
    {

    case SIGFPE:
      if (info)
        {
          if (info->si_code | FPE_INTDIV)
            (*wholedivProc) (info->si_addr); /* Integer divide by zero.  */
          if (info->si_code | FPE_INTOVF)
            (*wholevalueProc) (info->si_addr); /* Integer overflow.  */
          if (info->si_code | FPE_FLTDIV)
            (*realdivProc) (info->si_addr); /* Floating-point divide by zero.  */
          if (info->si_code | FPE_FLTOVF)
            (*realvalueProc) (info->si_addr); /* Floating-point overflow.  */
          if (info->si_code | FPE_FLTUND)
            (*realvalueProc) (info->si_addr); /* Floating-point underflow.  */
          if (info->si_code | FPE_FLTRES)
            (*realvalueProc) (
                info->si_addr); /* Floating-point inexact result.  */
          if (info->si_code | FPE_FLTINV)
            (*realvalueProc) (
                info->si_addr); /* Floating-point invalid result.  */
          if (info->si_code | FPE_FLTSUB)
            (*indexProc) (info->si_addr); /* Subscript out of range.  */
        }
      break;
    default:
      perror ("not expecting to arrive here with this signal");
    }
}

void
SysExceptions_InitExceptionHandlers (
    void (*indexf) (void *), void (*range) (void *), void (*casef) (void *),
    void (*invalidloc) (void *), void (*function) (void *),
    void (*wholevalue) (void *), void (*wholediv) (void *),
    void (*realvalue) (void *), void (*realdiv) (void *),
    void (*complexvalue) (void *), void (*complexdiv) (void *),
    void (*protection) (void *), void (*systemf) (void *),
    void (*coroutine) (void *), void (*exception) (void *))
{
  struct sigaction old;

  indexProc = indexf;
  rangeProc = range;
  caseProc = casef;
  invalidlocProc = invalidloc;
  functionProc = function;
  wholevalueProc = wholevalue;
  wholedivProc = wholediv;
  realvalueProc = realvalue;
  realdivProc = realdiv;
  complexvalueProc = complexvalue;
  complexdivProc = complexdiv;
  protectionProc = protection;
  systemProc = systemf;
  coroutineProc = coroutine;
  exceptionProc = exception;

  sigbus.sa_sigaction = sigbusDespatcher;
  sigbus.sa_flags = (SA_SIGINFO);
  sigemptyset (&sigbus.sa_mask);

  if (sigaction (SIGBUS, &sigbus, &old) != 0)
    perror ("unable to install the sigbus signal handler");

  sigsegv.sa_sigaction = sigbusDespatcher;
  sigsegv.sa_flags = (SA_SIGINFO);
  sigemptyset (&sigsegv.sa_mask);

  if (sigaction (SIGSEGV, &sigsegv, &old) != 0)
    perror ("unable to install the sigsegv signal handler");

  sigfpe.sa_sigaction = sigfpeDespatcher;
  sigfpe.sa_flags = (SA_SIGINFO);
  sigemptyset (&sigfpe.sa_mask);

  if (sigaction (SIGFPE, &sigfpe, &old) != 0)
    perror ("unable to install the sigfpe signal handler");
}

#else
void
SysExceptions_InitExceptionHandlers (void *indexf, void *range, void *casef,
                                     void *invalidloc, void *function,
                                     void *wholevalue, void *wholediv,
                                     void *realvalue, void *realdiv,
                                     void *complexvalue, void *complexdiv,
                                     void *protection, void *systemf,
                                     void *coroutine, void *exception)
{
}
#endif

/* GNU Modula-2 linking fodder.  */

void
_M2_SysExceptions_init (void)
{
}

void
_M2_SysExceptions_finish (void)
{
}
-----------------------------
New file: ./libm2pim/cgetopt.c
-----------------------------
/* getopt.c provide access to the C getopt library.

Copyright (C) 2009-2022 Free Software Foundation, Inc.
Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.

This file is part of GNU Modula-2.

GNU Modula-2 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GNU Modula-2 is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

#include <unistd.h>
#include <stdlib.h>
#include <getopt.h>

char *cgetopt_optarg;
int cgetopt_optind;
int cgetopt_opterr;
int cgetopt_optopt;

char
cgetopt_getopt (int argc, char *argv[], char *optstring)
{
  char r = getopt (argc, argv, optstring);

  cgetopt_optarg = optarg;
  cgetopt_optind = optind;
  cgetopt_opterr = opterr;
  cgetopt_optopt = optopt;

  if (r == (char)-1)
    return (char)0;
  return r;
}

int
cgetopt_getopt_long (int argc, char *argv[], char *optstring,
                    const struct option *longopts, int *longindex)
{
  int r = getopt_long (argc, argv, optstring, longopts, longindex);

  cgetopt_optarg = optarg;
  cgetopt_optind = optind;
  cgetopt_opterr = opterr;
  cgetopt_optopt = optopt;

  return r;
}

int
cgetopt_getopt_long_only (int argc, char *argv[], char *optstring,
                         const struct option *longopts, int *longindex)
{
  int r = getopt_long_only (argc, argv, optstring, longopts, longindex);

  cgetopt_optarg = optarg;
  cgetopt_optind = optind;
  cgetopt_opterr = opterr;
  cgetopt_optopt = optopt;

  return r;
}

typedef struct cgetopt_Options_s
{
  struct option *cinfo;
  unsigned int high;
} cgetopt_Options;

/* InitOptions a constructor for Options.  */

cgetopt_Options *
cgetopt_InitOptions (void)
{
  cgetopt_Options *o = (cgetopt_Options *)malloc (sizeof (cgetopt_Options));
  o->cinfo = (struct option *)malloc (sizeof (struct option));
  o->high = 0;
  return o;
}

/* KillOptions a deconstructor for Options.  Returns NULL after freeing
   up all allocated memory associated with o.  */

cgetopt_Options *
cgetopt_KillOptions (cgetopt_Options *o)
{
  free (o->cinfo);
  free (o);
  return NULL;
}

/* SetOption set option[index] with {name, has_arg, flag, val}.  */

void
cgetopt_SetOption (cgetopt_Options *o, unsigned int index, char *name,
 		   unsigned int has_arg, int *flag, int val)
{
  if (index > o->high)
    {
      o->cinfo
          = (struct option *)malloc (sizeof (struct option) * (index + 1));
      o->high = index + 1;
    }
  o->cinfo[index].name = name;
  o->cinfo[index].has_arg = has_arg;
  o->cinfo[index].flag = flag;
  o->cinfo[index].val = val;
}

/* GetLongOptionArray returns a pointer to the C array containing all
   long options.  */

struct option *
cgetopt_GetLongOptionArray (cgetopt_Options *o)
{
  return o->cinfo;
}

/* GNU Modula-2 linking fodder.  */

void
_M2_cgetopt_init (void)
{
}

void
_M2_cgetopt_finish (void)
{
}
-----------------------------
New file: ./libm2pim/sckt.c
-----------------------------
/* sckt.c provide access to the socket layer.

Copyright (C) 2005-2022 Free Software Foundation, Inc.
Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.

This file is part of GNU Modula-2.

GNU Modula-2 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GNU Modula-2 is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

#include <config.h>

#if defined(HAVE_SYS_TYPES_H)
#include <sys/types.h>
#endif

#if defined(HAVE_SYS_SOCKET_H)
#include <sys/socket.h>
#endif

#if defined(HAVE_NETINET_IN_H)
#include <netinet/in.h>
#endif

#if defined(HAVE_NETDB_H)
#include <netdb.h>
#endif

#if defined(HAVE_UNISTD_H)
#include <unistd.h>
#endif

#if defined(HAVE_SIGNAL_H)
#include <signal.h>
#endif

#if defined(HAVE_SYS_ERRNO_H)
#include <sys/errno.h>
#endif

#if defined(HAVE_ERRNO_H)
#include <errno.h>
#endif

#if defined(HAVE_MALLOC_H)
#include <malloc.h>
#endif

#if defined(HAVE_STRING_H)
#include <string.h>
#endif

#if defined(HAVE_STDLIB_H)
#include <stdlib.h>
#endif

#if defined(HAVE_STDIO_H)
#include <stdio.h>
#endif

#define PORTSTART 7000
#define NOOFTRIES 100
#define MAXHOSTNAME 256

#undef DEBUGGING

#if !defined(TRUE)
#define TRUE (1 == 1)
#endif
#if !defined(FALSE)
#define FALSE (1 == 0)
#endif

#if defined(HAVE_SYS_SOCKET_H)

#define ERROR(X)                                                              \
  {                                                                           \
    printf ("%s:%d:%s\n", __FILE__, __LINE__, X);                             \
    localExit (1);                                                            \
  }

#define ASSERT(X)                                                             \
  {                                                                           \
    if (!(X))                                                                 \
      {                                                                       \
        printf ("%s:%d: assert(%s) failed\n", __FILE__, __LINE__, #X);        \
        exit (1);                                                             \
      }                                                                       \
  }

typedef struct
{
  char hostname[MAXHOSTNAME];
  struct hostent *hp;
  struct sockaddr_in sa, isa;
  int sockFd;
  int portNo;
} tcpServerState;

int
localExit (int i)
{
  exit (1);
}

/* tcpServerEstablishPort returns a tcpState containing the relevant
   information about a socket declared to receive tcp connections.
   This method attempts to use the port specified by the parameter.  */

tcpServerState *
tcpServerEstablishPort (int portNo)
{
  tcpServerState *s = (tcpServerState *)malloc (sizeof (tcpServerState));
  int b, p, n;

  if (s == NULL)
    ERROR ("no more memory");

  /* Remove SIGPIPE which is raised on the server if the client is killed.  */
  signal (SIGPIPE, SIG_IGN);

  if (gethostname (s->hostname, MAXHOSTNAME) < 0)
    ERROR ("cannot find our hostname");

  s->hp = gethostbyname (s->hostname);
  if (s->hp == NULL)
    ERROR ("cannot get host name");

  p = -1;
  n = 0;
  do
    {
      p++;
       /* Open a TCP socket (an Internet stream socket).  */

      s->sockFd = socket (s->hp->h_addrtype, SOCK_STREAM, 0);
      if (s->sockFd < 0)
        ERROR ("socket");

      memset ((void *)&s->sa, 0, sizeof (s->sa));
      ASSERT ((s->hp->h_addrtype == AF_INET));
      s->sa.sin_family = s->hp->h_addrtype;
      s->sa.sin_addr.s_addr = htonl (INADDR_ANY);
      s->sa.sin_port = htons (portNo + p);

      b = bind (s->sockFd, (struct sockaddr *)&s->sa, sizeof (s->sa));
    }
  while ((b < 0) && (n < NOOFTRIES));

  if (b < 0)
    ERROR ("bind");

  s->portNo = portNo + p;
#if defined(DEBUGGING)
  printf ("the receiving host is: %s, the port is %d\n", s->hostname,
          s->portNo);
#endif
  listen (s->sockFd, 1);
  return s;
}

/* tcpServerEstablish returns a tcpServerState containing the relevant
   information about a socket declared to receive tcp connections.  */

tcpServerState *
tcpServerEstablish (void)
{
  return tcpServerEstablishPort (PORTSTART);
}

/* tcpServerAccept returns a file descriptor once a client has connected and
   been accepted.  */

int
tcpServerAccept (tcpServerState *s)
{
  int i = sizeof (s->isa);
  int t;

#if defined(DEBUGGING)
  printf ("before accept %d\n", s->sockFd);
#endif
  t = accept (s->sockFd, (struct sockaddr *)&s->isa, &i);
  return t;
}

/* tcpServerPortNo returns the portNo from structure, s.  */

int
tcpServerPortNo (tcpServerState *s)
{
  return s->portNo;
}

/* tcpServerSocketFd returns the sockFd from structure, s.  */

int
tcpServerSocketFd (tcpServerState *s)
{
  return s->sockFd;
}

/* getLocalIP returns the IP address of this machine.  */

unsigned int
getLocalIP (tcpServerState *s)
{
  char hostname[1024];
  struct hostent *hp;
  struct sockaddr_in sa;
  unsigned int ip;
  int ret = gethostname (hostname, sizeof (hostname));

  if (ret == -1)
    {
      ERROR ("gethostname");
      return 0;
    }

  hp = gethostbyname (hostname);
  if (hp == NULL)
    {
      ERROR ("gethostbyname");
      return 0;
    }

  if (sizeof (unsigned int) != sizeof (in_addr_t))
    {
      ERROR ("bad ip length");
      return 0;
    }

  memset (&sa, sizeof (struct sockaddr_in), 0);
  sa.sin_family = AF_INET;
  sa.sin_port = htons (80);
  if (hp->h_length == sizeof (unsigned int))
    {
      memcpy (&ip, hp->h_addr_list[0], hp->h_length);
      return ip;
    }

  return 0;
}

/* tcpServerIP returns the IP address from structure s.  */

int
tcpServerIP (tcpServerState *s)
{
  return *((int *)s->hp->h_addr_list[0]);
}

/* tcpServerClientIP returns the IP address of the client who
   has connected to server s.  */

unsigned int
tcpServerClientIP (tcpServerState *s)
{
  unsigned int ip;

  ASSERT (s->isa.sin_family == AF_INET);
  ASSERT (sizeof (ip) == 4);
  memcpy (&ip, &s->isa.sin_addr, sizeof (ip));
  return ip;
}

/* tcpServerClientPortNo returns the port number of the client who
   has connected to server s.  */

unsigned int
tcpServerClientPortNo (tcpServerState *s)
{
  return s->isa.sin_port;
}

/*
****************************************************************
***             C L I E N T     R O U T I N E S
****************************************************************
 */

typedef struct
{
  char hostname[MAXHOSTNAME];
  struct hostent *hp;
  struct sockaddr_in sa;
  int sockFd;
  int portNo;
} tcpClientState;

/* tcpClientSocket returns a file descriptor (socket) which has
   connected to, serverName:portNo.  */

tcpClientState *
tcpClientSocket (char *serverName, int portNo)
{
  tcpClientState *s = (tcpClientState *)malloc (sizeof (tcpClientState));

  if (s == NULL)
    ERROR ("no more memory");

  /* Remove SIGPIPE which is raised on the server if the client is killed.  */
  signal (SIGPIPE, SIG_IGN);

  s->hp = gethostbyname (serverName);
  if (s->hp == NULL)
    {
      fprintf (stderr, "cannot find host: %s\n", serverName);
      exit (1);
    }

  memset ((void *)&s->sa, 0, sizeof (s->sa));
  s->sa.sin_family = AF_INET;
  memcpy ((void *)&s->sa.sin_addr, (void *)s->hp->h_addr, s->hp->h_length);
  s->portNo = portNo;
  s->sa.sin_port = htons (portNo);

  /* Open a TCP socket (an Internet stream socket).  */

  s->sockFd = socket (s->hp->h_addrtype, SOCK_STREAM, 0);
  return s;
}

/* tcpClientSocketIP returns a file descriptor (socket) which has
   connected to, ip:portNo.  */

tcpClientState *
tcpClientSocketIP (unsigned int ip, int portNo)
{
  tcpClientState *s = (tcpClientState *)malloc (sizeof (tcpClientState));

  if (s == NULL)
    ERROR ("no more memory");

  /* Remove SIGPIPE which is raised on the server if the client is killed.  */
  signal (SIGPIPE, SIG_IGN);

  memset ((void *)&s->sa, 0, sizeof (s->sa));
  s->sa.sin_family = AF_INET;
  memcpy ((void *)&s->sa.sin_addr, (void *)&ip, sizeof (ip));
  s->portNo = portNo;
  s->sa.sin_port = htons (portNo);

  /* Open a TCP socket (an Internet stream socket).  */

  s->sockFd = socket (PF_INET, SOCK_STREAM, 0);
  return s;
}

/* tcpClientConnect returns the file descriptor associated with s,
   once a connect has been performed.  */

int
tcpClientConnect (tcpClientState *s)
{
  if (connect (s->sockFd, (struct sockaddr *)&s->sa, sizeof (s->sa)) < 0)
    ERROR ("failed to connect to the TCP server");

  return s->sockFd;
}

/* tcpClientPortNo returns the portNo from structure s.  */

int
tcpClientPortNo (tcpClientState *s)
{
  return s->portNo;
}

/* tcpClientSocketFd returns the sockFd from structure s.  */

int
tcpClientSocketFd (tcpClientState *s)
{
  return s->sockFd;
}

/* tcpClientIP returns the sockFd from structure s.  */

int
tcpClientIP (tcpClientState *s)
{
#if defined(DEBUGGING)
  printf ("client ip = %s\n", inet_ntoa (s->sa.sin_addr.s_addr));
#endif
  return s->sa.sin_addr.s_addr;
}
#endif

/* GNU Modula-2 link fodder.  */

void
_M2_sckt_init (void)
{
}

void
_M2_sckt_finish (void)
{
}
-----------------------------
New file: ./libm2iso/wrapsock.c
-----------------------------
/* wrapsock.c provides access to socket related system calls.

Copyright (C) 2008-2022 Free Software Foundation, Inc.
Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.

This file is part of GNU Modula-2.

GNU Modula-2 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GNU Modula-2 is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

#include "config.h"

#if defined(HAVE_SYS_TYPES_H)
#include "sys/types.h"
#endif

#if defined(HAVE_SYS_SOCKET_H)
#include "sys/socket.h"
#endif

#if defined(HAVE_NETINET_IN_H)
#include "netinet/in.h"
#endif

#if defined(HAVE_NETDB_H)
#include "netdb.h"
#endif

#if defined(HAVE_UNISTD_H)
#include "unistd.h"
#endif

#if defined(HAVE_SIGNAL_H)
#include "signal.h"
#endif

#if defined(HAVE_SYS_ERRNO_H)
#include "sys/errno.h"
#endif

#if defined(HAVE_ERRNO_H)
#include "errno.h"
#endif

#if defined(HAVE_MALLOC_H)
#include "malloc.h"
#endif

#if defined(HAVE_MALLOC_H)
#include "signal.h"
#endif

#if defined(HAVE_STRING_H)
#include "string.h"
#endif

#if defined(HAVE_STDLIB_H)
#include "stdlib.h"
#endif

#if !defined(TRUE)
#define TRUE (1 == 1)
#endif
#if !defined(FALSE)
#define FALSE (1 == 0)
#endif

#include "ChanConsts.h"

#define MAXHOSTNAME 1024
#define MAXPBBUF 1024

#if defined(HAVE_NETINET_IN_H)

typedef struct
{
  char hostname[MAXHOSTNAME];
  struct hostent *hp;
  struct sockaddr_in sa;
  int sockFd;
  int portNo;
  int hasChar;
  char pbChar[MAXPBBUF];
} clientInfo;

static openResults clientConnect (clientInfo *c);

/* clientOpen - returns an ISO Modula-2 OpenResult.  It attempts to
   connect to: hostname:portNo.  If successful then the data
   structure, c, will have its fields initialized.  */

openResults
wrapsock_clientOpen (clientInfo *c, char *hostname, unsigned int length,
                     int portNo)
{
  /* remove SIGPIPE which is raised on the server if the client is killed.  */
  signal (SIGPIPE, SIG_IGN);

  c->hp = gethostbyname (hostname);
  if (c->hp == NULL)
    return noSuchFile;

  memset ((void *)&c->sa, 0, sizeof (c->sa));
  c->sa.sin_family = AF_INET;
  memcpy ((void *)&c->sa.sin_addr, (void *)c->hp->h_addr, c->hp->h_length);
  c->portNo = portNo;
  c->sa.sin_port = htons (portNo);
  c->hasChar = 0;
  /* Open a TCP socket (an Internet stream socket) */

  c->sockFd = socket (c->hp->h_addrtype, SOCK_STREAM, 0);
  return clientConnect (c);
}

/* clientOpenIP - returns an ISO Modula-2 OpenResult.  It attempts to
   connect to: ipaddress:portNo.  If successful then the data
   structure, c, will have its fields initialized.  */

openResults
wrapsock_clientOpenIP (clientInfo *c, unsigned int ip, int portNo)
{
  /* remove SIGPIPE which is raised on the server if the client is killed.  */
  signal (SIGPIPE, SIG_IGN);

  memset ((void *)&c->sa, 0, sizeof (c->sa));
  c->sa.sin_family = AF_INET;
  memcpy ((void *)&c->sa.sin_addr, (void *)&ip, sizeof (ip));
  c->portNo = portNo;
  c->sa.sin_port = htons (portNo);

  /* Open a TCP socket (an Internet stream socket) */

  c->sockFd = socket (PF_INET, SOCK_STREAM, 0);
  return clientConnect (c);
}

/* clientConnect - returns an ISO Modula-2 OpenResult once a connect
   has been performed.  If successful the clientInfo will include the
   file descriptor ready for read/write operations.  */

static openResults
clientConnect (clientInfo *c)
{
  if (connect (c->sockFd, (struct sockaddr *)&c->sa, sizeof (c->sa)) < 0)
    return noSuchFile;

  return opened;
}

/* getClientPortNo - returns the portNo from structure, c.  */

int
wrapsock_getClientPortNo (clientInfo *c)
{
  return c->portNo;
}

/* getClientHostname - fills in the hostname of the server the to
   which the client is connecting.  */

void
wrapsock_getClientHostname (clientInfo *c, char *hostname, unsigned int high)
{
  strncpy (hostname, c->hostname, high + 1);
}

/* getClientSocketFd - returns the sockFd from structure, c.  */

int
wrapsock_getClientSocketFd (clientInfo *c)
{
  return c->sockFd;
}

/* getClientIP - returns the sockFd from structure, s.  */

unsigned int
wrapsock_getClientIP (clientInfo *c)
{
#if 0
  printf("client ip = %s\n", inet_ntoa (c->sa.sin_addr.s_addr));
#endif
  return c->sa.sin_addr.s_addr;
}

/* getPushBackChar - returns TRUE if a pushed back character is
   available.  */

unsigned int
wrapsock_getPushBackChar (clientInfo *c, char *ch)
{
  if (c->hasChar > 0)
    {
      c->hasChar--;
      *ch = c->pbChar[c->hasChar];
      return TRUE;
    }
  return FALSE;
}

/* setPushBackChar - returns TRUE if it is able to push back a
   character.  */

unsigned int
wrapsock_setPushBackChar (clientInfo *c, char ch)
{
  if (c->hasChar == MAXPBBUF)
    return FALSE;
  c->pbChar[c->hasChar] = ch;
  c->hasChar++;
  return TRUE;
}

/* getSizeOfClientInfo - returns the sizeof (opaque data type).  */

unsigned int
wrapsock_getSizeOfClientInfo (void)
{
  return sizeof (clientInfo);
}

#endif

/* GNU Modula-2 link fodder.  */

void
_M2_wrapsock_init (void)
{
}

void
_M2_wrapsock_finish (void)
{
}
-----------------------------
New file: ./libm2iso/ChanConsts.h
-----------------------------
/* ChanConsts.h provides a C header file for ISO ChanConst.def.

Copyright (C) 2009-2022 Free Software Foundation, Inc.
Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.

This file is part of GNU Modula-2.

GNU Modula-2 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GNU Modula-2 is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

/* taken from ChanConsts.def */

typedef enum openResults {
  opened,          /* the open succeeded as requested.  */
  wrongNameFormat, /* given name is in the wrong format for the implementation.
                      */
  wrongFlags, /* given flags include a value that does not apply to the device.
                 */
  tooManyOpen,      /* this device cannot support any more open channels.  */
  outOfChans,       /* no more channels can be allocated.  */
  wrongPermissions, /* file or directory permissions do not allow request.  */
  noRoomOnDevice,   /* storage limits on the device prevent the open.  */
  noSuchFile,       /* a needed file does not exist.  */
  fileExists,    /* a file of the given name already exists when a new one is
                    required.  */
  wrongFileType, /* the file is of the wrong type to support the required
                    operations.  */
  noTextOperations, /* text operations have been requested, but are not
                       supported.  */
  noRawOperations,  /* raw operations have been requested, but are not
                       supported.  */
  noMixedOperations,

  /* text and raw operations have been requested, but they are not
  supported in combination */
  alreadyOpen,

  /* the source/destination is already open for operations not
  supported in combination with the requested operations */
  otherProblem /* open failed for some other reason.  */
} openResults;
-----------------------------
New file: ./libm2iso/Makefile.am
-----------------------------
# Makefile for libm2iso.
#   Copyright 2013-2022  Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING3.  If not see
# <http://www.gnu.org/licenses/>.

SUFFIXES = .c .mod .def .o .obj .lo .a .la

ACLOCAL_AMFLAGS = -I . -I .. -I ../config

VPATH = . @srcdir@ @srcdir@/../../gcc/m2/gm2-libs-iso

# Multilib support.
MAKEOVERRIDES=

version := $(shell $(CC) -dumpversion)

# Directory in which the compiler finds libraries etc.
libsubdir = $(libdir)/gcc/$(target_alias)/$(version)
# Used to install the shared libgcc.
slibdir = @slibdir@

toolexeclibdir=@toolexeclibdir@
toolexecdir=@toolexecdir@

MULTIDIR := $(shell $(CC) $(CFLAGS) -print-multi-directory)
MULTIOSDIR := $(shell $(CC) $(CFLAGS) -print-multi-os-directory)

MULTIOSSUBDIR := $(shell if test x$(MULTIOSDIR) != x.; then echo /$(MULTIOSDIR); fi)
inst_libdir = $(libsubdir)$(MULTISUBDIR)
inst_slibdir = $(slibdir)$(MULTIOSSUBDIR)


# Work around what appears to be a GNU make bug handling MAKEFLAGS
# values defined in terms of make variables, as is the case for CC and
# friends when we are called from the top level Makefile.
AM_MAKEFLAGS = \
        "GCC_DIR=$(GCC_DIR)" \
        "GM2_SRC=$(GM2_SRC)" \
	"AR_FLAGS=$(AR_FLAGS)" \
	"CC_FOR_BUILD=$(CC_FOR_BUILD)" \
	"CC_FOR_TARGET=$(CC_FOR_TARGET)" \
	"GM2_FOR_TARGET=$(GM2_FOR_TARGET)" \
	"CFLAGS=$(CFLAGS)" \
	"CXXFLAGS=$(CXXFLAGS)" \
	"CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
	"CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
	"INSTALL=$(INSTALL)" \
	"INSTALL_DATA=$(INSTALL_DATA)" \
	"INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
	"INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
	"LDFLAGS=$(LDFLAGS)" \
	"LIBCFLAGS=$(LIBCFLAGS)" \
	"LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
	"MAKE=$(MAKE)" \
	"MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
        "MULTISUBDIR=$(MULTISUBDIR)" \
        "MULTIOSDIR=$(MULTIOSDIR)" \
        "MULTIBUILDTOP=$(MULTIBUILDTOP)" \
        "MULTIFLAGS=$(MULTIFLAGS)" \
	"PICFLAG=$(PICFLAG)" \
	"PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
	"SHELL=$(SHELL)" \
	"RUNTESTFLAGS=$(RUNTESTFLAGS)" \
	"exec_prefix=$(exec_prefix)" \
	"infodir=$(infodir)" \
	"libdir=$(libdir)" \
	"includedir=$(includedir)" \
	"prefix=$(prefix)" \
	"tooldir=$(tooldir)" \
        "toolexeclibdir=$(toolexeclibdir)" \
        "toolexecdir=$(toolexecdir)" \
	"gxx_include_dir=$(gxx_include_dir)" \
	"AR=$(AR)" \
	"AS=$(AS)" \
	"LD=$(LD)" \
	"RANLIB=$(RANLIB)" \
	"NM=$(NM)" \
	"NM_FOR_BUILD=$(NM_FOR_BUILD)" \
	"NM_FOR_TARGET=$(NM_FOR_TARGET)" \
	"DESTDIR=$(DESTDIR)" \
	"WERROR=$(WERROR)" \
        "TARGET_LIB_PATH_libgm2=$(TARGET_LIB_PATH_libgm2)"

# Subdir rules rely on $(FLAGS_TO_PASS)
FLAGS_TO_PASS = $(AM_MAKEFLAGS)


if BUILD_ISOLIB
M2DEFS = ChanConsts.def  CharClass.def \
         ClientSocket.def  ComplexMath.def \
         ConvStringLong.def  ConvStringReal.def \
         ConvTypes.def  COROUTINES.def \
         ErrnoCategory.def  EXCEPTIONS.def \
         GeneralUserExceptions.def  IOChan.def \
         IOConsts.def  IOLink.def \
         IOResult.def  LongComplexMath.def \
         LongConv.def  LongIO.def \
         LongMath.def  LongStr.def \
         LongWholeIO.def  LowLong.def \
         LowReal.def  LowShort.def \
         M2EXCEPTION.def  M2RTS.def \
         MemStream.def \
         Preemptive.def \
         Processes.def  ProgramArgs.def \
         RandomNumber.def \
         RawIO.def  RealConv.def \
         RealIO.def  RealMath.def \
         RealStr.def  RndFile.def \
         RTco.def \
         RTdata.def  RTentity.def \
         RTfio.def  RTgen.def \
         RTgenif.def  RTio.def \
         Semaphores.def  SeqFile.def \
         ServerSocket.def  ShortComplexMath.def \
         ShortIO.def  ShortWholeIO.def \
         SimpleCipher.def  SIOResult.def \
         SLongIO.def  SLongWholeIO.def \
         SRawIO.def  SRealIO.def \
         SShortIO.def  SShortWholeIO.def \
         StdChans.def  STextIO.def \
         Storage.def  StreamFile.def \
         StringChan.def  Strings.def \
         SWholeIO.def  SysClock.def \
         SYSTEM.def  TermFile.def \
         TERMINATION.def  TextIO.def \
         WholeConv.def  WholeIO.def \
         WholeStr.def  wrapsock.def \
         wraptime.def

M2MODS = ChanConsts.mod  CharClass.mod \
         ClientSocket.mod  ComplexMath.mod \
         ConvStringLong.mod  ConvStringReal.mod \
         ConvTypes.mod  COROUTINES.mod \
         EXCEPTIONS.mod  GeneralUserExceptions.mod \
         IOChan.mod  IOConsts.mod \
         IOLink.mod  IOResult.mod \
         LongComplexMath.mod  LongConv.mod \
         LongIO.mod  LongMath.mod \
         LongStr.mod  LongWholeIO.mod \
         LowLong.mod  LowReal.mod \
         LowShort.mod  M2EXCEPTION.mod \
         M2RTS.mod  MemStream.mod \
         Preemptive.mod \
         Processes.mod \
         ProgramArgs.mod  RandomNumber.mod \
         RawIO.mod  RealConv.mod \
         RealIO.mod  RealMath.mod \
         RealStr.mod  RndFile.mod \
         RTdata.mod  RTentity.mod \
         RTfio.mod  RTgenif.mod \
         RTgen.mod  RTio.mod \
         Semaphores.mod  SeqFile.mod \
         ServerSocket.mod  ShortComplexMath.mod \
         ShortIO.mod  ShortWholeIO.mod \
         SimpleCipher.mod  SIOResult.mod \
         SLongIO.mod  SLongWholeIO.mod \
         SRawIO.mod  SRealIO.mod \
         SShortIO.mod  SShortWholeIO.mod \
         StdChans.mod  STextIO.mod \
         Storage.mod  StreamFile.mod \
         StringChan.mod  Strings.mod \
         SWholeIO.mod  SysClock.mod \
         SYSTEM.mod  TermFile.mod \
         TERMINATION.mod  TextIO.mod \
         WholeConv.mod  WholeIO.mod \
         WholeStr.mod

toolexeclib_LTLIBRARIES = libm2iso.la
libm2iso_la_SOURCES =  $(M2MODS) \
                     ErrnoCategory.c  wrapsock.c \
                     wraptime.c RTco.c

C_INCLUDES = -I.. -I$(toplevel_srcdir)/libiberty -I$(toplevel_srcdir)/include

libm2isodir = libm2iso
libm2iso_la_DEPENDENCIES = SYSTEM.def $(addsuffix .lo, $(basename $(libm2iso_la_SOURCES)))
libm2iso_la_CFLAGS = $(C_INCLUDES) -I. -I.. -I$(GM2_SRC)/gm2-libs-iso -I$(GM2_SRC)/gm2-libs -DBUILD_GM2_LIBS -I@srcdir@/../ -I../../../gcc -I$(GCC_DIR) -I$(GCC_DIR)/../include -I../../libgcc -I$(GCC_DIR)/../libgcc -I$(MULTIBUILDTOP)../../gcc/include
libm2iso_la_M2FLAGS = -I. -Ilibm2iso -I$(GM2_SRC)/gm2-libs-iso -I$(GM2_SRC)/gm2-libs -fiso -fextended-opaque -fm2-g -g
libm2iso_la_LINK = $(LINK) -version-info $(libtool_VERSION)
CLEANFILES = SYSTEM.def
BUILT_SOURCES = SYSTEM.def

M2LIBDIR = /m2/m2iso/

SYSTEM.def: Makefile
	bash $(GM2_SRC)/tools-src/makeSystem -fiso \
             $(GM2_SRC)/gm2-libs-iso/SYSTEM.def \
             $(GM2_SRC)/gm2-libs-iso/SYSTEM.mod \
             -I$(GM2_SRC)/gm2-libs-iso:$(GM2_SRC)/gm2-libs \
             "$(GM2_FOR_TARGET)" $@

## add these to the .mod.o rule when optimization is fixed $(CFLAGS_FOR_TARGET) $(LIBCFLAGS)

.mod.lo:
	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(GM2_FOR_TARGET) -c $(CFLAGS_FOR_TARGET) $(LIBCFLAGS) $(libm2iso_la_M2FLAGS) $< -o $@

.c.lo:
	$(LIBTOOL) --tag=CC --mode=compile $(CC) -c $(CFLAGS) $(LIBCFLAGS) $(libm2iso_la_CFLAGS) $< -o $@

install-data-local: force
	mkdir -p $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)
	$(INSTALL_DATA) .libs/libm2iso.la $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)
	chmod 644 $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)libm2iso.la
	$(INSTALL_DATA) .libs/libm2iso.a $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)
	chmod 644 $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)/libm2iso.a
	$(RANLIB) $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)/libm2iso.a
	for i in $(M2DEFS) $(M2MODS) ; do \
           if [ -f $$i ] ; then \
              $(INSTALL_DATA) $$i '$(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)'; \
           elif [ -f @srcdir@/../../gcc/m2/gm2-libs-iso/$$i ] ; then \
              $(INSTALL_DATA) @srcdir@/../../gcc/m2/gm2-libs-iso/$$i '$(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)'; \
           else \
              echo "cannot find $$i" ; exit 1 ; \
           fi ; \
           chmod 644 $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)$$i ; \
	done

force:

endif
-----------------------------
New file: ./libm2iso/ErrnoCategory.c
-----------------------------
/* ErrnoCatogory.c categorizes values of errno maps onto ChanConsts.h.

Copyright (C) 2008-2022 Free Software Foundation, Inc.
Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.

This file is part of GNU Modula-2.

GNU Modula-2 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GNU Modula-2 is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

#include "config.h"

#include "ChanConsts.h"

#if defined(HAVE_ERRNO_H)
#include "errno.h"
#endif

#if defined(HAVE_SYS_ERRNO_H)
#include "sys/errno.h"
#endif

#if !defined(FALSE)
#define FALSE (1 == 0)
#endif

#if !defined(TRUE)
#define TRUE (1 == 1)
#endif

/* IsErrnoHard - returns TRUE if the value of errno is associated
   with a hard device error.  */

int
ErrnoCategory_IsErrnoHard (int e)
{
#if defined(HAVE_ERRNO_H) || defined(HAVE_SYS_ERRNO_H)
  return ((e == EPERM) || (e == ENOENT) || (e == EIO) || (e == ENXIO)
          || (e == EACCES) || (e == ENOTBLK) || (e == ENODEV) || (e == EINVAL)
          || (e == ENFILE) || (e == EROFS) || (e == EMLINK));
#else
  return FALSE;
#endif
}

/* IsErrnoSoft - returns TRUE if the value of errno is associated
   with a soft device error.  */

int
ErrnoCategory_IsErrnoSoft (int e)
{
#if defined(HAVE_ERRNO_H) || defined(HAVE_SYS_ERRNO_H)
  return ((e == ESRCH) || (e == EINTR) || (e == E2BIG) || (e == ENOEXEC)
          || (e == EBADF) || (e == ECHILD) || (e == EAGAIN) || (e == ENOMEM)
          || (e == EFAULT) || (e == EBUSY) || (e == EEXIST) || (e == EXDEV)
          || (e == ENOTDIR) || (e == EISDIR) || (e == EMFILE) || (e == ENOTTY)
          || (e == ETXTBSY) || (e == EFBIG) || (e == ENOSPC) || (e == EPIPE));
#else
  return FALSE;
#endif
}

int
ErrnoCategory_UnAvailable (int e)
{
#if defined(HAVE_ERRNO_H) || defined(HAVE_SYS_ERRNO_H)
  return ((e == ENOENT) || (e == ESRCH) || (e == ENXIO) || (e == ECHILD)
          || (e == ENOTBLK) || (e == ENODEV) || (e == ENOTDIR));
#else
  return FALSE;
#endif
}

/* GetOpenResults - maps errno onto the ISO Modula-2 enumerated type,
   OpenResults.  */

openResults
ErrnoCategory_GetOpenResults (int e)
{
  if (e == 0)
    return opened;
#if defined(HAVE_ERRNO_H) || defined(HAVE_SYS_ERRNO_H)
  switch (e)
    {
    case EPERM:
      return wrongPermissions;
      break;
    case ENOENT:
      return noSuchFile;
      break;
    case ENXIO:
      return noSuchFile;
      break;
    case EACCES:
      return wrongPermissions;
      break;
    case ENOTBLK:
      return wrongFileType;
      break;
    case EEXIST:
      return fileExists;
      break;
    case ENODEV:
      return noSuchFile;
      break;
    case ENOTDIR:
      return wrongFileType;
      break;
    case EISDIR:
      return wrongFileType;
      break;
    case EINVAL:
      return wrongFlags;
      break;
    case ENFILE:
      return tooManyOpen;
      break;
    case EMFILE:
      return tooManyOpen;
      break;
    case ENOTTY:
      return wrongFileType;
      break;
    case ENOSPC:
      return noRoomOnDevice;
      break;
    case EROFS:
      return wrongPermissions;
      break;

    default:
      return otherProblem;
    }
#else
  return otherProblem;
#endif
}

/* GNU Modula-2 linking fodder.  */

void
_M2_ErrnoCategory_init (void)
{
}

void
_M2_ErrnoCategory_finish (void)
{
}
-----------------------------
New file: ./libm2iso/RTco.c
-----------------------------
/* RTco.c provides minimal access to thread primitives.

Copyright (C) 2019-2022 Free Software Foundation, Inc.
Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.

This file is part of GNU Modula-2.

GNU Modula-2 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GNU Modula-2 is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include <unistd.h>
#include <pthread.h>
#include <sys/select.h>
#include <stdlib.h>

extern void M2RTS_Halt (const char *, int, const char *, const char *);
int RTco_init (void);

// #define TRACEON

#define POOL
#define SEM_POOL 10000
#define THREAD_POOL 10000

#define _GTHREAD_USE_COND_INIT_FUNC
#include "gthr.h"

/* Ensure that ANSI conform stdio is used.  This needs to be set
   before any system header file is included.  */
#if defined __MINGW32__
#define _POSIX 1
#define gm2_printf gnu_printf
#else
#define gm2_printf __printf__
#endif

#if !defined(TRUE)
#define TRUE (1 == 1)
#endif

#if !defined(FALSE)
#define FALSE (1 == 0)
#endif

#if defined(TRACEON)
#define tprintf printf
#else
/* sizeof is not evaluated.  */
#define tprintf (void)sizeof
#endif

typedef struct threadCB_s
{
  void (*proc) (void);
  int execution;
  pthread_t p;
  int tid;
  unsigned int interruptLevel;
} threadCB;


typedef struct threadSem_s
{
  __gthread_mutex_t mutex;
  __gthread_cond_t counter;
  int waiting;
  int sem_value;
} threadSem;

static unsigned int nThreads = 0;
static threadCB *threadArray = NULL;
static unsigned int nSemaphores = 0;
static threadSem **semArray = NULL;

/* used to lock the above module data structures.  */
static threadSem lock;
static int initialized = FALSE;

static void
initSem (threadSem *sem, int value)
{
  __GTHREAD_COND_INIT_FUNCTION (&sem->counter);
  __GTHREAD_MUTEX_INIT_FUNCTION (&sem->mutex);
  sem->waiting = FALSE;
  sem->sem_value = value;
}

static void
waitSem (threadSem *sem)
{
  __gthread_mutex_lock (&sem->mutex);
  if (sem->sem_value == 0)
    {
      sem->waiting = TRUE;
      __gthread_cond_wait (&sem->counter, &sem->mutex);
      sem->waiting = FALSE;
    }
  else
    sem->sem_value--;
  __gthread_mutex_unlock (&sem->mutex);
}

static void
signalSem (threadSem *sem)
{
  __gthread_mutex_unlock (&sem->mutex);
  if (sem->waiting)
    __gthread_cond_signal (&sem->counter);
  else
    sem->sem_value++;
  __gthread_mutex_unlock (&sem->mutex);
}

void stop (void) {}

void
RTco_wait (int sid)
{
  RTco_init ();
  tprintf ("wait %d\n", sid);
  waitSem (semArray[sid]);
}

void
RTco_signal (int sid)
{
  RTco_init ();
  tprintf ("signal %d\n", sid);
  signalSem (semArray[sid]);
}

static int
newSem (void)
{
#if defined(POOL)
  semArray[nSemaphores]
      = (threadSem *)malloc (sizeof (threadSem));
  nSemaphores += 1;
  if (nSemaphores == SEM_POOL)
    M2RTS_Halt (__FILE__, __LINE__, __FUNCTION__,
                "too many semaphores created");
#else
  threadSem *sem
      = (threadSem *)malloc (sizeof (threadSem));

  /* we need to be careful when using realloc as the lock (semaphore)
     operators use the semaphore address.  So we keep an array of pointer
     to semaphores.  */
  if (nSemaphores == 0)
    {
      semArray = (threadSem **)malloc (sizeof (sem));
      nSemaphores = 1;
    }
  else
    {
      nSemaphores += 1;
      semArray = (threadSem **)realloc (semArray,
					sizeof (sem) * nSemaphores);
    }
  semArray[nSemaphores - 1] = sem;
#endif
  return nSemaphores - 1;
}

static int
initSemaphore (int value)
{
  int sid = newSem ();

  initSem (semArray[sid], value);
  tprintf ("%d = initSemaphore (%d)\n", sid, value);
  return sid;
}

int
RTco_initSemaphore (int value)
{
  int sid;

  RTco_init ();
  waitSem (&lock);
  sid = initSemaphore (value);
  signalSem (&lock);
  return sid;
}

/* signalThread signal the semaphore associated with thread tid.  */

void
RTco_signalThread (int tid)
{
  int sem;
  RTco_init ();
  tprintf ("signalThread %d\n", tid);
  waitSem (&lock);
  sem = threadArray[tid].execution;
  signalSem (&lock);
  RTco_signal (sem);
}

/* waitThread wait on the semaphore associated with thread tid.  */

void
RTco_waitThread (int tid)
{
  RTco_init ();
  tprintf ("waitThread %d\n", tid);
  RTco_wait (threadArray[tid].execution);
}

int
currentThread (void)
{
  int tid;

  for (tid = 0; tid < nThreads; tid++)
    if (pthread_self () == threadArray[tid].p)
      return tid;
  M2RTS_Halt (__FILE__, __LINE__, __FUNCTION__,
              "failed to find currentThread");
}

int
RTco_currentThread (void)
{
  int tid;

  RTco_init ();
  waitSem (&lock);
  tid = currentThread ();
  tprintf ("currentThread %d\n", tid);
  signalSem (&lock);
  return tid;
}

/* currentInterruptLevel returns the interrupt level of the current thread.  */

unsigned int
RTco_currentInterruptLevel (void)
{
  RTco_init ();
  tprintf ("currentInterruptLevel %d\n",
           threadArray[RTco_currentThread ()].interruptLevel);
  return threadArray[RTco_currentThread ()].interruptLevel;
}

/* turninterrupts returns the old interrupt level and assigns the
   interrupt level to newLevel.  */

unsigned int
RTco_turnInterrupts (unsigned int newLevel)
{
  int tid = RTco_currentThread ();
  unsigned int old = RTco_currentInterruptLevel ();

  tprintf ("turnInterrupts from %d to %d\n", old, newLevel);
  waitSem (&lock);
  threadArray[tid].interruptLevel = newLevel;
  signalSem (&lock);
  return old;
}

static void
never (void)
{
  M2RTS_Halt (__FILE__, __LINE__, __FUNCTION__,
              "the main thread should never call here");
}

static void *
execThread (void *t)
{
  threadCB *tp = (threadCB *)t;

  tprintf ("exec thread tid = %d  function = 0x%p  arg = 0x%p\n", tp->tid,
           tp->proc, t);
  RTco_waitThread (
      tp->tid); /* forcing this thread to block, waiting to be scheduled.  */
  tprintf ("  exec thread [%d]  function = 0x%p  arg = 0x%p\n", tp->tid,
           tp->proc, t);
  tp->proc (); /* now execute user procedure.  */
#if 0
  M2RTS_CoroutineException ( __FILE__, __LINE__, __COLUMN__, __FUNCTION__, "coroutine finishing");
#endif
  M2RTS_Halt (__FILE__, __LINE__, __FUNCTION__, "execThread should never finish");
  return NULL;
}

static int
newThread (void)
{
#if defined(POOL)
  nThreads += 1;
  if (nThreads == THREAD_POOL)
    M2RTS_Halt (__FILE__, __LINE__, __FUNCTION__, "too many threads created");
  return nThreads - 1;
#else
  if (nThreads == 0)
    {
      threadArray = (threadCB *)malloc (sizeof (threadCB));
      nThreads = 1;
    }
  else
    {
      nThreads += 1;
      threadArray
          = (threadCB *)realloc (threadArray, sizeof (threadCB) * nThreads);
    }
  return nThreads - 1;
#endif
}

static int
initThread (void (*proc) (void), unsigned int stackSize,
            unsigned int interrupt)
{
  int tid = newThread ();
  pthread_attr_t attr;
  int result;

  threadArray[tid].proc = proc;
  threadArray[tid].tid = tid;
  threadArray[tid].execution = initSemaphore (0);
  threadArray[tid].interruptLevel = interrupt;

  /* set thread creation attributes.  */
  result = pthread_attr_init (&attr);
  if (result != 0)
    M2RTS_Halt (__FILE__, __LINE__, __FUNCTION__,
                "failed to create thread attribute");

  if (stackSize > 0)
    {
      result = pthread_attr_setstacksize (&attr, stackSize);
      if (result != 0)
        M2RTS_Halt (__FILE__, __LINE__, __FUNCTION__,
                    "failed to set stack size attribute");
    }

  tprintf ("initThread [%d]  function = 0x%p  (arg = 0x%p)\n", tid, proc,
           (void *)&threadArray[tid]);
  result = pthread_create (&threadArray[tid].p, &attr, execThread,
                           (void *)&threadArray[tid]);
  if (result != 0)
    M2RTS_Halt (__FILE__, __LINE__, __FUNCTION__, "thread_create failed");
  tprintf ("  created thread [%d]  function = 0x%p  0x%p\n", tid, proc,
           (void *)&threadArray[tid]);
  return tid;
}

int
RTco_initThread (void (*proc) (void), unsigned int stackSize,
                 unsigned int interrupt)
{
  int tid;

  RTco_init ();
  waitSem (&lock);
  tid = initThread (proc, stackSize, interrupt);
  signalSem (&lock);
  return tid;
}

/* transfer unlocks thread p2 and locks the current thread.  p1 is
   updated with the current thread id.  */

void
RTco_transfer (int *p1, int p2)
{
  int tid = currentThread ();

  if (!initialized)
    M2RTS_Halt (
        __FILE__, __LINE__, __FUNCTION__,
        "cannot transfer to a process before the process has been created");
  if (tid == p2)
    {
      /* error.  */
      M2RTS_Halt (__FILE__, __LINE__, __FUNCTION__,
	      "attempting to transfer to ourself");
    }
  else
    {
      *p1 = tid;
      tprintf ("start, context switching from: %d to %d\n", tid, p2);
      RTco_signalThread (p2);
      RTco_waitThread (tid);
      tprintf ("end, context back to %d\n", tid);
    }
}

int
RTco_select (int p1, void *p2, void *p3, void *p4, void *p5)
{
  tprintf ("[%x]  RTco.select (...)\n", pthread_self ());
  return pselect (p1, p2, p3, p4, p5, NULL);
}

int
RTco_init (void)
{
  if (!initialized)
    {
      int tid;

      tprintf ("RTco initialized\n");
      initSem (&lock, 0);
      /* create initial thread container.  */
#if defined(POOL)
      threadArray = (threadCB *)malloc (sizeof (threadCB) * THREAD_POOL);
      semArray = (threadSem **)malloc (sizeof (threadSem *) * SEM_POOL);
#endif
      tid = newThread (); /* for the current initial thread.  */
      threadArray[tid].tid = tid;
      threadArray[tid].execution = initSemaphore (0);
      threadArray[tid].p = pthread_self ();
      threadArray[tid].interruptLevel = 0;
      threadArray[tid].proc
          = never; /* this shouldn't happen as we are already running.  */
      initialized = TRUE;
      tprintf ("RTco initialized completed\n");
      signalSem (&lock);
    }
  return 0;
}

void
_M2_RTco_init ()
{
}

void
_M2_RTco_finish ()
{
}
-----------------------------
New file: ./libm2iso/wraptime.c
-----------------------------
/* wraptime.c provides access to time related system calls.

Copyright (C) 2009-2022 Free Software Foundation, Inc.
Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.

This file is part of GNU Modula-2.

GNU Modula-2 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GNU Modula-2 is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

#include "config.h"

#if defined(HAVE_SYS_TYPES_H)
#include "sys/types.h"
#endif

#if defined(HAVE_SYS_TIME_H)
#include "sys/time.h"
#endif

#if defined(HAVE_TIME_H)
#include "time.h"
#endif

#if defined(HAVE_MALLOC_H)
#include "malloc.h"
#endif

#if defined(HAVE_LIMITS_H)
#include "limits.h"
#endif

#if !defined(TRUE)
#define TRUE (1 == 1)
#endif

#if !defined(FALSE)
#define FALSE (1 == 0)
#endif

#if !defined(NULL)
#define NULL (void *)0
#endif

/* InitTimeval returns a newly created opaque type.  */

#if defined(HAVE_TIMEVAL) && defined(HAVE_MALLOC_H)
struct timeval *
wraptime_InitTimeval (void)
{
  return (struct timeval *)malloc (sizeof (struct timeval));
}
#else
void *
wraptime_InitTimeval (void)
{
  return NULL;
}
#endif

/* KillTimeval deallocates the memory associated with an opaque type.  */

struct timeval *
wraptime_KillTimeval (void *tv)
{
#if defined(HAVE_MALLOC_H)
  free (tv);
#endif
  return NULL;
}

/* InitTimezone returns a newly created opaque type.  */

#if defined(HAVE_STRUCT_TIMEZONE) && defined(HAVE_MALLOC_H)
struct timezone *
wraptime_InitTimezone (void)
{
  return (struct timezone *)malloc (sizeof (struct timezone));
}
#else
void *
wraptime_InitTimezone (void)
{
  return NULL;
}
#endif

/* KillTimezone - deallocates the memory associated with an opaque
   type.  */

struct timezone *
wraptime_KillTimezone (struct timezone *tv)
{
#if defined(HAVE_MALLOC_H)
  free (tv);
#endif
  return NULL;
}

/* InitTM - returns a newly created opaque type.  */

#if defined(HAVE_STRUCT_TM) && defined(HAVE_MALLOC_H)
struct tm *
wraptime_InitTM (void)
{
  return (struct tm *)malloc (sizeof (struct tm));
}
#else
void *
wraptime_InitTM (void)
{
  return NULL;
}
#endif

/* KillTM - deallocates the memory associated with an opaque type.  */

struct tm *
wraptime_KillTM (struct tm *tv)
{
#if defined(HAVE_MALLOC_H)
  free (tv);
#endif
  return NULL;
}

/* gettimeofday - calls gettimeofday(2) with the same parameters, tv,
   and, tz.  It returns 0 on success.  */

#if defined(HAVE_STRUCT_TIMEZONE) && defined(HAVE_GETTIMEOFDAY)
int
wraptime_gettimeofday (void *tv, struct timezone *tz)
{
  return gettimeofday (tv, tz);
}
#else
int
wraptime_gettimeofday (void *tv, void *tz)
{
  return -1;
}
#endif

/* settimeofday - calls settimeofday(2) with the same parameters, tv,
   and, tz.  It returns 0 on success.  */

#if defined(HAVE_STRUCT_TIMEZONE) && defined(HAVE_SETTIMEOFDAY)
int
wraptime_settimeofday (void *tv, struct timezone *tz)
{
  return settimeofday (tv, tz);
}
#else
int
wraptime_settimeofday (void *tv, void *tz)
{
  return -1;
}
#endif

/* wraptime_GetFractions - returns the tv_usec field inside the
   timeval structure.  */

#if defined(HAVE_TIMEVAL)
unsigned int
wraptime_GetFractions (struct timeval *tv)
{
  return (unsigned int)tv->tv_usec;
}
#else
unsigned int
wraptime_GetFractions (void *tv)
{
  return (unsigned int)-1;
}
#endif

/* localtime_r - returns the tm parameter, m, after it has been
   assigned with appropriate contents determined by, tv.  Notice that
   this procedure function expects, timeval, as its first parameter
   and not a time_t (as expected by the posix equivalent).  */

#if defined(HAVE_TIMEVAL)
struct tm *
wraptime_localtime_r (struct timeval *tv, struct tm *m)
{
  return localtime_r (&tv->tv_sec, m);
}
#else
struct tm *
wraptime_localtime_r (void *tv, struct tm *m)
{
  return m;
}
#endif

/* wraptime_GetYear - returns the year from the structure, m.  */

#if defined(HAVE_STRUCT_TM)
unsigned int
wraptime_GetYear (struct tm *m)
{
  return m->tm_year;
}
#else
unsigned int
wraptime_GetYear (void *m)
{
  return (unsigned int)-1;
}
#endif

/* wraptime_GetMonth - returns the month from the structure, m.  */

#if defined(HAVE_STRUCT_TM)
unsigned int
wraptime_GetMonth (struct tm *m)
{
  return m->tm_mon;
}
#else
unsigned int
wraptime_GetMonth (void *m)
{
  return (unsigned int)-1;
}
#endif

/* wraptime_GetDay - returns the day of the month from the structure,
   m.  */

#if defined(HAVE_STRUCT_TM)
unsigned int
wraptime_GetDay (struct tm *m)
{
  return m->tm_mday;
}
#else
unsigned int
wraptime_GetDay (void *m)
{
  return (unsigned int)-1;
}
#endif

/* wraptime_GetHour - returns the hour of the day from the structure,
   m.  */

#if defined(HAVE_STRUCT_TM)
unsigned int
wraptime_GetHour (struct tm *m)
{
  return m->tm_hour;
}
#else
unsigned int
wraptime_GetHour (void *m)
{
  return (unsigned int)-1;
}
#endif

/* wraptime_GetMinute - returns the minute within the hour from the
   structure, m.  */

#if defined(HAVE_STRUCT_TM)
unsigned int
wraptime_GetMinute (struct tm *m)
{
  return m->tm_min;
}
#else
unsigned int
wraptime_GetMinute (void *m)
{
  return (unsigned int)-1;
}
#endif

/* wraptime_GetSecond - returns the seconds in the minute from the
   structure, m.  The return value will always be in the range 0..59.
   A leap minute of value 60 will be truncated to 59.  */

#if defined(HAVE_STRUCT_TM)
unsigned int
wraptime_GetSecond (struct tm *m)
{
  if (m->tm_sec == 60)
    return 59;
  else
    return m->tm_sec;
}
#else
unsigned int
wraptime_GetSecond (void *m)
{
  return (unsigned int)-1;
}
#endif

/* wraptime_GetSummerTime - returns true if summer time is in effect.  */

#if defined(HAVE_STRUCT_TIMEZONE)
unsigned int
wraptime_GetSummerTime (struct timezone *tz)
{
  return tz->tz_dsttime != 0;
}
#else
unsigned int
wraptime_GetSummerTime (void *tz)
{
  return FALSE;
}
#endif

/* wraptime_GetDST - returns the number of minutes west of GMT.  */

#if defined(HAVE_STRUCT_TIMEZONE)
int
wraptime_GetDST (struct timezone *tz)
{
  return tz->tz_minuteswest;
}
#else
int
wraptime_GetDST (void *tz)
{
#if defined(INT_MIN)
  return INT_MIN;
#else
  return (int)((unsigned int)-1);
#endif
}
#endif

/* SetTimezone - set the timezone field inside timeval, tv.  */

#if defined(HAVE_STRUCT_TIMEZONE)
void
wraptime_SetTimezone (struct timezone *tz, int zone, int minuteswest)
{
  tz->tz_dsttime = zone;
  tz->tz_minuteswest = minuteswest;
}
#else
void
wraptime_SetTimezone (void *tz, int zone, int minuteswest)
{
}
#endif

/* SetTimeval - sets the fields in tm, t, with: second, minute, hour,
   day, month, year, fractions.  */

#if defined(HAVE_TIMEVAL)
void
wraptime_SetTimeval (struct tm *t, unsigned int second, unsigned int minute,
                     unsigned int hour, unsigned int day, unsigned int month,
                     unsigned int year, unsigned int yday, unsigned int wday,
                     unsigned int isdst)
{
  t->tm_sec = second;
  t->tm_min = minute;
  t->tm_hour = hour;
  t->tm_mday = day;
  t->tm_mon = month;
  t->tm_year = year;
  t->tm_yday = yday;
  t->tm_wday = wday;
  t->tm_isdst = isdst;
}
#else
void
wraptime_SetTimeval (void *t, unsigned int second, unsigned int minute,
                     unsigned int hour, unsigned int day, unsigned int month,
                     unsigned int year, unsigned int yday, unsigned int wday,
                     unsigned int isdst)
{
}
#endif

/* init - init/finish functions for the module */

void
_M2_wraptime_init ()
{
}
void
_M2_wraptime_finish ()
{
}
-----------------------------
New file: ./configure.ac
-----------------------------
# Configure script for libgm2.
# Copyright (C) 2013-2022 Free Software Foundation, Inc.

# This file is part of GCC.

# GCC is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.

# GCC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with GCC; see the file COPYING3.  If not see
# <http://www.gnu.org/licenses/>.

# Configure looks for the existence of this file to auto-config each language.
# We define several parameters used by configure:

# Process this file with autoreconf to produce a configure script.

AC_INIT(package-unused, version-unused,,libgm2)
AC_CONFIG_SRCDIR(Makefile.am)
# AC_CONFIG_MACRO_DIR([config])
AC_CONFIG_HEADER(config.h)

libtool_VERSION=17:0:0
AC_SUBST(libtool_VERSION)

AM_ENABLE_MULTILIB(, ..)

GCC_NO_EXECUTABLES

AC_USE_SYSTEM_EXTENSIONS

# Do not delete or change the following two lines.  For why, see
# http://gcc.gnu.org/ml/libstdc++/2003-07/msg00451.html
AC_CANONICAL_SYSTEM
target_alias=${target_alias-$host_alias}
AC_SUBST(target_alias)

AM_INIT_AUTOMAKE([1.9.3 no-define foreign no-dist -Wall -Wno-portability])

AH_TEMPLATE(PACKAGE, [Name of package])
AH_TEMPLATE(VERSION, [Version number of package])

AC_ARG_WITH(cross-host,
[  --with-cross-host=HOST           Configuring with a cross compiler])

# Checks for header files.
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_CHECK_HEADER([math.h],
	       [AC_DEFINE([HAVE_MATH_H], [1], [have math.h])])

AC_CHECK_HEADERS(limits.h stddef.h string.h strings.h stdlib.h \
                 time.h \
		 fcntl.h unistd.h sys/file.h sys/time.h sys/mman.h \
		 sys/resource.h sys/param.h sys/times.h sys/stat.h \
                 sys/socket.h \
                 sys/wait.h sys/ioctl.h errno.h sys/errno.h \
		 pwd.h direct.h dirent.h signal.h malloc.h langinfo.h \
                 pthread.h stdarg.h stdio.h sys/types.h termios.h \
                 netinet/in.h netdb.h sys/uio.h sys/stat.h wchar.h)


AC_CANONICAL_HOST
ACX_NONCANONICAL_HOST
ACX_NONCANONICAL_TARGET
GCC_TOPLEV_SUBDIRS

AC_MSG_CHECKING([for --enable-version-specific-runtime-libs])
AC_ARG_ENABLE(version-specific-runtime-libs,
[  --enable-version-specific-runtime-libs    Specify that runtime libraries should be installed in a compiler-specific directory ],
[case "$enableval" in
 yes) version_specific_libs=yes ;;
 no)  version_specific_libs=no ;;
 *)   AC_MSG_ERROR([Unknown argument to enable/disable version-specific libs]);;
 esac],
[version_specific_libs=no])
AC_MSG_RESULT($version_specific_libs)

AC_ARG_WITH(slibdir,
[  --with-slibdir=DIR      shared libraries in DIR [LIBDIR]],
slibdir="$with_slibdir",
if test "${version_specific_libs}" = yes; then
  slibdir='$(libsubdir)'
elif test -n "$with_cross_host" && test x"$with_cross_host" != x"no"; then
  slibdir='$(exec_prefix)/$(host_noncanonical)/lib'
else
  slibdir='$(libdir)'
fi)
AC_SUBST(slibdir)

# Command-line options.
# Very limited version of AC_MAINTAINER_MODE.
AC_ARG_ENABLE([maintainer-mode],
  [AC_HELP_STRING([--enable-maintainer-mode],
                 [enable make rules and dependencies not useful (and
                  sometimes confusing) to the casual installer])],
  [case ${enable_maintainer_mode} in
     yes) MAINT='' ;;
     no) MAINT='#' ;;
     *) AC_MSG_ERROR([--enable-maintainer-mode must be yes or no]) ;;
   esac
   maintainer_mode=${enableval}],
  [MAINT='#'])
AC_SUBST([MAINT])dnl

toolexecdir=no
toolexeclibdir=no

# Calculate toolexeclibdir
# Also toolexecdir, though it's only used in toolexeclibdir
case ${version_specific_libs} in
  yes)
    # Need the gcc compiler version to know where to install libraries
    # and header files if --enable-version-specific-runtime-libs option
    # is selected.
    toolexecdir='$(libdir)/gcc/$(target_noncanonical)'
    toolexeclibdir='$(toolexecdir)/$(gcc_version)$(MULTISUBDIR)'
    ;;
  no)
    if test -n "$with_cross_host" &&
       test x"$with_cross_host" != x"no"; then
      # Install a library built with a cross compiler in tooldir, not libdir.
      toolexecdir='$(exec_prefix)/$(target_noncanonical)'
      toolexeclibdir='$(toolexecdir)/lib'
    else
      toolexecdir='$(libdir)/gcc-lib/$(target_noncanonical)'
      toolexeclibdir='$(libdir)'
    fi
    multi_os_directory=`$CC -print-multi-os-directory`
    case $multi_os_directory in
      .) ;; # Avoid trailing /.
      *) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
    esac
    ;;
esac

AC_SUBST(toolexecdir)
AC_SUBST(toolexeclibdir)

AH_TEMPLATE(PACKAGE, [Name of package])
AH_TEMPLATE(VERSION, [Version number of package])

AM_MAINTAINER_MODE

# Check the compiler.
# The same as in boehm-gc and libstdc++. Have to borrow it from there.
# We must force CC to /not/ be precious variables; otherwise
# the wrong, non-multilib-adjusted value will be used in multilibs.
# As a side effect, we have to subst CFLAGS ourselves.

m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
m4_define([_AC_ARG_VAR_PRECIOUS],[])
AC_PROG_CC
AC_PROG_CXX
AM_PROG_AS
m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])

AC_SUBST(CFLAGS)

# In order to override CFLAGS_FOR_TARGET, all of our special flags go
# in XCFLAGS.  But we need them in CFLAGS during configury.  So put them
# in both places for now and restore CFLAGS at the end of config.
save_CFLAGS="$CFLAGS"

# Find other programs we need.
AC_CHECK_TOOL(AR, ar)
AC_CHECK_TOOL(NM, nm)
AC_CHECK_TOOL(RANLIB, ranlib, ranlib-not-found-in-path-error)
AC_PATH_PROG(PERL, perl, perl-not-found-in-path-error)
AC_PROG_MAKE_SET
AC_PROG_INSTALL

LT_INIT
AC_LIBTOOL_DLOPEN
# AM_PROG_LIBTOOL
AC_SUBST(enable_shared)
AC_SUBST(enable_static)

AC_CHECK_TYPES([struct timezone, struct stat, struct timeval])

AC_LANG_C
# Check the compiler.
# The same as in boehm-gc and libstdc++. Have to borrow it from there.
# We must force CC to /not/ be precious variables; otherwise
# the wrong, non-multilib-adjusted value will be used in multilibs.
# As a side effect, we have to subst CFLAGS ourselves.

m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
m4_define([_AC_ARG_VAR_PRECIOUS],[])
AC_PROG_CC
m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])

AC_SUBST(CFLAGS)

AC_DEFUN([GM2_UNDEF],[
  $as_echo "#undef HAVE_$1" >>confdefs.h
])

AC_DEFUN([GM2_CHECK_LIB],[
  AC_MSG_CHECKING([m2 front end checking $1 library for $2])
  if test x$gcc_no_link != xyes; then
    AC_CHECK_LIB([$1],[$2],[AC_DEFINE([HAVE_$3],[1],[found $2])],[GM2_UNDEF([$3],[$2])])
  else
    if test "x$[ac_cv_lib_$1_$2]" = xyes; then
      AC_DEFINE([HAVE_$3],[1],[lib$1 includes $2])
    elif test "x$[ac_cv_func_$2]" = xyes; then
      AC_DEFINE([HAVE_$3],[1],[function $2 exists])
    else
      GM2_UNDEF([$3],[$2])
    fi
  fi
])

GM2_CHECK_LIB([c],[access],[ACCESS])
GM2_CHECK_LIB([c],[brk],[BRK])
GM2_CHECK_LIB([c],[cfmakeraw],[CFMAKERAW])
GM2_CHECK_LIB([c],[close],[CLOSE])
GM2_CHECK_LIB([c],[ctime],[CTIME])
GM2_CHECK_LIB([c],[creat],[CREAT])
GM2_CHECK_LIB([c],[dup],[DUP])
GM2_CHECK_LIB([c],[execve],[EXECVE])
GM2_CHECK_LIB([c],[exit],[EXIT])
GM2_CHECK_LIB([c],[fcntl],[FCNTL])
GM2_CHECK_LIB([c],[fstat],[FSTAT])
GM2_CHECK_LIB([c],[getdents],[GETDENTS])
GM2_CHECK_LIB([c],[getgid],[GETGID])
GM2_CHECK_LIB([c],[getpid],[GETPID])
GM2_CHECK_LIB([c],[gettimeofday],[GETTIMEOFD])
GM2_CHECK_LIB([c],[getuid],[GETUID])
GM2_CHECK_LIB([c],[ioctl],[IOCTL])
GM2_CHECK_LIB([c],[kill],[KILL])
GM2_CHECK_LIB([c],[link],[LINK])
GM2_CHECK_LIB([c],[lseek],[LSEEK])
GM2_CHECK_LIB([c],[open],[OPEN])
GM2_CHECK_LIB([c],[pause],[PAUSE])
GM2_CHECK_LIB([c],[pipe],[PIPE])
GM2_CHECK_LIB([c],[rand],[RAND])
GM2_CHECK_LIB([c],[read],[READ])
GM2_CHECK_LIB([c],[select],[SELECT])
GM2_CHECK_LIB([c],[setitimer],[SETITIMER])
GM2_CHECK_LIB([c],[setgid],[SETGID])
GM2_CHECK_LIB([c],[setuid],[SETUID])
GM2_CHECK_LIB([c],[stat],[STAT])
GM2_CHECK_LIB([c],[strsignal],[STRSIGNAL])
GM2_CHECK_LIB([c],[strtod],[STRTOD])
GM2_CHECK_LIB([c],[strtold],[STRTOLD])
GM2_CHECK_LIB([c],[times],[TIMES])
GM2_CHECK_LIB([c],[unlink],[UNLINK])
GM2_CHECK_LIB([c],[wait],[WAIT])
GM2_CHECK_LIB([c],[write],[WRITE])

GM2_CHECK_LIB([m],[signbit],[SIGNBIT])
GM2_CHECK_LIB([m],[signbitf],[SIGNBITF])
GM2_CHECK_LIB([m],[signbitl],[SIGNBITL])

AC_MSG_NOTICE([libgm2 has finished checking target libc and libm contents.])

# We test the host here and later on check the target.

# All known M2_HOST_OS values.  This is the union of all host operating systems
# supported by gm2.

M2_SUPPORTED_HOST_OS="aix freebsd hurd linux netbsd openbsd solaris windows"

M2_HOST_OS=unknown

case ${host} in
  *-*-darwin*)   M2_HOST_OS=darwin ;;
  *-*-freebsd*)  M2_HOST_OS=freebsd ;;
  *-*-linux*)    M2_HOST_OS=linux ;;
  *-*-netbsd*)	 M2_HOST_OS=netbsd ;;
  *-*-openbsd*)  M2_HOST_OS=openbsd ;;
  *-*-solaris2*) M2_HOST_OS=solaris ;;
  *-*-aix*)      M2_HOST_OS=aix ;;
  *-*-gnu*)      M2_HOST_OS=hurd ;;
esac

# M2_HOST_OS=unknown
if test x${M2_HOST_OS} = xunknown; then
   AC_MSG_NOTICE([unsupported host, will build a minimal m2 library])
   BUILD_PIMLIB=false
   BUILD_ISOLIB=false
   BUILD_CORLIB=false
   BUILD_LOGLIB=false
else
   AC_MSG_NOTICE([m2 library will be built on ${M2_HOST_OS}])
   BUILD_PIMLIB=true
   BUILD_ISOLIB=true
   BUILD_CORLIB=true
   BUILD_LOGLIB=true
fi

CC_FOR_BUILD=${CC_FOR_BUILD:-gcc}
AC_SUBST(CC_FOR_BUILD)

# Now we check the target as long as it is a supported host.
# For some embedded targets we choose minimal runtime system which is
# just enough to satisfy the linker targetting raw metal.
if test x${M2_HOST_OS} != xunknown; then
AC_MSG_NOTICE([m2 library building for target ${target}])
case "$target" in

  avr25*-*-* | avr31*-*-* | avr35*-*-* | avr4*-*-* | avr5*-*-* | avr51*-*-* | avr6*-*-*)
  BUILD_PIMLIB=false
  BUILD_ISOLIB=false
  BUILD_CORLIB=false
  BUILD_LOGLIB=false
  ;;

  avrxmega2*-*-* | avrxmega4*-*-* | avrxmega5*-*-* | avrxmega6*-*-* | avrxmega7*-*-*)
  BUILD_PIMLIB=false
  BUILD_ISOLIB=false
  BUILD_CORLIB=false
  BUILD_LOGLIB=false
  ;;

  avr3-*-*)
  BUILD_PIMLIB=true
  BUILD_ISOLIB=true
  BUILD_CORLIB=true
  BUILD_LOGLIB=true
  ;;
  esp32-*-*)
  BUILD_PIMLIB=false
  BUILD_ISOLIB=false
  BUILD_CORLIB=false
  BUILD_LOGLIB=false
  ;;

esac
fi

# GM2_MSG_RESULT issue a query message from the first parameter and a boolean result
# in the second parameter is printed as a "yes" or "no".

AC_DEFUN([GM2_MSG_RESULT],[
   AC_MSG_CHECKING([$1])
   if test x${$2} = xtrue; then
      AC_MSG_RESULT([yes])
   else
      AC_MSG_RESULT([no])
   fi
])

if test x${M2_HOST_OS} = xunknown; then
   AC_MSG_NOTICE([m2 front end will only build minimal Modula-2 runtime library on this host])
else
   GM2_MSG_RESULT([m2 front end will build PIM libraries:],[BUILD_PIMLIB])
   GM2_MSG_RESULT([m2 front end will build ISO libraries:],[BUILD_ISOLIB])
   GM2_MSG_RESULT([m2 front end will build coroutine libraries:],[BUILD_CORLIB])
   GM2_MSG_RESULT([m2 front end will build Logitech compatability libraries:],[BUILD_LOGLIB])
fi

AM_CONDITIONAL([BUILD_PIMLIB], [test x$BUILD_PIMLIB = xtrue])
AM_CONDITIONAL([BUILD_ISOLIB], [test x$BUILD_ISOLIB = xtrue])
AM_CONDITIONAL([BUILD_CORLIB], [test x$BUILD_CORLIB = xtrue])
AM_CONDITIONAL([BUILD_LOGLIB], [test x$BUILD_LOGLIB = xtrue])

AC_CONFIG_SRCDIR([Makefile.am])
AC_CONFIG_FILES([Makefile libm2min/Makefile libm2pim/Makefile libm2iso/Makefile
                 libm2cor/Makefile libm2log/Makefile])

AC_MSG_NOTICE([libgm2 has been configured.])

AC_OUTPUT
-----------------------------
New file: ./autogen.sh
-----------------------------
#!/bin/sh

# autogen.sh regenerate the autoconf files.
#   Copyright 2013-2022  Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING3.  If not see
# <http://www.gnu.org/licenses/>.

rm -rf autom4te.cache

# libtoolize
rm -f aclocal.m4
# aclocal -I . -I config -I ../config
aclocal -I . -I ../config
autoreconf -I . -I ../config
automake --include-deps

rm -rf autom4te.cache

exit 0

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-05-18 19:11 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-18 19:11 [PATCH] Modula-2: merge proposal/review: 3/9 03.patch-set-03 v2 Gaius Mulley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).