📄 bsd-getopt_long.c
字号:
if (short_too) { --pure_optind; return -1; } if (PRINT_ERROR) fprintf(stderr, illoptstring, current_argv); pure_optopt = 0; return BADCH; } if (idx) *idx = match; if (long_options[match].flag) { *long_options[match].flag = long_options[match].val; return 0; } else return long_options[match].val;}/* * getopt_internal -- * Parse argc/argv argument vector. Called by user level routines. */static int pure_getopt_internal(int nargc, char * const *nargv, const char *options, const struct pure_option *long_options, int *idx, int flags){ char *oli; /* option letter list index */ int optchar, short_too; static int posixly_correct = -1; if (options == NULL) return -1; /* * Disable GNU extensions if POSIXLY_CORRECT is set or options * string begins with a '+'. */ if (posixly_correct == -1) posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); if (posixly_correct || *options == '+') flags &= ~FLAG_PERMUTE; else if (*options == '-') flags |= FLAG_ALLARGS; if (*options == '+' || *options == '-') options++; /* * XXX Some GNU programs (like cvs) set pure_optind to 0 instead of * XXX using pure_optreset. Work around this braindamage. */ if (pure_optind == 0) pure_optind = pure_optreset = 1; pure_optarg = NULL; if (pure_optreset) nonopt_start = nonopt_end = -1; start: if (pure_optreset || !*pure_place) { /* update scanning pointer */ pure_optreset = 0; if (pure_optind >= nargc) { /* end of argument vector */ pure_place = EMSG; if (nonopt_end != -1) { /* do permutation, if we have to */ pure_permute_args(nonopt_start, nonopt_end, pure_optind, nargv); pure_optind -= nonopt_end - nonopt_start; } else if (nonopt_start != -1) { /* * If we skipped non-options, set pure_optind * to the first of them. */ pure_optind = nonopt_start; } nonopt_start = nonopt_end = -1; return -1; } if (*(pure_place = nargv[pure_optind]) != '-' || (pure_place[1] == '\0' && strchr(options, '-') == NULL)) { pure_place = EMSG; /* found non-option */ if (flags & FLAG_ALLARGS) { /* * GNU extension: * return non-option as argument to option 1 */ pure_optarg = nargv[pure_optind++]; return INORDER; } if (!(flags & FLAG_PERMUTE)) { /* * If no permutation wanted, stop parsing * at first non-option. */ return -1; } /* do permutation */ if (nonopt_start == -1) nonopt_start = pure_optind; else if (nonopt_end != -1) { pure_permute_args(nonopt_start, nonopt_end, pure_optind, nargv); nonopt_start = pure_optind - (nonopt_end - nonopt_start); nonopt_end = -1; } pure_optind++; /* process next argument */ goto start; } if (nonopt_start != -1 && nonopt_end == -1) nonopt_end = pure_optind; /* * Check for "--" or "--foo" with no long options * but if pure_place is simply "-" leave it unmolested. */ if (pure_place[1] != '\0' && *++pure_place == '-' && (pure_place[1] == '\0' || long_options == NULL)) { pure_optind++; pure_place = EMSG; /* * We found an option (--), so if we skipped * non-options, we have to permute. */ if (nonopt_end != -1) { pure_permute_args(nonopt_start, nonopt_end, pure_optind, nargv); pure_optind -= nonopt_end - nonopt_start; } nonopt_start = nonopt_end = -1; return -1; } } /* * Check long options if: * 1) we were passed some * 2) the arg is not just "-" * 3) either the arg starts with -- we are pure_pure_getopt_long_only() */ if (long_options != NULL && pure_place != nargv[pure_optind] && (*pure_place == '-' || (flags & FLAG_LONGONLY))) { short_too = 0; if (*pure_place == '-') pure_place++; /* --foo long option */ else if (*pure_place != ':' && strchr(options, *pure_place) != NULL) short_too = 1; /* could be short option too */ optchar = pure_parse_long_options(nargv, options, long_options, idx, short_too); if (optchar != -1) { pure_place = EMSG; return optchar; } } if ((optchar = (int)*pure_place++) == (int)':' || (oli = strchr(options, optchar)) == NULL) { /* * If the user didn't specify '-' as an option, * assume it means -1 as POSIX specifies. */ if (optchar == (int)'-') return -1; /* option letter unknown or ':' */ if (!*pure_place) ++pure_optind; if (PRINT_ERROR) fprintf(stderr, illoptchar, optchar); pure_optopt = optchar; return BADCH; } if (long_options != NULL && optchar == 'W' && oli[1] == ';') { /* -W long-option */ if (*pure_place) /* no space */ /* NOTHING */; else if (++pure_optind >= nargc) { /* no arg */ pure_place = EMSG; if (PRINT_ERROR) fprintf(stderr, recargchar, optchar); pure_optopt = optchar; return BADARG; } else /* white space */ pure_place = nargv[pure_optind]; optchar = pure_parse_long_options(nargv, options, long_options, idx, 0); pure_place = EMSG; return optchar; } if (*++oli != ':') { /* doesn't take argument */ if (!*pure_place) ++pure_optind; } else { /* takes (optional) argument */ pure_optarg = NULL; if (*pure_place) /* no white space */ pure_optarg = pure_place; /* XXX: disable test for :: if PC? (GNU doesn't) */ else if (oli[1] != ':') { /* arg not optional */ if (++pure_optind >= nargc) { /* no arg */ pure_place = EMSG; if (PRINT_ERROR) fprintf(stderr, recargchar, optchar); pure_optopt = optchar; return BADARG; } else pure_optarg = nargv[pure_optind]; } pure_place = EMSG; ++pure_optind; } /* dump back option letter */ return optchar;}/* * getopt -- * Parse argc/argv argument vector. */int pure_getopt(int nargc, char * const *nargv, const char *options){ /* * We dont' pass FLAG_PERMUTE to pure_getopt_internal() since * the BSD getopt(3) (unlike GNU) has never done this. * * Furthermore, since many privileged programs call getopt() * before dropping privileges it makes sense to keep things * as simple (and bug-free) as possible. */ return pure_getopt_internal(nargc, nargv, options, NULL, NULL, 0);}/* * pure_getopt_long -- * Parse argc/argv argument vector. */int pure_getopt_long(int nargc, char * const *nargv, const char *options, const struct pure_option *long_options, int *idx){ return pure_getopt_internal(nargc, nargv, options, long_options, idx, FLAG_PERMUTE);}/* * pure_pure_getopt_long_only -- * Parse argc/argv argument vector. */int pure_pure_getopt_long_only(int nargc, char * const *nargv, const char *options, const struct pure_option *long_options, int *idx){ return pure_getopt_internal(nargc, nargv, options, long_options, idx, FLAG_PERMUTE|FLAG_LONGONLY);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -