]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR modula2/111530: Build failure on BSD due to getopt_long_only GNU extension dependency
authorGaius Mulley <gaiusmod2@gmail.com>
Fri, 27 Oct 2023 14:54:48 +0000 (15:54 +0100)
committerGaius Mulley <gaiusmod2@gmail.com>
Fri, 27 Oct 2023 14:54:48 +0000 (15:54 +0100)
This patch uses the libiberty getopt long functions (wrapped up inside
libgm2/libm2pim/cgetopt.cc) and only enables this implementation if
libgm2/configure.ac detects no getopt_long and friends on the target.

gcc/m2/ChangeLog:

PR modula2/111530
* gm2-libs-ch/cgetopt.c (cgetopt_cgetopt_long): Re-format.
(cgetopt_cgetopt_long_only): Re-format.
(cgetopt_SetOption):  Re-format and assign flag to NULL
if name is also NULL.
* gm2-libs/GetOpt.def (AddLongOption): Add index parameter
and change flag to be a VAR parameter rather than a pointer.
(GetOptLong): Re-format.
(GetOpt): Correct comment.
* gm2-libs/GetOpt.mod: Re-write to rely on cgetopt rather
than implement long option creation in GetOpt.
* gm2-libs/cgetopt.def (SetOption): has_arg type is INTEGER.

libgm2/ChangeLog:

PR modula2/111530
* Makefile.in: Regenerate.
* aclocal.m4: Regenerate.
* config.h.in: Regenerate.
* configure: Regenerate.
* configure.ac (AC_CHECK_HEADERS): Include getopt.h.
(GM2_CHECK_LIB): getopt_long check.
(GM2_CHECK_LIB): getopt_long_only check.
* libm2cor/Makefile.in: Regenerate.
* libm2iso/Makefile.in: Regenerate.
* libm2log/Makefile.in: Regenerate.
* libm2min/Makefile.in: Regenerate.
* libm2pim/Makefile.in: Regenerate.
* libm2pim/cgetopt.cc: Re-write using conditional on configure
and long function code from libiberty/getopt.c.

gcc/testsuite/ChangeLog:

PR modula2/111530
* gm2/pimlib/run/pass/testgetopt.mod: New test.

Signed-off-by: Gaius Mulley <gaiusmod2@gmail.com>
16 files changed:
gcc/m2/gm2-libs-ch/cgetopt.c
gcc/m2/gm2-libs/GetOpt.def
gcc/m2/gm2-libs/GetOpt.mod
gcc/m2/gm2-libs/cgetopt.def
gcc/testsuite/gm2/pimlib/run/pass/testgetopt.mod [new file with mode: 0644]
libgm2/Makefile.in
libgm2/aclocal.m4
libgm2/config.h.in
libgm2/configure
libgm2/configure.ac
libgm2/libm2cor/Makefile.in
libgm2/libm2iso/Makefile.in
libgm2/libm2log/Makefile.in
libgm2/libm2min/Makefile.in
libgm2/libm2pim/Makefile.in
libgm2/libm2pim/cgetopt.cc

