]> git.donarmstrong.com Git - mothur.git/blobdiff - getopt_long.cpp
Revert to previous commit
[mothur.git] / getopt_long.cpp
diff --git a/getopt_long.cpp b/getopt_long.cpp
new file mode 100644 (file)
index 0000000..3baa3ce
--- /dev/null
@@ -0,0 +1,2099 @@
+/*
+  This getopt_long() is compatible with GNU's, however, added original
+  extention (short 1 byte option).
+
+
+  Copyright (c) 2004 Koji Arai
+
+  Permission is hereby granted, free of charge, to any person
+  obtaining a copy of this software and associated documentation files
+  (the "Software"), to deal in the Software without restriction,
+  including without limitation the rights to use, copy, modify, merge,
+  publish, distribute, sublicense, and/or sell copies of the Software,
+  and to permit persons to whom the Software is furnished to do so,
+  subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be
+  included in all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+  SOFTWARE.
+
+
+  Compilation for Test:
+
+      GNU:
+      cc -DUSE_GNU -DDEBUG getopt_long.c -o test_getopt_long_gnu
+
+      not GNU:
+      cc -I. -DDEBUG getopt_long.c -o test_getopt_long
+
+      ./test_getopt_long
+      ./test_getopt_long_gnu
+
+  BUGS:
+    * not implemented any features for getopt() and getopt_long().
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#if DEBUG
+static int
+puts_argv(char **argv)
+{
+    int i;
+
+    for (i = 0; argv[i]; i++) {
+        if (i) printf(" ");
+
+        printf("%s", argv[i]);
+    }
+    printf("\n");
+
+    return 0;
+}
+#endif
+
+#ifndef USE_GNU
+#include <stdio.h>
+#include "getopt_long.h"
+
+char *optarg;
+int optind;
+
+int opterr;
+int optopt;
+
+/*
+  return value 0: no option (include '-')
+               1: short option like '-x'
+               2: long option like '--xxx' and just '--'
+*/
+static int
+is_option(char *arg)
+{
+    if (arg[0] == '-') {
+        switch (arg[1]) {
+        case 0:                 /* just "-" */
+            return 0;
+        case '-':               /* long option (include just "--")*/
+            return 2;
+        default:                /* short option */
+            return 1;
+        }
+    }
+    return 0;
+}
+
+static int
+insert_argv(char **argv, int src, int dest)
+{
+    int i;
+    char *tmp = argv[src];
+
+    if (src > dest) {
+        for (i = src; i > dest; i--)
+            argv[i] = argv[i-1];  //printf("%s\n", argv[i]);
+    }
+    if (src < dest) {
+        for (i = src; i < dest; i++)
+            argv[i] = argv[i+1]; //printf("%s\n", argv[i]);
+    }
+
+    argv[dest] = tmp;
+       //printf("%s\n", argv[dest]);
+
+    return 0;
+}
+
+static int
+search_longopt(char *arg, struct option *longopts)
+{
+    int i, found = -1;
+    int len;
+    for (len = 0; arg[len] && arg[len] != '='; len++)
+        ;
+
+    for (i = 0; longopts[i].name; i++) {
+       //printf("%d\t%s\t", i, longopts[i].name); 
+       //printf("%s\n", arg);
+        if (strncmp(arg, longopts[i].name, len) == 0) {
+            if (found != -1)
+                return -1;      /* found some candidate */
+            found = i;
+       //printf("found = %d\n", found);
+        }
+    }
+    return found;
+}
+
+/*
+ * implemented my extention feature.
+ * optional 1 byte argument with [...]
+ *   e.g.) shortopts = "a[0123]b"
+ *          accepts "-a0 -a1b" (same as "-a0 -a1 -b")
+ */
+static int
+has_argument_short(char *arg, const char *shortopts)
+{
+    int i;
+    int open_bracket = 0;
+    for (i = 0; shortopts[i]; i++) {
+        switch (shortopts[i]) {
+        case '[':
+            open_bracket++;
+            continue;
+        case ']':
+            if (open_bracket <= 0) {
+                fprintf(stderr, "getopt_long() -- unbalanced bracket in short options");
+                return -1;
+            }
+            open_bracket--;
+            continue;
+        }
+        if (open_bracket) continue;
+        if (*arg != shortopts[i]) continue;
+
+        switch (shortopts[i+1]) {
+        case ':':
+            if (shortopts[i+2] != ':') {
+                if (arg[1])
+                    return 1; /* following string is argument */
+                else
+                    return 2; /* next argv is argument */
+            }
+            else {
+                /* '::' means optional argument (GNU extention) */
+                if (arg[1])
+                    return 1;
+                else
+                    return 0; /* no argument */
+            }
+        case '[':
+            if (arg[1] == '\0')
+                return 0;   /* no argument */
+            /* my extention */
+            for (i++; shortopts[i] && shortopts[i] != ']'; i++) {
+                if (arg[1] == shortopts[i])
+                    return 3; /* has 1 byte argument */
+            }
+            if (!shortopts[i]) {
+                fprintf(stderr, "getopt_long() -- unbalanced bracket in short options");
+                return -1;
+            }
+            break;
+        default:
+            return 0;   /* no argument */
+        }
+    }
+    /* Invalid option */
+    return -1;
+}
+
+static int
+has_argument_long(char *arg, struct option *longopts)
+{
+    int i;
+
+    i = search_longopt(arg, longopts);
+    if (i == -1) {
+        /* Invalid option */
+        return -1;
+    }
+    else {
+        int len = strlen(arg);
+        char *p = strchr(arg, '=');
+        if (p) {
+            len = p - arg;
+        }
+
+        switch (longopts[i].has_arg) {
+        case no_argument:
+            return 0;
+        case required_argument:
+            if (arg[len] == '=')
+                return 1;
+            else
+                return 2;
+        case optional_argument:
+            if (arg[len] == '=')
+                return 1;
+            else
+                return 0;
+        default:
+            assert(0);
+        }
+    }
+}
+
+/*
+  -1: no option
+   0: no argument
+   1: has argument in this argv
+   2: has argument in next argv
+   3: has 1 byte argument in this argv
+*/
+static int
+has_argument(char *arg,
+             const char *shortopts,
+             struct option *longopts)
+{
+    int i, n;
+
+    switch (is_option(arg)) {
+    case 0:                     /* no option */
+        return -1;
+    case 1:
+        /* short option */
+        n = -1;
+        for (i = 1; arg[i]; i++) {
+            n = has_argument_short(arg+i, shortopts);
+            if (n == 0 && arg[i+1]) continue;
+            if (n == 3 && arg[i+2]) { i++; continue; }
+            break;
+        }
+        return n;
+    case 2:
+        /* long option */
+        return has_argument_long(arg+2, longopts);
+        break;
+    default:
+        assert(0);
+    }
+}
+
+int
+getopt_long(int argc, char **argv,
+            const char *shortopts,
+            struct option *longopts,
+            int *indexptr)
+{
+    char *opt;
+    int i;
+    static int shortoptind;
+    static int no_optind = 0;
+    
+    if (optind == 0) {            /* skip first argument (command name) */
+        optind++;
+        no_optind = 0;
+        shortoptind = 0;
+    }
+
+    optarg = 0;
+
+    if (no_optind && !shortoptind) {
+        while (!is_option(argv[no_optind]))
+            insert_argv(argv, no_optind, optind-1);
+
+        if (has_argument(argv[no_optind], shortopts, longopts) == 2)
+            no_optind += 2;
+        else
+            no_optind++;
+
+        if (argv[optind] && strcmp(argv[optind], "--") == 0) {
+            while (!is_option(argv[no_optind]))
+                insert_argv(argv, no_optind, optind);
+            optind = no_optind;
+            no_optind = 0;
+        }
+    }
+
+    if (optind >= argc)
+        goto end_of_option;
+
+ retry:
+    /*
+    puts_argv(&argv[optind]);
+    */
+    opt = argv[optind];
+    if (shortoptind == 0 && is_option(opt) == 1) {
+        shortoptind++;
+    }
+
+    if (shortoptind) {
+        /* short option */
+        char *p = &opt[shortoptind];
+
+        if (*p == '\0')
+            assert(0);
+
+        switch (has_argument_short(p, shortopts)) {
+        case 0:
+            /* no argument */
+            optarg = 0;
+
+            shortoptind++;
+            if (opt[shortoptind] == '\0')
+                optind++, shortoptind = 0;
+            return *p;
+        case 1:
+            /* following character is argument */
+            optind++, shortoptind = 0;
+            optarg = &p[1];
+            return *p;
+        case 2:
+            /* next argv is argument */
+            optind++, shortoptind = 0;
+            optarg = argv[optind++];
+            return *p;
+        case 3:
+            /* has 1 byte argument */
+            optarg = &p[1];
+            if (p[2] == 0)
+                optind++, shortoptind = 0;
+            else
+                shortoptind += 2;
+            return *p;
+        default:
+            /* Invalid option */
+            if (opterr)
+                fprintf(stderr,
+                        "%s: invalid option -- %c\n",
+                        argv[0],
+                        *p);
+
+            optind++, shortoptind = 0;
+            optopt = *p;
+            return '?';
+        }
+    }
+    else if (opt[0] == '-' && opt[1] == '-') {
+        /* long option */
+
+        if (opt[2] == '\0') {
+            /* end of command line switch */
+            optind++;
+            return -1;
+        }
+
+        opt += 2;
+
+        i = search_longopt(opt, longopts);
+        if (i == -1) {
+            optind++;
+            optopt = 0;
+            return '?';
+        }
+        else {
+            int len = strlen(opt);
+            char *p = strchr(opt, '=');
+            if (p) {
+                len = p - opt;
+            }
+
+            switch (longopts[i].has_arg) {
+            case no_argument:
+                break;
+            case required_argument:
+                if (opt[len] == '=')
+                    optarg = opt + len + 1;
+                else {
+                    optind++;
+                    optarg = argv[optind];
+                    if (optarg == 0) {
+                        if (opterr)
+                            fprintf(stderr,
+                                    "%s: option `--%s' requires an argument\n",
+                                    argv[0],
+                                    opt);
+
+                        optopt = 0;
+                        return '?'; /* no argument */
+                    }
+                }
+                break;
+            case optional_argument:
+                if (opt[len] == '=')
+                    optarg = opt + len + 1;
+                else {
+                    optarg = 0;
+                }
+                break;
+            default:
+                break;
+            }
+
+            *indexptr = i;
+            optind++;
+            if (longopts[i].flag) {
+                *longopts[i].flag = longopts[i].val;
+                return 0;
+            }
+            else {
+                return longopts[i].val;
+            }
+        }
+
+        optind++;
+        optopt = 0;
+        return '?';
+    }
+
+    /* not option */
+    if (no_optind == 0)
+        no_optind = optind;
+
+    for (i = optind; argv[i]; i++) {
+        if (is_option(argv[i])) {
+            optind = i;
+            goto retry;
+        }
+    }
+
+ end_of_option:
+    if (no_optind) {
+        optind = no_optind;
+        no_optind = 0;
+    }
+
+    return -1;
+}
+#endif /* USE_GNU */
+
+#if DEBUG
+
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#if USE_GNU
+#include <getopt.h>  /* use GNU getopt_long() */
+#endif
+
+static int verbose_flag;
+static int option_index;
+int argc;
+char *argv[50];
+char **p;
+int c;
+static struct option long_options[] = {
+    {"verbose", no_argument, &verbose_flag, 1},
+    {"brief", no_argument, &verbose_flag, 0},
+    {"add", required_argument, 0, 'a'},
+    {"append", no_argument, 0, 0},
+    {"delete", required_argument, 0, 0},
+    {"create", optional_argument, 0, 0},
+    {"change", optional_argument, 0, 0},
+    {0, 0, 0, 0}
+};
+
+int
+call_getopt_long(int argc, char **argv,
+                 const char *shortopts,
+                 struct option *longopts,
+                 int *indexptr)
+{
+    int c;
+    c = getopt_long(argc, argv, shortopts, longopts, indexptr);
+    puts_argv(argv);
+    printf("ret=%d(%c) option_index=%d ", c, c, option_index);
+    printf("optind=%d optarg=[%s] opterr=%d optopt=%d(%c)\n",
+           optind, optarg, opterr, optopt, optopt);
+    if (c == 0) {
+        struct option *opt;
+        opt = &longopts[*indexptr];
+        printf("long option: --%s has_arg=%d\n", opt->name, opt->has_arg);
+        if (opt->flag)
+            printf("           flag=[%8p] val=%d\n", opt->flag, *opt->flag);
+    }
+
+    return c;
+}
+
+void
+test1()
+{
+    optind = 0;
+    argc = 0;
+    p = argv;
+
+    argc++; *p++ = "command_name";
+    argc++; *p++ = "-a";
+    argc++; *p++ = "-bcd";
+    argc++; *p++ = "-d";
+    argc++; *p++ = "-e";
+    argc++; *p++ = "-f";
+    argc++; *p++ = "-g";
+    *p = 0;
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    assert(c == 'a');
+    assert(option_index == 0);
+    assert(optind == 2);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    assert(c == 'b');
+    assert(option_index == 0);
+    assert(optind == 2);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    assert(c == 'c');
+    assert(option_index == 0);
+    assert(optind == 3);
+    assert(optarg == &argv[2][3]);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    assert(c == 'd');
+    assert(option_index == 0);
+    assert(optind == 5);
+    assert(optarg == argv[4]);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    assert(c == '?');
+    assert(option_index == 0);
+    assert(optind == 6);
+    assert(optarg == 0);
+    assert(optopt == 'f');
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    assert(c == '?');
+    assert(option_index == 0);
+    assert(optind == 7);
+    assert(optarg == 0);
+    assert(optopt == 'g');
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    assert(c == -1);
+    assert(option_index == 0);
+    assert(optind == 7);
+    assert(optarg == 0);
+    assert(optopt == 'g');      /* no changed */
+}
+
+void
+test2()
+{
+    optind = 0;
+    argc = 0;
+    p = argv;
+
+    argc++; *p++ = "command_name";
+    argc++; *p++ = "--verbose";
+    argc++; *p++ = "--brief";
+    argc++; *p++ = "--add";
+    argc++; *p++ = "add_argument";
+    argc++; *p++ = "--add=add_argument";
+    argc++; *p++ = "--append";
+    argc++; *p++ = "--delete=del_argument";
+    argc++; *p++ = "--create=cre_argument";
+    argc++; *p++ = "--create";
+    argc++; *p++ = "files...";
+    *p = 0;
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    assert(c == 0);
+    assert(option_index == 0);
+    assert(optind == 2);
+    assert(optarg == 0);
+    assert(optopt == 'g');      /* no changed */
+    assert(strcmp(long_options[option_index].name, "verbose") == 0);
+    assert(*long_options[option_index].flag == 1);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    assert(c == 0);
+    assert(option_index == 1);
+    assert(optind == 3);
+    assert(optarg == 0);
+    assert(optopt == 'g');      /* no changed */
+    assert(strcmp(long_options[option_index].name, "brief") == 0);
+    assert(*long_options[option_index].flag == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    assert(c == 'a');
+    assert(option_index == 2);
+    assert(optind == 5);
+    assert(optarg == argv[4]);
+    assert(optopt == 'g');      /* no changed */
+    assert(strcmp(long_options[option_index].name, "add") == 0);
+    assert(long_options[option_index].flag == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    assert(c == 'a');
+    assert(option_index == 2);
+    assert(optind == 6);
+    assert(optarg == argv[5]+6);
+    assert(optopt == 'g');      /* no changed */
+    assert(strcmp(long_options[option_index].name, "add") == 0);
+    assert(long_options[option_index].flag == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    assert(c == 0);
+    assert(option_index == 3);
+    assert(optind == 7);
+    assert(optarg == 0);
+    assert(optopt == 'g');      /* no changed */
+    assert(strcmp(long_options[option_index].name, "append") == 0);
+    assert(long_options[option_index].flag == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    assert(c == 0);
+    assert(option_index == 4);
+    assert(optind == 8);
+    assert(optarg == argv[7]+9);
+    assert(optopt == 'g');      /* no changed */
+    assert(strcmp(long_options[option_index].name, "delete") == 0);
+    assert(long_options[option_index].flag == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    assert(c == 0);
+    assert(option_index == 5);
+    assert(optind == 9);
+    assert(optarg == argv[8]+9);
+    assert(optopt == 'g');      /* no changed */
+    assert(strcmp(long_options[option_index].name, "create") == 0);
+    assert(long_options[option_index].flag == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    assert(c == 0);
+    assert(option_index == 5);
+    assert(optind == 10);
+    assert(optarg == 0);
+    assert(optopt == 'g');      /* no changed */
+    assert(strcmp(long_options[option_index].name, "create") == 0);
+    assert(long_options[option_index].flag == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    assert(c == -1);
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 10);
+    assert(optarg == 0);
+    assert(optopt == 'g');      /* no changed */
+    assert(strcmp(argv[optind], "files...") == 0);
+
+}
+
+void
+test3()
+{
+    optind = 0;
+    argc = 0;
+    p = argv;
+
+    argc++; *p++ = "command_name";
+    argc++; *p++ = "--delete";  /* required argument has no argument */
+    *p = 0;
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    assert(c == '?');
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 2);        /* changed */
+    assert(optarg == 0);
+    assert(optopt == 0);       /* changed */
+    assert(argv[optind] == 0);
+
+    /* */
+    optind = 0;
+    argc = 0;
+    p = argv;
+
+    argc++; *p++ = "command_name";
+    argc++; *p++ = "--file";  /* not option */
+    *p = 0;
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    assert(c == '?');
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 2);
+    assert(optarg == 0);
+    assert(optopt == 0);
+    assert(argv[optind] == 0);
+}
+
+void
+test4()
+{
+    optind = 0;
+    argc = 0;
+    p = argv;
+
+    argc++; *p++ = "command_name";
+    argc++; *p++ = "-a";
+    argc++; *p++ = "a1";
+    argc++; *p++ = "a2";
+    argc++; *p++ = "-b";
+    argc++; *p++ = "b";
+    argc++; *p++ = "-efg";      /* some options in a argument */
+    argc++; *p++ = "g";
+    argc++; *p++ = "-c";
+    argc++; *p++ = "c";
+    argc++; *p++ = "d";
+    *p = 0;
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:efg:", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "a1") == 0);
+    assert(strcmp(*p++, "a2") == 0);
+    assert(strcmp(*p++, "-b") == 0);
+    assert(strcmp(*p++, "b") == 0);
+    assert(strcmp(*p++, "-efg") == 0);
+    assert(strcmp(*p++, "g") == 0);
+    assert(strcmp(*p++, "-c") == 0);
+    assert(strcmp(*p++, "c") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(*p == 0);
+
+    assert(c == 'a');
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 2);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:efg:", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "a1") == 0);
+    assert(strcmp(*p++, "a2") == 0);
+    assert(strcmp(*p++, "-b") == 0);
+    assert(strcmp(*p++, "b") == 0);
+    assert(strcmp(*p++, "-efg") == 0);
+    assert(strcmp(*p++, "g") == 0);
+    assert(strcmp(*p++, "-c") == 0);
+    assert(strcmp(*p++, "c") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(*p == 0);
+
+    assert(c == 'b');
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 5);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:efg:", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-b") == 0);
+    assert(strcmp(*p++, "a1") == 0);
+    assert(strcmp(*p++, "a2") == 0);
+    assert(strcmp(*p++, "b") == 0);
+    assert(strcmp(*p++, "-efg") == 0);
+    assert(strcmp(*p++, "g") == 0);
+    assert(strcmp(*p++, "-c") == 0);
+    assert(strcmp(*p++, "c") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(*p == 0);
+
+    assert(c == 'e');
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 6);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:efg:", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-b") == 0);
+    assert(strcmp(*p++, "a1") == 0);
+    assert(strcmp(*p++, "a2") == 0);
+    assert(strcmp(*p++, "b") == 0);
+    assert(strcmp(*p++, "-efg") == 0);
+    assert(strcmp(*p++, "g") == 0);
+    assert(strcmp(*p++, "-c") == 0);
+    assert(strcmp(*p++, "c") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(*p == 0);
+
+    assert(c == 'f');
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 6);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:efg:", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-b") == 0);
+    assert(strcmp(*p++, "a1") == 0);
+    assert(strcmp(*p++, "a2") == 0);
+    assert(strcmp(*p++, "b") == 0);
+    assert(strcmp(*p++, "-efg") == 0);
+    assert(strcmp(*p++, "g") == 0);
+    assert(strcmp(*p++, "-c") == 0);
+    assert(strcmp(*p++, "c") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(*p == 0);
+
+    assert(c == 'g');
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 8);
+    assert(optarg == argv[7]);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:efg:", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-b") == 0);
+    assert(strcmp(*p++, "-efg") == 0);
+    assert(strcmp(*p++, "g") == 0);
+    assert(strcmp(*p++, "a1") == 0);
+    assert(strcmp(*p++, "a2") == 0);
+    assert(strcmp(*p++, "b") == 0);
+    assert(strcmp(*p++, "-c") == 0);
+    assert(strcmp(*p++, "c") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(*p == 0);
+
+    assert(c == 'c');
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 10);
+    assert(optarg == argv[9]);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:efg:", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-b") == 0);
+    assert(strcmp(*p++, "-efg") == 0);
+    assert(strcmp(*p++, "g") == 0);
+    assert(strcmp(*p++, "-c") == 0);
+    assert(strcmp(*p++, "c") == 0);
+    assert(strcmp(*p++, "a1") == 0);
+    assert(strcmp(*p++, "a2") == 0);
+    assert(strcmp(*p++, "b") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(*p == 0);
+
+    assert(c == -1);
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 7);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+}
+
+void
+test5()
+{
+    optind = 0;
+    argc = 0;
+    p = argv;
+
+    argc++; *p++ = "command_name";
+    argc++; *p++ = "-a";
+    argc++; *p++ = "-";
+    argc++; *p++ = "-b";
+    *p = 0;
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-") == 0);
+    assert(strcmp(*p++, "-b") == 0);
+    assert(*p == 0);
+
+    assert(c == 'a');
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 2);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-") == 0);
+    assert(strcmp(*p++, "-b") == 0);
+    assert(*p == 0);
+
+    assert(c == 'b');
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 4);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-b") == 0);
+    assert(strcmp(*p++, "-") == 0);
+    assert(*p == 0);
+
+    assert(c == -1);
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 3);
+    assert(optarg == 0);
+    assert(optopt == 0);
+}
+
+void
+test6()
+{
+    optind = 0;
+    argc = 0;
+    p = argv;
+
+    argc++; *p++ = "command_name";
+    argc++; *p++ = "-a";
+    argc++; *p++ = "-";
+    argc++; *p++ = "-";
+    argc++; *p++ = "-b";
+    *p = 0;
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-") == 0);
+    assert(strcmp(*p++, "-") == 0);
+    assert(strcmp(*p++, "-b") == 0);
+    assert(*p == 0);
+
+    assert(c == 'a');
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 2);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-") == 0);
+    assert(strcmp(*p++, "-") == 0);
+    assert(strcmp(*p++, "-b") == 0);
+    assert(*p == 0);
+
+    assert(c == 'b');
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 5);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-b") == 0);
+    assert(strcmp(*p++, "-") == 0);
+    assert(strcmp(*p++, "-") == 0);
+    assert(*p == 0);
+
+    assert(c == -1);
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 3);
+    assert(optarg == 0);
+    assert(optopt == 0);
+}
+
+void
+test7()
+{
+    optind = 0;
+    argc = 0;
+    p = argv;
+
+    argc++; *p++ = "command_name";
+    argc++; *p++ = "-a";
+    argc++; *p++ = "-";
+    argc++; *p++ = "-";
+    argc++; *p++ = "-c";
+    argc++; *p++ = "c";
+    *p = 0;
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-") == 0);
+    assert(strcmp(*p++, "-") == 0);
+    assert(strcmp(*p++, "-c") == 0);
+    assert(strcmp(*p++, "c") == 0);
+    assert(*p == 0);
+
+    assert(c == 'a');
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 2);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-") == 0);
+    assert(strcmp(*p++, "-") == 0);
+    assert(strcmp(*p++, "-c") == 0);
+    assert(strcmp(*p++, "c") == 0);
+    assert(*p == 0);
+
+    assert(c == 'c');
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 6);
+    assert(optarg == argv[5]);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-c") == 0);
+    assert(strcmp(*p++, "c") == 0);
+    assert(strcmp(*p++, "-") == 0);
+    assert(strcmp(*p++, "-") == 0);
+    assert(*p == 0);
+
+    assert(c == -1);
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 4);
+    assert(optarg == 0);
+    assert(optopt == 0);
+}
+
+void
+test8()
+{
+    optind = 0;
+    argc = 0;
+    p = argv;
+
+    argc++; *p++ = "command_name";
+    argc++; *p++ = "-a";
+    argc++; *p++ = "-c";
+    argc++; *p++ = "c";
+    argc++; *p++ = "--";
+    argc++; *p++ = "-d";
+    argc++; *p++ = "d";
+    *p = 0;
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-c") == 0);
+    assert(strcmp(*p++, "c") == 0);
+    assert(strcmp(*p++, "--") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(*p == 0);
+
+    assert(c == 'a');
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 2);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-c") == 0);
+    assert(strcmp(*p++, "c") == 0);
+    assert(strcmp(*p++, "--") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(*p == 0);
+
+    assert(c == 'c');
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 4);
+    assert(optarg == argv[3]);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-c") == 0);
+    assert(strcmp(*p++, "c") == 0);
+    assert(strcmp(*p++, "--") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(*p == 0);
+
+    assert(c == -1);
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 5);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-c") == 0);
+    assert(strcmp(*p++, "c") == 0);
+    assert(strcmp(*p++, "--") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(*p == 0);
+
+    assert(c == 'd');
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 7);
+    assert(optarg == argv[6]);
+    assert(optopt == 0);
+}
+
+void
+test9()
+{
+    optind = 0;
+    argc = 0;
+    p = argv;
+
+    argc++; *p++ = "command_name";
+    argc++; *p++ = "-a";
+    argc++; *p++ = "-";
+    argc++; *p++ = "-";
+    argc++; *p++ = "-c";
+    argc++; *p++ = "c";
+    argc++; *p++ = "--";
+    argc++; *p++ = "-d";
+    argc++; *p++ = "d";
+    *p = 0;
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-") == 0);
+    assert(strcmp(*p++, "-") == 0);
+    assert(strcmp(*p++, "-c") == 0);
+    assert(strcmp(*p++, "c") == 0);
+    assert(strcmp(*p++, "--") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(*p == 0);
+
+    assert(c == 'a');
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 2);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-") == 0);
+    assert(strcmp(*p++, "-") == 0);
+    assert(strcmp(*p++, "-c") == 0);
+    assert(strcmp(*p++, "c") == 0);
+    assert(strcmp(*p++, "--") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(*p == 0);
+
+    assert(c == 'c');
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 6);
+    assert(optarg == argv[5]);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-c") == 0);
+    assert(strcmp(*p++, "c") == 0);
+    assert(strcmp(*p++, "--") == 0);
+    assert(strcmp(*p++, "-") == 0);
+    assert(strcmp(*p++, "-") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(*p == 0);
+
+    assert(c == -1);
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 5);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc:d:", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-c") == 0);
+    assert(strcmp(*p++, "c") == 0);
+    assert(strcmp(*p++, "--") == 0);
+    assert(strcmp(*p++, "-") == 0);
+    assert(strcmp(*p++, "-") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(*p == 0);
+
+    assert(c == 'd');
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 9);
+    assert(optarg == argv[8]);
+    assert(optopt == 0);
+}
+
+void
+test10()
+{
+    optind = 0;
+    argc = 0;
+    p = argv;
+
+    argc++; *p++ = "command_name";
+    argc++; *p++ = "-a";
+    argc++; *p++ = "-cc";
+    argc++; *p++ = "-d";
+    argc++; *p++ = "d";
+    argc++; *p++ = "-c";        /* no argument */
+    argc++; *p++ = "-d";        /* at last */
+    *p = 0;
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc::d::", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-cc") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "-c") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(*p == 0);
+
+    assert(c == 'a');
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 2);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc::d::", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-cc") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "-c") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(*p == 0);
+
+    assert(c == 'c');
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 3);
+    assert(optarg == argv[2]+2);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc::d::", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-cc") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "-c") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(*p == 0);
+
+    assert(c == 'd');
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 4);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc::d::", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-cc") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "-c") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(*p == 0);
+
+    assert(c == 'c');
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 6);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc::d::", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-cc") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(strcmp(*p++, "-c") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(*p == 0);
+
+    assert(c == 'd');
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 7);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc::d::", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-cc") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(strcmp(*p++, "-c") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(*p == 0);
+
+    assert(c == -1);
+    assert(option_index == 5);  /* no changed */
+    assert(optind == 6);
+    assert(optarg == 0);
+    assert(optopt == 0);
+}
+
+void
+test11()
+{
+    optind = 0;
+    argc = 0;
+    p = argv;
+
+    argc++; *p++ = "command_name";
+    argc++; *p++ = "--verbose";
+    argc++; *p++ = "--create=c";
+    argc++; *p++ = "--change";
+    argc++; *p++ = "d";
+    argc++; *p++ = "--create";  /* no argument */
+    argc++; *p++ = "--change";  /* at last */
+    *p = 0;
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc::d::", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "--verbose") == 0);
+    assert(strcmp(*p++, "--create=c") == 0);
+    assert(strcmp(*p++, "--change") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "--create") == 0);
+    assert(strcmp(*p++, "--change") == 0);
+    assert(*p == 0);
+
+    assert(c == 0);
+    assert(option_index == 0);
+    assert(optind == 2);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc::d::", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "--verbose") == 0);
+    assert(strcmp(*p++, "--create=c") == 0);
+    assert(strcmp(*p++, "--change") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "--create") == 0);
+    assert(strcmp(*p++, "--change") == 0);
+    assert(*p == 0);
+
+    assert(c == 0);
+    assert(option_index == 5);
+    assert(optind == 3);
+    assert(optarg == argv[2]+9);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc::d::", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "--verbose") == 0);
+    assert(strcmp(*p++, "--create=c") == 0);
+    assert(strcmp(*p++, "--change") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "--create") == 0);
+    assert(strcmp(*p++, "--change") == 0);
+    assert(*p == 0);
+
+    assert(c == 0);
+    assert(option_index == 6);
+    assert(optind == 4);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc::d::", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "--verbose") == 0);
+    assert(strcmp(*p++, "--create=c") == 0);
+    assert(strcmp(*p++, "--change") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "--create") == 0);
+    assert(strcmp(*p++, "--change") == 0);
+    assert(*p == 0);
+
+    assert(c == 0);
+    assert(option_index == 5);
+    assert(optind == 6);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc::d::", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "--verbose") == 0);
+    assert(strcmp(*p++, "--create=c") == 0);
+    assert(strcmp(*p++, "--change") == 0);
+    assert(strcmp(*p++, "--create") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "--change") == 0);
+    assert(*p == 0);
+
+    assert(c == 0);
+    assert(option_index == 6);
+    assert(optind == 7);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc::d::", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "--verbose") == 0);
+    assert(strcmp(*p++, "--create=c") == 0);
+    assert(strcmp(*p++, "--change") == 0);
+    assert(strcmp(*p++, "--create") == 0);
+    assert(strcmp(*p++, "--change") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(*p == 0);
+
+    assert(c == -1);
+    assert(option_index == 6);
+    assert(optind == 6);
+    assert(optarg == 0);
+    assert(optopt == 0);
+}
+
+void
+test12()
+{
+    optind = 0;
+    argc = 0;
+    p = argv;
+
+    argc++; *p++ = "command_name";
+    argc++; *p++ = "--verbose";
+    argc++; *p++ = "--create=c";
+    argc++; *p++ = "files...";
+    argc++; *p++ = "--delete";  /* required argument */
+    argc++; *p++ = "d";
+    argc++; *p++ = "--create";  /* no argument */
+    argc++; *p++ = "--change";  /* at last */
+    *p = 0;
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc::d::", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "--verbose") == 0);
+    assert(strcmp(*p++, "--create=c") == 0);
+    assert(strcmp(*p++, "files...") == 0);
+    assert(strcmp(*p++, "--delete") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "--create") == 0);
+    assert(strcmp(*p++, "--change") == 0);
+    assert(*p == 0);
+
+    assert(c == 0);
+    assert(option_index == 0);
+    assert(optind == 2);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc::d::", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "--verbose") == 0);
+    assert(strcmp(*p++, "--create=c") == 0);
+    assert(strcmp(*p++, "files...") == 0);
+    assert(strcmp(*p++, "--delete") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "--create") == 0);
+    assert(strcmp(*p++, "--change") == 0);
+    assert(*p == 0);
+
+    assert(c == 0);
+    assert(option_index == 5);
+    assert(optind == 3);
+    assert(optarg == argv[2]+9);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc::d::", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "--verbose") == 0);
+    assert(strcmp(*p++, "--create=c") == 0);
+    assert(strcmp(*p++, "files...") == 0);
+    assert(strcmp(*p++, "--delete") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "--create") == 0);
+    assert(strcmp(*p++, "--change") == 0);
+    assert(*p == 0);
+
+    assert(c == 0);
+    assert(option_index == 4);
+    assert(optind == 6);
+    assert(optarg == argv[5]);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc::d::", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "--verbose") == 0);
+    assert(strcmp(*p++, "--create=c") == 0);
+    assert(strcmp(*p++, "--delete") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "files...") == 0);
+    assert(strcmp(*p++, "--create") == 0);
+    assert(strcmp(*p++, "--change") == 0);
+    assert(*p == 0);
+
+    assert(c == 0);
+    assert(option_index == 5);
+    assert(optind == 7);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc::d::", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "--verbose") == 0);
+    assert(strcmp(*p++, "--create=c") == 0);
+    assert(strcmp(*p++, "--delete") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "--create") == 0);
+    assert(strcmp(*p++, "files...") == 0);
+    assert(strcmp(*p++, "--change") == 0);
+    assert(*p == 0);
+
+    assert(c == 0);
+    assert(option_index == 6);
+    assert(optind == 8);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc::d::", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "--verbose") == 0);
+    assert(strcmp(*p++, "--create=c") == 0);
+    assert(strcmp(*p++, "--delete") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "--create") == 0);
+    assert(strcmp(*p++, "--change") == 0);
+    assert(strcmp(*p++, "files...") == 0);
+    assert(*p == 0);
+
+    assert(c == -1);
+    assert(option_index == 6);
+    assert(optind == 7);
+    assert(optarg == 0);
+    assert(optopt == 0);
+}
+
+void
+test13()
+{
+    optind = 0;
+    argc = 0;
+    p = argv;
+
+    argc++; *p++ = "command_name";
+    argc++; *p++ = "--verbose";
+    argc++; *p++ = "--create=c";
+    argc++; *p++ = "files...";
+    argc++; *p++ = "--delete";
+    argc++; *p++ = "d";
+    argc++; *p++ = "--";        /* option terminator */
+    argc++; *p++ = "--change";
+    *p = 0;
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc::d::", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "--verbose") == 0);
+    assert(strcmp(*p++, "--create=c") == 0);
+    assert(strcmp(*p++, "files...") == 0);
+    assert(strcmp(*p++, "--delete") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "--") == 0);
+    assert(strcmp(*p++, "--change") == 0);
+    assert(*p == 0);
+
+    assert(c == 0);
+    assert(option_index == 0);
+    assert(optind == 2);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc::d::", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "--verbose") == 0);
+    assert(strcmp(*p++, "--create=c") == 0);
+    assert(strcmp(*p++, "files...") == 0);
+    assert(strcmp(*p++, "--delete") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "--") == 0);
+    assert(strcmp(*p++, "--change") == 0);
+    assert(*p == 0);
+
+    assert(c == 0);
+    assert(option_index == 5);
+    assert(optind == 3);
+    assert(optarg == argv[2]+9);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc::d::", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "--verbose") == 0);
+    assert(strcmp(*p++, "--create=c") == 0);
+    assert(strcmp(*p++, "files...") == 0);
+    assert(strcmp(*p++, "--delete") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "--") == 0);
+    assert(strcmp(*p++, "--change") == 0);
+    assert(*p == 0);
+
+    assert(c == 0);
+    assert(option_index == 4);
+    assert(optind == 6);
+    assert(optarg == argv[5]);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc::d::", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "--verbose") == 0);
+    assert(strcmp(*p++, "--create=c") == 0);
+    assert(strcmp(*p++, "--delete") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "--") == 0);
+    assert(strcmp(*p++, "files...") == 0);
+    assert(strcmp(*p++, "--change") == 0);
+    assert(*p == 0);
+
+    assert(c == -1);
+    assert(option_index == 4);
+    assert(optind == 6);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+}
+
+void
+test14()
+{
+    optind = 0;
+    argc = 0;
+    p = argv;
+
+    argc++; *p++ = "command_name";
+    argc++; *p++ = "-o5";
+    argc++; *p++ = "files...";
+    *p = 0;
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "o[567]", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-o5") == 0);
+    assert(strcmp(*p++, "files...") == 0);
+    assert(*p == 0);
+
+    assert(c == 'o');
+    assert(option_index == 4);  /* no changed */
+    assert(optind == 2);
+    assert(optarg == argv[1]+2);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc[cde]d[fgh]", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-o5") == 0);
+    assert(strcmp(*p++, "files...") == 0);
+    assert(*p == 0);
+
+    assert(c == -1);
+    assert(option_index == 4);  /* no changed */
+    assert(optind == 2);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+}
+
+void
+test15()
+{
+    optind = 0;
+    argc = 0;
+    p = argv;
+
+    argc++; *p++ = "command_name";
+    argc++; *p++ = "-a";
+    argc++; *p++ = "-ccd";
+    argc++; *p++ = "-ce";
+    argc++; *p++ = "-d";
+    argc++; *p++ = "d";
+    argc++; *p++ = "-cdd";
+    argc++; *p++ = "-d";
+    *p = 0;
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc[cde]d[fgh]", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-ccd") == 0);
+    assert(strcmp(*p++, "-ce") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "-cdd") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(*p == 0);
+
+    assert(c == 'a');
+    assert(option_index == 4);  /* no changed */
+    assert(optind == 2);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc[cde]d[fgh]", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-ccd") == 0);
+    assert(strcmp(*p++, "-ce") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "-cdd") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(*p == 0);
+
+    assert(c == 'c');
+    assert(option_index == 4);  /* no changed */
+    assert(optind == 2);
+    assert(optarg == argv[2]+2);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc[cde]d[fgh]", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-ccd") == 0);
+    assert(strcmp(*p++, "-ce") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "-cdd") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(*p == 0);
+
+    assert(c == 'd');
+    assert(option_index == 4);  /* no changed */
+    assert(optind == 3);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc[cde]d[fgh]", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-ccd") == 0);
+    assert(strcmp(*p++, "-ce") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "-cdd") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(*p == 0);
+
+    assert(c == 'c');
+    assert(option_index == 4);  /* no changed */
+    assert(optind == 4);
+    assert(optarg == argv[3]+2);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc[cde]d[fgh]", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-ccd") == 0);
+    assert(strcmp(*p++, "-ce") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "-cdd") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(*p == 0);
+
+    assert(c == 'd');
+    assert(option_index == 4);  /* no changed */
+    assert(optind == 5);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc[cde]d[fgh]", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-ccd") == 0);
+    assert(strcmp(*p++, "-ce") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "-cdd") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(*p == 0);
+
+    assert(c == 'c');
+    assert(option_index == 4);  /* no changed */
+    assert(optind == 6);
+    assert(optarg == argv[6]+2);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc[cde]d[fgh]", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-ccd") == 0);
+    assert(strcmp(*p++, "-ce") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "-cdd") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(*p == 0);
+
+    assert(c == 'd');
+    assert(option_index == 4);  /* no changed */
+    assert(optind == 7);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc[cde]d[fgh]", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-ccd") == 0);
+    assert(strcmp(*p++, "-ce") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(strcmp(*p++, "-cdd") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(*p == 0);
+
+    assert(c == 'd');
+    assert(option_index == 4);  /* no changed */
+    assert(optind == 8);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+
+    /*************************/
+    c = call_getopt_long(argc, argv, "abc[cde]d[fgh]", long_options, &option_index);
+
+    p = argv;
+    assert(strcmp(*p++, "command_name") == 0);
+    assert(strcmp(*p++, "-a") == 0);
+    assert(strcmp(*p++, "-ccd") == 0);
+    assert(strcmp(*p++, "-ce") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(strcmp(*p++, "-cdd") == 0);
+    assert(strcmp(*p++, "-d") == 0);
+    assert(strcmp(*p++, "d") == 0);
+    assert(*p == 0);
+
+    assert(c == -1);
+    assert(option_index == 4);  /* no changed */
+    assert(optind == 7);
+    assert(optarg == 0);
+    assert(optopt == 0);
+
+
+}
+
+int
+main()
+{
+    opterr = 0;
+    optopt = 0;
+
+    test1();
+    test2();
+    test3();
+    test4();
+    test5();
+    test6();
+    test7();
+    test8();
+    test9();
+    test10();
+    test11();
+    test12();
+    test13();
+#ifndef USE_GNU
+    test14();
+    test15();
+#endif
+
+    return 0;
+}
+#endif