Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

bsd-getopt-long.c File Reference

#include <config.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include "bsd-getopt-long.h"

Include dependency graph for bsd-getopt-long.c:

Include dependency graph

Go to the source code of this file.

Defines

#define IN_GETOPT_LONG_C   1
#define PRINT_ERROR   ((pure_opterr) && (*options != ':'))
#define FLAG_PERMUTE   0x01
#define FLAG_ALLARGS   0x02
#define FLAG_LONGONLY   0x04
#define BADCH   (int)'?'
#define BADARG   ((*options == ':') ? (int)':' : (int)'?')
#define INORDER   (int)1
#define EMSG   ""

Functions

int pure_getopt_internal (int, char *const *, const char *, const struct pure_option *, int *, int)
int pure_parse_long_options (char *const *, const char *, const struct pure_option *, int *, int)
int pure_gcd (int, int)
void pure_permute_args (int, int, int, char *const *)
int pure_getopt (int nargc, char *const *nargv, const char *options)
int pure_getopt_long (int nargc, char *const *nargv, const char *options, const struct pure_option *long_options, int *idx)
int pure_getopt_long_only (int nargc, char *const *nargv, const char *options, const struct pure_option *long_options, int *idx)

Variables

int pure_opterr = 1
int pure_optind = 1
int pure_optopt = '?'
int pure_optreset
const char * pure_optarg
const char * pure_place = EMSG
int nonopt_start = -1
int nonopt_end = -1
const char * recargchar = "option requires an argument -- %c\n"
const char * recargstring = "option requires an argument -- %s\n"
const char * ambig = "ambiguous option -- %.*s\n"
const char * noarg = "option doesn't take an argument -- %.*s\n"
const char * illoptchar = "unknown option -- %c\n"
const char * illoptstring = "unknown option -- %s\n"


Define Documentation

#define BADARG   ((*options == ':') ? (int)':' : (int)'?')
 

Definition at line 87 of file bsd-getopt-long.c.

Referenced by pure_getopt_internal(), and pure_parse_long_options().

#define BADCH   (int)'?'
 

Definition at line 86 of file bsd-getopt-long.c.

Referenced by pure_getopt_internal(), and pure_parse_long_options().

#define EMSG   ""
 

Definition at line 90 of file bsd-getopt-long.c.

Referenced by pure_getopt_internal().

#define FLAG_ALLARGS   0x02
 

Definition at line 82 of file bsd-getopt-long.c.

Referenced by pure_getopt_internal().

#define FLAG_LONGONLY   0x04
 

Definition at line 83 of file bsd-getopt-long.c.

Referenced by pure_getopt_internal(), and pure_getopt_long_only().

#define FLAG_PERMUTE   0x01
 

Definition at line 81 of file bsd-getopt-long.c.

Referenced by pure_getopt_internal(), pure_getopt_long(), and pure_getopt_long_only().

#define IN_GETOPT_LONG_C   1
 

Definition at line 57 of file bsd-getopt-long.c.

#define INORDER   (int)1
 

Definition at line 88 of file bsd-getopt-long.c.

Referenced by pure_getopt_internal().

#define PRINT_ERROR   ((pure_opterr) && (*options != ':'))
 

Definition at line 79 of file bsd-getopt-long.c.

Referenced by pure_getopt_internal(), and pure_parse_long_options().


Function Documentation

int pure_gcd int  ,
int 
[static]
 

Definition at line 116 of file bsd-getopt-long.c.

Referenced by pure_permute_args().

00117 {
00118     int c;
00119     
00120     c = a % b;
00121     while (c != 0) {
00122         a = b;
00123         b = c;
00124         c = a % b;
00125     }    
00126     return b;
00127 }

int pure_getopt int  nargc,
char *const *  nargv,
const char *  options
 

Definition at line 488 of file bsd-getopt-long.c.

References pure_getopt_internal().

00489 {
00490     
00491     /*
00492      * We dont' pass FLAG_PERMUTE to pure_getopt_internal() since
00493      * the BSD getopt(3) (unlike GNU) has never done this.
00494      *
00495      * Furthermore, since many privileged programs call getopt()
00496      * before dropping privileges it makes sense to keep things
00497      * as simple (and bug-free) as possible.
00498      */
00499     return pure_getopt_internal(nargc, nargv, options, NULL, NULL, 0);
00500 }

