/[oroborus]/oroborus/src/getopt.c
ViewVC logotype

Diff of /oroborus/src/getopt.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.2 by dreamind, Sun Jul 7 03:17:41 2002 UTC revision 1.3 by dreamind, Mon Jul 15 08:23:07 2002 UTC
# Line 183  int optopt = '?'; Line 183  int optopt = '?';
183    
184  static enum  static enum
185  {  {
186    REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER          REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
187  }  }
188  ordering;  ordering;
189    
# Line 214  extern char *getenv (); Line 214  extern char *getenv ();
214    
215  static char *  static char *
216  my_index (str, chr)  my_index (str, chr)
217       const char *str;                   const char *str;
218       int chr;                   int chr;
219  {  {
220    while (*str)          while (*str)
221      {                  {
222        if (*str == chr)                          if (*str == chr)
223          return (char *) str;                                  return (char *) str;
224        str++;                          str++;
225      }                  }
226    return 0;          return 0;
227  }  }
228    
229  /* If using GCC, we can safely declare strlen this way.  /* If using GCC, we can safely declare strlen this way.
# Line 266  static char *const *original_argv; Line 266  static char *const *original_argv;
266     is valid for the getopt call we must make sure that the ARGV passed     is valid for the getopt call we must make sure that the ARGV passed
267     to getopt is that one passed to the process.  */     to getopt is that one passed to the process.  */
268  static void  static void
269    __attribute__ ((unused)) store_args_and_env (int argc, char *const *argv)          __attribute__ ((unused)) store_args_and_env (int argc, char *const *argv)
270  {  {
271    /* XXX This is no good solution.  We should rather copy the args so          /* XXX This is no good solution.  We should rather copy the args so
272       that we can compare them later.  But we must not use malloc(3).  */             that we can compare them later.  But we must not use malloc(3).  */
273    original_argc = argc;          original_argc = argc;
274    original_argv = argv;          original_argv = argv;
275  }  }
276    
277  # ifdef text_set_element  # ifdef text_set_element
# Line 285  text_set_element (__libc_subinit, store_ Line 285  text_set_element (__libc_subinit, store_
285        __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];          \        __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];          \
286        __getopt_nonoption_flags[ch2] = __tmp;                                  \        __getopt_nonoption_flags[ch2] = __tmp;                                  \
287      }      }
288  #else /* !_LIBC */  #else   /* !_LIBC */
289  # define SWAP_FLAGS(ch1, ch2)  # define SWAP_FLAGS(ch1, ch2)
290  #endif /* _LIBC */  #endif /* _LIBC */
291    
# Line 304  static void exchange (char **); Line 304  static void exchange (char **);
304    
305  static void  static void
306  exchange (argv)  exchange (argv)
307       char **argv;                   char **argv;
308  {  {
309    int bottom = first_nonopt;          int bottom = first_nonopt;
310    int middle = last_nonopt;          int middle = last_nonopt;
311    int top = optind;          int top = optind;
312    char *tem;          char *tem;
313    
314    /* Exchange the shorter segment with the far end of the longer segment.          /* Exchange the shorter segment with the far end of the longer segment.
315       That puts the shorter segment into the right place.             That puts the shorter segment into the right place.
316       It leaves the longer segment in the right place overall,             It leaves the longer segment in the right place overall,
317       but it consists of two parts that need to be swapped next.  */             but it consists of two parts that need to be swapped next.  */
318    
319  #ifdef _LIBC  #ifdef _LIBC
320    /* First make sure the handling of the `__getopt_nonoption_flags'          /* First make sure the handling of the `__getopt_nonoption_flags'
321       string can work normally.  Our top argument must be in the range             string can work normally.  Our top argument must be in the range
322       of the string.  */             of the string.  */
323    if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)          if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
324      {                  {
325        /* We must extend the array.  The user plays games with us and                          /* We must extend the array.  The user plays games with us and
326           presents new arguments.  */                             presents new arguments.  */
327        char *new_str = malloc (top + 1);                          char *new_str = malloc (top + 1);
328        if (new_str == NULL)                          if (new_str == NULL)
329          nonoption_flags_len = nonoption_flags_max_len = 0;                                  nonoption_flags_len = nonoption_flags_max_len = 0;
330        else                          else
331          {                                  {
332            memset (__mempcpy (new_str, __getopt_nonoption_flags,                                          memset (__mempcpy (new_str, __getopt_nonoption_flags,
333                               nonoption_flags_max_len),                                                                                                                   nonoption_flags_max_len),
334                    '\0', top + 1 - nonoption_flags_max_len);                                                                          '\0', top + 1 - nonoption_flags_max_len);
335            nonoption_flags_max_len = top + 1;                                          nonoption_flags_max_len = top + 1;
336            __getopt_nonoption_flags = new_str;                                          __getopt_nonoption_flags = new_str;
337          }                                  }
338      }                  }
339  #endif  #endif
340    
341    while (top > middle && middle > bottom)          while (top > middle && middle > bottom)
342      {                  {
343        if (top - middle > middle - bottom)                          if (top - middle > middle - bottom)
344          {                                  {
345            /* Bottom segment is the short one.  */                                          /* Bottom segment is the short one.  */
346            int len = middle - bottom;                                          int len = middle - bottom;
347            register int i;                                          register int i;
348    
349            /* Swap it with the top part of the top segment.  */                                          /* Swap it with the top part of the top segment.  */
350            for (i = 0; i < len; i++)                                          for (i = 0; i < len; i++)
351              {                                                  {
352                tem = argv[bottom + i];                                                          tem = argv[bottom + i];
353                argv[bottom + i] = argv[top - (middle - bottom) + i];                                                          argv[bottom + i] = argv[top - (middle - bottom) + i];
354                argv[top - (middle - bottom) + i] = tem;                                                          argv[top - (middle - bottom) + i] = tem;
355                SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);                                                          SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
356              }                                                  }
357            /* Exclude the moved bottom segment from further swapping.  */                                          /* Exclude the moved bottom segment from further swapping.  */
358            top -= len;                                          top -= len;
359          }                                  }
360        else                          else
361          {                                  {
362            /* Top segment is the short one.  */                                          /* Top segment is the short one.  */
363            int len = top - middle;                                          int len = top - middle;
364            register int i;                                          register int i;
365    
366            /* Swap it with the bottom part of the bottom segment.  */                                          /* Swap it with the bottom part of the bottom segment.  */
367            for (i = 0; i < len; i++)                                          for (i = 0; i < len; i++)
368              {                                                  {
369                tem = argv[bottom + i];                                                          tem = argv[bottom + i];
370                argv[bottom + i] = argv[middle + i];                                                          argv[bottom + i] = argv[middle + i];
371                argv[middle + i] = tem;                                                          argv[middle + i] = tem;
372                SWAP_FLAGS (bottom + i, middle + i);                                                          SWAP_FLAGS (bottom + i, middle + i);
373              }                                                  }
374            /* Exclude the moved top segment from further swapping.  */                                          /* Exclude the moved top segment from further swapping.  */
375            bottom += len;                                          bottom += len;
376          }                                  }
377      }                  }
378    
379    /* Update records for the slots the non-options now occupy.  */          /* Update records for the slots the non-options now occupy.  */
380    
381    first_nonopt += (optind - last_nonopt);          first_nonopt += (optind - last_nonopt);
382    last_nonopt = optind;          last_nonopt = optind;
383  }  }
384    
385  /* Initialize the internal data when the first call is made.  */  /* Initialize the internal data when the first call is made.  */
# Line 389  static const char *_getopt_initialize (i Line 389  static const char *_getopt_initialize (i
389  #endif  #endif
390  static const char *  static const char *
391  _getopt_initialize (argc, argv, optstring)  _getopt_initialize (argc, argv, optstring)
392       int argc;                   int argc;
393       char *const *argv;                   char *const *argv;
394       const char *optstring;                   const char *optstring;
395  {  {
396    /* Start processing options with ARGV-element 1 (since ARGV-element 0          /* Start processing options with ARGV-element 1 (since ARGV-element 0
397       is the program name); the sequence of previously skipped             is the program name); the sequence of previously skipped
398       non-option ARGV-elements is empty.  */             non-option ARGV-elements is empty.  */
399    
400    first_nonopt = last_nonopt = optind;          first_nonopt = last_nonopt = optind;
401    
402    nextchar = NULL;          nextchar = NULL;
403    
404    posixly_correct = getenv ("POSIXLY_CORRECT");          posixly_correct = getenv ("POSIXLY_CORRECT");
405    
406    /* Determine how to handle the ordering of options and nonoptions.  */          /* Determine how to handle the ordering of options and nonoptions.  */
407    
408    if (optstring[0] == '-')          if (optstring[0] == '-')
409      {                  {
410        ordering = RETURN_IN_ORDER;                          ordering = RETURN_IN_ORDER;
411        ++optstring;                          ++optstring;
412      }                  }
413    else if (optstring[0] == '+')          else if (optstring[0] == '+')
414      {                  {
415        ordering = REQUIRE_ORDER;                          ordering = REQUIRE_ORDER;
416        ++optstring;                          ++optstring;
417      }                  }
418    else if (posixly_correct != NULL)          else if (posixly_correct != NULL)
419      ordering = REQUIRE_ORDER;                  ordering = REQUIRE_ORDER;
420    else          else
421      ordering = PERMUTE;                  ordering = PERMUTE;
422    
423  #ifdef _LIBC  #ifdef _LIBC
424    if (posixly_correct == NULL          if (posixly_correct == NULL
425        && argc == original_argc && argv == original_argv)                          && argc == original_argc && argv == original_argv)
426      {                  {
427        if (nonoption_flags_max_len == 0)                          if (nonoption_flags_max_len == 0)
428          {                                  {
429            if (__getopt_nonoption_flags == NULL                                          if (__getopt_nonoption_flags == NULL
430                || __getopt_nonoption_flags[0] == '\0')                                                          || __getopt_nonoption_flags[0] == '\0')
431              nonoption_flags_max_len = -1;                                                  nonoption_flags_max_len = -1;
432            else                                          else
433              {                                                  {
434                const char *orig_str = __getopt_nonoption_flags;                                                          const char *orig_str = __getopt_nonoption_flags;
435                int len = nonoption_flags_max_len = strlen (orig_str);                                                          int len = nonoption_flags_max_len = strlen (orig_str);
436                if (nonoption_flags_max_len < argc)                                                          if (nonoption_flags_max_len < argc)
437                  nonoption_flags_max_len = argc;                                                                  nonoption_flags_max_len = argc;
438                __getopt_nonoption_flags =                                                          __getopt_nonoption_flags =
439                  (char *) malloc (nonoption_flags_max_len);                                                                  (char *) malloc (nonoption_flags_max_len);
440                if (__getopt_nonoption_flags == NULL)                                                          if (__getopt_nonoption_flags == NULL)
441                  nonoption_flags_max_len = -1;                                                                  nonoption_flags_max_len = -1;
442                else                                                          else
443                  memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),                                                                  memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
444                          '\0', nonoption_flags_max_len - len);                                                                                                  '\0', nonoption_flags_max_len - len);
445              }                                                  }
446          }                                  }
447        nonoption_flags_len = nonoption_flags_max_len;                          nonoption_flags_len = nonoption_flags_max_len;
448      }                  }
449    else          else
450      nonoption_flags_len = 0;                  nonoption_flags_len = 0;
451  #endif  #endif
452    
453    return optstring;          return optstring;
454  }  }
455    
456  /* Scan elements of ARGV (whose length is ARGC) for option characters  /* Scan elements of ARGV (whose length is ARGC) for option characters
# Line 511  _getopt_initialize (argc, argv, optstrin Line 511  _getopt_initialize (argc, argv, optstrin
511    
512  int  int
513  _getopt_internal (argc, argv, optstring, longopts, longind, long_only)  _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
514       int argc;                   int argc;
515       char *const *argv;                   char *const *argv;
516       const char *optstring;                   const char *optstring;
517       const struct option *longopts;                   const struct option *longopts;
518       int *longind;                   int *longind;
519       int long_only;                   int long_only;
520  {  {
521    int print_errors = opterr;          int print_errors = opterr;
522    if (optstring[0] == ':')          if (optstring[0] == ':')
523      print_errors = 0;                  print_errors = 0;
524    
525    optarg = NULL;          optarg = NULL;
526    
527    if (optind == 0 || !__getopt_initialized)          if (optind == 0 || !__getopt_initialized)
528      {                  {
529        if (optind == 0)                          if (optind == 0)
530          optind = 1;             /* Don't scan ARGV[0], the program name.  */                                  optind = 1;                                                     /* Don't scan ARGV[0], the program name.  */
531        optstring = _getopt_initialize (argc, argv, optstring);                          optstring = _getopt_initialize (argc, argv, optstring);
532        __getopt_initialized = 1;                          __getopt_initialized = 1;
533      }                  }
534    
535    /* Test whether ARGV[optind] points to a non-option argument.          /* Test whether ARGV[optind] points to a non-option argument.
536       Either it does not have option syntax, or there is an environment flag             Either it does not have option syntax, or there is an environment flag
537       from the shell indicating it is not an option.  The later information             from the shell indicating it is not an option.  The later information
538       is only used when the used in the GNU libc.  */             is only used when the used in the GNU libc.  */
539  #ifdef _LIBC  #ifdef _LIBC
540  # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'       \  # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'       \
541                        || (optind < nonoption_flags_len                        \                        || (optind < nonoption_flags_len                        \
# Line 544  _getopt_internal (argc, argv, optstring, Line 544  _getopt_internal (argc, argv, optstring,
544  # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')  # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
545  #endif  #endif
546    
547    if (nextchar == NULL || *nextchar == '\0')          if (nextchar == NULL || *nextchar == '\0')
548      {                  {
549        /* Advance to the next ARGV-element.  */                          /* Advance to the next ARGV-element.  */
   
       /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been  
          moved back by the user (who may also have changed the arguments).  */  
       if (last_nonopt > optind)  
         last_nonopt = optind;  
       if (first_nonopt > optind)  
         first_nonopt = optind;  
   
       if (ordering == PERMUTE)  
         {  
           /* If we have just processed some options following some non-options,  
              exchange them so that the options come first.  */  
   
           if (first_nonopt != last_nonopt && last_nonopt != optind)  
             exchange ((char **) argv);  
           else if (last_nonopt != optind)  
             first_nonopt = optind;  
   
           /* Skip any additional non-options  
              and extend the range of non-options previously skipped.  */  
   
           while (optind < argc && NONOPTION_P)  
             optind++;  
           last_nonopt = optind;  
         }  
   
       /* The special ARGV-element `--' means premature end of options.  
          Skip it like a null option,  
          then exchange with previous non-options as if it were an option,  
          then skip everything else like a non-option.  */  
   
       if (optind != argc && !strcmp (argv[optind], "--"))  
         {  
           optind++;  
   
           if (first_nonopt != last_nonopt && last_nonopt != optind)  
             exchange ((char **) argv);  
           else if (first_nonopt == last_nonopt)  
             first_nonopt = optind;  
           last_nonopt = argc;  
   
           optind = argc;  
         }  
   
       /* If we have done all the ARGV-elements, stop the scan  
          and back over any non-options that we skipped and permuted.  */  
   
       if (optind == argc)  
         {  
           /* Set the next-arg-index to point at the non-options  
              that we previously skipped, so the caller will digest them.  */  
           if (first_nonopt != last_nonopt)  
             optind = first_nonopt;  
           return -1;  
         }  
   
       /* If we have come to a non-option and did not permute it,  
          either stop the scan or describe it to the caller and pass it by.  */  
   
       if (NONOPTION_P)  
         {  
           if (ordering == REQUIRE_ORDER)  
             return -1;  
           optarg = argv[optind++];  
           return 1;  
         }  
550    
551        /* We have found another option-ARGV-element.                          /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
552           Skip the initial punctuation.  */                             moved back by the user (who may also have changed the arguments).  */
553                            if (last_nonopt > optind)
554                                    last_nonopt = optind;
555                            if (first_nonopt > optind)
556                                    first_nonopt = optind;
557    
558                            if (ordering == PERMUTE)
559                                    {
560                                            /* If we have just processed some options following some non-options,
561                                               exchange them so that the options come first.  */
562    
563                                            if (first_nonopt != last_nonopt && last_nonopt != optind)
564                                                    exchange ((char **) argv);
565                                            else if (last_nonopt != optind)
566                                                    first_nonopt = optind;
567    
568                                            /* Skip any additional non-options
569                                               and extend the range of non-options previously skipped.  */
570    
571                                            while (optind < argc && NONOPTION_P)
572                                                    optind++;
573                                            last_nonopt = optind;
574                                    }
575    
576                            /* The special ARGV-element `--' means premature end of options.
577                               Skip it like a null option,
578                               then exchange with previous non-options as if it were an option,
579                               then skip everything else like a non-option.  */
580    
581                            if (optind != argc && !strcmp (argv[optind], "--"))
582                                    {
583                                            optind++;
584    
585                                            if (first_nonopt != last_nonopt && last_nonopt != optind)
586                                                    exchange ((char **) argv);
587                                            else if (first_nonopt == last_nonopt)
588                                                    first_nonopt = optind;
589                                            last_nonopt = argc;
590    
591                                            optind = argc;
592                                    }
593    
594                            /* If we have done all the ARGV-elements, stop the scan
595                               and back over any non-options that we skipped and permuted.  */
596    
597                            if (optind == argc)
598                                    {
599                                            /* Set the next-arg-index to point at the non-options
600                                               that we previously skipped, so the caller will digest them.  */
601                                            if (first_nonopt != last_nonopt)
602                                                    optind = first_nonopt;
603                                            return -1;
604                                    }
605    
606                            /* If we have come to a non-option and did not permute it,
607                               either stop the scan or describe it to the caller and pass it by.  */
608    
609                            if (NONOPTION_P)
610                                    {
611                                            if (ordering == REQUIRE_ORDER)
612                                                    return -1;
613                                            optarg = argv[optind++];
614                                            return 1;
615                                    }
616    
617        nextchar = (argv[optind] + 1                          /* We have found another option-ARGV-element.
618                    + (longopts != NULL && argv[optind][1] == '-'));                             Skip the initial punctuation.  */
     }  
619    
620    /* Decode the current option-ARGV-element.  */                          nextchar = (argv[optind] + 1
621                                                                            + (longopts != NULL && argv[optind][1] == '-'));
622                    }
623    
624    /* Check whether the ARGV-element is a long option.          /* Decode the current option-ARGV-element.  */
625    
626       If long_only and the ARGV-element has the form "-f", where f is          /* Check whether the ARGV-element is a long option.
      a valid short option, don't consider it an abbreviated form of  
      a long option that starts with f.  Otherwise there would be no  
      way to give the -f short option.  
   
      On the other hand, if there's a long option "fubar" and  
      the ARGV-element is "-fu", do consider that an abbreviation of  
      the long option, just like "--fu", and not "-f" with arg "u".  
   
      This distinction seems to be the most useful approach.  */  
   
   if (longopts != NULL  
       && (argv[optind][1] == '-'  
           || (long_only  
               && (argv[optind][2]  
                   || !my_index (optstring, argv[optind][1])))))  
     {  
       char *nameend;  
       const struct option *p;  
       const struct option *pfound = NULL;  
       int exact = 0;  
       int ambig = 0;  
       int indfound = -1;  
       int option_index;  
   
       for (nameend = nextchar; *nameend && *nameend != '='; nameend++)  
         /* Do nothing.  */ ;  
   
       /* Test all long options for either exact match  
          or abbreviated matches.  */  
       for (p = longopts, option_index = 0; p->name; p++, option_index++)  
         if (!strncmp (p->name, nextchar, nameend - nextchar))  
           {  
             if ((unsigned int) (nameend - nextchar)  
                 == (unsigned int) strlen (p->name))  
               {  
                 /* Exact match found.  */  
                 pfound = p;  
                 indfound = option_index;  
                 exact = 1;  
                 break;  
               }  
             else if (pfound == NULL)  
               {  
                 /* First nonexact match found.  */  
                 pfound = p;  
                 indfound = option_index;  
               }  
             else  
               /* Second or later nonexact match found.  */  
               ambig = 1;  
           }  
627    
628        if (ambig && !exact)             If long_only and the ARGV-element has the form "-f", where f is
629          {             a valid short option, don't consider it an abbreviated form of
630            if (print_errors)             a long option that starts with f.  Otherwise there would be no
631              fprintf (stderr, _("%s: option `%s' is ambiguous\n"),             way to give the -f short option.
632                       argv[0], argv[optind]);  
633            nextchar += strlen (nextchar);             On the other hand, if there's a long option "fubar" and
634            optind++;             the ARGV-element is "-fu", do consider that an abbreviation of
635            optopt = 0;             the long option, just like "--fu", and not "-f" with arg "u".
636            return '?';  
637          }             This distinction seems to be the most useful approach.  */
638    
639            if (longopts != NULL
640                            && (argv[optind][1] == '-'
641                                            || (long_only
642                                                            && (argv[optind][2]
643                                                                            || !my_index (optstring, argv[optind][1])))))
644                    {
645                            char *nameend;
646                            const struct option *p;
647                            const struct option *pfound = NULL;
648                            int exact = 0;
649                            int ambig = 0;
650                            int indfound = -1;
651                            int option_index;
652    
653                            for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
654                                    /* Do nothing.  */ ;
655    
656                            /* Test all long options for either exact match
657                               or abbreviated matches.  */
658                            for (p = longopts, option_index = 0; p->name; p++, option_index++)
659                                    if (!strncmp (p->name, nextchar, nameend - nextchar))
660                                            {
661                                                    if ((unsigned int) (nameend - nextchar)
662                                                                    == (unsigned int) strlen (p->name))
663                                                            {
664                                                                    /* Exact match found.  */
665                                                                    pfound = p;
666                                                                    indfound = option_index;
667                                                                    exact = 1;
668                                                                    break;
669                                                            }
670                                                    else if (pfound == NULL)
671                                                            {
672                                                                    /* First nonexact match found.  */
673                                                                    pfound = p;
674                                                                    indfound = option_index;
675                                                            }
676                                                    else
677                                                            /* Second or later nonexact match found.  */
678                                                            ambig = 1;
679                                            }
680    
681                            if (ambig && !exact)
682                                    {
683                                            if (print_errors)
684                                                    fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
685                                                                                     argv[0], argv[optind]);
686                                            nextchar += strlen (nextchar);
687                                            optind++;
688                                            optopt = 0;
689                                            return '?';
690                                    }
691    
692                            if (pfound != NULL)
693                                    {
694                                            option_index = indfound;
695                                            optind++;
696                                            if (*nameend)
697                                                    {
698                                                            /* Don't test has_arg with >, because some C compilers don't
699                                                               allow it to be used on enums.  */
700                                                            if (pfound->has_arg)
701                                                                    optarg = nameend + 1;
702                                                            else
703                                                                    {
704                                                                            if (print_errors)
705                                                                                    {
706                                                                                            if (argv[optind - 1][1] == '-')
707                                                                                                    /* --option */
708                                                                                                    fprintf (stderr,
709                                                                                                                                     _
710                                                                                                                                     ("%s: option `--%s' doesn't allow an argument\n"),
711                                                                                                                                     argv[0], pfound->name);
712                                                                                            else
713                                                                                                    /* +option or -option */
714                                                                                                    fprintf (stderr,
715                                                                                                                                     _
716                                                                                                                                     ("%s: option `%c%s' doesn't allow an argument\n"),
717                                                                                                                                     argv[0], argv[optind - 1][0], pfound->name);
718                                                                                    }
719    
720                                                                            nextchar += strlen (nextchar);
721    
722                                                                            optopt = pfound->val;
723                                                                            return '?';
724                                                                    }
725                                                    }
726                                            else if (pfound->has_arg == 1)
727                                                    {
728                                                            if (optind < argc)
729                                                                    optarg = argv[optind++];
730                                                            else
731                                                                    {
732                                                                            if (print_errors)
733                                                                                    fprintf (stderr,
734                                                                                                                     _("%s: option `%s' requires an argument\n"),
735                                                                                                                     argv[0], argv[optind - 1]);
736                                                                            nextchar += strlen (nextchar);
737                                                                            optopt = pfound->val;
738                                                                            return optstring[0] == ':' ? ':' : '?';
739                                                                    }
740                                                    }
741                                            nextchar += strlen (nextchar);
742                                            if (longind != NULL)
743                                                    *longind = option_index;
744                                            if (pfound->flag)
745                                                    {
746                                                            *(pfound->flag) = pfound->val;
747                                                            return 0;
748                                                    }
749                                            return pfound->val;
750                                    }
751    
752                            /* Can't find it as a long option.  If this is not getopt_long_only,
753                               or the option starts with '--' or is not a valid short
754                               option, then it's an error.
755                               Otherwise interpret it as a short option.  */
756                            if (!long_only || argv[optind][1] == '-'
757                                            || my_index (optstring, *nextchar) == NULL)
758                                    {
759                                            if (print_errors)
760                                                    {
761                                                            if (argv[optind][1] == '-')
762                                                                    /* --option */
763                                                                    fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
764                                                                                                     argv[0], nextchar);
765                                                            else
766                                                                    /* +option or -option */
767                                                                    fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
768                                                                                                     argv[0], argv[optind][0], nextchar);
769                                                    }
770                                            nextchar = (char *) "";
771                                            optind++;
772                                            optopt = 0;
773                                            return '?';
774                                    }
775                    }
776    
777        if (pfound != NULL)          /* Look at and handle the next short option-character.  */
         {  
           option_index = indfound;  
           optind++;  
           if (*nameend)  
             {  
               /* Don't test has_arg with >, because some C compilers don't  
                  allow it to be used on enums.  */  
               if (pfound->has_arg)  
                 optarg = nameend + 1;  
               else  
                 {  
                   if (print_errors)  
                     {  
                       if (argv[optind - 1][1] == '-')  
                         /* --option */  
                         fprintf (stderr,  
                                  _  
                                  ("%s: option `--%s' doesn't allow an argument\n"),  
                                  argv[0], pfound->name);  
                       else  
                         /* +option or -option */  
                         fprintf (stderr,  
                                  _  
                                  ("%s: option `%c%s' doesn't allow an argument\n"),  
                                  argv[0], argv[optind - 1][0], pfound->name);  
                     }  
   
                   nextchar += strlen (nextchar);  
   
                   optopt = pfound->val;  
                   return '?';  
                 }  
             }  
           else if (pfound->has_arg == 1)  
             {  
               if (optind < argc)  
                 optarg = argv[optind++];  
               else  
                 {  
                   if (print_errors)  
                     fprintf (stderr,  
                              _("%s: option `%s' requires an argument\n"),  
                              argv[0], argv[optind - 1]);  
                   nextchar += strlen (nextchar);  
                   optopt = pfound->val;  
                   return optstring[0] == ':' ? ':' : '?';  
                 }  
             }  
           nextchar += strlen (nextchar);  
           if (longind != NULL)  
             *longind = option_index;  
           if (pfound->flag)  
             {  
               *(pfound->flag) = pfound->val;  
               return 0;  
             }  
           return pfound->val;  
         }  
778    
       /* Can't find it as a long option.  If this is not getopt_long_only,  
          or the option starts with '--' or is not a valid short  
          option, then it's an error.  
          Otherwise interpret it as a short option.  */  
       if (!long_only || argv[optind][1] == '-'  
           || my_index (optstring, *nextchar) == NULL)  
779          {          {
780            if (print_errors)                  char c = *nextchar++;
781              {                  char *temp = my_index (optstring, c);
               if (argv[optind][1] == '-')  
                 /* --option */  
                 fprintf (stderr, _("%s: unrecognized option `--%s'\n"),  
                          argv[0], nextchar);  
               else  
                 /* +option or -option */  
                 fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),  
                          argv[0], argv[optind][0], nextchar);  
             }  
           nextchar = (char *) "";  
           optind++;  
           optopt = 0;  
           return '?';  
         }  
     }  
