(root)/
m4-1.4.19/
tests/
test-getopt.h
       1  /* Test of command line argument processing.
       2     Copyright (C) 2009-2021 Free Software Foundation, Inc.
       3  
       4     This program is free software: you can redistribute it and/or modify
       5     it under the terms of the GNU General Public License as published by
       6     the Free Software Foundation; either version 3 of the License, or
       7     (at your option) any later version.
       8  
       9     This program is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12     GNU General Public License for more details.
      13  
      14     You should have received a copy of the GNU General Public License
      15     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      16  
      17  /* Written by Bruno Haible <bruno@clisp.org>, 2009.  */
      18  
      19  #include <stdbool.h>
      20  
      21  /* The glibc/gnulib implementation of getopt supports setting optind =
      22     0, but not all other implementations do.  This matters for getopt.
      23     But for getopt_long, we require GNU compatibility.  */
      24  #if defined __GETOPT_PREFIX || (__GLIBC__ >= 2 && !defined __UCLIBC__)
      25  # define OPTIND_MIN 0
      26  #elif HAVE_DECL_OPTRESET
      27  # define OPTIND_MIN (optreset = 1)
      28  #else
      29  # define OPTIND_MIN 1
      30  #endif
      31  
      32  static void
      33  getopt_loop (int argc, const char **argv,
      34               const char *options,
      35               int *a_seen, int *b_seen,
      36               const char **p_value, const char **q_value,
      37               int *non_options_count, const char **non_options,
      38               int *unrecognized, bool *message_issued)
      39  {
      40    int c;
      41    int pos = ftell (stderr);
      42  
      43    while ((c = getopt (argc, (char **) argv, options)) != -1)
      44      {
      45        switch (c)
      46          {
      47          case 'a':
      48            (*a_seen)++;
      49            break;
      50          case 'b':
      51            (*b_seen)++;
      52            break;
      53          case 'p':
      54            *p_value = optarg;
      55            break;
      56          case 'q':
      57            *q_value = optarg;
      58            break;
      59          case '\1':
      60            /* Must only happen with option '-' at the beginning.  */
      61            ASSERT (options[0] == '-');
      62            non_options[(*non_options_count)++] = optarg;
      63            break;
      64          case ':':
      65            /* Must only happen with option ':' at the beginning.  */
      66            ASSERT (options[0] == ':'
      67                    || ((options[0] == '-' || options[0] == '+')
      68                        && options[1] == ':'));
      69            FALLTHROUGH;
      70          case '?':
      71            *unrecognized = optopt;
      72            break;
      73          default:
      74            *unrecognized = c;
      75            break;
      76          }
      77      }
      78  
      79    *message_issued = pos < ftell (stderr);
      80  }
      81  
      82  static void
      83  test_getopt (void)
      84  {
      85    int start;
      86    bool posixly = !!getenv ("POSIXLY_CORRECT");
      87    /* See comment in getopt.c:
      88       glibc gets a LSB-compliant getopt.
      89       Standalone applications get a POSIX-compliant getopt.  */
      90  #if defined __GETOPT_PREFIX || !(__GLIBC__ >= 2 || defined __MINGW32__)
      91    /* Using getopt from gnulib or from a non-glibc system.  */
      92    posixly = true;
      93  #endif
      94  
      95    /* Test processing of boolean options.  */
      96    for (start = OPTIND_MIN; start <= 1; start++)
      97      {
      98        int a_seen = 0;
      99        int b_seen = 0;
     100        const char *p_value = NULL;
     101        const char *q_value = NULL;
     102        int non_options_count = 0;
     103        const char *non_options[10];
     104        int unrecognized = 0;
     105        bool output;
     106        int argc = 0;
     107        const char *argv[10];
     108  
     109        argv[argc++] = "program";
     110        argv[argc++] = "-a";
     111        argv[argc++] = "foo";
     112        argv[argc++] = "bar";
     113        argv[argc] = NULL;
     114        optind = start;
     115        opterr = 1;
     116        getopt_loop (argc, argv, "ab",
     117                     &a_seen, &b_seen, &p_value, &q_value,
     118                     &non_options_count, non_options, &unrecognized, &output);
     119        ASSERT (a_seen == 1);
     120        ASSERT (b_seen == 0);
     121        ASSERT (p_value == NULL);
     122        ASSERT (q_value == NULL);
     123        ASSERT (non_options_count == 0);
     124        ASSERT (unrecognized == 0);
     125        ASSERT (optind == 2);
     126        ASSERT (!output);
     127      }
     128    for (start = OPTIND_MIN; start <= 1; start++)
     129      {
     130        int a_seen = 0;
     131        int b_seen = 0;
     132        const char *p_value = NULL;
     133        const char *q_value = NULL;
     134        int non_options_count = 0;
     135        const char *non_options[10];
     136        int unrecognized = 0;
     137        bool output;
     138        int argc = 0;
     139        const char *argv[10];
     140  
     141        argv[argc++] = "program";
     142        argv[argc++] = "-b";
     143        argv[argc++] = "-a";
     144        argv[argc++] = "foo";
     145        argv[argc++] = "bar";
     146        argv[argc] = NULL;
     147        optind = start;
     148        opterr = 1;
     149        getopt_loop (argc, argv, "ab",
     150                     &a_seen, &b_seen, &p_value, &q_value,
     151                     &non_options_count, non_options, &unrecognized, &output);
     152        ASSERT (a_seen == 1);
     153        ASSERT (b_seen == 1);
     154        ASSERT (p_value == NULL);
     155        ASSERT (q_value == NULL);
     156        ASSERT (non_options_count == 0);
     157        ASSERT (unrecognized == 0);
     158        ASSERT (optind == 3);
     159        ASSERT (!output);
     160      }
     161    for (start = OPTIND_MIN; start <= 1; start++)
     162      {
     163        int a_seen = 0;
     164        int b_seen = 0;
     165        const char *p_value = NULL;
     166        const char *q_value = NULL;
     167        int non_options_count = 0;
     168        const char *non_options[10];
     169        int unrecognized = 0;
     170        bool output;
     171        int argc = 0;
     172        const char *argv[10];
     173  
     174        argv[argc++] = "program";
     175        argv[argc++] = "-ba";
     176        argv[argc++] = "foo";
     177        argv[argc++] = "bar";
     178        argv[argc] = NULL;
     179        optind = start;
     180        opterr = 1;
     181        getopt_loop (argc, argv, "ab",
     182                     &a_seen, &b_seen, &p_value, &q_value,
     183                     &non_options_count, non_options, &unrecognized, &output);
     184        ASSERT (a_seen == 1);
     185        ASSERT (b_seen == 1);
     186        ASSERT (p_value == NULL);
     187        ASSERT (q_value == NULL);
     188        ASSERT (non_options_count == 0);
     189        ASSERT (unrecognized == 0);
     190        ASSERT (optind == 2);
     191        ASSERT (!output);
     192      }
     193    for (start = OPTIND_MIN; start <= 1; start++)
     194      {
     195        int a_seen = 0;
     196        int b_seen = 0;
     197        const char *p_value = NULL;
     198        const char *q_value = NULL;
     199        int non_options_count = 0;
     200        const char *non_options[10];
     201        int unrecognized = 0;
     202        bool output;
     203        int argc = 0;
     204        const char *argv[10];
     205  
     206        argv[argc++] = "program";
     207        argv[argc++] = "-ab";
     208        argv[argc++] = "-a";
     209        argv[argc++] = "foo";
     210        argv[argc++] = "bar";
     211        argv[argc] = NULL;
     212        optind = start;
     213        opterr = 1;
     214        getopt_loop (argc, argv, "ab",
     215                     &a_seen, &b_seen, &p_value, &q_value,
     216                     &non_options_count, non_options, &unrecognized, &output);
     217        ASSERT (a_seen == 2);
     218        ASSERT (b_seen == 1);
     219        ASSERT (p_value == NULL);
     220        ASSERT (q_value == NULL);
     221        ASSERT (non_options_count == 0);
     222        ASSERT (unrecognized == 0);
     223        ASSERT (optind == 3);
     224        ASSERT (!output);
     225      }
     226  
     227    /* Test processing of options with arguments.  */
     228    for (start = OPTIND_MIN; start <= 1; start++)
     229      {
     230        int a_seen = 0;
     231        int b_seen = 0;
     232        const char *p_value = NULL;
     233        const char *q_value = NULL;
     234        int non_options_count = 0;
     235        const char *non_options[10];
     236        int unrecognized = 0;
     237        bool output;
     238        int argc = 0;
     239        const char *argv[10];
     240  
     241        argv[argc++] = "program";
     242        argv[argc++] = "-pfoo";
     243        argv[argc++] = "bar";
     244        argv[argc] = NULL;
     245        optind = start;
     246        opterr = 1;
     247        getopt_loop (argc, argv, "p:q:",
     248                     &a_seen, &b_seen, &p_value, &q_value,
     249                     &non_options_count, non_options, &unrecognized, &output);
     250        ASSERT (a_seen == 0);
     251        ASSERT (b_seen == 0);
     252        ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
     253        ASSERT (q_value == NULL);
     254        ASSERT (non_options_count == 0);
     255        ASSERT (unrecognized == 0);
     256        ASSERT (optind == 2);
     257        ASSERT (!output);
     258      }
     259    for (start = OPTIND_MIN; start <= 1; start++)
     260      {
     261        int a_seen = 0;
     262        int b_seen = 0;
     263        const char *p_value = NULL;
     264        const char *q_value = NULL;
     265        int non_options_count = 0;
     266        const char *non_options[10];
     267        int unrecognized = 0;
     268        bool output;
     269        int argc = 0;
     270        const char *argv[10];
     271  
     272        argv[argc++] = "program";
     273        argv[argc++] = "-p";
     274        argv[argc++] = "foo";
     275        argv[argc++] = "bar";
     276        argv[argc] = NULL;
     277        optind = start;
     278        opterr = 1;
     279        getopt_loop (argc, argv, "p:q:",
     280                     &a_seen, &b_seen, &p_value, &q_value,
     281                     &non_options_count, non_options, &unrecognized, &output);
     282        ASSERT (a_seen == 0);
     283        ASSERT (b_seen == 0);
     284        ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
     285        ASSERT (q_value == NULL);
     286        ASSERT (non_options_count == 0);
     287        ASSERT (unrecognized == 0);
     288        ASSERT (optind == 3);
     289        ASSERT (!output);
     290      }
     291    for (start = OPTIND_MIN; start <= 1; start++)
     292      {
     293        int a_seen = 0;
     294        int b_seen = 0;
     295        const char *p_value = NULL;
     296        const char *q_value = NULL;
     297        int non_options_count = 0;
     298        const char *non_options[10];
     299        int unrecognized = 0;
     300        bool output;
     301        int argc = 0;
     302        const char *argv[10];
     303  
     304        argv[argc++] = "program";
     305        argv[argc++] = "-ab";
     306        argv[argc++] = "-q";
     307        argv[argc++] = "baz";
     308        argv[argc++] = "-pfoo";
     309        argv[argc++] = "bar";
     310        argv[argc] = NULL;
     311        optind = start;
     312        opterr = 1;
     313        getopt_loop (argc, argv, "abp:q:",
     314                     &a_seen, &b_seen, &p_value, &q_value,
     315                     &non_options_count, non_options, &unrecognized, &output);
     316        ASSERT (a_seen == 1);
     317        ASSERT (b_seen == 1);
     318        ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
     319        ASSERT (q_value != NULL && strcmp (q_value, "baz") == 0);
     320        ASSERT (non_options_count == 0);
     321        ASSERT (unrecognized == 0);
     322        ASSERT (optind == 5);
     323        ASSERT (!output);
     324      }
     325  
     326  #if GNULIB_TEST_GETOPT_GNU
     327    /* Test processing of options with optional arguments.  */
     328    for (start = OPTIND_MIN; start <= 1; start++)
     329      {
     330        int a_seen = 0;
     331        int b_seen = 0;
     332        const char *p_value = NULL;
     333        const char *q_value = NULL;
     334        int non_options_count = 0;
     335        const char *non_options[10];
     336        int unrecognized = 0;
     337        bool output;
     338        int argc = 0;
     339        const char *argv[10];
     340  
     341        argv[argc++] = "program";
     342        argv[argc++] = "-pfoo";
     343        argv[argc++] = "bar";
     344        argv[argc] = NULL;
     345        optind = start;
     346        opterr = 1;
     347        getopt_loop (argc, argv, "p::q::",
     348                     &a_seen, &b_seen, &p_value, &q_value,
     349                     &non_options_count, non_options, &unrecognized, &output);
     350        ASSERT (a_seen == 0);
     351        ASSERT (b_seen == 0);
     352        ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
     353        ASSERT (q_value == NULL);
     354        ASSERT (non_options_count == 0);
     355        ASSERT (unrecognized == 0);
     356        ASSERT (optind == 2);
     357        ASSERT (!output);
     358      }
     359    for (start = OPTIND_MIN; start <= 1; start++)
     360      {
     361        int a_seen = 0;
     362        int b_seen = 0;
     363        const char *p_value = NULL;
     364        const char *q_value = NULL;
     365        int non_options_count = 0;
     366        const char *non_options[10];
     367        int unrecognized = 0;
     368        bool output;
     369        int argc = 0;
     370        const char *argv[10];
     371  
     372        argv[argc++] = "program";
     373        argv[argc++] = "-p";
     374        argv[argc++] = "foo";
     375        argv[argc++] = "bar";
     376        argv[argc] = NULL;
     377        optind = start;
     378        opterr = 1;
     379        getopt_loop (argc, argv, "p::q::",
     380                     &a_seen, &b_seen, &p_value, &q_value,
     381                     &non_options_count, non_options, &unrecognized, &output);
     382        ASSERT (a_seen == 0);
     383        ASSERT (b_seen == 0);
     384        ASSERT (p_value == NULL);
     385        ASSERT (q_value == NULL);
     386        ASSERT (non_options_count == 0);
     387        ASSERT (unrecognized == 0);
     388        ASSERT (optind == 2);
     389        ASSERT (!output);
     390      }
     391    for (start = OPTIND_MIN; start <= 1; start++)
     392      {
     393        int a_seen = 0;
     394        int b_seen = 0;
     395        const char *p_value = NULL;
     396        const char *q_value = NULL;
     397        int non_options_count = 0;
     398        const char *non_options[10];
     399        int unrecognized = 0;
     400        bool output;
     401        int argc = 0;
     402        const char *argv[10];
     403  
     404        argv[argc++] = "program";
     405        argv[argc++] = "-p";
     406        argv[argc++] = "-a";
     407        argv[argc++] = "bar";
     408        argv[argc] = NULL;
     409        optind = start;
     410        opterr = 1;
     411        getopt_loop (argc, argv, "abp::q::",
     412                     &a_seen, &b_seen, &p_value, &q_value,
     413                     &non_options_count, non_options, &unrecognized, &output);
     414        ASSERT (a_seen == 1);
     415        ASSERT (b_seen == 0);
     416        ASSERT (p_value == NULL);
     417        ASSERT (q_value == NULL);
     418        ASSERT (non_options_count == 0);
     419        ASSERT (unrecognized == 0);
     420        ASSERT (optind == 3);
     421        ASSERT (!output);
     422      }
     423  #endif /* GNULIB_TEST_GETOPT_GNU */
     424  
     425    /* Check that invalid options are recognized; and that both opterr
     426       and leading ':' can silence output.  */
     427    for (start = OPTIND_MIN; start <= 1; start++)
     428      {
     429        int a_seen = 0;
     430        int b_seen = 0;
     431        const char *p_value = NULL;
     432        const char *q_value = NULL;
     433        int non_options_count = 0;
     434        const char *non_options[10];
     435        int unrecognized = 0;
     436        bool output;
     437        int argc = 0;
     438        const char *argv[10];
     439  
     440        argv[argc++] = "program";
     441        argv[argc++] = "-p";
     442        argv[argc++] = "foo";
     443        argv[argc++] = "-x";
     444        argv[argc++] = "-a";
     445        argv[argc++] = "bar";
     446        argv[argc] = NULL;
     447        optind = start;
     448        opterr = 42;
     449        getopt_loop (argc, argv, "abp:q:",
     450                     &a_seen, &b_seen, &p_value, &q_value,
     451                     &non_options_count, non_options, &unrecognized, &output);
     452        ASSERT (a_seen == 1);
     453        ASSERT (b_seen == 0);
     454        ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
     455        ASSERT (q_value == NULL);
     456        ASSERT (non_options_count == 0);
     457        ASSERT (unrecognized == 'x');
     458        ASSERT (optind == 5);
     459        ASSERT (output);
     460      }
     461    for (start = OPTIND_MIN; start <= 1; start++)
     462      {
     463        int a_seen = 0;
     464        int b_seen = 0;
     465        const char *p_value = NULL;
     466        const char *q_value = NULL;
     467        int non_options_count = 0;
     468        const char *non_options[10];
     469        int unrecognized = 0;
     470        bool output;
     471        int argc = 0;
     472        const char *argv[10];
     473  
     474        argv[argc++] = "program";
     475        argv[argc++] = "-p";
     476        argv[argc++] = "foo";
     477        argv[argc++] = "-x";
     478        argv[argc++] = "-a";
     479        argv[argc++] = "bar";
     480        argv[argc] = NULL;
     481        optind = start;
     482        opterr = 0;
     483        getopt_loop (argc, argv, "abp:q:",
     484                     &a_seen, &b_seen, &p_value, &q_value,
     485                     &non_options_count, non_options, &unrecognized, &output);
     486        ASSERT (a_seen == 1);
     487        ASSERT (b_seen == 0);
     488        ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
     489        ASSERT (q_value == NULL);
     490        ASSERT (non_options_count == 0);
     491        ASSERT (unrecognized == 'x');
     492        ASSERT (optind == 5);
     493        ASSERT (!output);
     494      }
     495    for (start = OPTIND_MIN; start <= 1; start++)
     496      {
     497        int a_seen = 0;
     498        int b_seen = 0;
     499        const char *p_value = NULL;
     500        const char *q_value = NULL;
     501        int non_options_count = 0;
     502        const char *non_options[10];
     503        int unrecognized = 0;
     504        bool output;
     505        int argc = 0;
     506        const char *argv[10];
     507  
     508        argv[argc++] = "program";
     509        argv[argc++] = "-p";
     510        argv[argc++] = "foo";
     511        argv[argc++] = "-x";
     512        argv[argc++] = "-a";
     513        argv[argc++] = "bar";
     514        argv[argc] = NULL;
     515        optind = start;
     516        opterr = 1;
     517        getopt_loop (argc, argv, ":abp:q:",
     518                     &a_seen, &b_seen, &p_value, &q_value,
     519                     &non_options_count, non_options, &unrecognized, &output);
     520        ASSERT (a_seen == 1);
     521        ASSERT (b_seen == 0);
     522        ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
     523        ASSERT (q_value == NULL);
     524        ASSERT (non_options_count == 0);
     525        ASSERT (unrecognized == 'x');
     526        ASSERT (optind == 5);
     527        ASSERT (!output);
     528      }
     529    for (start = OPTIND_MIN; start <= 1; start++)
     530      {
     531        int a_seen = 0;
     532        int b_seen = 0;
     533        const char *p_value = NULL;
     534        const char *q_value = NULL;
     535        int non_options_count = 0;
     536        const char *non_options[10];
     537        int unrecognized = 0;
     538        bool output;
     539        int argc = 0;
     540        const char *argv[10];
     541  
     542        argv[argc++] = "program";
     543        argv[argc++] = "-p";
     544        argv[argc++] = "foo";
     545        argv[argc++] = "-:";
     546        argv[argc++] = "-a";
     547        argv[argc++] = "bar";
     548        argv[argc] = NULL;
     549        optind = start;
     550        opterr = 42;
     551        getopt_loop (argc, argv, "abp:q:",
     552                     &a_seen, &b_seen, &p_value, &q_value,
     553                     &non_options_count, non_options, &unrecognized, &output);
     554        ASSERT (a_seen == 1);
     555        ASSERT (b_seen == 0);
     556        ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
     557        ASSERT (q_value == NULL);
     558        ASSERT (non_options_count == 0);
     559        ASSERT (unrecognized == ':');
     560        ASSERT (optind == 5);
     561        ASSERT (output);
     562      }
     563    for (start = OPTIND_MIN; start <= 1; start++)
     564      {
     565        int a_seen = 0;
     566        int b_seen = 0;
     567        const char *p_value = NULL;
     568        const char *q_value = NULL;
     569        int non_options_count = 0;
     570        const char *non_options[10];
     571        int unrecognized = 0;
     572        bool output;
     573        int argc = 0;
     574        const char *argv[10];
     575  
     576        argv[argc++] = "program";
     577        argv[argc++] = "-p";
     578        argv[argc++] = "foo";
     579        argv[argc++] = "-:";
     580        argv[argc++] = "-a";
     581        argv[argc++] = "bar";
     582        argv[argc] = NULL;
     583        optind = start;
     584        opterr = 0;
     585        getopt_loop (argc, argv, "abp:q:",
     586                     &a_seen, &b_seen, &p_value, &q_value,
     587                     &non_options_count, non_options, &unrecognized, &output);
     588        ASSERT (a_seen == 1);
     589        ASSERT (b_seen == 0);
     590        ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
     591        ASSERT (q_value == NULL);
     592        ASSERT (non_options_count == 0);
     593        ASSERT (unrecognized == ':');
     594        ASSERT (optind == 5);
     595        ASSERT (!output);
     596      }
     597    for (start = OPTIND_MIN; start <= 1; start++)
     598      {
     599        int a_seen = 0;
     600        int b_seen = 0;
     601        const char *p_value = NULL;
     602        const char *q_value = NULL;
     603        int non_options_count = 0;
     604        const char *non_options[10];
     605        int unrecognized = 0;
     606        bool output;
     607        int argc = 0;
     608        const char *argv[10];
     609  
     610        argv[argc++] = "program";
     611        argv[argc++] = "-p";
     612        argv[argc++] = "foo";
     613        argv[argc++] = "-:";
     614        argv[argc++] = "-a";
     615        argv[argc++] = "bar";
     616        argv[argc] = NULL;
     617        optind = start;
     618        opterr = 1;
     619        getopt_loop (argc, argv, ":abp:q:",
     620                     &a_seen, &b_seen, &p_value, &q_value,
     621                     &non_options_count, non_options, &unrecognized, &output);
     622        ASSERT (a_seen == 1);
     623        ASSERT (b_seen == 0);
     624        ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
     625        ASSERT (q_value == NULL);
     626        ASSERT (non_options_count == 0);
     627        ASSERT (unrecognized == ':');
     628        ASSERT (optind == 5);
     629        ASSERT (!output);
     630      }
     631  
     632    /* Check for missing argument behavior.  */
     633    for (start = OPTIND_MIN; start <= 1; start++)
     634      {
     635        int a_seen = 0;
     636        int b_seen = 0;
     637        const char *p_value = NULL;
     638        const char *q_value = NULL;
     639        int non_options_count = 0;
     640        const char *non_options[10];
     641        int unrecognized = 0;
     642        bool output;
     643        int argc = 0;
     644        const char *argv[10];
     645  
     646        argv[argc++] = "program";
     647        argv[argc++] = "-ap";
     648        argv[argc] = NULL;
     649        optind = start;
     650        opterr = 1;
     651        getopt_loop (argc, argv, "abp:q:",
     652                     &a_seen, &b_seen, &p_value, &q_value,
     653                     &non_options_count, non_options, &unrecognized, &output);
     654        ASSERT (a_seen == 1);
     655        ASSERT (b_seen == 0);
     656        ASSERT (p_value == NULL);
     657        ASSERT (q_value == NULL);
     658        ASSERT (non_options_count == 0);
     659        ASSERT (unrecognized == 'p');
     660        ASSERT (optind == 2);
     661        ASSERT (output);
     662      }
     663    for (start = OPTIND_MIN; start <= 1; start++)
     664      {
     665        int a_seen = 0;
     666        int b_seen = 0;
     667        const char *p_value = NULL;
     668        const char *q_value = NULL;
     669        int non_options_count = 0;
     670        const char *non_options[10];
     671        int unrecognized = 0;
     672        bool output;
     673        int argc = 0;
     674        const char *argv[10];
     675  
     676        argv[argc++] = "program";
     677        argv[argc++] = "-ap";
     678        argv[argc] = NULL;
     679        optind = start;
     680        opterr = 0;
     681        getopt_loop (argc, argv, "abp:q:",
     682                     &a_seen, &b_seen, &p_value, &q_value,
     683                     &non_options_count, non_options, &unrecognized, &output);
     684        ASSERT (a_seen == 1);
     685        ASSERT (b_seen == 0);
     686        ASSERT (p_value == NULL);
     687        ASSERT (q_value == NULL);
     688        ASSERT (non_options_count == 0);
     689        ASSERT (unrecognized == 'p');
     690        ASSERT (optind == 2);
     691        ASSERT (!output);
     692      }
     693    for (start = OPTIND_MIN; start <= 1; start++)
     694      {
     695        int a_seen = 0;
     696        int b_seen = 0;
     697        const char *p_value = NULL;
     698        const char *q_value = NULL;
     699        int non_options_count = 0;
     700        const char *non_options[10];
     701        int unrecognized = 0;
     702        bool output;
     703        int argc = 0;
     704        const char *argv[10];
     705  
     706        argv[argc++] = "program";
     707        argv[argc++] = "-ap";
     708        argv[argc] = NULL;
     709        optind = start;
     710        opterr = 1;
     711        getopt_loop (argc, argv, ":abp:q:",
     712                     &a_seen, &b_seen, &p_value, &q_value,
     713                     &non_options_count, non_options, &unrecognized, &output);
     714        ASSERT (a_seen == 1);
     715        ASSERT (b_seen == 0);
     716        ASSERT (p_value == NULL);
     717        ASSERT (q_value == NULL);
     718        ASSERT (non_options_count == 0);
     719        ASSERT (unrecognized == 'p');
     720        ASSERT (optind == 2);
     721        ASSERT (!output);
     722      }
     723  
     724    /* Check that by default, non-options arguments are moved to the end.  */
     725    for (start = OPTIND_MIN; start <= 1; start++)
     726      {
     727        int a_seen = 0;
     728        int b_seen = 0;
     729        const char *p_value = NULL;
     730        const char *q_value = NULL;
     731        int non_options_count = 0;
     732        const char *non_options[10];
     733        int unrecognized = 0;
     734        bool output;
     735        int argc = 0;
     736        const char *argv[10];
     737  
     738        argv[argc++] = "program";
     739        argv[argc++] = "donald";
     740        argv[argc++] = "-p";
     741        argv[argc++] = "billy";
     742        argv[argc++] = "duck";
     743        argv[argc++] = "-a";
     744        argv[argc++] = "bar";
     745        argv[argc] = NULL;
     746        optind = start;
     747        opterr = 1;
     748        getopt_loop (argc, argv, "abp:q:",
     749                     &a_seen, &b_seen, &p_value, &q_value,
     750                     &non_options_count, non_options, &unrecognized, &output);
     751        if (posixly)
     752          {
     753            ASSERT (strcmp (argv[0], "program") == 0);
     754            ASSERT (strcmp (argv[1], "donald") == 0);
     755            ASSERT (strcmp (argv[2], "-p") == 0);
     756            ASSERT (strcmp (argv[3], "billy") == 0);
     757            ASSERT (strcmp (argv[4], "duck") == 0);
     758            ASSERT (strcmp (argv[5], "-a") == 0);
     759            ASSERT (strcmp (argv[6], "bar") == 0);
     760            ASSERT (argv[7] == NULL);
     761            ASSERT (a_seen == 0);
     762            ASSERT (b_seen == 0);
     763            ASSERT (p_value == NULL);
     764            ASSERT (q_value == NULL);
     765            ASSERT (non_options_count == 0);
     766            ASSERT (unrecognized == 0);
     767            ASSERT (optind == 1);
     768            ASSERT (!output);
     769          }
     770        else
     771          {
     772            ASSERT (strcmp (argv[0], "program") == 0);
     773            ASSERT (strcmp (argv[1], "-p") == 0);
     774            ASSERT (strcmp (argv[2], "billy") == 0);
     775            ASSERT (strcmp (argv[3], "-a") == 0);
     776            ASSERT (strcmp (argv[4], "donald") == 0);
     777            ASSERT (strcmp (argv[5], "duck") == 0);
     778            ASSERT (strcmp (argv[6], "bar") == 0);
     779            ASSERT (argv[7] == NULL);
     780            ASSERT (a_seen == 1);
     781            ASSERT (b_seen == 0);
     782            ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
     783            ASSERT (q_value == NULL);
     784            ASSERT (non_options_count == 0);
     785            ASSERT (unrecognized == 0);
     786            ASSERT (optind == 4);
     787            ASSERT (!output);
     788          }
     789      }
     790  
     791    /* Check that '--' ends the argument processing.  */
     792    for (start = OPTIND_MIN; start <= 1; start++)
     793      {
     794        int a_seen = 0;
     795        int b_seen = 0;
     796        const char *p_value = NULL;
     797        const char *q_value = NULL;
     798        int non_options_count = 0;
     799        const char *non_options[10];
     800        int unrecognized = 0;
     801        bool output;
     802        int argc = 0;
     803        const char *argv[20];
     804  
     805        argv[argc++] = "program";
     806        argv[argc++] = "donald";
     807        argv[argc++] = "-p";
     808        argv[argc++] = "billy";
     809        argv[argc++] = "duck";
     810        argv[argc++] = "-a";
     811        argv[argc++] = "--";
     812        argv[argc++] = "-b";
     813        argv[argc++] = "foo";
     814        argv[argc++] = "-q";
     815        argv[argc++] = "johnny";
     816        argv[argc++] = "bar";
     817        argv[argc] = NULL;
     818        optind = start;
     819        opterr = 1;
     820        getopt_loop (argc, argv, "abp:q:",
     821                     &a_seen, &b_seen, &p_value, &q_value,
     822                     &non_options_count, non_options, &unrecognized, &output);
     823        if (posixly)
     824          {
     825            ASSERT (strcmp (argv[0], "program") == 0);
     826            ASSERT (strcmp (argv[1], "donald") == 0);
     827            ASSERT (strcmp (argv[2], "-p") == 0);
     828            ASSERT (strcmp (argv[3], "billy") == 0);
     829            ASSERT (strcmp (argv[4], "duck") == 0);
     830            ASSERT (strcmp (argv[5], "-a") == 0);
     831            ASSERT (strcmp (argv[6], "--") == 0);
     832            ASSERT (strcmp (argv[7], "-b") == 0);
     833            ASSERT (strcmp (argv[8], "foo") == 0);
     834            ASSERT (strcmp (argv[9], "-q") == 0);
     835            ASSERT (strcmp (argv[10], "johnny") == 0);
     836            ASSERT (strcmp (argv[11], "bar") == 0);
     837            ASSERT (argv[12] == NULL);
     838            ASSERT (a_seen == 0);
     839            ASSERT (b_seen == 0);
     840            ASSERT (p_value == NULL);
     841            ASSERT (q_value == NULL);
     842            ASSERT (non_options_count == 0);
     843            ASSERT (unrecognized == 0);
     844            ASSERT (optind == 1);
     845            ASSERT (!output);
     846          }
     847        else
     848          {
     849            ASSERT (strcmp (argv[0], "program") == 0);
     850            ASSERT (strcmp (argv[1], "-p") == 0);
     851            ASSERT (strcmp (argv[2], "billy") == 0);
     852            ASSERT (strcmp (argv[3], "-a") == 0);
     853            ASSERT (strcmp (argv[4], "--") == 0);
     854            ASSERT (strcmp (argv[5], "donald") == 0);
     855            ASSERT (strcmp (argv[6], "duck") == 0);
     856            ASSERT (strcmp (argv[7], "-b") == 0);
     857            ASSERT (strcmp (argv[8], "foo") == 0);
     858            ASSERT (strcmp (argv[9], "-q") == 0);
     859            ASSERT (strcmp (argv[10], "johnny") == 0);
     860            ASSERT (strcmp (argv[11], "bar") == 0);
     861            ASSERT (argv[12] == NULL);
     862            ASSERT (a_seen == 1);
     863            ASSERT (b_seen == 0);
     864            ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
     865            ASSERT (q_value == NULL);
     866            ASSERT (non_options_count == 0);
     867            ASSERT (unrecognized == 0);
     868            ASSERT (optind == 5);
     869            ASSERT (!output);
     870          }
     871      }
     872  
     873  #if GNULIB_TEST_GETOPT_GNU
     874    /* Check that the '-' flag causes non-options to be returned in order.  */
     875    for (start = OPTIND_MIN; start <= 1; start++)
     876      {
     877        int a_seen = 0;
     878        int b_seen = 0;
     879        const char *p_value = NULL;
     880        const char *q_value = NULL;
     881        int non_options_count = 0;
     882        const char *non_options[10];
     883        int unrecognized = 0;
     884        bool output;
     885        int argc = 0;
     886        const char *argv[10];
     887  
     888        argv[argc++] = "program";
     889        argv[argc++] = "donald";
     890        argv[argc++] = "-p";
     891        argv[argc++] = "billy";
     892        argv[argc++] = "duck";
     893        argv[argc++] = "-a";
     894        argv[argc++] = "bar";
     895        argv[argc] = NULL;
     896        optind = start;
     897        opterr = 1;
     898        getopt_loop (argc, argv, "-abp:q:",
     899                     &a_seen, &b_seen, &p_value, &q_value,
     900                     &non_options_count, non_options, &unrecognized, &output);
     901        ASSERT (strcmp (argv[0], "program") == 0);
     902        ASSERT (strcmp (argv[1], "donald") == 0);
     903        ASSERT (strcmp (argv[2], "-p") == 0);
     904        ASSERT (strcmp (argv[3], "billy") == 0);
     905        ASSERT (strcmp (argv[4], "duck") == 0);
     906        ASSERT (strcmp (argv[5], "-a") == 0);
     907        ASSERT (strcmp (argv[6], "bar") == 0);
     908        ASSERT (argv[7] == NULL);
     909        ASSERT (a_seen == 1);
     910        ASSERT (b_seen == 0);
     911        ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
     912        ASSERT (q_value == NULL);
     913        ASSERT (non_options_count == 3);
     914        ASSERT (strcmp (non_options[0], "donald") == 0);
     915        ASSERT (strcmp (non_options[1], "duck") == 0);
     916        ASSERT (strcmp (non_options[2], "bar") == 0);
     917        ASSERT (unrecognized == 0);
     918        ASSERT (optind == 7);
     919        ASSERT (!output);
     920      }
     921  
     922    /* Check that '--' ends the argument processing.  */
     923    for (start = OPTIND_MIN; start <= 1; start++)
     924      {
     925        int a_seen = 0;
     926        int b_seen = 0;
     927        const char *p_value = NULL;
     928        const char *q_value = NULL;
     929        int non_options_count = 0;
     930        const char *non_options[10];
     931        int unrecognized = 0;
     932        bool output;
     933        int argc = 0;
     934        const char *argv[20];
     935  
     936        argv[argc++] = "program";
     937        argv[argc++] = "donald";
     938        argv[argc++] = "-p";
     939        argv[argc++] = "billy";
     940        argv[argc++] = "duck";
     941        argv[argc++] = "-a";
     942        argv[argc++] = "--";
     943        argv[argc++] = "-b";
     944        argv[argc++] = "foo";
     945        argv[argc++] = "-q";
     946        argv[argc++] = "johnny";
     947        argv[argc++] = "bar";
     948        argv[argc] = NULL;
     949        optind = start;
     950        opterr = 1;
     951        getopt_loop (argc, argv, "-abp:q:",
     952                     &a_seen, &b_seen, &p_value, &q_value,
     953                     &non_options_count, non_options, &unrecognized, &output);
     954        ASSERT (strcmp (argv[0], "program") == 0);
     955        ASSERT (strcmp (argv[1], "donald") == 0);
     956        ASSERT (strcmp (argv[2], "-p") == 0);
     957        ASSERT (strcmp (argv[3], "billy") == 0);
     958        ASSERT (strcmp (argv[4], "duck") == 0);
     959        ASSERT (strcmp (argv[5], "-a") == 0);
     960        ASSERT (strcmp (argv[6], "--") == 0);
     961        ASSERT (strcmp (argv[7], "-b") == 0);
     962        ASSERT (strcmp (argv[8], "foo") == 0);
     963        ASSERT (strcmp (argv[9], "-q") == 0);
     964        ASSERT (strcmp (argv[10], "johnny") == 0);
     965        ASSERT (strcmp (argv[11], "bar") == 0);
     966        ASSERT (argv[12] == NULL);
     967        ASSERT (a_seen == 1);
     968        ASSERT (b_seen == 0);
     969        ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
     970        ASSERT (q_value == NULL);
     971        ASSERT (!output);
     972        if (non_options_count == 2)
     973          {
     974            /* glibc behaviour.  */
     975            ASSERT (non_options_count == 2);
     976            ASSERT (strcmp (non_options[0], "donald") == 0);
     977            ASSERT (strcmp (non_options[1], "duck") == 0);
     978            ASSERT (unrecognized == 0);
     979            ASSERT (optind == 7);
     980          }
     981        else
     982          {
     983            /* Another valid behaviour.  */
     984            ASSERT (non_options_count == 7);
     985            ASSERT (strcmp (non_options[0], "donald") == 0);
     986            ASSERT (strcmp (non_options[1], "duck") == 0);
     987            ASSERT (strcmp (non_options[2], "-b") == 0);
     988            ASSERT (strcmp (non_options[3], "foo") == 0);
     989            ASSERT (strcmp (non_options[4], "-q") == 0);
     990            ASSERT (strcmp (non_options[5], "johnny") == 0);
     991            ASSERT (strcmp (non_options[6], "bar") == 0);
     992            ASSERT (unrecognized == 0);
     993            ASSERT (optind == 12);
     994          }
     995      }
     996  
     997    /* Check that the '-' flag has to come first.  */
     998    for (start = OPTIND_MIN; start <= 1; start++)
     999      {
    1000        int a_seen = 0;
    1001        int b_seen = 0;
    1002        const char *p_value = NULL;
    1003        const char *q_value = NULL;
    1004        int non_options_count = 0;
    1005        const char *non_options[10];
    1006        int unrecognized = 0;
    1007        bool output;
    1008        int argc = 0;
    1009        const char *argv[10];
    1010  
    1011        argv[argc++] = "program";
    1012        argv[argc++] = "donald";
    1013        argv[argc++] = "-p";
    1014        argv[argc++] = "billy";
    1015        argv[argc++] = "duck";
    1016        argv[argc++] = "-a";
    1017        argv[argc++] = "bar";
    1018        argv[argc] = NULL;
    1019        optind = start;
    1020        opterr = 1;
    1021        getopt_loop (argc, argv, "abp:q:-",
    1022                     &a_seen, &b_seen, &p_value, &q_value,
    1023                     &non_options_count, non_options, &unrecognized, &output);
    1024        if (posixly)
    1025          {
    1026            ASSERT (strcmp (argv[0], "program") == 0);
    1027            ASSERT (strcmp (argv[1], "donald") == 0);
    1028            ASSERT (strcmp (argv[2], "-p") == 0);
    1029            ASSERT (strcmp (argv[3], "billy") == 0);
    1030            ASSERT (strcmp (argv[4], "duck") == 0);
    1031            ASSERT (strcmp (argv[5], "-a") == 0);
    1032            ASSERT (strcmp (argv[6], "bar") == 0);
    1033            ASSERT (argv[7] == NULL);
    1034            ASSERT (a_seen == 0);
    1035            ASSERT (b_seen == 0);
    1036            ASSERT (p_value == NULL);
    1037            ASSERT (q_value == NULL);
    1038            ASSERT (non_options_count == 0);
    1039            ASSERT (unrecognized == 0);
    1040            ASSERT (optind == 1);
    1041            ASSERT (!output);
    1042          }
    1043        else
    1044          {
    1045            ASSERT (strcmp (argv[0], "program") == 0);
    1046            ASSERT (strcmp (argv[1], "-p") == 0);
    1047            ASSERT (strcmp (argv[2], "billy") == 0);
    1048            ASSERT (strcmp (argv[3], "-a") == 0);
    1049            ASSERT (strcmp (argv[4], "donald") == 0);
    1050            ASSERT (strcmp (argv[5], "duck") == 0);
    1051            ASSERT (strcmp (argv[6], "bar") == 0);
    1052            ASSERT (argv[7] == NULL);
    1053            ASSERT (a_seen == 1);
    1054            ASSERT (b_seen == 0);
    1055            ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
    1056            ASSERT (q_value == NULL);
    1057            ASSERT (non_options_count == 0);
    1058            ASSERT (unrecognized == 0);
    1059            ASSERT (optind == 4);
    1060            ASSERT (!output);
    1061          }
    1062      }
    1063  
    1064    /* Check that the '+' flag causes the first non-option to terminate the
    1065       loop.  */
    1066    for (start = OPTIND_MIN; start <= 1; start++)
    1067      {
    1068        int a_seen = 0;
    1069        int b_seen = 0;
    1070        const char *p_value = NULL;
    1071        const char *q_value = NULL;
    1072        int non_options_count = 0;
    1073        const char *non_options[10];
    1074        int unrecognized = 0;
    1075        bool output;
    1076        int argc = 0;
    1077        const char *argv[10];
    1078  
    1079        argv[argc++] = "program";
    1080        argv[argc++] = "donald";
    1081        argv[argc++] = "-p";
    1082        argv[argc++] = "billy";
    1083        argv[argc++] = "duck";
    1084        argv[argc++] = "-a";
    1085        argv[argc++] = "bar";
    1086        argv[argc] = NULL;
    1087        optind = start;
    1088        opterr = 1;
    1089        getopt_loop (argc, argv, "+abp:q:",
    1090                     &a_seen, &b_seen, &p_value, &q_value,
    1091                     &non_options_count, non_options, &unrecognized, &output);
    1092        ASSERT (strcmp (argv[0], "program") == 0);
    1093        ASSERT (strcmp (argv[1], "donald") == 0);
    1094        ASSERT (strcmp (argv[2], "-p") == 0);
    1095        ASSERT (strcmp (argv[3], "billy") == 0);
    1096        ASSERT (strcmp (argv[4], "duck") == 0);
    1097        ASSERT (strcmp (argv[5], "-a") == 0);
    1098        ASSERT (strcmp (argv[6], "bar") == 0);
    1099        ASSERT (argv[7] == NULL);
    1100        ASSERT (a_seen == 0);
    1101        ASSERT (b_seen == 0);
    1102        ASSERT (p_value == NULL);
    1103        ASSERT (q_value == NULL);
    1104        ASSERT (non_options_count == 0);
    1105        ASSERT (unrecognized == 0);
    1106        ASSERT (optind == 1);
    1107        ASSERT (!output);
    1108      }
    1109    for (start = OPTIND_MIN; start <= 1; start++)
    1110      {
    1111        int a_seen = 0;
    1112        int b_seen = 0;
    1113        const char *p_value = NULL;
    1114        const char *q_value = NULL;
    1115        int non_options_count = 0;
    1116        const char *non_options[10];
    1117        int unrecognized = 0;
    1118        bool output;
    1119        int argc = 0;
    1120        const char *argv[10];
    1121  
    1122        argv[argc++] = "program";
    1123        argv[argc++] = "-+";
    1124        argv[argc] = NULL;
    1125        optind = start;
    1126        getopt_loop (argc, argv, "+abp:q:",
    1127                     &a_seen, &b_seen, &p_value, &q_value,
    1128                     &non_options_count, non_options, &unrecognized, &output);
    1129        ASSERT (a_seen == 0);
    1130        ASSERT (b_seen == 0);
    1131        ASSERT (p_value == NULL);
    1132        ASSERT (q_value == NULL);
    1133        ASSERT (non_options_count == 0);
    1134        ASSERT (unrecognized == '+');
    1135        ASSERT (optind == 2);
    1136        ASSERT (output);
    1137      }
    1138  
    1139    /* Check that '--' ends the argument processing.  */
    1140    for (start = OPTIND_MIN; start <= 1; start++)
    1141      {
    1142        int a_seen = 0;
    1143        int b_seen = 0;
    1144        const char *p_value = NULL;
    1145        const char *q_value = NULL;
    1146        int non_options_count = 0;
    1147        const char *non_options[10];
    1148        int unrecognized = 0;
    1149        bool output;
    1150        int argc = 0;
    1151        const char *argv[20];
    1152  
    1153        argv[argc++] = "program";
    1154        argv[argc++] = "donald";
    1155        argv[argc++] = "-p";
    1156        argv[argc++] = "billy";
    1157        argv[argc++] = "duck";
    1158        argv[argc++] = "-a";
    1159        argv[argc++] = "--";
    1160        argv[argc++] = "-b";
    1161        argv[argc++] = "foo";
    1162        argv[argc++] = "-q";
    1163        argv[argc++] = "johnny";
    1164        argv[argc++] = "bar";
    1165        argv[argc] = NULL;
    1166        optind = start;
    1167        opterr = 1;
    1168        getopt_loop (argc, argv, "+abp:q:",
    1169                     &a_seen, &b_seen, &p_value, &q_value,
    1170                     &non_options_count, non_options, &unrecognized, &output);
    1171        ASSERT (strcmp (argv[0], "program") == 0);
    1172        ASSERT (strcmp (argv[1], "donald") == 0);
    1173        ASSERT (strcmp (argv[2], "-p") == 0);
    1174        ASSERT (strcmp (argv[3], "billy") == 0);
    1175        ASSERT (strcmp (argv[4], "duck") == 0);
    1176        ASSERT (strcmp (argv[5], "-a") == 0);
    1177        ASSERT (strcmp (argv[6], "--") == 0);
    1178        ASSERT (strcmp (argv[7], "-b") == 0);
    1179        ASSERT (strcmp (argv[8], "foo") == 0);
    1180        ASSERT (strcmp (argv[9], "-q") == 0);
    1181        ASSERT (strcmp (argv[10], "johnny") == 0);
    1182        ASSERT (strcmp (argv[11], "bar") == 0);
    1183        ASSERT (argv[12] == NULL);
    1184        ASSERT (a_seen == 0);
    1185        ASSERT (b_seen == 0);
    1186        ASSERT (p_value == NULL);
    1187        ASSERT (q_value == NULL);
    1188        ASSERT (non_options_count == 0);
    1189        ASSERT (unrecognized == 0);
    1190        ASSERT (optind == 1);
    1191        ASSERT (!output);
    1192      }
    1193  #endif /* GNULIB_TEST_GETOPT_GNU */
    1194  
    1195    /* Check that the '+' flag has to come first.  */
    1196    for (start = OPTIND_MIN; start <= 1; start++)
    1197      {
    1198        int a_seen = 0;
    1199        int b_seen = 0;
    1200        const char *p_value = NULL;
    1201        const char *q_value = NULL;
    1202        int non_options_count = 0;
    1203        const char *non_options[10];
    1204        int unrecognized = 0;
    1205        bool output;
    1206        int argc = 0;
    1207        const char *argv[10];
    1208  
    1209        argv[argc++] = "program";
    1210        argv[argc++] = "donald";
    1211        argv[argc++] = "-p";
    1212        argv[argc++] = "billy";
    1213        argv[argc++] = "duck";
    1214        argv[argc++] = "-a";
    1215        argv[argc++] = "bar";
    1216        argv[argc] = NULL;
    1217        optind = start;
    1218        opterr = 1;
    1219        getopt_loop (argc, argv, "abp:q:+",
    1220                     &a_seen, &b_seen, &p_value, &q_value,
    1221                     &non_options_count, non_options, &unrecognized, &output);
    1222        if (posixly)
    1223          {
    1224            ASSERT (strcmp (argv[0], "program") == 0);
    1225            ASSERT (strcmp (argv[1], "donald") == 0);
    1226            ASSERT (strcmp (argv[2], "-p") == 0);
    1227            ASSERT (strcmp (argv[3], "billy") == 0);
    1228            ASSERT (strcmp (argv[4], "duck") == 0);
    1229            ASSERT (strcmp (argv[5], "-a") == 0);
    1230            ASSERT (strcmp (argv[6], "bar") == 0);
    1231            ASSERT (argv[7] == NULL);
    1232            ASSERT (a_seen == 0);
    1233            ASSERT (b_seen == 0);
    1234            ASSERT (p_value == NULL);
    1235            ASSERT (q_value == NULL);
    1236            ASSERT (non_options_count == 0);
    1237            ASSERT (unrecognized == 0);
    1238            ASSERT (optind == 1);
    1239            ASSERT (!output);
    1240          }
    1241        else
    1242          {
    1243            ASSERT (strcmp (argv[0], "program") == 0);
    1244            ASSERT (strcmp (argv[1], "-p") == 0);
    1245            ASSERT (strcmp (argv[2], "billy") == 0);
    1246            ASSERT (strcmp (argv[3], "-a") == 0);
    1247            ASSERT (strcmp (argv[4], "donald") == 0);
    1248            ASSERT (strcmp (argv[5], "duck") == 0);
    1249            ASSERT (strcmp (argv[6], "bar") == 0);
    1250            ASSERT (argv[7] == NULL);
    1251            ASSERT (a_seen == 1);
    1252            ASSERT (b_seen == 0);
    1253            ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
    1254            ASSERT (q_value == NULL);
    1255            ASSERT (non_options_count == 0);
    1256            ASSERT (unrecognized == 0);
    1257            ASSERT (optind == 4);
    1258            ASSERT (!output);
    1259          }
    1260      }
    1261  
    1262  #if GNULIB_TEST_GETOPT_GNU
    1263    /* If GNU extensions are supported, require compliance with POSIX
    1264       interpretation on leading '+' behavior.
    1265       http://austingroupbugs.net/view.php?id=191  */
    1266    for (start = OPTIND_MIN; start <= 1; start++)
    1267      {
    1268        int a_seen = 0;
    1269        int b_seen = 0;
    1270        const char *p_value = NULL;
    1271        const char *q_value = NULL;
    1272        int non_options_count = 0;
    1273        const char *non_options[10];
    1274        int unrecognized = 0;
    1275        bool output;
    1276        int argc = 0;
    1277        const char *argv[10];
    1278  
    1279        argv[argc++] = "program";
    1280        argv[argc++] = "donald";
    1281        argv[argc++] = "-p";
    1282        argv[argc++] = "billy";
    1283        argv[argc++] = "duck";
    1284        argv[argc++] = "-a";
    1285        argv[argc++] = "bar";
    1286        argv[argc] = NULL;
    1287        optind = start;
    1288        opterr = 1;
    1289        getopt_loop (argc, argv, "+:abp:q:",
    1290                     &a_seen, &b_seen, &p_value, &q_value,
    1291                     &non_options_count, non_options, &unrecognized, &output);
    1292        ASSERT (strcmp (argv[0], "program") == 0);
    1293        ASSERT (strcmp (argv[1], "donald") == 0);
    1294        ASSERT (strcmp (argv[2], "-p") == 0);
    1295        ASSERT (strcmp (argv[3], "billy") == 0);
    1296        ASSERT (strcmp (argv[4], "duck") == 0);
    1297        ASSERT (strcmp (argv[5], "-a") == 0);
    1298        ASSERT (strcmp (argv[6], "bar") == 0);
    1299        ASSERT (argv[7] == NULL);
    1300        ASSERT (a_seen == 0);
    1301        ASSERT (b_seen == 0);
    1302        ASSERT (p_value == NULL);
    1303        ASSERT (q_value == NULL);
    1304        ASSERT (non_options_count == 0);
    1305        ASSERT (unrecognized == 0);
    1306        ASSERT (optind == 1);
    1307        ASSERT (!output);
    1308      }
    1309    for (start = OPTIND_MIN; start <= 1; start++)
    1310      {
    1311        int a_seen = 0;
    1312        int b_seen = 0;
    1313        const char *p_value = NULL;
    1314        const char *q_value = NULL;
    1315        int non_options_count = 0;
    1316        const char *non_options[10];
    1317        int unrecognized = 0;
    1318        bool output;
    1319        int argc = 0;
    1320        const char *argv[10];
    1321  
    1322        argv[argc++] = "program";
    1323        argv[argc++] = "-p";
    1324        argv[argc] = NULL;
    1325        optind = start;
    1326        getopt_loop (argc, argv, "+:abp:q:",
    1327                     &a_seen, &b_seen, &p_value, &q_value,
    1328                     &non_options_count, non_options, &unrecognized, &output);
    1329        ASSERT (a_seen == 0);
    1330        ASSERT (b_seen == 0);
    1331        ASSERT (p_value == NULL);
    1332        ASSERT (q_value == NULL);
    1333        ASSERT (non_options_count == 0);
    1334        ASSERT (unrecognized == 'p');
    1335        ASSERT (optind == 2);
    1336        ASSERT (!output);
    1337      }
    1338    for (start = OPTIND_MIN; start <= 1; start++)
    1339      {
    1340        int a_seen = 0;
    1341        int b_seen = 0;
    1342        const char *p_value = NULL;
    1343        const char *q_value = NULL;
    1344        int non_options_count = 0;
    1345        const char *non_options[10];
    1346        int unrecognized = 0;
    1347        bool output;
    1348        int argc = 0;
    1349        const char *argv[10];
    1350  
    1351        argv[argc++] = "program";
    1352        argv[argc++] = "-b";
    1353        argv[argc++] = "-p";
    1354        argv[argc] = NULL;
    1355        optind = start;
    1356        getopt_loop (argc, argv, "+:abp:q:",
    1357                     &a_seen, &b_seen, &p_value, &q_value,
    1358                     &non_options_count, non_options, &unrecognized, &output);
    1359        ASSERT (a_seen == 0);
    1360        ASSERT (b_seen == 1);
    1361        ASSERT (p_value == NULL);
    1362        ASSERT (q_value == NULL);
    1363        ASSERT (non_options_count == 0);
    1364        ASSERT (unrecognized == 'p');
    1365        ASSERT (optind == 3);
    1366        ASSERT (!output);
    1367      }
    1368  
    1369    /* Check that 'W' does not dump core:
    1370       https://sourceware.org/bugzilla/show_bug.cgi?id=12922
    1371       Technically, POSIX says the presence of ';' in the opt-string
    1372       gives unspecified behavior, so we only test this when GNU compliance
    1373       is desired.  */
    1374    for (start = OPTIND_MIN; start <= 1; start++)
    1375      {
    1376        int argc = 0;
    1377        const char *argv[10];
    1378        int pos = ftell (stderr);
    1379  
    1380        argv[argc++] = "program";
    1381        argv[argc++] = "-W";
    1382        argv[argc++] = "dummy";
    1383        argv[argc] = NULL;
    1384        optind = start;
    1385        opterr = 1;
    1386        ASSERT (getopt (argc, (char **) argv, "W;") == 'W');
    1387        ASSERT (ftell (stderr) == pos);
    1388        ASSERT (optind == 2);
    1389      }
    1390  #endif /* GNULIB_TEST_GETOPT_GNU */
    1391  }