mlibc: Mescc-tools support: getopt, getopt_long.
authorJan Nieuwenhuizen <janneke@gnu.org>
Sun, 19 Nov 2017 15:48:37 +0000 (16:48 +0100)
committerJan Nieuwenhuizen <janneke@gnu.org>
Sun, 19 Nov 2017 15:48:37 +0000 (16:48 +0100)
* mlibc/getopt.c: Move to ANSI C.  Remove GETOPT_COMPAT and
  non-POSIXLY_CORRECT options.
* mlibc/include/getopt.h: New file.
* mlibc/libc-gcc+tcc.c: Include getopt.c.
* mlibc/libc-mes+tcc.c: Likewise.

mlibc/getopt.c
mlibc/include/getopt.h [new file with mode: 0644]
mlibc/libc-gcc+tcc.c
mlibc/libc-mes+tcc.c

index e13fac3bf08d06264a5c9a3eb0e4fa4dfc9ac955..91555ab19a094a05b7874246b9ca2a432096faa7 100644 (file)
@@ -1,9 +1,6 @@
 /* Getopt for GNU.
-   NOTE: getopt is now part of the C library, so if you don't know what
-   "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
-   before changing it!
-
    Copyright (C) 1987, 88, 89, 90, 91, 1992 Free Software Foundation, Inc.
+   Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 \f
-/* AIX requires this to be the first thing in the file. */
-#ifdef __GNUC__
-#define alloca __builtin_alloca
-#else /* not __GNUC__ */
-#ifdef sparc
-#include <alloca.h>
-#else
-#ifdef _AIX
- #pragma alloca
-#else
-char *alloca ();
-#endif
-#endif /* sparc */
-#endif /* not __GNUC__ */
-
-#ifdef LIBC
-/* For when compiled as part of the GNU C library.  */
-#include <ansidecl.h>
-#endif
 
 #include <stdio.h>
+#include <string.h>
+#include <getopt.h>
 
-/* This needs to come after some library #include
-   to get __GNU_LIBRARY__ defined.  */
-#ifdef __GNU_LIBRARY__
-#undef alloca
-#include <stdlib.h>
-#else  /* Not GNU C library.  */
-#define        __alloca        alloca
-#endif /* GNU C library.  */
-
-
-#ifndef __STDC__
-#define const
+#if __MESC__
+#define static
 #endif
 
-/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
-   long-named option.  Because this is not POSIX.2 compliant, it is
-   being phased out. */
-#define GETOPT_COMPAT
-
-/* This version of `getopt' appears to the caller like standard Unix `getopt'
-   but it behaves differently for the user, since it allows the user
-   to intersperse the options with the other arguments.
-
-   As `getopt' works, it permutes the elements of ARGV so that,
-   when it is done, all the options precede everything else.  Thus
-   all application programs are extended to handle flexible argument order.
-
-   Setting the environment variable POSIXLY_CORRECT disables permutation.
-   Then the behavior is completely standard.
-
-   GNU application programs can use a third alternative mode in which
-   they can distinguish the relative order of options and other arguments.  */
-
-#include "getopt.h"
-
 /* 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.  */
+   the argument value is returned here. */
 
 char *optarg = 0;
 
@@ -112,75 +59,6 @@ static char *nextchar;
 
 int opterr = 1;
 
-/* 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 EOF with `optind' != ARGC.  */
-
-static enum
-{
-  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
-} ordering;
-\f
-#ifdef __GNU_LIBRARY__
-#include <string.h>
-#define        my_index        strchr
-#define        my_bcopy(src, dst, n)   memcpy ((dst), (src), (n))
-#else
-
-/* Avoid depending on library functions or files
-   whose names are inconsistent.  */
-
-char *getenv ();
-
-static char *
-my_index (string, chr)
-     char *string;
-     int chr;
-{
-  while (*string)
-    {
-      if (*string == chr)
-       return string;
-      string++;
-    }
-  return 0;
-}
-
-static void
-my_bcopy (from, to, size)
-     char *from, *to;
-     int size;
-{
-  int i;
-  for (i = 0; i < size; i++)
-    to[i] = from[i];
-}
-#endif                         /* GNU C library.  */
 \f
 /* Handle permutation of arguments.  */
 
@@ -191,34 +69,6 @@ my_bcopy (from, to, size)
 static int first_nonopt;
 static int last_nonopt;
 
