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 
00082 # ifdef HAVE_LIBINTL_H
00083 #  include <libintl.h>
00084 #  define _(msgid)      gettext (msgid)
00085 # else
00086 #  define _(msgid)      (msgid)
00087 # endif
00088 #endif
00089 
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104 #include "getopt.h"
00105 
00106 
00107 
00108 
00109 
00110 
00111 
00112 char *optarg;
00113 
00114 
00115 
00116 
00117 
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125 
00126 
00127 int optind = 1;
00128 
00129 
00130 
00131 
00132 
00133 int __getopt_initialized;
00134 
00135 
00136 
00137 
00138 
00139 
00140 
00141 
00142 static char *nextchar;
00143 
00144 
00145 
00146 
00147 int opterr = 1;
00148 
00149 
00150 
00151 
00152 
00153 int optopt = '?';
00154 
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 static enum
00185 {
00186   REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
00187 } ordering;
00188 
00189 
00190 static char *posixly_correct;
00191 
00192 #ifdef  __GNU_LIBRARY__
00193 
00194 
00195 
00196 
00197 # include <string.h>
00198 # define my_index       strchr
00199 #else
00200 
00201 # if HAVE_STRING_H
00202 #  include <string.h>
00203 # else
00204 #  include <strings.h>
00205 # endif
00206 
00207 
00208 
00209 
00210 #ifndef getenv
00211 extern char *getenv ();
00212 #endif
00213 
00214 static char *
00215 my_index (str, chr)
00216      const char *str;
00217      int chr;
00218 {
00219   while (*str)
00220     {
00221       if (*str == chr)
00222         return (char *) str;
00223       str++;
00224     }
00225   return 0;
00226 }
00227 
00228 
00229 
00230 #ifdef __GNUC__
00231 
00232 
00233 # if (!defined __STDC__ || !__STDC__) && !defined strlen
00234 
00235 
00236 extern int strlen (const char *);
00237 # endif 
00238 #endif 
00239 
00240 #endif 
00241 
00242 
00243 
00244 
00245 
00246 
00247 
00248 static int first_nonopt;
00249 static int last_nonopt;
00250 
00251 #ifdef _LIBC
00252 
00253 
00254 
00255 
00256 extern char *__getopt_nonoption_flags;
00257 
00258 static int nonoption_flags_max_len;
00259 static int nonoption_flags_len;
00260 
00261 static int original_argc;
00262 static char *const *original_argv;
00263 
00264 
00265 
00266 
00267 static void
00268 __attribute__ ((unused))
00269 store_args_and_env (int argc, char *const *argv)
00270 {
00271   
00272 
00273   original_argc = argc;
00274   original_argv = argv;
00275 }
00276 # ifdef text_set_element
00277 text_set_element (__libc_subinit, store_args_and_env);
00278 # endif 
00279 
00280 # define SWAP_FLAGS(ch1, ch2) \
00281   if (nonoption_flags_len > 0)                                                \
00282     {                                                                         \
00283       char __tmp = __getopt_nonoption_flags[ch1];                             \
00284       __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];          \
00285       __getopt_nonoption_flags[ch2] = __tmp;                                  \
00286     }
00287 #else   
00288 # define SWAP_FLAGS(ch1, ch2)
00289 #endif  
00290 
00291 
00292 
00293 
00294 
00295 
00296 
00297 
00298 
00299 
00300 #if defined __STDC__ && __STDC__
00301 static void exchange (char **);
00302 #endif
00303 
00304 static void
00305 exchange (argv)
00306      char **argv;
00307 {
00308   int bottom = first_nonopt;
00309   int middle = last_nonopt;
00310   int top = optind;
00311   char *tem;
00312 
00313   
00314 
00315 
00316 
00317 
00318 #ifdef _LIBC
00319   
00320 
00321 
00322   if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
00323     {
00324       
00325 
00326       char *new_str = malloc (top + 1);
00327       if (new_str == NULL)
00328         nonoption_flags_len = nonoption_flags_max_len = 0;
00329       else
00330         {
00331           memset (__mempcpy (new_str, __getopt_nonoption_flags,
00332                              nonoption_flags_max_len),
00333                   '\0', top + 1 - nonoption_flags_max_len);
00334           nonoption_flags_max_len = top + 1;
00335           __getopt_nonoption_flags = new_str;
00336         }
00337     }
00338 #endif
00339 
00340   while (top > middle && middle > bottom)
00341     {
00342       if (top - middle > middle - bottom)
00343         {
00344           
00345           int len = middle - bottom;
00346           register int i;
00347 
00348           
00349           for (i = 0; i < len; i++)
00350             {
00351               tem = argv[bottom + i];
00352               argv[bottom + i] = argv[top - (middle - bottom) + i];
00353               argv[top - (middle - bottom) + i] = tem;
00354               SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
00355             }
00356           
00357           top -= len;
00358         }
00359       else
00360         {
00361           
00362           int len = top - middle;
00363           register int i;
00364 
00365           
00366           for (i = 0; i < len; i++)
00367             {
00368               tem = argv[bottom + i];
00369               argv[bottom + i] = argv[middle + i];
00370               argv[middle + i] = tem;
00371               SWAP_FLAGS (bottom + i, middle + i);
00372             }
00373           
00374           bottom += len;
00375         }
00376     }
00377 
00378   
00379 
00380   first_nonopt += (optind - last_nonopt);
00381   last_nonopt = optind;
00382 }
00383 
00384 
00385 
00386 #if defined __STDC__ && __STDC__
00387 static const char *_getopt_initialize (int, char *const *, const char *);
00388 #endif
00389 static const char *
00390 _getopt_initialize (argc, argv, optstring)
00391      int argc;
00392      char *const *argv;
00393      const char *optstring;
00394 {
00395   
00396 
00397 
00398 
00399   first_nonopt = last_nonopt = optind;
00400 
00401   nextchar = NULL;
00402 
00403   posixly_correct = getenv ("POSIXLY_CORRECT");
00404 
00405   
00406 
00407   if (optstring[0] == '-')
00408     {
00409       ordering = RETURN_IN_ORDER;
00410       ++optstring;
00411     }
00412   else if (optstring[0] == '+')
00413     {
00414       ordering = REQUIRE_ORDER;
00415       ++optstring;
00416     }
00417   else if (posixly_correct != NULL)
00418     ordering = REQUIRE_ORDER;
00419   else
00420     ordering = PERMUTE;
00421 
00422 #ifdef _LIBC
00423   if (posixly_correct == NULL
00424       && argc == original_argc && argv == original_argv)
00425     {
00426       if (nonoption_flags_max_len == 0)
00427         {
00428           if (__getopt_nonoption_flags == NULL
00429               || __getopt_nonoption_flags[0] == '\0')
00430             nonoption_flags_max_len = -1;
00431           else
00432             {
00433               const char *orig_str = __getopt_nonoption_flags;
00434               int len = nonoption_flags_max_len = strlen (orig_str);
00435               if (nonoption_flags_max_len < argc)
00436                 nonoption_flags_max_len = argc;
00437               __getopt_nonoption_flags =
00438                 (char *) malloc (nonoption_flags_max_len);
00439               if (__getopt_nonoption_flags == NULL)
00440                 nonoption_flags_max_len = -1;
00441               else
00442                 memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
00443                         '\0', nonoption_flags_max_len - len);
00444             }
00445         }
00446       nonoption_flags_len = nonoption_flags_max_len;
00447     }
00448   else
00449     nonoption_flags_len = 0;
00450 #endif
00451 
00452   return optstring;
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 
00506 
00507 
00508 
00509 
00510 
00511 int
00512 _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
00513      int argc;
00514      char *const *argv;
00515      const char *optstring;
00516      const struct option *longopts;
00517      int *longind;
00518      int long_only;
00519 {
00520   int print_errors = opterr;
00521   if (optstring[0] == ':')
00522     print_errors = 0;
00523 
00524   optarg = NULL;
00525 
00526   if (optind == 0 || !__getopt_initialized)
00527     {
00528       if (optind == 0)
00529         optind = 1;     
00530       optstring = _getopt_initialize (argc, argv, optstring);
00531       __getopt_initialized = 1;
00532     }
00533 
00534   
00535 
00536 
00537 
00538 #ifdef _LIBC
00539 # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'       \
00540                       || (optind < nonoption_flags_len                        \
00541                           && __getopt_nonoption_flags[optind] == '1'))
00542 #else
00543 # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
00544 #endif
00545 
00546   if (nextchar == NULL || *nextchar == '\0')
00547     {
00548       
00549 
00550       
00551 
00552       if (last_nonopt > optind)
00553         last_nonopt = optind;
00554       if (first_nonopt > optind)
00555         first_nonopt = optind;
00556 
00557       if (ordering == PERMUTE)
00558         {
00559           
00560 
00561 
00562           if (first_nonopt != last_nonopt && last_nonopt != optind)
00563             exchange ((char **) argv);
00564           else if (last_nonopt != optind)
00565             first_nonopt = optind;
00566 
00567           
00568 
00569 
00570           while (optind < argc && NONOPTION_P)
00571             optind++;
00572           last_nonopt = optind;
00573         }
00574 
00575       
00576 
00577 
00578 
00579 
00580       if (optind != argc && !strcmp (argv[optind], "--"))
00581         {
00582           optind++;
00583 
00584           if (first_nonopt != last_nonopt && last_nonopt != optind)
00585             exchange ((char **) argv);
00586           else if (first_nonopt == last_nonopt)
00587             first_nonopt = optind;
00588           last_nonopt = argc;
00589 
00590           optind = argc;
00591         }
00592 
00593       
00594 
00595 
00596       if (optind == argc)
00597         {
00598           
00599 
00600           if (first_nonopt != last_nonopt)
00601             optind = first_nonopt;
00602           return -1;
00603         }
00604 
00605       
00606 
00607 
00608       if (NONOPTION_P)
00609         {
00610           if (ordering == REQUIRE_ORDER)
00611             return -1;
00612           optarg = argv[optind++];
00613           return 1;
00614         }
00615 
00616       
00617 
00618 
00619       nextchar = (argv[optind] + 1
00620                   + (longopts != NULL && argv[optind][1] == '-'));
00621     }
00622 
00623   
00624 
00625   
00626 
00627 
00628 
00629 
00630 
00631 
00632 
00633 
00634 
00635 
00636 
00637 
00638   if (longopts != NULL
00639       && (argv[optind][1] == '-'
00640           || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
00641     {
00642       char *nameend;
00643       const struct option *p;
00644       const struct option *pfound = NULL;
00645       int exact = 0;
00646       int ambig = 0;
00647       int indfound = -1;
00648       int option_index;
00649 
00650       for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
00651          ;
00652 
00653       
00654 
00655       for (p = longopts, option_index = 0; p->name; p++, option_index++)
00656         if (!strncmp (p->name, nextchar, nameend - nextchar))
00657           {
00658             if ((unsigned int) (nameend - nextchar)
00659                 == (unsigned int) strlen (p->name))
00660               {
00661                 
00662                 pfound = p;
00663                 indfound = option_index;
00664                 exact = 1;
00665                 break;
00666               }
00667             else if (pfound == NULL)
00668               {
00669                 
00670                 pfound = p;
00671                 indfound = option_index;
00672               }
00673             else
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