00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <sys/types.h>
00027 #include <stdlib.h>
00028 #include <stdio.h>
00029 #include <string.h>
00030 #include "my_getopt.h"
00031
00032 int my_optind=1, my_opterr=1, my_optopt=0;
00033 char *my_optarg=0;
00034
00035
00036 int my_getopt_reset(void)
00037 {
00038 my_optind = 1;
00039 my_opterr = 1;
00040 my_optopt = 0;
00041 my_optarg = 0;
00042 return 0;
00043 }
00044
00045
00046
00047
00048
00049 int my_getopt(int argc, char * argv[], const char *opts)
00050 {
00051 static int charind=0;
00052 const char *s;
00053 char mode, colon_mode;
00054 int off = 0, opt = -1;
00055
00056 if(0 ) colon_mode = mode = '+';
00057 else {
00058 if((colon_mode = *opts) == ':') off ++;
00059 if(((mode = opts[off]) == '+') || (mode == '-')) {
00060 off++;
00061 if((colon_mode != ':') && ((colon_mode = opts[off]) == ':'))
00062 off ++;
00063 }
00064 }
00065 my_optarg = 0;
00066 if(charind) {
00067 my_optopt = argv[my_optind][charind];
00068 for(s=opts+off; *s; s++) if(my_optopt == *s) {
00069 charind++;
00070 if((*(++s) == ':') || ((my_optopt == 'W') && (*s == ';'))) {
00071 if(argv[my_optind][charind]) {
00072 my_optarg = &(argv[my_optind++][charind]);
00073 charind = 0;
00074 } else if(*(++s) != ':') {
00075 charind = 0;
00076 if(++my_optind >= argc) {
00077 if(my_opterr) fprintf(stderr,
00078 "%s: option requires an argument -- %c\n",
00079 argv[0], my_optopt);
00080 opt = (colon_mode == ':') ? ':' : '?';
00081 goto my_getopt_ok;
00082 }
00083 my_optarg = argv[my_optind++];
00084 }
00085 }
00086 opt = my_optopt;
00087 goto my_getopt_ok;
00088 }
00089 if(my_opterr) fprintf(stderr,
00090 "%s: illegal option -- %c\n",
00091 argv[0], my_optopt);
00092 opt = '?';
00093 if(argv[my_optind][++charind] == '\0') {
00094 my_optind++;
00095 charind = 0;
00096 }
00097 my_getopt_ok:
00098 if(charind && ! argv[my_optind][charind]) {
00099 my_optind++;
00100 charind = 0;
00101 }
00102 } else if((my_optind >= argc) ||
00103 ((argv[my_optind][0] == '-') &&
00104 (argv[my_optind][1] == '-') &&
00105 (argv[my_optind][2] == '\0'))) {
00106 my_optind++;
00107 opt = -1;
00108 } else if((argv[my_optind][0] != '-') ||
00109 (argv[my_optind][1] == '\0')) {
00110 char *tmp;
00111 int i, j, k;
00112
00113 if(mode == '+') opt = -1;
00114 else if(mode == '-') {
00115 my_optarg = argv[my_optind++];
00116 charind = 0;
00117 opt = 1;
00118 } else {
00119 for(i=j=my_optind; i<argc; i++) if((argv[i][0] == '-') &&
00120 (argv[i][1] != '\0')) {
00121 my_optind=i;
00122 opt=my_getopt(argc, argv, opts);
00123 while(i > j) {
00124 tmp=argv[--i];
00125 for(k=i; k+1<my_optind; k++) argv[k]=argv[k+1];
00126 argv[--my_optind]=tmp;
00127 }
00128 break;
00129 }
00130 if(i == argc) opt = -1;
00131 }
00132 } else {
00133 charind++;
00134 opt = my_getopt(argc, argv, opts);
00135 }
00136 if (my_optind > argc) my_optind = argc;
00137 return opt;
00138 }
00139
00140
00141
00142
00143
00144
00145 int _my_getopt_internal(int argc, char * argv[], const char *shortopts,
00146 const struct option *longopts, int *longind,
00147 int long_only)
00148 {
00149 char mode, colon_mode = *shortopts;
00150 int shortoff = 0, opt = -1;
00151
00152 if(0 ) colon_mode = mode = '+';
00153 else {
00154 if((colon_mode = *shortopts) == ':') shortoff ++;
00155 if(((mode = shortopts[shortoff]) == '+') || (mode == '-')) {
00156 shortoff++;
00157 if((colon_mode != ':') && ((colon_mode = shortopts[shortoff]) == ':'))
00158 shortoff ++;
00159 }
00160 }
00161 my_optarg = 0;
00162 if((my_optind >= argc) ||
00163 ((argv[my_optind][0] == '-') &&
00164 (argv[my_optind][1] == '-') &&
00165 (argv[my_optind][2] == '\0'))) {
00166 my_optind++;
00167 opt = -1;
00168 } else if((argv[my_optind][0] != '-') ||
00169 (argv[my_optind][1] == '\0')) {
00170 char *tmp;
00171 int i, j, k;
00172
00173 opt = -1;
00174 if(mode == '+') return -1;
00175 else if(mode == '-') {
00176 my_optarg = argv[my_optind++];
00177 return 1;
00178 }
00179 for(i=j=my_optind; i<argc; i++) if((argv[i][0] == '-') &&
00180 (argv[i][1] != '\0')) {
00181 my_optind=i;
00182 opt=_my_getopt_internal(argc, argv, shortopts,
00183 longopts, longind,
00184 long_only);
00185 while(i > j) {
00186 tmp=argv[--i];
00187 for(k=i; k+1<my_optind; k++)
00188 argv[k]=argv[k+1];
00189 argv[--my_optind]=tmp;
00190 }
00191 break;
00192 }
00193 } else if((!long_only) && (argv[my_optind][1] != '-'))
00194 opt = my_getopt(argc, argv, shortopts);
00195 else {
00196 int charind, offset;
00197 int found = 0, ind, hits = 0;
00198
00199 if(((my_optopt = argv[my_optind][1]) != '-') && ! argv[my_optind][2]) {
00200 int c;
00201
00202 ind = shortoff;
00203 while((c = shortopts[ind++])) {
00204 if(((shortopts[ind] == ':') ||
00205 ((c == 'W') && (shortopts[ind] == ';'))) &&
00206 (shortopts[++ind] == ':'))
00207 ind ++;
00208 if(my_optopt == c) return my_getopt(argc, argv, shortopts);
00209 }
00210 }
00211 offset = 2 - (argv[my_optind][1] != '-');
00212 for(charind = offset;
00213 (argv[my_optind][charind] != '\0') &&
00214 (argv[my_optind][charind] != '=');
00215 charind++);
00216 for(ind = 0; longopts[ind].name && !hits; ind++)
00217 if((strlen(longopts[ind].name) == (size_t) (charind - offset)) &&
00218 (strncmp(longopts[ind].name,
00219 argv[my_optind] + offset, charind - offset) == 0))
00220 found = ind, hits++;
00221 if(!hits) for(ind = 0; longopts[ind].name; ind++)
00222 if(strncmp(longopts[ind].name,
00223 argv[my_optind] + offset, charind - offset) == 0)
00224 found = ind, hits++;
00225 if(hits == 1) {
00226 opt = 0;
00227
00228 if(argv[my_optind][charind] == '=') {
00229 if(longopts[found].has_arg == 0) {
00230 opt = '?';
00231 if(my_opterr) fprintf(stderr,
00232 "%s: option `--%s' doesn't allow an argument\n",
00233 argv[0], longopts[found].name);
00234 } else {
00235 my_optarg = argv[my_optind] + ++charind;
00236 charind = 0;
00237 }
00238 } else if(longopts[found].has_arg == 1) {
00239 if(++my_optind >= argc) {
00240 opt = (colon_mode == ':') ? ':' : '?';
00241 if(my_opterr) fprintf(stderr,
00242 "%s: option `--%s' requires an argument\n",
00243 argv[0], longopts[found].name);
00244 } else my_optarg = argv[my_optind];
00245 }
00246 if(!opt) {
00247 if (longind) *longind = found;
00248 if(!longopts[found].flag) opt = longopts[found].val;
00249 else *(longopts[found].flag) = longopts[found].val;
00250 }
00251 my_optind++;
00252 } else if(!hits) {
00253 if(offset == 1) opt = my_getopt(argc, argv, shortopts);
00254 else {
00255 opt = '?';
00256 if(my_opterr) fprintf(stderr,
00257 "%s: unrecognized option `%s'\n",
00258 argv[0], argv[my_optind++]);
00259 }
00260 } else {
00261 opt = '?';
00262 if(my_opterr) fprintf(stderr,
00263 "%s: option `%s' is ambiguous\n",
00264 argv[0], argv[my_optind++]);
00265 }
00266 }
00267 if (my_optind > argc) my_optind = argc;
00268 return opt;
00269 }
00270
00271 int my_getopt_long(int argc, char * argv[], const char *shortopts,
00272 const struct option *longopts, int *longind)
00273 {
00274 return _my_getopt_internal(argc, argv, shortopts, longopts, longind, 0);
00275 }
00276
00277 int my_getopt_long_only(int argc, char * argv[], const char *shortopts,
00278 const struct option *longopts, int *longind)
00279 {
00280 return _my_getopt_internal(argc, argv, shortopts, longopts, longind, 1);
00281 }