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] == '