00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 #ifndef _NO_PROTO
00027 # define _NO_PROTO
00028 #endif
00029 
00030 #ifdef HAVE_CONFIG_H
00031 # include <config.h>
00032 #endif
00033 
00034 #if !defined __STDC__ || !__STDC__
00035 
00036 
00037 # ifndef const
00038 #  define const
00039 # endif
00040 #endif
00041 
00042 #include <stdio.h>
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 #define GETOPT_INTERFACE_VERSION 2
00053 #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
00054 # include <gnu-versions.h>
00055 # if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
00056 #  define ELIDE_CODE
00057 # endif
00058 #endif
00059 
00060 #ifndef ELIDE_CODE
00061 
00062 
00063 
00064 
00065 #ifdef  __GNU_LIBRARY__
00066 
00067 
00068 # include <stdlib.h>
00069 # include <unistd.h>
00070 #endif  
00071 
00072 #ifdef VMS
00073 # include <unixlib.h>
00074 # if HAVE_STRING_H - 0
00075 #  include <string.h>
00076 # endif
00077 #endif
00078 
00079 #ifndef _
00080 
00081 # if defined HAVE_LIBINTL_H || defined _LIBC
00082 #  include <libintl.h>
00083 #  ifndef _
00084 #   define _(msgid)     gettext (msgid)
00085 #  endif
00086 # else
00087 #  define _(msgid)      (msgid)
00088 # endif
00089 #endif
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104 
00105 #include "getopt.h"
00106 
00107 
00108 
00109 
00110 
00111 
00112 
00113 char *optarg;
00114 
00115 
00116 
00117 
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125 
00126 
00127 
00128 int optind = 1;
00129 
00130 
00131 
00132 
00133 
00134 int __getopt_initialized;
00135 
00136 
00137 
00138 
00139 
00140 
00141 
00142 
00143 static char *nextchar;
00144 
00145 
00146 
00147 
00148 int opterr = 1;
00149 
00150 
00151 
00152 
00153 
00154 int optopt = '?';
00155 
00156 
00157 
00158 
00159 
00160 
00161 
00162 
00163 
00164 
00165 
00166 
00167 
00168 
00169 
00170 
00171 
00172 
00173 
00174 
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 
00184 
00185 static enum
00186 {
00187   REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
00188 } ordering;
00189 
00190 
00191 static char *posixly_correct;
00192 
00193 #ifdef  __GNU_LIBRARY__
00194 
00195 
00196 
00197 
00198 # include <string.h>
00199 # define my_index       strchr
00200 #else
00201 
00202 # if HAVE_STRING_H
00203 #  include <string.h>
00204 # else
00205 #  include <strings.h>
00206 # endif
00207 
00208 
00209 
00210 
00211 #ifndef getenv
00212 extern char *getenv ();
00213 #endif
00214 
00215 static char *
00216 my_index (str, chr)
00217      const char *str;
00218      int chr;
00219 {
00220   while (*str)
00221     {
00222       if (*str == chr)
00223         return (char *) str;
00224       str++;
00225     }
00226   return 0;
00227 }
00228 
00229 
00230 
00231 #ifdef __GNUC__
00232 
00233 
00234 # if (!defined __STDC__ || !__STDC__) && !defined strlen
00235 
00236 
00237 extern int strlen (const char *);
00238 # endif 
00239 #endif 
00240 
00241 #endif 
00242 
00243 
00244 
00245 
00246 
00247 
00248 
00249 static int first_nonopt;
00250 static int last_nonopt;
00251 
00252 #ifdef _LIBC
00253 
00254 
00255 
00256 extern int __libc_argc;
00257 extern char **__libc_argv;
00258 
00259 
00260 
00261 
00262 # ifdef USE_NONOPTION_FLAGS
00263 
00264 extern char *__getopt_nonoption_flags;
00265 
00266 static int nonoption_flags_max_len;
00267 static int nonoption_flags_len;
00268 # endif
00269 
00270 # ifdef USE_NONOPTION_FLAGS
00271 #  define SWAP_FLAGS(ch1, ch2) \
00272   if (nonoption_flags_len > 0)                                                \
00273     {                                                                         \
00274       char __tmp = __getopt_nonoption_flags[ch1];                             \
00275       __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];          \
00276       __getopt_nonoption_flags[ch2] = __tmp;                                  \
00277     }
00278 # else
00279 #  define SWAP_FLAGS(ch1, ch2)
00280 # endif
00281 #else   
00282 # define SWAP_FLAGS(ch1, ch2)
00283 #endif  
00284 
00285 
00286 
00287 
00288 
00289 
00290 
00291 
00292 
00293 
00294 #if defined __STDC__ && __STDC__
00295 static void exchange (char **);
00296 #endif
00297 
00298 static void
00299 exchange (argv)
00300      char **argv;
00301 {
00302   int bottom = first_nonopt;
00303   int middle = last_nonopt;
00304   int top = optind;
00305   char *tem;
00306 
00307   
00308 
00309 
00310 
00311 
00312 #if defined _LIBC && defined USE_NONOPTION_FLAGS
00313   
00314 
00315 
00316   if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
00317     {
00318       
00319 
00320       char *new_str = malloc (top + 1);
00321       if (new_str == NULL)
00322         nonoption_flags_len = nonoption_flags_max_len = 0;
00323       else
00324         {
00325           memset (__mempcpy (new_str, __getopt_nonoption_flags,
00326                              nonoption_flags_max_len),
00327                   '\0', top + 1 - nonoption_flags_max_len);
00328           nonoption_flags_max_len = top + 1;
00329           __getopt_nonoption_flags = new_str;
00330         }
00331     }
00332 #endif
00333 
00334   while (top > middle && middle > bottom)
00335     {
00336       if (top - middle > middle - bottom)
00337         {
00338           
00339           int len = middle - bottom;
00340           register int i;
00341 
00342           
00343           for (i = 0; i < len; i++)
00344             {
00345               tem = argv[bottom + i];
00346               argv[bottom + i] = argv[top - (middle - bottom) + i];
00347               argv[top - (middle - bottom) + i] = tem;
00348               SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
00349             }
00350           
00351           top -= len;
00352         }
00353       else
00354         {
00355           
00356           int len = top - middle;
00357           register int i;
00358 
00359           
00360           for (i = 0; i < len; i++)
00361             {
00362               tem = argv[bottom + i];
00363               argv[bottom + i] = argv[middle + i];
00364               argv[middle + i] = tem;
00365               SWAP_FLAGS (bottom + i, middle + i);
00366             }
00367           
00368           bottom += len;
00369         }
00370     }
00371 
00372   
00373 
00374   first_nonopt += (optind - last_nonopt);
00375   last_nonopt = optind;
00376 }
00377 
00378 
00379 
00380 #if defined __STDC__ && __STDC__
00381 static const char *_getopt_initialize (int, char *const *, const char *);
00382 #endif
00383 static const char *
00384 _getopt_initialize (argc, argv, optstring)
00385      int argc;
00386      char *const *argv;
00387      const char *optstring;
00388 {
00389   
00390 
00391 
00392 
00393   first_nonopt = last_nonopt = optind;
00394 
00395   nextchar = NULL;
00396 
00397   posixly_correct = getenv ("POSIXLY_CORRECT");
00398 
00399   
00400 
00401   if (optstring[0] == '-')
00402     {
00403       ordering = RETURN_IN_ORDER;
00404       ++optstring;
00405     }
00406   else if (optstring[0] == '+')
00407     {
00408       ordering = REQUIRE_ORDER;
00409       ++optstring;
00410     }
00411   else if (posixly_correct != NULL)
00412     ordering = REQUIRE_ORDER;
00413   else
00414     ordering = PERMUTE;
00415 
00416 #if defined _LIBC && defined USE_NONOPTION_FLAGS
00417   if (posixly_correct == NULL
00418       && argc == __libc_argc && argv == __libc_argv)
00419     {
00420       if (nonoption_flags_max_len == 0)
00421         {
00422           if (__getopt_nonoption_flags == NULL
00423               || __getopt_nonoption_flags[0] == '\0')
00424             nonoption_flags_max_len = -1;
00425           else
00426             {
00427               const char *orig_str = __getopt_nonoption_flags;
00428               int len = nonoption_flags_max_len = strlen (orig_str);
00429               if (nonoption_flags_max_len < argc)
00430                 nonoption_flags_max_len = argc;
00431               __getopt_nonoption_flags =
00432                 (char *) malloc (nonoption_flags_max_len);
00433               if (__getopt_nonoption_flags == NULL)
00434                 nonoption_flags_max_len = -1;
00435               else
00436                 memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
00437                         '\0', nonoption_flags_max_len - len);
00438             }
00439         }
00440       nonoption_flags_len = nonoption_flags_max_len;
00441     }
00442   else
00443     nonoption_flags_len = 0;
00444 #endif
00445 
00446   return optstring;
00447 }
00448 
00449 
00450 
00451 
00452 
00453 
00454 
00455 
00456 
00457 
00458 
00459 
00460 
00461 
00462 
00463 
00464 
00465 
00466 
00467 
00468 
00469 
00470 
00471 
00472 
00473 
00474 
00475 
00476 
00477 
00478 
00479 
00480 
00481 
00482 
00483 
00484 
00485 
00486 
00487 
00488 
00489 
00490 
00491 
00492 
00493 
00494 
00495 
00496 
00497 
00498 
00499 
00500 
00501 
00502 
00503 
00504 
00505 int
00506 _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
00507      int argc;
00508      char *const *argv;
00509      const char *optstring;
00510      const struct option *longopts;
00511      int *longind;
00512      int long_only;
00513 {
00514   int print_errors = opterr;
00515   if (optstring[0] == ':')
00516     print_errors = 0;
00517 
00518   if (argc < 1)
00519     return -1;
00520 
00521   optarg = NULL;
00522 
00523   if (optind == 0 || !__getopt_initialized)
00524     {
00525       if (optind == 0)
00526         optind = 1;     
00527       optstring = _getopt_initialize (argc, argv, optstring);
00528       __getopt_initialized = 1;
00529     }
00530 
00531   
00532 
00533 
00534 
00535 #if defined _LIBC && defined USE_NONOPTION_FLAGS
00536 # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'       \
00537                       || (optind < nonoption_flags_len                        \
00538                           && __getopt_nonoption_flags[optind] == '1'))
00539 #else
00540 # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
00541 #endif
00542 
00543   if (nextchar == NULL || *nextchar == '\0')
00544     {
00545       
00546 
00547       
00548 
00549       if (last_nonopt > optind)
00550         last_nonopt = optind;
00551       if (first_nonopt > optind)
00552         first_nonopt = optind;
00553 
00554       if (ordering == PERMUTE)
00555         {
00556           
00557 
00558 
00559           if (first_nonopt != last_nonopt && last_nonopt != optind)
00560             exchange ((char **) argv);
00561           else if (last_nonopt != optind)
00562             first_nonopt = optind;
00563 
00564           
00565 
00566 
00567           while (optind < argc && NONOPTION_P)
00568             optind++;
00569           last_nonopt = optind;
00570         }
00571 
00572       
00573 
00574 
00575 
00576 
00577       if (optind != argc && !strcmp (argv[optind], "--"))
00578         {
00579           optind++;
00580 
00581           if (first_nonopt != last_nonopt && last_nonopt != optind)
00582             exchange ((char **) argv);
00583           else if (first_nonopt == last_nonopt)
00584             first_nonopt = optind;
00585           last_nonopt = argc;
00586 
00587           optind = argc;
00588         }
00589 
00590       
00591 
00592 
00593       if (optind == argc)
00594         {
00595           
00596 
00597           if (first_nonopt != last_nonopt)
00598             optind = first_nonopt;
00599           return -1;
00600         }
00601 
00602       
00603 
00604 
00605       if (NONOPTION_P)
00606         {
00607           if (ordering == REQUIRE_ORDER)
00608             return -1;
00609           optarg = argv[optind++];
00610           return 1;
00611         }
00612 
00613       
00614 
00615 
00616       nextchar = (argv[optind] + 1
00617                   + (longopts != NULL && argv[optind][1] == '-'));
00618     }
00619 
00620   
00621 
00622   
00623 
00624 
00625 
00626 
00627 
00628 
00629 
00630 
00631 
00632 
00633 
00634 
00635   if (longopts != NULL
00636       && (argv[optind][1] == '-'
00637           || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
00638     {
00639       char *nameend;
00640       const struct option *p;
00641       const struct option *pfound = NULL;
00642       int exact = 0;
00643       int ambig = 0;
00644       int indfound = -1;
00645       int option_index;
00646 
00647       for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
00648          ;
00649 
00650       
00651 
00652       for (p = longopts, option_index = 0; p->name; p++, option_index++)
00653         if (!strncmp (p->name, nextchar, nameend - nextchar))
00654           {
00655             if ((unsigned int) (nameend - nextchar)
00656                 == (unsigned int) strlen (p->name))
00657               {
00658                 
00659                 pfound = p;
00660                 indfound = option_index;
00661                 exact = 1;
00662                 break;
00663               }
00664             else if (pfound == NULL)
00665               {
00666                 
00667                 pfound = p;
00668                 indfound = option_index;
00669               }
00670             else if (long_only
00671                      || pfound->has_arg != p->has_arg
00672                      || pfound->flag != p->flag
00673                      || pfound->val != p->val)
00674               
00675               ambig = 1;
00676           }
00677 
00678       if (ambig && !exact)
00679         {
00680           if (print_errors)
00681             fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
00682                      argv[0], argv[optind]);
00683           nextchar += strlen (nextchar);
00684           optind++;
00685           optopt = 0;
00686           return '?';
00687         }
00688 
00689       if (pfound != NULL)
00690         {
00691           option_index = indfound;
00692           optind++;
00693           if (*nameend)
00694             {
00695               
00696 
00697               if (pfound->has_arg)
00698                 optarg = nameend + 1;
00699               else
00700                 {
00701                   if (print_errors)
00702                     {
00703                       if (argv[optind - 1][1] == '-')
00704                         
00705                         fprintf (stderr,
00706                                  _("%s: option `--%s' doesn't allow an argument\n"),
00707                                  argv[0], pfound->name);
00708                       else
00709                         
00710                         fprintf (stderr,
00711                                  _("%s: option `%c%s' doesn't allow an argument\n"),
00712                                  argv[0], argv[optind - 1][0], pfound->name);
00713                     }
00714 
00715                   nextchar += strlen (nextchar);
00716 
00717                   optopt = pfound->val;
00718                   return '?';
00719                 }
00720             }
00721           else if (pfound->has_arg == 1)
00722             {
00723               if (optind < argc)
00724                 optarg = argv[optind++];
00725               else
00726                 {
00727                   if (print_errors)
00728                     fprintf (stderr,
00729                            _("%s: option `%s' requires an argument\n"),
00730                            argv[0], argv[optind - 1]);
00731                   nextchar += strlen (nextchar);
00732                   optopt = pfound->val;
00733                   return optstring[0] == ':' ? ':' : '?';
00734                 }
00735             }
00736           nextchar += strlen (nextchar);
00737           if (longind != NULL)
00738             *longind = option_index;
00739           if (pfound->flag)
00740             {
00741               *(pfound->flag) = pfound->val;
00742               return 0;
00743             }
00744           return pfound->val;
00745         }
00746 
00747       
00748 
00749 
00750 
00751       if (!long_only || argv[optind][1] == '-'
00752           || my_index (optstring, *nextchar) == NULL)
00753         {
00754           if (print_errors)
00755             {
00756               if (argv[optind][1] == '-')
00757                 
00758                 fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
00759                          argv[0], nextchar);
00760               else
00761                 
00762                 fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
00763                          argv[0], argv[optind][0], nextchar);
00764             }
00765           nextchar = (char *) "";
00766           optind++;
00767           optopt = 0;
00768           return '?';
00769         }
00770     }
00771 
00772   
00773 
00774   {
00775     char c = *nextchar++;
00776     char *temp = my_index (optstring, c);
00777 
00778     
00779     if (*nextchar == '\0')
00780       ++optind;
00781 
00782     if (temp == NULL || c == ':')
00783       {
00784         if (print_errors)
00785           {
00786             if (posixly_correct)
00787               
00788               fprintf (stderr, _("%s: illegal option -- %c\n"),
00789                        argv[0], c);
00790             else
00791               fprintf (stderr, _("%s: invalid option -- %c\n"),
00792                        argv[0], c);
00793           }
00794         optopt = c;
00795         return '?';
00796       }
00797     
00798     if (temp[0] == 'W' && temp[1] == ';')
00799       {
00800         char *nameend;
00801         const struct option *p;
00802         const struct option *pfound = NULL;
00803         int exact = 0;
00804         int ambig = 0;
00805         int indfound = 0;
00806         int option_index;
00807 
00808         
00809         if (*nextchar != '\0')
00810           {
00811             optarg = nextchar;
00812             
00813 
00814             optind++;
00815           }
00816         else if (optind == argc)
00817           {
00818             if (print_errors)
00819               {
00820                 
00821                 fprintf (stderr, _("%s: option requires an argument -- %c\n"),
00822                          argv[0], c);
00823               }
00824             optopt = c;
00825             if (optstring[0] == ':')
00826               c = ':';
00827             else
00828               c = '?';
00829             return c;
00830           }
00831         else
00832           
00833 
00834           optarg = argv[optind++];
00835 
00836         
00837 
00838 
00839         for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
00840            ;
00841 
00842         
00843 
00844         for (p = longopts, option_index = 0; p->name; p++, option_index++)
00845           if (!strncmp (p->name, nextchar, nameend - nextchar))
00846             {
00847               if ((unsigned int) (nameend - nextchar) == strlen (p->name))
00848                 {
00849                   
00850                   pfound = p;
00851                   indfound = option_index;
00852                   exact = 1;
00853                   break;
00854                 }
00855               else if (pfound == NULL)
00856                 {
00857                   
00858                   pfound = p;
00859                   indfound = option_index;
00860                 }
00861               else
00862                 
00863                 ambig = 1;
00864             }
00865         if (ambig && !exact)
00866           {
00867             if (print_errors)
00868               fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
00869                        argv[0], argv[optind]);
00870             nextchar += strlen (nextchar);
00871             optind++;
00872             return '?';
00873           }
00874         if (pfound != NULL)
00875           {
00876             option_index = indfound;
00877             if (*nameend)
00878               {
00879                 
00880 
00881                 if (pfound->has_arg)
00882                   optarg = nameend + 1;
00883                 else
00884                   {
00885                     if (print_errors)
00886                       fprintf (stderr, _("\
00887 %s: option `-W %s' doesn't allow an argument\n"),
00888                                argv[0], pfound->name);
00889 
00890                     nextchar += strlen (nextchar);
00891                     return '?';
00892                   }
00893               }
00894             else if (pfound->has_arg == 1)
00895               {
00896                 if (optind < argc)
00897                   optarg = argv[optind++];
00898                 else
00899                   {
00900                     if (print_errors)
00901                       fprintf (stderr,
00902                                _("%s: option `%s' requires an argument\n"),
00903                                argv[0], argv[optind - 1]);
00904                     nextchar += strlen (nextchar);
00905                     return optstring[0] == ':' ? ':' : '?';
00906                   }
00907               }
00908             nextchar += strlen (nextchar);
00909             if (longind != NULL)
00910               *longind = option_index;
00911             if (pfound->flag)
00912               {
00913                 *(pfound->flag) = pfound->val;
00914                 return 0;
00915               }
00916             return pfound->val;
00917           }
00918           nextchar = NULL;
00919           return 'W';   
00920       }
00921     if (temp[1] == ':')
00922       {
00923         if (temp[2] == ':')
00924           {
00925             
00926             if (*nextchar != '\0')
00927               {
00928                 optarg = nextchar;
00929                 optind++;
00930               }
00931             else
00932               optarg = NULL;
00933             nextchar = NULL;
00934           }
00935         else
00936           {
00937             
00938             if (*nextchar != '\0')
00939               {
00940                 optarg = nextchar;
00941                 
00942 
00943                 optind++;
00944               }
00945             else if (optind == argc)
00946               {
00947                 if (print_errors)
00948                   {
00949                     
00950                     fprintf (stderr,
00951                              _("%s: option requires an argument -- %c\n"),
00952                              argv[0], c);
00953                   }
00954                 optopt = c;
00955                 if (optstring[0] == ':')
00956                   c = ':';
00957                 else
00958                   c = '?';
00959               }
00960             else
00961               
00962 
00963               optarg = argv[optind++];
00964             nextchar = NULL;
00965           }
00966       }
00967     return c;
00968   }
00969 }
00970 
00971 int
00972 getopt (argc, argv, optstring)
00973      int argc;
00974      char *const *argv;
00975      const char *optstring;
00976 {
00977   return _getopt_internal (argc, argv, optstring,
00978                            (const struct option *) 0,
00979                            (int *) 0,
00980                            0);
00981 }
00982 
00983 #endif  
00984 
00985 #ifdef TEST
00986 
00987 
00988 
00989 
00990 int
00991 main (argc, argv)
00992      int argc;
00993      char **argv;
00994 {
00995   int c;
00996   int digit_optind = 0;
00997 
00998   while (1)
00999     {
01000       int this_option_optind = optind ? optind : 1;
01001 
01002       c = getopt (argc, argv, "abc:d:0123456789");
01003       if (c == -1)
01004         break;
01005 
01006       switch (c)
01007         {
01008         case '0':
01009         case '1':
01010         case '2':
01011         case '3':
01012         case '4':
01013         case '5':
01014         case '6':
01015         case '7':
01016         case '8':
01017         case '9':
01018           if (digit_optind != 0 && digit_optind != this_option_optind)
01019             printf ("digits occur in two different argv-elements.\n");
01020           digit_optind = this_option_optind;
01021           printf ("option %c\n", c);
01022           break;
01023 
01024         case 'a':
01025           printf ("option a\n");
01026           break;
01027 
01028         case 'b':
01029           printf ("option b\n");
01030           break;
01031 
01032         case 'c':
01033           printf ("option c with value `%s'\n", optarg);
01034           break;
01035 
01036         case '?':
01037           break;
01038 
01039         default:
01040           printf ("?? getopt returned character code 0%o ??\n", c);
01041         }
01042     }
01043 
01044   if (optind < argc)
01045     {
01046       printf ("non-option ARGV-elements: ");
01047       while (optind < argc)
01048         printf ("%s ", argv[optind++]);
01049       printf ("\n");
01050     }
01051 
01052   exit (0);
01053 }
01054 
01055 #endif