public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/m2link] Static scaffold fixes, gm2l tidyup.
@ 2022-07-05 13:50 Gaius Mulley
  0 siblings, 0 replies; only message in thread
From: Gaius Mulley @ 2022-07-05 13:50 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:33abd43d4cac0e932f64e5dcce0c5ddf338bf625

commit 33abd43d4cac0e932f64e5dcce0c5ddf338bf625
Author: Gaius Mulley <gaius.mulley@southwales.ac.uk>
Date:   Tue Jul 5 14:15:16 2022 +0100

    Static scaffold fixes, gm2l tidyup.
    
    This patch fixes many static scaffold bugs and contains
    a re-implementation of UnixArgs.cc and termios.cc.  gm2l
    contains new options --exlude=, --include= and -flibs=.
    
    2022-07-04  Gaius Mulley  <gaius.mulley@southwales.ac.uk>
    
    gcc/ChangeLog:
    
            * doc/gm2.texi (-fscaffold-c): Removed.  (-fscaffold-c++)
            Removed.  (-fmodules) Removed.  (-fonlylink) Removed.
    
    gcc/m2/ChangLog:
    
            * Make-lang.in (UnixArgs.o): Use UnixArgs.cc.
            (gm2-pge-boot/Gtermsios.o) Use mc-boot-ch/Gtermios.cc.
            * bnf/gm2l.bnf: Partial re-write and introduced
            --include=, --exclude= and -flibs=.  (AddUserInclude)
            New procedure.  (ScanSources) Remove IncludeM2RTS
            filter.  (MakeModule) Return a boolean if a new module
            is seen.  (source) New field userInclude.
            (source) New field userExclude.  (DisplaySources)
            test for userExclude and userInclude and produce
            appropriate diagnostic.  (DisplayUsage) Remove
            --M2RTS.  Add -flibs=, --include-list= and --exclude-list=.
            (PopulateList) New procedure.  (addInclude) New procedure.
            (SetLibs) New procedure.  (SetExclude) New procedure.
            (ScanArgs) Remove IncludeM2RTS.  Remove --M2RTS.
            Add --include=, --exclude= and -flibs=.  Detect if multiple
            source files are given and detect any unrecognized option.
            * bnf/gm2m.bnf (main): Renamed as mainModule.
            * gm2-compiler/M2Options.mod (SetScaffoldDynamic): Ensure that
            ScaffoldStatic is not also set.  (SetScaffoldStatic) Ensure
            that ScaffoldDynamic is not also set.
            * gm2-compiler/M2Quads.mod (BuildM2FiniFunction):
            Add ForeachModuleCallFinish for the static clause.
            (BuildM2InitFunction) Add ForeachModuleCallInit for the
            static clause.
            * gm2-compiler/M2Scaffold.def (ForeachModuleCallInit):
            New procedure.  (ForeachModuleCallFinish) New Procedure.
            * gm2-compiler/M2Scaffold.mod (ForeachModuleCallInit):
            New procedure implemented.  (ForeachModuleCallFinish) New
            Procedure implemented.  (LookupModuleSym) New procedure.
            (ReadModules) Addition parameter tok and populate
            uselistModules.  (DeclareModuleExtern) Renamed from
            DeclareCtorModuleExtern.
            * gm2-compiler/M2Swig.mod (main): Renamed as mainModule.
            * gm2-compiler/SymbolTable.def (PutModuleCtorExtern): Exported
            and declared.  (MakeModuleCtor) Pass extra boolean public true.
            (InitCtorFields) pub new parameter.  (PutProcedureExternPublic)
            New procedure.  (PutCtorExtern) New procedure.
            (PutModuleCtorExtern) New procedure.
            * gm2-gcc/init.cc: Rewritten to pass envp to call init and fini
            functions.
            * gm2-gcc/m2expr.def: FOR "C" removed.
            * gm2-libs-ch/RTcodummy.c: Undo removal of _init and _finish
            functions.
            * gm2-libs-ch/pthdummy.c (Removed).
            * m2/gm2spec.cc (seen_scaffold_static): New boolean.
            (seen_scaffold_dynamic) New boolean.  (scaffold_static)
            New boolean.  (scaffold_dynamic) New boolean.
            (get_libexec) Removed.  (add_exec_dir) Rewritten comment.
            (lang_specific_driver) Check that dynamic scaffold and static
            scaffold are not both enabled.
            * mc-boot-ch/Gpth.c (Removed).
            * mc-boot-ch/Gtermios.c (Removed).
            * mc-boot-ch/Gtermios.cc (Added).  Converted from Gtermios.c.
    
    gm2tools/ChangeLog:
    
            * gm2l.1 (--M2RTS) Removed.  (-M2RTS) Removed.  (--include=) Added.
            (--exclude=) Added.  (-flibs=) Added.
    
    libgm2/ChangeLog:
    
            * libm2iso/ErrnoCategory.cc (_finish): Changed to _fini.
            * libm2iso/RTco.cc (_finish): Changed to _fini.
            * libm2pim/SysExceptions.cc (_finish): Changed to _fini.
            * libm2pim/errno.cc (_finish): Changed to _fini.
            * libm2pim/termios.cc (_finish): Changed to _fini.
    
    Signed-off-by: Gaius Mulley <gaius.mulley@southwales.ac.uk>

Diff:
---
 gcc/doc/gm2.texi                                  |   27 +-
 gcc/m2/Make-lang.in                               |    2 +-
 gcc/m2/bnf/gm2l.bnf                               |  242 ++-
 gcc/m2/bnf/gm2m.bnf                               |   23 +-
 gcc/m2/gm2-compiler/M2Batch.def                   |    9 +-
 gcc/m2/gm2-compiler/M2Options.mod                 |   12 +-
 gcc/m2/gm2-compiler/M2Quads.mod                   |   13 +-
 gcc/m2/gm2-compiler/M2Scaffold.def                |   18 +
 gcc/m2/gm2-compiler/M2Scaffold.mod                |  152 +-
 gcc/m2/gm2-compiler/M2Swig.mod                    |    6 +-
 gcc/m2/gm2-compiler/SymbolTable.def               |   12 +-
 gcc/m2/gm2-compiler/SymbolTable.mod               |  102 +-
 gcc/m2/gm2-gcc/init.cc                            |  293 +--
 gcc/m2/gm2-gcc/m2expr.def                         |    2 +-
 gcc/m2/gm2-libs-ch/RTcodummy.c                    |    2 -
 gcc/m2/gm2-libs-ch/pthdummy.c                     |   50 -
 gcc/m2/gm2spec.cc                                 |   62 +-
 gcc/m2/mc-boot-ch/Gpth.c                          |   53 -
 gcc/m2/mc-boot-ch/Gtermios.c                      | 1955 ---------------------
 gcc/testsuite/gm2/link/pimc/pass/testunixargs.mod |    4 +-
 gm2tools/gm2l.1                                   |   61 +-
 libgm2/libm2iso/ErrnoCategory.cc                  |    4 +-
 libgm2/libm2iso/RTco.cc                           |    4 +-
 libgm2/libm2pim/SysExceptions.cc                  |    4 +-
 libgm2/libm2pim/errno.cc                          |    4 +-
 libgm2/libm2pim/termios.cc                        |    4 +-
 26 files changed, 729 insertions(+), 2391 deletions(-)

diff --git a/gcc/doc/gm2.texi b/gcc/doc/gm2.texi
index 91e2bf0259b..84791e9ba4a 100644
--- a/gcc/doc/gm2.texi
+++ b/gcc/doc/gm2.texi
@@ -538,8 +538,8 @@ You can compile and link it by: @samp{gm2 -g hello.mod}.
 The result will be an @samp{a.out} file created in your directory.
 
 You can split this command into two steps if you prefer.  The compile
