ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

getopt.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.