Hash :
bd543f03
Author :
Date :
1991-12-13T00:00:00
The Independent JPEG Group's JPEG software v2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
/*
* egetopt.c -- Extended 'getopt'.
*
* A while back, a public-domain version of getopt() was posted to the
* net. A bit later, a gentleman by the name of Keith Bostic made some
* enhancements and reposted it.
*
* In recent weeks (i.e., early-to-mid 1988) there's been some
* heated discussion in comp.lang.c about the merits and drawbacks
* of getopt(), especially with regard to its handling of '?'.
*
* In light of this, I have taken Mr. Bostic's public-domain getopt()
* and have made some changes that I hope will be considered to be
* improvements. I call this routine 'egetopt' ("Extended getopt").
* The default behavior of this routine is the same as that of getopt(),
* but it has some optional features that make it more useful. These
* options are controlled by the settings of some global variables.
* By not setting any of these extra global variables, you will have
* the same functionality as getopt(), which should satisfy those
* purists who believe getopt() is perfect and can never be improved.
* If, on the other hand, you are someone who isn't satisfied with the
* status quo, egetopt() may very well give you the added capabilities
* you want.
*
* Look at the enclosed README file for a description of egetopt()'s
* new features.
*
* The code was originally posted to the net as getopt.c by ...
*
* Keith Bostic
* ARPA: keith@seismo
* UUCP: seismo!keith
*
* Current version: added enhancements and comments, reformatted code.
*
* Lloyd Zusman
* Master Byte Software
* Los Gatos, California
* Internet: ljz@fx.com
* UUCP: ...!ames!fxgrp!ljz
*
* May, 1988
*
* Modified for use in free JPEG code:
*
* Ed Hanway
* UUCP: uunet!sisd!jeh
*
* October, 1991
*/
/* The original egetopt.c was written not to need stdio.h.
* For the JPEG code this is an unnecessary and unportable assumption.
* Also, we make all the variables and routines "static" to avoid
* possible conflicts with a system-library version of getopt.
*
* In the JPEG code, this file is compiled by #including it in jcmain.c
* or jdmain.c. Since ANSI2KNR does not process include files, we can't
* rely on it to convert function definitions to K&R style. Hence we
* provide both styles of function header with an explicit #ifdef PROTO (ick).
*/
#define GVAR static /* make empty to export these variables */
/*
* None of these constants are referenced in the executable portion of
* the code ... their sole purpose is to initialize global variables.
*/
#define BADCH (int)'?'
#define NEEDSEP (int)':'
#define MAYBESEP (int)'\0'
#define EMSG ""
#define START "-"
/*
* Here are all the pertinent global variables.
*/
GVAR int opterr = 1; /* if true, output error message */
GVAR int optind = 1; /* index into parent argv vector */
GVAR int optopt; /* character checked for validity */
GVAR int optbad = BADCH; /* character returned on error */
GVAR int optchar = 0; /* character that begins returned option */
GVAR int optneed = NEEDSEP; /* flag for mandatory argument */
GVAR int optmaybe = MAYBESEP; /* flag for optional argument */
GVAR const char *optarg; /* argument associated with option */
GVAR const char *optstart = START; /* list of characters that start options */
/*
* Macros.
*/
/*
* Conditionally print out an error message and return (depends on the
* setting of 'opterr').
*/
#define TELL(S) { \
if (opterr) \
fprintf(stderr, "%s%s%c\n", *nargv, (S), optopt); \
return (optbad); \
}
/*
* This works similarly to index() and strchr(). I include it so that you
* don't need to be concerned as to which one your system has.
*/
#ifdef PROTO
LOCAL const char *
_sindex (const char *string, int ch)
#else
LOCAL const char *
_sindex (string, ch)
const char *string;
int ch;
#endif
{
if (string != NULL) {
for (; *string != '\0'; ++string) {
if (*string == (char)ch) {
return (string);
}
}
}
return (NULL);
}
/*
* Here it is:
*/
#ifdef PROTO
LOCAL int
egetopt (int nargc, char **nargv, const char *ostr)
#else
LOCAL int
egetopt (nargc, nargv, ostr)
int nargc;
char **nargv;
const char *ostr;
#endif
{
static const char *place = EMSG; /* option letter processing */
register const char *oli; /* option letter list index */
register const char *osi = NULL; /* option start list index */
if (nargv == (char **)NULL) {
return (EOF);
}
if (nargc <= optind || nargv[optind] == NULL) {
return (EOF);
}
if (place == NULL) {
place = EMSG;
}
/*
* Update scanning pointer.
*/
if (*place == '\0') {
place = nargv[optind];
if (place == NULL) {
return (EOF);
}
osi = _sindex(optstart, *place);
if (osi != NULL) {
optchar = (int)*osi;
}
if (optind >= nargc || osi == NULL || *++place == '\0') {
return (EOF);
}
/*
* Two adjacent, identical flag characters were found.
* This takes care of "--", for example.
*/
if (*place == place[-1]) {
++optind;
return (EOF);
}
}
/*
* If the option is a separator or the option isn't in the list,
* we've got an error.
*/
optopt = (int)*place++;
oli = _sindex(ostr, optopt);
if (optopt == optneed || optopt == optmaybe || oli == NULL) {
/*
* If we're at the end of the current argument, bump the
* argument index.
*/
if (*place == '\0') {
++optind;
}
TELL(": illegal option -- "); /* byebye */
}
/*
* If there is no argument indicator, then we don't even try to
* return an argument.
*/
++oli;
if (*oli == '\0' || (*oli != optneed && *oli != optmaybe)) {
/*
* If we're at the end of the current argument, bump the
* argument index.
*/
if (*place == '\0') {
++optind;
}
optarg = NULL;
}
/*
* If we're here, there's an argument indicator. It's handled
* differently depending on whether it's a mandatory or an
* optional argument.
*/
else {
/*
* If there's no white space, use the rest of the
* string as the argument. In this case, it doesn't
* matter if the argument is mandatory or optional.
*/
if (*place != '\0') {
optarg = place;
}
/*
* If we're here, there's whitespace after the option.
*
* Is it a mandatory argument? If so, return the
* next command-line argument if there is one.
*/
else if (*oli == optneed) {
/*
* If we're at the end of the argument list, there
* isn't an argument and hence we have an error.
* Otherwise, make 'optarg' point to the argument.
*/
if (nargc <= ++optind) {
place = EMSG;
TELL(": option requires an argument -- ");
}
else {
optarg = nargv[optind];
}
}
/*
* If we're here it must have been an optional argument.
*/
else {
if (nargc <= ++optind) {
place = EMSG;
optarg = NULL;
}
else {
optarg = nargv[optind];
if (optarg == NULL) {
place = EMSG;
}
/*
* If the next item begins with a flag
* character, we treat it like a new
* argument. This is accomplished by
* decrementing 'optind' and returning
* a null argument.
*/
else if (_sindex(optstart, *optarg) != NULL) {
--optind;
optarg = NULL;
}
}
}
place = EMSG;
++optind;
}
/*
* Return option letter.
*/
return (optopt);
}