3/19 modula2 front end: gm2 driver files.
Checks
Context |
Check |
Description |
snail/gcc-patch-check |
success
|
Github commit url
|
Commit Message
This patchset contains the c++, h and option related files necessary
to build the driver program gm2. The patch also consists of the
autoconf/configure related build infastructure sources found in
gcc/m2. The reviewer might need to look at the 01-02-make patchset.
The gm2 driver is heavily based on the fortran driver, it also adds
the c++ libraries and modula-2 search paths and libraries depending
upon dialect for user convenience. Users could link modula-2 objects
using g++ if they supply the include and link paths.
------8<----------8<----------8<----------8<----------8<----------8<----
Comments
On Mon, Oct 10, 2022 at 5:33 PM Gaius Mulley via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
>
>
> This patchset contains the c++, h and option related files necessary
> to build the driver program gm2. The patch also consists of the
> autoconf/configure related build infastructure sources found in
> gcc/m2. The reviewer might need to look at the 01-02-make patchset.
> The gm2 driver is heavily based on the fortran driver, it also adds
> the c++ libraries and modula-2 search paths and libraries depending
> upon dialect for user convenience. Users could link modula-2 objects
> using g++ if they supply the include and link paths.
>
>
> ------8<----------8<----------8<----------8<----------8<----------8<----
> diff -ruw /dev/null gcc-git-devel-modula2/gcc/m2/gm2spec.cc
> --- /dev/null 2022-08-24 16:22:16.888000070 +0100
> +++ gcc-git-devel-modula2/gcc/m2/gm2spec.cc 2022-10-07 20:21:18.662097087 +0100
> @@ -0,0 +1,937 @@
> +/* gm2spec.cc specific flags and argument handling within GNU Modula-2.
> +
> +Copyright (C) 2007-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 "coretypes.h"
> +#include "tm.h"
> +#include "xregex.h"
> +#include "obstack.h"
> +#include "intl.h"
> +#include "prefix.h"
> +#include "opt-suggestions.h"
> +#include "gcc.h"
> +#include "opts.h"
> +#include "vec.h"
> +
> +#include "m2/gm2config.h"
> +
> +#ifdef HAVE_DIRENT_H
> +#include <dirent.h>
> +#else
> +#ifdef HAVE_SYS_NDIR_H
> +#include <sys/ndir.h>
> +#endif
> +#ifdef HAVE_SYS_DIR_H
> +#include <sys/dir.h>
> +#endif
> +#ifdef HAVE_NDIR_H
> +#include <ndir.h>
> +#endif
> +#endif
> +
> +/* This bit is set if we saw a `-xfoo' language specification. */
> +#define LANGSPEC (1<<1)
> +/* This bit is set if they did `-lm' or `-lmath'. */
> +#define MATHLIB (1<<2)
> +/* This bit is set if they did `-lc'. */
> +#define WITHLIBC (1<<3)
> +/* Skip this option. */
> +#define SKIPOPT (1<<4)
> +
> +#ifndef MATH_LIBRARY
> +#define MATH_LIBRARY "m"
> +#endif
> +#ifndef MATH_LIBRARY_PROFILE
> +#define MATH_LIBRARY_PROFILE MATH_LIBRARY
> +#endif
> +
> +#ifndef LIBSTDCXX
> +#define LIBSTDCXX "stdc++"
> +#endif
> +#ifndef LIBSTDCXX_PROFILE
> +#define LIBSTDCXX_PROFILE LIBSTDCXX
> +#endif
> +#ifndef LIBSTDCXX_STATIC
> +#define LIBSTDCXX_STATIC NULL
> +#endif
> +
> +#ifndef LIBCXX
> +#define LIBCXX "c++"
> +#endif
> +#ifndef LIBCXX_PROFILE
> +#define LIBCXX_PROFILE LIBCXX
> +#endif
> +#ifndef LIBCXX_STATIC
> +#define LIBCXX_STATIC NULL
> +#endif
> +
> +#ifndef LIBCXXABI
> +#define LIBCXXABI "c++abi"
> +#endif
> +#ifndef LIBCXXABI_PROFILE
> +#define LIBCXXABI_PROFILE LIBCXXABI
> +#endif
> +#ifndef LIBCXXABI_STATIC
> +#define LIBCXXABI_STATIC NULL
> +#endif
> +
> +/* The values used here must match those of the stdlib_kind enumeration
> + in c.opt. */
> +enum stdcxxlib_kind
> +{
> + USE_LIBSTDCXX = 1,
> + USE_LIBCXX = 2
> +};
> +
> +#define DEFAULT_DIALECT "pim"
> +#undef DEBUG_ARG
> +
> +typedef enum { iso, pim, min, logitech, pimcoroutine, maxlib } libs;
> +
> +/* These are the library names which are installed as part of gm2 and reflect
> + -flibs=name. The -flibs= option provides the user with a short cut to add
> + libraries without having to know the include and link path. */
> +
> +static const char *library_name[maxlib]
> + = { "m2iso", "m2pim", "m2min", "m2log", "m2cor" };
> +
> +/* They match the installed archive name for example libm2iso.a,
> + libm2pim.a, libm2min.a, libm2log.a and libm2cor.a. They also match a
> + subdirectory name where the definition modules are kept. The driver
> + checks the argument to -flibs= for an entry in library_name or
> + alternatively the existance of the subdirectory (to allow for third
> + party libraries to coexist). */
> +
> +static const char *library_abbrev[maxlib]
> + = { "iso", "pim", "min", "log", "cor" };
> +
> +/* Users may specifiy -flibs=pim,iso etc which are mapped onto
> + -flibs=m2pim,m2iso respectively. This provides a match between
> + the dialect of Modula-2 and the library set. */
> +
> +static const char *add_include (const char *libpath, const char *library);
> +
> +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_gen_module_list = false;
> +static bool seen_uselist = false;
> +static bool uselist = false;
> +static bool gen_module_list = true; // Default uses -fgen-module-list=-.
> +static const char *gen_module_filename = "-";
> +static const char *multilib_dir = NULL;
> +/* The original argument list and related info is copied here. */
> +static unsigned int gm2_xargc;
> +static const struct cl_decoded_option *gm2_x_decoded_options;
> +static void append_arg (const struct cl_decoded_option *);
> +
> +/* The new argument list will be built here. */
> +static unsigned int gm2_newargc;
> +static struct cl_decoded_option *gm2_new_decoded_options;
> +
> +
> +/* Return whether strings S1 and S2 are both NULL or both the same
> + string. */
> +
> +static bool
> +strings_same (const char *s1, const char *s2)
> +{
> + return s1 == s2 || (s1 != NULL && s2 != NULL && strcmp (s1, s2) == 0);
> +}
> +
> +bool
> +options_same (const struct cl_decoded_option *opt1,
> + const struct cl_decoded_option *opt2)
> +{
> + return (opt1->opt_index == opt2->opt_index
> + && strings_same (opt1->arg, opt2->arg)
> + && strings_same (opt1->orig_option_with_args_text,
> + opt2->orig_option_with_args_text)
> + && strings_same (opt1->canonical_option[0],
> + opt2->canonical_option[0])
> + && strings_same (opt1->canonical_option[1],
> + opt2->canonical_option[1])
> + && strings_same (opt1->canonical_option[2],
> + opt2->canonical_option[2])
> + && strings_same (opt1->canonical_option[3],
> + opt2->canonical_option[3])
> + && (opt1->canonical_option_num_elements
> + == opt2->canonical_option_num_elements)
> + && opt1->value == opt2->value
> + && opt1->errors == opt2->errors);
> +}
> +
> +/* Append another argument to the list being built. */
> +
> +static void
> +append_arg (const struct cl_decoded_option *arg)
> +{
> + static unsigned int newargsize;
> +
> + if (gm2_new_decoded_options == gm2_x_decoded_options
> + && gm2_newargc < gm2_xargc
> + && options_same (arg, &gm2_x_decoded_options[gm2_newargc]))
> + {
> + ++gm2_newargc;
> + return; /* Nothing new here. */
> + }
> +
> + if (gm2_new_decoded_options == gm2_x_decoded_options)
> + { /* Make new arglist. */
> + unsigned int i;
> +
> + newargsize = (gm2_xargc << 2) + 20; /* This should handle all. */
> + gm2_new_decoded_options = XNEWVEC (struct cl_decoded_option, newargsize);
> +
> + /* Copy what has been done so far. */
> + for (i = 0; i < gm2_newargc; ++i)
> + gm2_new_decoded_options[i] = gm2_x_decoded_options[i];
> + }
> +
> + if (gm2_newargc == newargsize)
> + fatal_error (input_location, "overflowed output argument list for %qs",
> + arg->orig_option_with_args_text);
> +
> + gm2_new_decoded_options[gm2_newargc++] = *arg;
> +}
> +
> +/* Append an option described by OPT_INDEX, ARG and VALUE to the list
> + being built. */
> +
> +static void
> +append_option (size_t opt_index, const char *arg, int value)
> +{
> + struct cl_decoded_option decoded;
> +
> + generate_option (opt_index, arg, value, CL_DRIVER, &decoded);
> + append_arg (&decoded);
> +}
> +
> +/* build_archive_path returns a string containing the path to the
> + archive defined by libpath and dialectLib. */
> +
> +static const char *
> +build_archive_path (const char *libpath, const char *library)
> +{
> + if (library != NULL)
> + {
> + const char *libdir = (const char *)library;
> +
> + if (libdir != NULL)
> + {
> + int machine_length = 0;
> + char dir_sep[2];
> +
> + dir_sep[0] = DIR_SEPARATOR;
> + dir_sep[1] = (char)0;
> +
> + if (multilib_dir != NULL)
> + {
> + machine_length = strlen (multilib_dir);
> + machine_length += strlen (dir_sep);
> + }
> +
> + int l = strlen (libpath) + 1 + strlen ("m2") + 1
> + + strlen (libdir) + 1 + machine_length + 1;
> + char *s = (char *)xmalloc (l);
> +
> + strcpy (s, libpath);
> + strcat (s, dir_sep);
> + if (machine_length > 0)
> + {
> + strcat (s, multilib_dir);
> + strcat (s, dir_sep);
> + }
> + strcat (s, "m2");
> + strcat (s, dir_sep);
> + strcat (s, libdir);
> + return s;
> + }
> + }
> + return NULL;
> +}
> +
> +/* safe_strdup safely duplicates a string. */
> +
> +static char *
> +safe_strdup (const char *s)
> +{
> + if (s != NULL)
> + return xstrdup (s);
> + return NULL;
> +}
> +
> +/* add_default_combination adds the correct link path and then the
> + library name. */
> +
> +static bool
> +add_default_combination (const char *libpath, const char *library)
> +{
> + if (library != NULL)
> + {
> + append_option (OPT_L, build_archive_path (libpath, library), 1);
> + append_option (OPT_l, safe_strdup (library), 1);
> + return true;
> + }
> + return false;
> +}
> +
> +/* add_default_archives adds the default archives to the end of the
> + current command line. */
> +
> +static int
> +add_default_archives (const char *libpath, const char *libraries)
> +{
> + const char *l = libraries;
> + const char *e;
> + char *libname;
> + unsigned int libcount = 0;
> +
> + do
> + {
> + e = index (l, ',');
> + if (e == NULL)
> + {
> + libname = xstrdup (l);
> + l = NULL;
> + if (add_default_combination (libpath, libname))
> + libcount++;
> + free (libname);
> + }
> + else
> + {
> + libname = xstrndup (l, e - l);
> + l = e + 1;
> + if (add_default_combination (libpath, libname))
> + libcount++;
> + free (libname);
> + }
> + }
> + while ((l != NULL) && (l[0] != (char)0));
> + return libcount;
> +}
> +
> +/* build_include_path builds the component of the include path
> + referenced by the library. */
> +
> +static const char *
> +build_include_path (const char *libpath, const char *library)
> +{
> + char dir_sep[2];
> + char *gm2libs;
> + unsigned int machine_length = 0;
> +
> + dir_sep[0] = DIR_SEPARATOR;
> + dir_sep[1] = (char)0;
> +
> + if (multilib_dir != NULL)
> + {
> + machine_length = strlen (multilib_dir);
> + machine_length += strlen (dir_sep);
> + }
> +
> + gm2libs = (char *)alloca (strlen (libpath) + strlen (dir_sep) + strlen ("m2")
> + + strlen (dir_sep) + strlen (library) + 1
> + + machine_length + 1);
> + strcpy (gm2libs, libpath);
> + strcat (gm2libs, dir_sep);
> + if (machine_length > 0)
> + {
> + strcat (gm2libs, multilib_dir);
> + strcat (gm2libs, dir_sep);
> + }
> + strcat (gm2libs, "m2");
> + strcat (gm2libs, dir_sep);
> + strcat (gm2libs, library);
> +
> + return xstrdup (gm2libs);
> +}
> +
> +/* add_include add the correct include path given the libpath and
> + library. The new path is returned. */
> +
> +static const char *
> +add_include (const char *libpath, const char *library)
> +{
> + if (library == NULL)
> + return NULL;
> + else
> + return build_include_path (libpath, library);
> +}
> +
> +/* add_default_includes add the appropriate default include paths
> + depending upon the style of libraries chosen. */
> +
> +static void
> +add_default_includes (const char *libpath, const char *libraries)
> +{
> + const char *l = libraries;
> + const char *e;
> + const char *c;
> + const char *path;
> +
> + do
> + {
> + e = index (l, ',');
> + if (e == NULL)
> + {
> + c = xstrdup (l);
> + l = NULL;
> + }
> + else
> + {
> + c = xstrndup (l, e - l);
> + l = e + 1;
> + }
> + path = add_include (libpath, c);
> + append_option (OPT_I, path, 1);
> + }
> + while ((l != NULL) && (l[0] != (char)0));
> +}
> +
> +/* library_installed returns true if directory library is found under
> + libpath. */
> +
> +static bool
> +library_installed (const char *libpath, const char *library)
> +{
> +#if defined(HAVE_OPENDIR) && defined(HAVE_DIRENT_H)
> + const char *complete = build_archive_path (libpath, library);
> + DIR *directory = opendir (complete);
> +
> + if (directory == NULL || (errno == ENOENT))
> + return false;
> + /* Directory exists and therefore the library also exists. */
> + closedir (directory);
> + return true;
> +#else
> + return false;
> +#endif
> +}
> +
> +/* check_valid check to see that the library is valid.
> + It check the library against the default library set in gm2 and
> + also against any additional libraries installed in the prefix tree. */
> +
> +static bool
> +check_valid_library (const char *libpath, const char *library)
> +{
> + /* Firstly check against the default libraries (which might not be
> + installed yet). */
> + for (int i = 0; i < maxlib; i++)
> + if (strcmp (library, library_name[i]) == 0)
> + return true;
> + /* Secondly check whether it is installed (a third party library). */
> + return library_installed (libpath, library);
> +}
> +
> +/* check_valid_list check to see that the libraries specified are valid.
> + It checks against the default library set in gm2 and also against
> + any additional libraries installed in the libpath tree. */
> +
> +static bool
> +check_valid_list (const char *libpath, const char *libraries)
> +{
> + const char *start = libraries;
> + const char *end;
> + const char *copy;
> +
> + do
> + {
> + end = index (start, ',');
> + if (end == NULL)
> + {
> + copy = xstrdup (start);
> + start = NULL;
> + }
> + else
> + {
> + copy = xstrndup (start, end - start);
> + start = end + 1;
> + }
> + if (! check_valid_library (libpath, copy))
> + {
> + error ("library specified %sq is either not installed or does not exist",
> + copy);
> + return false;
> + }
> + }
> + while ((start != NULL) && (start[0] != (char)0));
> + return true;
> +}
> +
> +/* add_word returns a new string which has the contents of lib
> + appended to list. If list is NULL then lib is duplicated and
> + returned otherwise the list is appended by "," and the contents of
> + lib. */
> +
> +static const char *
> +add_word (const char *list, const char *lib)
> +{
> + char *copy;
> + if (list == NULL)
> + return xstrdup (lib);
> + copy = (char *) xmalloc (strlen (list) + strlen (lib) + 1 + 1);
> + strcpy (copy, list);
> + strcat (copy, ",");
> + strcat (copy, lib);
> + return copy;
> +}
> +
> +/* convert_abbreviation checks abbreviation against known library
> + abbreviations. If an abbreviation is found it converts the element
> + to the full library name, otherwise the user supplied name is added
> + to the full_libraries list. A new string is returned. */
> +
> +static const char *
> +convert_abbreviation (const char *full_libraries, const char *abbreviation)
> +{
> + for (int i = 0; i < maxlib; i++)
> + if (strcmp (abbreviation, library_abbrev[i]) == 0)
> + return add_word (full_libraries, library_name[i]);
> + /* No abbreviation found therefore assume user specified full library name. */
> + return add_word (full_libraries, abbreviation);
> +}
> +
> +/* convert_abbreviations checks each element in the library list to
> + see if an a known library abbreviation was used. If found it
> + converts the element to the full library name, otherwise the
> + element is copied into the list. A new string is returned. */
> +
> +static const char *
> +convert_abbreviations (const char *libraries)
> +{
> + const char *start = libraries;
> + const char *end;
> + const char *full_libraries = NULL;
> +
> + do
> + {
> + end = index (start, ',');
> + if (end == NULL)
> + {
> + full_libraries = convert_abbreviation (full_libraries, start);
> + start = NULL;
> + }
> + else
> + {
> + full_libraries = convert_abbreviation (full_libraries, xstrndup (start, end - start));
> + start = end + 1;
> + }
> + }
> + while ((start != NULL) && (start[0] != (char)0));
> + return full_libraries;
> +}
> +
> +
> +void
> +lang_specific_driver (struct cl_decoded_option **in_decoded_options,
> + unsigned int *in_decoded_options_count,
> + int *in_added_libraries)
> +{
> + unsigned int argc = *in_decoded_options_count;
> + struct cl_decoded_option *decoded_options = *in_decoded_options;
> + unsigned int i;
> +
> + /* True if we saw a `-xfoo' language specification on the command
> + line. This function will add a -xmodula-2 if the user has not
> + already placed one onto the command line. */
> + bool seen_x_flag = false;
> + const char *language = NULL;
> +
> + /* If nonzero, the user gave us the `-p' or `-pg' flag. */
> + int saw_profile_flag = 0;
> +
> + /* What action to take for the c++ runtime library:
> + -1 means we should not link it in.
> + 0 means we should link it if it is needed.
> + 1 means it is needed and should be linked in.
> + 2 means it is needed but should be linked statically. */
> + int library = 0;
> +
> + /* Which c++ runtime library to link. */
> + stdcxxlib_kind which_library = USE_LIBSTDCXX;
> +
> + const char *libraries = NULL;
> + const char *dialect = DEFAULT_DIALECT;
> + const char *libpath = LIBSUBDIR;
> +
> + /* An array used to flag each argument that needs a bit set for
> + LANGSPEC, MATHLIB, or WITHLIBC. */
> + int *args;
> +
> + /* Have we seen -fmod=? */
> + bool seen_module_extension = false;
> +
> + /* Should the driver perform a link? */
> + bool linking = true;
> +
> + /* "-lm" or "-lmath" if it appears on the command line. */
> + const struct cl_decoded_option *saw_math = NULL;
> +
> + /* "-lc" if it appears on the command line. */
> + const struct cl_decoded_option *saw_libc = NULL;
> +
> + /* By default, we throw on the math library if we have one. */
> + int need_math = (MATH_LIBRARY[0] != '\0');
> +
> + /* 1 if we should add -lpthread to the command-line. */
> + int need_pthread = 1;
> +
> + /* True if we saw -static. */
> + int static_link = 0;
> +
> + /* True if we should add -shared-libgcc to the command-line. */
> + int shared_libgcc = 1;
> +
> + /* Have we seen the -v flag? */
> + bool verbose = false;
> +
> + /* The number of libraries added in. */
> + int added_libraries;
> +
> + /* True if we should add -fplugin=m2rte to the command-line. */
> + bool need_plugin = true;
> +
> + /* True if we should set up include paths and library paths. */
> + bool allow_libraries = true;
> +
> +#if defined(DEBUG_ARG)
> + printf ("argc = %d\n", argc);
> + fprintf (stderr, "Incoming:");
> + for (i = 0; i < argc; i++)
> + fprintf (stderr, " %s", decoded_options[i].orig_option_with_args_text);
> + fprintf (stderr, "\n");
> +#endif
> +
> + gm2_xargc = argc;
> + gm2_x_decoded_options = decoded_options;
> + gm2_newargc = 0;
> + gm2_new_decoded_options = decoded_options;
> + added_libraries = *in_added_libraries;
> + args = XCNEWVEC (int, argc);
> +
> + /* First pass through arglist.
> +
> + If -nostdlib or a "turn-off-linking" option is anywhere in the
> + command line, don't do any library-option processing (except
> + relating to -x). */
> +
> + for (i = 1; i < argc; i++)
> + {
> + const char *arg = decoded_options[i].arg;
> + args[i] = 0;
> +#if defined(DEBUG_ARG)
> + printf ("1st pass: %s\n",
> + decoded_options[i].orig_option_with_args_text);
> +#endif
> + switch (decoded_options[i].opt_index)
> + {
> + case OPT_fiso:
> + dialect = "iso";
> + break;
> + case OPT_fpim2:
> + dialect = "pim2";
> + break;
> + case OPT_fpim3:
> + dialect = "pim3";
> + break;
> + case OPT_fpim4:
> + dialect = "pim4";
> + break;
> + case OPT_fpim:
> + dialect = "pim";
> + break;
> + case OPT_flibs_:
> + libraries = xstrdup (arg);
> + allow_libraries = decoded_options[i].value;
> + break;
> + case OPT_fmod_:
> + seen_module_extension = true;
> + break;
> + case OPT_fpthread:
> + need_pthread = decoded_options[i].value;
> + break;
> + case OPT_fm2_plugin:
> + need_plugin = decoded_options[i].value;
> + break;
> + case OPT_fscaffold_dynamic:
> + seen_scaffold_dynamic = true;
> + scaffold_dynamic = decoded_options[i].value;
> + break;
> + case OPT_fscaffold_static:
> + seen_scaffold_static = true;
> + scaffold_static = decoded_options[i].value;
> + break;
> + case OPT_fgen_module_list_:
> + seen_gen_module_list = true;
> + gen_module_list = decoded_options[i].value;
> + if (gen_module_list)
> + gen_module_filename = decoded_options[i].arg;
> + break;
> + case OPT_fuse_list_:
> + seen_uselist = true;
> + uselist = decoded_options[i].value;
> + break;
> +
> + case OPT_nostdlib:
> + case OPT_nostdlib__:
> + case OPT_nodefaultlibs:
> + library = -1;
> + break;
> +
> + case OPT_l:
> + if (strcmp (arg, MATH_LIBRARY) == 0)
> + {
> + args[i] |= MATHLIB;
> + need_math = 0;
> + }
> + else if (strcmp (arg, "c") == 0)
> + args[i] |= WITHLIBC;
> + else
> + /* Unrecognized libraries (e.g. -lfoo) may require libstdc++. */
> + library = (library == 0) ? 1 : library;
> + break;
> +
> + case OPT_pg:
> + case OPT_p:
> + saw_profile_flag++;
> + break;
> +
> + case OPT_x:
> + seen_x_flag = true;
> + language = arg;
> + break;
> +
> + case OPT_v:
> + verbose = true;
> + break;
> +
> + case OPT_Xlinker:
> + case OPT_Wl_:
> + /* Arguments that go directly to the linker might be .o files,
> + or something, and so might cause libstdc++ to be needed. */
> + if (library == 0)
> + library = 1;
> + break;
> +
> + case OPT_c:
> + case OPT_r:
> + case OPT_S:
> + case OPT_E:
> + case OPT_M:
> + case OPT_MM:
> + case OPT_fsyntax_only:
> + /* Don't specify libraries if we won't link, since that would
> + cause a warning. */
> + linking = false;
> + library = -1;
> + break;
> +
> + case OPT_static:
> + static_link = 1;
> + break;
> +
> + case OPT_static_libgcc:
> + shared_libgcc = 0;
> + break;
> +
> + case OPT_static_libstdc__:
> + library = library >= 0 ? 2 : library;
> + args[i] |= SKIPOPT;
> + break;
> +
> + case OPT_stdlib_:
> + which_library = (stdcxxlib_kind) decoded_options[i].value;
> + break;
> +
> + default:
> + if ((decoded_options[i].orig_option_with_args_text != NULL)
> + && (strncmp (decoded_options[i].orig_option_with_args_text,
> + "-m", 2) == 0))
> + multilib_dir = xstrdup (decoded_options[i].orig_option_with_args_text
> + + 2);
> + }
> + }
> + if (language != NULL && (strcmp (language, "modula-2") != 0))
> + return;
> +
> + 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");
> + }
> + if (uselist && gen_module_list)
> + {
> + if (! seen_gen_module_list)
> + gen_module_list = false;
> + if (uselist && gen_module_list)
> + error ("%qs and %qs cannot both be enabled",
> + "-fgen-module-list=", "-fuse-list=");
> + }
> +
> +
> + /* There's no point adding -shared-libgcc if we don't have a shared
> + libgcc. */
> +#ifndef ENABLE_SHARED_LIBGCC
> + shared_libgcc = 0;
> +#endif
> +
> + /* Second pass through arglist, transforming arguments as appropriate. */
> +
> + append_arg (&decoded_options[0]); /* Start with command name, of course. */
> + for (i = 1; i < argc; ++i)
> + {
> +#if defined(DEBUG_ARG)
> + printf ("2nd pass: %s\n",
> + decoded_options[i].orig_option_with_args_text);
> +#endif
> + if ((args[i] & SKIPOPT) == 0)
> + {
> + append_arg (&decoded_options[i]);
> + /* Make sure -lstdc++ is before the math library, since libstdc++
> + itself uses those math routines. */
> + if (!saw_math && (args[i] & MATHLIB) && library > 0)
> + saw_math = &decoded_options[i];
> +
> + if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
> + saw_libc = &decoded_options[i];
> + }
> +#if defined(DEBUG_ARG)
> + else
> + printf ("skipping: %s\n",
> + decoded_options[i].orig_option_with_args_text);
> +#endif
> + }
> +
> + /* We now add in extra arguments to facilitate a successful
> + compile or link. For example include paths for dialect of Modula-2,
> + library paths and default scaffold linking options. */
> +
> + /* If we have not seen either uselist or gen_module_list and we need
> + to link then we turn on -fgen_module_list=- as the default. */
> + if ((! (seen_uselist || seen_gen_module_list)) && linking)
> + append_option (OPT_fgen_module_list_, "-", 1);
> +
> + if (allow_libraries)
> + {
> + /* If the libraries have not been specified by the user but the
> + dialect has been specified then select the appropriate libraries. */
> + if (libraries == NULL)
> + {
> + if (strcmp (dialect, "iso") == 0)
> + libraries = xstrdup ("m2iso,m2pim");
> + else
> + /* Default to pim libraries if none specified. */
> + libraries = xstrdup ("m2pim,m2log,m2iso");
> + }
> + libraries = convert_abbreviations (libraries);
> + if (! check_valid_list (libpath, libraries))
> + return;
> + add_default_includes (libpath, libraries);
> + }
> + if ((! seen_x_flag) && seen_module_extension)
> + append_option (OPT_x, "modula-2", 1);
> +
> + if (need_plugin)
> + append_option (OPT_fplugin_, "m2rte", 1);
> +
> + if (linking)
> + {
> + if (allow_libraries)
> + add_default_archives (libpath, libraries);
> + /* Add `-lstdc++' if we haven't already done so. */
> +#ifdef HAVE_LD_STATIC_DYNAMIC
> + if (library > 1 && !static_link)
> + append_option (OPT_Wl_, LD_STATIC_OPTION, 1);
> +#endif
> + if (which_library == USE_LIBCXX)
> + {
> + append_option (OPT_l, saw_profile_flag ? LIBCXX_PROFILE : LIBCXX, 1);
> + added_libraries++;
> + if (LIBCXXABI != NULL)
> + {
> + append_option (OPT_l, saw_profile_flag ? LIBCXXABI_PROFILE
> + : LIBCXXABI, 1);
> + added_libraries++;
> + }
> + }
> + else
> + {
> + append_option (OPT_l, saw_profile_flag ? LIBSTDCXX_PROFILE
> + : LIBSTDCXX, 1);
> + added_libraries++;
> + }
> + /* Add target-dependent static library, if necessary. */
> + if ((static_link || library > 1) && LIBSTDCXX_STATIC != NULL)
> + {
> + append_option (OPT_l, LIBSTDCXX_STATIC, 1);
> + added_libraries++;
> + }
> +#ifdef HAVE_LD_STATIC_DYNAMIC
> + if (library > 1 && !static_link)
> + append_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1);
> +#endif
> + }
> + if (need_math)
> + {
> + append_option (OPT_l, saw_profile_flag ? MATH_LIBRARY_PROFILE :
> + MATH_LIBRARY, 1);
> + added_libraries++;
> + }
> + if (need_pthread)
> + {
> + append_option (OPT_l, "pthread", 1);
> + added_libraries++;
> + }
> + if (shared_libgcc && !static_link)
> + append_option (OPT_shared_libgcc, NULL, 1);
It feels like most of the above would usually be handled via lang specific
specs rather than open-coded in the driver? Is there a specific reason you
opted for explicit handling here?
Otherwise the patch looks generally OK, the string builds using strcat & friends
looks like it neither takes advantage of how obstacks can be used there nor
that we're now C++ and could use std::string - but that's a matter of taste and
no objection.
Thanks,
Richard.
> + if (verbose && gm2_new_decoded_options != gm2_x_decoded_options)
> + {
> + fprintf (stderr, _("Driving:"));
> + for (i = 0; i < gm2_newargc; i++)
> + fprintf (stderr, " %s",
> + gm2_new_decoded_options[i].orig_option_with_args_text);
> + fprintf (stderr, "\n");
> + fprintf (stderr, "new argc = %d, added_libraries = %d\n",
> + gm2_newargc, added_libraries);
> + }
> +
> + *in_decoded_options_count = gm2_newargc;
> + *in_decoded_options = gm2_new_decoded_options;
> + *in_added_libraries = added_libraries;
> +}
> +
> +/* Called before linking. Returns 0 on success and -1 on failure. */
> +int
> +lang_specific_pre_link (void) /* Not used for M2. */
> +{
> + return 0;
> +}
> +
> +/* Number of extra output files that lang_specific_pre_link may generate. */
> +int lang_specific_extra_outfiles = 0;
> diff -ruw /dev/null gcc-git-devel-modula2/gcc/m2/lang.opt
> --- /dev/null 2022-08-24 16:22:16.888000070 +0100
> +++ gcc-git-devel-modula2/gcc/m2/lang.opt 2022-10-07 20:21:18.662097087 +0100
> @@ -0,0 +1,356 @@
> +; Options for the Modula-2 front end.
> +;
> +; Copyright (C) 2016-2022 Free Software Foundation, Inc.
> +; Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
> +;
> +; This file is part of GNU Modula-2.
> +;
> +; GNU Modula-2 is free software; you can redistribute it and/or modify
> +; it under the terms of the GNU General Public License as published by
> +; the Free Software Foundation; either version 3, or (at your option)
> +; any later version.
> +;
> +; GNU Modula-2 is distributed in the hope that it will be useful, but
> +; WITHOUT ANY WARRANTY; without even the implied warranty of
> +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> +; General Public License for more details.
> +;
> +; You should have received a copy of the GNU General Public License
> +; along with GNU Modula-2; see the file COPYING. If not,
> +; see <https://www.gnu.org/licenses/>. *)
> +
> +; See the GCC internals manual for a description of this file's format.
> +
> +; Please try to keep this file in ASCII collating order.
> +
> +Language
> +Modula-2
> +
> +B
> +Modula-2
> +; Documented in c.opt
> +
> +D
> +Modula-2
> +; Documented in c.opt
> +
> +E
> +Modula-2
> +; Documented in c.opt (passed to the preprocessor if -fcpp is used)
> +
> +I
> +Modula-2 Joined Separate
> +; Documented in c.opt
> +
> +L
> +Modula-2 Joined Separate
> +; Not documented
> +
> +M
> +Modula-2
> +; Documented in c.opt
> +
> +O
> +Modula-2
> +; Documented in c.opt
> +
> +Wall
> +Modula-2
> +; Documented in c.opt
> +
> +Wpedantic
> +Modula-2
> +; Documented in common.opt
> +
> +Wpedantic-param-names
> +Modula-2
> +compiler checks to force definition module procedure parameter names with their implementation module counterpart
> +
> +Wpedantic-cast
> +Modula-2
> +compiler warns if a cast is being used on types of differing sizes
> +
> +Wverbose-unbounded
> +Modula-2
> +inform user which parameters will be passed by reference
> +
> +Wstyle
> +Modula-2
> +extra compile time semantic checking, typically tries to catch poor programming style
> +
> +Wunused-variable
> +Modula-2
> +; Documented in c.opt
> +
> +Wunused-parameter
> +Modula-2
> +; Documented in c.opt
> +
> +c
> +Modula-2
> +; Documented in c.opt
> +
> +fauto-init
> +Modula-2
> +automatically initializes all pointers to NIL
> +
> +fbounds
> +Modula-2
> +turns on runtime subrange, array index and indirection via NIL pointer checking
> +
> +fcase
> +Modula-2
> +turns on runtime checking to check whether a CASE statement requires an ELSE clause when on was not specified
> +
> +fobjc-std=objc1
> +Modula-2
> +; Documented in c.opt
> +
> +fcpp
> +Modula-2
> +use cpp to preprocess the module
> +
> +fcpp-end
> +Modula-2
> +passed to the preprocessor if -fcpp is used (internal switch)
> +
> +fcpp-begin
> +Modula-2
> +passed to the preprocessor if -fcpp is used (internal switch)
> +
> +fdebug-builtins
> +Modula-2
> +call a real function, rather than the builtin equivalent
> +
> +fdump-system-exports
> +Modula-2
> +display all inbuilt system items
> +
> +fd
> +Modula-2
> +turn on internal debugging of the compiler
> +
> +fdebug-trace-quad
> +Modula-2
> +turn on quadruple tracing (internal switch)
> +
> +fdebug-trace-api
> +Modula-2
> +turn on the Modula-2 api tracing (internal switch)
> +
> +fdebug-function-line-numbers
> +Modula-2
> +turn on the Modula-2 function line number generation (internal switch)
> +
> +fdef=
> +Modula-2 Joined
> +recognise the specified suffix as a definition module filename
> +
> +fexceptions
> +Modula-2
> +; Documented in common.opt
> +
> +fextended-opaque
> +Modula-2
> +allows opaque types to be implemented as any type (a GNU Modula-2 extension)
> +
> +ffloatvalue
> +Modula-2
> +turns on runtime checking to check whether a floating point number is about to exceed range
> +
> +fgen-module-list=
> +Modula-2 Joined
> +create a topologically sorted module list from all dependent modules used in the application
> +
> +findex
> +Modula-2
> +turns on all range checking for numerical values
> +
> +fiso
> +Modula-2
> +use ISO dialect of Modula-2
> +
> +flibs=
> +Modula-2 Joined
> +specify the library order, currently legal entries include: log, min, pim, iso or their directory name equivalent m2log, m2min, m2pim, m2iso.
> +
> +flocation=
> +Modula-2 Joined
> +set all location values to a specific value (internal switch)
> +
> +fm2-g
> +Modula-2
> +generate extra nops to improve debugging, producing an instruction for every code related keyword
> +
> +fm2-lower-case
> +Modula-2
> +generate error messages which render keywords in lower case
> +
> +fm2-plugin
> +Modula-2
> +insert plugin to identify runtime errors at compiletime (default on)
> +
> +fm2-statistics
> +Modula-2
> +display statistics about the amount of source lines compiled and symbols used
> +
> +fm2-strict-type
> +Modula-2
> +experimental flag to turn on the new strict type checker
> +
> +fm2-whole-program
> +Modula-2
> +compile all implementation modules and program module at once
> +
> +fmod=
> +Modula-2 Joined
> +recognise the specified suffix as implementation and module filenames
> +
> +fnil
> +Modula-2
> +turns on runtime checking to detect accessing data through a NIL value pointer
> +
> +fpim
> +Modula-2
> +use PIM [234] dialect of Modula-2
> +
> +fpim2
> +Modula-2
> +use PIM 2 dialect of Modula-2
> +
> +fpim3
> +Modula-2
> +use PIM 3 dialect of Modula-2
> +
> +fpim4
> +Modula-2
> +use PIM 4 dialect of Modula-2
> +
> +fpositive-mod-floor-div
> +Modula-2
> +force positive result from MOD and DIV result floor
> +
> +fpthread
> +Modula-2
> +link against the pthread library (default on)
> +
> +fq
> +Modula-2
> +internal compiler debugging information, dump the list of quadruples
> +
> +frange
> +Modula-2
> +turns on all range checking for numerical values
> +
> +freturn
> +Modula-2
> +turns on runtime checking for functions which finish without executing a RETURN statement
> +
> +fruntime-modules=
> +Modula-2 Joined
> +specify the list of runtime modules and their initialization order
> +
> +fscaffold-static
> +Modula-2
> +generate static scaffold initialization and finalization for every module inside main
> +
> +fscaffold-dynamic
> +Modula-2
> +the modules initialization order is dynamically determined by M2RTS and application dependancies
> +
> +fscaffold-c
> +Modula-2
> +generate a C source scaffold for the current module being compiled
> +
> +fscaffold-c++
> +Modula-2
> +generate a C++ source scaffold for the current module being compiled
> +
> +fscaffold-main
> +Modula-2
> +generate the main function
> +
> +fshared
> +Modula-2
> +generate a shared library from the module
> +
> +fsoft-check-all
> +Modula-2
> +turns on all software runtime checking (an abbreviation for -fnil -frange -findex -fwholediv -fcase -freturn -fwholediv -ffloatvalue)
> +
> +fsources
> +Modula-2
> +display the location of module source files as they are compiled
> +
> +fswig
> +Modula-2
> +create a swig interface file for the module
> +
> +funbounded-by-reference
> +Modula-2
> +optimize non var unbounded parameters by passing it by reference, providing it is not written to within the callee procedure.
> +
> +fuse-list=
> +Modula-2 Joined
> +orders the initialization/finalializations for scaffold-static or force linking of modules if scaffold-dynamic
> +
> +fversion
> +Modula-2
> +; Documented in common.opt
> +
> +fwholediv
> +Modula-2
> +turns on all division and modulus by zero checking for ordinal values
> +
> +fwholevalue
> +Modula-2
> +turns on runtime checking to check whether a whole number is about to exceed range
> +
> +fxcode
> +Modula-2
> +issue all errors and warnings in the Xcode format
> +
> +iprefix
> +Modula-2
> +; Documented in c.opt
> +
> +isystem
> +Modula-2
> +; Documented in c.opt
> +
> +idirafter
> +Modula-2
> +; Documented in c.opt
> +
> +imultilib
> +Modula-2
> +; Documented in c.opt
> +
> +lang-asm
> +Modula-2
> +; Documented in c.opt
> +
> +-save-temps
> +Modula-2 Alias(save-temps)
> +
> +save-temps
> +Modula-2
> +save temporary preprocessed files
> +
> +save-temps=
> +Modula-2 Joined
> +save temporary preprocessed files
> +
> +traditional-cpp
> +Modula-2
> +; Documented in c.opt
> +
> +v
> +Modula-2
> +; Documented in c.opt
> +
> +x
> +Modula-2 Joined
> +specify the language from the compiler driver
> +
> +; This comment is to ensure we retain the blank line above.
> diff -ruw /dev/null gcc-git-devel-modula2/gcc/m2/lang-specs.h
> --- /dev/null 2022-08-24 16:22:16.888000070 +0100
> +++ gcc-git-devel-modula2/gcc/m2/lang-specs.h 2022-10-07 20:21:18.662097087 +0100
> @@ -0,0 +1,38 @@
> +/* Definitions for specs for GNU Modula-2.
> + Copyright (C) 2001-2022 Free Software Foundation, Inc.
> + Contributed by Gaius Mulley.
> +
> +This file is part of GCC.
> +
> +GCC is free software; you can redistribute it and/or modify
> +it under the terms of the GNU General Public License as published by
> +the Free Software Foundation; either version 3, or (at your option)
> +any later version.
> +
> +GCC is distributed in the hope that it will be useful,
> +but WITHOUT ANY WARRANTY; without even the implied warranty of
> +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +GNU General Public License for more details.
> +
> +You should have received a copy of the GNU General Public License
> +along with GCC; see the file COPYING3. If not see
> +<http://www.gnu.org/licenses/>. */
> +
> +/* This is the contribution to the `default_compilers' array in gcc.c for
> + GNU Modula-2. */
> +
> +/* Pass the preprocessor options on the command line together with
> + the exec prefix. */
> +
> +#define M2CPP "%{fcpp:-fcpp-begin " \
> + " -E -lang-asm -traditional-cpp " \
> + " %(cpp_unique_options) -fcpp-end}"
> +
> + {".mod", "@modula-2", 0, 0, 0},
> + {"@modula-2",
> + "cc1gm2 " M2CPP
> + " %(cc1_options) %{B*} %{c*} %{f*} %{+e*} %{I*} "
> + " %{MD} %{MMD} %{M} %{MM} %{MA} %{MT*} %{MF*} %V"
> + " %{save-temps*}"
> + " %i %{!fsyntax-only:%(invoke_as)}",
> + 0, 0, 0},
> diff -ruw /dev/null gcc-git-devel-modula2/gcc/m2/config-lang.in
> --- /dev/null 2022-08-24 16:22:16.888000070 +0100
> +++ gcc-git-devel-modula2/gcc/m2/config-lang.in 2022-10-07 20:21:18.634096743 +0100
> @@ -0,0 +1,83 @@
> +# Top level configure fragment for GNU Modula-2.
> +# Copyright (C) 2000-2022 Free Software Foundation, Inc.
> +
> +# This file is part of GCC.
> +
> +# GCC is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3, or (at your option)
> +# any later version.
> +
> +# GCC is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +
> +# You should have received a copy of the GNU General Public License
> +# along with GCC; see the file COPYING3. If not see
> +# <http://www.gnu.org/licenses/>.
> +
> +# Configure looks for the existence of this file to auto-config each language.
> +# We define several parameters used by configure:
> +#
> +# language - name of language as it would appear in $(LANGUAGES)
> +# compilers - value to add to $(COMPILERS)
> +# stagestuff - files to add to $(STAGESTUFF)
> +
> +language="m2"
> +
> +compilers="cc1gm2\$(exeext)"
> +
> +stagestuff="gm2\$(exeext) cc1gm2\$(exeext) cc1gm2-cross\$(exeext)"
> +
> +target_libs="target-libstdc++-v3 target-libgm2"
> +
> +# The Modula-2 frontend needs C++ compiler during stage 1.
> +lang_requires_boot_languages=c++
> +
> +# Do not build by default.
> +build_by_default="no"
> +
> +gtfiles="\$(srcdir)/m2/gm2-lang.cc \
> + \$(srcdir)/m2/gm2-lang.h \
> + \$(srcdir)/m2/gm2-gcc/rtegraph.cc \
> + \$(srcdir)/m2/gm2-gcc/m2block.cc \
> + \$(srcdir)/m2/gm2-gcc/m2builtins.cc \
> + \$(srcdir)/m2/gm2-gcc/m2decl.cc \
> + \$(srcdir)/m2/gm2-gcc/m2except.cc \
> + \$(srcdir)/m2/gm2-gcc/m2expr.cc \
> + \$(srcdir)/m2/gm2-gcc/m2statement.cc \
> + \$(srcdir)/m2/gm2-gcc/m2type.cc"
> +
> +outputs="m2/config-make \
> + m2/Make-maintainer \
> + "
> +
> +mkdir -p m2/gm2-compiler-boot
> +mkdir -p m2/gm2-libs-boot
> +mkdir -p m2/gm2-ici-boot
> +mkdir -p m2/gm2-libiberty
> +mkdir -p m2/gm2-gcc
> +mkdir -p m2/gm2-compiler
> +mkdir -p m2/gm2-libs
> +mkdir -p m2/gm2-libs-iso
> +mkdir -p m2/gm2-compiler-paranoid
> +mkdir -p m2/gm2-libs-paranoid
> +mkdir -p m2/gm2-compiler-verify
> +mkdir -p m2/boot-bin
> +mkdir -p m2/gm2-libs-pim
> +mkdir -p m2/gm2-libs-coroutines
> +mkdir -p m2/gm2-libs-min
> +mkdir -p m2/pge-boot
> +mkdir -p plugin
> +mkdir -p stage1/m2 stage2/m2 stage3/m2 stage4/m2
> +
> +# directories used by Make-maintainer
> +
> +mkdir -p m2/gm2-auto
> +mkdir -p m2/gm2-pg-boot
> +mkdir -p m2/gm2-pge-boot
> +mkdir -p m2/gm2-ppg-boot
> +mkdir -p m2/mc-boot
> +mkdir -p m2/mc-boot-ch
> +mkdir -p m2/mc-boot-gen
> diff -ruw /dev/null gcc-git-devel-modula2/gcc/m2/config-make.in
> --- /dev/null 2022-08-24 16:22:16.888000070 +0100
> +++ gcc-git-devel-modula2/gcc/m2/config-make.in 2022-10-07 20:21:18.634096743 +0100
> @@ -0,0 +1,2 @@
> +# Target libraries are put under this directory:
> +TARGET_SUBDIR = @target_subdir@
> diff -ruw /dev/null gcc-git-devel-modula2/gcc/m2/configure.ac
> --- /dev/null 2022-08-24 16:22:16.888000070 +0100
> +++ gcc-git-devel-modula2/gcc/m2/configure.ac 2022-10-07 20:21:18.634096743 +0100
> @@ -0,0 +1,43 @@
> +# configure.ac provides gm2spec.c with access to config values.
> +
> +# Copyright (C) 2001-2022 Free Software Foundation, Inc.
> +# Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
> +
> +# GCC is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3, or (at your option)
> +# any later version.
> +
> +# GCC is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +
> +# You should have received a copy of the GNU General Public License
> +# along with GCC; see the file COPYING3. If not see
> +# <http://www.gnu.org/licenses/>.
> +
> +AC_INIT(m2, [ ])
> +
> +# Determine the host, build, and target systems
> +AC_CANONICAL_BUILD
> +AC_CANONICAL_HOST
> +AC_CANONICAL_TARGET
> +
> +AC_CHECK_PROGS(regex_flex, flex)
> +if test x$regex_flex = "x" ; then
> + AC_MSG_ERROR([flex is required to build GNU Modula-2 (hint install flex).])
> +fi
> +
> +AC_CHECK_PROGS(regex_realpath, realpath)
> +if test x$regex_realpath = "x" ; then
> + AC_MSG_ERROR([realpath is required to build GNU Modula-2 (hint install coreutils).])
> +fi
> +
> +AC_CHECK_FUNCS([stpcpy])
> +
> +AC_CHECK_HEADERS(sys/types.h)
> +AC_HEADER_DIRENT
> +AC_CHECK_LIB([c],[opendir],[AC_DEFINE([HAVE_OPENDIR],[1],[found opendir])])
> +AC_CONFIG_HEADERS(gm2config.h, [echo timestamp > stamp-h])
> +AC_OUTPUT
> diff -ruw /dev/null gcc-git-devel-modula2/gcc/m2/gm2config.h.in
> --- /dev/null 2022-08-24 16:22:16.888000070 +0100
> +++ gcc-git-devel-modula2/gcc/m2/gm2config.h.in 2022-10-07 20:21:18.662097087 +0100
> @@ -0,0 +1,56 @@
> +/* gm2config.h.in template file for values required by gm2spec.c.
> +
> +Copyright (C) 2006-2022 Free Software Foundation, Inc.
> +Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
> +
> +This file is part of GNU Modula-2.
> +
> +GNU Modula-2 is free software; you can redistribute it and/or modify
> +it under the terms of the GNU General Public License as published by
> +the Free Software Foundation; either version 3, or (at your option)
> +any later version.
> +
> +GNU Modula-2 is distributed in the hope that it will be useful, but
> +WITHOUT ANY WARRANTY; without even the implied warranty of
> +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> +General Public License for more details.
> +
> +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/>. */
> +
> +#ifndef PACKAGE_BUGREPORT
> +/* Define to the address where bug reports for this package should be sent. */
> +#undef PACKAGE_BUGREPORT
> +#endif
> +
> +#ifndef PACKAGE_NAME
> +/* Define to the full name of this package. */
> +#undef PACKAGE_NAME
> +#endif
> +
> +#ifndef PACKAGE_STRING
> +/* Define to the full name and version of this package. */
> +#undef PACKAGE_STRING
> +#endif
> +
> +/* Define to 1 if you have the `stpcmp' function. */
> +#undef HAVE_STPCMP
> +
> +/* Define to 1 if you have the dirent.h header. */
> +#undef HAVE_DIRENT_H
> +
> +/* Define to 1 if you have the sys/ndir.h header. */
> +#undef HAVE_SYS_NDIR_H
> +
> +/* Define to 1 if you have the sys/dir.h header. */
> +#undef HAVE_SYS_DIR_H
> +
> +/* Define to 1 if you have the ndir.h header. */
> +#undef HAVE_NDIR_H
> +
> +/* Define to 1 if you have the sys/types.h header. */
> +#undef HAVE_SYS_TYPES_H
> +
> +/* Define to 1 if you have the opendir function. */
> +#undef HAVE_OPENDIR
Richard Biener <richard.guenther@gmail.com> writes:
[snip]
> It feels like most of the above would usually be handled via lang specific
> specs rather than open-coded in the driver? Is there a specific reason you
> opted for explicit handling here?
The last time submitting the patches I perhaps went overboard using
lang-specs - and so tried to adopt the style from C++/fortran this time
around. I'm happy to utilize lang-specs to reduce the driver code though.
> Otherwise the patch looks generally OK, the string builds using strcat & friends
> looks like it neither takes advantage of how obstacks can be used there nor
> that we're now C++ and could use std::string - but that's a matter of taste and
> no objection.
ok thanks!
regards,
Gaius
@@ -0,0 +1,937 @@
+/* gm2spec.cc specific flags and argument handling within GNU Modula-2.
+
+Copyright (C) 2007-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 "coretypes.h"
+#include "tm.h"
+#include "xregex.h"
+#include "obstack.h"
+#include "intl.h"
+#include "prefix.h"
+#include "opt-suggestions.h"
+#include "gcc.h"
+#include "opts.h"
+#include "vec.h"
+
+#include "m2/gm2config.h"
+
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#else
+#ifdef HAVE_SYS_NDIR_H
+#include <sys/ndir.h>
+#endif
+#ifdef HAVE_SYS_DIR_H
+#include <sys/dir.h>
+#endif
+#ifdef HAVE_NDIR_H
+#include <ndir.h>
+#endif
+#endif
+
+/* This bit is set if we saw a `-xfoo' language specification. */
+#define LANGSPEC (1<<1)
+/* This bit is set if they did `-lm' or `-lmath'. */
+#define MATHLIB (1<<2)
+/* This bit is set if they did `-lc'. */
+#define WITHLIBC (1<<3)
+/* Skip this option. */
+#define SKIPOPT (1<<4)
+
+#ifndef MATH_LIBRARY
+#define MATH_LIBRARY "m"
+#endif
+#ifndef MATH_LIBRARY_PROFILE
+#define MATH_LIBRARY_PROFILE MATH_LIBRARY
+#endif
+
+#ifndef LIBSTDCXX
+#define LIBSTDCXX "stdc++"
+#endif
+#ifndef LIBSTDCXX_PROFILE
+#define LIBSTDCXX_PROFILE LIBSTDCXX
+#endif
+#ifndef LIBSTDCXX_STATIC
+#define LIBSTDCXX_STATIC NULL
+#endif
+
+#ifndef LIBCXX
+#define LIBCXX "c++"
+#endif
+#ifndef LIBCXX_PROFILE
+#define LIBCXX_PROFILE LIBCXX
+#endif
+#ifndef LIBCXX_STATIC
+#define LIBCXX_STATIC NULL
+#endif
+
+#ifndef LIBCXXABI
+#define LIBCXXABI "c++abi"
+#endif
+#ifndef LIBCXXABI_PROFILE
+#define LIBCXXABI_PROFILE LIBCXXABI
+#endif
+#ifndef LIBCXXABI_STATIC
+#define LIBCXXABI_STATIC NULL
+#endif
+
+/* The values used here must match those of the stdlib_kind enumeration
+ in c.opt. */
+enum stdcxxlib_kind
+{
+ USE_LIBSTDCXX = 1,
+ USE_LIBCXX = 2
+};
+
+#define DEFAULT_DIALECT "pim"
+#undef DEBUG_ARG
+
+typedef enum { iso, pim, min, logitech, pimcoroutine, maxlib } libs;
+
+/* These are the library names which are installed as part of gm2 and reflect
+ -flibs=name. The -flibs= option provides the user with a short cut to add
+ libraries without having to know the include and link path. */
+
+static const char *library_name[maxlib]
+ = { "m2iso", "m2pim", "m2min", "m2log", "m2cor" };
+
+/* They match the installed archive name for example libm2iso.a,
+ libm2pim.a, libm2min.a, libm2log.a and libm2cor.a. They also match a
+ subdirectory name where the definition modules are kept. The driver
+ checks the argument to -flibs= for an entry in library_name or
+ alternatively the existance of the subdirectory (to allow for third
+ party libraries to coexist). */
+
+static const char *library_abbrev[maxlib]
+ = { "iso", "pim", "min", "log", "cor" };
+
+/* Users may specifiy -flibs=pim,iso etc which are mapped onto
+ -flibs=m2pim,m2iso respectively. This provides a match between
+ the dialect of Modula-2 and the library set. */
+
+static const char *add_include (const char *libpath, const char *library);
+
+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_gen_module_list = false;
+static bool seen_uselist = false;
+static bool uselist = false;
+static bool gen_module_list = true; // Default uses -fgen-module-list=-.
+static const char *gen_module_filename = "-";
+static const char *multilib_dir = NULL;
+/* The original argument list and related info is copied here. */
+static unsigned int gm2_xargc;
+static const struct cl_decoded_option *gm2_x_decoded_options;
+static void append_arg (const struct cl_decoded_option *);
+
+/* The new argument list will be built here. */
+static unsigned int gm2_newargc;
+static struct cl_decoded_option *gm2_new_decoded_options;
+
+
+/* Return whether strings S1 and S2 are both NULL or both the same
+ string. */
+
+static bool
+strings_same (const char *s1, const char *s2)
+{
+ return s1 == s2 || (s1 != NULL && s2 != NULL && strcmp (s1, s2) == 0);
+}
+
+bool
+options_same (const struct cl_decoded_option *opt1,
+ const struct cl_decoded_option *opt2)
+{
+ return (opt1->opt_index == opt2->opt_index
+ && strings_same (opt1->arg, opt2->arg)
+ && strings_same (opt1->orig_option_with_args_text,
+ opt2->orig_option_with_args_text)
+ && strings_same (opt1->canonical_option[0],
+ opt2->canonical_option[0])
+ && strings_same (opt1->canonical_option[1],
+ opt2->canonical_option[1])
+ && strings_same (opt1->canonical_option[2],
+ opt2->canonical_option[2])
+ && strings_same (opt1->canonical_option[3],
+ opt2->canonical_option[3])
+ && (opt1->canonical_option_num_elements
+ == opt2->canonical_option_num_elements)
+ && opt1->value == opt2->value
+ && opt1->errors == opt2->errors);
+}
+
+/* Append another argument to the list being built. */
+
+static void
+append_arg (const struct cl_decoded_option *arg)
+{
+ static unsigned int newargsize;
+
+ if (gm2_new_decoded_options == gm2_x_decoded_options
+ && gm2_newargc < gm2_xargc
+ && options_same (arg, &gm2_x_decoded_options[gm2_newargc]))
+ {
+ ++gm2_newargc;
+ return; /* Nothing new here. */
+ }
+
+ if (gm2_new_decoded_options == gm2_x_decoded_options)
+ { /* Make new arglist. */
+ unsigned int i;
+
+ newargsize = (gm2_xargc << 2) + 20; /* This should handle all. */
+ gm2_new_decoded_options = XNEWVEC (struct cl_decoded_option, newargsize);
+
+ /* Copy what has been done so far. */
+ for (i = 0; i < gm2_newargc; ++i)
+ gm2_new_decoded_options[i] = gm2_x_decoded_options[i];
+ }
+
+ if (gm2_newargc == newargsize)
+ fatal_error (input_location, "overflowed output argument list for %qs",
+ arg->orig_option_with_args_text);
+
+ gm2_new_decoded_options[gm2_newargc++] = *arg;
+}
+
+/* Append an option described by OPT_INDEX, ARG and VALUE to the list
+ being built. */
+
+static void
+append_option (size_t opt_index, const char *arg, int value)
+{
+ struct cl_decoded_option decoded;
+
+ generate_option (opt_index, arg, value, CL_DRIVER, &decoded);
+ append_arg (&decoded);
+}
+
+/* build_archive_path returns a string containing the path to the
+ archive defined by libpath and dialectLib. */
+
+static const char *
+build_archive_path (const char *libpath, const char *library)
+{
+ if (library != NULL)
+ {
+ const char *libdir = (const char *)library;
+
+ if (libdir != NULL)
+ {
+ int machine_length = 0;
+ char dir_sep[2];
+
+ dir_sep[0] = DIR_SEPARATOR;
+ dir_sep[1] = (char)0;
+
+ if (multilib_dir != NULL)
+ {
+ machine_length = strlen (multilib_dir);
+ machine_length += strlen (dir_sep);
+ }
+
+ int l = strlen (libpath) + 1 + strlen ("m2") + 1
+ + strlen (libdir) + 1 + machine_length + 1;
+ char *s = (char *)xmalloc (l);
+
+ strcpy (s, libpath);
+ strcat (s, dir_sep);
+ if (machine_length > 0)
+ {
+ strcat (s, multilib_dir);
+ strcat (s, dir_sep);
+ }
+ strcat (s, "m2");
+ strcat (s, dir_sep);
+ strcat (s, libdir);
+ return s;
+ }
+ }
+ return NULL;
+}
+
+/* safe_strdup safely duplicates a string. */
+
+static char *
+safe_strdup (const char *s)
+{
+ if (s != NULL)
+ return xstrdup (s);
+ return NULL;
+}
+
+/* add_default_combination adds the correct link path and then the
+ library name. */
+
+static bool
+add_default_combination (const char *libpath, const char *library)
+{
+ if (library != NULL)
+ {
+ append_option (OPT_L, build_archive_path (libpath, library), 1);
+ append_option (OPT_l, safe_strdup (library), 1);
+ return true;
+ }
+ return false;
+}
+
+/* add_default_archives adds the default archives to the end of the
+ current command line. */
+
+static int
+add_default_archives (const char *libpath, const char *libraries)
+{
+ const char *l = libraries;
+ const char *e;
+ char *libname;
+ unsigned int libcount = 0;
+
+ do
+ {
+ e = index (l, ',');
+ if (e == NULL)
+ {
+ libname = xstrdup (l);
+ l = NULL;
+ if (add_default_combination (libpath, libname))
+ libcount++;
+ free (libname);
+ }
+ else
+ {
+ libname = xstrndup (l, e - l);
+ l = e + 1;
+ if (add_default_combination (libpath, libname))
+ libcount++;
+ free (libname);
+ }
+ }
+ while ((l != NULL) && (l[0] != (char)0));
+ return libcount;
+}
+
+/* build_include_path builds the component of the include path
+ referenced by the library. */
+
+static const char *
+build_include_path (const char *libpath, const char *library)
+{
+ char dir_sep[2];
+ char *gm2libs;
+ unsigned int machine_length = 0;
+
+ dir_sep[0] = DIR_SEPARATOR;
+ dir_sep[1] = (char)0;
+
+ if (multilib_dir != NULL)
+ {
+ machine_length = strlen (multilib_dir);
+ machine_length += strlen (dir_sep);
+ }
+
+ gm2libs = (char *)alloca (strlen (libpath) + strlen (dir_sep) + strlen ("m2")
+ + strlen (dir_sep) + strlen (library) + 1
+ + machine_length + 1);
+ strcpy (gm2libs, libpath);
+ strcat (gm2libs, dir_sep);
+ if (machine_length > 0)
+ {
+ strcat (gm2libs, multilib_dir);
+ strcat (gm2libs, dir_sep);
+ }
+ strcat (gm2libs, "m2");
+ strcat (gm2libs, dir_sep);
+ strcat (gm2libs, library);
+
+ return xstrdup (gm2libs);
+}
+
+/* add_include add the correct include path given the libpath and
+ library. The new path is returned. */
+
+static const char *
+add_include (const char *libpath, const char *library)
+{
+ if (library == NULL)
+ return NULL;
+ else
+ return build_include_path (libpath, library);
+}
+
+/* add_default_includes add the appropriate default include paths
+ depending upon the style of libraries chosen. */
+
+static void
+add_default_includes (const char *libpath, const char *libraries)
+{
+ const char *l = libraries;
+ const char *e;
+ const char *c;
+ const char *path;
+
+ do
+ {
+ e = index (l, ',');
+ if (e == NULL)
+ {
+ c = xstrdup (l);
+ l = NULL;
+ }
+ else
+ {
+ c = xstrndup (l, e - l);
+ l = e + 1;
+ }
+ path = add_include (libpath, c);
+ append_option (OPT_I, path, 1);
+ }
+ while ((l != NULL) && (l[0] != (char)0));
+}
+
+/* library_installed returns true if directory library is found under
+ libpath. */
+
+static bool
+library_installed (const char *libpath, const char *library)
+{
+#if defined(HAVE_OPENDIR) && defined(HAVE_DIRENT_H)
+ const char *complete = build_archive_path (libpath, library);
+ DIR *directory = opendir (complete);
+
+ if (directory == NULL || (errno == ENOENT))
+ return false;
+ /* Directory exists and therefore the library also exists. */
+ closedir (directory);
+ return true;
+#else
+ return false;
+#endif
+}
+
+/* check_valid check to see that the library is valid.
+ It check the library against the default library set in gm2 and
+ also against any additional libraries installed in the prefix tree. */
+
+static bool
+check_valid_library (const char *libpath, const char *library)
+{
+ /* Firstly check against the default libraries (which might not be
+ installed yet). */
+ for (int i = 0; i < maxlib; i++)
+ if (strcmp (library, library_name[i]) == 0)
+ return true;
+ /* Secondly check whether it is installed (a third party library). */
+ return library_installed (libpath, library);
+}
+
+/* check_valid_list check to see that the libraries specified are valid.
+ It checks against the default library set in gm2 and also against
+ any additional libraries installed in the libpath tree. */
+
+static bool
+check_valid_list (const char *libpath, const char *libraries)
+{
+ const char *start = libraries;
+ const char *end;
+ const char *copy;
+
+ do
+ {
+ end = index (start, ',');
+ if (end == NULL)
+ {
+ copy = xstrdup (start);
+ start = NULL;
+ }
+ else
+ {
+ copy = xstrndup (start, end - start);
+ start = end + 1;
+ }
+ if (! check_valid_library (libpath, copy))
+ {
+ error ("library specified %sq is either not installed or does not exist",
+ copy);
+ return false;
+ }
+ }
+ while ((start != NULL) && (start[0] != (char)0));
+ return true;
+}
+
+/* add_word returns a new string which has the contents of lib
+ appended to list. If list is NULL then lib is duplicated and
+ returned otherwise the list is appended by "," and the contents of
+ lib. */
+
+static const char *
+add_word (const char *list, const char *lib)
+{
+ char *copy;
+ if (list == NULL)
+ return xstrdup (lib);
+ copy = (char *) xmalloc (strlen (list) + strlen (lib) + 1 + 1);
+ strcpy (copy, list);
+ strcat (copy, ",");
+ strcat (copy, lib);
+ return copy;
+}
+
+/* convert_abbreviation checks abbreviation against known library
+ abbreviations. If an abbreviation is found it converts the element
+ to the full library name, otherwise the user supplied name is added
+ to the full_libraries list. A new string is returned. */
+
+static const char *
+convert_abbreviation (const char *full_libraries, const char *abbreviation)
+{
+ for (int i = 0; i < maxlib; i++)
+ if (strcmp (abbreviation, library_abbrev[i]) == 0)
+ return add_word (full_libraries, library_name[i]);
+ /* No abbreviation found therefore assume user specified full library name. */
+ return add_word (full_libraries, abbreviation);
+}
+
+/* convert_abbreviations checks each element in the library list to
+ see if an a known library abbreviation was used. If found it
+ converts the element to the full library name, otherwise the
+ element is copied into the list. A new string is returned. */
+
+static const char *
+convert_abbreviations (const char *libraries)
+{
+ const char *start = libraries;
+ const char *end;
+ const char *full_libraries = NULL;
+
+ do
+ {
+ end = index (start, ',');
+ if (end == NULL)
+ {
+ full_libraries = convert_abbreviation (full_libraries, start);
+ start = NULL;
+ }
+ else
+ {
+ full_libraries = convert_abbreviation (full_libraries, xstrndup (start, end - start));
+ start = end + 1;
+ }
+ }
+ while ((start != NULL) && (start[0] != (char)0));
+ return full_libraries;
+}
+
+
+void
+lang_specific_driver (struct cl_decoded_option **in_decoded_options,
+ unsigned int *in_decoded_options_count,
+ int *in_added_libraries)
+{
+ unsigned int argc = *in_decoded_options_count;
+ struct cl_decoded_option *decoded_options = *in_decoded_options;
+ unsigned int i;
+
+ /* True if we saw a `-xfoo' language specification on the command
+ line. This function will add a -xmodula-2 if the user has not
+ already placed one onto the command line. */
+ bool seen_x_flag = false;
+ const char *language = NULL;
+
+ /* If nonzero, the user gave us the `-p' or `-pg' flag. */
+ int saw_profile_flag = 0;
+
+ /* What action to take for the c++ runtime library:
+ -1 means we should not link it in.
+ 0 means we should link it if it is needed.
+ 1 means it is needed and should be linked in.
+ 2 means it is needed but should be linked statically. */
+ int library = 0;
+
+ /* Which c++ runtime library to link. */
+ stdcxxlib_kind which_library = USE_LIBSTDCXX;
+
+ const char *libraries = NULL;
+ const char *dialect = DEFAULT_DIALECT;
+ const char *libpath = LIBSUBDIR;
+
+ /* An array used to flag each argument that needs a bit set for
+ LANGSPEC, MATHLIB, or WITHLIBC. */
+ int *args;
+
+ /* Have we seen -fmod=? */
+ bool seen_module_extension = false;
+
+ /* Should the driver perform a link? */
+ bool linking = true;
+
+ /* "-lm" or "-lmath" if it appears on the command line. */
+ const struct cl_decoded_option *saw_math = NULL;
+
+ /* "-lc" if it appears on the command line. */
+ const struct cl_decoded_option *saw_libc = NULL;
+
+ /* By default, we throw on the math library if we have one. */
+ int need_math = (MATH_LIBRARY[0] != '\0');
+
+ /* 1 if we should add -lpthread to the command-line. */
+ int need_pthread = 1;
+
+ /* True if we saw -static. */
+ int static_link = 0;
+
+ /* True if we should add -shared-libgcc to the command-line. */
+ int shared_libgcc = 1;
+
+ /* Have we seen the -v flag? */
+ bool verbose = false;
+
+ /* The number of libraries added in. */
+ int added_libraries;
+
+ /* True if we should add -fplugin=m2rte to the command-line. */
+ bool need_plugin = true;
+
+ /* True if we should set up include paths and library paths. */
+ bool allow_libraries = true;
+
+#if defined(DEBUG_ARG)
+ printf ("argc = %d\n", argc);
+ fprintf (stderr, "Incoming:");
+ for (i = 0; i < argc; i++)
+ fprintf (stderr, " %s", decoded_options[i].orig_option_with_args_text);
+ fprintf (stderr, "\n");
+#endif
+
+ gm2_xargc = argc;
+ gm2_x_decoded_options = decoded_options;
+ gm2_newargc = 0;
+ gm2_new_decoded_options = decoded_options;
+ added_libraries = *in_added_libraries;
+ args = XCNEWVEC (int, argc);
+
+ /* First pass through arglist.
+
+ If -nostdlib or a "turn-off-linking" option is anywhere in the
+ command line, don't do any library-option processing (except
+ relating to -x). */
+
+ for (i = 1; i < argc; i++)
+ {
+ const char *arg = decoded_options[i].arg;
+ args[i] = 0;
+#if defined(DEBUG_ARG)
+ printf ("1st pass: %s\n",
+ decoded_options[i].orig_option_with_args_text);
+#endif
+ switch (decoded_options[i].opt_index)
+ {
+ case OPT_fiso:
+ dialect = "iso";
+ break;
+ case OPT_fpim2:
+ dialect = "pim2";
+ break;
+ case OPT_fpim3:
+ dialect = "pim3";
+ break;
+ case OPT_fpim4:
+ dialect = "pim4";
+ break;
+ case OPT_fpim:
+ dialect = "pim";
+ break;
+ case OPT_flibs_:
+ libraries = xstrdup (arg);
+ allow_libraries = decoded_options[i].value;
+ break;
+ case OPT_fmod_:
+ seen_module_extension = true;
+ break;
+ case OPT_fpthread:
+ need_pthread = decoded_options[i].value;
+ break;
+ case OPT_fm2_plugin:
+ need_plugin = decoded_options[i].value;
+ break;
+ case OPT_fscaffold_dynamic:
+ seen_scaffold_dynamic = true;
+ scaffold_dynamic = decoded_options[i].value;
+ break;
+ case OPT_fscaffold_static:
+ seen_scaffold_static = true;
+ scaffold_static = decoded_options[i].value;
+ break;
+ case OPT_fgen_module_list_:
+ seen_gen_module_list = true;
+ gen_module_list = decoded_options[i].value;
+ if (gen_module_list)
+ gen_module_filename = decoded_options[i].arg;
+ break;
+ case OPT_fuse_list_:
+ seen_uselist = true;
+ uselist = decoded_options[i].value;
+ break;
+
+ case OPT_nostdlib:
+ case OPT_nostdlib__:
+ case OPT_nodefaultlibs:
+ library = -1;
+ break;
+
+ case OPT_l:
+ if (strcmp (arg, MATH_LIBRARY) == 0)
+ {
+ args[i] |= MATHLIB;
+ need_math = 0;
+ }
+ else if (strcmp (arg, "c") == 0)
+ args[i] |= WITHLIBC;
+ else
+ /* Unrecognized libraries (e.g. -lfoo) may require libstdc++. */
+ library = (library == 0) ? 1 : library;
+ break;
+
+ case OPT_pg:
+ case OPT_p:
+ saw_profile_flag++;
+ break;
+
+ case OPT_x:
+ seen_x_flag = true;
+ language = arg;
+ break;
+
+ case OPT_v:
+ verbose = true;
+ break;
+
+ case OPT_Xlinker:
+ case OPT_Wl_:
+ /* Arguments that go directly to the linker might be .o files,
+ or something, and so might cause libstdc++ to be needed. */
+ if (library == 0)
+ library = 1;
+ break;
+
+ case OPT_c:
+ case OPT_r:
+ case OPT_S:
+ case OPT_E:
+ case OPT_M:
+ case OPT_MM:
+ case OPT_fsyntax_only:
+ /* Don't specify libraries if we won't link, since that would
+ cause a warning. */
+ linking = false;
+ library = -1;
+ break;
+
+ case OPT_static:
+ static_link = 1;
+ break;
+
+ case OPT_static_libgcc:
+ shared_libgcc = 0;
+ break;
+
+ case OPT_static_libstdc__:
+ library = library >= 0 ? 2 : library;
+ args[i] |= SKIPOPT;
+ break;
+
+ case OPT_stdlib_:
+ which_library = (stdcxxlib_kind) decoded_options[i].value;
+ break;
+
+ default:
+ if ((decoded_options[i].orig_option_with_args_text != NULL)
+ && (strncmp (decoded_options[i].orig_option_with_args_text,
+ "-m", 2) == 0))
+ multilib_dir = xstrdup (decoded_options[i].orig_option_with_args_text
+ + 2);
+ }
+ }
+ if (language != NULL && (strcmp (language, "modula-2") != 0))
+ return;
+
+ 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");
+ }
+ if (uselist && gen_module_list)
+ {
+ if (! seen_gen_module_list)
+ gen_module_list = false;
+ if (uselist && gen_module_list)
+ error ("%qs and %qs cannot both be enabled",
+ "-fgen-module-list=", "-fuse-list=");
+ }
+
+
+ /* There's no point adding -shared-libgcc if we don't have a shared
+ libgcc. */
+#ifndef ENABLE_SHARED_LIBGCC
+ shared_libgcc = 0;
+#endif
+
+ /* Second pass through arglist, transforming arguments as appropriate. */
+
+ append_arg (&decoded_options[0]); /* Start with command name, of course. */
+ for (i = 1; i < argc; ++i)
+ {
+#if defined(DEBUG_ARG)
+ printf ("2nd pass: %s\n",
+ decoded_options[i].orig_option_with_args_text);
+#endif
+ if ((args[i] & SKIPOPT) == 0)
+ {
+ append_arg (&decoded_options[i]);
+ /* Make sure -lstdc++ is before the math library, since libstdc++
+ itself uses those math routines. */
+ if (!saw_math && (args[i] & MATHLIB) && library > 0)
+ saw_math = &decoded_options[i];
+
+ if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
+ saw_libc = &decoded_options[i];
+ }
+#if defined(DEBUG_ARG)
+ else
+ printf ("skipping: %s\n",
+ decoded_options[i].orig_option_with_args_text);
+#endif
+ }
+
+ /* We now add in extra arguments to facilitate a successful
+ compile or link. For example include paths for dialect of Modula-2,
+ library paths and default scaffold linking options. */
+
+ /* If we have not seen either uselist or gen_module_list and we need
+ to link then we turn on -fgen_module_list=- as the default. */
+ if ((! (seen_uselist || seen_gen_module_list)) && linking)
+ append_option (OPT_fgen_module_list_, "-", 1);
+
+ if (allow_libraries)
+ {
+ /* If the libraries have not been specified by the user but the
+ dialect has been specified then select the appropriate libraries. */
+ if (libraries == NULL)
+ {
+ if (strcmp (dialect, "iso") == 0)
+ libraries = xstrdup ("m2iso,m2pim");
+ else
+ /* Default to pim libraries if none specified. */
+ libraries = xstrdup ("m2pim,m2log,m2iso");
+ }
+ libraries = convert_abbreviations (libraries);
+ if (! check_valid_list (libpath, libraries))
+ return;
+ add_default_includes (libpath, libraries);
+ }
+ if ((! seen_x_flag) && seen_module_extension)
+ append_option (OPT_x, "modula-2", 1);
+
+ if (need_plugin)
+ append_option (OPT_fplugin_, "m2rte", 1);
+
+ if (linking)
+ {
+ if (allow_libraries)
+ add_default_archives (libpath, libraries);
+ /* Add `-lstdc++' if we haven't already done so. */
+#ifdef HAVE_LD_STATIC_DYNAMIC
+ if (library > 1 && !static_link)
+ append_option (OPT_Wl_, LD_STATIC_OPTION, 1);
+#endif
+ if (which_library == USE_LIBCXX)
+ {
+ append_option (OPT_l, saw_profile_flag ? LIBCXX_PROFILE : LIBCXX, 1);
+ added_libraries++;
+ if (LIBCXXABI != NULL)
+ {
+ append_option (OPT_l, saw_profile_flag ? LIBCXXABI_PROFILE
+ : LIBCXXABI, 1);
+ added_libraries++;
+ }
+ }
+ else
+ {
+ append_option (OPT_l, saw_profile_flag ? LIBSTDCXX_PROFILE
+ : LIBSTDCXX, 1);
+ added_libraries++;
+ }
+ /* Add target-dependent static library, if necessary. */
+ if ((static_link || library > 1) && LIBSTDCXX_STATIC != NULL)
+ {
+ append_option (OPT_l, LIBSTDCXX_STATIC, 1);
+ added_libraries++;
+ }
+#ifdef HAVE_LD_STATIC_DYNAMIC
+ if (library > 1 && !static_link)
+ append_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1);
+#endif
+ }
+ if (need_math)
+ {
+ append_option (OPT_l, saw_profile_flag ? MATH_LIBRARY_PROFILE :
+ MATH_LIBRARY, 1);
+ added_libraries++;
+ }
+ if (need_pthread)
+ {
+ append_option (OPT_l, "pthread", 1);
+ added_libraries++;
+ }
+ if (shared_libgcc && !static_link)
+ append_option (OPT_shared_libgcc, NULL, 1);
+
+ if (verbose && gm2_new_decoded_options != gm2_x_decoded_options)
+ {
+ fprintf (stderr, _("Driving:"));
+ for (i = 0; i < gm2_newargc; i++)
+ fprintf (stderr, " %s",
+ gm2_new_decoded_options[i].orig_option_with_args_text);
+ fprintf (stderr, "\n");
+ fprintf (stderr, "new argc = %d, added_libraries = %d\n",
+ gm2_newargc, added_libraries);
+ }
+
+ *in_decoded_options_count = gm2_newargc;
+ *in_decoded_options = gm2_new_decoded_options;
+ *in_added_libraries = added_libraries;
+}
+
+/* Called before linking. Returns 0 on success and -1 on failure. */
+int
+lang_specific_pre_link (void) /* Not used for M2. */
+{
+ return 0;
+}
+
+/* Number of extra output files that lang_specific_pre_link may generate. */
+int lang_specific_extra_outfiles = 0;
@@ -0,0 +1,356 @@
+; Options for the Modula-2 front end.
+;
+; Copyright (C) 2016-2022 Free Software Foundation, Inc.
+; Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
+;
+; This file is part of GNU Modula-2.
+;
+; GNU Modula-2 is free software; you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation; either version 3, or (at your option)
+; any later version.
+;
+; GNU Modula-2 is distributed in the hope that it will be useful, but
+; WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+; General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with GNU Modula-2; see the file COPYING. If not,
+; see <https://www.gnu.org/licenses/>. *)
+
+; See the GCC internals manual for a description of this file's format.
+
+; Please try to keep this file in ASCII collating order.
+
+Language
+Modula-2
+
+B
+Modula-2
+; Documented in c.opt
+
+D
+Modula-2
+; Documented in c.opt
+
+E
+Modula-2
+; Documented in c.opt (passed to the preprocessor if -fcpp is used)
+
+I
+Modula-2 Joined Separate
+; Documented in c.opt
+
+L
+Modula-2 Joined Separate
+; Not documented
+
+M
+Modula-2
+; Documented in c.opt
+
+O
+Modula-2
+; Documented in c.opt
+
+Wall
+Modula-2
+; Documented in c.opt
+
+Wpedantic
+Modula-2
+; Documented in common.opt
+
+Wpedantic-param-names
+Modula-2
+compiler checks to force definition module procedure parameter names with their implementation module counterpart
+
+Wpedantic-cast
+Modula-2
+compiler warns if a cast is being used on types of differing sizes
+
+Wverbose-unbounded
+Modula-2
+inform user which parameters will be passed by reference
+
+Wstyle
+Modula-2
+extra compile time semantic checking, typically tries to catch poor programming style
+
+Wunused-variable
+Modula-2
+; Documented in c.opt
+
+Wunused-parameter
+Modula-2
+; Documented in c.opt
+
+c
+Modula-2
+; Documented in c.opt
+
+fauto-init
+Modula-2
+automatically initializes all pointers to NIL
+
+fbounds
+Modula-2
+turns on runtime subrange, array index and indirection via NIL pointer checking
+
+fcase
+Modula-2
+turns on runtime checking to check whether a CASE statement requires an ELSE clause when on was not specified
+
+fobjc-std=objc1
+Modula-2
+; Documented in c.opt
+
+fcpp
+Modula-2
+use cpp to preprocess the module
+
+fcpp-end
+Modula-2
+passed to the preprocessor if -fcpp is used (internal switch)
+
+fcpp-begin
+Modula-2
+passed to the preprocessor if -fcpp is used (internal switch)
+
+fdebug-builtins
+Modula-2
+call a real function, rather than the builtin equivalent
+
+fdump-system-exports
+Modula-2
+display all inbuilt system items
+
+fd
+Modula-2
+turn on internal debugging of the compiler
+
+fdebug-trace-quad
+Modula-2
+turn on quadruple tracing (internal switch)
+
+fdebug-trace-api
+Modula-2
+turn on the Modula-2 api tracing (internal switch)
+
+fdebug-function-line-numbers
+Modula-2
+turn on the Modula-2 function line number generation (internal switch)
+
+fdef=
+Modula-2 Joined
+recognise the specified suffix as a definition module filename
+
+fexceptions
+Modula-2
+; Documented in common.opt
+
+fextended-opaque
+Modula-2
+allows opaque types to be implemented as any type (a GNU Modula-2 extension)
+
+ffloatvalue
+Modula-2
+turns on runtime checking to check whether a floating point number is about to exceed range
+
+fgen-module-list=
+Modula-2 Joined
+create a topologically sorted module list from all dependent modules used in the application
+
+findex
+Modula-2
+turns on all range checking for numerical values
+
+fiso
+Modula-2
+use ISO dialect of Modula-2
+
+flibs=
+Modula-2 Joined
+specify the library order, currently legal entries include: log, min, pim, iso or their directory name equivalent m2log, m2min, m2pim, m2iso.
+
+flocation=
+Modula-2 Joined
+set all location values to a specific value (internal switch)
+
+fm2-g
+Modula-2
+generate extra nops to improve debugging, producing an instruction for every code related keyword
+
+fm2-lower-case
+Modula-2
+generate error messages which render keywords in lower case
+
+fm2-plugin
+Modula-2
+insert plugin to identify runtime errors at compiletime (default on)
+
+fm2-statistics
+Modula-2
+display statistics about the amount of source lines compiled and symbols used
+
+fm2-strict-type
+Modula-2
+experimental flag to turn on the new strict type checker
+
+fm2-whole-program
+Modula-2
+compile all implementation modules and program module at once
+
+fmod=
+Modula-2 Joined
+recognise the specified suffix as implementation and module filenames
+
+fnil
+Modula-2
+turns on runtime checking to detect accessing data through a NIL value pointer
+
+fpim
+Modula-2
+use PIM [234] dialect of Modula-2
+
+fpim2
+Modula-2
+use PIM 2 dialect of Modula-2
+
+fpim3
+Modula-2
+use PIM 3 dialect of Modula-2
+
+fpim4
+Modula-2
+use PIM 4 dialect of Modula-2
+
+fpositive-mod-floor-div
+Modula-2
+force positive result from MOD and DIV result floor
+
+fpthread
+Modula-2
+link against the pthread library (default on)
+
+fq
+Modula-2
+internal compiler debugging information, dump the list of quadruples
+
+frange
+Modula-2
+turns on all range checking for numerical values
+
+freturn
+Modula-2
+turns on runtime checking for functions which finish without executing a RETURN statement
+
+fruntime-modules=
+Modula-2 Joined
+specify the list of runtime modules and their initialization order
+
+fscaffold-static
+Modula-2
+generate static scaffold initialization and finalization for every module inside main
+
+fscaffold-dynamic
+Modula-2
+the modules initialization order is dynamically determined by M2RTS and application dependancies
+
+fscaffold-c
+Modula-2
+generate a C source scaffold for the current module being compiled
+
+fscaffold-c++
+Modula-2
+generate a C++ source scaffold for the current module being compiled
+
+fscaffold-main
+Modula-2
+generate the main function
+
+fshared
+Modula-2
+generate a shared library from the module
+
+fsoft-check-all
+Modula-2
+turns on all software runtime checking (an abbreviation for -fnil -frange -findex -fwholediv -fcase -freturn -fwholediv -ffloatvalue)
+
+fsources
+Modula-2
+display the location of module source files as they are compiled
+
+fswig
+Modula-2
+create a swig interface file for the module
+
+funbounded-by-reference
+Modula-2
+optimize non var unbounded parameters by passing it by reference, providing it is not written to within the callee procedure.
+
+fuse-list=
+Modula-2 Joined
+orders the initialization/finalializations for scaffold-static or force linking of modules if scaffold-dynamic
+
+fversion
+Modula-2
+; Documented in common.opt
+
+fwholediv
+Modula-2
+turns on all division and modulus by zero checking for ordinal values
+
+fwholevalue
+Modula-2
+turns on runtime checking to check whether a whole number is about to exceed range
+
+fxcode
+Modula-2
+issue all errors and warnings in the Xcode format
+
+iprefix
+Modula-2
+; Documented in c.opt
+
+isystem
+Modula-2
+; Documented in c.opt
+
+idirafter
+Modula-2
+; Documented in c.opt
+
+imultilib
+Modula-2
+; Documented in c.opt
+
+lang-asm
+Modula-2
+; Documented in c.opt
+
+-save-temps
+Modula-2 Alias(save-temps)
+
+save-temps
+Modula-2
+save temporary preprocessed files
+
+save-temps=
+Modula-2 Joined
+save temporary preprocessed files
+
+traditional-cpp
+Modula-2
+; Documented in c.opt
+
+v
+Modula-2
+; Documented in c.opt
+
+x
+Modula-2 Joined
+specify the language from the compiler driver
+
+; This comment is to ensure we retain the blank line above.
@@ -0,0 +1,38 @@
+/* Definitions for specs for GNU Modula-2.
+ Copyright (C) 2001-2022 Free Software Foundation, Inc.
+ Contributed by Gaius Mulley.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* This is the contribution to the `default_compilers' array in gcc.c for
+ GNU Modula-2. */
+
+/* Pass the preprocessor options on the command line together with
+ the exec prefix. */
+
+#define M2CPP "%{fcpp:-fcpp-begin " \
+ " -E -lang-asm -traditional-cpp " \
+ " %(cpp_unique_options) -fcpp-end}"
+
+ {".mod", "@modula-2", 0, 0, 0},
+ {"@modula-2",
+ "cc1gm2 " M2CPP
+ " %(cc1_options) %{B*} %{c*} %{f*} %{+e*} %{I*} "
+ " %{MD} %{MMD} %{M} %{MM} %{MA} %{MT*} %{MF*} %V"
+ " %{save-temps*}"
+ " %i %{!fsyntax-only:%(invoke_as)}",
+ 0, 0, 0},
@@ -0,0 +1,83 @@
+# Top level configure fragment for GNU Modula-2.
+# Copyright (C) 2000-2022 Free Software Foundation, Inc.
+
+# This file is part of GCC.
+
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# Configure looks for the existence of this file to auto-config each language.
+# We define several parameters used by configure:
+#
+# language - name of language as it would appear in $(LANGUAGES)
+# compilers - value to add to $(COMPILERS)
+# stagestuff - files to add to $(STAGESTUFF)
+
+language="m2"
+
+compilers="cc1gm2\$(exeext)"
+
+stagestuff="gm2\$(exeext) cc1gm2\$(exeext) cc1gm2-cross\$(exeext)"
+
+target_libs="target-libstdc++-v3 target-libgm2"
+
+# The Modula-2 frontend needs C++ compiler during stage 1.
+lang_requires_boot_languages=c++
+
+# Do not build by default.
+build_by_default="no"
+
+gtfiles="\$(srcdir)/m2/gm2-lang.cc \
+ \$(srcdir)/m2/gm2-lang.h \
+ \$(srcdir)/m2/gm2-gcc/rtegraph.cc \
+ \$(srcdir)/m2/gm2-gcc/m2block.cc \
+ \$(srcdir)/m2/gm2-gcc/m2builtins.cc \
+ \$(srcdir)/m2/gm2-gcc/m2decl.cc \
+ \$(srcdir)/m2/gm2-gcc/m2except.cc \
+ \$(srcdir)/m2/gm2-gcc/m2expr.cc \
+ \$(srcdir)/m2/gm2-gcc/m2statement.cc \
+ \$(srcdir)/m2/gm2-gcc/m2type.cc"
+
+outputs="m2/config-make \
+ m2/Make-maintainer \
+ "
+
+mkdir -p m2/gm2-compiler-boot
+mkdir -p m2/gm2-libs-boot
+mkdir -p m2/gm2-ici-boot
+mkdir -p m2/gm2-libiberty
+mkdir -p m2/gm2-gcc
+mkdir -p m2/gm2-compiler
+mkdir -p m2/gm2-libs
+mkdir -p m2/gm2-libs-iso
+mkdir -p m2/gm2-compiler-paranoid
+mkdir -p m2/gm2-libs-paranoid
+mkdir -p m2/gm2-compiler-verify
+mkdir -p m2/boot-bin
+mkdir -p m2/gm2-libs-pim
+mkdir -p m2/gm2-libs-coroutines
+mkdir -p m2/gm2-libs-min
+mkdir -p m2/pge-boot
+mkdir -p plugin
+mkdir -p stage1/m2 stage2/m2 stage3/m2 stage4/m2
+
+# directories used by Make-maintainer
+
+mkdir -p m2/gm2-auto
+mkdir -p m2/gm2-pg-boot
+mkdir -p m2/gm2-pge-boot
+mkdir -p m2/gm2-ppg-boot
+mkdir -p m2/mc-boot
+mkdir -p m2/mc-boot-ch
+mkdir -p m2/mc-boot-gen
@@ -0,0 +1,2 @@
+# Target libraries are put under this directory:
+TARGET_SUBDIR = @target_subdir@
@@ -0,0 +1,43 @@
+# configure.ac provides gm2spec.c with access to config values.
+
+# Copyright (C) 2001-2022 Free Software Foundation, Inc.
+# Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
+
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+AC_INIT(m2, [ ])
+
+# Determine the host, build, and target systems
+AC_CANONICAL_BUILD
+AC_CANONICAL_HOST
+AC_CANONICAL_TARGET
+
+AC_CHECK_PROGS(regex_flex, flex)
+if test x$regex_flex = "x" ; then
+ AC_MSG_ERROR([flex is required to build GNU Modula-2 (hint install flex).])
+fi
+
+AC_CHECK_PROGS(regex_realpath, realpath)
+if test x$regex_realpath = "x" ; then
+ AC_MSG_ERROR([realpath is required to build GNU Modula-2 (hint install coreutils).])
+fi
+
+AC_CHECK_FUNCS([stpcpy])
+
+AC_CHECK_HEADERS(sys/types.h)
+AC_HEADER_DIRENT
+AC_CHECK_LIB([c],[opendir],[AC_DEFINE([HAVE_OPENDIR],[1],[found opendir])])
+AC_CONFIG_HEADERS(gm2config.h, [echo timestamp > stamp-h])
+AC_OUTPUT
@@ -0,0 +1,56 @@
+/* gm2config.h.in template file for values required by gm2spec.c.
+
+Copyright (C) 2006-2022 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
+
+This file is part of GNU Modula-2.
+
+GNU Modula-2 is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GNU Modula-2 is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+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/>. */
+
+#ifndef PACKAGE_BUGREPORT
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+#endif
+
+#ifndef PACKAGE_NAME
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+#endif
+
+#ifndef PACKAGE_STRING
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+#endif
+
+/* Define to 1 if you have the `stpcmp' function. */
+#undef HAVE_STPCMP
+
+/* Define to 1 if you have the dirent.h header. */
+#undef HAVE_DIRENT_H
+
+/* Define to 1 if you have the sys/ndir.h header. */
+#undef HAVE_SYS_NDIR_H
+
+/* Define to 1 if you have the sys/dir.h header. */
+#undef HAVE_SYS_DIR_H
+
+/* Define to 1 if you have the ndir.h header. */
+#undef HAVE_NDIR_H
+
+/* Define to 1 if you have the sys/types.h header. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the opendir function. */
+#undef HAVE_OPENDIR