getopt for windows
Posted 工藤-新一
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 [email protected] 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] == ‘\0‘) 305 306 if (d->__nextchar == NULL || *d->__nextchar == ‘\0‘) 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\n"), 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\n"), 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\n"), 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\n"), 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‘\n"), 538 argv[0], d->__nextchar); 539 } 540 else 541 { 542 /* +option or -option */ 543 fprintf (stderr, _("%s: unrecognized option ‘%c%s‘\n"), 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 == ‘\0‘) 563 ++d->optind; 564 565 if (temp == NULL || c == ‘:‘) 566 { 567 if (print_errors) 568 { 569 570 fprintf (stderr, _("%s: invalid option -- ‘%c‘\n"), 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 != ‘\0‘) 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‘\n"), 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\n"), 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\n"), 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\n"), 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 != ‘\0‘) 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 != ‘\0‘) 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‘\n"), 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 ‘\0‘. 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("\nNo Usage\n"); 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\n"); 36 break; 37 case ‘m‘: 38 //TODO:获取参数n表示要获取的符号个数,通过system调用findstr /<Symbol/>将相应的符号行从temp文件中取出 39 //将取出的数据处理只保留地址保存到Addr文件中。 40 //通过while(n)来处理每一个argv的符号。 41 42 printf("n\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 ("\n"); 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.\n"); 111 digit_optind = this_option_optind; 112 printf ("option %c\n", c); 113 break; 114 115 case ‘a‘: 116 printf ("option a\n"); 117 break; 118 119 case ‘b‘: 120 printf ("option b\n"); 121 break; 122 123 case ‘c‘: 124 printf ("option c with value `%s‘\n", optarg); 125 break; 126 127 case ‘d‘: 128 printf ("option d with value `%s‘\n", optarg); 129 break; 130 131 case ‘?‘: 132 break; 133 134 default: 135 printf ("?? getopt returned character code 0%o ??\n", 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 ("\n"); 145 } 146 147 return 0; 148 } 149 */
以上是关于getopt for windows的主要内容,如果未能解决你的问题,请参考以下文章
shinyapp windows发布--不用shinyserver 日常记录