int pure_getopt_internal int  ,
char *const *  ,
const char *  ,
const struct pure_option ,
int *  ,
int 
[static]
 

Definition at line 288 of file bsd-getopt-long.c.

References BADARG, BADCH, EMSG, FLAG_ALLARGS, FLAG_LONGONLY, FLAG_PERMUTE, illoptchar, INORDER, nonopt_end, nonopt_start, PRINT_ERROR, pure_optarg, pure_optind, pure_optopt, pure_optreset, pure_parse_long_options(), pure_permute_args(), pure_place, and recargchar.

Referenced by pure_getopt(), pure_getopt_long(), and pure_getopt_long_only().

00292 {
00293     char *oli;                /* option letter list index */
00294     int optchar, short_too;
00295     static int posixly_correct = -1;
00296     
00297     if (options == NULL)
00298         return -1;
00299     
00300     /*
00301      * Disable GNU extensions if POSIXLY_CORRECT is set or options
00302      * string begins with a '+'.
00303      */
00304     if (posixly_correct == -1)
00305         posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
00306     if (posixly_correct || *options == '+')
00307         flags &= ~FLAG_PERMUTE;
00308     else if (*options == '-')
00309         flags |= FLAG_ALLARGS;
00310     if (*options == '+' || *options == '-')
00311         options++;
00312     
00313     /*
00314      * XXX Some GNU programs (like cvs) set pure_optind to 0 instead of
00315      * XXX using pure_optreset.  Work around this braindamage.
00316      */
00317     if (pure_optind == 0)
00318         pure_optind = pure_optreset = 1;
00319     
00320     pure_optarg = NULL;
00321     if (pure_optreset)
00322         nonopt_start = nonopt_end = -1;
00323     start:
00324     if (pure_optreset || !*pure_place) {        /* update scanning pointer */
00325         pure_optreset = 0;
00326         if (pure_optind >= nargc) {          /* end of argument vector */
00327             pure_place = EMSG;
00328             if (nonopt_end != -1) {
00329                 /* do permutation, if we have to */
00330                 pure_permute_args(nonopt_start, nonopt_end,
00331                                   pure_optind, nargv);
00332                 pure_optind -= nonopt_end - nonopt_start;
00333             }
00334             else if (nonopt_start != -1) {
00335                 /*
00336                  * If we skipped non-options, set pure_optind
00337                  * to the first of them.
00338                  */
00339                 pure_optind = nonopt_start;
00340             }
00341             nonopt_start = nonopt_end = -1;
00342             return -1;
00343         }
00344         if (*(pure_place = nargv[pure_optind]) != '-' ||
00345             (pure_place[1] == '\0' && strchr(options, '-') == NULL)) {
00346             pure_place = EMSG;        /* found non-option */
00347             if (flags & FLAG_ALLARGS) {
00348                 /*
00349                  * GNU extension:
00350                  * return non-option as argument to option 1
00351                  */
00352                 pure_optarg = nargv[pure_optind++];
00353                 return INORDER;
00354             }
00355             if (!(flags & FLAG_PERMUTE)) {
00356                 /*
00357                  * If no permutation wanted, stop parsing
00358                  * at first non-option.
00359                  */
00360                 return -1;
00361             }
00362             /* do permutation */
00363             if (nonopt_start == -1)
00364                 nonopt_start = pure_optind;
00365             else if (nonopt_end != -1) {
00366                 pure_permute_args(nonopt_start, nonopt_end,
00367                                   pure_optind, nargv);
00368                 nonopt_start = pure_optind -
00369                     (nonopt_end - nonopt_start);
00370                 nonopt_end = -1;
00371             }
00372             pure_optind++;
00373             /* process next argument */
00374             goto start;
00375         }
00376         if (nonopt_start != -1 && nonopt_end == -1)
00377             nonopt_end = pure_optind;
00378 
00379         /*
00380          * Check for "--" or "--foo" with no long options
00381          * but if pure_place is simply "-" leave it unmolested.
00382          */
00383 
00384         if (pure_place[1] != '\0' && *++pure_place == '-' &&
00385             (pure_place[1] == '\0' || long_options == NULL)) {
00386             pure_optind++;
00387             pure_place = EMSG;
00388             /*
00389              * We found an option (--), so if we skipped
00390              * non-options, we have to permute.
00391              */
00392             if (nonopt_end != -1) {
00393                 pure_permute_args(nonopt_start, nonopt_end,
00394                                   pure_optind, nargv);
00395                 pure_optind -= nonopt_end - nonopt_start;
00396             }
00397             nonopt_start = nonopt_end = -1;
00398             return -1;
00399         }
00400     }
00401     
00402     /*
00403      * Check long options if:
00404      *  1) we were passed some
00405      *  2) the arg is not just "-"
00406      *  3) either the arg starts with -- we are pure_getopt_long_only()
00407      */
00408     if (long_options != NULL && pure_place != nargv[pure_optind] &&
00409         (*pure_place == '-' || (flags & FLAG_LONGONLY))) {
00410         short_too = 0;
00411         if (*pure_place == '-')
00412             pure_place++;        /* --foo long option */
00413         else if (*pure_place != ':' && strchr(options, *pure_place) != NULL)
00414             short_too = 1;        /* could be short option too */
00415         
00416         optchar = pure_parse_long_options(nargv, options, long_options,
00417                                           idx, short_too);
00418         if (optchar != -1) {
00419             pure_place = EMSG;
00420             return optchar;
00421         }
00422     }
00423     
00424     if ((optchar = (int) *pure_place++) == ':' ||
00425         (optchar == '-' && *pure_place != '\0') ||        
00426         (oli = strchr(options, optchar)) == NULL) { 
00427          /*
00428           * If the user specified "-" and '-' isn't listed in
00429           * options, return -1 (non-option) as per POSIX.
00430           * Otherwise, it is an unknown option character (or :').
00431           */
00432         if (optchar == '-' && *pure_place == '\0')
00433             return -1;
00434         if (!*pure_place)
00435             ++pure_optind;
00436         if (PRINT_ERROR)
00437             fprintf(stderr, illoptchar, optchar);
00438         pure_optopt = optchar;
00439         return BADCH;
00440     }
00441     if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
00442         /* -W long-option */
00443         if (*pure_place)            /* no space */
00444             /* NOTHING */;
00445         else if (++pure_optind >= nargc) {    /* no arg */
00446             pure_place = EMSG;
00447             if (PRINT_ERROR)
00448                 fprintf(stderr, recargchar, optchar);
00449             pure_optopt = optchar;
00450             return BADARG;
00451         } else                /* white space */
00452             pure_place = nargv[pure_optind];
00453         optchar = pure_parse_long_options(nargv, options, long_options,
00454                                           idx, 0);
00455         pure_place = EMSG;
00456         return optchar;
00457     }
00458     if (*++oli != ':') {            /* doesn't take argument */
00459         if (!*pure_place)
00460             ++pure_optind;
00461     } else {                /* takes (optional) argument */
00462         pure_optarg = NULL;
00463         if (*pure_place)            /* no white space */
00464             pure_optarg = pure_place;
00465         /* XXX: disable test for :: if PC? (GNU doesn't) */
00466         else if (oli[1] != ':') {    /* arg not optional */
00467             if (++pure_optind >= nargc) {    /* no arg */
00468                 pure_place = EMSG;
00469                 if (PRINT_ERROR)
00470                     fprintf(stderr, recargchar, optchar);
00471                 pure_optopt = optchar;
00472                 return BADARG;
00473             } else {
00474                 pure_optarg = nargv[pure_optind];
00475             }
00476         }
00477         pure_place = EMSG;
00478         ++pure_optind;
00479     }
00480     /* dump back option letter */
00481     return optchar;
00482 }