index 017fe91ad95df1c8e9d3c3919628a9aeb473acf9..36aadbdddc1edd012f5a298d3d95ec21457ab637 100644 (file)
@@ -59,7 +59,7 @@ cgetopt_getopt (int argc, char *argv[], char *optstring)
 
 int
 cgetopt_cgetopt_long (int argc, char *argv[], char *optstring, const struct option *longopts,
-                    int *longindex)
+                     int *longindex)
 {
   int r = getopt_long (argc, argv, optstring, longopts, longindex);
 
@@ -74,7 +74,7 @@ cgetopt_cgetopt_long (int argc, char *argv[], char *optstring, const struct opti
 
 int
 cgetopt_cgetopt_long_only (int argc, char *argv[], char *optstring,
-                         const struct option *longopts, int *longindex)
+                          const struct option *longopts, int *longindex)
 {
   int r = getopt_long_only (argc, argv, optstring, longopts, longindex);
 
@@ -121,8 +121,8 @@ cgetopt_KillOptions (cgetopt_Options *o)
 
 void
 cgetopt_SetOption (cgetopt_Options *o, unsigned int index,
-                 char *name, bool has_arg,
-                 int *flag, int val)
+                  char *name, int has_arg,
+                  int *flag, int val)
 {
   if (index > o->high)
     {
@@ -131,6 +131,8 @@ cgetopt_SetOption (cgetopt_Options *o, unsigned int index,
     }
   o->cinfo[index].name = name;
   o->cinfo[index].has_arg = has_arg;
+  if (name == NULL)
+    flag = NULL;
   o->cinfo[index].flag = flag;
   o->cinfo[index].val = val;
 }
index 2da5512991884a84c1ad7400cdeb60a701c68e38..bd021e42a53ceada9b25cf5b0d63212def5f2076 100644 (file)
@@ -40,7 +40,7 @@ TYPE
 
 (*
    GetOpt - call C getopt and fill in the parameters:
-            optarg, optind, opterr and optop.
+            optarg, optind, opterr and optopt.
 *)
 
 PROCEDURE GetOpt (argc: INTEGER; argv: ADDRESS; optstring: String;
@@ -83,13 +83,12 @@ PROCEDURE InitLongOptions () : LongOptions ;
        val    is the value to return, or to load into the variable
               pointed to by flag.
 
-       The last element of the array has to be filled with zeros.
+       The last element of the array must be filled with zeros.
 *)
 
-PROCEDURE AddLongOption (lo: LongOptions;
+PROCEDURE AddLongOption (lo: LongOptions; index: CARDINAL;
                          name: String; has_arg: INTEGER;
-                         flag: PtrToInteger;
-                         val: INTEGER) : LongOptions ;
+                         VAR flag: INTEGER; val: INTEGER) : LongOptions ;
 
 
 (*
@@ -106,8 +105,8 @@ PROCEDURE KillLongOptions (lo: LongOptions) : LongOptions ;
                 then optstring should be an empty string, not NIL.
 *)
 
-PROCEDURE GetOptLong (argc: INTEGER; argv: ADDRESS; optstring: String;
-                      longopts: LongOptions;
+PROCEDURE GetOptLong (argc: INTEGER; argv: ADDRESS;
+                      optstring: String; longopts: LongOptions;
                       VAR longindex: INTEGER) : INTEGER ;
 
 
index e7eaae63fcc442cdb427b3ecb96f29a5f72a653c..e3dcb94d93cf964d4e5484106278397d9df229a3 100644 (file)
@@ -34,19 +34,8 @@ IMPORT cgetopt ;
 
 
 TYPE
-   Crecord = RECORD    (* see man 3 getopt.  *)
-                name   : ADDRESS ;
-                has_arg: INTEGER ;
-                flag   : PtrToInteger ;
-                val    : INTEGER ;
-             END ;
-
-   ptrToCrecord = POINTER TO Crecord ;
-
    LongOptions = POINTER TO RECORD
-                               cptr: ptrToCrecord ;
-                               len : CARDINAL ;
-                               size: CARDINAL ;
+                               cptr: cgetopt.Options
                             END ;
 
 
@@ -79,9 +68,7 @@ VAR
 BEGIN
    NEW (lo) ;
    WITH lo^ DO
-      cptr := NIL ;
-      len := 0 ;
-      size := 0
+      cptr := cgetopt.InitOptions ()
    END ;
    RETURN lo
 END InitLongOptions ;
@@ -110,69 +97,25 @@ END InitLongOptions ;
 
        val    is the value to return, or to load into the variable pointed to by flag.
 
-       The last element of the array has to be filled with zeros.
+       The last element of the array must be filled with zeros.
 *)
 
-PROCEDURE AddLongOption (lo: LongOptions;
+PROCEDURE AddLongOption (lo: LongOptions; index: CARDINAL;
                          name: String; has_arg: INTEGER;
-                         flag: PtrToInteger; val: INTEGER) : LongOptions ;
-VAR
-   old,
-   entry: ptrToCrecord ;
+                         VAR flag: INTEGER; val: INTEGER) : LongOptions ;
 BEGIN
-   IF lo^.cptr = NIL
-   THEN
-      NEW (lo^.cptr) ;
-      lo^.len := 1 ;
-      lo^.size := SIZE (Crecord) ;
-      entry := lo^.cptr
-   ELSE
-      old := lo^.cptr ;
-      INC (lo^.len) ;
-      lo^.size := lo^.len * SIZE (Crecord) ;
-      REALLOCATE (lo^.cptr, lo^.size) ;
-      IF lo^.cptr = NIL
-      THEN
-         entry := NIL
-      ELSIF old = lo^.cptr
-      THEN
-         entry := lo^.cptr ;
-         INC (entry, SIZE (Crecord) * lo^.len-1)
-      ELSE
-         MemCopy (old, lo^.len-1, lo^.cptr) ;
-         entry := lo^.cptr ;
-         INC (entry, SIZE (Crecord) * lo^.len-1)
-      END
-   END ;
-   fillIn (entry, name, has_arg, flag, val) ;
+   cgetopt.SetOption (lo^.cptr, index, name, has_arg, flag, val) ;
    RETURN lo
 END AddLongOption ;
 
 
-(*
-   fillIn - fills in
-*)
-
-PROCEDURE fillIn (entry: ptrToCrecord;
-                  name: String; has_arg: INTEGER; flag: PtrToInteger; val: INTEGER) ;
-BEGIN
-   IF entry # NIL
-   THEN
-      entry^.name := name ;
-      entry^.has_arg := has_arg ;
-      entry^.flag := flag ;
-      entry^.val := val
-   END
-END fillIn ;
-
-
 (*
    KillLongOptions - returns NIL and also frees up memory associated with, lo.
 *)
 
 PROCEDURE KillLongOptions (lo: LongOptions) : LongOptions ;
 BEGIN
-   DEALLOCATE (lo^.cptr, lo^.size) ;
+   lo^.cptr := cgetopt.KillOptions (lo^.cptr) ;
    DISPOSE (lo) ;
    RETURN NIL
 END KillLongOptions ;
@@ -186,11 +129,9 @@ END KillLongOptions ;
 
 PROCEDURE GetOptLong (argc: INTEGER; argv: ADDRESS; optstring: String;
                       longopts: LongOptions; VAR longindex: INTEGER) : INTEGER ;
-VAR
-   r: INTEGER ;
 BEGIN
-   r := cgetopt.getopt_long (argc, argv, string (optstring), longopts^.cptr, longindex) ;
-   RETURN r
+   RETURN cgetopt.getopt_long (argc, argv, string (optstring),
+                               cgetopt.GetLongOptionArray (longopts^.cptr), longindex)
 END GetOptLong ;
 
 
@@ -201,12 +142,9 @@ END GetOptLong ;
 
 PROCEDURE GetOptLongOnly (argc: INTEGER; argv: ADDRESS; optstring: String;
                           longopts: LongOptions; VAR longindex: INTEGER) : INTEGER ;
-VAR
-   r: INTEGER ;
 BEGIN
-   r := cgetopt.getopt_long_only (argc, argv, string (optstring),
-                                 longopts^.cptr, longindex) ;
-   RETURN r
+   RETURN cgetopt.getopt_long_only (argc, argv, string (optstring),
+                                    cgetopt.GetLongOptionArray (longopts^.cptr), longindex)
 END GetOptLongOnly ;
 
 
index 79da9ad2e9ed0edeb467a9365558eb794f2be026..e2162d5a4e00379d7b4fc65cab3f7b440952f032 100644 (file)
@@ -28,7 +28,6 @@ DEFINITION MODULE cgetopt ;
 
 FROM SYSTEM IMPORT ADDRESS ;
 
-
 TYPE
    Options = ADDRESS ;
 
@@ -92,7 +91,7 @@ PROCEDURE KillOptions (o: Options) : Options ;
 *)
 
 PROCEDURE SetOption (o: Options; index: CARDINAL;
-                     name: ADDRESS; has_arg: BOOLEAN;
+                     name: ADDRESS; has_arg: INTEGER;
                      VAR flag: INTEGER; val: INTEGER) ;
 
 
diff --git a/gcc/testsuite/gm2/pimlib/run/pass/testgetopt.mod b/gcc/testsuite/gm2/pimlib/run/pass/testgetopt.mod
new file mode 100644 (file)
index 0000000..3e322da
--- /dev/null
@@ -0,0 +1,74 @@
+MODULE testgetopt ;
+
+FROM libc IMPORT printf, exit ;
+FROM GetOpt IMPORT InitLongOptions, KillLongOptions, AddLongOption,
+                   GetOptLong, PtrToInteger, LongOptions ;
+FROM DynamicStrings IMPORT String, InitString, string ;
+IMPORT UnixArgs ;
+FROM Storage IMPORT ALLOCATE ;
+FROM SYSTEM IMPORT ADR ;
+
+
+(*
+   Assert -
+*)
+
+PROCEDURE Assert (condition: BOOLEAN) ;
+BEGIN
+   IF NOT condition
+   THEN
+      printf ("assert failed, condition is false\n") ;
+      exit (1)
+   END
+END Assert ;
+
+
+
+(*
+   test -
+*)
+
+PROCEDURE test ;
+VAR
+   result   : INTEGER ;
+   optstring: String ;
+   i, val   : INTEGER ;
+   ch       : CHAR ;
+BEGIN
+   longopts := AddLongOption (longopts, 0, InitString ('help'), 0, result, 0) ;
+   longopts := AddLongOption (longopts, 1, InitString ('dir'), 1, result, 0) ;
+   longopts := AddLongOption (longopts, 2, NIL, 0, result, 0) ;
+   optstring := InitString ('hd:') ;
+   i := 1 ;
+   REPEAT
+      val := GetOptLong (UnixArgs.GetArgC (), UnixArgs.GetArgV (),
+                         optstring, longopts, i) ;
+      IF val = 0
+      THEN
+         printf ("long option detected, result = %d, val = %d, index i = %d, optstring = %s\n",
+                 result, val, i, string (optstring))
+      ELSIF val > 0
+      THEN
+         ch := VAL (CHAR, val) ;
+         CASE ch OF
+
+         'h': printf ("short option 'h' seen\n")
+
+         ELSE
+            printf ("unknown short option '%c' seen\n", ch)
+         END
+      ELSE
+         printf ("unknown long option\n")
+      END ;
+      INC (i)
+   UNTIL val <= 0
+END test ;
+
+
+VAR
+   longopts: LongOptions ;
+BEGIN
+   longopts := InitLongOptions () ;
+   test ;
+   longopts := KillLongOptions (longopts)
+END testgetopt.
index 47fbf6915a3711b87a92de5b5708c3dc1be17e4c..add0dd25665a0cd2be9b894c6126617a5b160350 100644 (file)
@@ -90,15 +90,15 @@ host_triplet = @host@
 target_triplet = @target@
 subdir = .
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \
+       $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
+       $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
+       $(top_srcdir)/../config/acx.m4 \
        $(top_srcdir)/../config/depstand.m4 \
        $(top_srcdir)/../config/lead-dot.m4 \
        $(top_srcdir)/../config/multi.m4 \
        $(top_srcdir)/../config/no-executables.m4 \
-       $(top_srcdir)/../config/override.m4 \
-       $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
-       $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
-       $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac
+       $(top_srcdir)/../config/override.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
index 832065fbb9be36758a0b0265609450ebd0381d16..c352303012d2bc3ca3e9f3b09f80a5585472a366 100644 (file)
@@ -1187,14 +1187,14 @@ AC_SUBST([am__tar])
 AC_SUBST([am__untar])
 ]) # _AM_PROG_TAR
 
