getopt_long.c (126692) | getopt_long.c (127733) |
---|---|
1/* $OpenBSD: getopt_long.c,v 1.16 2004/02/04 18:17:25 millert Exp $ */ 2/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ 3 4/* 5 * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above --- 48 unchanged lines hidden (view full) --- 57 */ 58 59#if 0 60#if defined(LIBC_SCCS) && !defined(lint) 61static char *rcsid = "$OpenBSD: getopt_long.c,v 1.16 2004/02/04 18:17:25 millert Exp $"; 62#endif /* LIBC_SCCS and not lint */ 63#endif 64#include <sys/cdefs.h> | 1/* $OpenBSD: getopt_long.c,v 1.16 2004/02/04 18:17:25 millert Exp $ */ 2/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ 3 4/* 5 * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above --- 48 unchanged lines hidden (view full) --- 57 */ 58 59#if 0 60#if defined(LIBC_SCCS) && !defined(lint) 61static char *rcsid = "$OpenBSD: getopt_long.c,v 1.16 2004/02/04 18:17:25 millert Exp $"; 62#endif /* LIBC_SCCS and not lint */ 63#endif 64#include <sys/cdefs.h> |
65__FBSDID("$FreeBSD: head/lib/libc/stdlib/getopt_long.c 126692 2004-03-06 14:24:10Z ache $"); | 65__FBSDID("$FreeBSD: head/lib/libc/stdlib/getopt_long.c 127733 2004-04-01 22:09:07Z ache $"); |
66 67#include <err.h> 68#include <errno.h> 69#include <getopt.h> 70#include <stdlib.h> 71#include <string.h> 72 73#define GNU_COMPATIBLE /* Be more compatible, configure's use us! */ --- 28 unchanged lines hidden (view full) --- 102#define D_PREFIX 0 103#define DD_PREFIX 1 104#define W_PREFIX 2 105#endif 106 107static int getopt_internal(int, char * const *, const char *, 108 const struct option *, int *, int); 109static int parse_long_options(char * const *, const char *, | 66 67#include <err.h> 68#include <errno.h> 69#include <getopt.h> 70#include <stdlib.h> 71#include <string.h> 72 73#define GNU_COMPATIBLE /* Be more compatible, configure's use us! */ --- 28 unchanged lines hidden (view full) --- 102#define D_PREFIX 0 103#define DD_PREFIX 1 104#define W_PREFIX 2 105#endif 106 107static int getopt_internal(int, char * const *, const char *, 108 const struct option *, int *, int); 109static int parse_long_options(char * const *, const char *, |
110 const struct option *, int *, int); | 110 const struct option *, int *, int, int); |
111static int gcd(int, int); 112static void permute_args(int, int, int, char * const *); 113 114static char *place = EMSG; /* option letter processing */ 115 116/* XXX: set optreset to 1 rather than these two */ 117static int nonopt_start = -1; /* first non option argument (for permute) */ 118static int nonopt_end = -1; /* first option after non options (for permute) */ --- 73 unchanged lines hidden (view full) --- 192 193/* 194 * parse_long_options -- 195 * Parse long options in argc/argv argument vector. 196 * Returns -1 if short_too is set and the option does not match long_options. 197 */ 198static int 199parse_long_options(char * const *nargv, const char *options, | 111static int gcd(int, int); 112static void permute_args(int, int, int, char * const *); 113 114static char *place = EMSG; /* option letter processing */ 115 116/* XXX: set optreset to 1 rather than these two */ 117static int nonopt_start = -1; /* first non option argument (for permute) */ 118static int nonopt_end = -1; /* first option after non options (for permute) */ --- 73 unchanged lines hidden (view full) --- 192 193/* 194 * parse_long_options -- 195 * Parse long options in argc/argv argument vector. 196 * Returns -1 if short_too is set and the option does not match long_options. 197 */ 198static int 199parse_long_options(char * const *nargv, const char *options, |
200 const struct option *long_options, int *idx, int short_too) | 200 const struct option *long_options, int *idx, int short_too, int flags) |
201{ 202 char *current_argv, *has_equal; 203#ifdef GNU_COMPATIBLE 204 char *current_dash; 205#endif 206 size_t current_argv_len; | 201{ 202 char *current_argv, *has_equal; 203#ifdef GNU_COMPATIBLE 204 char *current_dash; 205#endif 206 size_t current_argv_len; |
207 int i, match; | 207 int i, match, exact_match, second_partial_match; |
208 209 current_argv = place; 210#ifdef GNU_COMPATIBLE 211 switch (dash_prefix) { 212 case D_PREFIX: 213 current_dash = "-"; 214 break; 215 case DD_PREFIX: 216 current_dash = "--"; 217 break; 218 case W_PREFIX: 219 current_dash = "-W "; 220 break; 221 default: 222 current_dash = ""; 223 break; 224 } 225#endif 226 match = -1; | 208 209 current_argv = place; 210#ifdef GNU_COMPATIBLE 211 switch (dash_prefix) { 212 case D_PREFIX: 213 current_dash = "-"; 214 break; 215 case DD_PREFIX: 216 current_dash = "--"; 217 break; 218 case W_PREFIX: 219 current_dash = "-W "; 220 break; 221 default: 222 current_dash = ""; 223 break; 224 } 225#endif 226 match = -1; |
227 exact_match = 0; 228 second_partial_match = 0; |
|
227 228 optind++; 229 230 if ((has_equal = strchr(current_argv, '=')) != NULL) { 231 /* argument found (--option=arg) */ 232 current_argv_len = has_equal - current_argv; 233 has_equal++; 234 } else 235 current_argv_len = strlen(current_argv); 236 237 for (i = 0; long_options[i].name; i++) { 238 /* find matching long option */ 239 if (strncmp(current_argv, long_options[i].name, 240 current_argv_len)) 241 continue; 242 243 if (strlen(long_options[i].name) == current_argv_len) { 244 /* exact match */ 245 match = i; | 229 230 optind++; 231 232 if ((has_equal = strchr(current_argv, '=')) != NULL) { 233 /* argument found (--option=arg) */ 234 current_argv_len = has_equal - current_argv; 235 has_equal++; 236 } else 237 current_argv_len = strlen(current_argv); 238 239 for (i = 0; long_options[i].name; i++) { 240 /* find matching long option */ 241 if (strncmp(current_argv, long_options[i].name, 242 current_argv_len)) 243 continue; 244 245 if (strlen(long_options[i].name) == current_argv_len) { 246 /* exact match */ 247 match = i; |
248 exact_match = 1; |
|
246 break; 247 } 248 /* 249 * If this is a known short option, don't allow 250 * a partial match of a single character. 251 */ | 249 break; 250 } 251 /* 252 * If this is a known short option, don't allow 253 * a partial match of a single character. 254 */ |
252 if (short_too && current_argv_len == 1) | 255 if (short_too && 256 (!(flags & FLAG_LONGONLY) || current_argv_len == 1)) |
253 continue; 254 | 257 continue; 258 |
255 if (match == -1) /* partial match */ | 259 if (match == -1) /* first partial match */ |
256 match = i; | 260 match = i; |
257 else { 258 /* ambiguous abbreviation */ 259 if (PRINT_ERROR) 260 warnx(ambig, | 261 else if ((flags & FLAG_LONGONLY) || 262 long_options[i].has_arg != 263 long_options[match].has_arg || 264 long_options[i].flag != long_options[match].flag || 265 long_options[i].val != long_options[match].val) 266 second_partial_match = 1; 267 } 268 if (!exact_match && second_partial_match) { 269 /* ambiguous abbreviation */ 270 if (PRINT_ERROR) 271 warnx(ambig, |
261#ifdef GNU_COMPATIBLE | 272#ifdef GNU_COMPATIBLE |
262 current_dash, | 273 current_dash, |
263#endif | 274#endif |
264 (int)current_argv_len, 265 current_argv); 266 optopt = 0; 267 return (BADCH); 268 } | 275 (int)current_argv_len, 276 current_argv); 277 optopt = 0; 278 return (BADCH); |
269 } 270 if (match != -1) { /* option found */ 271 if (long_options[match].has_arg == no_argument 272 && has_equal) { 273 if (PRINT_ERROR) 274 warnx(noarg, 275#ifdef GNU_COMPATIBLE 276 current_dash, --- 210 unchanged lines hidden (view full) --- 487 place++; /* --foo long option */ 488#ifdef GNU_COMPATIBLE 489 dash_prefix = DD_PREFIX; 490#endif 491 } else if (*place != ':' && strchr(options, *place) != NULL) 492 short_too = 1; /* could be short option too */ 493 494 optchar = parse_long_options(nargv, options, long_options, | 279 } 280 if (match != -1) { /* option found */ 281 if (long_options[match].has_arg == no_argument 282 && has_equal) { 283 if (PRINT_ERROR) 284 warnx(noarg, 285#ifdef GNU_COMPATIBLE 286 current_dash, --- 210 unchanged lines hidden (view full) --- 497 place++; /* --foo long option */ 498#ifdef GNU_COMPATIBLE 499 dash_prefix = DD_PREFIX; 500#endif 501 } else if (*place != ':' && strchr(options, *place) != NULL) 502 short_too = 1; /* could be short option too */ 503 504 optchar = parse_long_options(nargv, options, long_options, |
495 idx, short_too); | 505 idx, short_too, flags); |
496 if (optchar != -1) { 497 place = EMSG; 498 return (optchar); 499 } 500 } 501 502 if ((optchar = (int)*place++) == (int)':' || 503 (optchar == (int)'-' && *place != '\0') || --- 29 unchanged lines hidden (view full) --- 533 optopt = optchar; 534 return (BADARG); 535 } else /* white space */ 536 place = nargv[optind]; 537#ifdef GNU_COMPATIBLE 538 dash_prefix = W_PREFIX; 539#endif 540 optchar = parse_long_options(nargv, options, long_options, | 506 if (optchar != -1) { 507 place = EMSG; 508 return (optchar); 509 } 510 } 511 512 if ((optchar = (int)*place++) == (int)':' || 513 (optchar == (int)'-' && *place != '\0') || --- 29 unchanged lines hidden (view full) --- 543 optopt = optchar; 544 return (BADARG); 545 } else /* white space */ 546 place = nargv[optind]; 547#ifdef GNU_COMPATIBLE 548 dash_prefix = W_PREFIX; 549#endif 550 optchar = parse_long_options(nargv, options, long_options, |
541 idx, 0); | 551 idx, 0, flags); |
542 place = EMSG; 543 return (optchar); 544 } 545 if (*++oli != ':') { /* doesn't take argument */ 546 if (!*place) 547 ++optind; 548 } else { /* takes (optional) argument */ 549 optarg = NULL; --- 83 unchanged lines hidden --- | 552 place = EMSG; 553 return (optchar); 554 } 555 if (*++oli != ':') { /* doesn't take argument */ 556 if (!*place) 557 ++optind; 558 } else { /* takes (optional) argument */ 559 optarg = NULL; --- 83 unchanged lines hidden --- |