Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygengetopt.c
Go to the documentation of this file.
00001 #include <assert.h> 00002 #include <errno.h> 00003 #include <stdlib.h> 00004 #include <string.h> 00005 #include <getopt.h> 00006 #include <stdarg.h> 00007 #include <stdio.h> 00008 00009 #define REPLACE_GETOPT 00010 00011 #define _DIAGASSERT(x) do {} while (0) 00012 00013 #ifdef REPLACE_GETOPT 00014 #ifdef __weak_alias 00015 __weak_alias(getopt,_getopt) 00016 #endif 00017 int opterr = 1; 00018 int optind = 1; 00019 int optopt = '?'; 00020 int optreset; 00021 char *optarg; 00022 #endif 00023 00024 #ifdef __weak_alias 00025 __weak_alias(getopt_long,_getopt_long) 00026 #endif 00027 00028 #ifndef __CYGWIN__ 00029 #define __progname __argv[0] 00030 #else 00031 extern char __declspec(dllimport) *__progname; 00032 #endif 00033 00034 #define IGNORE_FIRST (*options == '-' || *options == '+') 00035 #define PRINT_ERROR ((opterr) && ((*options != ':') || (IGNORE_FIRST && options[1] != ':'))) 00036 00037 #ifndef IS_POSIXLY_CORRECT 00038 #define IS_POSIXLY_CORRECT (getenv("POSIXLY_CORRECT") != NULL) 00039 #endif 00040 00041 #define PERMUTE (!IS_POSIXLY_CORRECT && !IGNORE_FIRST) 00042 00043 #define IN_ORDER (!IS_POSIXLY_CORRECT && *options == '-') 00044 00045 #define BADCH (int)'?' 00046 #define BADARG ((IGNORE_FIRST && options[1] == ':') || (*options == ':') ? (int)':' : (int)'?') 00047 #define INORDER (int)1 00048 00049 static char EMSG[1]; 00050 00051 static int getopt_internal (int,char * const *,const char *); 00052 static int gcd (int,int); 00053 static void permute_args (int,int,int,char * const *); 00054 00055 static char *place = EMSG; 00056 00057 static int nonopt_start = -1; 00058 static int nonopt_end = -1; 00059 00060 static const char recargchar[] = "option requires an argument -- %c"; 00061 static const char recargstring[] = "option requires an argument -- %s"; 00062 static const char ambig[] = "ambiguous option -- %.*s"; 00063 static const char noarg[] = "option doesn't take an argument -- %.*s"; 00064 static const char illoptchar[] = "unknown option -- %c"; 00065 static const char illoptstring[] = "unknown option -- %s"; 00066 00067 static void 00068 _vwarnx(const char *fmt,va_list ap) 00069 { 00070 (void)fprintf(stderr,"%s: ",__progname); 00071 if (fmt != NULL) 00072 (void)vfprintf(stderr,fmt,ap); 00073 (void)fprintf(stderr,"\n"); 00074 } 00075 00076 static void 00077 warnx(const char *fmt,...) 00078 { 00079 va_list ap; 00080 va_start(ap,fmt); 00081 _vwarnx(fmt,ap); 00082 va_end(ap); 00083 } 00084 00085 static int 00086 gcd(a,b) 00087 int a; 00088 int b; 00089 { 00090 int c; 00091 00092 c = a % b; 00093 while (c != 0) { 00094 a = b; 00095 b = c; 00096 c = a % b; 00097 } 00098 00099 return b; 00100 } 00101 00102 static void 00103 permute_args(panonopt_start,panonopt_end,opt_end,nargv) 00104 int panonopt_start; 00105 int panonopt_end; 00106 int opt_end; 00107 char * const *nargv; 00108 { 00109 int cstart,cyclelen,i,j,ncycle,nnonopts,nopts,pos; 00110 char *swap; 00111 00112 _DIAGASSERT(nargv != NULL); 00113 00114 nnonopts = panonopt_end - panonopt_start; 00115 nopts = opt_end - panonopt_end; 00116 ncycle = gcd(nnonopts,nopts); 00117 cyclelen = (opt_end - panonopt_start) / ncycle; 00118 00119 for (i = 0; i < ncycle; i++) { 00120 cstart = panonopt_end+i; 00121 pos = cstart; 00122 for (j = 0; j < cyclelen; j++) { 00123 if (pos >= panonopt_end) 00124 pos -= nnonopts; 00125 else 00126 pos += nopts; 00127 swap = nargv[pos]; 00128 00129 ((char **) nargv)[pos] = nargv[cstart]; 00130 00131 ((char **)nargv)[cstart] = swap; 00132 } 00133 } 00134 } 00135 00136 static int 00137 getopt_internal(nargc,nargv,options) 00138 int nargc; 00139 char * const *nargv; 00140 const char *options; 00141 { 00142 char *oli; 00143 int optchar; 00144 00145 _DIAGASSERT(nargv != NULL); 00146 _DIAGASSERT(options != NULL); 00147 00148 optarg = NULL; 00149 00150 if (optind == 0) 00151 optind = 1; 00152 00153 if (optreset) 00154 nonopt_start = nonopt_end = -1; 00155 start: 00156 if (optreset || !*place) { 00157 optreset = 0; 00158 if (optind >= nargc) { 00159 place = EMSG; 00160 if (nonopt_end != -1) { 00161 00162 permute_args(nonopt_start,nonopt_end,optind,nargv); 00163 optind -= nonopt_end - nonopt_start; 00164 } 00165 else if (nonopt_start != -1) { 00166 00167 optind = nonopt_start; 00168 } 00169 nonopt_start = nonopt_end = -1; 00170 return -1; 00171 } 00172 if ((*(place = nargv[optind]) != '-') 00173 || (place[1] == '\0')) { 00174 place = EMSG; 00175 if (IN_ORDER) { 00176 00177 optarg = nargv[optind++]; 00178 return INORDER; 00179 } 00180 if (!PERMUTE) { 00181 00182 return -1; 00183 } 00184 00185 if (nonopt_start == -1) 00186 nonopt_start = optind; 00187 else if (nonopt_end != -1) { 00188 permute_args(nonopt_start,nonopt_end,optind,nargv); 00189 nonopt_start = optind - 00190 (nonopt_end - nonopt_start); 00191 nonopt_end = -1; 00192 } 00193 optind++; 00194 00195 goto start; 00196 } 00197 if (nonopt_start != -1 && nonopt_end == -1) 00198 nonopt_end = optind; 00199 if (place[1] && *++place == '-') { 00200 place++; 00201 return -2; 00202 } 00203 } 00204 if ((optchar = (int)*place++) == (int)':' || 00205 (oli = strchr(options + (IGNORE_FIRST ? 1 : 0),optchar)) == NULL) { 00206 00207 if (!*place) 00208 ++optind; 00209 if (PRINT_ERROR) 00210 warnx(illoptchar,optchar); 00211 optopt = optchar; 00212 return BADCH; 00213 } 00214 if (optchar == 'W' && oli[1] == ';') { 00215 00216 if (*place) 00217 return -2; 00218 00219 if (++optind >= nargc) { 00220 place = EMSG; 00221 if (PRINT_ERROR) 00222 warnx(recargchar,optchar); 00223 optopt = optchar; 00224 return BADARG; 00225 } else 00226 place = nargv[optind]; 00227 00228 return -2; 00229 } 00230 if (*++oli != ':') { 00231 if (!*place) 00232 ++optind; 00233 } else { 00234 optarg = NULL; 00235 if (*place) 00236 optarg = place; 00237 00238 else if (oli[1] != ':') { 00239 if (++optind >= nargc) { 00240 place = EMSG; 00241 if (PRINT_ERROR) 00242 warnx(recargchar,optchar); 00243 optopt = optchar; 00244 return BADARG; 00245 } else 00246 optarg = nargv[optind]; 00247 } 00248 place = EMSG; 00249 ++optind; 00250 } 00251 00252 return optchar; 00253 } 00254 00255 #ifdef REPLACE_GETOPT 00256 00257 int 00258 getopt(nargc,nargv,options) 00259 int nargc; 00260 char * const *nargv; 00261 const char *options; 00262 { 00263 int retval; 00264 00265 _DIAGASSERT(nargv != NULL); 00266 _DIAGASSERT(options != NULL); 00267 00268 if ((retval = getopt_internal(nargc,nargv,options)) == -2) { 00269 ++optind; 00270 00271 if (nonopt_end != -1) { 00272 permute_args(nonopt_start,nonopt_end,optind,nargv); 00273 optind -= nonopt_end - nonopt_start; 00274 } 00275 nonopt_start = nonopt_end = -1; 00276 retval = -1; 00277 } 00278 return retval; 00279 } 00280 #endif 00281 00282 int 00283 getopt_long(nargc,nargv,options,long_options,idx) 00284 int nargc; 00285 char * const *nargv; 00286 const char *options; 00287 const struct option *long_options; 00288 int *idx; 00289 { 00290 int retval; 00291 00292 _DIAGASSERT(nargv != NULL); 00293 _DIAGASSERT(options != NULL); 00294 _DIAGASSERT(long_options != NULL); 00295 00296 if ((retval = getopt_internal(nargc,nargv,options)) == -2) { 00297 char *current_argv,*has_equal; 00298 size_t current_argv_len; 00299 int i,match; 00300 00301 current_argv = place; 00302 match = -1; 00303 00304 optind++; 00305 place = EMSG; 00306 00307 if (*current_argv == '\0') { 00308 00309 if (nonopt_end != -1) { 00310 permute_args(nonopt_start,nonopt_end,optind,nargv); 00311 optind -= nonopt_end - nonopt_start; 00312 } 00313 nonopt_start = nonopt_end = -1; 00314 return -1; 00315 } 00316 if ((has_equal = strchr(current_argv,'=')) != NULL) { 00317 00318 current_argv_len = has_equal - current_argv; 00319 has_equal++; 00320 } else 00321 current_argv_len = strlen(current_argv); 00322 00323 for (i = 0; long_options[i].name; i++) { 00324 00325 if (strncmp(current_argv,long_options[i].name,current_argv_len)) 00326 continue; 00327 00328 if (strlen(long_options[i].name) == 00329 (unsigned)current_argv_len) { 00330 00331 match = i; 00332 break; 00333 } 00334 if (match == -1) 00335 match = i; 00336 else { 00337 00338 if (PRINT_ERROR) 00339 warnx(ambig,(int)current_argv_len,current_argv); 00340 optopt = 0; 00341 return BADCH; 00342 } 00343 } 00344 if (match != -1) { 00345 if (long_options[match].has_arg == no_argument 00346 && has_equal) { 00347 if (PRINT_ERROR) 00348 warnx(noarg,(int)current_argv_len,current_argv); 00349 00350 if (long_options[match].flag == NULL) 00351 optopt = long_options[match].val; 00352 else 00353 optopt = 0; 00354 return BADARG; 00355 } 00356 if (long_options[match].has_arg == required_argument || 00357 long_options[match].has_arg == optional_argument) { 00358 if (has_equal) 00359 optarg = has_equal; 00360 else if (long_options[match].has_arg == 00361 required_argument) { 00362 00363 optarg = nargv[optind++]; 00364 } 00365 } 00366 if ((long_options[match].has_arg == required_argument) 00367 && (optarg == NULL)) { 00368 00369 if (PRINT_ERROR) 00370 warnx(recargstring,current_argv); 00371 00372 if (long_options[match].flag == NULL) 00373 optopt = long_options[match].val; 00374 else 00375 optopt = 0; 00376 --optind; 00377 return BADARG; 00378 } 00379 } else { 00380 if (PRINT_ERROR) 00381 warnx(illoptstring,current_argv); 00382 optopt = 0; 00383 return BADCH; 00384 } 00385 if (long_options[match].flag) { 00386 *long_options[match].flag = long_options[match].val; 00387 retval = 0; 00388 } else 00389 retval = long_options[match].val; 00390 if (idx) 00391 *idx = match; 00392 } 00393 return retval; 00394 } Generated on Sun May 27 2012 04:17:12 for ReactOS by
1.7.6.1
|