+m4_include([../libtool.m4])
+m4_include([../ltoptions.m4])
+m4_include([../ltsugar.m4])
+m4_include([../ltversion.m4])
+m4_include([../lt~obsolete.m4])
 m4_include([../config/acx.m4])
 m4_include([../config/depstand.m4])
 m4_include([../config/lead-dot.m4])
 m4_include([../config/multi.m4])
 m4_include([../config/no-executables.m4])
 m4_include([../config/override.m4])
-m4_include([../libtool.m4])
-m4_include([../ltoptions.m4])
-m4_include([../ltsugar.m4])
-m4_include([../ltversion.m4])
-m4_include([../lt~obsolete.m4])
index f91f5a42f1ec3a648200a0ebb4912441f5ba0c7c..a9d932f99be103f4f07cf44eb610c6f3018df62c 100644 (file)
 /* function getgid exists */
 #undef HAVE_GETGID
 
+/* Define to 1 if you have the <getopt.h> header file. */
+#undef HAVE_GETOPT_H
+
+/* function getopt_long exists */
+#undef HAVE_GETOPT_LONG
+
+/* function getopt_long_only exists */
+#undef HAVE_GETOPT_LONG_ONLY
+
 /* function getpid exists */
 #undef HAVE_GETPID
 
index d55a7f4a74b6791a6811046692d66c03b4276947..a0ad71e7c6ca892b5fbdd7cfa57715c1de0ac496 100755 (executable)
@@ -4950,8 +4950,8 @@ fi
 
 
 
-for ac_header in limits.h stddef.h string.h strings.h stdlib.h \
-                 time.h \
+for ac_header in getopt.h limits.h stddef.h string.h strings.h \
+                 stdlib.h time.h \
                 fcntl.h unistd.h sys/file.h sys/time.h sys/mman.h \
                 sys/resource.h sys/param.h sys/times.h sys/stat.h \
                  sys/socket.h \
@@ -4973,7 +4973,6 @@ done
 
 
 
-
  case ${build_alias} in
   "") build_noncanonical=${build} ;;
   *) build_noncanonical=${build_alias} ;;
@@ -12789,7 +12788,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 12792 "configure"
+#line 12791 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12895,7 +12894,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 12898 "configure"
+#line 12897 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -18061,6 +18060,144 @@ $as_echo "#define HAVE_GETGID 1" >>confdefs.h
   fi
 
 
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking m2 front end checking c library for getopt_long" >&5
+$as_echo_n "checking m2 front end checking c library for getopt_long... " >&6; }
+  if test x$gcc_no_link != xyes; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getopt_long in -lc" >&5
+$as_echo_n "checking for getopt_long in -lc... " >&6; }
+if ${ac_cv_lib_c_getopt_long+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc  $LIBS"
+if test x$gcc_no_link = xyes; then
+  as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
+fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getopt_long ();
+int
+main ()
+{
+return getopt_long ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_c_getopt_long=yes
+else
+  ac_cv_lib_c_getopt_long=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_getopt_long" >&5
+$as_echo "$ac_cv_lib_c_getopt_long" >&6; }
+if test "x$ac_cv_lib_c_getopt_long" = xyes; then :
+
+$as_echo "#define HAVE_GETOPT_LONG 1" >>confdefs.h
+
+else
+
+  $as_echo "#undef HAVE_GETOPT_LONG" >>confdefs.h
+
+fi
+
+  else
+    if test "x$ac_cv_lib_c_getopt_long" = xyes; then
+
+$as_echo "#define HAVE_GETOPT_LONG 1" >>confdefs.h
+
+    elif test "x$ac_cv_func_getopt_long" = xyes; then
+
+$as_echo "#define HAVE_GETOPT_LONG 1" >>confdefs.h
+
+    else
+
+  $as_echo "#undef HAVE_GETOPT_LONG" >>confdefs.h
+
+    fi
+  fi
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking m2 front end checking c library for getopt_long_only" >&5
+$as_echo_n "checking m2 front end checking c library for getopt_long_only... " >&6; }
+  if test x$gcc_no_link != xyes; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getopt_long_only in -lc" >&5
+$as_echo_n "checking for getopt_long_only in -lc... " >&6; }
+if ${ac_cv_lib_c_getopt_long_only+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc  $LIBS"
+if test x$gcc_no_link = xyes; then
+  as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
+fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getopt_long_only ();
+int
+main ()
+{
+return getopt_long_only ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_c_getopt_long_only=yes
+else
+  ac_cv_lib_c_getopt_long_only=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_getopt_long_only" >&5
+$as_echo "$ac_cv_lib_c_getopt_long_only" >&6; }
+if test "x$ac_cv_lib_c_getopt_long_only" = xyes; then :
+
+$as_echo "#define HAVE_GETOPT_LONG_ONLY 1" >>confdefs.h
+
+else
+
+  $as_echo "#undef HAVE_GETOPT_LONG_ONLY" >>confdefs.h
+
+fi
+
+  else
+    if test "x$ac_cv_lib_c_getopt_long_only" = xyes; then
+
+$as_echo "#define HAVE_GETOPT_LONG_ONLY 1" >>confdefs.h
+
+    elif test "x$ac_cv_func_getopt_long_only" = xyes; then
+
+$as_echo "#define HAVE_GETOPT_LONG_ONLY 1" >>confdefs.h
+
+    else
+
+  $as_echo "#undef HAVE_GETOPT_LONG_ONLY" >>confdefs.h
+
+    fi
+  fi
+
+
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking m2 front end checking c library for getpid" >&5
 $as_echo_n "checking m2 front end checking c library for getpid... " >&6; }
   if test x$gcc_no_link != xyes; then
index 5701b95878b261621634b21deccd43a2598cdee8..11f4b50678168314faa2343542405ccfcef978f7 100644 (file)
@@ -92,8 +92,8 @@ AC_HEADER_SYS_WAIT
 AC_CHECK_HEADER([math.h],
               [AC_DEFINE([HAVE_MATH_H], [1], [have math.h])])
 
-AC_CHECK_HEADERS(limits.h stddef.h string.h strings.h stdlib.h \
-                 time.h \
+AC_CHECK_HEADERS(getopt.h limits.h stddef.h string.h strings.h \
+                 stdlib.h time.h \
                 fcntl.h unistd.h sys/file.h sys/time.h sys/mman.h \
                 sys/resource.h sys/param.h sys/times.h sys/stat.h \
                  sys/socket.h \
@@ -102,7 +102,6 @@ AC_CHECK_HEADERS(limits.h stddef.h string.h strings.h stdlib.h \
                  pthread.h stdarg.h stdio.h sys/types.h termios.h \
                  netinet/in.h netdb.h sys/uio.h sys/stat.h wchar.h)
 
-
 AC_CANONICAL_HOST
 ACX_NONCANONICAL_HOST
 ACX_NONCANONICAL_TARGET
@@ -296,6 +295,8 @@ GM2_CHECK_LIB([c],[fcntl],[FCNTL])
 GM2_CHECK_LIB([c],[fstat],[FSTAT])
 GM2_CHECK_LIB([c],[getdents],[GETDENTS])
 GM2_CHECK_LIB([c],[getgid],[GETGID])
+GM2_CHECK_LIB([c],[getopt_long],[GETOPT_LONG])
+GM2_CHECK_LIB([c],[getopt_long_only],[GETOPT_LONG_ONLY])
 GM2_CHECK_LIB([c],[getpid],[GETPID])
 GM2_CHECK_LIB([c],[gettimeofday],[GETTIMEOFD])
 GM2_CHECK_LIB([c],[getuid],[GETUID])
index 449a26bc2ad4f326bac82da364f0c181f3986b56..a8a311ef4dd805a92851d6239dc203086e021774 100644 (file)
@@ -108,15 +108,15 @@ target_triplet = @target@
 @BUILD_CORLIB_TRUE@@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_1 = -nodefaultrpaths -Wl,-rpath,@loader_path/
 subdir = libm2cor
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \
+       $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
+       $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
+       $(top_srcdir)/../config/acx.m4 \
        $(top_srcdir)/../config/depstand.m4 \
        $(top_srcdir)/../config/lead-dot.m4 \
        $(top_srcdir)/../config/multi.m4 \
        $(top_srcdir)/../config/no-executables.m4 \
-       $(top_srcdir)/../config/override.m4 \
-       $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
-       $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
-       $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac
+       $(top_srcdir)/../config/override.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 DIST_COMMON = $(srcdir)/Makefile.am
index 6700664cb077762a2a63d6b533a1f439ee5427fe..21632b49503690f4cab09d51ce484de13e9bbd60 100644 (file)
@@ -108,15 +108,15 @@ target_triplet = @target@
 @BUILD_ISOLIB_TRUE@@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_1 = -nodefaultrpaths -Wl,-rpath,@loader_path/
 subdir = libm2iso
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \
+       $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
+       $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
+       $(top_srcdir)/../config/acx.m4 \
        $(top_srcdir)/../config/depstand.m4 \
        $(top_srcdir)/../config/lead-dot.m4 \
        $(top_srcdir)/../config/multi.m4 \
        $(top_srcdir)/../config/no-executables.m4 \
-       $(top_srcdir)/../config/override.m4 \
-       $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
-       $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
-       $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac
+       $(top_srcdir)/../config/override.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 DIST_COMMON = $(srcdir)/Makefile.am
index 9b9b416bd1a60ca3e5bea2ce65cbc7a80c9c223d..e1e26f758c723866c79b206b61206371d234fb0f 100644 (file)
@@ -108,15 +108,15 @@ target_triplet = @target@
 @BUILD_LOGLIB_TRUE@@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_1 = -nodefaultrpaths -Wl,-rpath,@loader_path/
 subdir = libm2log
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \
+       $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
+       $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
+       $(top_srcdir)/../config/acx.m4 \
        $(top_srcdir)/../config/depstand.m4 \
        $(top_srcdir)/../config/lead-dot.m4 \
        $(top_srcdir)/../config/multi.m4 \
        $(top_srcdir)/../config/no-executables.m4 \
-       $(top_srcdir)/../config/override.m4 \
-       $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
-       $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
-       $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac
+       $(top_srcdir)/../config/override.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 DIST_COMMON = $(srcdir)/Makefile.am
index 4a909c7cd273011bef251c67f23a658f05f1b3a4..9d348b0f94338436b4f368261738c39f069d21dc 100644 (file)
@@ -108,15 +108,15 @@ target_triplet = @target@
 @ENABLE_DARWIN_AT_RPATH_TRUE@am__append_1 = -nodefaultrpaths -Wl,-rpath,@loader_path/
 subdir = libm2min
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \
+       $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
+       $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
+       $(top_srcdir)/../config/acx.m4 \
        $(top_srcdir)/../config/depstand.m4 \
        $(top_srcdir)/../config/lead-dot.m4 \
        $(top_srcdir)/../config/multi.m4 \
        $(top_srcdir)/../config/no-executables.m4 \
-       $(top_srcdir)/../config/override.m4 \
-       $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
-       $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
-       $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac
+       $(top_srcdir)/../config/override.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 DIST_COMMON = $(srcdir)/Makefile.am
index e64722e5c5251797fff0c786aafb6d4b822021d5..d0256f846ef5380ee208a3a0895b3e6f0460b859 100644 (file)
@@ -108,15 +108,15 @@ target_triplet = @target@
 @BUILD_PIMLIB_TRUE@@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_1 = -nodefaultrpaths -Wl,-rpath,@loader_path/
 subdir = libm2pim
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \
+       $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
+       $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
+       $(top_srcdir)/../config/acx.m4 \
        $(top_srcdir)/../config/depstand.m4 \
        $(top_srcdir)/../config/lead-dot.m4 \
        $(top_srcdir)/../config/multi.m4 \
        $(top_srcdir)/../config/no-executables.m4 \
-       $(top_srcdir)/../config/override.m4 \
-       $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
-       $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
-       $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac
+       $(top_srcdir)/../config/override.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 DIST_COMMON = $(srcdir)/Makefile.am
index a3954db5517e6b1d9e62a87554c7de772e2cad90..2e97648e522bbf02669fc674c50fe3d5352cef24 100644 (file)
@@ -1,6 +1,6 @@
 /* cgetopt.cc provide access to the C getopt library.
 
-Copyright (C) 2009-2022 Free Software Foundation, Inc.
+Copyright (C) 2009-2023 Free Software Foundation, Inc.
 Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
 
 This file is part of GNU Modula-2.
@@ -28,63 +28,34 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #include <stdlib.h>
 #include <getopt.h>
 #include <m2rts.h>
+#include <stdio.h>
+#include <config.h>
 
 #define EXPORT(FUNC) m2pim ## _cgetopt_ ## FUNC
 #define M2EXPORT(FUNC) m2pim ## _M2_cgetopt_ ## FUNC
 #define M2LIBNAME "m2pim"
 
+#if !defined(_)
+#define _(X) X
+#endif
+
 extern "C" {char *EXPORT(optarg);}
 extern "C" {int EXPORT(optind);}
 extern "C" {int EXPORT(opterr);}
 extern "C" {int EXPORT(optopt);}
 
-extern "C" char
-EXPORT(getopt) (int argc, char *argv[], char *optstring)
-{
-  char r = getopt (argc, argv, optstring);
-
-  EXPORT(optarg) = optarg;
-  EXPORT(optind) = optind;
-  EXPORT(opterr) = opterr;
-  EXPORT(optopt) = optopt;
-
-  if (r == (char)-1)
-    return (char)0;
-  return r;
-}
-
-extern "C" int
-EXPORT(getopt_long) (int argc, char *argv[], char *optstring,
-                    const struct option *longopts, int *longindex)
-{
-  int r = getopt_long (argc, argv, optstring, longopts, longindex);
-
-  EXPORT(optarg) = optarg;
-  EXPORT(optind) = optind;
-  EXPORT(opterr) = opterr;
-  EXPORT(optopt) = optopt;
-
-  return r;
-}
-
-extern "C" int
-EXPORT(getopt_long_only) (int argc, char *argv[], char *optstring,
-                         const struct option *longopts, int *longindex)
-{
-  int r = getopt_long_only (argc, argv, optstring, longopts, longindex);
-
-  EXPORT(optarg) = optarg;
-  EXPORT(optind) = optind;
-  EXPORT(opterr) = opterr;
-  EXPORT(optopt) = optopt;
+int
+libiberty_getopt_long_only (int argc, char *const *argv, const char *options,
+                           const struct option *long_options, int *opt_index);
+int
+libiberty_getopt_long (int argc,  char *const *argv,  const char *options,
+                      const struct option *long_options, int *opt_index);
 
-  return r;
-}
 
 typedef struct cgetopt_Options_s
 {
   struct option *cinfo;
-  unsigned int high;
+  unsigned int empty_slot;
 } cgetopt_Options;
 
 /* InitOptions a constructor for Options.  */
@@ -94,7 +65,7 @@ EXPORT(InitOptions) (void)
 {
   cgetopt_Options *o = (cgetopt_Options *)malloc (sizeof (cgetopt_Options));
   o->cinfo = (struct option *)malloc (sizeof (struct option));
-  o->high = 0;
+  o->empty_slot = 1;
   return o;
 }
 
@@ -113,16 +84,21 @@ EXPORT(KillOptions) (cgetopt_Options *o)
 
 extern "C" void
 EXPORT(SetOption) (cgetopt_Options *o, unsigned int index, char *name,
-                  bool has_arg, int *flag, int val)
+                  int has_arg, int *flag, int val)
 {
-  if (index > o->high)
+  if (index >= o->empty_slot)
     {
       o->cinfo
-          = (struct option *)malloc (sizeof (struct option) * (index + 1));
-      o->high = index + 1;
+       = (struct option *)realloc (o->cinfo,
+                                   sizeof (struct option) * (index + 1));
+      o->empty_slot = index + 1;
     }
   o->cinfo[index].name = name;
   o->cinfo[index].has_arg = has_arg;
+  /* Set flag to NULL if name is NULL, as flag comes from a VAR parameter
+     (which cannot be NIL in modula-2).  */
+  if (name == NULL)
+    flag = NULL;
   o->cinfo[index].flag = flag;
   o->cinfo[index].val = val;
 }
@@ -136,6 +112,962 @@ EXPORT(GetLongOptionArray) (cgetopt_Options *o)
   return o->cinfo;
 }
 