-/* 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.  */
-
-static void
-exchange (argv)
-     char **argv;
-{
-  int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *);
-  char **temp = (char **) __alloca (nonopts_size);
-
-  /* Interchange the two blocks of data in ARGV.  */
-
-  my_bcopy (&argv[first_nonopt], temp, nonopts_size);
-  my_bcopy (&argv[last_nonopt], &argv[first_nonopt],
-           (optind - last_nonopt) * sizeof (char *));
-  my_bcopy (temp, &argv[first_nonopt + optind - last_nonopt], nonopts_size);
-
-  /* Update records for the slots the non-options now occupy.  */
-
-  first_nonopt += (optind - last_nonopt);
-  last_nonopt = optind;
-}
 \f
 /* Scan elements of ARGV (whose length is ARGC) for option characters
    given in OPTSTRING.
@@ -251,7 +101,6 @@ exchange (argv)
 
    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
@@ -277,13 +126,8 @@ exchange (argv)
    long-named options.  */
 
 int
-_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
-     int argc;
-     char *const *argv;
-     const char *optstring;
-     const struct option *longopts;
-     int *longind;
-     int long_only;
+_getopt_internal (int argc, char *const
+                  *argv, char const *optstring, struct option const *longopts, int *longind, int long_only)
 {
   int option_index;
 
@@ -299,69 +143,10 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
       first_nonopt = last_nonopt = optind = 1;
 
       nextchar = NULL;
-
-      /* 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 (getenv ("POSIXLY_CORRECT") != NULL)
-       ordering = REQUIRE_ORDER;
-      else
-       ordering = PERMUTE;
     }
 
   if (nextchar == NULL || *nextchar == '\0')
     {
-      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 != optind)
-           exchange ((char **) argv);
-         else if (last_nonopt != optind)
-           first_nonopt = optind;
-
-         /* Now skip any additional non-options
-            and extend the range of non-options previously skipped.  */
-
-         while (optind < argc
-                && (argv[optind][0] != '-' || argv[optind][1] == '\0')
-#ifdef GETOPT_COMPAT
-                && (longopts == NULL
-                    || argv[optind][0] != '+' || argv[optind][1] == '\0')
-#endif                         /* GETOPT_COMPAT */
-                )
-           optind++;
-         last_nonopt = optind;
-       }
-
-      /* 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 (optind != argc && !strcmp (argv[optind], "--"))
-       {
-         optind++;
-
-         if (first_nonopt != last_nonopt && last_nonopt != optind)
-           exchange ((char **) argv);
-         else if (first_nonopt == last_nonopt)
-           first_nonopt = optind;
-         last_nonopt = argc;
-
-         optind = argc;
-       }
-
       /* If we have done all the ARGV-elements, stop the scan
         and back over any non-options that we skipped and permuted.  */
 
@@ -377,18 +162,8 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
       /* 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 ((argv[optind][0] != '-' || argv[optind][1] == '\0')
-#ifdef GETOPT_COMPAT
-         && (longopts == NULL
-             || argv[optind][0] != '+' || argv[optind][1] == '\0')
-#endif                         /* GETOPT_COMPAT */
-         )
-       {
-         if (ordering == REQUIRE_ORDER)
-           return EOF;
-         optarg = argv[optind++];
-         return 1;
-       }
+      if ((argv[optind][0] != '-' || argv[optind][1] == '\0'))
+        return EOF;
 
       /* We have found another option-ARGV-element.
         Start decoding its characters.  */