782    
783    /* Look at and handle the next short option-character.  */                  /* Increment `optind' when we start to process its last character.  */
784                    if (*nextchar == '\0')
785    {                          ++optind;
786      char c = *nextchar++;  
787      char *temp = my_index (optstring, c);                  if (temp == NULL || c == ':')
788                            {
789      /* Increment `optind' when we start to process its last character.  */                                  if (print_errors)
790      if (*nextchar == '\0')                                          {
791        ++optind;                                                  if (posixly_correct)
792                                                            /* 1003.2 specifies the format of this message.  */
793      if (temp == NULL || c == ':')                                                          fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c);
794        {                                                  else
795          if (print_errors)                                                          fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c);
796            {                                          }
797              if (posixly_correct)                                  optopt = c;
798                /* 1003.2 specifies the format of this message.  */                                  return '?';
799                fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c);                          }
800              else                  /* Convenience. Treat POSIX -W foo same as long option --foo */
801                fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c);                  if (temp[0] == 'W' && temp[1] == ';')
802            }                          {
803          optopt = c;                                  char *nameend;
804          return '?';                                  const struct option *p;
805        }                                  const struct option *pfound = NULL;
806      /* Convenience. Treat POSIX -W foo same as long option --foo */                                  int exact = 0;
807      if (temp[0] == 'W' && temp[1] == ';')                                  int ambig = 0;
808        {                                  int indfound = 0;
809          char *nameend;                                  int option_index;
810          const struct option *p;  
811          const struct option *pfound = NULL;                                  /* This is an option that requires an argument.  */
812          int exact = 0;                                  if (*nextchar != '\0')
813          int ambig = 0;                                          {
814          int indfound = 0;                                                  optarg = nextchar;
815          int option_index;                                                  /* If we end this ARGV-element by taking the rest as an arg,
816                                                       we must advance to the next element now.  */
817          /* This is an option that requires an argument.  */                                                  optind++;
818          if (*nextchar != '\0')                                          }
819            {                                  else if (optind == argc)
820              optarg = nextchar;                                          {
821              /* If we end this ARGV-element by taking the rest as an arg,                                                  if (print_errors)
822                 we must advance to the next element now.  */                                                          {
823              optind++;                                                                  /* 1003.2 specifies the format of this message.  */
824            }                                                                  fprintf (stderr, _("%s: option requires an argument -- %c\n"),
825          else if (optind == argc)                                                                                                   argv[0], c);
826            {                                                          }
827              if (print_errors)                                                  optopt = c;
828                {                                                  if (optstring[0] == ':')
829                  /* 1003.2 specifies the format of this message.  */                                                          c = ':';
830                  fprintf (stderr, _("%s: option requires an argument -- %c\n"),                                                  else
831                           argv[0], c);                                                          c = '?';
832                }                                                  return c;
833              optopt = c;                                          }
834              if (optstring[0] == ':')                                  else
835                c = ':';                                          /* We already incremented `optind' once;
836              else                                             increment it again when taking next ARGV-elt as argument.  */
837                c = '?';                                          optarg = argv[optind++];
838              return c;  
839            }                                  /* optarg is now the argument, see if it's in the
840          else                                     table of longopts.  */
841            /* We already incremented `optind' once;  
842               increment it again when taking next ARGV-elt as argument.  */                                  for (nextchar = nameend = optarg; *nameend && *nameend != '=';
843            optarg = argv[optind++];                                                   nameend++)
844                                            /* Do nothing.  */ ;
845          /* optarg is now the argument, see if it's in the  
846             table of longopts.  */                                  /* Test all long options for either exact match
847                                       or abbreviated matches.  */
848          for (nextchar = nameend = optarg; *nameend && *nameend != '=';                                  for (p = longopts, option_index = 0; p->name; p++, option_index++)
849               nameend++)                                          if (!strncmp (p->name, nextchar, nameend - nextchar))
850            /* Do nothing.  */ ;                                                  {
851                                                            if ((unsigned int) (nameend - nextchar) == strlen (p->name))
852          /* Test all long options for either exact match                                                                  {
853             or abbreviated matches.  */                                                                          /* Exact match found.  */
854          for (p = longopts, option_index = 0; p->name; p++, option_index++)                                                                          pfound = p;
855            if (!strncmp (p->name, nextchar, nameend - nextchar))                                                                          indfound = option_index;
856              {                                                                          exact = 1;
857                if ((unsigned int) (nameend - nextchar) == strlen (p->name))                                                                          break;
858                  {                                                                  }
859                    /* Exact match found.  */                                                          else if (pfound == NULL)
860                    pfound = p;                                                                  {
861                    indfound = option_index;                                                                          /* First nonexact match found.  */
862                    exact = 1;                                                                          pfound = p;
863                    break;                                                                          indfound = option_index;
864                  }                                                                  }
865                else if (pfound == NULL)                                                          else
866                  {                                                                  /* Second or later nonexact match found.  */
867                    /* First nonexact match found.  */                                                                  ambig = 1;
868                    pfound = p;                                                  }
869                    indfound = option_index;                                  if (ambig && !exact)
870                  }                                          {
871                else                                                  if (print_errors)
872                  /* Second or later nonexact match found.  */                                                          fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
873                  ambig = 1;                                                                                           argv[0], argv[optind]);
874              }                                                  nextchar += strlen (nextchar);
875          if (ambig && !exact)                                                  optind++;
876            {                                                  return '?';
877              if (print_errors)                                          }
878                fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),                                  if (pfound != NULL)
879                         argv[0], argv[optind]);                                          {
880              nextchar += strlen (nextchar);                                                  option_index = indfound;
881              optind++;                                                  if (*nameend)
882              return '?';                                                          {
883            }                                                                  /* Don't test has_arg with >, because some C compilers don't
884          if (pfound != NULL)                                                                     allow it to be used on enums.  */
885            {                                                                  if (pfound->has_arg)
886              option_index = indfound;                                                                          optarg = nameend + 1;
887              if (*nameend)                                                                  else
888                {                                                                          {
889                  /* Don't test has_arg with >, because some C compilers don't                                                                                  if (print_errors)
890                     allow it to be used on enums.  */                                                                                          fprintf (stderr, _("\
                 if (pfound->has_arg)  
                   optarg = nameend + 1;  
                 else  
                   {  
                     if (print_errors)  
                       fprintf (stderr, _("\  
891  %s: option `-W %s' doesn't allow an argument\n"), argv[0], pfound->name);  %s: option `-W %s' doesn't allow an argument\n"), argv[0], pfound->name);
892    
893                      nextchar += strlen (nextchar);                                                                                  nextchar += strlen (nextchar);
894                      return '?';                                                                                  return '?';
895                    }                                                                          }
896                }                                                          }
897              else if (pfound->has_arg == 1)                                                  else if (pfound->has_arg == 1)
898                {                                                          {
899                  if (optind < argc)                                                                  if (optind < argc)
900                    optarg = argv[optind++];                                                                          optarg = argv[optind++];
901                  else                                                                  else
902                    {                                                                          {
903                      if (print_errors)                                                                                  if (print_errors)
904                        fprintf (stderr,                                                                                          fprintf (stderr,
905                                 _("%s: option `%s' requires an argument\n"),                                                                                                                           _("%s: option `%s' requires an argument\n"),
906                                 argv[0], argv[optind - 1]);                                                                                                                           argv[0], argv[optind - 1]);
907                      nextchar += strlen (nextchar);                                                                                  nextchar += strlen (nextchar);
908                      return optstring[0] == ':' ? ':' : '?';                                                                                  return optstring[0] == ':' ? ':' : '?';
909                    }                                                                          }
910                }                                                          }
911              nextchar += strlen (nextchar);                                                  nextchar += strlen (nextchar);
912              if (longind != NULL)                                                  if (longind != NULL)
913                *longind = option_index;                                                          *longind = option_index;
914              if (pfound->flag)                                                  if (pfound->flag)
915                {                                                          {
916                  *(pfound->flag) = pfound->val;                                                                  *(pfound->flag) = pfound->val;
917                  return 0;                                                                  return 0;
918                }                                                          }
919              return pfound->val;                                                  return pfound->val;
920            }                                          }
921          nextchar = NULL;                                  nextchar = NULL;
922          return 'W';             /* Let the application handle it.   */                                  return 'W';                                                     /* Let the application handle it.   */
923        }                          }
924      if (temp[1] == ':')                  if (temp[1] == ':')
925        {                          {
926          if (temp[2] == ':')                                  if (temp[2] == ':')
927            {                                          {
928              /* This is an option that accepts an argument optionally.  */                                                  /* This is an option that accepts an argument optionally.  */
929              if (*nextchar != '\0')                                                  if (*nextchar != '\0')
930                {                                                          {
931                  optarg = nextchar;                                                                  optarg = nextchar;
932                  optind++;                                                                  optind++;
933                }                                                          }
934              else                                                  else
935                optarg = NULL;                                                          optarg = NULL;
936              nextchar = NULL;                                                  nextchar = NULL;
937            }                                          }
938          else                                  else
939            {                                          {
940              /* This is an option that requires an argument.  */                                                  /* This is an option that requires an argument.  */
941              if (*nextchar != '\0')                                                  if (*nextchar != '\0')
942                {                                                          {
943                  optarg = nextchar;                                                                  optarg = nextchar;
944                  /* If we end this ARGV-element by taking the rest as an arg,                                                                  /* If we end this ARGV-element by taking the rest as an arg,
945                     we must advance to the next element now.  */                                                                     we must advance to the next element now.  */
946                  optind++;                                                                  optind++;
947                }                                                          }
948              else if (optind == argc)                                                  else if (optind == argc)
949                {                                                          {
950                  if (print_errors)                                                                  if (print_errors)
951                    {                                                                          {
952                      /* 1003.2 specifies the format of this message.  */                                                                                  /* 1003.2 specifies the format of this message.  */
953                      fprintf (stderr,                                                                                  fprintf (stderr,
954                               _("%s: option requires an argument -- %c\n"),                                                                                                                   _("%s: option requires an argument -- %c\n"),
955                               argv[0], c);                                                                                                                   argv[0], c);
956                    }                                                                          }
957                  optopt = c;                                                                  optopt = c;
958                  if (optstring[0] == ':')                                                                  if (optstring[0] == ':')
959                    c = ':';                                                                          c = ':';
960                  else                                                                  else
961                    c = '?';                                                                          c = '?';
962                }                                                          }
963              else                                                  else
964                /* We already incremented `optind' once;                                                          /* We already incremented `optind' once;
965                   increment it again when taking next ARGV-elt as argument.  */                                                             increment it again when taking next ARGV-elt as argument.  */
966                optarg = argv[optind++];                                                          optarg = argv[optind++];
967              nextchar = NULL;                                                  nextchar = NULL;
968            }                                          }
969        }                          }
970      return c;                  return c;
971    }          }
972  }  }
973    
974  int  int
975  getopt (argc, argv, optstring)  getopt (argc, argv, optstring)
976       int argc;                   int argc;
977       char *const *argv;                   char *const *argv;
978       const char *optstring;                   const char *optstring;
979  {  {
980    return _getopt_internal (argc, argv, optstring,          return _getopt_internal (argc, argv, optstring,
981                             (const struct option *) 0, (int *) 0, 0);                                                                                                           (const struct option *) 0, (int *) 0, 0);
982  }  }
983    
984  #endif /* Not ELIDE_CODE.  */  #endif /* Not ELIDE_CODE.  */
# Line 990  getopt (argc, argv, optstring) Line 990  getopt (argc, argv, optstring)
990    
991  int  int
992  main (argc, argv)  main (argc, argv)
993       int argc;                   int argc;
994       char **argv;                   char **argv;
995  {  {
996    int c;          int c;
997    int digit_optind = 0;          int digit_optind = 0;
998    
999    while (1)          while (1)
1000      {                  {
1001        int this_option_optind = optind ? optind : 1;                          int this_option_optind = optind ? optind : 1;
   
       c = getopt (argc, argv, "abc:d:0123456789");  
       if (c == -1)  
         break;  
   
       switch (c)  
         {  
         case '0':  
         case '1':  
         case '2':  
         case '3':  
         case '4':  
         case '5':  
         case '6':  
         case '7':  
         case '8':  
         case '9':  
           if (digit_optind != 0 && digit_optind != this_option_optind)  
             printf ("digits occur in two different argv-elements.\n");  
           digit_optind = this_option_optind;  
           printf ("option %c\n", c);  
           break;  
   
         case 'a':  
           printf ("option a\n");  
           break;  
   
         case 'b':  
           printf ("option b\n");  
           break;  
   
         case 'c':  
           printf ("option c with value `%s'\n", optarg);  
           break;  
   
         case '?':  
           break;  
1002    
1003          default:                          c = getopt (argc, argv, "abc:d:0123456789");
1004            printf ("?? getopt returned character code 0%o ??\n", c);                          if (c == -1)
1005          }                                  break;
1006      }  
1007                            switch (c)
1008                                    {
1009                                    case '0':
1010                                    case '1':
1011                                    case '2':
1012                                    case '3':
1013                                    case '4':
1014                                    case '5':
1015                                    case '6':
1016                                    case '7':
1017                                    case '8':
1018                                    case '9':
1019                                            if (digit_optind != 0 && digit_optind != this_option_optind)
1020                                                    printf ("digits occur in two different argv-elements.\n");
1021                                            digit_optind = this_option_optind;
1022                                            printf ("option %c\n", c);
1023                                            break;
1024    
1025                                    case 'a':
1026                                            printf ("option a\n");
1027                                            break;
1028    
1029                                    case 'b':
1030                                            printf ("option b\n");
1031                                            break;
1032    
1033                                    case 'c':
1034                                            printf ("option c with value `%s'\n", optarg);
1035                                            break;
1036    
1037                                    case '?':
1038                                            break;
1039    
1040                                    default:
1041                                            printf ("?? getopt returned character code 0%o ??\n", c);
1042                                    }
1043                    }
1044    
1045    if (optind < argc)          if (optind < argc)
1046      {                  {
1047        printf ("non-option ARGV-elements: ");                          printf ("non-option ARGV-elements: ");
1048        while (optind < argc)                          while (optind < argc)
1049          printf ("%s ", argv[optind++]);                                  printf ("%s ", argv[optind++]);
1050        printf ("\n");                          printf ("\n");
1051      }                  }
1052    
1053    exit (0);          exit (0);
1054  }  }
1055    
1056  #endif /* TEST */  #endif /* TEST */
1057    
1058  /**This must remain at the end of the file.**********  /**This must remain at the end of the file.**********
1059   * vim600:set sw=2 ts=8:                            *   * vim600:set sw=2 ts=2:                            *
1060   * vim600:set cindent cinoptions={1s,>2s,^-1s,n-1s: *   * vim600:set cindent cinoptions={1s,>2s,^-1s,n-1s: *
1061   * vim600:set foldmethod=marker:                    *   * vim600:set foldmethod=marker:                    *
1062   ****************************************************/   ****************************************************/

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26