getopt.c

来自「ftpserver very good sample」· C语言 代码 · 共 194 行

C
194
字号
/* getopt.c *  * Reimplemented in relatively portable code, so that Win32 * and other platforms can share the joy. * * Limitations: *   - Does not rearrange argv[]. That means that options and other *     arguments are parsed in the order in which they apper. *  * Copyright 2000 - 2001 Jarle (jgaa) Aase * Released under Gnu Lesser Public Lisence (LGPL) * * Homepage: http://clib.jgaa.com * Authors homepage: http://www.jgaa.com * Bug-reports: http://support.jgaa.com */#include "StdAfx.h"#ifndef WAR_GETOPT_CLASS#   include "jgaa/getopt.h"    const char *optarg;    int optind, opterr = 1, optopt;#endif#ifdef WAR_GETOPT_CLASS#   define getopt_err GetoptErr#   define getopt_long WarGetopt::GetoptLongint WarGetopt::GetoptErr#else    static int getopt_err#endif    (int ch, int arg, const char *parg){    char varg[2];    optopt = arg;    if (!parg)    {        varg[0] = arg;        varg[1] = 0;        parg = varg;    }    if (opterr) switch (ch)        {        case ':':            fprintf(stderr, "Missing argument for %s\n", parg);            break;        case '?':            fprintf(stderr, "Unknown argument %s\n", parg);            break;        default:            fprintf(stderr, "getopt_err(): internal error\n");        }    return ch;}int getopt_long(int argc,                char * const argv[],                const char *optstring,                const struct option *longopts,                int *longindex){#ifndef WAR_GETOPT_CLASS    static int opt_idx;#endif    char target = 0;    const char *p_arg = NULL, *eq_p = NULL, *p_target = NULL;    unsigned eq_pos = 0;    int opt_longindex, *p_flag;    if (!opt_idx)    {        if (++optind >= argc)        {            optind = argc;            return -1; // End of arguments        }    }    if (opt_idx || ((argv[optind][0] == '-') && (argv[optind][1] != '-')))    {        // Short form        target = argv[optind][++opt_idx];        if (target == 0)        {            opt_idx = 0;            return getopt_long(argc, argv, optstring, longopts, longindex);        }        p_arg = strchr(optstring, target);        if (!p_arg)            return getopt_err('?', target, NULL);        if (*++p_arg == ':')        {            optarg = &argv[optind][opt_idx + 1];            opt_idx = 0;            if (!*optarg)                optarg = NULL;            if (!optarg)            {                if (*++p_arg == ':')                {                    // Ok. Optional argument.                    goto have_target;                }                if (++optind >= argc)                {                    --optind;                    target = ':';                    goto have_target;                }                optarg = argv[optind];                goto have_target;            }        }        if (optarg && !*optarg)            optarg = NULL;have_target:        return target;    }    if (((argv[optind][0] == '-') && (argv[optind][1] == '-')))    {        // Long form        if (!*(p_target = &argv[optind][2]))        {            ++optind;            return -1; /* "--" argument ends parameter parsing */        }        eq_p = strchr(p_target, '=');        eq_pos = eq_p ? eq_p - p_target : strlen(p_target);        // Search for option        for(opt_longindex = 0; longopts[opt_longindex].name ; opt_longindex++)        {            if ((strlen(longopts[opt_longindex].name) >= eq_pos)                    && (longopts[opt_longindex].has_arg                        ? !strncmp(longopts[opt_longindex].name, p_target, eq_pos)                        : !strcmp(longopts[opt_longindex].name, p_target)))            {                if (longindex)                    *longindex = opt_longindex;                if (longopts[opt_longindex].has_arg)                {                    if (eq_p)                    {                        optarg = ++eq_p;                        if (!*optarg)                            return getopt_err(':', 0, longopts[opt_longindex].name);                    }                    else if (longopts[opt_longindex].has_arg == required_argument)                    {                        if ((++optind >= argc)                                || (!*(optarg = argv[optind])))                        {                            --optind;                            return getopt_err(':', 0, longopts[opt_longindex].name);                        }                    }                }                if (longopts[opt_longindex].flag == NULL)                    return longopts[opt_longindex].val;                p_flag = longopts[opt_longindex].flag;                *p_flag = longopts[opt_longindex].val;                return 0;            }        }        return getopt_err('?', 0, p_target);    }    // Not a formal parameter    return -1;}

⌨️ 快捷键说明

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