大家好,我是阿桃,一个想成为被点赞关注的程序员。
工控行业、物联网行业、机器人行业软件开发可联系我,联系方式QQ:845699561
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] == '\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 */