getopt_long: add program name to warnx
authorgit <redacted>
Mon, 20 Apr 2026 16:30:56 +0000 (12:30 -0400)
committergit <redacted>
Mon, 20 Apr 2026 16:30:56 +0000 (12:30 -0400)
formatting overhaul

asprintf.h
getopt_long.h

index fc66ba5c294603abe39add0fe8810167bf863d2e..ddce911bff42210a5b1888d286c0846643783e59 100644 (file)
 
 /* https://git.datadissipation.net */
 #ifndef ASPRINTF_H_
- #define ASPRINTF_H_ 1
+ #define ASPRINTF_H_            1
 
-#ifdef ASPRINTF_INCLUDE_LIBC
+ #ifdef ASPRINTF_INCLUDE_LIBC
   #include <stdarg.h>
   #include <stdio.h>
   #include <stdlib.h>
-#endif /* ASPRINTF_INCLUDE_LIBC */
+ #endif /* ASPRINTF_INCLUDE_LIBC */
 
-#ifndef HAVE_ASPRINTF
-  #define HAVE_ASPRINTF 1
-  #define asprintf  i_asprintf_
-  #define vasprintf i_vasprintf_
-  int i_vasprintf_(char **strp, const char *fmt, va_list ap);
-  int i_asprintf_(char **strp, const char *fmt, ...);
-#endif /* !HAVE_ASPRINTF */
+ #ifndef HAVE_ASPRINTF
+  #define HAVE_ASPRINTF         1
+  #define asprintf              i_asprintf_
+  #define vasprintf             i_vasprintf_
+int i_vasprintf_(char **strp, const char *fmt, va_list ap);
+int i_asprintf_(char **strp, const char *fmt, ...);
+ #endif /* !HAVE_ASPRINTF */
 
-#ifdef ASPRINTF_IMPLEMENTATION
+ #ifdef ASPRINTF_IMPLEMENTATION
 int
 i_vasprintf_(char **strp, const char *fmt, va_list ap)
 {
-       int size, ret;
-       va_list tp;
+       int size;
+       va_list tp;
 
        va_copy(tp, ap);
        size = vsnprintf(NULL, 0, fmt, tp);
        va_end(tp);
 
-       if (size < 0) {
+       if (size < 0 || !(*strp = malloc(size + 1)))
                return -1;
-       }
-       *strp = malloc(size + 1);
-       if (*strp == NULL) {
-               return -1;
-       }
-
-       ret = vsnprintf(*strp, size + 1, fmt, ap);
-       if (ret < 0) {
-               free(*strp);
-               return -1;
-       }
 
-       return ret;
+       return vsnprintf(*strp, size + 1, fmt, ap);
 }
 
 int
@@ -83,5 +72,5 @@ i_asprintf_(char **strp, const char *fmt, ...)
 
        return ret;
 }
-#endif /* ASPRINTF_IMPLEMENTATION */
+ #endif /* ASPRINTF_IMPLEMENTATION */
 #endif /* !ASPRINTF_H_ */
index 41f59de5e50651a3e76a7f247ee07a15eb172ca9..4778009409ad23f13d769c3ab3e5ba4dd67eb860 100644 (file)
@@ -78,7 +78,7 @@
 
 /* https://git.datadissipation.net */
 #ifndef GETOPT_LONG_H_
- #define GETOPT_LONG_H_ 1
+ #define GETOPT_LONG_H_         1
 
  #ifdef GETOPT_LONG_INCLUDE_LIBC
   #include <stdarg.h>
  #endif /* GETOPT_LONG_INCLUDE_LIBC */
 
  #ifndef HAVE_GETOPT_LONG
-  #define HAVE_GETOPT_LONG 1
-
-  #define no_argument        0
-  #define required_argument  1
-  #define optional_argument  2
-
-  /* 
  * structs are in their own namespace, so this should be OK
  * the worst it can do is make compiler messages worse
  */
-  #define option i_option_
-
-  #define optarg    i_optarg_
-  #define suboptarg i_suboptarg_
-  #define optind    i_optind_
-  #define opterr    i_opterr_
-  #define optopt    i_optopt_
-  #define optreset  i_optreset_
-
-  #define getopt                      i_getopt_
-  #define getsubopt                   i_getsubopt_
-  #define getopt_long                 i_getopt_long_
-  #define getopt_long_only            i_getopt_long_only_
+  #define HAVE_GETOPT_LONG      1
+
+  #define no_argument           0
+  #define required_argument     1
+  #define optional_argument     2
+
+/*
+ * structs are in their own namespace, so this should be OK
+ * the worst it can do is make compiler messages worse
+ */
+  #define option                i_option_
+
+  #define optarg                i_optarg_
+  #define suboptarg             i_suboptarg_
+  #define optind                i_optind_
+  #define opterr                i_opterr_
+  #define optopt                i_optopt_
+  #define optreset              i_optreset_
+
+  #define getopt                i_getopt_
+  #define getsubopt             i_getsubopt_
+  #define getopt_long           i_getopt_long_
+  #define getopt_long_only      i_getopt_long_only_
 
   #ifndef GETOPT_LONG_IMPLEMENTATION
-   extern char *i_optarg_;
-   extern char *i_suboptarg_;
-   extern int  i_optind_, i_opterr_, i_optopt_, i_optreset_;
+extern char *i_optarg_;
+extern char *i_suboptarg_;
+extern int i_optind_, i_opterr_, i_optopt_, i_optreset_;
   #endif /* !GETOPT_LONG_IMPLEMENTATION */
 