-step can be achieved by: @samp{gm2 -g -c hello.mod} and the link via:
-@samp{gm2 -g -fonlylink hello.mod}.
+step can be achieved by: @samp{gm2 -g -c -fscaffold-main hello.mod}
+and the link via: @samp{gm2 -g hello.o}.
 
 @footnote{To see all the compile actions taken by @samp{gm2} users can also
 add the @samp{-v} flag at the command line, for example:
@@ -606,11 +606,11 @@ generate a shared library from the module.
 @item -fruntime-modules=
 specify, using a comma separated list, the runtime modules and their
 order.  These modules will initialized first before any other modules
-in the application dependancy.  By default the runtime modules list is
+in the application dependency.  By default the runtime modules list is
 set to @code{Storage,SYSTEM,M2RTS,RTExceptions,IOLink}.  Note that
 these modules will only be linked into your executable if they are
 required.  So adding a long list of dependant modules will not effect
-the size of the executable it merely states the initialisation order
+the size of the executable it merely states the initialization order
 should they be required.
 
 @item -fnil
@@ -737,16 +737,6 @@ infastructure when compiling implementation and program modules.
 By default this option is on.  Use @samp{-fno-scaffold-dynamic}
 to turn it off or select @samp{-fno-scaffold-dynamic}.
 
-@item -fscaffold-c
-this option generates a C source scaffold file for the program module.
-This file can be compiled and linked with the module objects to
-produce the application.
-
-@item -fscaffold-c++
-this option generates a C++ source scaffold file for the program module.
-This file can be compiled and linked with the module objects to
-produce the application.
-
 @item -fcpp
 preprocess the source with @samp{cpp -lang-asm -traditional-cpp}
 For further details about these options @xref{Invocation, , ,cpp}.
@@ -814,11 +804,6 @@ displays the path to the source of each module.  This option
 can be used at compile time to check the correct definition module
 is being used.
 
-@item -fmodules
-displays the path to each modules object file.  This option
-can only be invoked with the @code{-c} option.
-It is used to see the location of objects when linking occurs.
-
 @item -fdef=
 recognise the specified suffix as a definition module filename.
 The default implmentation and module filename suffix is @file{.def}.
@@ -835,10 +820,6 @@ suffixed filename does not exist.
 @item -fxcode
 issues all errors and warnings in the @file{Xcode} format.
 
-@item -fonlylink
-only link the modula-2 application, do not compile the program module
-beforehand.
-
 @item -funbounded-by-reference
 enable optimization of unbounded parameters by attempting to pass non
 @code{VAR} unbounded parameters by reference.  This optimization
diff --git a/gcc/m2/Make-lang.in b/gcc/m2/Make-lang.in
index ed572e3102c..a882076da3a 100644
--- a/gcc/m2/Make-lang.in
+++ b/gcc/m2/Make-lang.in
@@ -2092,7 +2092,7 @@ m2/gm2-pge-boot/$(SRC_PREFIX)UnixArgs.o:  $(srcdir)/m2/mc-boot-ch/GUnixArgs.cc
 m2/gm2-pge-boot/$(SRC_PREFIX)Selective.o:  $(srcdir)/m2/mc-boot-ch/GSelective.c m2/gm2-libs/gm2-libs-host.h
 	$(CXX) -I. -I$(srcdir)/../include -I$(srcdir) -I$(srcdir)/m2/mc-boot-ch $(INCLUDES) -Im2/gm2-libs -g -c $< -o $@
 
-m2/gm2-pge-boot/$(SRC_PREFIX)termios.o:  $(srcdir)/m2/mc-boot-ch/Gtermios.c m2/gm2-libs/gm2-libs-host.h
+m2/gm2-pge-boot/$(SRC_PREFIX)termios.o:  $(srcdir)/m2/mc-boot-ch/Gtermios.cc m2/gm2-libs/gm2-libs-host.h
 	$(CXX) -I. -I$(srcdir)/../include -I$(srcdir) -I$(srcdir)/m2/mc-boot-ch -Im2/gm2-libs $(INCLUDES) -g -c $< -o $@
 
 m2/gm2-pge-boot/$(SRC_PREFIX)SysExceptions.o:  $(srcdir)/m2/mc-boot-ch/GSysExceptions.c m2/gm2-libs/gm2-libs-host.h
diff --git a/gcc/m2/bnf/gm2l.bnf b/gcc/m2/bnf/gm2l.bnf
index 633a85c3cd9..0af2062bacf 100644
--- a/gcc/m2/bnf/gm2l.bnf
+++ b/gcc/m2/bnf/gm2l.bnf
@@ -24,7 +24,6 @@
    are the top two lines in the file.
 
 Copyright (C) 2001-2022 Free Software Foundation, Inc.
-Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
 
 This file is part of GNU Modula-2.
 
@@ -44,22 +43,6 @@ see <https://www.gnu.org/licenses/>.  *)
 
 MODULE gm2l ;
 
-(*
-   Author     : Gaius Mulley
-   Title      : gm2l
-   Date       : Date: Sat 16-09-1989 Time: 17:49:34.18
-              : [$Date: 2013/07/20 12:33:01 $]
-   SYSTEM     : UNIX (GNU Modula-2)
-   Description: generates the list of initialization order for the modules.
-                The initialization module list is used for two purposes.
-                (i)  for linking all the objects or archives
-                (ii) for creating the initialization call sequence for each module.
-                If a definition module contains EXPORT UNQUALIFIED and there is no
-                implementation module found then we assume this definition module
-                will match a foreign language, therefore we do not create an
-                initialization call but we do link this object/archive.
-                This allows us to write definition modules for C libraries.
-*)
 
 IMPORT Break ;
 IMPORT M2Search ;
@@ -87,10 +70,12 @@ IMPORT m2flex ;
 FROM SYSTEM IMPORT ADDRESS ;
 FROM M2DriverOptions IMPORT ScanCppArgs ;
 FROM DynamicStrings IMPORT String, InitString, KillString, Slice, InitStringCharStar,
-                           Mark, EqualArray, string, ConCat, ConCatChar, Dup ;
+                           Mark, EqualArray, string, ConCat, ConCatChar, Dup, Length,
+                           char ;
 FROM Lists IMPORT List, InitList, KillList, IncludeItemIntoList, GetItemFromList,
                   RemoveItemFromList, NoOfItemsInList, IsItemInList ;
 FROM M2Options IMPORT SetVerbose, Verbose ;
+(* FROM GccInstall IMPORT GetInstalledIncludeDir, GetDirSeparator ; *)
 
 
 CONST
@@ -103,6 +88,8 @@ TYPE
                           name       : Name ;
                           fullpath   : String ;
                           Depth      : CARDINAL ;
+                          userExclude,
+                          userInclude,
                           OnlyDef    ,
                           ForC       : BOOLEAN ;
                           next       : Source ;
@@ -121,10 +108,11 @@ VAR
    MainSrc,
    MainName       : Name ;
    Head, Tail     : Source ;    (* Head source list *)
-   IncludeM2RTS   : BOOLEAN ;   (* Do we automatically include M2RTS into the top module? *)
    pSource        : Source ;    (* Current module being parsed *)
    CommentChar    : CHAR ;
    pBlock         : BlockInfoPtr ;
+   includeModules,
+   excludeModules : List ;
 
 
 (*
@@ -187,7 +175,9 @@ BEGIN
       n := NoOfItemsInList (ImportedModules) ;
       WHILE i<=n DO
          modname := GetItemFromList (ImportedModules, i) ;
-         MakeModule (modname) ;
+         IF MakeModule (modname)
+         THEN
+         END ;
          MakeDependant (pSource^.name, modname) ;
          INC (i)
       END ;
@@ -229,6 +219,31 @@ BEGIN
 END RegisterImport ;
 
 
+(*
+   AddUserInclude - if any module in includeModules does not exist in the graph
+                    add it as a dependant to the mainName.
+*)
+
+PROCEDURE AddUserInclude (mainName: Name) ;
+VAR
+   i, n: CARDINAL ;
+   name: Name ;
+BEGIN
+   i := 1 ;
+   n := NoOfItemsInList (includeModules) ;
+   WHILE i <= n DO
+      name := GetItemFromList (includeModules, i) ;
+      IF MakeModule (name)
+      THEN
+         Tail^.userInclude := TRUE ;
+         (* Not seen this module therefore add it as a dependant to the mainName.  *)
+         MakeDependant (mainName, name)
+      END ;
+      INC (i)
+   END
+END AddUserInclude ;
+
+
 (*
    ScanSources - scans all the source files for IMPORTs and places all
                  imports into the Sources array.
@@ -250,14 +265,8 @@ BEGIN
       ExamineCompilationUnit (MainName, isdefimp) ;
       CloseSource ;
       ReInitialize ;
-      MakeModule (MainName) ;  (* Head now contains a reference to MainName.  *)
-      IF IncludeM2RTS
+      IF MakeModule (MainName)  (* Head now contains a reference to MainName.  *)
       THEN
-         (*
-            we should include M2RTS as a dependant module otherwise it simply wont link
-         *)
-         MakeModule (MakeKey ('M2RTS')) ;  (* Tail now contains a reference to M2RTS.  *)
-         MakeDependant (MainName, MakeKey ('M2RTS'))
       END ;
       pSource := Head ;
       WHILE pSource # NIL DO
@@ -597,10 +606,11 @@ END Real ;
 
 % module gm2l end
 (*
-   MakeModule - makes a module for ModuleName.
+   MakeModule - makes a module for ModuleName.  It returns TRUE if a new
+                module entry is created.
 *)
 
-PROCEDURE MakeModule (ModuleName: Name) ;
+PROCEDURE MakeModule (ModuleName: Name) : BOOLEAN ;
 VAR
    s: Source ;
 BEGIN
@@ -609,7 +619,7 @@ BEGIN
       WITH s^ DO
          IF name = ModuleName
          THEN
-            RETURN
+            RETURN FALSE
          ELSE
             s := s^.next
          END
@@ -630,8 +640,11 @@ BEGIN
       Depth       := 0 ;
       ForC        := FALSE ;
       OnlyDef     := FALSE ;
+      userExclude := FALSE ;
+      userInclude := FALSE ;
       next        := NIL
-   END
+   END ;
+   RETURN TRUE
 END MakeModule ;
 
 
@@ -761,7 +774,14 @@ BEGIN
    WHILE p # NIL DO
       WITH p^ DO
          fprintf3 (fo, '%c %a %4d ', CommentChar, name, Depth) ;
-         IF p^.fullpath = NIL
+         IF IsItemInList (excludeModules, name)
+         THEN
+            fprintf0 (fo, 'excluded via command line\n') ;
+            userExclude := TRUE
+         ELSIF p^.userInclude
+         THEN
+            fprintf0 (fo, 'included via command line\n')
+         ELSIF p^.fullpath = NIL
          THEN
             fprintf1 (fo, 'no source file found for module %a\n', p^.name) ;
             fprintf1 (StdErr, 'no source file found for module %a\n', p^.name) ;
@@ -778,17 +798,15 @@ BEGIN
       END ;
       p := p^.next
    END ;
-   fprintf3 (fo, '%c\n%c Initialization order\n%c\n', CommentChar, CommentChar, CommentChar) ;
+   fprintf3 (fo, '%c\n%c Initialization order\n%c\n',
+             CommentChar, CommentChar, CommentChar) ;
    p := Head ;
    WHILE p # NIL DO
       WITH p^ DO
-         (*
-            do not automatically link ForC modules,
-	    the user must specify them either as -lmodule or module.o
-         *)
-         IF (NOT ForC) OR (name = MakeKey ('SYSTEM'))
+         (* Do not automatically include ForC modules.  *)
+         IF (NOT ForC) AND (NOT userExclude)
          THEN
-            fprintf1(fo, '%a\n', name)
+            fprintf1 (fo, '%a\n', name)
          END
       END ;
       p := p^.next
@@ -818,13 +836,126 @@ END OpenOutputFile ;
 
 PROCEDURE DisplayUsage ;
 BEGIN
-   printf0 ('Usage: gm2l [-fdef=extension][-fmod=extension][-h][--help]\n');
-   printf0 ('            [-Isearchpath][--M2RTS][-M2RTS][-v][--verbose]\n');
+   printf0 ('Usage: gm2l [-fdef=extension][-flibs=list][-fmod=extension][-h][--help]\n');
+   printf0 ('            [-Isearchpath][--exclude=list][--include=list][-v][--verbose]\n');
    printf0 ('            [-o outputfile] modulefile\n');
    exit (0)
 END DisplayUsage ;
 
 
+(*
+   PopulateList - creates a list of namekey entries from a comma separated string s.
+*)
+
+PROCEDURE PopulateList (VAR list: List; s: String) ;
+VAR
+   word : String ;
+   start,
+   i, n : INTEGER ;
+BEGIN
+   n := Length (s) ;
+   i := 0 ;
+   start := 0 ;
+   WHILE i < n DO
+      IF char (s, i) = ','
+      THEN
+         IF i > start
+         THEN
+            word := Slice (s, start, i) ;
+            IncludeItemIntoList (list, makekey (string (word))) ;
+            word := KillString (word) ;
+            start := i + 1
+         END
+      END ;
+      INC (i)
+   END ;
+   IF i > start
+   THEN
+      word := Slice (s, start, 0) ;
+      IncludeItemIntoList (list, makekey (string (word))) ;
+      word := KillString (word)
+   END
+END PopulateList ;
+
+
+(*
+   addInclude - adds include path for
+*)
+
+PROCEDURE addInclude (name: Name) ;
+VAR
+   s: String ;
+BEGIN
+(*
+   s := ConCat (InitStringCharStar (GetInstalledIncludeDir ()),
+                InitStringCharStar (GetDirSeparator ())) ;
+   s := ConCat (s, Mark (InitStringCharStar (KeyToCharStar (name)))) ;
+   PrependSearchPath (s)
+*)
+END addInclude ;
+
+
+(*
+   SetLibs - configures the include paths from the libraries shortcuts.
+*)
+
+PROCEDURE SetLibs (s: String) ;
+VAR
+   libs: List ;
+   n, i: CARDINAL ;
+   name: Name ;
+BEGIN
+   InitList (libs) ;
+   PopulateList (libs, s) ;
+   n := NoOfItemsInList (libs) ;
+   i := 1 ;
+   WHILE i <= n DO
+      name := GetItemFromList (libs, i) ;
+      IF name = MakeKey ('pim')
+      THEN
+         addInclude (MakeKey ('m2pim'))
+      ELSIF name = MakeKey ('min')
+      THEN
+         addInclude (MakeKey ('m2min'))
+      ELSIF name = MakeKey ('iso')
+      THEN
+         addInclude (MakeKey ('m2iso'))
+      ELSIF name = MakeKey ('log')
+      THEN
+         addInclude (MakeKey ('m2log'))
+      ELSIF name = MakeKey ('cor')
+      THEN
+         addInclude (MakeKey ('m2cor'))
+      ELSE
+         (* Third party library.  *)
+         addInclude (name)
+      END ;
+      INC (i)
+   END ;
+   KillList (libs)
+END SetLibs ;
+
+
+(*
+   SetExclude - populates the excludeModules with the list specified in s.
+*)
+
+PROCEDURE SetExclude (s: String) ;
+BEGIN
+   PopulateList (excludeModules, s)
+END SetExclude ;
+
+
+(*
+   SetInclude - populates the includeModules with the list specified in s.
+*)
+
+PROCEDURE SetInclude (s: String) ;
+BEGIN
+   PopulateList (includeModules, s)
+END SetInclude ;
+
+
 (*
    ScanArgs - scans the argument list and returns TRUE if the main source
               module is found.
@@ -835,7 +966,6 @@ VAR
    i, n: CARDINAL ;
    s   : String ;
 BEGIN
-   IncludeM2RTS := TRUE ;
    MainName := NulName ;
    n := SArgs.Narg () ;
    IF n=1
@@ -867,13 +997,18 @@ BEGIN
             ELSIF EqualArray(Mark (Slice (s, 0, 6)), '-fmod=')
             THEN
                SetModExtension (Slice (s, 6, 0))
+            ELSIF EqualArray(Mark (Slice (s, 0, 6)), '-flibs=')
+            THEN
+               SetLibs (Slice (s, 7, 0))
             ELSIF EqualArray (s, '-fcpp-begin')
             THEN
                i := ScanCppArgs (i)
-            ELSIF EqualArray (s, '--M2RTS') OR EqualArray (s, '-M2RTS')
+            ELSIF EqualArray(Mark (Slice (s, 0, 10)), '--exclude=')
             THEN
-               (* no M2RTS to be automatically linked imported from the main module *)
-               IncludeM2RTS := FALSE
+               SetExclude (Slice (s, 10, 0))
+            ELSIF EqualArray(Mark (Slice (s, 0, 10)), '--include=')
+            THEN
+               SetInclude (Slice (s, 10, 0))
             ELSIF EqualArray (s, '-h') OR EqualArray (s, '--help')
 	    THEN
 	       DisplayUsage
@@ -884,8 +1019,20 @@ BEGIN
                THEN
                   OpenOutputFile (s)
                END
+            ELSIF MainSrc = NulName
+            THEN
+               IF (Length (s) > 0) AND (char (s, 0) = '-')
+               THEN
+                  fprintf1 (StdErr, 'unknown option: %s\n', s) ;
+                  exit (1)
+               ELSE
+                  MainSrc := makekey (string (s))
+               END
             ELSE
-               MainSrc := makekey (string (s))
+               fprintf2 (StdErr,
+                         'only one application module can be specified, application module was set to %a it is now being set to %s\n',
+                         MainSrc, s) ;
+               exit (1)
             END
          END ;
          INC (i)
@@ -897,9 +1044,12 @@ END ScanArgs ;
 
 BEGIN
    fo := StdOut ;
+   InitList (includeModules) ;
+   InitList (excludeModules) ;
    IF ScanArgs ()
    THEN
       ScanSources (MainSrc) ;
+      AddUserInclude (MainSrc) ;
       CalculateDepth ;
       SortSources ;
       DisplaySources
diff --git a/gcc/m2/bnf/gm2m.bnf b/gcc/m2/bnf/gm2m.bnf
index 65c61c051c9..36e163970d0 100644
--- a/gcc/m2/bnf/gm2m.bnf
+++ b/gcc/m2/bnf/gm2m.bnf
@@ -118,7 +118,7 @@ TYPE
 
 VAR
    Verbose        : BOOLEAN ;
-   main           : PtrToNode ;
+   mainModule     : PtrToNode ;
    DefExistsTree  : SymbolTree ; (* Table of definition modules found or not   *)
    ModExistsTree  : SymbolTree ; (* Table of imp/program modules found or not  *)
    Files          : PtrToSource ;
@@ -390,7 +390,8 @@ BEGIN
          using a tree strategy. We must ensure that the objects are
          also included.
       *)
-      MakeObject(son^.Source^.ModName, main, 1) ;   (* attach the object to the executable.  *)
+      MakeObject(son^.Source^.ModName, mainModule, 1) ;
+      (* attach the object to the executable.  *)
 
       name := KillString(name) ;
       IF Debugging
@@ -1882,20 +1883,20 @@ BEGIN
                CloseSource ;
                ReInitialize ;
 
-               main := NewNode() ;
-               main^.Father := NIL ;
-               main^.Source := NewSource() ;
-               Files := main^.Source ;
-               WITH main^.Source^ DO
-                  SourceNode := main ;
+               mainModule := NewNode() ;
+               mainModule^.Father := NIL ;
+               mainModule^.Source := NewSource() ;
+               Files := mainModule^.Source ;
+               WITH mainModule^.Source^ DO
+                  SourceNode := mainModule ;
                   ModName := MainName ;
 
-                  main^.Source^.Ext := ExeExtn ;
+                  Ext := ExeExtn ;
                   (* .exe is never written out, it is just a unique extension
                      representing not matching .o .mod or .def *)
                   e := CalculateFileName(s, Mark(InitString('exe'))) ;
-                  MakeExe(ModName, main, 0) ;
-                  UnixMake(main) ;
+                  MakeExe(ModName, mainModule, 0) ;
+                  UnixMake(mainModule) ;
                   IF EnableRuntimeDebugging
                   THEN
                      DisplaySource
diff --git a/gcc/m2/gm2-compiler/M2Batch.def b/gcc/m2/gm2-compiler/M2Batch.def
index 1b0e63848d5..be11532ad54 100644
--- a/gcc/m2/gm2-compiler/M2Batch.def
+++ b/gcc/m2/gm2-compiler/M2Batch.def
@@ -37,7 +37,7 @@ EXPORT QUALIFIED MakeDefinitionSource,
                  MakeProgramSource,
                  GetSource, GetModuleNo, IsModuleKnown,
                  AssociateDefinition, GetDefinitionModuleFile,
-                 AssociateModule, GetModuleFile,
+                 AssociateModule, GetModuleFile, Get,
                  ForeachSourceModuleDo, IsSourceSeen, IsModuleSeen,
                  LookupModule, LookupOuterModule, DisplayModules ;
 
@@ -177,6 +177,13 @@ PROCEDURE LookupModule (tok: CARDINAL; n: Name) : CARDINAL ;
 PROCEDURE LookupOuterModule (tok: CARDINAL; n: Name) : CARDINAL ;
 
 
+(*
+   Get - returns the module symbol matching name, n.
+*)
+
+PROCEDURE Get (n: Name) : CARDINAL ;
+
+
 (*
    DisplayModules - a debugging routine to textually emit the names of modules in the DoneQ.
 *)
diff --git a/gcc/m2/gm2-compiler/M2Options.mod b/gcc/m2/gm2-compiler/M2Options.mod
index 450c08a25ed..aef709bb3d2 100644
--- a/gcc/m2/gm2-compiler/M2Options.mod
+++ b/gcc/m2/gm2-compiler/M2Options.mod
@@ -1064,7 +1064,11 @@ END SetSaveTempsDir ;
 
 PROCEDURE SetScaffoldDynamic (value: BOOLEAN) ;
 BEGIN
-   ScaffoldDynamic := value
+   ScaffoldDynamic := value ;
+   IF ScaffoldDynamic
+   THEN
+      ScaffoldStatic := FALSE
+   END
 END SetScaffoldDynamic ;
 
 
@@ -1074,7 +1078,11 @@ END SetScaffoldDynamic ;
 
 PROCEDURE SetScaffoldStatic (value: BOOLEAN) ;
 BEGIN
-   ScaffoldStatic := value
+   ScaffoldStatic := value ;
+   IF ScaffoldStatic
+   THEN
+      ScaffoldDynamic := FALSE
+   END
 END SetScaffoldStatic ;
 
 
diff --git a/gcc/m2/gm2-compiler/M2Quads.mod b/gcc/m2/gm2-compiler/M2Quads.mod
index c3263657b19..ef95851ab43 100644
--- a/gcc/m2/gm2-compiler/M2Quads.mod
+++ b/gcc/m2/gm2-compiler/M2Quads.mod
@@ -28,7 +28,8 @@ FROM NameKey IMPORT Name, NulName, MakeKey, GetKey, makekey, KeyToCharStar, Writ
 FROM FormatStrings IMPORT Sprintf0, Sprintf1, Sprintf2, Sprintf3 ;
 FROM M2DebugStack IMPORT DebugStack ;
 FROM M2Scaffold IMPORT DeclareScaffold, mainFunction, initFunction,
-                       finiFunction, linkFunction, PopulateCtorArray ;
+                       finiFunction, linkFunction, PopulateCtorArray,
+                       ForeachModuleCallInit, ForeachModuleCallFinish ;
 
 FROM M2MetaError IMPORT MetaError0, MetaError1, MetaError2, MetaError3,
                         MetaErrors1, MetaErrors2, MetaErrors3,
@@ -2479,7 +2480,10 @@ BEGIN
          END
       ELSIF ScaffoldStatic
       THEN
-
+         ForeachModuleCallInit (tok,
+                                RequestSym (tok, MakeKey ("argc")),
+                                RequestSym (tok, MakeKey ("argv")),
+                                RequestSym (tok, MakeKey ("envp")))
       END ;
       EndScope ;
       BuildProcedureEnd ;
@@ -2531,7 +2535,10 @@ BEGIN
          END
       ELSIF ScaffoldStatic
       THEN
-
+         ForeachModuleCallFinish (tok,
+                                  RequestSym (tok, MakeKey ("argc")),
+                                  RequestSym (tok, MakeKey ("argv")),
+                                  RequestSym (tok, MakeKey ("envp")))
       END ;
       EndScope ;
       BuildProcedureEnd ;
diff --git a/gcc/m2/gm2-compiler/M2Scaffold.def b/gcc/m2/gm2-compiler/M2Scaffold.def
index adf7effed48..f99efbc1656 100644
--- a/gcc/m2/gm2-compiler/M2Scaffold.def
+++ b/gcc/m2/gm2-compiler/M2Scaffold.def
@@ -52,4 +52,22 @@ PROCEDURE DeclareArgEnvParams (tokno: CARDINAL; proc: CARDINAL) ;
 PROCEDURE PopulateCtorArray (tok: CARDINAL) ;
 
 
+(*
+   ForeachModuleCallInit - precondition: the module list will be ordered.
+                           postcondition: foreach module in the application universe
+                                             call _M2_module_init (argc, argv, envp);
+*)
+
+PROCEDURE ForeachModuleCallInit (tok: CARDINAL; argc, argv, envp: CARDINAL) ;
+
+
+(*
+   ForeachModuleCallFinish - precondition: the module list will be ordered.
+                             postcondition: foreach module in the application universe
+                                               call _M2_module_finish (argc, argv, envp);
+*)
+
+PROCEDURE ForeachModuleCallFinish (tok: CARDINAL; argc, argv, envp: CARDINAL) ;
+
+
 END M2Scaffold.
diff --git a/gcc/m2/gm2-compiler/M2Scaffold.mod b/gcc/m2/gm2-compiler/M2Scaffold.mod
index e7c5fdee19f..47ada7b5a98 100644
--- a/gcc/m2/gm2-compiler/M2Scaffold.mod
+++ b/gcc/m2/gm2-compiler/M2Scaffold.mod
@@ -27,7 +27,8 @@ FROM SymbolTable IMPORT NulSym, MakeProcedure, PutFunction,
                         MakeSubrange, PutSubrange,
                         MakeSubscript, PutSubscript, PutArraySubscript,
                         MakeVar, PutVar, MakeProcedureCtorExtern,
-                        GetMainModule,
+                        GetMainModule, GetModuleCtors, MakeDefImp,
+                        PutModuleCtorExtern,
                         GetSymName, StartScope, EndScope ;
 
 FROM NameKey IMPORT NulName, Name, MakeKey, makekey, KeyToCharStar ;
@@ -40,9 +41,13 @@ FROM M2MetaError IMPORT MetaErrorT0 ;
 
 FROM SFIO IMPORT OpenToWrite, WriteS, ReadS, OpenToRead, Exists ;
 FROM FIO IMPORT File, EOF, IsNoError, Close ;
-FROM M2Options IMPORT GetUselist ;
+FROM M2Options IMPORT GetUselist, ScaffoldStatic ;
 FROM M2Base IMPORT Proc ;
-FROM M2Quads IMPORT PushTFtok, PushTtok, BuildDesignatorArray, BuildAssignment ;
+
+FROM M2Quads IMPORT PushTFtok, PushTtok, PushT, BuildDesignatorArray, BuildAssignment,
+                    BuildProcedureCall ;
+
+FROM M2Batch IMPORT IsModuleKnown, Get ;
 
 FROM DynamicStrings IMPORT String, InitString, KillString, ConCat, RemoveWhitePrefix,
                     EqualArray, Mark, Assign, Fin, InitStringChar, Length, Slice, Equal,
@@ -52,10 +57,11 @@ CONST
    Comment = '#'  ; (* Comment leader      *)
 
 VAR
+   uselistModules,
    ctorModules,
-   ctorGlobals  : List ;
+   ctorGlobals   : List ;
    ctorArray,
-   ctorArrayType: CARDINAL ;
+   ctorArrayType : CARDINAL ;
 
 
 (* The dynamic scaffold takes the form:
@@ -122,6 +128,76 @@ BEGIN
 END DeclareCtorGlobal ;
 
 
+(*
+   ForeachModuleCallInit - is only called when -fscaffold-static is enabled.
+                           precondition: the module list will be ordered.
+                           postcondition: foreach module in the application universe
+                                             call _M2_module_init (argc, argv, envp);
+*)
+
+PROCEDURE ForeachModuleCallInit (tok: CARDINAL; argc, argv, envp: CARDINAL) ;
+VAR
+   module    : CARDINAL ;
+   i, n      : CARDINAL ;
+   ctor, init,
+   fini, dep : CARDINAL ;
+BEGIN
+   i := 1 ;
+   n := NoOfItemsInList (uselistModules) ;
+   WHILE i <= n DO
+      module := GetItemFromList (uselistModules, i) ;
+      IF module # NulSym
+      THEN
+         GetModuleCtors (module, ctor, init, fini, dep) ;
+         IF init # NulSym
+         THEN
+            PushTtok (init, tok) ;
+            PushTtok (argc, tok) ;
+            PushTtok (argv, tok) ;
+            PushTtok (envp, tok) ;
+            PushT (3) ;
+            BuildProcedureCall (tok)
+         END
+      END ;
+      INC (i)
+   END
+END ForeachModuleCallInit ;
+
+
+(*
+   ForeachModuleCallFinish - precondition: the module list will be ordered.
+                             postcondition: foreach module in the application universe
+                                               call _M2_module_finish (argc, argv, envp);
+*)
+
+PROCEDURE ForeachModuleCallFinish (tok: CARDINAL; argc, argv, envp: CARDINAL) ;
+VAR
+   module    : CARDINAL ;
+   i         : CARDINAL ;
+   ctor, init,
+   fini, dep : CARDINAL ;
+BEGIN
+   i := NoOfItemsInList (uselistModules) ;
+   WHILE i >= 1 DO
+      module := GetItemFromList (uselistModules, i) ;
+      IF module # NulSym
+      THEN
+         GetModuleCtors (module, ctor, init, fini, dep) ;
+         IF fini # NulSym
+         THEN
+            PushTtok (fini, tok) ;
+            PushTtok (argc, tok) ;
+            PushTtok (argv, tok) ;
+            PushTtok (envp, tok) ;
+            PushT (3) ;
+            BuildProcedureCall (tok)
+         END
+      END ;
+      DEC (i)
+   END
+END ForeachModuleCallFinish ;
+
+
 (*
    PopulateCtorArray - assign each element of the ctorArray to the external module ctor.
                        This is only used to force the linker to pull in the ctors from
@@ -145,16 +221,40 @@ BEGIN
 END PopulateCtorArray ;
 
 
+(*
+   LookupModuleSym - returns a defimp module.  It looks up an existing
+                     module and if this does not exist creates a new one.
+*)
+
+PROCEDURE LookupModuleSym (tok: CARDINAL; name: Name) : CARDINAL ;
+VAR
+   sym: CARDINAL ;
+BEGIN
+   sym := Get (name) ;
+   IF sym = NulSym
+   THEN
+      sym := MakeDefImp (tok, name)
+   END ;
+   IF sym # GetMainModule ()
+   THEN
+      PutModuleCtorExtern (tok, sym)
+   END ;
+   RETURN sym
+END LookupModuleSym ;
+
+
 (*
    ReadModules - populate ctorGlobals with the modules specified by -fuselist=filename.
 *)
 
-PROCEDURE ReadModules (filename: String) ;
+PROCEDURE ReadModules (tok: CARDINAL; filename: String) ;
 VAR
-   f: File ;
-   s: String ;
+   f   : File ;
+   s   : String ;
+   name: Name ;
 BEGIN
    InitList (ctorGlobals) ;
+   InitList (uselistModules) ;
    f := OpenToRead (filename) ;
    WHILE NOT EOF (f) DO
       s := ReadS (f) ;
@@ -163,7 +263,9 @@ BEGIN
                      Mark (Slice (s, 0, Length (Mark (InitStringChar (Comment)))-1)))) AND
          (NOT EqualArray (s, ''))
       THEN
-         IncludeItemIntoList (ctorGlobals, makekey (string (s)))
+         name := makekey (string (s)) ;
+         IncludeItemIntoList (ctorGlobals, name) ;
+         IncludeItemIntoList (uselistModules, LookupModuleSym (tok, name))
       END ;
       s := KillString (s)
    END ;
@@ -186,7 +288,7 @@ BEGIN
    ELSE
       IF Exists (filename)
       THEN
-         ReadModules (filename)
+         ReadModules (tok, filename)
       ELSE
          MetaErrorT0 (tok,
                       '{%E}the filename specified by the -fuselist= option does not exist') ;
@@ -198,26 +300,33 @@ END CreateCtorList ;
 
 
 (*
-   DeclareCtorModuleExtern - declare an extern _M2_modulename_ctor procedure for each module.
+   DeclareModuleExtern - declare the extern _M2_modulename_ctor, _M2_modulename_init,
+                         _M2_modulename_fini, _M2_modulename_dep for each external module.
 *)
 
-PROCEDURE DeclareCtorModuleExtern (tokenno: CARDINAL) ;
+PROCEDURE DeclareModuleExtern (tokenno: CARDINAL) ;
 VAR
-   name: Name ;
-   n, i: CARDINAL ;
+   init,
+   fini,
+   dep,
+   ctor,
+   module: CARDINAL ;
+   n, i : CARDINAL ;
 BEGIN
    InitList (ctorModules) ;
    i := 1 ;
-   n := NoOfItemsInList (ctorGlobals) ;
+   n := NoOfItemsInList (uselistModules) ;
    WHILE i <= n DO
-      name := GetItemFromList (ctorGlobals, i) ;
-      IF name # GetSymName (GetMainModule ())
+      module := GetItemFromList (uselistModules, i) ;
+      IF module # GetMainModule ()
       THEN
-         IncludeItemIntoList (ctorModules, MakeProcedureCtorExtern (tokenno, name))
+         PutModuleCtorExtern (tokenno, module)
       END ;
+      GetModuleCtors (module, ctor, init, fini, dep) ;
+      IncludeItemIntoList (ctorModules, ctor) ;
       INC (i)
    END
-END DeclareCtorModuleExtern ;
+END DeclareModuleExtern ;
 
 
 (*
@@ -231,7 +340,7 @@ BEGIN
    IF CreateCtorList (tokenno)
    THEN
       DeclareCtorGlobal (tokenno) ;
-      DeclareCtorModuleExtern (tokenno) ;
+      DeclareModuleExtern (tokenno) ;
       linkFunction := MakeProcedure (tokenno, MakeKey ("_M2_link"))
    END ;
 
@@ -281,5 +390,6 @@ BEGIN
    mainFunction := NulSym ;
    linkFunction := NulSym ;
    ctorGlobals := NIL ;
-   ctorModules := NIL
+   ctorModules := NIL ;
+   uselistModules := NIL
 END M2Scaffold.
diff --git a/gcc/m2/gm2-compiler/M2Swig.mod b/gcc/m2/gm2-compiler/M2Swig.mod
index 8083376df80..15b36c427f0 100644
--- a/gcc/m2/gm2-compiler/M2Swig.mod
+++ b/gcc/m2/gm2-compiler/M2Swig.mod
@@ -69,7 +69,7 @@ TYPE
 VAR
    includedArray: BOOLEAN ;
    uKey         : Index ;
-   main         : CARDINAL ;
+   mainModule   : CARDINAL ;
    Done,
    ToDo         : List ;
    f            : File ;
@@ -793,7 +793,7 @@ END DoWriteSymbol ;
 
 PROCEDURE DoCheckExported (sym: WORD) ;
 BEGIN
-   IF IsExported(main, sym)
+   IF IsExported(mainModule, sym)
    THEN
       DoWriteSymbol(sym)
    END
@@ -901,7 +901,7 @@ PROCEDURE DoWriteFile (sym: CARDINAL) ;
 VAR
    n: Name ;
 BEGIN
-   main := sym ;
+   mainModule := sym ;
    n := GetSymName(sym) ;
    fprintf0(f, '/* automatically generated by gm2 -fswig */\n') ;
    fprintf0(f, '%') ;
diff --git a/gcc/m2/gm2-compiler/SymbolTable.def b/gcc/m2/gm2-compiler/SymbolTable.def
index a25c2bfb21b..70a4f79b765 100644
--- a/gcc/m2/gm2-compiler/SymbolTable.def
+++ b/gcc/m2/gm2-compiler/SymbolTable.def
@@ -55,7 +55,7 @@ EXPORT QUALIFIED NulSym,
                  SetMainModule,
                  SetFileModule,
                  MakeModule, MakeDefImp,
-                 MakeInnerModule, MakeModuleCtor,
+                 MakeInnerModule, MakeModuleCtor, PutModuleCtorExtern,
                  MakeProcedure,
                  MakeProcedureCtorExtern,
                  MakeConstant,
@@ -641,6 +641,16 @@ PROCEDURE MakeModuleCtor (moduleTok, beginTok, finallyTok: CARDINAL;
                           moduleSym: CARDINAL) ;
 
 
+(*
+   PutModuleCtorExtern - for every ctor related procedure in module sym.
+                         Make it external.  It will create any missing
+                         init/fini procedures but not any missing dep/ctor
+                         procedures.
+*)
+
+PROCEDURE PutModuleCtorExtern (tok: CARDINAL; sym: CARDINAL) ;
+
+
 (*
    MakeVar - creates a variable sym with VarName. It returns the
              symbol index.
diff --git a/gcc/m2/gm2-compiler/SymbolTable.mod b/gcc/m2/gm2-compiler/SymbolTable.mod
index 665e12aace7..6c1cce8ef5d 100644
--- a/gcc/m2/gm2-compiler/SymbolTable.mod
+++ b/gcc/m2/gm2-compiler/SymbolTable.mod
@@ -3073,11 +3073,12 @@ BEGIN
    IF IsDefImp (moduleSym)
    THEN
       InitCtorFields (moduleTok, beginTok, finallyTok,
-                      pSym^.DefImp.ctors, GetSymName (moduleSym), FALSE)
+                      pSym^.DefImp.ctors, GetSymName (moduleSym),
+                      FALSE, TRUE)
    ELSE
       InitCtorFields (moduleTok, beginTok, finallyTok,
                       pSym^.Module.ctors, GetSymName (moduleSym),
-                      IsInnerModule (moduleSym))
+                      IsInnerModule (moduleSym), TRUE)
    END
 END MakeModuleCtor ;
 
@@ -3088,14 +3089,16 @@ END MakeModuleCtor ;
 *)
 
 PROCEDURE InitCtorFields (moduleTok, beginTok, finallyTok: CARDINAL;
-                          VAR ctor: ModuleCtor; name: Name; inner: BOOLEAN) ;
+                          VAR ctor: ModuleCtor; name: Name;
+                          inner, pub: BOOLEAN) ;
 BEGIN
    IF ScaffoldDynamic AND (NOT inner)
    THEN
       (* The ctor procedure must be public.  *)
       ctor.ctor := MakeProcedure (moduleTok, GenName ("_M2_", name, "_ctor")) ;
-      PutCtor (ctor.ctor, TRUE) ;
-      PutPublic (ctor.ctor, TRUE) ;
+      PutCtor (ctor.ctor, pub) ;
+      PutPublic (ctor.ctor, pub) ;
+      PutExtern (ctor.ctor, NOT pub) ;
       (* The dep procedure is local to the module.  *)
       ctor.dep := MakeProcedure (moduleTok, GenName ("_M2_", name, "_dep")) ;
    ELSE
@@ -3104,10 +3107,12 @@ BEGIN
    END ;
    (* The init/fini procedures must be public.  *)
    ctor.init := MakeProcedure (beginTok, GenName ("_M2_", name, "_init")) ;
-   PutPublic (ctor.init, TRUE) ;
+   PutPublic (ctor.init, pub) ;
+   PutExtern (ctor.init, NOT pub) ;
    DeclareArgEnvParams (beginTok, ctor.init) ;
    ctor.fini := MakeProcedure (finallyTok, GenName ("_M2_", name, "_fini")) ;
-   PutPublic (ctor.fini, TRUE) ;
+   PutPublic (ctor.fini, pub) ;
+   PutExtern (ctor.fini, NOT pub) ;
    DeclareArgEnvParams (beginTok, ctor.fini)
 END InitCtorFields ;
 
@@ -3139,7 +3144,7 @@ BEGIN
          InternalError ('expecting Module or DefImp symbol')
       END
    END
-END GetModCtors ;
+END GetModuleCtors ;
 
 
 (*
@@ -3465,8 +3470,8 @@ BEGIN
          InitList(ListOfProcs) ;      (* List of all procedures        *)
                                       (* declared within this module.  *)
          InitList(ListOfModules) ;    (* List of all inner modules.    *)
-         InitWhereDeclaredTok(tok, At) ;  (* Where symbol declared.        *)
-         InitWhereFirstUsedTok(tok, At) ; (* Where symbol first used.      *)
+         InitWhereDeclaredTok(tok, At) ;  (* Where symbol declared.    *)
+         InitWhereFirstUsedTok(tok, At) ; (* Where symbol first used.  *)
          errorScope := GetCurrentErrorScope () ; (* Title error scope. *)
       END
    END ;
@@ -3475,6 +3480,83 @@ BEGIN
 END MakeDefImp ;
 
 
+(*
+   PutProcedureExternPublic - if procedure is not NulSym set extern
+                              and public booleans.
+*)
+
+PROCEDURE PutProcedureExternPublic (procedure: CARDINAL; extern, pub: BOOLEAN) ;
+BEGIN
+   IF procedure # NulSym
+   THEN
+      PutExtern (procedure, extern) ;
+      PutPublic (procedure, pub)
+   END
+END PutProcedureExternPublic ;
+
+
+(*
+   PutCtorExtern -
+*)
+
+PROCEDURE PutCtorExtern (tok: CARDINAL; sym: CARDINAL;
+                         VAR ctor: ModuleCtor; extern: BOOLEAN) ;
+BEGIN
+   (* If the ctor does not exist then make it extern/ (~extern) public.  *)
+   IF ctor.ctor = NulSym
+   THEN
+      ctor.ctor := MakeProcedure (tok, GenName ("_M2_", GetSymName (sym), "_ctor"))
+   END ;
+   PutProcedureExternPublic (ctor.ctor, extern, NOT extern) ;
+   PutCtor (ctor.ctor, NOT extern) ;
+   (* If the ctor does not exist then make it extern/ (~extern) public.  *)
+   IF ctor.dep = NulSym
+   THEN
+      ctor.dep := MakeProcedure (tok, GenName ("_M2_", GetSymName (sym), "_dep"))
+   END ;
+   PutProcedureExternPublic (ctor.dep, extern, NOT extern) ;
+   (* If init/fini do not exist then create them.  *)
+   IF ctor.init = NulSym
+   THEN
+      ctor.init := MakeProcedure (tok, GenName ("_M2_", GetSymName (sym), "_init")) ;
+      DeclareArgEnvParams (tok, ctor.init)
+   END ;
+   PutProcedureExternPublic (ctor.init, extern, NOT extern) ;
+   IF ctor.fini = NulSym
+   THEN
+      ctor.fini := MakeProcedure (tok, GenName ("_M2_", GetSymName (sym), "_fini")) ;
+      DeclareArgEnvParams (tok, ctor.fini)
+   END ;
+   PutProcedureExternPublic (ctor.fini, extern, NOT extern)
+END PutCtorExtern ;
+
+
+(*
+   PutModuleCtorExtern - for every ctor related procedure in module sym.
+                         Make it external.  It will create any missing
+                         init/fini procedures but not any missing dep/ctor
+                         procedures.
+*)
+
+PROCEDURE PutModuleCtorExtern (tok: CARDINAL; sym: CARDINAL) ;
+VAR
+   pSym: PtrToSymbol ;
+BEGIN
+   Assert (IsModule (sym) OR IsDefImp (sym)) ;
+   pSym := GetPsym (sym) ;
+   WITH pSym^ DO
+      CASE SymbolType OF
+
+      DefImpSym:  PutCtorExtern (tok, sym, DefImp.ctors, TRUE) |
+      ModuleSym:  PutCtorExtern (tok, sym, Module.ctors, TRUE)
+
+      ELSE
+         InternalError ('expecting DefImp or Module symbol')
+      END
+   END
+END PutModuleCtorExtern ;
+
+
 (*
    MakeProcedure - creates a procedure sym with name. It returns
                    the symbol index.
diff --git a/gcc/m2/gm2-gcc/init.cc b/gcc/m2/gm2-gcc/init.cc
index fdd21012974..74c04a2d1ac 100644
--- a/gcc/m2/gm2-gcc/init.cc
+++ b/gcc/m2/gm2-gcc/init.cc
@@ -29,82 +29,86 @@ along with GNU Modula-2; see the file COPYING3.  If not see
 #define EXTERN extern
 #endif /* !__GNUG__  */
 
-EXTERN void _M2_M2Bitset_init (int argc, char *argv[]);
-EXTERN void _M2_Debug_init (int argc, char *argv[]);
-EXTERN void _M2_M2Defaults_init (int argc, char *argv[]);
-EXTERN void _M2_Environment_init (int argc, char *argv[]);
-EXTERN void _M2_RTExceptions_init (int argc, char *argv[]);
-EXTERN void _M2_M2EXCEPTION_init (int argc, char *argv[]);
-EXTERN void _M2_M2RTS_init (int argc, char *argv[]);
-EXTERN void _M2_SysExceptions_init (int argc, char *argv[]);
-EXTERN void _M2_DynamicStrings_init (int argc, char *argv[]);
-EXTERN void _M2_Assertion_init (int argc, char *argv[]);
-EXTERN void _M2_FormatStrings_init (int argc, char *argv[]);
-EXTERN void _M2_FIO_init (int argc, char *argv[]);
-EXTERN void _M2_SFIO_init (int argc, char *argv[]);
-EXTERN void _M2_SArgs_init (int argc, char *argv[]);
-EXTERN void _M2_Lists_init (int argc, char *argv[]);
-EXTERN void _M2_UnixArgs_init (int argc, char *argv[]);
-EXTERN void _M2_Args_init (int argc, char *argv[]);
-EXTERN void _M2_wrapc_init (int argc, char *argv[]);
-EXTERN void _M2_TimeString_init (int argc, char *argv[]);
-EXTERN void _M2_IO_init (int argc, char *argv[]);
-EXTERN void _M2_StdIO_init (int argc, char *argv[]);
-EXTERN void _M2_CmdArgs_init (int argc, char *argv[]);
-EXTERN void _M2_M2Preprocess_init (int argc, char *argv[]);
-EXTERN void _M2_M2Error_init (int argc, char *argv[]);
-EXTERN void _M2_M2Search_init (int argc, char *argv[]);
-EXTERN void _M2_Indexing_init (int argc, char *argv[]);
-EXTERN void _M2_NameKey_init (int argc, char *argv[]);
-EXTERN void _M2_NumberIO_init (int argc, char *argv[]);
-EXTERN void _M2_FpuIO_init (int argc, char *argv[]);
-EXTERN void _M2_SysStorage_init (int argc, char *argv[]);
-EXTERN void _M2_Storage_init (int argc, char *argv[]);
-EXTERN void _M2_StrIO_init (int argc, char *argv[]);
-EXTERN void _M2_M2Debug_init (int argc, char *argv[]);
-EXTERN void _M2_M2Batch_init (int argc, char *argv[]);
-EXTERN void _M2_StrLib_init (int argc, char *argv[]);
-EXTERN void _M2_M2ALU_init (int argc, char *argv[]);
-EXTERN void _M2_M2Options_init (int argc, char *argv[]);
-EXTERN void _M2_M2Comp_init (int argc, char *argv[]);
-EXTERN void _M2_M2LexBuf_init (int argc, char *argv[]);
-EXTERN void _M2_SymbolTable_init (int argc, char *argv[]);
-EXTERN void _M2_M2Base_init (int argc, char *argv[]);
-EXTERN void _M2_M2Quads_init (int argc, char *argv[]);
-EXTERN void _M2_SymbolKey_init (int argc, char *argv[]);
-EXTERN void _M2_FifoQueue_init (int argc, char *argv[]);
-EXTERN void _M2_M2Reserved_init (int argc, char *argv[]);
-EXTERN void _M2_M2Const_init (int argc, char *argv[]);
-EXTERN void _M2_P1SymBuild_init (int argc, char *argv[]);
-EXTERN void _M2_P2SymBuild_init (int argc, char *argv[]);
-EXTERN void _M2_P3SymBuild_init (int argc, char *argv[]);
-EXTERN void _M2_M2System_init (int argc, char *argv[]);
-EXTERN void _M2_M2BasicBlock_init (int argc, char *argv[]);
-EXTERN void _M2_M2Pass_init (int argc, char *argv[]);
-EXTERN void _M2_M2Code_init (int argc, char *argv[]);
-EXTERN void _M2_M2AsmUtil_init (int argc, char *argv[]);
-EXTERN void _M2_M2FileName_init (int argc, char *argv[]);
-EXTERN void _M2_M2Version_init (int argc, char *argv[]);
-EXTERN void _M2_M2Students_init (int argc, char *argv[]);
-EXTERN void _M2_StrCase_init (int argc, char *argv[]);
-EXTERN void _M2_SymbolConversion_init (int argc, char *argv[]);
-EXTERN void _M2_M2GCCDeclare_init (int argc, char *argv[]);
-EXTERN void _M2_M2GenGCC_init (int argc, char *argv[]);
-EXTERN void _M2_M2Range_init (int argc, char *argv[]);
-EXTERN void _M2_M2Swig_init (int argc, char *argv[]);
-EXTERN void _M2_M2MetaError_init (int argc, char *argv[]);
-EXTERN void _M2_M2CaseList_init (int argc, char *argv[]);
-EXTERN void _M2_PCSymBuild_init (int argc, char *argv[]);
-EXTERN void _M2_PCBuild_init (int argc, char *argv[]);
-EXTERN void _M2_Sets_init (int argc, char *argv[]);
-EXTERN void _M2_dtoa_init (int argc, char *argv[]);
-EXTERN void _M2_ldtoa_init (int argc, char *argv[]);
-EXTERN void _M2_M2Check_init (int argc, char *argv[]);
-EXTERN void _M2_M2SSA_init (int argc, char *argv[]);
+EXTERN void _M2_M2Bitset_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_Debug_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2Defaults_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_Environment_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_RTExceptions_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2EXCEPTION_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2RTS_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2Dependent_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_SysExceptions_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_DynamicStrings_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_Assertion_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_FormatStrings_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_FIO_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_SFIO_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_SArgs_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_Lists_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_UnixArgs_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_Args_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_wrapc_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_TimeString_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_IO_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_StdIO_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_CmdArgs_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2Preprocess_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2Error_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2Search_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_Indexing_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_NameKey_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_NumberIO_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_FpuIO_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_SysStorage_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_Storage_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_StrIO_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2Debug_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2Batch_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_StrLib_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2ALU_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2Options_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2Comp_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2LexBuf_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_SymbolTable_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2Base_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2Quads_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_SymbolKey_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_FifoQueue_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2Reserved_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2Const_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_P1SymBuild_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_P2SymBuild_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_P3SymBuild_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2System_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2BasicBlock_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2Pass_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2Code_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2AsmUtil_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2FileName_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2Version_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2Students_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_StrCase_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_SymbolConversion_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2GCCDeclare_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2GenGCC_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2Range_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2Swig_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2MetaError_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2CaseList_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_PCSymBuild_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_PCBuild_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_Sets_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_dtoa_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_ldtoa_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2Check_init (int argc, char *argv[], char *envp[]);
+EXTERN void _M2_M2SSA_init (int argc, char *argv[], char *envp[]);
 EXTERN void exit (int);
 EXTERN void M2Comp_compile (const char *filename);
 EXTERN void RTExceptions_DefaultErrorCatch (void);
 
+int StaticInitialization = 1;
+char *ForcedModuleInitOrder = NULL;
+
 
 /* FrontEndInit - initialise the modules, this is a global
    initialisation.  This is called once.  */
@@ -112,36 +116,37 @@ EXTERN void RTExceptions_DefaultErrorCatch (void);
 void
 init_FrontEndInit (void)
 {
-  _M2_Debug_init (0, NULL);
-  _M2_RTExceptions_init (0, NULL);
-  _M2_M2Defaults_init (0, NULL);
-  _M2_Environment_init (0, NULL);
-  _M2_M2EXCEPTION_init (0, NULL);
-  _M2_M2RTS_init (0, NULL);
-  _M2_SysExceptions_init (0, NULL);
-  _M2_DynamicStrings_init (0, NULL);
-  _M2_Assertion_init (0, NULL);
-  _M2_FormatStrings_init (0, NULL);
-  _M2_FIO_init (0, NULL);
-  _M2_SFIO_init (0, NULL);
-  _M2_SArgs_init (0, NULL);
-  _M2_Lists_init (0, NULL);
-  _M2_UnixArgs_init (0, NULL);
-  _M2_Args_init (0, NULL);
-  _M2_wrapc_init (0, NULL);
-  _M2_TimeString_init (0, NULL);
-  _M2_IO_init (0, NULL);
-  _M2_StdIO_init (0, NULL);
-  _M2_CmdArgs_init (0, NULL);
-  _M2_FpuIO_init (0, NULL);
-  _M2_SysStorage_init (0, NULL);
-  _M2_Storage_init (0, NULL);
-  _M2_StrIO_init (0, NULL);
-  _M2_StrLib_init (0, NULL);
-  _M2_dtoa_init (0, NULL);
-  _M2_ldtoa_init (0, NULL);
-  _M2_M2Search_init (0, NULL);
-  _M2_M2Options_init (0, NULL);
+  _M2_Debug_init (0, NULL, NULL);
+  _M2_RTExceptions_init (0, NULL, NULL);
+  _M2_M2Defaults_init (0, NULL, NULL);
+  _M2_Environment_init (0, NULL, NULL);
+  _M2_M2EXCEPTION_init (0, NULL, NULL);
+  _M2_M2Dependent_init (0, NULL, NULL);
+  _M2_M2RTS_init (0, NULL, NULL);
+  _M2_SysExceptions_init (0, NULL, NULL);
+  _M2_DynamicStrings_init (0, NULL, NULL);
+  _M2_Assertion_init (0, NULL, NULL);
+  _M2_FormatStrings_init (0, NULL, NULL);
+  _M2_FIO_init (0, NULL, NULL);
+  _M2_SFIO_init (0, NULL, NULL);
+  _M2_SArgs_init (0, NULL, NULL);
+  _M2_Lists_init (0, NULL, NULL);
+  _M2_UnixArgs_init (0, NULL, NULL);
+  _M2_Args_init (0, NULL, NULL);
+  _M2_wrapc_init (0, NULL, NULL);
+  _M2_TimeString_init (0, NULL, NULL);
+  _M2_IO_init (0, NULL, NULL);
+  _M2_StdIO_init (0, NULL, NULL);
+  _M2_CmdArgs_init (0, NULL, NULL);
+  _M2_FpuIO_init (0, NULL, NULL);
+  _M2_SysStorage_init (0, NULL, NULL);
+  _M2_Storage_init (0, NULL, NULL);
+  _M2_StrIO_init (0, NULL, NULL);
+  _M2_StrLib_init (0, NULL, NULL);
+  _M2_dtoa_init (0, NULL, NULL);
+  _M2_ldtoa_init (0, NULL, NULL);
+  _M2_M2Search_init (0, NULL, NULL);
+  _M2_M2Options_init (0, NULL, NULL);
 }
 
 /* PerCompilationInit - initialise the modules before compiling,
@@ -150,47 +155,47 @@ init_FrontEndInit (void)
 void
 init_PerCompilationInit (const char *filename)
 {
-  _M2_M2Bitset_init (0, NULL);
-  _M2_M2Preprocess_init (0, NULL);
-  _M2_M2Error_init (0, NULL);
-  _M2_Indexing_init (0, NULL);
-  _M2_NameKey_init (0, NULL);
-  _M2_NumberIO_init (0, NULL);
-  _M2_M2Debug_init (0, NULL);
-  _M2_M2Batch_init (0, NULL);
-  _M2_M2ALU_init (0, NULL);
-  _M2_M2Comp_init (0, NULL);
-  _M2_M2LexBuf_init (0, NULL);
-  _M2_SymbolTable_init (0, NULL);
-  _M2_M2Base_init (0, NULL);
-  _M2_M2Quads_init (0, NULL);
-  _M2_SymbolKey_init (0, NULL);
-  _M2_FifoQueue_init (0, NULL);
-  _M2_M2Reserved_init (0, NULL);
-  _M2_M2Const_init (0, NULL);
-  _M2_P1SymBuild_init (0, NULL);
-  _M2_P2SymBuild_init (0, NULL);
-  _M2_P3SymBuild_init (0, NULL);
-  _M2_M2System_init (0, NULL);
-  _M2_M2BasicBlock_init (0, NULL);
-  _M2_M2Pass_init (0, NULL);
-  _M2_M2Code_init (0, NULL);
-  _M2_M2AsmUtil_init (0, NULL);
-  _M2_M2FileName_init (0, NULL);
-  _M2_M2Version_init (0, NULL);
-  _M2_M2Students_init (0, NULL);
-  _M2_StrCase_init (0, NULL);
-  _M2_SymbolConversion_init (0, NULL);
-  _M2_M2GCCDeclare_init (0, NULL);
-  _M2_M2GenGCC_init (0, NULL);
-  _M2_M2Range_init (0, NULL);
-  _M2_M2Swig_init (0, NULL);
-  _M2_M2MetaError_init (0, NULL);
-  _M2_M2CaseList_init (0, NULL);
-  _M2_PCSymBuild_init (0, NULL);
-  _M2_PCBuild_init (0, NULL);
-  _M2_Sets_init (0, NULL);
-  _M2_M2SSA_init (0, NULL);
-  _M2_M2Check_init (0, NULL);
+  _M2_M2Bitset_init (0, NULL, NULL);
+  _M2_M2Preprocess_init (0, NULL, NULL);
+  _M2_M2Error_init (0, NULL, NULL);
+  _M2_Indexing_init (0, NULL, NULL);
+  _M2_NameKey_init (0, NULL, NULL);
+  _M2_NumberIO_init (0, NULL, NULL);
+  _M2_M2Debug_init (0, NULL, NULL);
+  _M2_M2Batch_init (0, NULL, NULL);
+  _M2_M2ALU_init (0, NULL, NULL);
+  _M2_M2Comp_init (0, NULL, NULL);
+  _M2_M2LexBuf_init (0, NULL, NULL);
+  _M2_SymbolTable_init (0, NULL, NULL);
+  _M2_M2Base_init (0, NULL, NULL);
+  _M2_M2Quads_init (0, NULL, NULL);
+  _M2_SymbolKey_init (0, NULL, NULL);
+  _M2_FifoQueue_init (0, NULL, NULL);
+  _M2_M2Reserved_init (0, NULL, NULL);
+  _M2_M2Const_init (0, NULL, NULL);
+  _M2_P1SymBuild_init (0, NULL, NULL);
+  _M2_P2SymBuild_init (0, NULL, NULL);
+  _M2_P3SymBuild_init (0, NULL, NULL);
+  _M2_M2System_init (0, NULL, NULL);
+  _M2_M2BasicBlock_init (0, NULL, NULL);
+  _M2_M2Pass_init (0, NULL, NULL);
+  _M2_M2Code_init (0, NULL, NULL);
+  _M2_M2AsmUtil_init (0, NULL, NULL);
+  _M2_M2FileName_init (0, NULL, NULL);
+  _M2_M2Version_init (0, NULL, NULL);
+  _M2_M2Students_init (0, NULL, NULL);
+  _M2_StrCase_init (0, NULL, NULL);
+  _M2_SymbolConversion_init (0, NULL, NULL);
+  _M2_M2GCCDeclare_init (0, NULL, NULL);
+  _M2_M2GenGCC_init (0, NULL, NULL);
+  _M2_M2Range_init (0, NULL, NULL);
+  _M2_M2Swig_init (0, NULL, NULL);
+  _M2_M2MetaError_init (0, NULL, NULL);
+  _M2_M2CaseList_init (0, NULL, NULL);
+  _M2_PCSymBuild_init (0, NULL, NULL);
+  _M2_PCBuild_init (0, NULL, NULL);
+  _M2_Sets_init (0, NULL, NULL);
+  _M2_M2SSA_init (0, NULL, NULL);
+  _M2_M2Check_init (0, NULL, NULL);
   M2Comp_compile (filename);
 }
diff --git a/gcc/m2/gm2-gcc/m2expr.def b/gcc/m2/gm2-gcc/m2expr.def
index ee95764391b..8988c78d575 100644
--- a/gcc/m2/gm2-gcc/m2expr.def
+++ b/gcc/m2/gm2-gcc/m2expr.def
@@ -19,7 +19,7 @@ You should have received a copy of the GNU General Public License
 along with GNU Modula-2; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  *)
 
-DEFINITION MODULE FOR "C" m2expr ;
+DEFINITION MODULE m2expr ;
 
 FROM SYSTEM IMPORT ADDRESS ;
 FROM m2tree IMPORT Tree ;
diff --git a/gcc/m2/gm2-libs-ch/RTcodummy.c b/gcc/m2/gm2-libs-ch/RTcodummy.c
index 63738c403ab..d397a27db11 100644
--- a/gcc/m2/gm2-libs-ch/RTcodummy.c
+++ b/gcc/m2/gm2-libs-ch/RTcodummy.c
@@ -120,7 +120,6 @@ RTco_turnInterrupts (unsigned int newLevel)
   return 0;
 }
 
-#if 0
 void
 _M2_RTco_init (void)
 {
@@ -130,7 +129,6 @@ void
 _M2_RTco_finish (void)
 {
 }
-#endif
 
 
 #ifdef __cplusplus
diff --git a/gcc/m2/gm2-libs-ch/pthdummy.c b/gcc/m2/gm2-libs-ch/pthdummy.c
deleted file mode 100644
index 5d55ec00526..00000000000
--- a/gcc/m2/gm2-libs-ch/pthdummy.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/* pthdummy.c provide dummy stubs to satisy bootstrap requirements.
-
-Copyright (C) 2018-2022 Free Software Foundation, Inc.
-Contributed by Gaius Mulley <gaius@glam.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
-pth_select (__attribute__ ((unused)) int p1,
-	    __attribute__ ((unused)) void *p2,
-	    __attribute__ ((unused)) void *p3,
-	    __attribute__ ((unused)) void *p4,
-	    __attribute__ ((unused)) void *p5)
-{
-  return 0;
-}
-
-
-int
-pth_uctx_create (__attribute__ ((unused)) void *p)
-{
-  return 0;
-}
-
-
-int
-pth_init (void)
-{
-  return 0;
-}
diff --git a/gcc/m2/gm2spec.cc b/gcc/m2/gm2spec.cc
index 1305d9ceb53..3b36afaa839 100644
--- a/gcc/m2/gm2spec.cc
+++ b/gcc/m2/gm2spec.cc
@@ -66,10 +66,6 @@ along with GNU Modula-2; see the file COPYING3.  If not see
 #define LIBRARY_PATH_ENV "LIBRARY_PATH"
 #endif
 
-#ifndef GM2_LIBEXEC_ENV
-#define GM2_LIBEXEC_ENV "GM2_LIBEXEC"
-#endif
-
 int lang_specific_extra_outfiles = 0;
 
 /* DEBUGGING will print all the options at various stages with their
@@ -119,8 +115,11 @@ static void insert_option (unsigned int *in_decoded_options_count,
 static const char *gen_link_path (const char *libpath, const char *dialect);
 static const char *add_exec_dir (int argc, const char *argv[]);
 static const char *gen_gm2_libexec (const char *path);
-static const char *get_libexec (void);
 
+static bool seen_scaffold_static = false;
+static bool seen_scaffold_dynamic = false;
+static bool scaffold_static = false;
+static bool scaffold_dynamic = true;  // Default uses -fscaffold-dynamic.
 static bool seen_B = false;
 static const char *B_path = NULL;
 static const char *multilib_dir = NULL;
@@ -133,17 +132,6 @@ static const char *multilib_dir = NULL;
 #endif
 
 
-static const char *
-get_libexec (void)
-{
-  const char *libexec = getenv (GM2_LIBEXEC_ENV);
-
-  if (libexec == NULL || (strcmp (libexec, "") == 0))
-    return STANDARD_LIBEXEC_PREFIX;
-  else
-    return libexec;
-}
-
 /* gen_gm2_libexec, return a libexec string.  */
 
 static const char *
@@ -165,7 +153,7 @@ gen_gm2_libexec (const char *libexec)
   return s;
 }
 
-/* add_exec_dir prepends the exec path to the given executable filename.  */
+/* add_exec_dir wraps the exec path with the -fcpp-prog= option.  */
 
 static const char *
 add_exec_dir (int argc, const char *argv[])
@@ -177,7 +165,7 @@ add_exec_dir (int argc, const char *argv[])
       if (seen_B)
         path = xstrdup (B_path);
       else
-        path = gen_gm2_libexec (get_libexec ());
+        path = gen_gm2_libexec (STANDARD_LIBEXEC_PREFIX);
 
       if (path != NULL)
         {
@@ -241,7 +229,7 @@ add_lib (size_t opt_index, const char *lib, int joined)
   fe_generate_option (opt_index, lib, joined);
 }
 
-/* insert_option inserts an option at position on the command line.  */
+/* insert_option inserts an option at position index on the command line.  */
 
 static void
 insert_option (unsigned int *in_decoded_options_count,
@@ -267,8 +255,8 @@ insert_option (unsigned int *in_decoded_options_count,
   *in_decoded_options = new_decoded_options;
 }
 
-/* add_library adds a library to the command line at arg position.
-   It returns the number of arguments added.  If libraryname is NULL or
+/* add_library adds a library to the command line at arg position.  It
+   returns the number of arguments added.  If libraryname is NULL or
    empty then zero is returned.  */
 
 static int
@@ -290,8 +278,7 @@ add_library (const char *libraryname, unsigned int *in_decoded_options_count,
   generate_option (OPT_l, libraryname, 1, CL_DRIVER,
                    &(*in_decoded_options)[position]);
 
-#if 0
-  // defined(DEBUGGING)
+#if defined(DEBUGGING)
   print_options ("after add_library", *in_decoded_options_count, *in_decoded_options);
 #endif
   return 1;
@@ -717,6 +704,14 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
         case OPT_fno_m2_plugin:
           need_plugin = false;
           break;
+	case OPT_fscaffold_dynamic:
+	  seen_scaffold_dynamic = true;
+	  scaffold_dynamic = (*in_decoded_options)[i].value;
+	  break;
+	case OPT_fscaffold_static:
+	  seen_scaffold_static = true;
+	  scaffold_static = (*in_decoded_options)[i].value;
+	  break;
 	default:
 	  if (((*in_decoded_options)[i].orig_option_with_args_text != NULL)
 	      && (strncmp ((*in_decoded_options)[i].orig_option_with_args_text,
@@ -726,12 +721,20 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
 	}
     }
 
+  if (scaffold_static && scaffold_dynamic)
+    {
+      if (! seen_scaffold_dynamic)
+	scaffold_dynamic = false;
+      if (scaffold_dynamic && scaffold_static)
+	error ("%qs and %qs cannot both be enabled",
+	       "-fscaffold-dynamic", "-fscaffold-static");
+    }
   libpath = fe_getenv (LIBRARY_PATH_ENV);
   if (libpath == NULL || (strcmp (libpath, "") == 0))
     libpath = LIBSUBDIR;
 
 #if defined(DEBUGGING)
-  print_options ("at beginning", *in_decoded_options_count, *in_decoded_options);
+  print_options ("after scaffold checking", *in_decoded_options_count, *in_decoded_options);
 #endif
   i = 1;
   for (i = 1; i < *in_decoded_options_count; i++)
@@ -774,7 +777,7 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
   if (language != NULL && (strcmp (language, "modula-2") != 0))
     return;
 #if defined(DEBUGGING)
-  print_options ("in the middle", *in_decoded_options_count, *in_decoded_options);
+  print_options ("after dialect detection", *in_decoded_options_count, *in_decoded_options);
 #endif
 
   /* If the libraries have not been specified by the user and the
@@ -785,7 +788,7 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
       if (strcmp (dialect, "iso") == 0)
         libraries = xstrdup ("m2iso,m2pim");
       else
-        libraries = xstrdup ("m2pim");  /* Always require m2pim for dynamic scaffold.  */
+        libraries = xstrdup ("m2pim");  /* Default to pim libraries if none specified.  */
     }
 
   libraries = convert_abbreviations (libraries);
@@ -802,6 +805,7 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
   if (linking)
     {
       if (strcmp (dialect, "iso") == 0)
+	/* We need the pim libraries even if using iso.  */
         (*in_added_libraries)
             += add_library ("m2pim", in_decoded_options_count,
                             in_decoded_options, *in_decoded_options_count);
@@ -839,16 +843,16 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
         }
     }
 #if defined(DEBUGGING)
-  print_options ("before include purge", *in_decoded_options_count, *in_decoded_options);
+  print_options ("before include options purge", *in_decoded_options_count, *in_decoded_options);
 #endif
   purge_include_options (in_decoded_options_count, in_decoded_options);
 #if defined(DEBUGGING)
-  print_options ("after include purge", *in_decoded_options_count, *in_decoded_options);
+  print_options ("after include options purge", *in_decoded_options_count, *in_decoded_options);
 #endif
 }
 
 /* lang_specific_pre_link - does nothing.  */
-
+// --fixme-- remove lang_specific_pre_link here and all other drivers.
 int
 lang_specific_pre_link (void)
 {
diff --git a/gcc/m2/mc-boot-ch/Gpth.c b/gcc/m2/mc-boot-ch/Gpth.c
deleted file mode 100644
index 32ad7f3444c..00000000000
--- a/gcc/m2/mc-boot-ch/Gpth.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Gpth.c provides access to pth_select for Modula-2.
-
-Copyright (C) 2016-2022 Free Software Foundation, Inc.
-Contributed by Gaius Mulley <gaius@glam.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.
-
-You should have received a copy of the GNU General Public License
-along with GNU Modula-2; see the file COPYING3.  If not see
-<http://www.gnu.org/licenses/>.  */
-
-int
-pth_pth_select (int p1, int p2, int p3, int p4, int p5)
-{
-  return 0;
-}
-
-int
-pth_pth_uctx_create (void *p)
-{
-}
-
-int
-pth_pth_uctx_make (void *p1, void *p2, unsigned int p3, void *p4, void *p5,
-                   void *p6, void *p7)
-{
-}
-
-int
-pth_pth_uctx_save (void *p1)
-{
-}
-
-int
-pth_pth_uctx_switch (void *p1, void *p2)
-{
-}
-
-int
-pth_pth_init (void)
-{
-  return 0;
-}
diff --git a/gcc/m2/mc-boot-ch/Gtermios.c b/gcc/m2/mc-boot-ch/Gtermios.c
deleted file mode 100644
index 82975b3e98f..00000000000
--- a/gcc/m2/mc-boot-ch/Gtermios.c
+++ /dev/null
@@ -1,1955 +0,0 @@
-/* Gtermios.c handwritten module for mc.
-
-Copyright (C) 2010-2022 Free Software Foundation, Inc.
-Contributed by Gaius Mulley <gaius@glam.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.
-
-You should have received a copy of the GNU General Public License
-along with GNU Modula-2; see the file COPYING3.  If not see
-<http://www.gnu.org/licenses/>.  */
-
-#include "config.h"
-#include "system.h"
-
-#include "gm2-libs-host.h"
-
-#ifdef HAVE_TERMIOS_H
-# include <termios.h>
-#endif
-
-#ifdef TERMIOS_NEEDS_XOPEN_SOURCE
-#define _XOPEN_SOURCE
-#endif
-
-#if defined(__cplusplus)
-#define EXTERN extern "C"
-#else
-#define EXTERN
-#endif
-
-#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.  */
-EXTERN void *EXPORT (InitTermios) (void);
-EXTERN void *EXPORT (KillTermios) (struct termios *p);
-EXTERN int EXPORT (cfgetospeed) (struct termios *t);
-EXTERN int EXPORT (cfgetispeed) (struct termios *t);
-EXTERN int EXPORT (cfsetospeed) (struct termios *t, unsigned int b);
-EXTERN int EXPORT (cfsetispeed) (struct termios *t, unsigned int b);
-EXTERN int EXPORT (cfsetspeed) (struct termios *t, unsigned int b);
-EXTERN int EXPORT (tcgetattr) (int fd, struct termios *t);
-EXTERN int EXPORT (tcsetattr) (int fd, int option, struct termios *t);
-EXTERN void EXPORT (cfmakeraw) (struct termios *t);
-EXTERN int EXPORT (tcsendbreak) (int fd, int duration);
-EXTERN int EXPORT (tcdrain) (int fd);
-EXTERN int EXPORT (tcflushi) (int fd);
-EXTERN int EXPORT (tcflusho) (int fd);
-EXTERN int EXPORT (tcflushio) (int fd);
-EXTERN int EXPORT (tcflowoni) (int fd);
-EXTERN int EXPORT (tcflowoffi) (int fd);
-EXTERN int EXPORT (tcflowono) (int fd);
-EXTERN int EXPORT (tcflowoffo) (int fd);
-EXTERN int EXPORT (GetFlag) (struct termios *t, Flag f, int *b);
-EXTERN int EXPORT (SetFlag) (struct termios *t, Flag f, int b);
-EXTERN int EXPORT (GetChar) (struct termios *t, ControlChar c, char *ch);
-EXTERN int EXPORT (SetChar) (struct termios *t, ControlChar c, char ch);
-EXTERN int EXPORT (tcsnow) (void);
-EXTERN int EXPORT (tcsflush) (void);
-EXTERN int EXPORT (tcsdrain) (void);
-EXTERN int doSetUnset (unsigned int *bitset, unsigned int mask, int value);
-EXTERN void _M2_termios_init (void);
-EXTERN void _M2_termios_finish (void);
-
-/* InitTermios - new data structure.  */
-
-EXTERN
-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.  */
-
-EXTERN
-void *EXPORT (KillTermios) (struct termios *p)
-{
-  free (p);
-  return NULL;
-}
-
-/* tcsnow - return the value of TCSANOW.  */
-
-EXTERN
-int EXPORT (tcsnow) (void) { return TCSANOW; }
-
-/* tcsdrain - return the value of TCSADRAIN.  */
-
-EXTERN
-int EXPORT (tcsdrain) (void) { return TCSADRAIN; }
-
-/* tcsflush - return the value of TCSAFLUSH.  */
-
-EXTERN
-int EXPORT (tcsflush) (void) { return TCSAFLUSH; }
-
-/* cfgetospeed - return output baud rate.  */
-
-EXTERN
-int EXPORT (cfgetospeed) (struct termios *t) { return cfgetospeed (t); }
-
-/* cfgetispeed - return input baud rate.  */
-
-EXTERN
-int EXPORT (cfgetispeed) (struct termios *t) { return cfgetispeed (t); }
-
-/* cfsetospeed - set output baud rate.  */
-
-EXTERN
-int EXPORT (cfsetospeed) (struct termios *t, unsigned int b)
-{
-  return cfsetospeed (t, b);
-}
-
-/* cfsetispeed - set input baud rate.  */
-
-EXTERN
-int EXPORT (cfsetispeed) (struct termios *t, unsigned int b)
-{
-  return cfsetispeed (t, b);
-}
-
-/* cfsetspeed - set input and output baud rate.  */
-
-EXTERN
-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.  */
-
-EXTERN
-int EXPORT (tcgetattr) (int fd, struct termios *t)
-{
-  return tcgetattr (fd, t);
-}
-
-/* tcsetattr - set state of, fd, to, t, using option.  */
-
-EXTERN
-int EXPORT (tcsetattr) (int fd, int option, struct termios *t)
-{
-  return tcsetattr (fd, option, t);
-}
-
-/* cfmakeraw - sets the terminal to raw mode.  */
-
-EXTERN
-void EXPORT (cfmakeraw) (struct termios *t)
-{
-#if defined(HAVE_CFMAKERAW)
-  return cfmakeraw (t);
-#endif
-}
-
-/* tcsendbreak - send zero bits for duration.  */
-
-EXTERN
-int EXPORT (tcsendbreak) (int fd, int duration)
-{
-  return tcsendbreak (fd, duration);
-}
-
-/* tcdrain - waits for pending output to be written on, fd.  */
-
-EXTERN
-int EXPORT (tcdrain) (int fd) { return tcdrain (fd); }
-
-/* tcflushi - flush input.  */
-
-EXTERN
-int EXPORT (tcflushi) (int fd)
-{
-#if defined(TCIFLUSH)
-  return tcflush (fd, TCIFLUSH);
-#else
-  return 1;
-#endif
-}
-
-/* tcflusho - flush output.  */
-
-EXTERN
-int EXPORT (tcflusho) (int fd)
-{
-#if defined(TCOFLUSH)
-  return tcflush (fd, TCOFLUSH);
-#else
-  return 1;
-#endif
-}
-
-/* tcflushio - flush input and output.  */
-
-EXTERN
-int EXPORT (tcflushio) (int fd)
-{
-#if defined(TCIOFLUSH)
-  return tcflush (fd, TCIOFLUSH);
-#else
-  return 1;
-#endif
-}
-
-/* tcflowoni - restart input on, fd.  */
-
-EXTERN
-int EXPORT (tcflowoni) (int fd)
-{
-#if defined(TCION)
-  return tcflow (fd, TCION);
-#else
-  return 1;
-#endif
-}
-
-/* tcflowoffi - stop input on, fd.  */
-
-EXTERN
-int EXPORT (tcflowoffi) (int fd)
-{
-#if defined(TCIOFF)
-  return tcflow (fd, TCIOFF);
-#else
-  return 1;
-#endif
-}
-
-/* tcflowono - restart output on, fd.  */
-
-EXTERN
-int EXPORT (tcflowono) (int fd)
-{
-#if defined(TCOON)
-  return tcflow (fd, TCOON);
-#else
-  return 1;
-#endif
-}
-
-/* tcflowoffo - stop output on, fd.  */
-
-EXTERN
-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.  */
-
-EXTERN
-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.  */
-
-EXTERN
-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_BAUD)
-      *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.  */
-
-EXTERN
-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.  */
-
-EXTERN
-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.  */
-
-EXTERN
-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;
-    }
-}
-
-void
-_M2_termios_init (void)
-{
-}
-
-void
-_M2_termios_finish (void)
-{
-}
diff --git a/gcc/testsuite/gm2/link/pimc/pass/testunixargs.mod b/gcc/testsuite/gm2/link/pimc/pass/testunixargs.mod
index b78663f7bf3..978634e1911 100644
--- a/gcc/testsuite/gm2/link/pimc/pass/testunixargs.mod
+++ b/gcc/testsuite/gm2/link/pimc/pass/testunixargs.mod
@@ -9,6 +9,6 @@ VAR
    ptr: ADDRESS ;
    num: CARDINAL ;
 BEGIN