int pure_getopt_long int  nargc,
char *const *  nargv,
const char *  options,
const struct pure_option long_options,
int *  idx
 

Definition at line 506 of file bsd-getopt-long.c.

References FLAG_PERMUTE, and pure_getopt_internal().

00508 {
00509     return pure_getopt_internal(nargc, nargv, options, long_options, idx,
00510                                 FLAG_PERMUTE);
00511 }

int pure_getopt_long_only int  nargc,
char *const *  nargv,
const char *  options,
const struct pure_option long_options,
int *  idx
 

Definition at line 517 of file bsd-getopt-long.c.

References FLAG_LONGONLY, FLAG_PERMUTE, and pure_getopt_internal().

00521 {
00522     return pure_getopt_internal(nargc, nargv, options, long_options, idx,
00523                                 FLAG_PERMUTE|FLAG_LONGONLY);
00524 }

int pure_parse_long_options char *const *  ,
const char *  ,
const struct pure_option ,
int *  ,
int 
[static]
 

Definition at line 170 of file bsd-getopt-long.c.

References ambig, BADARG, BADCH, pure_option::flag, pure_option::has_arg, illoptstring, name, pure_option::name, no_argument, noarg, optional_argument, PRINT_ERROR, pure_optarg, pure_optind, pure_optopt, pure_place, recargstring, required_argument, and pure_option::val.