-  struct i_option_ {
+struct i_option_ {
        const char *name;
        /*
         * one of no_argument, required_argument, and optional_argument:
        int *flag;
        /* if flag not NULL, value to set *flag to; else return value */
        int val;
-  };
+};
 
-  int  i_getopt_(int argc, char * const *argv, const char *optstring);
-  int  i_getsubopt_(char **optionp, char * const *tokens, char **valuep);
-  int  i_getopt_long_(int argc, char * const *argv, const char *optstring,
-                      const struct option *longopts, int *longindex);
-  int  i_getopt_long_only_(int argc, char * const *argv, const char *optstring,
-                           const struct option *longopts, int *longindex);
+int   i_getopt_(int argc, char * const *argv, const char *optstring);
+int   i_getsubopt_(char **optionp, char * const *tokens, char **valuep);
+int   i_getopt_long_(int argc, char * const *argv, const char *optstring,
+                    const struct option *longopts, int *longindex);
+int   i_getopt_long_only_(int argc, char * const *argv, const char *optstring,
+                         const struct option *longopts, int *longindex);
 
  #endif /* !HAVE_GETOPT_LONG */
+
  #ifdef GETOPT_LONG_IMPLEMENTATION
   #define I_PRINT_ERROR_       ((i_opterr_) && (*options != ':'))
 
