zoukankan      html  css  js  c++  java
  • getopt for windows

      Glibc库里有个getopt用于解析命令行参数,挺方便的,下面的是别人从Glibc源码的获取的几个getopt相关的文件,已经将平台相关的修改掉,windows下可以调用,本来是要用没用到就没去看正确性,具体以最新的Glibc源码为准。

      

      1 /*
      2 getopt.c
      3 
      4 Copyright (C) 2012, coreBugZJ, all rights reserved.
      5 
      6 在 Windows 平台下使用 Linux 的 getopt, getopt_long, getopt_long_only 函数。
      7 
      8 修改自 glibc 2.8 中 getopt.c 文件,
      9 */
     10 
     11 
     12 
     13 
     14 /* Getopt for GNU.
     15    NOTE: getopt is part of the C library, so if you don't know what
     16    "Keep this file name-space clean" means, talk to drepper@gnu.org
     17    before changing it!
     18    Copyright (C) 1987-1996,1998-2004,2008 Free Software Foundation, Inc.
     19    This file is part of the GNU C Library.
     20 
     21    The GNU C Library is free software; you can redistribute it and/or
     22    modify it under the terms of the GNU Lesser General Public
     23    License as published by the Free Software Foundation; either
     24    version 2.1 of the License, or (at your option) any later version.
     25 
     26    The GNU C Library is distributed in the hope that it will be useful,
     27    but WITHOUT ANY WARRANTY; without even the implied warranty of
     28    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     29    Lesser General Public License for more details.
     30 
     31    You should have received a copy of the GNU Lesser General Public
     32    License along with the GNU C Library; if not, write to the Free
     33    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     34    02111-1307 USA.  */
     35 
     36 #include <stdio.h>
     37 
     38 /* Comment out all this code if we are using the GNU C Library, and are not
     39    actually compiling the library itself.  This code is part of the GNU C
     40    Library, but also included in many other GNU distributions.  Compiling
     41    and linking in this code is a waste when using the GNU C library
     42    (especially if it is a shared library).  Rather than having every GNU
     43    program understand `configure --with-gnu-libc' and omit the object files,
     44    it is simpler to just do this in the source for each such file.  */
     45 
     46 
     47 #include <string.h>
     48 
     49 #define _(msgid) (msgid)
     50 
     51 
     52 #ifndef attribute_hidden
     53 # define attribute_hidden
     54 #endif
     55 
     56 /* This version of `getopt' appears to the caller like standard Unix `getopt'
     57    but it behaves differently for the user, since it allows the user
     58    to intersperse the options with the other arguments.
     59 
     60    As `getopt' works, it permutes the elements of ARGV so that,
     61    when it is done, all the options precede everything else.  Thus
     62    all application programs are extended to handle flexible argument order.
     63 
     64    Setting the environment variable POSIXLY_CORRECT disables permutation.
     65    Then the behavior is completely standard.
     66 
     67    GNU application programs can use a third alternative mode in which
     68    they can distinguish the relative order of options and other arguments.  */
     69 
     70 #include "getopt.h"
     71 #include "getopt_int.h"
     72 
     73 /* For communication from `getopt' to the caller.
     74    When `getopt' finds an option that takes an argument,
     75    the argument value is returned here.
     76    Also, when `ordering' is RETURN_IN_ORDER,
     77    each non-option ARGV-element is returned here.  */
     78 
     79 char *optarg;
     80 
     81 /* Index in ARGV of the next element to be scanned.
     82    This is used for communication to and from the caller
     83    and for communication between successive calls to `getopt'.
     84 
     85    On entry to `getopt', zero means this is the first call; initialize.
     86 
     87    When `getopt' returns -1, this is the index of the first of the
     88    non-option elements that the caller should itself scan.
     89 
     90    Otherwise, `optind' communicates from one call to the next
     91    how much of ARGV has been scanned so far.  */
     92 
     93 /* 1003.2 says this must be 1 before any call.  */
     94 int optind = 1;
     95 
     96 /* Callers store zero here to inhibit the error message
     97    for unrecognized options.  */
     98 
     99 int opterr = 1;
    100 
    101 /* Set to an option character which was unrecognized.
    102    This must be initialized on some systems to avoid linking in the
    103    system's own getopt implementation.  */
    104 
    105 int optopt = '?';
    106 
    107 /* Keep a global copy of all internal members of getopt_data.  */
    108 
    109 static struct _getopt_data getopt_data;
    110 
    111 
    112 #ifndef getenv
    113 extern char *getenv ();
    114 #endif
    115 
    116  
    117 # define SWAP_FLAGS(ch1, ch2)
    118 
    119 /* Exchange two adjacent subsequences of ARGV.
    120    One subsequence is elements [first_nonopt,last_nonopt)
    121    which contains all the non-options that have been skipped so far.
    122    The other is elements [last_nonopt,optind), which contains all
    123    the options processed since those non-options were skipped.
    124 
    125    `first_nonopt' and `last_nonopt' are relocated so that they describe
    126    the new indices of the non-options in ARGV after they are moved.  */
    127 
    128 static void
    129 exchange (char **argv, struct _getopt_data *d)
    130 {
    131   int bottom = d->__first_nonopt;
    132   int middle = d->__last_nonopt;
    133   int top = d->optind;
    134   char *tem;
    135 
    136   /* Exchange the shorter segment with the far end of the longer segment.
    137      That puts the shorter segment into the right place.
    138      It leaves the longer segment in the right place overall,
    139      but it consists of two parts that need to be swapped next.  */
    140 
    141   while (top > middle && middle > bottom)
    142     {
    143       if (top - middle > middle - bottom)
    144     {
    145       /* Bottom segment is the short one.  */
    146       int len = middle - bottom;
    147       register int i;
    148 
    149       /* Swap it with the top part of the top segment.  */
    150       for (i = 0; i < len; i++)
    151         {
    152           tem = argv[bottom + i];
    153           argv[bottom + i] = argv[top - (middle - bottom) + i];
    154           argv[top - (middle - bottom) + i] = tem;
    155           SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
    156         }
    157       /* Exclude the moved bottom segment from further swapping.  */
    158       top -= len;
    159     }
    160       else
    161     {
    162       /* Top segment is the short one.  */
    163       int len = top - middle;
    164       register int i;
    165 
    166       /* Swap it with the bottom part of the bottom segment.  */
    167       for (i = 0; i < len; i++)
    168         {
    169           tem = argv[bottom + i];
    170           argv[bottom + i] = argv[middle + i];
    171           argv[middle + i] = tem;
    172           SWAP_FLAGS (bottom + i, middle + i);
    173         }
    174       /* Exclude the moved top segment from further swapping.  */
    175       bottom += len;
    176     }
    177     }
    178 
    179   /* Update records for the slots the non-options now occupy.  */
    180 
    181   d->__first_nonopt += (d->optind - d->__last_nonopt);
    182   d->__last_nonopt = d->optind;
    183 }
    184 
    185 /* Initialize the internal data when the first call is made.  */
    186 
    187 static const char *
    188 _getopt_initialize (int argc, char *const *argv, const char *optstring,
    189             struct _getopt_data *d)
    190 {
    191   /* Start processing options with ARGV-element 1 (since ARGV-element 0
    192      is the program name); the sequence of previously skipped
    193      non-option ARGV-elements is empty.  */
    194 
    195   d->__first_nonopt = d->__last_nonopt = d->optind;
    196 
    197   d->__nextchar = NULL;
    198 
    199   d->__posixly_correct = !!getenv ("POSIXLY_CORRECT");
    200 
    201   /* Determine how to handle the ordering of options and nonoptions.  */
    202 
    203   if (optstring[0] == '-')
    204     {
    205       d->__ordering = RETURN_IN_ORDER;
    206       ++optstring;
    207     }
    208   else if (optstring[0] == '+')
    209     {
    210       d->__ordering = REQUIRE_ORDER;
    211       ++optstring;
    212     }
    213   else if (d->__posixly_correct)
    214     d->__ordering = REQUIRE_ORDER;
    215   else
    216     d->__ordering = PERMUTE;
    217 
    218 
    219   return optstring;
    220 }
    221  
    222 /* Scan elements of ARGV (whose length is ARGC) for option characters
    223    given in OPTSTRING.
    224 
    225    If an element of ARGV starts with '-', and is not exactly "-" or "--",
    226    then it is an option element.  The characters of this element
    227    (aside from the initial '-') are option characters.  If `getopt'
    228    is called repeatedly, it returns successively each of the option characters
    229    from each of the option elements.
    230 
    231    If `getopt' finds another option character, it returns that character,
    232    updating `optind' and `nextchar' so that the next call to `getopt' can
    233    resume the scan with the following option character or ARGV-element.
    234 
    235    If there are no more option characters, `getopt' returns -1.
    236    Then `optind' is the index in ARGV of the first ARGV-element
    237    that is not an option.  (The ARGV-elements have been permuted
    238    so that those that are not options now come last.)
    239 
    240    OPTSTRING is a string containing the legitimate option characters.
    241    If an option character is seen that is not listed in OPTSTRING,
    242    return '?' after printing an error message.  If you set `opterr' to
    243    zero, the error message is suppressed but we still return '?'.
    244 
    245    If a char in OPTSTRING is followed by a colon, that means it wants an arg,
    246    so the following text in the same ARGV-element, or the text of the following
    247    ARGV-element, is returned in `optarg'.  Two colons mean an option that
    248    wants an optional arg; if there is text in the current ARGV-element,
    249    it is returned in `optarg', otherwise `optarg' is set to zero.
    250 
    251    If OPTSTRING starts with `-' or `+', it requests different methods of
    252    handling the non-option ARGV-elements.
    253    See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
    254 
    255    Long-named options begin with `--' instead of `-'.
    256    Their names may be abbreviated as long as the abbreviation is unique
    257    or is an exact match for some defined option.  If they have an
    258    argument, it follows the option name in the same ARGV-element, separated
    259    from the option name by a `=', or else the in next ARGV-element.
    260    When `getopt' finds a long-named option, it returns 0 if that option's
    261    `flag' field is nonzero, the value of the option's `val' field
    262    if the `flag' field is zero.
    263 
    264    The elements of ARGV aren't really const, because we permute them.
    265    But we pretend they're const in the prototype to be compatible
    266    with other systems.
    267 
    268    LONGOPTS is a vector of `struct option' terminated by an
    269    element containing a name which is zero.
    270 
    271    LONGIND returns the index in LONGOPT of the long-named option found.
    272    It is only valid when a long-named option has been found by the most
    273    recent call.
    274 
    275    If LONG_ONLY is nonzero, '-' as well as '--' can introduce
    276    long-named options.  */
    277 
    278 int
    279 _getopt_internal_r (int argc, char *const *argv, const char *optstring,
    280             const struct option *longopts, int *longind,
    281             int long_only, struct _getopt_data *d)
    282 {
    283   int print_errors = d->opterr;
    284   if (optstring[0] == ':')
    285     print_errors = 0;
    286 
    287   if (argc < 1)
    288     return -1;
    289 
    290   d->optarg = NULL;
    291 
    292   if (d->optind == 0 || !d->__initialized)
    293     {
    294       if (d->optind == 0)
    295     d->optind = 1;    /* Don't scan ARGV[0], the program name.  */
    296       optstring = _getopt_initialize (argc, argv, optstring, d);
    297       d->__initialized = 1;
    298     }
    299 
    300   /* Test whether ARGV[optind] points to a non-option argument.
    301      Either it does not have option syntax, or there is an environment flag
    302      from the shell indicating it is not an option.  The later information
    303      is only used when the used in the GNU libc.  */
    304 # define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '')
    305 
    306   if (d->__nextchar == NULL || *d->__nextchar == '')
    307     {
    308       /* Advance to the next ARGV-element.  */
    309 
    310       /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
    311      moved back by the user (who may also have changed the arguments).  */
    312       if (d->__last_nonopt > d->optind)
    313     d->__last_nonopt = d->optind;
    314       if (d->__first_nonopt > d->optind)
    315     d->__first_nonopt = d->optind;
    316 
    317       if (d->__ordering == PERMUTE)
    318     {
    319       /* If we have just processed some options following some non-options,
    320          exchange them so that the options come first.  */
    321 
    322       if (d->__first_nonopt != d->__last_nonopt
    323           && d->__last_nonopt != d->optind)
    324         exchange ((char **) argv, d);
    325       else if (d->__last_nonopt != d->optind)
    326         d->__first_nonopt = d->optind;
    327 
    328       /* Skip any additional non-options
    329          and extend the range of non-options previously skipped.  */
    330 
    331       while (d->optind < argc && NONOPTION_P)
    332         d->optind++;
    333       d->__last_nonopt = d->optind;
    334     }
    335 
    336       /* The special ARGV-element `--' means premature end of options.
    337      Skip it like a null option,
    338      then exchange with previous non-options as if it were an option,
    339      then skip everything else like a non-option.  */
    340 
    341       if (d->optind != argc && !strcmp (argv[d->optind], "--"))
    342     {
    343       d->optind++;
    344 
    345       if (d->__first_nonopt != d->__last_nonopt
    346           && d->__last_nonopt != d->optind)
    347         exchange ((char **) argv, d);
    348       else if (d->__first_nonopt == d->__last_nonopt)
    349         d->__first_nonopt = d->optind;
    350       d->__last_nonopt = argc;
    351 
    352       d->optind = argc;
    353     }
    354 
    355       /* If we have done all the ARGV-elements, stop the scan
    356      and back over any non-options that we skipped and permuted.  */
    357 
    358       if (d->optind == argc)
    359     {
    360       /* Set the next-arg-index to point at the non-options
    361          that we previously skipped, so the caller will digest them.  */
    362       if (d->__first_nonopt != d->__last_nonopt)
    363         d->optind = d->__first_nonopt;
    364       return -1;
    365     }
    366 
    367       /* If we have come to a non-option and did not permute it,
    368      either stop the scan or describe it to the caller and pass it by.  */
    369 
    370       if (NONOPTION_P)
    371     {
    372       if (d->__ordering == REQUIRE_ORDER)
    373         return -1;
    374       d->optarg = argv[d->optind++];
    375       return 1;
    376     }
    377 
    378       /* We have found another option-ARGV-element.
    379      Skip the initial punctuation.  */
    380 
    381       d->__nextchar = (argv[d->optind] + 1
    382           + (longopts != NULL && argv[d->optind][1] == '-'));
    383     }
    384 
    385   /* Decode the current option-ARGV-element.  */
    386 
    387   /* Check whether the ARGV-element is a long option.
    388 
    389      If long_only and the ARGV-element has the form "-f", where f is
    390      a valid short option, don't consider it an abbreviated form of
    391      a long option that starts with f.  Otherwise there would be no
    392      way to give the -f short option.
    393 
    394      On the other hand, if there's a long option "fubar" and
    395      the ARGV-element is "-fu", do consider that an abbreviation of
    396      the long option, just like "--fu", and not "-f" with arg "u".
    397 
    398      This distinction seems to be the most useful approach.  */
    399 
    400   if (longopts != NULL
    401       && (argv[d->optind][1] == '-'
    402       || (long_only && (argv[d->optind][2]
    403                 || !strchr (optstring, argv[d->optind][1])))))
    404     {
    405       char *nameend;
    406       const struct option *p;
    407       const struct option *pfound = NULL;
    408       int exact = 0;
    409       int ambig = 0;
    410       int indfound = -1;
    411       int option_index;
    412 
    413       for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++)
    414     /* Do nothing.  */ ;
    415 
    416       /* Test all long options for either exact match
    417      or abbreviated matches.  */
    418       for (p = longopts, option_index = 0; p->name; p++, option_index++)
    419     if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
    420       {
    421         if ((unsigned int) (nameend - d->__nextchar)
    422         == (unsigned int) strlen (p->name))
    423           {
    424         /* Exact match found.  */
    425         pfound = p;
    426         indfound = option_index;
    427         exact = 1;
    428         break;
    429           }
    430         else if (pfound == NULL)
    431           {
    432         /* First nonexact match found.  */
    433         pfound = p;
    434         indfound = option_index;
    435           }
    436         else if (long_only
    437              || pfound->has_arg != p->has_arg
    438              || pfound->flag != p->flag
    439              || pfound->val != p->val)
    440           /* Second or later nonexact match found.  */
    441           ambig = 1;
    442       }
    443 
    444       if (ambig && !exact)
    445     {
    446       if (print_errors)
    447         {
    448           fprintf (stderr, _("%s: option '%s' is ambiguous
    "),
    449                argv[0], argv[d->optind]);
    450         }
    451       d->__nextchar += strlen (d->__nextchar);
    452       d->optind++;
    453       d->optopt = 0;
    454       return '?';
    455     }
    456 
    457       if (pfound != NULL)
    458     {
    459       option_index = indfound;
    460       d->optind++;
    461       if (*nameend)
    462         {
    463           /* Don't test has_arg with >, because some C compilers don't
    464          allow it to be used on enums.  */
    465           if (pfound->has_arg)
    466         d->optarg = nameend + 1;
    467           else
    468         {
    469           if (print_errors)
    470             {
    471 
    472               if (argv[d->optind - 1][1] == '-')
    473             {
    474               /* --option */
    475               fprintf (stderr, _("
    476 %s: option '--%s' doesn't allow an argument
    "),
    477                    argv[0], pfound->name);
    478             }
    479               else
    480             {
    481               /* +option or -option */
    482               fprintf (stderr, _("
    483 %s: option '%c%s' doesn't allow an argument
    "),
    484                    argv[0], argv[d->optind - 1][0],
    485                    pfound->name);
    486             }
    487 
    488             }
    489 
    490           d->__nextchar += strlen (d->__nextchar);
    491 
    492           d->optopt = pfound->val;
    493           return '?';
    494         }
    495         }
    496       else if (pfound->has_arg == 1)
    497         {
    498           if (d->optind < argc)
    499         d->optarg = argv[d->optind++];
    500           else
    501         {
    502           if (print_errors)
    503             {
    504               fprintf (stderr,
    505                    _("%s: option '%s' requires an argument
    "),
    506                    argv[0], argv[d->optind - 1]);
    507             }
    508           d->__nextchar += strlen (d->__nextchar);
    509           d->optopt = pfound->val;
    510           return optstring[0] == ':' ? ':' : '?';
    511         }
    512         }
    513       d->__nextchar += strlen (d->__nextchar);
    514       if (longind != NULL)
    515         *longind = option_index;
    516       if (pfound->flag)
    517         {
    518           *(pfound->flag) = pfound->val;
    519           return 0;
    520         }
    521       return pfound->val;
    522     }
    523 
    524       /* Can't find it as a long option.  If this is not getopt_long_only,
    525      or the option starts with '--' or is not a valid short
    526      option, then it's an error.
    527      Otherwise interpret it as a short option.  */
    528       if (!long_only || argv[d->optind][1] == '-'
    529       || strchr (optstring, *d->__nextchar) == NULL)
    530     {
    531       if (print_errors)
    532         {
    533 
    534           if (argv[d->optind][1] == '-')
    535         {
    536           /* --option */
    537           fprintf (stderr, _("%s: unrecognized option '--%s'
    "),
    538                argv[0], d->__nextchar);
    539         }
    540           else
    541         {
    542           /* +option or -option */
    543           fprintf (stderr, _("%s: unrecognized option '%c%s'
    "),
    544                argv[0], argv[d->optind][0], d->__nextchar);
    545         }
    546 
    547         }
    548       d->__nextchar = (char *) "";
    549       d->optind++;
    550       d->optopt = 0;
    551       return '?';
    552     }
    553     }
    554 
    555   /* Look at and handle the next short option-character.  */
    556 
    557   {
    558     char c = *d->__nextchar++;
    559     char *temp = strchr (optstring, c);
    560 
    561     /* Increment `optind' when we start to process its last character.  */
    562     if (*d->__nextchar == '')
    563       ++d->optind;
    564 
    565     if (temp == NULL || c == ':')
    566       {
    567     if (print_errors)
    568       {
    569 
    570         fprintf (stderr, _("%s: invalid option -- '%c'
    "), argv[0], c);
    571 
    572       }
    573     d->optopt = c;
    574     return '?';
    575       }
    576     /* Convenience. Treat POSIX -W foo same as long option --foo */
    577     if (temp[0] == 'W' && temp[1] == ';')
    578       {
    579     char *nameend;
    580     const struct option *p;
    581     const struct option *pfound = NULL;
    582     int exact = 0;
    583     int ambig = 0;
    584     int indfound = 0;
    585     int option_index;
    586 
    587     /* This is an option that requires an argument.  */
    588     if (*d->__nextchar != '')
    589       {
    590         d->optarg = d->__nextchar;
    591         /* If we end this ARGV-element by taking the rest as an arg,
    592            we must advance to the next element now.  */
    593         d->optind++;
    594       }
    595     else if (d->optind == argc)
    596       {
    597         if (print_errors)
    598           {
    599         fprintf (stderr,
    600              _("%s: option requires an argument -- '%c'
    "),
    601              argv[0], c);
    602           }
    603         d->optopt = c;
    604         if (optstring[0] == ':')
    605           c = ':';
    606         else
    607           c = '?';
    608         return c;
    609       }
    610     else
    611       /* We already incremented `d->optind' once;
    612          increment it again when taking next ARGV-elt as argument.  */
    613       d->optarg = argv[d->optind++];
    614 
    615     /* optarg is now the argument, see if it's in the
    616        table of longopts.  */
    617 
    618     for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '=';
    619          nameend++)
    620       /* Do nothing.  */ ;
    621 
    622     /* Test all long options for either exact match
    623        or abbreviated matches.  */
    624     for (p = longopts, option_index = 0; p->name; p++, option_index++)
    625       if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
    626         {
    627           if ((unsigned int) (nameend - d->__nextchar) == strlen (p->name))
    628         {
    629           /* Exact match found.  */
    630           pfound = p;
    631           indfound = option_index;
    632           exact = 1;
    633           break;
    634         }
    635           else if (pfound == NULL)
    636         {
    637           /* First nonexact match found.  */
    638           pfound = p;
    639           indfound = option_index;
    640         }
    641           else
    642         /* Second or later nonexact match found.  */
    643         ambig = 1;
    644         }
    645     if (ambig && !exact)
    646       {
    647         if (print_errors)
    648           {
    649         fprintf (stderr, _("%s: option '-W %s' is ambiguous
    "),
    650              argv[0], argv[d->optind]);
    651           }
    652         d->__nextchar += strlen (d->__nextchar);
    653         d->optind++;
    654         return '?';
    655       }
    656     if (pfound != NULL)
    657       {
    658         option_index = indfound;
    659         if (*nameend)
    660           {
    661         /* Don't test has_arg with >, because some C compilers don't
    662            allow it to be used on enums.  */
    663         if (pfound->has_arg)
    664           d->optarg = nameend + 1;
    665         else
    666           {
    667             if (print_errors)
    668               {
    669             fprintf (stderr, _("
    670 %s: option '-W %s' doesn't allow an argument
    "),
    671                  argv[0], pfound->name);
    672               }
    673 
    674             d->__nextchar += strlen (d->__nextchar);
    675             return '?';
    676           }
    677           }
    678         else if (pfound->has_arg == 1)
    679           {
    680         if (d->optind < argc)
    681           d->optarg = argv[d->optind++];
    682         else
    683           {
    684             if (print_errors)
    685               {
    686             fprintf (stderr,
    687                  _("%s: option '%s' requires an argument
    "),
    688                  argv[0], argv[d->optind - 1]);
    689               }
    690             d->__nextchar += strlen (d->__nextchar);
    691             return optstring[0] == ':' ? ':' : '?';
    692           }
    693           }
    694         d->__nextchar += strlen (d->__nextchar);
    695         if (longind != NULL)
    696           *longind = option_index;
    697         if (pfound->flag)
    698           {
    699         *(pfound->flag) = pfound->val;
    700         return 0;
    701           }
    702         return pfound->val;
    703       }
    704       d->__nextchar = NULL;
    705       return 'W';    /* Let the application handle it.   */
    706       }
    707     if (temp[1] == ':')
    708       {
    709     if (temp[2] == ':')
    710       {
    711         /* This is an option that accepts an argument optionally.  */
    712         if (*d->__nextchar != '')
    713           {
    714         d->optarg = d->__nextchar;
    715         d->optind++;
    716           }
    717         else
    718           d->optarg = NULL;
    719         d->__nextchar = NULL;
    720       }
    721     else
    722       {
    723         /* This is an option that requires an argument.  */
    724         if (*d->__nextchar != '')
    725           {
    726         d->optarg = d->__nextchar;
    727         /* If we end this ARGV-element by taking the rest as an arg,
    728            we must advance to the next element now.  */
    729         d->optind++;
    730           }
    731         else if (d->optind == argc)
    732           {
    733         if (print_errors)
    734           {
    735             fprintf (stderr,
    736                  _("%s: option requires an argument -- '%c'
    "),
    737                  argv[0], c);
    738           }
    739         d->optopt = c;
    740         if (optstring[0] == ':')
    741           c = ':';
    742         else
    743           c = '?';
    744           }
    745         else
    746           /* We already incremented `optind' once;
    747          increment it again when taking next ARGV-elt as argument.  */
    748           d->optarg = argv[d->optind++];
    749         d->__nextchar = NULL;
    750       }
    751       }
    752     return c;
    753   }
    754 }
    755 
    756 int
    757 _getopt_internal (int argc, char *const *argv, const char *optstring,
    758           const struct option *longopts, int *longind, int long_only)
    759 {
    760   int result;
    761 
    762   getopt_data.optind = optind;
    763   getopt_data.opterr = opterr;
    764 
    765   result = _getopt_internal_r (argc, argv, optstring, longopts,
    766                    longind, long_only, &getopt_data);
    767 
    768   optind = getopt_data.optind;
    769   optarg = getopt_data.optarg;
    770   optopt = getopt_data.optopt;
    771 
    772   return result;
    773 }
    774 
    775 int
    776 getopt (int argc, char *const *argv, const char *optstring)
    777 {
    778   return _getopt_internal (argc, argv, optstring,
    779                (const struct option *) 0,
    780                (int *) 0,
    781                0);
    782 }
      1 /*
      2 getopt.h
      3 
      4 Copyright (C) 2012, coreBugZJ, all rights reserved.
      5 
      6 在 Windows 平台下使用 Linux 的 getopt, getopt_long, getopt_long_only 函数。
      7 
      8 修改自 glibc 2.8 中 getopt.h 文件,
      9 */
     10 
     11 
     12 
     13 
     14 /* Declarations for getopt.
     15    Copyright (C) 1989-1994,1996-1999,2001,2003,2004
     16    Free Software Foundation, Inc.
     17    This file is part of the GNU C Library.
     18 
     19    The GNU C Library is free software; you can redistribute it and/or
     20    modify it under the terms of the GNU Lesser General Public
     21    License as published by the Free Software Foundation; either
     22    version 2.1 of the License, or (at your option) any later version.
     23 
     24    The GNU C Library is distributed in the hope that it will be useful,
     25    but WITHOUT ANY WARRANTY; without even the implied warranty of
     26    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     27    Lesser General Public License for more details.
     28 
     29    You should have received a copy of the GNU Lesser General Public
     30    License along with the GNU C Library; if not, write to the Free
     31    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     32    02111-1307 USA.  */
     33 
     34 #ifndef _GETOPT_H
     35 #define _GETOPT_H 1
     36 
     37 /* If __GNU_LIBRARY__ is not already defined, either we are being used
     38    standalone, or this is the first header included in the source file.
     39    If we are being used with glibc, we need to include <features.h>, but
     40    that does not exist if we are standalone.  So: if __GNU_LIBRARY__ is
     41    not defined, include <ctype.h>, which will pull in <features.h> for us
     42    if it's from glibc.  (Why ctype.h?  It's guaranteed to exist and it
     43    doesn't flood the namespace with stuff the way some other headers do.)  */
     44 #include <ctype.h>
     45 
     46 
     47 #ifdef    __cplusplus
     48 extern "C" {
     49 #endif
     50 
     51 /* For communication from `getopt' to the caller.
     52    When `getopt' finds an option that takes an argument,
     53    the argument value is returned here.
     54    Also, when `ordering' is RETURN_IN_ORDER,
     55    each non-option ARGV-element is returned here.  */
     56 
     57 extern char *optarg;
     58 
     59 /* Index in ARGV of the next element to be scanned.
     60    This is used for communication to and from the caller
     61    and for communication between successive calls to `getopt'.
     62 
     63    On entry to `getopt', zero means this is the first call; initialize.
     64 
     65    When `getopt' returns -1, this is the index of the first of the
     66    non-option elements that the caller should itself scan.
     67 
     68    Otherwise, `optind' communicates from one call to the next
     69    how much of ARGV has been scanned so far.  */
     70 
     71 extern int optind;
     72 
     73 /* Callers store zero here to inhibit the error message `getopt' prints
     74    for unrecognized options.  */
     75 
     76 extern int opterr;
     77 
     78 /* Set to an option character which was unrecognized.  */
     79 
     80 extern int optopt;
     81 
     82 /* Describe the long-named options requested by the application.
     83    The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
     84    of `struct option' terminated by an element containing a name which is
     85    zero.
     86 
     87    The field `has_arg' is:
     88    no_argument        (or 0) if the option does not take an argument,
     89    required_argument    (or 1) if the option requires an argument,
     90    optional_argument     (or 2) if the option takes an optional argument.
     91 
     92    If the field `flag' is not NULL, it points to a variable that is set
     93    to the value given in the field `val' when the option is found, but
     94    left unchanged if the option is not found.
     95 
     96    To have a long-named option do something other than set an `int' to
     97    a compiled-in constant, such as set a value from `optarg', set the
     98    option's `flag' field to zero and its `val' field to a nonzero
     99    value (the equivalent single-letter option character, if there is
    100    one).  For long options that have a zero `flag' field, `getopt'
    101    returns the contents of the `val' field.  */
    102 
    103 struct option
    104 {
    105   const char *name;
    106   /* has_arg can't be an enum because some compilers complain about
    107      type mismatches in all the code that assumes it is an int.  */
    108   int has_arg;
    109   int *flag;
    110   int val;
    111 };
    112 
    113 /* Names for the values of the `has_arg' field of `struct option'.  */
    114 
    115 #define no_argument        0
    116 #define required_argument    1
    117 #define optional_argument    2
    118 
    119 
    120 /* Get definitions and prototypes for functions to process the
    121    arguments in ARGV (ARGC of them, minus the program name) for
    122    options given in OPTS.
    123 
    124    Return the option character from OPTS just read.  Return -1 when
    125    there are no more options.  For unrecognized options, or options
    126    missing arguments, `optopt' is set to the option letter, and '?' is
    127    returned.
    128 
    129    The OPTS string is a list of characters which are recognized option
    130    letters, optionally followed by colons, specifying that that letter
    131    takes an argument, to be placed in `optarg'.
    132 
    133    If a letter in OPTS is followed by two colons, its argument is
    134    optional.  This behavior is specific to the GNU `getopt'.
    135 
    136    The argument `--' causes premature termination of argument
    137    scanning, explicitly telling `getopt' that there are no more
    138    options.
    139 
    140    If OPTS begins with `--', then non-option arguments are treated as
    141    arguments to the option ''.  This behavior is specific to the GNU
    142    `getopt'.  */
    143 
    144 /* Many other libraries have conflicting prototypes for getopt, with
    145    differences in the consts, in stdlib.h.  To avoid compilation
    146    errors, only prototype getopt for the GNU C library.  */
    147 extern int getopt (int ___argc, char *const *___argv, const char *__shortopts);
    148 
    149 extern int getopt_long (int ___argc, char *const *___argv,
    150             const char *__shortopts,
    151                 const struct option *__longopts, int *__longind);
    152 
    153 extern int getopt_long_only (int ___argc, char *const *___argv,
    154                  const char *__shortopts,
    155                      const struct option *__longopts, int *__longind);
    156 
    157 
    158 #ifdef    __cplusplus
    159 }
    160 #endif
    161 
    162 
    163 #endif /* getopt.h */
      1 /*
      2 getopt_int.h
      3 
      4 Copyright (C) 2012, coreBugZJ, all rights reserved.
      5 
      6 在 Windows 平台下使用 Linux 的 getopt, getopt_long, getopt_long_only 函数。
      7 
      8 修改自 glibc 2.8 中 getopt_int.h 文件,
      9 */
     10 
     11 
     12 
     13 
     14 
     15 /* Internal declarations for getopt.
     16    Copyright (C) 1989-1994,1996-1999,2001,2003,2004
     17    Free Software Foundation, Inc.
     18    This file is part of the GNU C Library.
     19 
     20    The GNU C Library is free software; you can redistribute it and/or
     21    modify it under the terms of the GNU Lesser General Public
     22    License as published by the Free Software Foundation; either
     23    version 2.1 of the License, or (at your option) any later version.
     24 
     25    The GNU C Library is distributed in the hope that it will be useful,
     26    but WITHOUT ANY WARRANTY; without even the implied warranty of
     27    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     28    Lesser General Public License for more details.
     29 
     30    You should have received a copy of the GNU Lesser General Public
     31    License along with the GNU C Library; if not, write to the Free
     32    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     33    02111-1307 USA.  */
     34 
     35 #ifndef _GETOPT_INT_H
     36 #define _GETOPT_INT_H    1
     37 
     38 extern int _getopt_internal (int ___argc, char *const *___argv,
     39                  const char *__shortopts,
     40                      const struct option *__longopts, int *__longind,
     41                  int __long_only);
     42 
     43  
     44 /* Reentrant versions which can handle parsing multiple argument
     45    vectors at the same time.  */
     46 
     47 /* Data type for reentrant functions.  */
     48 struct _getopt_data
     49 {
     50   /* These have exactly the same meaning as the corresponding global
     51      variables, except that they are used for the reentrant
     52      versions of getopt.  */
     53   int optind;
     54   int opterr;
     55   int optopt;
     56   char *optarg;
     57 
     58   /* Internal members.  */
     59 
     60   /* True if the internal members have been initialized.  */
     61   int __initialized;
     62 
     63   /* The next char to be scanned in the option-element
     64      in which the last option character we returned was found.
     65      This allows us to pick up the scan where we left off.
     66 
     67      If this is zero, or a null string, it means resume the scan
     68      by advancing to the next ARGV-element.  */
     69   char *__nextchar;
     70 
     71   /* Describe how to deal with options that follow non-option ARGV-elements.
     72 
     73      If the caller did not specify anything,
     74      the default is REQUIRE_ORDER if the environment variable
     75      POSIXLY_CORRECT is defined, PERMUTE otherwise.
     76 
     77      REQUIRE_ORDER means don't recognize them as options;
     78      stop option processing when the first non-option is seen.
     79      This is what Unix does.
     80      This mode of operation is selected by either setting the environment
     81      variable POSIXLY_CORRECT, or using `+' as the first character
     82      of the list of option characters.
     83 
     84      PERMUTE is the default.  We permute the contents of ARGV as we
     85      scan, so that eventually all the non-options are at the end.
     86      This allows options to be given in any order, even with programs
     87      that were not written to expect this.
     88 
     89      RETURN_IN_ORDER is an option available to programs that were
     90      written to expect options and other ARGV-elements in any order
     91      and that care about the ordering of the two.  We describe each
     92      non-option ARGV-element as if it were the argument of an option
     93      with character code 1.  Using `-' as the first character of the
     94      list of option characters selects this mode of operation.
     95 
     96      The special argument `--' forces an end of option-scanning regardless
     97      of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
     98      `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
     99 
    100   enum
    101     {
    102       REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
    103     } __ordering;
    104 
    105   /* If the POSIXLY_CORRECT environment variable is set.  */
    106   int __posixly_correct;
    107 
    108 
    109   /* Handle permutation of arguments.  */
    110 
    111   /* Describe the part of ARGV that contains non-options that have
    112      been skipped.  `first_nonopt' is the index in ARGV of the first
    113      of them; `last_nonopt' is the index after the last of them.  */
    114 
    115   int __first_nonopt;
    116   int __last_nonopt;
    117 };
    118 
    119 /* The initializer is necessary to set OPTIND and OPTERR to their
    120    default values and to clear the initialization flag.  */
    121 #define _GETOPT_DATA_INITIALIZER    { 1, 1 }
    122 
    123 extern int _getopt_internal_r (int ___argc, char *const *___argv,
    124                    const char *__shortopts,
    125                    const struct option *__longopts, int *__longind,
    126                    int __long_only, struct _getopt_data *__data);
    127 
    128 extern int _getopt_long_r (int ___argc, char *const *___argv,
    129                const char *__shortopts,
    130                const struct option *__longopts, int *__longind,
    131                struct _getopt_data *__data);
    132 
    133 extern int _getopt_long_only_r (int ___argc, char *const *___argv,
    134                 const char *__shortopts,
    135                 const struct option *__longopts,
    136                 int *__longind,
    137                 struct _getopt_data *__data);
    138 
    139 #endif /* getopt_int.h */
     1 /*
     2 getopt1.c
     3 
     4 Copyright (C) 2012, coreBugZJ, all rights reserved.
     5 
     6 在 Windows 平台下使用 Linux 的 getopt, getopt_long, getopt_long_only 函数。
     7 
     8 修改自 glibc 2.8 中 getopt1.c 文件,
     9 */
    10 
    11 
    12 
    13 
    14 
    15 
    16 /* getopt_long and getopt_long_only entry points for GNU getopt.
    17    Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98,2004
    18      Free Software Foundation, Inc.
    19    This file is part of the GNU C Library.
    20 
    21    The GNU C Library is free software; you can redistribute it and/or
    22    modify it under the terms of the GNU Lesser General Public
    23    License as published by the Free Software Foundation; either
    24    version 2.1 of the License, or (at your option) any later version.
    25 
    26    The GNU C Library is distributed in the hope that it will be useful,
    27    but WITHOUT ANY WARRANTY; without even the implied warranty of
    28    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    29    Lesser General Public License for more details.
    30 
    31    You should have received a copy of the GNU Lesser General Public
    32    License along with the GNU C Library; if not, write to the Free
    33    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    34    02111-1307 USA.  */
    35 
    36 
    37 #include "getopt.h"
    38 #include "getopt_int.h"
    39 
    40 
    41 int
    42 getopt_long (int argc, char *const *argv, const char *options,
    43          const struct option *long_options, int *opt_index)
    44 {
    45   return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
    46 }
    47 
    48 int
    49 _getopt_long_r (int argc, char *const *argv, const char *options,
    50         const struct option *long_options, int *opt_index,
    51         struct _getopt_data *d)
    52 {
    53   return _getopt_internal_r (argc, argv, options, long_options, opt_index,
    54                  0, d);
    55 }
    56 
    57 /* Like getopt_long, but '-' as well as '--' can indicate a long option.
    58    If an option that starts with '-' (not '--') doesn't match a long option,
    59    but does match a short option, it is parsed as a short option
    60    instead.  */
    61 
    62 int
    63 getopt_long_only (int argc, char *const *argv, const char *options,
    64           const struct option *long_options, int *opt_index)
    65 {
    66   return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
    67 }
    68 
    69 int
    70 _getopt_long_only_r (int argc, char *const *argv, const char *options,
    71              const struct option *long_options, int *opt_index,
    72              struct _getopt_data *d)
    73 {
    74   return _getopt_internal_r (argc, argv, options, long_options, opt_index,
    75                  1, d);
    76 }
      1 /*
      2 test_getopt.c
      3 
      4 Copyright (C) 2012, coreBugZJ, all rights reserved.
      5 
      6 在 Windows 平台下使用 Linux 的 getopt, getopt_long, getopt_long_only 函数。
      7 
      8 修改自 glibc 2.8 中 getopt.c 文件,
      9 */
     10 
     11 
     12 #include <stdio.h>
     13 #include "getopt.h"
     14 
     15 
     16 
     17 
     18 static void usage()
     19 {
     20     printf("
    No Usage
    ");
     21 }
     22 
     23 //具体应用根据实际情况修改
     24 static void conf_cmdline(int argc, char **argv)
     25 {
     26     int c;
     27 
     28     /* 
     29      * getopt作为选项的判断,getopt_long可以指定长参数
     30      * 
     31      */
     32     while ((c = getopt(argc, argv, "e:l:m:")) != EOF)
     33         switch (c) {
     34         case 'l':
     35             printf("c
    ");
     36             break;
     37         case 'm':
     38             //TODO:获取参数n表示要获取的符号个数,通过system调用findstr /<Symbol/>将相应的符号行从temp文件中取出
     39             //将取出的数据处理只保留地址保存到Addr文件中。
     40             //通过while(n)来处理每一个argv的符号。
     41 
     42             printf("n
    ");          
     43             break;
     44         case 'e':
     45             //TODO:获取ELF文件,调用system("nm.exe -n elf > temp.txt")将符号表保存到temp文件中,
     46 
     47             break;
     48         default:
     49             //列出命令行使用方法
     50             usage();
     51         //退出函数
     52             exit(1);
     53         }
     54     //多线程时需要重新恢复初值
     55     optind = 1;
     56 }
     57 
     58 void main(int argc, char **argv)
     59 {
     60     conf_cmdline(argc, argv);    
     61 }
     62 
     63 
     64 /*
     65 int main (int argc, char **argv)
     66 {
     67         int c;
     68         int digit_optind = 0;
     69 
     70         while (1)
     71         {
     72                 int this_option_optind = optind ? optind : 1;
     73                 int option_index = 0;
     74                 static struct option long_options[] =
     75                 {
     76                         {"add", 1, 0, 0},
     77                         {"append", 0, 0, 0},
     78                         {"delete", 1, 0, 0},
     79                         {"verbose", 0, 0, 0},
     80                         {"create", 0, 0, 0},
     81                         {"file", 1, 0, 0},
     82                         {0, 0, 0, 0}
     83                 };
     84 
     85                 c = getopt_long (argc, argv, "abc:d:0123456789",
     86                         long_options, &option_index);
     87                 if (c == -1)
     88                         break;
     89 
     90                 switch (c)
     91                 {
     92                 case 0:
     93                         printf ("option %s", long_options[option_index].name);
     94                         if (optarg)
     95                                 printf (" with arg %s", optarg);
     96                         printf ("
    ");
     97                         break;
     98 
     99                 case '0':
    100                 case '1':
    101                 case '2':
    102                 case '3':
    103                 case '4':
    104                 case '5':
    105                 case '6':
    106                 case '7':
    107                 case '8':
    108                 case '9':
    109                         if (digit_optind != 0 && digit_optind != this_option_optind)
    110                                 printf ("digits occur in two different argv-elements.
    ");
    111                         digit_optind = this_option_optind;
    112                         printf ("option %c
    ", c);
    113                         break;
    114 
    115                 case 'a':
    116                         printf ("option a
    ");
    117                         break;
    118 
    119                 case 'b':
    120                         printf ("option b
    ");
    121                         break;
    122 
    123                 case 'c':
    124                         printf ("option c with value `%s'
    ", optarg);
    125                         break;
    126 
    127                 case 'd':
    128                         printf ("option d with value `%s'
    ", optarg);
    129                         break;
    130 
    131                 case '?':
    132                         break;
    133 
    134                 default:
    135                         printf ("?? getopt returned character code 0%o ??
    ", c);
    136                 }
    137         }
    138 
    139         if (optind < argc)
    140         {
    141                 printf ("non-option ARGV-elements: ");
    142                 while (optind < argc)
    143                         printf ("%s ", argv[optind++]);
    144                 printf ("
    ");
    145         }
    146 
    147         return 0;
    148 }
    149 */
  • 相关阅读:
    微信小程序使用canvas画布实现当前页面截屏并分享
    微信小程序分享转发用法大全——自定义分享、全局分享、组合分享
    小程序条形码插件wxbarcode的使用及改进
    支付宝小程序开发——修改小程序原生radio默认样式
    常用maven配置
    Android Studio 星云常用配置工具箱
    星云最佳实践功法秘籍
    Intellij Idea 星云常用配置工具箱
    那些好用的Chrome 插件
    星云的Linux专用学习手册
  • 原文地址:https://www.cnblogs.com/gt-xy/p/7955702.html
Copyright © 2011-2022 走看看