-   ptr := ArgV ;
-   num := ArgC
+   ptr := GetArgV () ;
+   num := GetArgC ()
 END testunixargs.
\ No newline at end of file
diff --git a/gm2tools/gm2l.1 b/gm2tools/gm2l.1
index 2c87026c718..76971ac5ead 100644
--- a/gm2tools/gm2l.1
+++ b/gm2tools/gm2l.1
@@ -1,15 +1,15 @@
-.TH gm2l "1" "June 2021" "Modula-2" "User Commands"
+.TH gm2l "1" "July 2022" "Modula-2" "User Commands"
 .SH NAME
 gm2l \- generate an initialization sequence by analyzing module imports.
 .SH SYNOPSIS
 .B gm2l
 .RB [ -fdef= extension ]
+.RB [ -flibs= list ]
 .RB [ -fmod= extension ]
 .RB [ -h ]
 .RB [ --help ]
 .RB [ -I searchpath ]
-.RB [ --M2RTS ]
-.RB [ -M2RTS ]
+.RB [ --exclude= list ]
 .RB [ -v ]
 .RB [ --verbose ]
 .RB [ -o " outputfile" ]
@@ -17,19 +17,14 @@ gm2l \- generate an initialization sequence by analyzing module imports.
 .SH DESCRIPTION
 .PP
 A tool for generating a static initialization sequence by analyzing