-  #define I_FLAG_PERMUTE_      0x01    /* permute non-options to the end of argv */
-  #define I_FLAG_ALLARGS_      0x02    /* treat non-options as args to option "-1" */
-  #define I_FLAG_LONGONLY_     0x04    /* operate as getopt_long_only */
-
-  /* return values */
-  #define      I_BADCH_                (int)'?'
-  #define      I_BADARG_               ((*options == ':') ? (int)':' : (int)'?')
-  #define      I_INORDER_              (int)1
-
-  #define      I_EMSG_                 ""
-
-  int  i_opterr_ = 1;          /* if error message should be printed */
-  int  i_optind_ = 1;          /* index into parent argv vector */
-  int  i_optopt_ = '?';        /* character checked for validity */
-  int   i_optreset_;            /* reset getopt */
-  char  *i_optarg_;            /* argument associated with option */
-  char  *i_suboptarg_;          /* argument associated with suboption */
-
-  /* XXX: set optreset to 1 rather than these two */
-  static int   i_nonopt_start_ = -1;   /* first non option argument (for permute) */
-  static int   i_nonopt_end_ = -1;     /* first option after non options (for permute) */
-  static char   *i_place_ = I_EMSG_;    /* option letter processing */
-  
-  /* Error messages */
-  static const char i_recargchar_[] = "option requires an argument -- %c";
-  static const char i_recargstring_[] = "option requires an argument -- %s";
-  static const char i_ambig_[] = "i_ambig_uous option -- %.*s";
-  static const char i_noarg_[] = "option doesn't take an argument -- %.*s";
-  static const char i_illoptchar_[] = "unknown option -- %c";
-  static const char i_illoptstring_[] = "unknown option -- %s";
-
-  static void i_warnx_(const char *, ...);
-  static int  i_getopt_internal_(int, char * const *, const char *,
-                             const struct option *, int *, int);
-  static int  i_parse_long_options__(char * const *, const char *,
-                             const struct option *, int *, int);
-  static int  i_gcd_(int, int);
-  static void i_permute_args_(int, int, int, char * const *);
-
-  /*
-   * Own warnx() for portability
-   */
-  void
-  i_warnx_(const char *fmt, ...)
-  {
-         va_list args;
-       
-         /* Linux "program_invocation_short_name" is a GNU extension, so we don't use it */
-         #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
-          #define I_GET_PROG_NAME_() getprogname()
-         #else
-          #define I_GET_PROG_NAME_() "warnx"
-         #endif
-
-         va_start(args, fmt);
-         fprintf(stderr, "%s: ", I_GET_PROG_NAME_());
-         vfprintf(stderr, fmt, args);
-         fputc('\n', stderr);
-         va_end(args);
-  }
-
-  /*
-   * Compute the greatest common divisor of a and b.
-   */
-  static int
-  i_gcd_(int a, int b)
-  {
-         int c;
-
-         c = a % b;
-         while (c != 0) {
-                 a = b;
-                 b = c;
-                 c = a % b;
-         }
-
-         return (b);
-  }
-
-  /*
-   * Exchange the block from nonopt_start to nonopt_end with the block
-   * from nonopt_end to opt_end (keeping the same order of arguments
-   * in each block).
-   */
-  static void
-  i_permute_args_(int panonopt_start, int panonopt_end, int opt_end,
-                  char * const *nargv)
-  {
-         int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
-         char *swap;
-
-         /*
-          * compute lengths of blocks and number and size of cycles
-          */
-         nnonopts = panonopt_end - panonopt_start;
-         nopts = opt_end - panonopt_end;
-         ncycle = i_gcd_(nnonopts, nopts);
-         cyclelen = (opt_end - panonopt_start) / ncycle;
-
-         for (i = 0; i < ncycle; i++) {
+  #define I_FLAG_PERMUTE_      0x01    /* permute non-options to the end of argv */
+  #define I_FLAG_ALLARGS_      0x02    /* treat non-options as args to option "-1" */
+  #define I_FLAG_LONGONLY_     0x04    /* operate as getopt_long_only */
+
+/* return values */
+  #define      I_BADCH_        (int) '?'
+  #define      I_BADARG_       ((*options == ':') ? (int) ':' : (int) '?')
+  #define      I_INORDER_      (int) 1
+
+  #define      I_EMSG_         ""
+
+int i_opterr_ = 1;                      /* if error message should be printed */
+int i_optind_ = 1;                      /* index into parent argv vector */
+int i_optopt_ = '?';                    /* character checked for validity */
+int i_optreset_;                        /* reset getopt */
+char  *i_optarg_;                       /* argument associated with option */
+char  *i_suboptarg_;                    /* argument associated with suboption */
+
+/* XXX: set optreset to 1 rather than these two */
+static int i_nonopt_start_ = -1;        /* first non option argument (for permute) */
+static int i_nonopt_end_ = -1;          /* first option after non options (for permute) */
+static char   *i_place_ = I_EMSG_;      /* option letter processing */
+static char   *i_progname_;             /* program name == argv[0] */
+
+/* Error messages */
+static const char i_recargchar_[] = "option requires an argument -- %c";
+static const char i_recargstring_[] = "option requires an argument -- %s";
+static const char i_ambig_[] = "i_ambig_uous option -- %.*s";
+static const char i_noarg_[] = "option doesn't take an argument -- %.*s";
+static const char i_illoptchar_[] = "unknown option -- %c";
+static const char i_illoptstring_[] = "unknown option -- %s";
+
+static void i_warnx_(const char *, ...);
+static int  i_getopt_internal_(int, char * const *, const char *,
+                              const struct option *, int *, int);
+static int  i_parse_long_options__(char * const *, const char *,
+                                  const struct option *, int *, int);
+static int  i_gcd_(int, int);
+static void i_permute_args_(int, int, int, char * const *);
+
+/*
+ * Own warnx() for portability
+ */
+void
+i_warnx_(const char *fmt, ...)
+{
+       va_list args;
+
+       va_start(args, fmt);
+       fprintf(stderr, "%s: ", i_progname_);
+       vfprintf(stderr, fmt, args);
+       fputc('\n', stderr);
+       va_end(args);
+}
+
+/*
+ * Compute the greatest common divisor of a and b.
+ */
+static int
+i_gcd_(int a, int b)
+{
+       int c;
+
+       c = a % b;
+       while (c != 0) {
+               a = b;
+               b = c;
+               c = a % b;
+       }
+
+       return (b);
+}
+
+/*
+ * Exchange the block from nonopt_start to nonopt_end with the block
+ * from nonopt_end to opt_end (keeping the same order of arguments
+ * in each block).
+ */
+static void
+i_permute_args_(int panonopt_start, int panonopt_end, int opt_end,
+               char * const *nargv)
+{
+       int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
+       char *swap;
+
+       /*
+        * compute lengths of blocks and number and size of cycles
+        */
+       nnonopts = panonopt_end - panonopt_start;
+       nopts = opt_end - panonopt_end;
+       ncycle = i_gcd_(nnonopts, nopts);
+       cyclelen = (opt_end - panonopt_start) / ncycle;
+
+       for (i = 0; i < ncycle; i++) {
                cstart = panonopt_end+i;
                pos = cstart;
                for (j = 0; j < cyclelen; j++) {
-                     if (pos >= panonopt_end)
-                         pos -= nnonopts;
-                     else
-                         pos += nopts;
-                     swap = nargv[pos];
-                     /* LINTED const cast */
-                     ((char **) nargv)[pos] = nargv[cstart];
-                     /* LINTED const cast */
-                     ((char **)nargv)[cstart] = swap;
-                     }
-         }
-  }
-
-  /*
-   * i_parse_long_options__ --
-   *   Parse long options in argc/argv argument vector.
-   * Returns -1 if short_too is set and the option does not match long_options.
-   */
-  static int
-  i_parse_long_options__(char * const *nargv, const char *options,
-         const struct option *long_options, int *idx, int short_too)
-  {
-         char *current_argv, *has_equal;
-         size_t current_argv_len;
-         int i, match;
-
-         current_argv = i_place_;
-         match = -1;
-
-         i_optind_++;
-
-         if ((has_equal = strchr(current_argv, '=')) != NULL) {
-                 /* argument found (--option=arg) */
-                 current_argv_len = has_equal - current_argv;
-                 has_equal++;
-         } else {
-                 current_argv_len = strlen(current_argv);
-         }
-         for (i = 0; long_options[i].name; i++) {
-                 /* find matching long option */
-                 if (strncmp(current_argv, long_options[i].name,
-                     current_argv_len))
-                     continue;
-
-                 if (strlen(long_options[i].name) == current_argv_len) {
-                     /* exact match */
-                     match = i;
-                     break;
-                 }
-                 /*
-                  * If this is a known short option, don't allow
-                  * a partial match of a single character.
-                  */
-                 if (short_too && current_argv_len == 1)
-                     continue;
-
-                 if (match == -1) {    /* partial match */
-                     match = i;
-                 } else {
-                     /* ambiguous abbreviation */
-                     if (I_PRINT_ERROR_)
-                         i_warnx_(i_ambig_, (int)current_argv_len,
-                                    current_argv);
-                     i_optopt_ = 0;
-                     return (I_BADCH_);
-                 }
-         }
-         if (match != -1) {            /* option found */
-                 if (long_options[match].has_arg == no_argument
-                      && has_equal) {
-                     if (I_PRINT_ERROR_)
-                         i_warnx_(i_noarg_, (int)current_argv_len,
-                                  current_argv);
-                     /*
-                      * XXX: GNU sets optopt to val regardless of flag
-                      */
-                     if (long_options[match].flag == NULL)
-                         i_optopt_ = long_options[match].val;
-                     else
-                         i_optopt_ = 0;
-                     return (I_BADARG_);
-                 }
-                 if (long_options[match].has_arg == required_argument ||
-                     long_options[match].has_arg == optional_argument) {
-                     if (has_equal)
-                         i_optarg_ = has_equal;
-                     else if (long_options[match].has_arg ==
-                              required_argument) {
+                       if (pos >= panonopt_end)
+                               pos -= nnonopts;
+                       else
+                               pos += nopts;
+                       swap = nargv[pos];
+                       /* LINTED const cast */
+                       ((char **) nargv)[pos] = nargv[cstart];
+                       /* LINTED const cast */
+                       ((char **) nargv)[cstart] = swap;
+               }
+       }
+}
+
+/*
+ * i_parse_long_options__ --
+ *     Parse long options in argc/argv argument vector.
+ * Returns -1 if short_too is set and the option does not match long_options.
+ */
+static int
+i_parse_long_options__(char * const *nargv, const char *options,
+                      const struct option *long_options, int *idx, int
+                      short_too)
+{
+       char *current_argv, *has_equal;
+       size_t current_argv_len;
+       int i, match;
+
+       current_argv = i_place_;
+       match = -1;
+
+       i_optind_++;
+
+       if ((has_equal = strchr(current_argv, '=')) != NULL) {
+               /* argument found (--option=arg) */
+               current_argv_len = has_equal - current_argv;
+               has_equal++;
+       } else {
+               current_argv_len = strlen(current_argv);
+       }
+       for (i = 0; long_options[i].name; i++) {
+               /* find matching long option */
+               if (strncmp(current_argv, long_options[i].name,
+                           current_argv_len))
+                       continue;
+
+               if (strlen(long_options[i].name) == current_argv_len) {
+                       /* exact match */
+                       match = i;
+                       break;
+               }
+               /*
+                * If this is a known short option, don't allow
+                * a partial match of a single character.
+                */
+               if (short_too && current_argv_len == 1)
+                       continue;
+
+               if (match == -1) {      /* partial match */
+                       match = i;
+               } else {
+                       /* ambiguous abbreviation */
+                       if (I_PRINT_ERROR_)
+                               i_warnx_(i_ambig_, (int) current_argv_len,
+                                        current_argv);
+                       i_optopt_ = 0;
+                       return (I_BADCH_);
+               }
+       }
+       if (match != -1) {              /* option found */
+               if (long_options[match].has_arg == no_argument
+                   && has_equal) {
+                       if (I_PRINT_ERROR_)
+                               i_warnx_(i_noarg_, (int) current_argv_len,
+                                        current_argv);
+                       /*
+                        * XXX: GNU sets optopt to val regardless of flag
+                        */
+                       if (long_options[match].flag == NULL)
+                               i_optopt_ = long_options[match].val;
+                       else
+                               i_optopt_ = 0;
+                       return (I_BADARG_);
+               }
+               if (long_options[match].has_arg == required_argument ||
+                   long_options[match].has_arg == optional_argument) {
+                       if (has_equal){
+                               i_optarg_ = has_equal;
+                       } else if (long_options[match].has_arg ==
+                                  required_argument) {
                                /*
                                 * optional argument doesn't use next nargv
                                 */
-                         i_optarg_ = nargv[i_optind_++];
-                     }
-                 }
-                 if ((long_options[match].has_arg == required_argument)
-                      && (i_optarg_ == NULL)) {
+                               i_optarg_ = nargv[i_optind_++];
+                       }
+               }
+               if ((long_options[match].has_arg == required_argument)
+                   && (i_optarg_ == NULL)) {
                        /*
                         * Missing argument; leading ':' indicates no error
                         * should be generated.
                         */
                        if (I_PRINT_ERROR_)
                                i_warnx_(i_recargstring_,
-                                   current_argv);
+                                        current_argv);
                        /*
                         * XXX: GNU sets optopt to val regardless of flag
                         */
                                i_optopt_ = 0;
                        --i_optind_;
                        return (I_BADARG_);
-                 }
-         } else {                      /* unknown option */
-                 if (short_too) {
-                     --i_optind_;
-                     return (-1);
-                 }
-                 if (I_PRINT_ERROR_)
-                     i_warnx_(i_illoptstring_, current_argv);
-                 i_optopt_ = 0;
-                 return (I_BADCH_);
-         }
-         if (idx)
-                 *idx = match;
-         if (long_options[match].flag) {
-                 *long_options[match].flag = long_options[match].val;
-                 return (0);
-         } else
-                 return (long_options[match].val);
-  }
-
-  /*
-   * i_getopt_internal_ --
-   *   Parse argc/argv argument vector.  Called by user level routines.
-   */
-  static int
-  i_getopt_internal_(int nargc, char *const *nargv, const char *options,
-                const struct option *long_options, int *idx, int flags)
-  {
-         char *oli;                            /* option letter list index */
-         int optchar, short_too;
-         static int posix_me_harder = -1;
-
-         if (options == NULL)
-                 return (-1);
-
-         /*
-          * XXX Some GNU programs (like cvs) set optind to 0 instead of
-          * XXX using optreset. Work around this braindamage.
-          */
-         if (i_optind_ == 0)
-                 i_optind_ = i_optreset_ = 1;
-
-         /*
-          * Disable GNU extensions if POSIXLY_CORRECT is set or options
-          * string begins with a '+'.
-          */
-         if (posix_me_harder == -1 || i_optreset_)
-                 posix_me_harder = (getenv("POSIXLY_CORRECT") != NULL);
-         if (*options == '-')
-                 flags |= I_FLAG_ALLARGS_;
-         else if (posix_me_harder || *options == '+')
-                 flags &= ~I_FLAG_PERMUTE_;
-         if (*options == '+' || *options == '-')
-                 options++;
-
-         i_optarg_ = NULL;
-         if (i_optreset_)
-                 i_nonopt_start_ = i_nonopt_end_ = -1;
-         start:
-         if (i_optreset_ || !*i_place_) {              /* update scanning pointer */
-                 i_optreset_ = 0;
-                 if (i_optind_ >= nargc) {          /* end of argument vector */
-                     i_place_ = I_EMSG_;
-                     if (i_nonopt_end_ != -1) {
-                         /* do permutation, if we have to */
-                         i_permute_args_(i_nonopt_start_, i_nonopt_end_,
-                                         i_optind_, nargv);
-                         i_optind_ -= i_nonopt_end_ - i_nonopt_start_;
-                     } else if (i_nonopt_start_ != -1) {
-                         /*
-                          * If we skipped non-options, set optind
-                          * to the first of them.
-                          */
-                         i_optind_ = i_nonopt_start_;
-                     }
-                     i_nonopt_start_ = i_nonopt_end_ = -1;
-                     return (-1);
-                 }
-                 if (*(i_place_ = nargv[i_optind_]) != '-' ||
-                    (i_place_[1] == '\0' && strchr(options, '-') == NULL)) {
-                     i_place_ = I_EMSG_;               /* found non-option */
-                     if (flags & I_FLAG_ALLARGS_) {
-                         /*
-                          * GNU extension:
-                          * return non-option as argument to option 1
-                          */
-                         i_optarg_ = nargv[i_optind_++];
-                         return (I_INORDER_);
-                     }
-                     if (!(flags & I_FLAG_PERMUTE_)) {
+               }
+       } else {                        /* unknown option */
+               if (short_too) {
+                       --i_optind_;
+                       return (-1);
+               }
+               if (I_PRINT_ERROR_)
+                       i_warnx_(i_illoptstring_, current_argv);
+               i_optopt_ = 0;
+               return (I_BADCH_);
+       }
+       if (idx)
+               *idx = match;
+       if (long_options[match].flag) {
+               *long_options[match].flag = long_options[match].val;
+               return (0);
+       } else {
+               return (long_options[match].val);
+       }
+}
+
+/*
+ * i_getopt_internal_ --
+ *     Parse argc/argv argument vector.  Called by user level routines.
+ */
+static int
+i_getopt_internal_(int nargc, char *const *nargv, const char *options,
+                  const struct option *long_options, int *idx, int flags)
+{
+       char *oli;                              /* option letter list index */
+       int optchar, short_too;
+       static int posix_me_harder = -1;
+
+       i_progname_ = nargv[0];
+
+       if (options == NULL)
+               return (-1);
+
+       /*
+        * XXX Some GNU programs (like cvs) set optind to 0 instead of
+        * XXX using optreset. Work around this braindamage.
+        */
+       if (i_optind_ == 0)
+               i_optind_ = i_optreset_ = 1;
+
+       /*
+        * Disable GNU extensions if POSIXLY_CORRECT is set or options
+        * string begins with a '+'.
+        */
+       if (posix_me_harder == -1 || i_optreset_)
+               posix_me_harder = (getenv("POSIXLY_CORRECT") != NULL);
+       if (*options == '-')
+               flags |= I_FLAG_ALLARGS_;
+       else if (posix_me_harder || *options == '+')
+               flags &= ~I_FLAG_PERMUTE_;
+       if (*options == '+' || *options == '-')
+               options++;
+
+       i_optarg_ = NULL;
+       if (i_optreset_)
+               i_nonopt_start_ = i_nonopt_end_ = -1;
+start:
+       if (i_optreset_ || !*i_place_) {                /* update scanning pointer */
+               i_optreset_ = 0;
+               if (i_optind_ >= nargc) {               /* end of argument vector */
+                       i_place_ = I_EMSG_;
+                       if (i_nonopt_end_ != -1) {
+                               /* do permutation, if we have to */
+                               i_permute_args_(i_nonopt_start_, i_nonopt_end_,
+                                               i_optind_, nargv);
+                               i_optind_ -= i_nonopt_end_ - i_nonopt_start_;
+                       } else if (i_nonopt_start_ != -1) {
+                               /*
+                                * If we skipped non-options, set optind
+                                * to the first of them.
+                                */
+                               i_optind_ = i_nonopt_start_;
+                       }
+                       i_nonopt_start_ = i_nonopt_end_ = -1;
+                       return (-1);
+               }
+               if (*(i_place_ = nargv[i_optind_]) != '-' ||
+                   (i_place_[1] == '\0' && strchr(options, '-') == NULL)) {
+                       i_place_ = I_EMSG_;             /* found non-option */
+                       if (flags & I_FLAG_ALLARGS_) {
+                               /*
+                                * GNU extension:
+                                * return non-option as argument to option 1
+                                */
+                               i_optarg_ = nargv[i_optind_++];
+                               return (I_INORDER_);
+                       }
+                       if (!(flags & I_FLAG_PERMUTE_)) {
                                /*
                                 * If no permutation wanted, stop parsing
                                 * at first non-option.
                                 */
                                return (-1);
-                     }
-                     /* do permutation */
-                     if (i_nonopt_start_ == -1) {
-                         i_nonopt_start_ = i_optind_;
-                     } else if (i_nonopt_end_ != -1) {
-                         i_permute_args_(i_nonopt_start_, i_nonopt_end_,
-                                         i_optind_, nargv);
-                         i_nonopt_start_ = i_optind_ -
-                                       (i_nonopt_end_ - i_nonopt_start_);
-                         i_nonopt_end_ = -1;
-                     }
-                     i_optind_++;
-                     /* process next argument */
-                     goto start;
-                 }
-                 if (i_nonopt_start_ != -1 && i_nonopt_end_ == -1)
-                     i_nonopt_end_ = i_optind_;
-
-                 /*
-                  * If we have "-" do nothing, if "--" we are done.
-                  */
-                 if (i_place_[1] != '\0' && *++i_place_ == '-' && i_place_[1] == '\0') {
-                     i_optind_++;
-                     i_place_ = I_EMSG_;
-                     /*
-                      * We found an option (--), so if we skipped
-                      * non-options, we have to permute.
-                      */
-                 if (i_nonopt_end_ != -1) {
-                     i_permute_args_(i_nonopt_start_, i_nonopt_end_,
-                                     i_optind_, nargv);
-                     i_optind_ -= i_nonopt_end_ - i_nonopt_start_;
-                 }
-                     i_nonopt_start_ = i_nonopt_end_ = -1;
-                     return (-1);
-                 }
-         }
-
-         /*
-          * Check long options if:
-          *  1) we were passed some
-          *  2) the arg is not just "-"
-          *  3) either the arg starts with -- we are i_getopt_long_only()
-          */
-         if (long_options != NULL && i_place_ != nargv[i_optind_] &&
-            (*i_place_ == '-' || (flags & I_FLAG_LONGONLY_))) {
-                 short_too = 0;
-                 if (*i_place_ == '-')
-                     i_place_++;               /* --foo long option */
-                 else if (*i_place_ != ':' 
-                          && strchr(options, *i_place_) != NULL)
-                     short_too = 1;    /* could be short option too */
-
-                 optchar = i_parse_long_options__(nargv, options, long_options,
-                                                idx, short_too);
-                 if (optchar != -1) {
-                     i_place_ = I_EMSG_;
-                 return (optchar);
-             }
-         }
-
-         if ((optchar = (int)*i_place_++) == (int)':' ||
-           (optchar == (int)'-' && *i_place_ != '\0') ||
+                       }
+                       /* do permutation */
+                       if (i_nonopt_start_ == -1) {
+                               i_nonopt_start_ = i_optind_;
+                       } else if (i_nonopt_end_ != -1) {
+                               i_permute_args_(i_nonopt_start_, i_nonopt_end_,
+                                               i_optind_, nargv);
+                               i_nonopt_start_ = i_optind_ -
+                                                 (i_nonopt_end_ -
+                                                  i_nonopt_start_);
+                               i_nonopt_end_ = -1;
+                       }
+                       i_optind_++;
+                       /* process next argument */
+                       goto start;
+               }
+               if (i_nonopt_start_ != -1 && i_nonopt_end_ == -1)
+                       i_nonopt_end_ = i_optind_;
+
+               /*
+                * If we have "-" do nothing, if "--" we are done.
+                */
+               if (i_place_[1] != '\0' && *++i_place_ == '-' && i_place_[1] ==
+                   '\0') {
+                       i_optind_++;
+                       i_place_ = I_EMSG_;
+                       /*
+                        * We found an option (--), so if we skipped
+                        * non-options, we have to permute.
+                        */
+                       if (i_nonopt_end_ != -1) {
+                               i_permute_args_(i_nonopt_start_, i_nonopt_end_,
+                                               i_optind_, nargv);
+                               i_optind_ -= i_nonopt_end_ - i_nonopt_start_;
+                       }
+                       i_nonopt_start_ = i_nonopt_end_ = -1;
+                       return (-1);
+               }
+       }
+
+       /*
+        * Check long options if:
+        *  1) we were passed some
+        *  2) the arg is not just "-"
+        *  3) either the arg starts with -- we are i_getopt_long_only()
+        */
+       if (long_options != NULL && i_place_ != nargv[i_optind_] &&
+           (*i_place_ == '-' || (flags & I_FLAG_LONGONLY_))) {
+               short_too = 0;
+               if (*i_place_ == '-')
+                       i_place_++;     /* --foo long option */
+               else if (*i_place_ != ':'
+                        && strchr(options, *i_place_) != NULL)
+                       short_too = 1;  /* could be short option too */
+
+               optchar = i_parse_long_options__(nargv, options, long_options,
+                                                idx, short_too);
+               if (optchar != -1) {
+                       i_place_ = I_EMSG_;
+                       return (optchar);
+               }
+       }
+
+       if ((optchar = (int) *i_place_++) == (int) ':' ||
+           (optchar == (int) '-' && *i_place_ != '\0') ||
            (oli = strchr(options, optchar)) == NULL) {
-                 /*
-                  * If the user specified "-" and  '-' isn't listed in
-                  * options, return -1 (non-option) as per POSIX.
-                  * Otherwise, it is an unknown option character (or ':').
-                  */
-                 if (optchar == (int)'-' && *i_place_ == '\0')
-                     return (-1);
-                 if (!*i_place_)
-                     ++i_optind_;
-                 if (I_PRINT_ERROR_)
-                     i_warnx_(i_illoptchar_, optchar);
-                 i_optopt_ = optchar;
-                 return (I_BADCH_);
-         }
-         if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
-                 /* -W long-option */
-                 if (*i_place_) {                      /* no space */
-                     /* NOTHING */;
-                 } else if (++i_optind_ >= nargc) {    /* no arg */
-                     i_place_ = I_EMSG_;
-                     if (I_PRINT_ERROR_)
-                         i_warnx_(i_recargchar_, optchar);
-                     i_optopt_ = optchar;
-                     return (I_BADARG_);
-                 } else {                              /* white space */
-                     i_place_ = nargv[i_optind_];
-                 }
-                 optchar = i_parse_long_options__(nargv, options, long_options,
-                                                  idx, 0);
-                 i_place_ = I_EMSG_;
-                 return (optchar);
-         }
-         if (*++oli != ':') {                  /* doesn't take argument */
-                 if (!*i_place_)
-                     ++i_optind_;
-         } else {                              /* takes (optional) argument */
-                 i_optarg_ = NULL;
-                 if (*i_place_)                /* no white space */
-                     i_optarg_ = i_place_;
-                 else if (oli[1] != ':') {     /* arg not optional */
-                     if (++i_optind_ >= nargc) {       /* no arg */
-                         i_place_ = I_EMSG_;
-                         if (I_PRINT_ERROR_)
-                             i_warnx_(i_recargchar_, optchar);
-                         i_optopt_ = optchar;
-                         return (I_BADARG_);
-                     } else {
-                         i_optarg_ = nargv[i_optind_];
-                     }
-                 }
-                 i_place_ = I_EMSG_;
-                 ++i_optind_;
-         }
-         /* dump back option letter */
-         return (optchar);
-  }
-
-  int
-  i_getsubopt_(char **optionp, char * const *tokens, char **valuep)
-  {
-         int cnt;
-         char *p;
-
-         i_suboptarg_ = *valuep = NULL;
-
-         if (!optionp || !*optionp)
-                 return(-1);
-
-         /* skip leading white-space, commas */
-         for (p = *optionp; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
-
-         if (!*p) {
-                 *optionp = p;
-                 return(-1);
-         }
-
-         /* save the start of the token, and skip the rest of the token. */
-         for (i_suboptarg_ = p;
-              *++p && *p != ',' && *p != '=' && *p != ' ' && *p != '\t';);
-
-         if (*p) {
-                 /*
-                  * If there's an equals sign, set the value pointer, and
-                  * skip over the value part of the token.  Terminate the
-                  * token.
-                  */
-                 if (*p == '=') {
-                     *p = '\0';
-                     for (*valuep = ++p;
-                         *p && *p != ',' && *p != ' ' && *p != '\t'; ++p);
-                     if (*p) 
-                         *p++ = '\0';
-                 } else {
-                     *p++ = '\0';
-                 }
-                 /* Skip any whitespace or commas after this token. */
-                 for (; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
-         }
-
-         /* set optionp for next round. */
-         *optionp = p;
-
-         for (cnt = 0; *tokens; ++tokens, ++cnt)
-                 if (!strcmp(i_suboptarg_, *tokens))
-                     return(cnt);
-         return(-1);
-  }
-
-  int
-  i_getopt_(int argc, char * const *argv, const char *optstring)
-  {
-         #ifdef GETOPT_PERMUTE_ARGS
-          return (i_getopt_internal_(argc, argv, optstring, NULL, NULL,
-                  I_FLAG_PERMUTE_));
-         #else
-          return (i_getopt_internal_(argc, argv, optstring, NULL, NULL, 0));
-         #endif
-  }
-
-  int
-  i_getopt_long_(int argc, char * const *argv, const char *optstring,
-            const struct option *longopts, int *longindex)
-  {  
-         #ifdef GETOPT_LONG_PERMUTE_ARGS
-          return (i_getopt_internal_(argc, argv, optstring, longopts, longindex,
-                  I_FLAG_PERMUTE_));
-         #else
-          return (i_getopt_internal_(argc, argv, optstring, longopts, longindex, 0));
-         #endif
-
-  }
-
-  int
-  i_getopt_long_only_(int argc, char * const *argv, const char *optstring,
-                   const struct option *longopts, int *longindex)
-  {
-         #ifdef GETOPT_LONG_ONLY_PERMUTE_ARGS
-          return (i_getopt_internal_(argc, argv, optstring, longopts, longindex,
-                  I_FLAG_PERMUTE_ | I_FLAG_LONGONLY_));
-         #else
-          return (i_getopt_internal_(argc, argv, optstring, longopts, longindex,
-                  I_FLAG_LONGONLY_));
-         #endif
-  }
+               /*
+                * If the user specified "-" and  '-' isn't listed in
+                * options, return -1 (non-option) as per POSIX.
+                * Otherwise, it is an unknown option character (or ':').
+                */
+               if (optchar == (int) '-' && *i_place_ == '\0')
+                       return (-1);
+               if (!*i_place_)
+                       ++i_optind_;
+               if (I_PRINT_ERROR_)
+                       i_warnx_(i_illoptchar_, optchar);
+               i_optopt_ = optchar;
+               return (I_BADCH_);
+       }
+       if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
+               /* -W long-option */
+               if (*i_place_) {                        /* no space */
+                       /* NOTHING */
+                       ;
+               } else if (++i_optind_ >= nargc) {      /* no arg */
+                       i_place_ = I_EMSG_;
+                       if (I_PRINT_ERROR_)
+                               i_warnx_(i_recargchar_, optchar);
+                       i_optopt_ = optchar;
+                       return (I_BADARG_);
+               } else {                                /* white space */
+                       i_place_ = nargv[i_optind_];
+               }
+               optchar = i_parse_long_options__(nargv, options, long_options,
+                                                idx, 0);
+               i_place_ = I_EMSG_;
+               return (optchar);
+       }
+       if (*++oli != ':') {                            /* doesn't take argument */
+               if (!*i_place_)
+                       ++i_optind_;
+       } else {                                        /* takes (optional) argument */
+               i_optarg_ = NULL;
+               if (*i_place_){                         /* no white space */
+                       i_optarg_ = i_place_;
+               } else if (oli[1] != ':'){              /* arg not optional */
+                       if (++i_optind_ >= nargc) {     /* no arg */
+                               i_place_ = I_EMSG_;
+                               if (I_PRINT_ERROR_)
+                                       i_warnx_(i_recargchar_, optchar);
+                               i_optopt_ = optchar;
+                               return (I_BADARG_);
+                       } else {
+                               i_optarg_ = nargv[i_optind_];
+                       }
+               }
+               i_place_ = I_EMSG_;
+               ++i_optind_;
+       }
+       /* dump back option letter */
+       return (optchar);
+}
+
+int
+i_getsubopt_(char **optionp, char * const *tokens, char **valuep)
+{
+       int cnt;
+       char *p;
+
+       i_suboptarg_ = *valuep = NULL;
+
+       if (!optionp || !*optionp)
+               return (-1);
+
+       /* skip leading white-space, commas */
+       for (p = *optionp; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p) ;
+
+       if (!*p) {
+               *optionp = p;
+               return (-1);
+       }
+
+       /* save the start of the token, and skip the rest of the token. */
+       for (i_suboptarg_ = p;
+            *++p && *p != ',' && *p != '=' && *p != ' ' && *p != '\t';) ;
+
+       if (*p) {
+               /*
+                * If there's an equals sign, set the value pointer, and
+                * skip over the value part of the token.  Terminate the
+                * token.
+                */
+               if (*p == '=') {
+                       *p = '\0';
+                       for (*valuep = ++p;
+                            *p && *p != ',' && *p != ' ' && *p != '\t'; ++p) ;
+                       if (*p)
+                               *p++ = '\0';
+               } else {
+                       *p++ = '\0';
+               }
+               /* Skip any whitespace or commas after this token. */
+               for (; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p) ;
+       }
+
+       /* set optionp for next round. */
+       *optionp = p;
+
+       for (cnt = 0; *tokens; ++tokens, ++cnt)
+               if (!strcmp(i_suboptarg_, *tokens))
+                       return (cnt);
+       return (-1);
+}
+
+int
+i_getopt_(int argc, char * const *argv, const char *optstring)
+{
+#ifdef GETOPT_PERMUTE_ARGS
+       return (i_getopt_internal_(argc, argv, optstring, NULL, NULL,
+                                  I_FLAG_PERMUTE_));
+#else
+       return (i_getopt_internal_(argc, argv, optstring, NULL, NULL, 0));
+#endif
+}
+
+int
+i_getopt_long_(int argc, char * const *argv, const char *optstring,
+              const struct option *longopts, int *longindex)
+{
+#ifdef GETOPT_LONG_PERMUTE_ARGS
+       return (i_getopt_internal_(argc, argv, optstring, longopts, longindex,
+                                  I_FLAG_PERMUTE_));
+#else
+       return (i_getopt_internal_(argc, argv, optstring, longopts, longindex, 0
+                                  ));
+#endif
+}
+
+int
+i_getopt_long_only_(int argc, char * const *argv, const char *optstring,
+                   const struct option *longopts, int *longindex)
+{
+#ifdef GETOPT_LONG_ONLY_PERMUTE_ARGS
+       return (i_getopt_internal_(argc, argv, optstring, longopts, longindex,
+                                  I_FLAG_PERMUTE_ | I_FLAG_LONGONLY_));
+#else
+       return (i_getopt_internal_(argc, argv, optstring, longopts, longindex,
+                                  I_FLAG_LONGONLY_));
+#endif
+}
  #endif /* GETOPT_LONG_IMPLEMENTATION */
 #endif /* !GETOPT_LONG_H_ */