Referenced by pure_getopt_internal().

00173 {
00174     const char *current_argv, *has_equal;
00175     size_t current_argv_len;
00176     int i, match;
00177     
00178     current_argv = pure_place;
00179     match = -1;
00180     
00181     pure_optind++;
00182     
00183     if ((has_equal = strchr(current_argv, '=')) != NULL) {
00184         /* argument found (--option=arg) */
00185         current_argv_len = has_equal - current_argv;
00186         has_equal++;
00187     } else
00188         current_argv_len = strlen(current_argv);
00189     
00190     for (i = 0; long_options[i].name; i++) {
00191         /* find matching long option */
00192         if (strncmp(current_argv, long_options[i].name,
00193             current_argv_len))
00194             continue;
00195         
00196         if (strlen(long_options[i].name) == current_argv_len) {
00197             /* exact match */
00198             match = i;
00199             break;
00200         }
00201         /*
00202          * If this is a known short option, don't allow
00203          * a partial match of a single character.
00204          */
00205         if (short_too && current_argv_len == 1)
00206             continue;
00207         
00208         if (match == -1)    /* partial match */
00209             match = i;
00210         else {
00211             /* ambiguous abbreviation */
00212             if (PRINT_ERROR)
00213                 fprintf(stderr, ambig, (int)current_argv_len,
00214                         current_argv);
00215             pure_optopt = 0;
00216             return BADCH;
00217         }
00218     }
00219     if (match != -1) {        /* option found */
00220         if (long_options[match].has_arg == no_argument
00221             && has_equal) {
00222             if (PRINT_ERROR)
00223                 fprintf(stderr, noarg, (int)current_argv_len,
00224                         current_argv);
00225             /*
00226              * XXX: GNU sets pure_optopt to val regardless of flag
00227              */
00228             if (long_options[match].flag == NULL)
00229                 pure_optopt = long_options[match].val;
00230             else
00231                 pure_optopt = 0;
00232             return BADARG;
00233         }
00234         if (long_options[match].has_arg == required_argument ||
00235             long_options[match].has_arg == optional_argument) {
00236             if (has_equal)
00237                 pure_optarg = has_equal;
00238             else if (long_options[match].has_arg ==
00239                      required_argument) {
00240                 /*
00241                  * optional argument doesn't use next nargv
00242                  */
00243                 pure_optarg = nargv[pure_optind++];
00244             }
00245         }
00246         if ((long_options[match].has_arg == required_argument)
00247             && (pure_optarg == NULL)) {
00248             /*
00249              * Missing argument; leading ':' indicates no error
00250              * should be generated.
00251              */
00252             if (PRINT_ERROR)
00253                 fprintf(stderr, recargstring,
00254                         current_argv);
00255             /*
00256              * XXX: GNU sets pure_optopt to val regardless of flag
00257              */
00258             if (long_options[match].flag == NULL)
00259                 pure_optopt = long_options[match].val;
00260             else
00261                 pure_optopt = 0;
00262             --pure_optind;
00263             return BADARG;
00264         }
00265     } else {            /* unknown option */
00266         if (short_too) {
00267             --pure_optind;
00268             return -1;
00269         }
00270         if (PRINT_ERROR)
00271             fprintf(stderr, illoptstring, current_argv);
00272         pure_optopt = 0;
00273         return BADCH;
00274     }
00275     if (idx)
00276         *idx = match;
00277     if (long_options[match].flag) {
00278         *long_options[match].flag = long_options[match].val;
00279         return 0;
00280     } else
00281         return long_options[match].val;
00282 }