-module imports.  This tool will generate a textual list of modules in
-an order which satisfies a topological order of an import graph.  The
-textual list of modules can be manipulated and used by the other
-Modula-2 link tools:
+module imports from source files.  It also generates a list of all
+dependent modules for an application.  This tool will generate a
+textual list of modules in an order which satisfies a topological
+order of an import graph.  The textual list of modules can be used by
+the other Modula-2 tools:
 .IR gm2lcc (1)
-.IR gm2lgen (1)
-.IR gm2lorder (1).
-The command line program
-.IR gm2
-can be instructed to automatically invoke
-.IR gm2l (1)
-and the above programs to construct a C++ scaffold for a Modula-2
-application.
+and
+.IR gm2 (1).
 .SH OPTIONS
 .TP
 .B -fdef= extension
@@ -38,6 +33,22 @@ this option is not specified then an extension of
 .B .def
 is assumed.
 .TP
+.B -flibs= list
+add include paths for the named libraries in the list.
+The shorthand names
+.B pim ,
+.B iso ,
+.B cor ,
+.B log ,
+expand to the installed library paths:
+.B m2pim ,
+.B m2iso ,
+.B m2cor
+and
+.B m2log .
+Any other names in the list
+are treated as the base directory name in the installed library path.
+.TP
 .B -fmod= extension
 assume that program and implementation modules have the posfix
 \fIextension\fP.  If this option is not specified then an extension of
@@ -55,12 +66,18 @@ equivalent to
 specifies the search path used to find definition, implementation and
 program modules.
 .TP
-.B --M2RTS
-do not include the module M2RTS even if it is a dependant module.
-.TP
-.B -M2RTS
-equivalent to
-.B --M2RTS\fR.
+.B --exclude= module1,module2
+do not include module1 and module2 in the textual list output.
+The string after the
+.B --exclude=
+should be a comma separated list of module names.
+.B --include= module1,module2
+include module1 and module2 in the textual list output.
+The string after the
+.B --include=
+should be a comma separated list of module names.  Any included
+modules which are not found by traversing the import graph are added
+as dependants to the main program.
 .TP
 .B -v
 turn on the verbose flag.  This will display the module name and
@@ -71,7 +88,5 @@ equivalent to
 .B -v\fR.
 .SH "SEE ALSO"
 .IR gm2lcc (1),
-.IR gm2lgen (1),
-.IR gm2lorder (1)
 and
 .IR gm2 (1).
diff --git a/libgm2/libm2iso/ErrnoCategory.cc b/libgm2/libm2iso/ErrnoCategory.cc
index ce673135dbe..70e840d352b 100644
--- a/libgm2/libm2iso/ErrnoCategory.cc
+++ b/libgm2/libm2iso/ErrnoCategory.cc
@@ -162,7 +162,7 @@ _M2_ErrnoCategory_init (int, char *argv[], char *env[])
 }
 
 extern "C" void
-_M2_ErrnoCategory_finish (int, char *argv[], char *env[])
+_M2_ErrnoCategory_fini (int, char *argv[], char *env[])
 {
 }
 
@@ -175,6 +175,6 @@ struct _M2_ErrnoCategory_ctor { _M2_ErrnoCategory_ctor (); } _M2_ErrnoCategory_c
 
 _M2_ErrnoCategory_ctor::_M2_ErrnoCategory_ctor (void)
 {
-  M2RTS_RegisterModule ("ErrnoCategory", _M2_ErrnoCategory_init, _M2_ErrnoCategory_finish,
+  M2RTS_RegisterModule ("ErrnoCategory", _M2_ErrnoCategory_init, _M2_ErrnoCategory_fini,
 			_M2_ErrnoCategory_dep);
 }
diff --git a/libgm2/libm2iso/RTco.cc b/libgm2/libm2iso/RTco.cc
index f97e7dad299..9aad1561b0c 100644
--- a/libgm2/libm2iso/RTco.cc
+++ b/libgm2/libm2iso/RTco.cc
@@ -106,7 +106,7 @@ _M2_RTco_init (int argc, char *argv[], char *envp[])
 }
 
 extern "C" void
-_M2_RTco_finish (int argc, char *argv[], char *envp[])
+_M2_RTco_fini (int argc, char *argv[], char *envp[])
 {
 }
 
