⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bsd-getopt_long.c

📁 功能强大的ftp服务器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	$OpenBSD: getopt_long.c,v 1.13 2003/06/03 01:52:40 millert Exp $	*//*	$NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $	*//* * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *//*- * Copyright (c) 2000 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Dieter Baron and Thomas Klausner. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *        This product includes software developed by the NetBSD *        Foundation, Inc. and its contributors. * 4. Neither the name of The NetBSD Foundation nor the names of its *    contributors may be used to endorse or promote products derived *    from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */#define IN_GETOPT_LONG_C 1#include <config.h>#include "ftpd.h"#ifndef HAVE_GETOPT_LONG# include "bsd-getopt_long.h"# ifdef WITH_DMALLOC#  include <dmalloc.h># endifint	pure_opterr = 1;		/* if error message should be printed */int	pure_optind = 1;		/* index into parent argv vector */int	pure_optopt = '?';		/* character checked for validity */int	pure_optreset;		/* reset getopt */const char    *pure_optarg;		/* argument associated with option */# define PRINT_ERROR	((pure_opterr) && (*options != ':'))# define FLAG_PERMUTE	0x01	/* permute non-options to the end of argv */# define FLAG_ALLARGS	0x02	/* treat non-options as args to option "-1" */# define FLAG_LONGONLY	0x04	/* operate as pure_pure_getopt_long_only *//* return values */# define	BADCH		(int)'?'# define	BADARG		((*options == ':') ? (int)':' : (int)'?')# define	INORDER 	(int)1# define	EMSG		""static int pure_getopt_internal(int, char * const *, const char *,                                const struct pure_option *, int *, int);static int pure_parse_long_options(char * const *, const char *,                                   const struct pure_option *, int *, int);static int pure_gcd(int, int);static void pure_permute_args(int, int, int, char * const *);static const char *pure_place = EMSG; /* option letter processing *//* XXX: set pure_optreset to 1 rather than these two */static int nonopt_start = -1; /* first non option argument (for permute) */static int nonopt_end = -1;   /* first option after non options (for permute) *//* Error messages */static const char *recargchar = "option requires an argument -- %c";static const char *recargstring = "option requires an argument -- %s";static const char *ambig = "ambiguous option -- %.*s";static const char *noarg = "option doesn't take an argument -- %.*s";static const char *illoptchar = "unknown option -- %c";static const char *illoptstring = "unknown option -- %s";/* * Compute the greatest common divisor of a and b. */static int pure_gcd(int a, int b){    int c;        c = a % b;    while (c != 0) {        a = b;        b = c;        c = a % b;    }        return b;}/* * Exchange the block from nonopt_start to nonopt_end with the block * from nonopt_end to opt_end (keeping the same order of arguments * in each block). */static void pure_permute_args(int panonopt_start, int panonopt_end,                               int opt_end, char * const *nargv){    int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;    char *swap;        /*     * compute lengths of blocks and number and size of cycles     */    nnonopts = panonopt_end - panonopt_start;    nopts = opt_end - panonopt_end;    ncycle = pure_gcd(nnonopts, nopts);    cyclelen = (opt_end - panonopt_start) / ncycle;        for (i = 0; i < ncycle; i++) {        cstart = panonopt_end+i;        pos = cstart;        for (j = 0; j < cyclelen; j++) {            if (pos >= panonopt_end)                pos -= nnonopts;            else                pos += nopts;            swap = nargv[pos];            /* LINTED const cast */            ((char **) nargv)[pos] = nargv[cstart];            /* LINTED const cast */            ((char **)nargv)[cstart] = swap;        }    }}/* * pure_parse_long_options -- *	Parse long options in argc/argv argument vector. * Returns -1 if short_too is set and the option does not match long_options. */static int pure_parse_long_options(char * const *nargv, const char *options,                                   const struct pure_option *long_options,                                   int *idx, int short_too){    const char *current_argv, *has_equal;    size_t current_argv_len;    int i, match;        current_argv = pure_place;    match = -1;        pure_optind++;        if ((has_equal = strchr(current_argv, '=')) != NULL) {        /* argument found (--option=arg) */        current_argv_len = has_equal - current_argv;        has_equal++;    } else        current_argv_len = strlen(current_argv);        for (i = 0; long_options[i].name; i++) {        /* find matching long option */        if (strncmp(current_argv, long_options[i].name,		    current_argv_len))            continue;                if (strlen(long_options[i].name) == current_argv_len) {            /* exact match */            match = i;            break;        }        /*         * If this is a known short option, don't allow         * a partial match of a single character.         */        if (short_too && current_argv_len == 1)            continue;                if (match == -1)	/* partial match */            match = i;        else {            /* ambiguous abbreviation */            if (PRINT_ERROR)                fprintf(stderr, ambig, (int)current_argv_len,                        current_argv);            pure_optopt = 0;            return BADCH;        }    }    if (match != -1) {		/* option found */        if (long_options[match].has_arg == no_argument            && has_equal) {            if (PRINT_ERROR)                fprintf(stderr, noarg, (int)current_argv_len,                        current_argv);            /*             * XXX: GNU sets pure_optopt to val regardless of flag             */            if (long_options[match].flag == NULL)                pure_optopt = long_options[match].val;            else                pure_optopt = 0;            return BADARG;        }        if (long_options[match].has_arg == required_argument ||            long_options[match].has_arg == optional_argument) {            if (has_equal)                pure_optarg = has_equal;            else if (long_options[match].has_arg ==                     required_argument) {                /*                 * optional argument doesn't use next nargv                 */                pure_optarg = nargv[pure_optind++];            }        }        if ((long_options[match].has_arg == required_argument)            && (pure_optarg == NULL)) {            /*             * Missing argument; leading ':' indicates no error             * should be generated.             */            if (PRINT_ERROR)                fprintf(stderr, recargstring,                        current_argv);            /*             * XXX: GNU sets pure_optopt to val regardless of flag             */            if (long_options[match].flag == NULL)                pure_optopt = long_options[match].val;            else                pure_optopt = 0;            --pure_optind;            return BADARG;        }    } else {			/* unknown option */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -