忘记了上次在哪里找到这个功能库,只有一个 .h 和 .c 文件,再次搜索的时候发现找不到了,结果只能在之前的代码中,两个文件提出使用,顾将这两个文件备份在这里。
1 /* Getopt for Microsoft C 2 This code is a modification of the Free Software Foundation, Inc. 3 Getopt library for parsing command line argument the purpose was 4 to provide a Microsoft Visual C friendly derivative. This code 5 provides functionality for both Unicode and Multibyte builds. 6 7 Date: 02/03/2011 - Ludvik Jerabek - Initial Release 8 Version: 1.0 9 Comment: Supports getopt, getopt_long, and getopt_long_only 10 and POSIXLY_CORRECT environment flag 11 License: LGPL 12 13 Revisions: 14 15 02/03/2011 - Ludvik Jerabek - Initial Release 16 02/20/2011 - Ludvik Jerabek - Fixed compiler warnings at Level 4 17 07/05/2011 - Ludvik Jerabek - Added no_argument, required_argument, optional_argument defs 18 08/03/2011 - Ludvik Jerabek - Fixed non-argument runtime bug which caused runtime exception 19 08/09/2011 - Ludvik Jerabek - Added code to export functions for DLL and LIB 20 02/15/2012 - Ludvik Jerabek - Fixed _GETOPT_THROW definition missing in implementation file 21 08/01/2012 - Ludvik Jerabek - Created separate functions for char and wchar_t characters so single dll can do both unicode and ansi 22 10/15/2012 - Ludvik Jerabek - Modified to match latest GNU features 23 06/19/2015 - Ludvik Jerabek - Fixed maximum option limitation caused by option_a (255) and option_w (65535) structure val variable 24 25 **DISCLAIMER** 26 THIS MATERIAL IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 27 EITHER EXPRESS OR IMPLIED, INCLUDING, BUT Not LIMITED TO, THE 28 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 29 PURPOSE, OR NON-INFRINGEMENT. SOME JURISDICTIONS DO NOT ALLOW THE 30 EXCLUSION OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY NOT 31 APPLY TO YOU. IN NO EVENT WILL I BE LIABLE TO ANY PARTY FOR ANY 32 DIRECT, INDIRECT, SPECIAL OR OTHER CONSEQUENTIAL DAMAGES FOR ANY 33 USE OF THIS MATERIAL INCLUDING, WITHOUT LIMITATION, ANY LOST 34 PROFITS, BUSINESS INTERRUPTION, LOSS OF PROGRAMS OR OTHER DATA ON 35 YOUR INFORMATION HANDLING SYSTEM OR OTHERWISE, EVEN If WE ARE 36 EXPRESSLY ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 37 */ 38 #ifndef __GETOPT_H_ 39 #define __GETOPT_H_ 40 41 #ifdef _GETOPT_API 42 #undef _GETOPT_API 43 #endif 44 45 #if defined(EXPORTS_GETOPT) && defined(STATIC_GETOPT) 46 #error "The preprocessor definitions of EXPORTS_GETOPT and STATIC_GETOPT can only be used individually" 47 #elif defined(STATIC_GETOPT) 48 #pragma message("Warning static builds of getopt violate the Lesser GNU Public License") 49 #define _GETOPT_API 50 #elif defined(EXPORTS_GETOPT) 51 #pragma message("Exporting getopt library") 52 #define _GETOPT_API __declspec(dllexport) 53 #else 54 #pragma message("Importing getopt library") 55 #define _GETOPT_API __declspec(dllimport) 56 #endif 57 58 // Change behavior for C\C++ 59 #ifdef __cplusplus 60 #define _BEGIN_EXTERN_C extern "C" { 61 #define _END_EXTERN_C } 62 #define _GETOPT_THROW throw() 63 #else 64 #define _BEGIN_EXTERN_C 65 #define _END_EXTERN_C 66 #define _GETOPT_THROW 67 #endif 68 69 // Standard GNU options 70 #define null_argument 0 /*Argument Null*/ 71 #define no_argument 0 /*Argument Switch Only*/ 72 #define required_argument 1 /*Argument Required*/ 73 #define optional_argument 2 /*Argument Optional*/ 74 75 // Shorter Options 76 #define ARG_NULL 0 /*Argument Null*/ 77 #define ARG_NONE 0 /*Argument Switch Only*/ 78 #define ARG_REQ 1 /*Argument Required*/ 79 #define ARG_OPT 2 /*Argument Optional*/ 80 81 #include <string.h> 82 #include <wchar.h> 83 84 _BEGIN_EXTERN_C 85 86 extern _GETOPT_API int optind; 87 extern _GETOPT_API int opterr; 88 extern _GETOPT_API int optopt; 89 90 // Ansi 91 struct option_a 92 { 93 const char* name; 94 int has_arg; 95 int *flag; 96 int val; 97 }; 98 extern _GETOPT_API char *optarg_a; 99 extern _GETOPT_API int getopt_a(int argc, char *const *argv, const char *optstring) _GETOPT_THROW; 100 extern _GETOPT_API int getopt_long_a(int argc, char *const *argv, const char *options, const struct option_a *long_options, int *opt_index) _GETOPT_THROW; 101 extern _GETOPT_API int getopt_long_only_a(int argc, char *const *argv, const char *options, const struct option_a *long_options, int *opt_index) _GETOPT_THROW; 102 103 // Unicode 104 struct option_w 105 { 106 const wchar_t* name; 107 int has_arg; 108 int *flag; 109 int val; 110 }; 111 extern _GETOPT_API wchar_t *optarg_w; 112 extern _GETOPT_API int getopt_w(int argc, wchar_t *const *argv, const wchar_t *optstring) _GETOPT_THROW; 113 extern _GETOPT_API int getopt_long_w(int argc, wchar_t *const *argv, const wchar_t *options, const struct option_w *long_options, int *opt_index) _GETOPT_THROW; 114 extern _GETOPT_API int getopt_long_only_w(int argc, wchar_t *const *argv, const wchar_t *options, const struct option_w *long_options, int *opt_index) _GETOPT_THROW; 115 116 _END_EXTERN_C 117 118 #undef _BEGIN_EXTERN_C 119 #undef _END_EXTERN_C 120 #undef _GETOPT_THROW 121 #undef _GETOPT_API 122 123 #ifdef _UNICODE 124 #define getopt getopt_w 125 #define getopt_long getopt_long_w 126 #define getopt_long_only getopt_long_only_w 127 #define option option_w 128 #define optarg optarg_w 129 #else 130 #define getopt getopt_a 131 #define getopt_long getopt_long_a 132 #define getopt_long_only getopt_long_only_a 133 #define option option_a 134 #define optarg optarg_a 135 #endif 136 #endif // __GETOPT_H_
1 /* Getopt for Microsoft C 2 This code is a modification of the Free Software Foundation, Inc. 3 Getopt library for parsing command line argument the purpose was 4 to provide a Microsoft Visual C friendly derivative. This code 5 provides functionality for both Unicode and Multibyte builds. 6 7 Date: 02/03/2011 - Ludvik Jerabek - Initial Release 8 Version: 1.0 9 Comment: Supports getopt, getopt_long, and getopt_long_only 10 and POSIXLY_CORRECT environment flag 11 License: LGPL 12 13 Revisions: 14 15 02/03/2011 - Ludvik Jerabek - Initial Release 16 02/20/2011 - Ludvik Jerabek - Fixed compiler warnings at Level 4 17 07/05/2011 - Ludvik Jerabek - Added no_argument, required_argument, optional_argument defs 18 08/03/2011 - Ludvik Jerabek - Fixed non-argument runtime bug which caused runtime exception 19 08/09/2011 - Ludvik Jerabek - Added code to export functions for DLL and LIB 20 02/15/2012 - Ludvik Jerabek - Fixed _GETOPT_THROW definition missing in implementation file 21 08/01/2012 - Ludvik Jerabek - Created separate functions for char and wchar_t characters so single dll can do both unicode and ansi 22 10/15/2012 - Ludvik Jerabek - Modified to match latest GNU features 23 06/19/2015 - Ludvik Jerabek - Fixed maximum option limitation caused by option_a (255) and option_w (65535) structure val variable 24 25 **DISCLAIMER** 26 THIS MATERIAL IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 27 EITHER EXPRESS OR IMPLIED, INCLUDING, BUT Not LIMITED TO, THE 28 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 29 PURPOSE, OR NON-INFRINGEMENT. SOME JURISDICTIONS DO NOT ALLOW THE 30 EXCLUSION OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY NOT 31 APPLY TO YOU. IN NO EVENT WILL I BE LIABLE TO ANY PARTY FOR ANY 32 DIRECT, INDIRECT, SPECIAL OR OTHER CONSEQUENTIAL DAMAGES FOR ANY 33 USE OF THIS MATERIAL INCLUDING, WITHOUT LIMITATION, ANY LOST 34 PROFITS, BUSINESS INTERRUPTION, LOSS OF PROGRAMS OR OTHER DATA ON 35 YOUR INFORMATION HANDLING SYSTEM OR OTHERWISE, EVEN If WE ARE 36 EXPRESSLY ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 37 */ 38 #define _CRT_SECURE_NO_WARNINGS 39 #include <stdlib.h> 40 #include <stdio.h> 41 #include <malloc.h> 42 #include "getopt.h" 43 44 #ifdef __cplusplus 45 #define _GETOPT_THROW throw() 46 #else 47 #define _GETOPT_THROW 48 #endif 49 50 int optind = 1; 51 int opterr = 1; 52 int optopt = ‘?‘; 53 enum ENUM_ORDERING { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER }; 54 55 // 56 // 57 // Ansi structures and functions follow 58 // 59 // 60 61 static struct _getopt_data_a 62 { 63 int optind; 64 int opterr; 65 int optopt; 66 char *optarg; 67 int __initialized; 68 char *__nextchar; 69 enum ENUM_ORDERING __ordering; 70 int __posixly_correct; 71 int __first_nonopt; 72 int __last_nonopt; 73 } getopt_data_a; 74 char *optarg_a; 75 76 static void exchange_a(char **argv, struct _getopt_data_a *d) 77 { 78 int bottom = d->__first_nonopt; 79 int middle = d->__last_nonopt; 80 int top = d->optind; 81 char *tem; 82 while (top > middle && middle > bottom) 83 { 84 if (top - middle > middle - bottom) 85 { 86 int len = middle - bottom; 87 register int i; 88 for (i = 0; i < len; i++) 89 { 90 tem = argv[bottom + i]; 91 argv[bottom + i] = argv[top - (middle - bottom) + i]; 92 argv[top - (middle - bottom) + i] = tem; 93 } 94 top -= len; 95 } 96 else 97 { 98 int len = top - middle; 99 register int i; 100 for (i = 0; i < len; i++) 101 { 102 tem = argv[bottom + i]; 103 argv[bottom + i] = argv[middle + i]; 104 argv[middle + i] = tem; 105 } 106 bottom += len; 107 } 108 } 109 d->__first_nonopt += (d->optind - d->__last_nonopt); 110 d->__last_nonopt = d->optind; 111 } 112 static const char *_getopt_initialize_a (const char *optstring, struct _getopt_data_a *d, int posixly_correct) 113 { 114 d->__first_nonopt = d->__last_nonopt = d->optind; 115 d->__nextchar = NULL; 116 d->__posixly_correct = posixly_correct | !!getenv("POSIXLY_CORRECT"); 117 if (optstring[0] == ‘-‘) 118 { 119 d->__ordering = RETURN_IN_ORDER; 120 ++optstring; 121 } 122 else if (optstring[0] == ‘+‘) 123 { 124 d->__ordering = REQUIRE_ORDER; 125 ++optstring; 126 } 127 else if (d->__posixly_correct) 128 d->__ordering = REQUIRE_ORDER; 129 else 130 d->__ordering = PERMUTE; 131 return optstring; 132 } 133 int _getopt_internal_r_a (int argc, char *const *argv, const char *optstring, const struct option_a *longopts, int *longind, int long_only, struct _getopt_data_a *d, int posixly_correct) 134 { 135 int print_errors = d->opterr; 136 if (argc < 1) 137 return -1; 138 d->optarg = NULL; 139 if (d->optind == 0 || !d->__initialized) 140 { 141 if (d->optind == 0) 142 d->optind = 1; 143 optstring = _getopt_initialize_a (optstring, d, posixly_correct); 144 d->__initialized = 1; 145 } 146 else if (optstring[0] == ‘-‘ || optstring[0] == ‘+‘) 147 optstring++; 148 if (optstring[0] == ‘:‘) 149 print_errors = 0; 150 if (d->__nextchar == NULL || *d->__nextchar == ‘\0‘) 151 { 152 if (d->__last_nonopt > d->optind) 153 d->__last_nonopt = d->optind; 154 if (d->__first_nonopt > d->optind) 155 d->__first_nonopt = d->optind; 156 if (d->__ordering == PERMUTE) 157 { 158 if (d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind) 159 exchange_a ((char **) argv, d); 160 else if (d->__last_nonopt != d->optind) 161 d->__first_nonopt = d->optind; 162 while (d->optind < argc && (argv[d->optind][0] != ‘-‘ || argv[d->optind][1] == ‘\0‘)) 163 d->optind++; 164 d->__last_nonopt = d->optind; 165 } 166 if (d->optind != argc && !strcmp(argv[d->optind], "--")) 167 { 168 d->optind++; 169 if (d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind) 170 exchange_a((char **) argv, d); 171 else if (d->__first_nonopt == d->__last_nonopt) 172 d->__first_nonopt = d->optind; 173 d->__last_nonopt = argc; 174 d->optind = argc; 175 } 176 if (d->optind == argc) 177 { 178 if (d->__first_nonopt != d->__last_nonopt) 179 d->optind = d->__first_nonopt; 180 return -1; 181 } 182 if ((argv[d->optind][0] != ‘-‘ || argv[d->optind][1] == ‘\0‘)) 183 { 184 if (d->__ordering == REQUIRE_ORDER) 185 return -1; 186 d->optarg = argv[d->optind++]; 187 return 1; 188 } 189 d->__nextchar = (argv[d->optind] + 1 + (longopts != NULL && argv[d->optind][1] == ‘-‘)); 190 } 191 if (longopts != NULL && (argv[d->optind][1] == ‘-‘ || (long_only && (argv[d->optind][2] || !strchr(optstring, argv[d->optind][1]))))) 192 { 193 char *nameend; 194 unsigned int namelen; 195 const struct option_a *p; 196 const struct option_a *pfound = NULL; 197 struct option_list 198 { 199 const struct option_a *p; 200 struct option_list *next; 201 } *ambig_list = NULL; 202 int exact = 0; 203 int indfound = -1; 204 int option_index; 205 for (nameend = d->__nextchar; *nameend && *nameend != ‘=‘; nameend++); 206 namelen = (unsigned int)(nameend - d->__nextchar); 207 for (p = longopts, option_index = 0; p->name; p++, option_index++) 208 if (!strncmp(p->name, d->__nextchar, namelen)) 209 { 210 if (namelen == (unsigned int)strlen(p->name)) 211 { 212 pfound = p; 213 indfound = option_index; 214 exact = 1; 215 break; 216 } 217 else if (pfound == NULL) 218 { 219 pfound = p; 220 indfound = option_index; 221 } 222 else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val) 223 { 224 struct option_list *newp = (struct option_list*)alloca(sizeof(*newp)); 225 newp->p = p; 226 newp->next = ambig_list; 227 ambig_list = newp; 228 } 229 } 230 if (ambig_list != NULL && !exact) 231 { 232 if (print_errors) 233 { 234 struct option_list first; 235 first.p = pfound; 236 first.next = ambig_list; 237 ambig_list = &first; 238 fprintf (stderr, "%s: option ‘%s‘ is ambiguous; possibilities:", argv[0], argv[d->optind]); 239 do 240 { 241 fprintf (stderr, " ‘--%s‘", ambig_list->p->name); 242 ambig_list = ambig_list->next; 243 } 244 while (ambig_list != NULL); 245 fputc (‘\n‘, stderr); 246 } 247 d->__nextchar += strlen(d->__nextchar); 248 d->optind++; 249 d->optopt = 0; 250 return ‘?‘; 251 } 252 if (pfound != NULL) 253 { 254 option_index = indfound; 255 d->optind++; 256 if (*nameend) 257 { 258 if (pfound->has_arg) 259 d->optarg = nameend + 1; 260 else 261 { 262 if (print_errors) 263 { 264 if (argv[d->optind - 1][1] == ‘-‘) 265 { 266 fprintf(stderr, "%s: option ‘--%s‘ doesn‘t allow an argument\n",argv[0], pfound->name); 267 } 268 else 269 { 270 fprintf(stderr, "%s: option ‘%c%s‘ doesn‘t allow an argument\n",argv[0], argv[d->optind - 1][0],pfound->name); 271 } 272 } 273 d->__nextchar += strlen(d->__nextchar); 274 d->optopt = pfound->val; 275 return ‘?‘; 276 } 277 } 278 else if (pfound->has_arg == 1) 279 { 280 if (d->optind < argc) 281 d->optarg = argv[d->optind++]; 282 else 283 { 284 if (print_errors) 285 { 286 fprintf(stderr,"%s: option ‘--%s‘ requires an argument\n",argv[0], pfound->name); 287 } 288 d->__nextchar += strlen(d->__nextchar); 289 d->optopt = pfound->val; 290 return optstring[0] == ‘:‘ ? ‘:‘ : ‘?‘; 291 } 292 } 293 d->__nextchar += strlen(d->__nextchar); 294 if (longind != NULL) 295 *longind = option_index; 296 if (pfound->flag) 297 { 298 *(pfound->flag) = pfound->val; 299 return 0; 300 } 301 return pfound->val; 302 } 303 if (!long_only || argv[d->optind][1] == ‘-‘ || strchr(optstring, *d->__nextchar) == NULL) 304 { 305 if (print_errors) 306 { 307 if (argv[d->optind][1] == ‘-‘) 308 { 309 fprintf(stderr, "%s: unrecognized option ‘--%s‘\n",argv[0], d->__nextchar); 310 } 311 else 312 { 313 fprintf(stderr, "%s: unrecognized option ‘%c%s‘\n",argv[0], argv[d->optind][0], d->__nextchar); 314 } 315 } 316 d->__nextchar = (char *)""; 317 d->optind++; 318 d->optopt = 0; 319 return ‘?‘; 320 } 321 } 322 { 323 char c = *d->__nextchar++; 324 char *temp = (char*)strchr(optstring, c); 325 if (*d->__nextchar == ‘\0‘) 326 ++d->optind; 327 if (temp == NULL || c == ‘:‘ || c == ‘;‘) 328 { 329 if (print_errors) 330 { 331 fprintf(stderr, "%s: invalid option -- ‘%c‘\n", argv[0], c); 332 } 333 d->optopt = c; 334 return ‘?‘; 335 } 336 if (temp[0] == ‘W‘ && temp[1] == ‘;‘) 337 { 338 char *nameend; 339 const struct option_a *p; 340 const struct option_a *pfound = NULL; 341 int exact = 0; 342 int ambig = 0; 343 int indfound = 0; 344 int option_index; 345 if (longopts == NULL) 346 goto no_longs; 347 if (*d->__nextchar != ‘\0‘) 348 { 349 d->optarg = d->__nextchar; 350 d->optind++; 351 } 352 else if (d->optind == argc) 353 { 354 if (print_errors) 355 { 356 fprintf(stderr,"%s: option requires an argument -- ‘%c‘\n",argv[0], c); 357 } 358 d->optopt = c; 359 if (optstring[0] == ‘:‘) 360 c = ‘:‘; 361 else 362 c = ‘?‘; 363 return c; 364 } 365 else 366 d->optarg = argv[d->optind++]; 367 for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != ‘=‘; nameend++); 368 for (p = longopts, option_index = 0; p->name; p++, option_index++) 369 if (!strncmp(p->name, d->__nextchar, nameend - d->__nextchar)) 370 { 371 if ((unsigned int) (nameend - d->__nextchar) == strlen(p->name)) 372 { 373 pfound = p; 374 indfound = option_index; 375 exact = 1; 376 break; 377 } 378 else if (pfound == NULL) 379 { 380 pfound = p; 381 indfound = option_index; 382 } 383 else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val) 384 ambig = 1; 385 } 386 if (ambig && !exact) 387 { 388 if (print_errors) 389 { 390 fprintf(stderr, "%s: option ‘-W %s‘ is ambiguous\n",argv[0], d->optarg); 391 } 392 d->__nextchar += strlen(d->__nextchar); 393 d->optind++; 394 return ‘?‘; 395 } 396 if (pfound != NULL) 397 { 398 option_index = indfound; 399 if (*nameend) 400 { 401 if (pfound->has_arg) 402 d->optarg = nameend + 1; 403 else 404 { 405 if (print_errors) 406 { 407 fprintf(stderr, "%s: option ‘-W %s‘ doesn‘t allow an argument\n",argv[0], pfound->name); 408 } 409 d->__nextchar += strlen(d->__nextchar); 410 return ‘?‘; 411 } 412 } 413 else if (pfound->has_arg == 1) 414 { 415 if (d->optind < argc) 416 d->optarg = argv[d->optind++]; 417 else 418 { 419 if (print_errors) 420 { 421 fprintf(stderr, "%s: option ‘-W %s‘ requires an argument\n",argv[0], pfound->name); 422 } 423 d->__nextchar += strlen(d->__nextchar); 424 return optstring[0] == ‘:‘ ? ‘:‘ : ‘?‘; 425 } 426 } 427 else 428 d->optarg = NULL; 429 d->__nextchar += strlen(d->__nextchar); 430 if (longind != NULL) 431 *longind = option_index; 432 if (pfound->flag) 433 { 434 *(pfound->flag) = pfound->val; 435 return 0; 436 } 437 return pfound->val; 438 } 439 no_longs: 440 d->__nextchar = NULL; 441 return ‘W‘; 442 } 443 if (temp[1] == ‘:‘) 444 { 445 if (temp[2] == ‘:‘) 446 { 447 if (*d->__nextchar != ‘\0‘) 448 { 449 d->optarg = d->__nextchar; 450 d->optind++; 451 } 452 else 453 d->optarg = NULL; 454 d->__nextchar = NULL; 455 } 456 else 457 { 458 if (*d->__nextchar != ‘\0‘) 459 { 460 d->optarg = d->__nextchar; 461 d->optind++; 462 } 463 else if (d->optind == argc) 464 { 465 if (print_errors) 466 { 467 fprintf(stderr,"%s: option requires an argument -- ‘%c‘\n",argv[0], c); 468 } 469 d->optopt = c; 470 if (optstring[0] == ‘:‘) 471 c = ‘:‘; 472 else 473 c = ‘?‘; 474 } 475 else 476 d->optarg = argv[d->optind++]; 477 d->__nextchar = NULL; 478 } 479 } 480 return c; 481 } 482 } 483 int _getopt_internal_a (int argc, char *const *argv, const char *optstring, const struct option_a *longopts, int *longind, int long_only, int posixly_correct) 484 { 485 int result; 486 getopt_data_a.optind = optind; 487 getopt_data_a.opterr = opterr; 488 result = _getopt_internal_r_a (argc, argv, optstring, longopts,longind, long_only, &getopt_data_a,posixly_correct); 489 optind = getopt_data_a.optind; 490 optarg_a = getopt_data_a.optarg; 491 optopt = getopt_data_a.optopt; 492 return result; 493 } 494 int getopt_a (int argc, char *const *argv, const char *optstring) _GETOPT_THROW 495 { 496 return _getopt_internal_a (argc, argv, optstring, (const struct option_a *) 0, (int *) 0, 0, 0); 497 } 498 int getopt_long_a (int argc, char *const *argv, const char *options, const struct option_a *long_options, int *opt_index) _GETOPT_THROW 499 { 500 return _getopt_internal_a (argc, argv, options, long_options, opt_index, 0, 0); 501 } 502 int getopt_long_only_a (int argc, char *const *argv, const char *options, const struct option_a *long_options, int *opt_index) _GETOPT_THROW 503 { 504 return _getopt_internal_a (argc, argv, options, long_options, opt_index, 1, 0); 505 } 506 int _getopt_long_r_a (int argc, char *const *argv, const char *options, const struct option_a *long_options, int *opt_index, struct _getopt_data_a *d) 507 { 508 return _getopt_internal_r_a (argc, argv, options, long_options, opt_index,0, d, 0); 509 } 510 int _getopt_long_only_r_a (int argc, char *const *argv, const char *options, const struct option_a *long_options, int *opt_index, struct _getopt_data_a *d) 511 { 512 return _getopt_internal_r_a (argc, argv, options, long_options, opt_index, 1, d, 0); 513 } 514 515 // 516 // 517 // Unicode Structures and Functions 518 // 519 // 520 521 static struct _getopt_data_w 522 { 523 int optind; 524 int opterr; 525 int optopt; 526 wchar_t *optarg; 527 int __initialized; 528 wchar_t *__nextchar; 529 enum ENUM_ORDERING __ordering; 530 int __posixly_correct; 531 int __first_nonopt; 532 int __last_nonopt; 533 } getopt_data_w; 534 wchar_t *optarg_w; 535 536 static void exchange_w(wchar_t **argv, struct _getopt_data_w *d) 537 { 538 int bottom = d->__first_nonopt; 539 int middle = d->__last_nonopt; 540 int top = d->optind; 541 wchar_t *tem; 542 while (top > middle && middle > bottom) 543 { 544 if (top - middle > middle - bottom) 545 { 546 int len = middle - bottom; 547 register int i; 548 for (i = 0; i < len; i++) 549 { 550 tem = argv[bottom + i]; 551 argv[bottom + i] = argv[top - (middle - bottom) + i]; 552 argv[top - (middle - bottom) + i] = tem; 553 } 554 top -= len; 555 } 556 else 557 { 558 int len = top - middle; 559 register int i; 560 for (i = 0; i < len; i++) 561 { 562 tem = argv[bottom + i]; 563 argv[bottom + i] = argv[middle + i]; 564 argv[middle + i] = tem; 565 } 566 bottom += len; 567 } 568 } 569 d->__first_nonopt += (d->optind - d->__last_nonopt); 570 d->__last_nonopt = d->optind; 571 } 572 static const wchar_t *_getopt_initialize_w (const wchar_t *optstring, struct _getopt_data_w *d, int posixly_correct) 573 { 574 d->__first_nonopt = d->__last_nonopt = d->optind; 575 d->__nextchar = NULL; 576 d->__posixly_correct = posixly_correct | !!_wgetenv(L"POSIXLY_CORRECT"); 577 if (optstring[0] == L‘-‘) 578 { 579 d->__ordering = RETURN_IN_ORDER; 580 ++optstring; 581 } 582 else if (optstring[0] == L‘+‘) 583 { 584 d->__ordering = REQUIRE_ORDER; 585 ++optstring; 586 } 587 else if (d->__posixly_correct) 588 d->__ordering = REQUIRE_ORDER; 589 else 590 d->__ordering = PERMUTE; 591 return optstring; 592 } 593 int _getopt_internal_r_w (int argc, wchar_t *const *argv, const wchar_t *optstring, const struct option_w *longopts, int *longind, int long_only, struct _getopt_data_w *d, int posixly_correct) 594 { 595 int print_errors = d->opterr; 596 if (argc < 1) 597 return -1; 598 d->optarg = NULL; 599 if (d->optind == 0 || !d->__initialized) 600 { 601 if (d->optind == 0) 602 d->optind = 1; 603 optstring = _getopt_initialize_w (optstring, d, posixly_correct); 604 d->__initialized = 1; 605 } 606 else if (optstring[0] == L‘-‘ || optstring[0] == L‘+‘) 607 optstring++; 608 if (optstring[0] == L‘:‘) 609 print_errors = 0; 610 if (d->__nextchar == NULL || *d->__nextchar == L‘\0‘) 611 { 612 if (d->__last_nonopt > d->optind) 613 d->__last_nonopt = d->optind; 614 if (d->__first_nonopt > d->optind) 615 d->__first_nonopt = d->optind; 616 if (d->__ordering == PERMUTE) 617 { 618 if (d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind) 619 exchange_w((wchar_t **) argv, d); 620 else if (d->__last_nonopt != d->optind) 621 d->__first_nonopt = d->optind; 622 while (d->optind < argc && (argv[d->optind][0] != L‘-‘ || argv[d->optind][1] == L‘\0‘)) 623 d->optind++; 624 d->__last_nonopt = d->optind; 625 } 626 if (d->optind != argc && !wcscmp(argv[d->optind], L"--")) 627 { 628 d->optind++; 629 if (d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind) 630 exchange_w((wchar_t **) argv, d); 631 else if (d->__first_nonopt == d->__last_nonopt) 632 d->__first_nonopt = d->optind; 633 d->__last_nonopt = argc; 634 d->optind = argc; 635 } 636 if (d->optind == argc) 637 { 638 if (d->__first_nonopt != d->__last_nonopt) 639 d->optind = d->__first_nonopt; 640 return -1; 641 } 642 if ((argv[d->optind][0] != L‘-‘ || argv[d->optind][1] == L‘\0‘)) 643 { 644 if (d->__ordering == REQUIRE_ORDER) 645 return -1; 646 d->optarg = argv[d->optind++]; 647 return 1; 648 } 649 d->__nextchar = (argv[d->optind] + 1 + (longopts != NULL && argv[d->optind][1] == L‘-‘)); 650 } 651 if (longopts != NULL && (argv[d->optind][1] == L‘-‘ || (long_only && (argv[d->optind][2] || !wcschr(optstring, argv[d->optind][1]))))) 652 { 653 wchar_t *nameend; 654 unsigned int namelen; 655 const struct option_w *p; 656 const struct option_w *pfound = NULL; 657 struct option_list 658 { 659 const struct option_w *p; 660 struct option_list *next; 661 } *ambig_list = NULL; 662 int exact = 0; 663 int indfound = -1; 664 int option_index; 665 for (nameend = d->__nextchar; *nameend && *nameend != L‘=‘; nameend++); 666 namelen = (unsigned int)(nameend - d->__nextchar); 667 for (p = longopts, option_index = 0; p->name; p++, option_index++) 668 if (!wcsncmp(p->name, d->__nextchar, namelen)) 669 { 670 if (namelen == (unsigned int)wcslen(p->name)) 671 { 672 pfound = p; 673 indfound = option_index; 674 exact = 1; 675 break; 676 } 677 else if (pfound == NULL) 678 { 679 pfound = p; 680 indfound = option_index; 681 } 682 else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val) 683 { 684 struct option_list *newp = (struct option_list*)alloca(sizeof(*newp)); 685 newp->p = p; 686 newp->next = ambig_list; 687 ambig_list = newp; 688 } 689 } 690 if (ambig_list != NULL && !exact) 691 { 692 if (print_errors) 693 { 694 struct option_list first; 695 first.p = pfound; 696 first.next = ambig_list; 697 ambig_list = &first; 698 fwprintf(stderr, L"%s: option ‘%s‘ is ambiguous; possibilities:", argv[0], argv[d->optind]); 699 do 700 { 701 fwprintf (stderr, L" ‘--%s‘", ambig_list->p->name); 702 ambig_list = ambig_list->next; 703 } 704 while (ambig_list != NULL); 705 fputwc (L‘\n‘, stderr); 706 } 707 d->__nextchar += wcslen(d->__nextchar); 708 d->optind++; 709 d->optopt = 0; 710 return L‘?‘; 711 } 712 if (pfound != NULL) 713 { 714 option_index = indfound; 715 d->optind++; 716 if (*nameend) 717 { 718 if (pfound->has_arg) 719 d->optarg = nameend + 1; 720 else 721 { 722 if (print_errors) 723 { 724 if (argv[d->optind - 1][1] == L‘-‘) 725 { 726 fwprintf(stderr, L"%s: option ‘--%s‘ doesn‘t allow an argument\n",argv[0], pfound->name); 727 } 728 else 729 { 730 fwprintf(stderr, L"%s: option ‘%c%s‘ doesn‘t allow an argument\n",argv[0], argv[d->optind - 1][0],pfound->name); 731 } 732 } 733 d->__nextchar += wcslen(d->__nextchar); 734 d->optopt = pfound->val; 735 return L‘?‘; 736 } 737 } 738 else if (pfound->has_arg == 1) 739 { 740 if (d->optind < argc) 741 d->optarg = argv[d->optind++]; 742 else 743 { 744 if (print_errors) 745 { 746 fwprintf(stderr,L"%s: option ‘--%s‘ requires an argument\n",argv[0], pfound->name); 747 } 748 d->__nextchar += wcslen(d->__nextchar); 749 d->optopt = pfound->val; 750 return optstring[0] == L‘:‘ ? L‘:‘ : L‘?‘; 751 } 752 } 753 d->__nextchar += wcslen(d->__nextchar); 754 if (longind != NULL) 755 *longind = option_index; 756 if (pfound->flag) 757 { 758 *(pfound->flag) = pfound->val; 759 return 0; 760 } 761 return pfound->val; 762 } 763 if (!long_only || argv[d->optind][1] == L‘-‘ || wcschr(optstring, *d->__nextchar) == NULL) 764 { 765 if (print_errors) 766 { 767 if (argv[d->optind][1] == L‘-‘) 768 { 769 fwprintf(stderr, L"%s: unrecognized option ‘--%s‘\n",argv[0], d->__nextchar); 770 } 771 else 772 { 773 fwprintf(stderr, L"%s: unrecognized option ‘%c%s‘\n",argv[0], argv[d->optind][0], d->__nextchar); 774 } 775 } 776 d->__nextchar = (wchar_t *)L""; 777 d->optind++; 778 d->optopt = 0; 779 return L‘?‘; 780 } 781 } 782 { 783 wchar_t c = *d->__nextchar++; 784 wchar_t *temp = (wchar_t*)wcschr(optstring, c); 785 if (*d->__nextchar == L‘\0‘) 786 ++d->optind; 787 if (temp == NULL || c == L‘:‘ || c == L‘;‘) 788 { 789 if (print_errors) 790 { 791 fwprintf(stderr, L"%s: invalid option -- ‘%c‘\n", argv[0], c); 792 } 793 d->optopt = c; 794 return L‘?‘; 795 } 796 if (temp[0] == L‘W‘ && temp[1] == L‘;‘) 797 { 798 wchar_t *nameend; 799 const struct option_w *p; 800 const struct option_w *pfound = NULL; 801 int exact = 0; 802 int ambig = 0; 803 int indfound = 0; 804 int option_index; 805 if (longopts == NULL) 806 goto no_longs; 807 if (*d->__nextchar != L‘\0‘) 808 { 809 d->optarg = d->__nextchar; 810 d->optind++; 811 } 812 else if (d->optind == argc) 813 { 814 if (print_errors) 815 { 816 fwprintf(stderr,L"%s: option requires an argument -- ‘%c‘\n",argv[0], c); 817 } 818 d->optopt = c; 819 if (optstring[0] == L‘:‘) 820 c = L‘:‘; 821 else 822 c = L‘?‘; 823 return c; 824 } 825 else 826 d->optarg = argv[d->optind++]; 827 for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != L‘=‘; nameend++); 828 for (p = longopts, option_index = 0; p->name; p++, option_index++) 829 if (!wcsncmp(p->name, d->__nextchar, nameend - d->__nextchar)) 830 { 831 if ((unsigned int) (nameend - d->__nextchar) == wcslen(p->name)) 832 { 833 pfound = p; 834 indfound = option_index; 835 exact = 1; 836 break; 837 } 838 else if (pfound == NULL) 839 { 840 pfound = p; 841 indfound = option_index; 842 } 843 else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val) 844 ambig = 1; 845 } 846 if (ambig && !exact) 847 { 848 if (print_errors) 849 { 850 fwprintf(stderr, L"%s: option ‘-W %s‘ is ambiguous\n",argv[0], d->optarg); 851 } 852 d->__nextchar += wcslen(d->__nextchar); 853 d->optind++; 854 return L‘?‘; 855 } 856 if (pfound != NULL) 857 { 858 option_index = indfound; 859 if (*nameend) 860 { 861 if (pfound->has_arg) 862 d->optarg = nameend + 1; 863 else 864 { 865 if (print_errors) 866 { 867 fwprintf(stderr, L"%s: option ‘-W %s‘ doesn‘t allow an argument\n",argv[0], pfound->name); 868 } 869 d->__nextchar += wcslen(d->__nextchar); 870 return L‘?‘; 871 } 872 } 873 else if (pfound->has_arg == 1) 874 { 875 if (d->optind < argc) 876 d->optarg = argv[d->optind++]; 877 else 878 { 879 if (print_errors) 880 { 881 fwprintf(stderr, L"%s: option ‘-W %s‘ requires an argument\n",argv[0], pfound->name); 882 } 883 d->__nextchar += wcslen(d->__nextchar); 884 return optstring[0] == L‘:‘ ? L‘:‘ : L‘?‘; 885 } 886 } 887 else 888 d->optarg = NULL; 889 d->__nextchar += wcslen(d->__nextchar); 890 if (longind != NULL) 891 *longind = option_index; 892 if (pfound->flag) 893 { 894 *(pfound->flag) = pfound->val; 895 return 0; 896 } 897 return pfound->val; 898 } 899 no_longs: 900 d->__nextchar = NULL; 901 return L‘W‘; 902 } 903 if (temp[1] == L‘:‘) 904 { 905 if (temp[2] == L‘:‘) 906 { 907 if (*d->__nextchar != L‘\0‘) 908 { 909 d->optarg = d->__nextchar; 910 d->optind++; 911 } 912 else 913 d->optarg = NULL; 914 d->__nextchar = NULL; 915 } 916 else 917 { 918 if (*d->__nextchar != L‘\0‘) 919 { 920 d->optarg = d->__nextchar; 921 d->optind++; 922 } 923 else if (d->optind == argc) 924 { 925 if (print_errors) 926 { 927 fwprintf(stderr,L"%s: option requires an argument -- ‘%c‘\n",argv[0], c); 928 } 929 d->optopt = c; 930 if (optstring[0] == L‘:‘) 931 c = L‘:‘; 932 else 933 c = L‘?‘; 934 } 935 else 936 d->optarg = argv[d->optind++]; 937 d->__nextchar = NULL; 938 } 939 } 940 return c; 941 } 942 } 943 int _getopt_internal_w (int argc, wchar_t *const *argv, const wchar_t *optstring, const struct option_w *longopts, int *longind, int long_only, int posixly_correct) 944 { 945 int result; 946 getopt_data_w.optind = optind; 947 getopt_data_w.opterr = opterr; 948 result = _getopt_internal_r_w (argc, argv, optstring, longopts,longind, long_only, &getopt_data_w,posixly_correct); 949 optind = getopt_data_w.optind; 950 optarg_w = getopt_data_w.optarg; 951 optopt = getopt_data_w.optopt; 952 return result; 953 } 954 int getopt_w (int argc, wchar_t *const *argv, const wchar_t *optstring) _GETOPT_THROW 955 { 956 return _getopt_internal_w (argc, argv, optstring, (const struct option_w *) 0, (int *) 0, 0, 0); 957 } 958 int getopt_long_w (int argc, wchar_t *const *argv, const wchar_t *options, const struct option_w *long_options, int *opt_index) _GETOPT_THROW 959 { 960 return _getopt_internal_w (argc, argv, options, long_options, opt_index, 0, 0); 961 } 962 int getopt_long_only_w (int argc, wchar_t *const *argv, const wchar_t *options, const struct option_w *long_options, int *opt_index) _GETOPT_THROW 963 { 964 return _getopt_internal_w (argc, argv, options, long_options, opt_index, 1, 0); 965 } 966 int _getopt_long_r_w (int argc, wchar_t *const *argv, const wchar_t *options, const struct option_w *long_options, int *opt_index, struct _getopt_data_w *d) 967 { 968 return _getopt_internal_r_w (argc, argv, options, long_options, opt_index,0, d, 0); 969 } 970 int _getopt_long_only_r_w (int argc, wchar_t *const *argv, const wchar_t *options, const struct option_w *long_options, int *opt_index, struct _getopt_data_w *d) 971 { 972 return _getopt_internal_r_w (argc, argv, options, long_options, opt_index, 1, d, 0); 973 }
时间: 2024-10-20 08:52:11