@@ -462,6 +462,6 @@ struct _M2_RTco_ctor { _M2_RTco_ctor (); } _M2_RTco_ctor;
 
 _M2_RTco_ctor::_M2_RTco_ctor (void)
 {
-  M2RTS_RegisterModule ("RTco", _M2_RTco_init, _M2_RTco_finish,
+  M2RTS_RegisterModule ("RTco", _M2_RTco_init, _M2_RTco_fini,
 			_M2_RTco_dep);
 }
diff --git a/libgm2/libm2pim/SysExceptions.cc b/libgm2/libm2pim/SysExceptions.cc
index 859bb6303eb..780b097aaa6 100644
--- a/libgm2/libm2pim/SysExceptions.cc
+++ b/libgm2/libm2pim/SysExceptions.cc
@@ -241,7 +241,7 @@ _M2_SysExceptions_init (int, char *[], char *[])
 }
 
 extern "C" void
-_M2_SysExceptions_finish (int, char *[], char *[])
+_M2_SysExceptions_fini (int, char *[], char *[])
 {
 }
 
@@ -254,6 +254,6 @@ struct _M2_SysExceptions_ctor { _M2_SysExceptions_ctor (); } _M2_SysExceptions_c
 
 _M2_SysExceptions_ctor::_M2_SysExceptions_ctor (void)
 {
-  M2RTS_RegisterModule ("SysExceptions", _M2_SysExceptions_init, _M2_SysExceptions_finish,
+  M2RTS_RegisterModule ("SysExceptions", _M2_SysExceptions_init, _M2_SysExceptions_fini,
 			_M2_SysExceptions_dep);
 }
diff --git a/libgm2/libm2pim/errno.cc b/libgm2/libm2pim/errno.cc
index e1a5400174e..d47b7b75253 100644
--- a/libgm2/libm2pim/errno.cc
+++ b/libgm2/libm2pim/errno.cc
@@ -52,7 +52,7 @@ _M2_errno_init (int, char *[], char *[])
 }
 
 extern "C" void