void pure_permute_args int  ,
int  ,
int  ,
char *const * 
[static]
 

Definition at line 134 of file bsd-getopt-long.c.

References pure_gcd().

Referenced by pure_getopt_internal().

00136 {
00137     int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
00138     char *swap;
00139     
00140     /*
00141      * compute lengths of blocks and number and size of cycles
00142      */
00143     nnonopts = panonopt_end - panonopt_start;
00144     nopts = opt_end - panonopt_end;
00145     ncycle = pure_gcd(nnonopts, nopts);
00146     cyclelen = (opt_end - panonopt_start) / ncycle;
00147     
00148     for (i = 0; i < ncycle; i++) {
00149         cstart = panonopt_end+i;
00150         pos = cstart;
00151         for (j = 0; j < cyclelen; j++) {
00152             if (pos >= panonopt_end)
00153                 pos -= nnonopts;
00154             else
00155                 pos += nopts;
00156             swap = nargv[pos];
00157             /* LINTED const cast */
00158             ((char **) nargv)[pos] = nargv[cstart];
00159             /* LINTED const cast */
00160             ((char **)nargv)[cstart] = swap;
00161         }
00162     }
00163 }


Variable Documentation

const char* ambig = "ambiguous option -- %.*s\n" [static]
 

Definition at line 108 of file bsd-getopt-long.c.

Referenced by pure_parse_long_options().

const char* illoptchar = "unknown option -- %c\n" [static]
 

Definition at line 110 of file bsd-getopt-long.c.

Referenced by pure_getopt_internal().

const char* illoptstring = "unknown option -- %s\n" [static]
 

Definition at line 111 of file bsd-getopt-long.c.

Referenced by pure_parse_long_options().

const char* noarg = "option doesn't take an argument -- %.*s\n" [static]
 

Definition at line 109 of file bsd-getopt-long.c.

Referenced by pure_parse_long_options().

int nonopt_end = -1 [static]
 

Definition at line 103 of file bsd-getopt-long.c.

Referenced by pure_getopt_internal().

int nonopt_start = -1 [static]
 

Definition at line 102 of file bsd-getopt-long.c.

Referenced by pure_getopt_internal().

const char* pure_optarg
 

Definition at line 77 of file bsd-getopt-long.c.

Referenced by pure_getopt_internal(), and pure_parse_long_options().

int pure_opterr = 1
 

Definition at line 73 of file bsd-getopt-long.c.

int pure_optind = 1
 

Definition at line 74 of file bsd-getopt-long.c.

Referenced by pure_getopt_internal(), and pure_parse_long_options().

int pure_optopt = '?'
 

Definition at line 75 of file bsd-getopt-long.c.

Referenced by pure_getopt_internal(), and pure_parse_long_options().

int pure_optreset
 

Definition at line 76 of file bsd-getopt-long.c.

Referenced by pure_getopt_internal().

const char* pure_place = EMSG [static]
 

Definition at line 99 of file bsd-getopt-long.c.

Referenced by pure_getopt_internal(), and pure_parse_long_options().

const char* recargchar = "option requires an argument -- %c\n" [static]
 

Definition at line 106 of file bsd-getopt-long.c.

Referenced by pure_getopt_internal().

const char* recargstring = "option requires an argument -- %s\n" [static]
 

Definition at line 107 of file bsd-getopt-long.c.

Referenced by pure_parse_long_options().


Generated on Wed Sep 14 02:57:33 2005 for bro_docs by doxygen 1.3.5