+
+/* The following code has been taken from libiberty/getopt.c and is
+   conditionally compiled if long option support is absent on the target.
+   It has been changed just to deal with the long option functions as we
+   assume all targets have getopt.  This code also keeps all data and code
+   static as the interface code only comes though functions defined in
+   cgetopt.def.  */
+
+#if (! defined(HAVE_GETOPT_LONG_ONLY)) || (! defined(HAVE_GETOPT_LONG))
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+static char *cgetopt_optarg = NULL;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns -1, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+/* 1003.2 says this must be 1 before any call.  */
+static int cgetopt_optind = 1;
+
+/* Formerly, initialization of getopt depended on optind==0, which
+   causes problems with re-calling getopt as programs generally don't
+   know that. */
+
+static int __getopt_initialized = 0;
+
+/* The next char to be scanned in the option-element
+   in which the last option character we returned was found.
+   This allows us to pick up the scan where we left off.
+
+   If this is zero, or a null string, it means resume the scan
+   by advancing to the next ARGV-element.  */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+   for unrecognized options.  */
+
+static int cgetopt_opterr = 1;
+
+/* Set to an option character which was unrecognized.
+   This must be initialized on some systems to avoid linking in the
+   system's own getopt implementation.  */
+
+static int cgetopt_optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+   If the caller did not specify anything,
+   the default is REQUIRE_ORDER if the environment variable
+   POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+   REQUIRE_ORDER means don't recognize them as options;
+   stop option processing when the first non-option is seen.
+   This is what Unix does.
+   This mode of operation is selected by either setting the environment
+   variable POSIXLY_CORRECT, or using `+' as the first character
+   of the list of option characters.
+
+   PERMUTE is the default.  We permute the contents of ARGV as we scan,
+   so that eventually all the non-options are at the end.  This allows options
+   to be given in any order, even with programs that were not written to
+   expect this.
+
+   RETURN_IN_ORDER is an option available to programs that were written
+   to expect options and other ARGV-elements in any order and that care about
+   the ordering of the two.  We describe each non-option ARGV-element
+   as if it were the argument of an option with character code 1.
+   Using `-' as the first character of the list of option characters
+   selects this mode of operation.
+
+   The special argument `--' forces an end of option-scanning regardless
+   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
+   `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
+
+static enum
+{
+  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+/* Value of POSIXLY_CORRECT environment variable.  */
+static char *posixly_correct;
+\f
+#ifdef __GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+   because there are many ways it can cause trouble.
+   On some systems, it contains special magic macros that don't work
+   in GCC.  */
+# include <string.h>
+# define my_index      strchr
+#else
+
+# if HAVE_STRING_H
+#  include <string.h>
+# else
+#  if HAVE_STRINGS_H
+#   include <strings.h>
+#  endif
+# endif
+
+/* Avoid depending on library functions or files
+   whose names are inconsistent.  */
+
+#if HAVE_STDLIB_H && HAVE_DECL_GETENV
+#  include <stdlib.h>
+#elif !defined(getenv)
+#  ifdef __cplusplus
+extern "C" {
+#  endif /* __cplusplus */
+extern char *getenv (const char *);
+#  ifdef __cplusplus
+}
+#  endif /* __cplusplus */
+#endif
+
+static char *
+my_index (const char *str, int chr)
+{
+  while (*str)
+    {
+      if (*str == chr)
+       return (char *) str;
+      str++;
+    }
+  return 0;
+}
+
+/* If using GCC, we can safely declare strlen this way.
+   If not using GCC, it is ok not to declare it.  */
+#ifdef __GNUC__
+/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
+   That was relevant to code that was here before.  */
+# if (!defined __STDC__ || !__STDC__) && !defined strlen
+/* gcc with -traditional declares the built-in strlen to return int,
+   and has done so at least since version 2.4.5. -- rms.  */
+extern int strlen (const char *);
+# endif /* not __STDC__ */
+#endif /* __GNUC__ */
+
+#endif /* not __GNU_LIBRARY__ */
+\f
+/* Handle permutation of arguments.  */
+
+/* Describe the part of ARGV that contains non-options that have
+   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
+   `last_nonopt' is the index after the last of them.  */
+
+static int first_nonopt;
+static int last_nonopt;
+
+#ifdef _LIBC
+/* Bash 2.0 gives us an environment variable containing flags
+   indicating ARGV elements that should not be considered arguments.  */
+
+/* Defined in getopt_init.c  */
+extern char *__getopt_nonoption_flags;
+
+static int nonoption_flags_max_len;
+static int nonoption_flags_len;
+
+static int original_argc;
+static char *const *original_argv;
+
+/* Make sure the environment variable bash 2.0 puts in the environment
+   is valid for the getopt call we must make sure that the ARGV passed
+   to getopt is that one passed to the process.  */
+static void
+__attribute__ ((unused))
+store_args_and_env (int argc, char *const *argv)
+{
+  /* XXX This is no good solution.  We should rather copy the args so
+     that we can compare them later.  But we must not use malloc(3).  */
+  original_argc = argc;
+  original_argv = argv;
+}
+# ifdef text_set_element
+text_set_element (__libc_subinit, store_args_and_env);
+# endif /* text_set_element */
+
+# define SWAP_FLAGS(ch1, ch2) \
+  if (nonoption_flags_len > 0)                                               \
+    {                                                                        \
+      char __tmp = __getopt_nonoption_flags[ch1];                            \
+      __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];         \
+      __getopt_nonoption_flags[ch2] = __tmp;                                 \
+    }
+#else  /* !_LIBC */
+# define SWAP_FLAGS(ch1, ch2)
+#endif /* _LIBC */
+
+/* Exchange two adjacent subsequences of ARGV.
+   One subsequence is elements [first_nonopt,last_nonopt)
+   which contains all the non-options that have been skipped so far.
+   The other is elements [last_nonopt,optind), which contains all
+   the options processed since those non-options were skipped.
+
+   `first_nonopt' and `last_nonopt' are relocated so that they describe
+   the new indices of the non-options in ARGV after they are moved.  */
+
+#if defined __STDC__ && __STDC__
+static void exchange (char **);
+#endif
+
+static void
+exchange (char **argv)
+{
+  int bottom = first_nonopt;
+  int middle = last_nonopt;
+  int top = cgetopt_optind;
+  char *tem;
+
+  /* Exchange the shorter segment with the far end of the longer segment.
+     That puts the shorter segment into the right place.
+     It leaves the longer segment in the right place overall,
+     but it consists of two parts that need to be swapped next.  */
+
+#ifdef _LIBC
+  /* First make sure the handling of the `__getopt_nonoption_flags'
+     string can work normally.  Our top argument must be in the range
+     of the string.  */
+  if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
+    {
+      /* We must extend the array.  The user plays games with us and
+        presents new arguments.  */
+      char *new_str = (char *) malloc (top + 1);
+      if (new_str == NULL)
+       nonoption_flags_len = nonoption_flags_max_len = 0;
+      else
+       {
+         memset (mempcpy (new_str, __getopt_nonoption_flags,
+                          nonoption_flags_max_len),
+                 '\0', top + 1 - nonoption_flags_max_len);
+         nonoption_flags_max_len = top + 1;
+         __getopt_nonoption_flags = new_str;
+       }
+    }
+#endif
+
+  while (top > middle && middle > bottom)
+    {
+      if (top - middle > middle - bottom)
+       {
+         /* Bottom segment is the short one.  */
+         int len = middle - bottom;
+         int i;
+
+         /* Swap it with the top part of the top segment.  */
+         for (i = 0; i < len; i++)
+           {
+             tem = argv[bottom + i];
+             argv[bottom + i] = argv[top - (middle - bottom) + i];
+             argv[top - (middle - bottom) + i] = tem;
+             SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
+           }
+         /* Exclude the moved bottom segment from further swapping.  */
+         top -= len;
+       }
+      else
+       {
+         /* Top segment is the short one.  */
+         int len = top - middle;
+         int i;
+
+         /* Swap it with the bottom part of the bottom segment.  */
+         for (i = 0; i < len; i++)
+           {
+             tem = argv[bottom + i];
+             argv[bottom + i] = argv[middle + i];
+             argv[middle + i] = tem;
+             SWAP_FLAGS (bottom + i, middle + i);
+           }
+         /* Exclude the moved top segment from further swapping.  */
+         bottom += len;
+       }
+    }
+
+  /* Update records for the slots the non-options now occupy.  */
+
+  first_nonopt += (cgetopt_optind - last_nonopt);
+  last_nonopt = cgetopt_optind;
+}
+
+/* Initialize the internal data when the first call is made.  */
+
+#if defined __STDC__ && __STDC__
+static const char *_getopt_initialize (int, char *const *, const char *);
+#endif
+static const char *
+_getopt_initialize (int argc, char *const *argv, const char *optstring)
+{
+  /* Start processing options with ARGV-element 1 (since ARGV-element 0
+     is the program name); the sequence of previously skipped
+     non-option ARGV-elements is empty.  */
+
+  first_nonopt = last_nonopt = cgetopt_optind;
+
+  nextchar = NULL;
+
+  posixly_correct = getenv ("POSIXLY_CORRECT");
+
+  /* Determine how to handle the ordering of options and nonoptions.  */
+
+  if (optstring[0] == '-')
+    {
+      ordering = RETURN_IN_ORDER;
+      ++optstring;
+    }
+  else if (optstring[0] == '+')
+    {
+      ordering = REQUIRE_ORDER;
+      ++optstring;
+    }
+  else if (posixly_correct != NULL)
+    ordering = REQUIRE_ORDER;
+  else
+    ordering = PERMUTE;
+
+#ifdef _LIBC
+  if (posixly_correct == NULL
+      && argc == original_argc && argv == original_argv)
+    {
+      if (nonoption_flags_max_len == 0)
+       {
+         if (__getopt_nonoption_flags == NULL
+             || __getopt_nonoption_flags[0] == '\0')
+           nonoption_flags_max_len = -1;
+         else
+           {
+             const char *orig_str = __getopt_nonoption_flags;
+             int len = nonoption_flags_max_len = strlen (orig_str);
+             if (nonoption_flags_max_len < argc)
+               nonoption_flags_max_len = argc;
+             __getopt_nonoption_flags =
+               (char *) malloc (nonoption_flags_max_len);
+             if (__getopt_nonoption_flags == NULL)
+               nonoption_flags_max_len = -1;
+             else
+               memset (mempcpy (__getopt_nonoption_flags, orig_str, len),
+                       '\0', nonoption_flags_max_len - len);
+           }
+       }
+      nonoption_flags_len = nonoption_flags_max_len;
+    }
+  else
+    nonoption_flags_len = 0;
+#endif
+
+  return optstring;
+}
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+   given in OPTSTRING.
+
+   If an element of ARGV starts with '-', and is not exactly "-" or "--",
+   then it is an option element.  The characters of this element
+   (aside from the initial '-') are option characters.  If `getopt'
+   is called repeatedly, it returns successively each of the option characters
+   from each of the option elements.
+
+   If `getopt' finds another option character, it returns that character,
+   updating `optind' and `nextchar' so that the next call to `getopt' can
+   resume the scan with the following option character or ARGV-element.
+
+   If there are no more option characters, `getopt' returns -1.
+   Then `optind' is the index in ARGV of the first ARGV-element
+   that is not an option.  (The ARGV-elements have been permuted
+   so that those that are not options now come last.)
+
+   OPTSTRING is a string containing the legitimate option characters.
+   If an option character is seen that is not listed in OPTSTRING,
+   return '?' after printing an error message.  If you set `opterr' to
+   zero, the error message is suppressed but we still return '?'.
+
+   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+   so the following text in the same ARGV-element, or the text of the following
+   ARGV-element, is returned in `optarg'.  Two colons mean an option that
+   wants an optional arg; if there is text in the current ARGV-element,
+   it is returned in `optarg', otherwise `optarg' is set to zero.
+
+   If OPTSTRING starts with `-' or `+', it requests different methods of
+   handling the non-option ARGV-elements.
+   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+   Long-named options begin with `--' instead of `-'.
+   Their names may be abbreviated as long as the abbreviation is unique
+   or is an exact match for some defined option.  If they have an
+   argument, it follows the option name in the same ARGV-element, separated
+   from the option name by a `=', or else the in next ARGV-element.
+   When `getopt' finds a long-named option, it returns 0 if that option's
+   `flag' field is nonzero, the value of the option's `val' field
+   if the `flag' field is zero.
+
+   The elements of ARGV aren't really const, because we permute them.
+   But we pretend they're const in the prototype to be compatible
+   with other systems.
+
+   LONGOPTS is a vector of `struct option' terminated by an
+   element containing a name which is zero.
+
+   LONGIND returns the index in LONGOPT of the long-named option found.
+   It is only valid when a long-named option has been found by the most
+   recent call.
+
+   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+   long-named options.  */
+
+static
+int
+_getopt_internal (int argc, char *const *argv, const char *optstring,
+                  const struct option *longopts,
+                  int *longind, int long_only)
+{
+  cgetopt_optarg = NULL;
+
+  if (cgetopt_optind == 0 || !__getopt_initialized)
+    {
+      if (cgetopt_optind == 0)
+       cgetopt_optind = 1;     /* Don't scan ARGV[0], the program name.  */
+      optstring = _getopt_initialize (argc, argv, optstring);
+      __getopt_initialized = 1;
+    }
+
+  /* Test whether ARGV[optind] points to a non-option argument.
+     Either it does not have option syntax, or there is an environment flag
+     from the shell indicating it is not an option.  The later information
+     is only used when the used in the GNU libc.  */
+#ifdef _LIBC
+# define NONOPTION_P (argv[cgetopt_optind][0] != '-' || argv[cgetopt_optind][1] == '\0'              \
+                     || (cgetopt_optind < nonoption_flags_len                        \
+                         && __getopt_nonoption_flags[cgetopt_optind] == '1'))
+#else
+# define NONOPTION_P (argv[cgetopt_optind][0] != '-' || argv[cgetopt_optind][1] == '\0')
+#endif
+
+  if (nextchar == NULL || *nextchar == '\0')
+    {
+      /* Advance to the next ARGV-element.  */
+
+      /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
+        moved back by the user (who may also have changed the arguments).  */
+      if (last_nonopt > cgetopt_optind)
+       last_nonopt = cgetopt_optind;
+      if (first_nonopt > cgetopt_optind)
+       first_nonopt = cgetopt_optind;
+
+      if (ordering == PERMUTE)
+       {
+         /* If we have just processed some options following some non-options,
+            exchange them so that the options come first.  */
+
+         if (first_nonopt != last_nonopt && last_nonopt != cgetopt_optind)
+           exchange ((char **) argv);
+         else if (last_nonopt != cgetopt_optind)
+           first_nonopt = cgetopt_optind;
+
+         /* Skip any additional non-options
+            and extend the range of non-options previously skipped.  */
+
+         while (cgetopt_optind < argc && NONOPTION_P)
+           cgetopt_optind++;
+         last_nonopt = cgetopt_optind;
+       }
+
+      /* The special ARGV-element `--' means premature end of options.
+        Skip it like a null option,
+        then exchange with previous non-options as if it were an option,
+        then skip everything else like a non-option.  */
+
+      if (cgetopt_optind != argc && !strcmp (argv[cgetopt_optind], "--"))
+       {
+         cgetopt_optind++;
+
+         if (first_nonopt != last_nonopt && last_nonopt != cgetopt_optind)
+           exchange ((char **) argv);
+         else if (first_nonopt == last_nonopt)
+           first_nonopt = cgetopt_optind;
+         last_nonopt = argc;
+
+         cgetopt_optind = argc;
+       }
+
+      /* If we have done all the ARGV-elements, stop the scan
+        and back over any non-options that we skipped and permuted.  */
+
+      if (cgetopt_optind == argc)
+       {
+         /* Set the next-arg-index to point at the non-options
+            that we previously skipped, so the caller will digest them.  */
+         if (first_nonopt != last_nonopt)
+           cgetopt_optind = first_nonopt;
+         return -1;
+       }
+
+      /* If we have come to a non-option and did not permute it,
+        either stop the scan or describe it to the caller and pass it by.  */
+
+      if (NONOPTION_P)
+       {
+         if (ordering == REQUIRE_ORDER)
+           return -1;
+         cgetopt_optarg = argv[cgetopt_optind++];
+         return 1;
+       }
+
+      /* We have found another option-ARGV-element.
+        Skip the initial punctuation.  */
+
+      nextchar = (argv[cgetopt_optind] + 1
+                 + (longopts != NULL && argv[cgetopt_optind][1] == '-'));
+    }
+
+  /* Decode the current option-ARGV-element.  */
+
+  /* Check whether the ARGV-element is a long option.
+
+     If long_only and the ARGV-element has the form "-f", where f is
+     a valid short option, don't consider it an abbreviated form of
+     a long option that starts with f.  Otherwise there would be no
+     way to give the -f short option.
+
+     On the other hand, if there's a long option "fubar" and
+     the ARGV-element is "-fu", do consider that an abbreviation of
+     the long option, just like "--fu", and not "-f" with arg "u".
+
+     This distinction seems to be the most useful approach.  */
+
+  if (longopts != NULL
+      && (argv[cgetopt_optind][1] == '-'
+         || (long_only && (argv[cgetopt_optind][2] || !my_index (optstring, argv[cgetopt_optind][1])))))
+    {
+      char *nameend;
+      const struct option *p;
+      const struct option *pfound = NULL;
+      int exact = 0;
+      int ambig = 0;
+      int indfound = -1;
+      int option_index;
+
+      for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+       /* Do nothing.  */ ;
+
+      /* Test all long options for either exact match
+        or abbreviated matches.  */
+      for (p = longopts, option_index = 0; p->name; p++, option_index++)
+       if (!strncmp (p->name, nextchar, nameend - nextchar))
+         {
+           if ((unsigned int) (nameend - nextchar)
+               == (unsigned int) strlen (p->name))
+             {
+               /* Exact match found.  */
+               pfound = p;
+               indfound = option_index;
+               exact = 1;
+               break;
+             }
+           else if (pfound == NULL)
+             {
+               /* First nonexact match found.  */
+               pfound = p;
+               indfound = option_index;
+             }
+           else
+             /* Second or later nonexact match found.  */
+             ambig = 1;
+         }
+
+      if (ambig && !exact)
+       {
+         if (cgetopt_opterr)
+           fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
+                    argv[0], argv[cgetopt_optind]);
+         nextchar += strlen (nextchar);
+         cgetopt_optind++;
+         cgetopt_optopt = 0;
+         return '?';
+       }
+
+      if (pfound != NULL)
+       {
+         option_index = indfound;
+         cgetopt_optind++;
+         if (*nameend)
+           {
+             /* Don't test has_arg with >, because some C compilers don't
+                allow it to be used on enums.  */
+             if (pfound->has_arg)
+               cgetopt_optarg = nameend + 1;
+             else
+               {
+                 if (cgetopt_opterr)
+                   {
+                     if (argv[cgetopt_optind - 1][1] == '-')
+                       /* --option */
+                       fprintf (stderr,
+                                _("%s: option `--%s' doesn't allow an argument\n"),
+                                argv[0], pfound->name);
+                     else
+                       /* +option or -option */
+                       fprintf (stderr,
+                                _("%s: option `%c%s' doesn't allow an argument\n"),
+                                argv[0], argv[cgetopt_optind - 1][0], pfound->name);
+
+                     nextchar += strlen (nextchar);
+
+                     cgetopt_optopt = pfound->val;
+                     return '?';
+                   }
+               }
+           }
+         else if (pfound->has_arg == 1)
+           {
+             if (cgetopt_optind < argc)
+               cgetopt_optarg = argv[cgetopt_optind++];
+             else
+               {
+                 if (cgetopt_opterr)
+                   fprintf (stderr,
+                          _("%s: option `%s' requires an argument\n"),
+                          argv[0], argv[cgetopt_optind - 1]);
+                 nextchar += strlen (nextchar);
+                 cgetopt_optopt = pfound->val;
+                 return optstring[0] == ':' ? ':' : '?';
+               }
+           }
+         nextchar += strlen (nextchar);
+         if (longind != NULL)
+           *longind = option_index;
+         if (pfound->flag)
+           {
+             *(pfound->flag) = pfound->val;
+             return 0;
+           }
+         return pfound->val;
+       }
+
+      /* Can't find it as a long option.  If this is not getopt_long_only,
+        or the option starts with '--' or is not a valid short
+        option, then it's an error.
+        Otherwise interpret it as a short option.  */
+      if (!long_only || argv[cgetopt_optind][1] == '-'
+         || my_index (optstring, *nextchar) == NULL)
+       {
+         if (cgetopt_opterr)
+           {
+             if (argv[cgetopt_optind][1] == '-')
+               /* --option */
+               fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
+                        argv[0], nextchar);
+             else
+               /* +option or -option */
+               fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
+                        argv[0], argv[cgetopt_optind][0], nextchar);
+           }
+         nextchar = (char *) "";
+         cgetopt_optind++;
+         cgetopt_optopt = 0;
+         return '?';
+       }
+    }
+
+  /* Look at and handle the next short option-character.  */
+
+  {
+    char c = *nextchar++;
+    const char *temp = my_index (optstring, c);
+
+    /* Increment `cgetopt_optind' when we start to process its last character.  */
+    if (*nextchar == '\0')
+      ++cgetopt_optind;
+
+    if (temp == NULL || c == ':')
+      {
+       if (cgetopt_opterr)
+         {
+           if (posixly_correct)
+             /* 1003.2 specifies the format of this message.  */
+             fprintf (stderr, _("%s: illegal option -- %c\n"),
+                      argv[0], c);
+           else
+             fprintf (stderr, _("%s: invalid option -- %c\n"),
+                      argv[0], c);
+         }
+       cgetopt_optopt = c;
+       return '?';
+      }
+    /* Convenience. Treat POSIX -W foo same as long option --foo */
+    if (temp[0] == 'W' && temp[1] == ';')
+      {
+       char *nameend;
+       const struct option *p;
+       const struct option *pfound = NULL;
+       int exact = 0;
+       int ambig = 0;
+       int indfound = 0;
+       int option_index;
+
+       /* This is an option that requires an argument.  */
+       if (*nextchar != '\0')
+         {
+           cgetopt_optarg = nextchar;
+           /* If we end this ARGV-element by taking the rest as an arg,
+              we must advance to the next element now.  */
+           cgetopt_optind++;
+         }
+       else if (cgetopt_optind == argc)
+         {
+           if (cgetopt_opterr)
+             {
+               /* 1003.2 specifies the format of this message.  */
+               fprintf (stderr, _("%s: option requires an argument -- %c\n"),
+                        argv[0], c);
+             }
+           cgetopt_optopt = c;
+           if (optstring[0] == ':')
+             c = ':';
+           else
+             c = '?';
+           return c;
+         }
+       else
+         /* We already incremented `optind' once;
+            increment it again when taking next ARGV-elt as argument.  */
+         cgetopt_optarg = argv[cgetopt_optind++];
+
+       /* cgetopt_optarg is now the argument, see if it's in the
+          table of longopts.  */
+
+       for (nextchar = nameend = cgetopt_optarg; *nameend && *nameend != '='; nameend++)
+         /* Do nothing.  */ ;
+
+       /* Test all long options for either exact match
+          or abbreviated matches.  */
+       for (p = longopts, option_index = 0; p->name; p++, option_index++)
+         if (!strncmp (p->name, nextchar, nameend - nextchar))
+           {
+             if ((unsigned int) (nameend - nextchar) == strlen (p->name))
+               {
+                 /* Exact match found.  */
+                 pfound = p;
+                 indfound = option_index;
+                 exact = 1;
+                 break;
+               }
+             else if (pfound == NULL)
+               {
+                 /* First nonexact match found.  */
+                 pfound = p;
+                 indfound = option_index;
+               }
+             else
+               /* Second or later nonexact match found.  */
+               ambig = 1;
+           }
+       if (ambig && !exact)
+         {
+           if (cgetopt_opterr)
+             fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
+                      argv[0], argv[cgetopt_optind]);
+           nextchar += strlen (nextchar);
+           cgetopt_optind++;
+           return '?';
+         }
+       if (pfound != NULL)
+         {
+           option_index = indfound;
+           if (*nameend)
+             {
+               /* Don't test has_arg with >, because some C compilers don't
+                  allow it to be used on enums.  */
+               if (pfound->has_arg)
+                 cgetopt_optarg = nameend + 1;
+               else
+                 {
+                   if (cgetopt_opterr)
+                     fprintf (stderr, _("\
+%s: option `-W %s' doesn't allow an argument\n"),
+                              argv[0], pfound->name);
+
+                   nextchar += strlen (nextchar);
+                   return '?';
+                 }
+             }
+           else if (pfound->has_arg == 1)
+             {
+               if (cgetopt_optind < argc)
+                 cgetopt_optarg = argv[cgetopt_optind++];
+               else
+                 {
+                   if (cgetopt_opterr)
+                     fprintf (stderr,
+                              _("%s: option `%s' requires an argument\n"),
+                              argv[0], argv[cgetopt_optind - 1]);
+                   nextchar += strlen (nextchar);
+                   return optstring[0] == ':' ? ':' : '?';
+                 }
+             }
+           nextchar += strlen (nextchar);
+           if (longind != NULL)
+             *longind = option_index;
+           if (pfound->flag)
+             {
+               *(pfound->flag) = pfound->val;
+               return 0;
+             }
+           return pfound->val;
+         }
+         nextchar = NULL;
+         return 'W';   /* Let the application handle it.   */
+      }
+    if (temp[1] == ':')
+      {
+       if (temp[2] == ':')
+         {
+           /* This is an option that accepts an argument optionally.  */
+           if (*nextchar != '\0')
+             {
+               cgetopt_optarg = nextchar;
+               cgetopt_optind++;
+             }
+           else
+             cgetopt_optarg = NULL;
+           nextchar = NULL;
+         }
+       else
+         {
+           /* This is an option that requires an argument.  */
+           if (*nextchar != '\0')
+             {
+               cgetopt_optarg = nextchar;
+               /* If we end this ARGV-element by taking the rest as an arg,
+                  we must advance to the next element now.  */
+               cgetopt_optind++;
+             }
+           else if (cgetopt_optind == argc)
+             {
+               if (cgetopt_opterr)
+                 {
+                   /* 1003.2 specifies the format of this message.  */
+                   fprintf (stderr,
+                          _("%s: option requires an argument -- %c\n"),
+                          argv[0], c);
+                 }
+               cgetopt_optopt = c;
+               if (optstring[0] == ':')
+                 c = ':';
+               else
+                 c = '?';
+             }
+           else
+             /* We already incremented `optind' once;
+                increment it again when taking next ARGV-elt as argument.  */
+             cgetopt_optarg = argv[cgetopt_optind++];
+           nextchar = NULL;
+         }
+      }
+    return c;
+  }
+}
+
+int
+libiberty_getopt_long (int argc,  char *const *argv,  const char *options,
+                      const struct option *long_options, int *opt_index)
+{
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+   If an option that starts with '-' (not '--') doesn't match a long option,
+   but does match a short option, it is parsed as a short option
+   instead.  */
+
+int
+libiberty_getopt_long_only (int argc, char *const *argv, const char *options,
+                           const struct option *long_options, int *opt_index)
+{
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+#endif
+
+
+extern "C" char
+EXPORT(getopt) (int argc, char *argv[], char *optstring)
+{
+  char r = getopt (argc, argv, optstring);
+
+  EXPORT(optarg) = optarg;
+  EXPORT(optind) = optind;
+  EXPORT(opterr) = opterr;
+  EXPORT(optopt) = optopt;
+
+  if (r == (char)-1)
+    return (char)0;
+  return r;
+}
+
+extern "C" int
+EXPORT(getopt_long) (int argc, char *argv[], char *optstring,
+                    const struct option *longopts, int *longindex)
+{
+#if defined(HAVE_GETOPT_LONG)
+  int r = getopt_long (argc, argv, optstring, longopts, longindex);
+
+  EXPORT(optarg) = optarg;
+  EXPORT(optind) = optind;
+  EXPORT(opterr) = opterr;
+  EXPORT(optopt) = optopt;
+#else
+  int r = libiberty_getopt_long (argc, argv, optstring, longopts, longindex);
+
+  EXPORT(optarg) = cgetopt_optarg;
+  EXPORT(optind) = cgetopt_optind;
+  EXPORT(opterr) = cgetopt_opterr;
+  EXPORT(optopt) = cgetopt_optopt;
+#endif
+
+  return r;
+}
+
+
+extern "C" int
+EXPORT(getopt_long_only) (int argc, char *argv[], char *optstring,
+                         const struct option *longopts, int *longindex)
+{
+#if defined(HAVE_GETOPT_LONG_ONLY)
+  int r = getopt_long_only (argc, argv, optstring, longopts, longindex);
+
+  EXPORT(optarg) = optarg;
+  EXPORT(optind) = optind;
+  EXPORT(opterr) = opterr;
+  EXPORT(optopt) = optopt;
+#else
+  int r = libiberty_getopt_long_only (argc, argv, optstring, longopts, longindex);
+
+  EXPORT(optarg) = cgetopt_optarg;
+  EXPORT(optind) = cgetopt_optind;
+  EXPORT(opterr) = cgetopt_opterr;
+  EXPORT(optopt) = cgetopt_optopt;
+#endif
+
+  return r;
+}
+
+
 /* GNU Modula-2 linking fodder.  */
 
 extern "C" void