@@ -399,11 +174,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
 
   if (longopts != NULL
       && ((argv[optind][0] == '-'
-          && (argv[optind][1] == '-' || long_only))
-#ifdef GETOPT_COMPAT
-         || argv[optind][0] == '+'
-#endif                         /* GETOPT_COMPAT */
-         ))
+          && (argv[optind][1] == '-' || long_only))))
     {
       const struct option *p;
       char *s = nextchar;
@@ -506,10 +277,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
         option, then it's an error.
         Otherwise interpret it as a short option. */
       if (!long_only || argv[optind][1] == '-'
-#ifdef GETOPT_COMPAT
-         || argv[optind][0] == '+'
-#endif                         /* GETOPT_COMPAT */
-         || my_index (optstring, *nextchar) == NULL)
+         || strchr (optstring, *nextchar) == NULL)
        {
          if (opterr)
            {
@@ -532,7 +300,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
 
   {
     char c = *nextchar++;
-    char *temp = my_index (optstring, c);
+    char *temp = strchr (optstring, c);
 
     /* Increment `optind' when we start to process its last character.  */
     if (*nextchar == '\0')
@@ -593,85 +361,16 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
 }
 
 int
-getopt (argc, argv, optstring)
-     int argc;
-     char *const *argv;
-     const char *optstring;
+getopt (int argc, char *const *argv, char const *optstring)
 {
   return _getopt_internal (argc, argv, optstring,
                           (const struct option *) 0,
                           (int *) 0,
                           0);
 }
-\f
-#ifdef TEST
-
-/* Compile with -DTEST to make an executable for use in testing
-   the above definition of `getopt'.  */
 
 int
-main (argc, argv)
-     int argc;
-     char **argv;
+getopt_long (int argc, char *const *argv, const char *options, struct option const *long_options, int *opt_index)
 {
-  int c;
-  int digit_optind = 0;
-
-  while (1)
-    {
-      int this_option_optind = optind ? optind : 1;
-
-      c = getopt (argc, argv, "abc:d:0123456789");
-      if (c == EOF)
-       break;
-
-      switch (c)
-       {
-       case '0':
-       case '1':
-       case '2':
-       case '3':
-       case '4':
-       case '5':
-       case '6':
-       case '7':
-       case '8':
-       case '9':
-         if (digit_optind != 0 && digit_optind != this_option_optind)
-           printf ("digits occur in two different argv-elements.\n");
-         digit_optind = this_option_optind;
-         printf ("option %c\n", c);
-         break;
-
-       case 'a':
-         printf ("option a\n");
-         break;
-
-       case 'b':
-         printf ("option b\n");
-         break;
-
-       case 'c':
-         printf ("option c with value `%s'\n", optarg);
-         break;
-
-       case '?':
-         break;
-
-       default:
-         printf ("?? getopt returned character code 0%o ??\n", c);
-       }
-    }
-
-  if (optind < argc)
-    {
-      printf ("non-option ARGV-elements: ");
-      while (optind < argc)
-       printf ("%s ", argv[optind++]);
-      printf ("\n");
-    }
-
-  exit (0);
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
 }
-
-#endif /* TEST */
diff --git a/mlibc/include/getopt.h b/mlibc/include/getopt.h
new file mode 100644 (file)
index 0000000..85e4b50
--- /dev/null
@@ -0,0 +1,60 @@
+/* -*-comment-start: "//";comment-end:""-*-
+ * Mes --- Maxwell Equations of Software
+ * Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
+ * Copyright © 2017 Jan Nieuwenhuizen <janneke@gnu.org>
+ *
+ * This file is part of Mes.
+ *
+ * Mes is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Mes 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 Mes.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __MES_GETOPT_H
+#define __MES_GETOPT_H 1
+
+#if __GNUC__ && POSIX
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#undef __MES_GETOPT_H
+#include_next <getopt.h>
+
+#else // ! (__GNUC__ && POSIX)
+#include <endian.h>
+int isdigit (int);
+int isxdigit (int);
+#endif // ! (__GNUC__ && POSIX)
+
+char *optarg;
+int optind;
+int opterr;
+struct option
+{
+  char const *name;
+  int has_arg;
+  int *flag;
+  int val;
+};
+
+enum _argtype
+{
+  no_argument,
+  required_argument,
+  optional_argument
+};
+
+int getopt (int argc, char *const *argv, char const *shortopts);
+int getopt_long (int argc, char *const *argv, char const *shortopts,
+                 struct option const *longopts, int *longind);
+
+#endif // __MES_GETOPT_H
+
index d6ed603bbc70e8fa14b971fb881bdab3c9150ff0..18ac36dcab41306a958a5727b1b979c05e0fd177 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <libc-gcc.c>
 #include <libc-mes+tcc.c>
+#include <getopt.c>
 
 int errno;
 
index 5aff13609912ae732394584df2838fad84b123aa..087253a214f652eeef1d5525d84d41426bbcf001 100644 (file)
@@ -31,6 +31,7 @@
 
 #if !__GNUC__ && !__TINYC__
 #include <libc-mes.c>
+#include <getopt.c>
 
 int errno;