-_M2_errno_finish (int, char *[], char *[])
+_M2_errno_fini (int, char *[], char *[])
 {
 }
 
@@ -65,6 +65,6 @@ struct _M2_errno_ctor { _M2_errno_ctor (); } _M2_errno_ctor;
 
 _M2_errno_ctor::_M2_errno_ctor (void)
 {
-  M2RTS_RegisterModule ("errno", _M2_errno_init, _M2_errno_finish,
+  M2RTS_RegisterModule ("errno", _M2_errno_init, _M2_errno_fini,
 			_M2_errno_dep);
 }
diff --git a/libgm2/libm2pim/termios.cc b/libgm2/libm2pim/termios.cc
index d3b3ebcf589..3015ee1380d 100644
--- a/libgm2/libm2pim/termios.cc
+++ b/libgm2/libm2pim/termios.cc
@@ -1969,7 +1969,7 @@ _M2_termios_init (int, char *[], char *[])
 }
 
 extern "C" void
-_M2_termios_finish (int, char *[], char *[])
+_M2_termios_fini (int, char *[], char *[])
 {
 }
 
@@ -1982,6 +1982,6 @@ struct _M2_termios_ctor { _M2_termios_ctor (); } _M2_termios_ctor;
 
 _M2_termios_ctor::_M2_termios_ctor (void)
 {
-  M2RTS_RegisterModule ("termios", _M2_termios_init, _M2_termios_finish,
+  M2RTS_RegisterModule ("termios", _M2_termios_init, _M2_termios_fini,
 			_M2_termios_dep);
 }


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-07-05 13:50 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-05 13:50 [gcc/devel/m2link] Static scaffold fixes, gm2l tidyup 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).