OLD | NEW |
(Empty) | |
| 1 #define _GNU_SOURCE |
| 2 #include <stddef.h> |
| 3 #include <getopt.h> |
| 4 #include <stdio.h> |
| 5 #include <string.h> |
| 6 |
| 7 extern int __optpos, __optreset; |
| 8 |
| 9 static void permute(char *const *argv, int dest, int src) |
| 10 { |
| 11 char **av = (char **)argv; |
| 12 char *tmp = av[src]; |
| 13 int i; |
| 14 for (i=src; i>dest; i--) |
| 15 av[i] = av[i-1]; |
| 16 av[dest] = tmp; |
| 17 } |
| 18 |
| 19 void __getopt_msg(const char *, const char *, const char *, size_t); |
| 20 |
| 21 static int __getopt_long_core(int argc, char *const *argv, const char *optstring
, const struct option *longopts, int *idx, int longonly); |
| 22 |
| 23 static int __getopt_long(int argc, char *const *argv, const char *optstring, con
st struct option *longopts, int *idx, int longonly) |
| 24 { |
| 25 int ret, skipped, resumed; |
| 26 if (!optind || __optreset) { |
| 27 __optreset = 0; |
| 28 __optpos = 0; |
| 29 optind = 1; |
| 30 } |
| 31 if (optind >= argc || !argv[optind]) return -1; |
| 32 skipped = optind; |
| 33 if (optstring[0] != '+' && optstring[0] != '-') { |
| 34 int i; |
| 35 for (i=optind; ; i++) { |
| 36 if (i >= argc || !argv[i]) return -1; |
| 37 if (argv[i][0] == '-' && argv[i][1]) break; |
| 38 } |
| 39 optind = i; |
| 40 } |
| 41 resumed = optind; |
| 42 ret = __getopt_long_core(argc, argv, optstring, longopts, idx, longonly)
; |
| 43 if (resumed > skipped) { |
| 44 int i, cnt = optind-resumed; |
| 45 for (i=0; i<cnt; i++) |
| 46 permute(argv, skipped, optind-1); |
| 47 optind = skipped + cnt; |
| 48 } |
| 49 return ret; |
| 50 } |
| 51 |
| 52 static int __getopt_long_core(int argc, char *const *argv, const char *optstring
, const struct option *longopts, int *idx, int longonly) |
| 53 { |
| 54 optarg = 0; |
| 55 if (longopts && argv[optind][0] == '-' && |
| 56 ((longonly && argv[optind][1]) || |
| 57 (argv[optind][1] == '-' && argv[optind][2]))) |
| 58 { |
| 59 int colon = optstring[optstring[0]=='+'||optstring[0]=='-']==':'
; |
| 60 int i, cnt, match; |
| 61 char *opt; |
| 62 for (cnt=i=0; longopts[i].name; i++) { |
| 63 const char *name = longopts[i].name; |
| 64 opt = argv[optind]+1; |
| 65 if (*opt == '-') opt++; |
| 66 for (; *name && *name == *opt; name++, opt++); |
| 67 if (*opt && *opt != '=') continue; |
| 68 match = i; |
| 69 if (!*name) { |
| 70 cnt = 1; |
| 71 break; |
| 72 } |
| 73 cnt++; |
| 74 } |
| 75 if (cnt==1) { |
| 76 i = match; |
| 77 optind++; |
| 78 optopt = longopts[i].val; |
| 79 if (*opt == '=') { |
| 80 if (!longopts[i].has_arg) { |
| 81 if (colon || !opterr) |
| 82 return '?'; |
| 83 __getopt_msg(argv[0], |
| 84 ": option does not take an argum
ent: ", |
| 85 longopts[i].name, |
| 86 strlen(longopts[i].name)); |
| 87 return '?'; |
| 88 } |
| 89 optarg = opt+1; |
| 90 } else if (longopts[i].has_arg == required_argument) { |
| 91 if (!(optarg = argv[optind])) { |
| 92 if (colon) return ':'; |
| 93 if (!opterr) return '?'; |
| 94 __getopt_msg(argv[0], |
| 95 ": option requires an argument:
", |
| 96 longopts[i].name, |
| 97 strlen(longopts[i].name)); |
| 98 return '?'; |
| 99 } |
| 100 optind++; |
| 101 } |
| 102 if (idx) *idx = i; |
| 103 if (longopts[i].flag) { |
| 104 *longopts[i].flag = longopts[i].val; |
| 105 return 0; |
| 106 } |
| 107 return longopts[i].val; |
| 108 } |
| 109 if (argv[optind][1] == '-') { |
| 110 if (!colon && opterr) |
| 111 __getopt_msg(argv[0], cnt ? |
| 112 ": option is ambiguous: " : |
| 113 ": unrecognized option: ", |
| 114 argv[optind]+2, |
| 115 strlen(argv[optind]+2)); |
| 116 optind++; |
| 117 return '?'; |
| 118 } |
| 119 } |
| 120 return getopt(argc, argv, optstring); |
| 121 } |
| 122 |
| 123 int getopt_long(int argc, char *const *argv, const char *optstring, const struct
option *longopts, int *idx) |
| 124 { |
| 125 return __getopt_long(argc, argv, optstring, longopts, idx, 0); |
| 126 } |
| 127 |
| 128 int getopt_long_only(int argc, char *const *argv, const char *optstring, const s
truct option *longopts, int *idx) |
| 129 { |
| 130 return __getopt_long(argc, argv, optstring, longopts, idx, 1); |
| 131 } |
OLD | NEW |