YoushouldhavereceivedacopyoftheGNULibraryGeneralPublic LicensealongwiththeGNUCLibrary;seethefileCOPYING.LIB.Ifnot, writetotheFreeSoftwareFoundation,Inc.,59TemplePlace-Suite330,
Boston, MA 02111-1307, USA. */
#include <stdio.h> #include <stdlib.h> #ifndef _MSC_VER /* Visual C++ doesn't have unistd.h */ #include <unistd.h> #endif #include <string.h>
#ifndef _ /* This is for other GNU distributions with internationalized messages.
When compiling libc, the _ macro is predefined. */ #ifdef HAVE_LIBINTL_H #include <libintl.h> #define _(msgid) gettext (msgid) #else #define _(msgid) (msgid) #endif #endif
/* This version of `gnu_getopt' appears to the caller like standard Unix`getopt'butitbehavesdifferentlyfortheuser,sinceit allowstheusertointerspersetheoptionswiththeother arguments.
GNUapplicationprogramscanuseathirdalternativemodeinwhich
they can distinguish the relative order of options and other arguments. */
#include"gnu_getopt.h"
#ifdef __cplusplus extern"C" { #endif
/* For communication from `gnu_getopt' to the caller. When`gnu_getopt'findsanoptionthattakesanargument, theargumentvalueisreturnedhere. Also,when`ordering'isRETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
char *gnu_optarg = NULL;
/* Index in ARGV of the next element to be scanned. Thisisusedforcommunicationtoandfromthecaller andforcommunicationbetweensuccessivecallsto`gnu_getopt'.
Otherwise,`gnu_optind'communicatesfromonecalltothenext
how much of ARGV has been scanned so far. */
/* 1003.2 says this must be 1 before any call. */ int gnu_optind = 1;
/* Formerly, initialization of gnu_getopt depended on gnu_optind==0, which causesproblemswithre-callinggnu_getoptasprogramsgenerallydon't
know that. */
int __gnu_getopt_initialized = 0;
/* The next char to be scanned in the option-element inwhichthelastoptioncharacterwereturnedwasfound. Thisallowsustopickupthescanwhereweleftoff.
Ifthisiszero,oranullstring,itmeansresumethescan
by advancing to the next ARGV-element. */
staticchar *nextchar;
/* Callers store zero here to inhibit the error message
for unrecognized options. */
int gnu_opterr = 1;
/* Set to an option character which was unrecognized. Thismustbeinitializedonsomesystemstoavoidlinkinginthe
system's own gnu_getopt implementation. */
int gnu_optopt = '?';
/* Describe how to deal with options that follow non-option ARGV-elements.
Thespecialargument`--'forcesanendofoption-scanningregardless ofthevalueof`ordering'.InthecaseofRETURN_IN_ORDER,only
`--' can cause `gnu_getopt' to return -1 with `gnu_optind' != ARGC. */
/* Value of POSIXLY_CORRECT environment variable. */ staticchar *posixly_correct;
/* Avoid depending on library functions or files
whose names are inconsistent. */
staticchar *
my_index( constchar* str, int chr ) { while ( *str ) { if ( *str == chr ) return(char *) str;
str++;
} return0;
}
/* Handle permutation of arguments. */
/* Describe the part of ARGV that contains non-options that have beenskipped.`first_nonopt'istheindexinARGVofthefirstofthem;
`last_nonopt' is the index after the last of them. */
staticint first_nonopt; staticint last_nonopt;
/* Exchange two adjacent subsequences of ARGV. Onesubsequenceiselements[first_nonopt,last_nonopt) whichcontainsallthenon-optionsthathavebeenskippedsofar. Theotheriselements[last_nonopt,gnu_optind),whichcontainsall theoptionsprocessedsincethosenon-optionswereskipped.
`first_nonopt'and`last_nonopt'arerelocatedsothattheydescribe
the new indices of the non-options in ARGV after they are moved. */
staticvoid exchange( char **argv );
staticvoid
exchange( char **argv ) { int bottom = first_nonopt; int middle = last_nonopt; int top = gnu_optind; char *tem;
/* Exchange the shorter segment with the far end of the longer segment. Thatputstheshortersegmentintotherightplace. Itleavesthelongersegmentintherightplaceoverall,
but it consists of two parts that need to be swapped next. */
while ( top > middle && middle > bottom ) { if ( top - middle > middle - bottom ) { /* Bottom segment is the short one. */ int len = middle - bottom; registerint i;
/* Swap it with the top part of the top segment. */ for ( i = 0; i < len; i++ ) {
tem = argv[bottom + i];
argv[bottom + i] = argv[top - (middle - bottom) + i];
argv[top - (middle - bottom) + i] = tem;
} /* Exclude the moved bottom segment from further swapping. */
top -= len;
} else { /* Top segment is the short one. */ int len = top - middle; registerint i;
/* Swap it with the bottom part of the bottom segment. */ for ( i = 0; i < len; i++ ) {
tem = argv[bottom + i];
argv[bottom + i] = argv[middle + i];
argv[middle + i] = tem;
} /* Exclude the moved top segment from further swapping. */
bottom += len;
}
}
/* Update records for the slots the non-options now occupy. */
int
_gnu_getopt_internal( int argc, char *const *argv, constchar *optstring, conststruct option *longopts, int *longind, int long_only ) {
gnu_optarg = NULL;
if ( !__gnu_getopt_initialized || gnu_optind == 0 ) {
optstring = _gnu_getopt_initialize (argc, argv, optstring);
gnu_optind = 1; /* Don't scan ARGV[0], the program name. */
__gnu_getopt_initialized = 1;
}
/* Test whether ARGV[gnu_optind] points to a non-option argument. Eitheritdoesnothaveoptionsyntax,orthereisanenvironmentflag fromtheshellindicatingitisnotanoption.Thelaterinformation
is only used when the used in the GNU libc. */
if ( nextchar == NULL || *nextchar == '\0' ) { /* 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 > gnu_optind )
last_nonopt = gnu_optind; if ( first_nonopt > gnu_optind )
first_nonopt = gnu_optind;
if ( ordering == PERMUTE ) { /* If we have just processed some options following some non-options,
exchange them so that the options come first. */
/* The special ARGV-element `--' means premature end of options. Skipitlikeanulloption, thenexchangewithpreviousnon-optionsasifitwereanoption,
then skip everything else like a non-option. */
/* If we have done all the ARGV-elements, stop the scan
and back over any non-options that we skipped and permuted. */
if ( gnu_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 )
gnu_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;
gnu_optarg = argv[gnu_optind++]; return1;
}
/* We have found another option-ARGV-element.
Skip the initial punctuation. */
/* Check whether the ARGV-element is a long option. Iflong_onlyandtheARGV-elementhastheform"-f",wherefis avalidshortoption,don'tconsideritanabbreviatedformof alongoptionthatstartswithf.Otherwisetherewouldbeno waytogivethe-fshortoption. Ontheotherhand,ifthere'salongoption"fubar"and theARGV-elementis"-fu",doconsiderthatanabbreviationof thelongoption,justlike"--fu",andnot"-f"witharg"u".
This distinction seems to be the most useful approach. */
if ( longopts != NULL
&& (argv[gnu_optind][1] == '-'
|| (long_only && (argv[gnu_optind][2] || !my_index (optstring, argv[gnu_optind][1])))) ) { char *nameend; conststruct option *p; conststruct 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 ( (unsignedint) (nameend - nextchar)
== (unsignedint) strlen (p->name) ) { /* Exact match found. */
pfound = p;
indfound = option_index;
exact = 1; break;
} elseif ( pfound == NULL ) { /* First nonexact match found. */
pfound = p;
indfound = option_index;
} else /* Second or later nonexact match found. */
ambig = 1;
}
if ( ambig && !exact ) { if ( gnu_opterr )
fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
argv[0], argv[gnu_optind]);
nextchar += strlen (nextchar);
gnu_optind++;
gnu_optopt = 0; return'?';
}
if ( pfound != NULL ) {
option_index = indfound;
gnu_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 )
gnu_optarg = nameend + 1; else { if ( gnu_opterr ) { if ( argv[gnu_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[gnu_optind - 1][0], pfound->name);
}
}
/* Increment `gnu_optind' when we start to process its last character. */ if ( *nextchar == '\0' )
++gnu_optind;
if ( temp == NULL || c == ':' ) { if ( gnu_opterr ) { if ( posixly_correct ) /* 1003.2 specifies the format of this message. */
fprintf (stderr, _("%s: illegal option -- %c\n"),
argv[0], c); else
fprintf (stderr, _("%s: invalid option -- %c\n"),
argv[0], c);
}
gnu_optopt = c; return'?';
} /* Convenience. Treat POSIX -W foo same as long option --foo */ if ( temp[0] == 'W' && temp[1] == ';' ) { char *nameend; conststruct option *p; conststruct option *pfound = NULL; int exact = 0; int ambig = 0; int indfound = 0; int option_index;
/* This is an option that requires an argument. */ if ( *nextchar != '\0' ) {
gnu_optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg,
we must advance to the next element now. */
gnu_optind++;
} elseif ( gnu_optind == argc ) { if ( gnu_opterr ) { /* 1003.2 specifies the format of this message. */
fprintf (stderr, _("%s: option requires an argument -- %c\n"),
argv[0], c);
}
gnu_optopt = c; if ( optstring[0] == ':' )
c = ':'; else
c = '?'; return c;
} else /* We already incremented `gnu_optind' once;
increment it again when taking next ARGV-elt as argument. */
gnu_optarg = argv[gnu_optind++];
/* gnu_optarg is now the argument, see if it's in the
table of longopts. */
for ( nextchar = nameend = gnu_optarg; *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 ( (unsignedint) (nameend - nextchar) == strlen (p->name) ) { /* Exact match found. */
pfound = p;
indfound = option_index;
exact = 1; break;
} elseif ( pfound == NULL ) { /* First nonexact match found. */
pfound = p;
indfound = option_index;
} else /* Second or later nonexact match found. */
ambig = 1;
} if ( ambig && !exact ) { if ( gnu_opterr )
fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
argv[0], argv[gnu_optind]);
nextchar += strlen (nextchar);
gnu_optind++; return'?';
} if ( pfound != NULL ) {
option_index = indfound; 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 )
gnu_optarg = nameend + 1; else { if ( gnu_opterr )
fprintf (stderr, _("\
%s: option `-W %s' doesn't allow an argument\n"),
argv[0], pfound->name);
nextchar += strlen (nextchar); return'?';
}
} elseif ( pfound->has_arg == 1 ) { if ( gnu_optind < argc )
gnu_optarg = argv[gnu_optind++]; else { if ( gnu_opterr )
fprintf (stderr,
_("%s: option `%s' requires an argument\n"),
argv[0], argv[gnu_optind - 1]);
nextchar += strlen (nextchar); return optstring[0] == ':' ? ':' : '?';
}
}
nextchar += strlen (nextchar); if ( longind != NULL )
*longind = option_index; if ( pfound->flag ) {
*(pfound->flag) = pfound->val; return0;
} return pfound->val;
}
nextchar = NULL; return'W'; /* Let the application handle it. */
} if ( temp[1] == ':' ) { if ( temp[2] == ':' ) { /* This is an option that accepts an argument optionally. */ if ( *nextchar != '\0' ) {
gnu_optarg = nextchar;
gnu_optind++;
} else
gnu_optarg = NULL;
nextchar = NULL;
} else { /* This is an option that requires an argument. */ if ( *nextchar != '\0' ) {
gnu_optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg,
we must advance to the next element now. */
gnu_optind++;
} elseif ( gnu_optind == argc ) { if ( gnu_opterr ) { /* 1003.2 specifies the format of this message. */
fprintf (stderr,
_("%s: option requires an argument -- %c\n"),
argv[0], c);
}
gnu_optopt = c; if ( optstring[0] == ':' )
c = ':'; else
c = '?';
} else /* We already incremented `gnu_optind' once;
increment it again when taking next ARGV-elt as argument. */
gnu_optarg = argv[gnu_optind++];
nextchar = NULL;
}
} return c;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.