getopt_long.c
Go to the documentation of this file.
00001 
00006 /*
00007 Copyright (C) 2007-12 Andrea Vedaldi and Brian Fulkerson.
00008 All rights reserved.
00009 
00010 This file is part of the VLFeat library and is made available under
00011 the terms of the BSD license (see the COPYING file).
00012 */
00013 
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <stdio.h>
00026 
00027 #include "generic.h"
00028 #include "getopt_long.h"
00029 
00030 int    opterr = 1 ;
00031 int    optind = 1 ;
00032 int    optopt ;
00033 char * optarg ;
00034 int    optreset ;
00035 
00036 #define BADCH   '?'
00037 #define BADARG  ':'
00038 #define EEND    -1
00039 #define EMSG    ""
00040 
00073 VL_EXPORT int
00074 getopt_long(int argc, char *const argv[],
00075             const char *optstring,
00076             const struct option * longopts,
00077             int *longindex)
00078 {
00079   static char *place = EMSG;    /* option letter processing */
00080   static int   optbegin  = 0 ;
00081   static int   optend    = 0 ;
00082   char        *oli;             /* option letter list index */
00083   int          has_colon = 0 ;
00084   int          ret_val   = 0 ;
00085 
00086   /*
00087      A semicolon at the beginning of optstring has a special meaning.
00088      If we find one, we annote and remove it.
00089   */
00090   has_colon = optstring && optstring[0] == ':' ;
00091   if (has_colon) ++ optstring ;
00092 
00093   /*
00094    Here we are either processing a short option sequence or
00095    we start processing a new option. This is indicated by optreset.
00096   */
00097 
00098   if (optreset || *place == '\0') {
00099 
00100     /* ---------------------------------------------------------------
00101      *                                 Look for next short/long option
00102      * ------------------------------------------------------------ */
00103     optreset = 0 ;
00104 
00105     /* no more arguments ? */
00106     if (optind >= argc) {
00107       place = EMSG ;
00108       return -1 ;
00109     }
00110 
00111     /* next argument that may hold an option */
00112     optbegin = optind ;
00113 
00114     /* ---------------------------------------------------------------
00115      *                                     Look for an option to parse
00116      * ------------------------------------------------------------ */
00117 
00118   parse_option_at_optbegin :
00119 
00120     /* place points to the candidate option */
00121     place = argv [optbegin] ;
00122 
00123     /* an option is introduced by '-' */
00124     if (place [0] != '-') {
00125       /* this argument is not an option: try next argument */
00126       ++ optbegin ;
00127       if (optbegin >= argc) {
00128         /* no more arguments to look for options */
00129         place = EMSG ;
00130         return -1 ;
00131       }
00132       goto parse_option_at_optbegin ;
00133     }
00134 
00135     /* consume leading `-' */
00136     ++ place ;
00137 
00138     /* assume the option is composed of one argument only */
00139     optend = optbegin + 1 ;
00140 
00141     /* assume no argument */
00142     optarg = 0 ;
00143 
00144     /* ---------------------------------------------------------------
00145      *                                                     option `--'
00146      * ------------------------------------------------------------ */
00147 
00148     /* this special option (void long option) ends the option processing */
00149     if (place[0]        &&
00150         place[0] == '-' &&
00151         place[1] == '\0') {
00152 
00153       optind  = optend ;
00154       place   = EMSG ;
00155       ret_val = -1 ;
00156       goto done_option ;
00157     }
00158 
00159     /* ---------------------------------------------------------------
00160      *                                                     long option
00161      * ------------------------------------------------------------ */
00162 
00163     if (place[0]        &&
00164         place[0] == '-' &&
00165         place[1] ) {
00166 
00167       size_t namelen ;
00168       int i ;
00169 
00170       /* consume second `-' */
00171       ++ place ;
00172 
00173       /* count characters before `=' */
00174       namelen = strcspn(place, "=") ;
00175 
00176       /* scan longopts for this option */
00177       for (i = 0 ; longopts[i].name != NULL ; ++ i) {
00178 
00179         if (strlen  (       longopts[i].name) == namelen &&
00180             strncmp (place, longopts[i].name, namelen) == 0 ) {
00181 
00182           /* save back long option index */
00183           if (longindex) *longindex = i ;
00184 
00185           /* process long option argument */
00186           if (longopts[i].has_arg == required_argument ||
00187               longopts[i].has_arg == optional_argument) {
00188 
00189             /* --option=value style */
00190             if (place[namelen] == '=') {
00191               optarg = place + namelen + 1 ;
00192             }
00193 
00194             /* --option value style (only required_argument) */
00195             else if (longopts[i].has_arg == required_argument) {
00196               /* missing argument ? */
00197               if (optbegin >= argc - 1) {
00198                 if (! has_colon && opterr)
00199                   fprintf(stderr,
00200                           "%s: option requires an argument -- %s\n",
00201                           argv[0], place);
00202                 place   = EMSG ;
00203                 ret_val = has_colon ? BADARG : BADCH ;
00204                 goto done_option ;
00205               }
00206               optarg = argv [optend] ;
00207               ++ optend ;
00208             }
00209           }
00210 
00211           /* determine return value */
00212           if (longopts[i].flag == NULL) {
00213             ret_val = longopts[i].val ;
00214           }
00215           else {
00216             *longopts[i].flag = longopts[i].val;
00217             ret_val = 0 ;
00218           }
00219 
00220           /* mark sequence closed */
00221           place = EMSG ;
00222           goto done_option ;
00223         } /* if match */
00224 
00225       } /* scan longoptions */
00226 
00227       /* no matching option found */
00228       if (! has_colon && opterr)
00229         fprintf(stderr,
00230                 "%s: illegal option -- %s\n", argv[0], place) ;
00231       place   = EMSG ;
00232       ret_val = BADCH ;
00233       goto done_option ;
00234     }
00235   } /* end new option */
00236 
00237   /* -----------------------------------------------------------------
00238    *                                      Finish short option sequence
00239    * -------------------------------------------------------------- */
00240   optopt = (int) *place++ ;
00241 
00242   /* search charcater in option list */
00243   oli = strchr(optstring, optopt);
00244 
00245   /* short option not found */
00246   if (!oli) {
00247 
00248     if (! has_colon && opterr)
00249       fprintf(stderr,
00250               "%s: illegal option -- %c\n",
00251               argv[0], optopt);
00252 
00253     if (*place) {
00254       /* more short options in the list */
00255       return BADCH ;
00256     }
00257 
00258     else {
00259       /* error occured as last option in the list */
00260       place   = EMSG ;
00261       ret_val = BADCH ;
00262       goto done_option ;
00263     }
00264   } /* end short option not found */
00265 
00266   if (oli[1] != ':') {
00267     /* short option with no argument */
00268 
00269     if (*place) {
00270       /* more short options in the list */
00271       return optopt ;
00272     }
00273     else {
00274       /* last option in the list */
00275       place   = EMSG ;
00276       ret_val = optopt ;
00277       goto done_option ;
00278     }
00279 
00280   } else {
00281     /* short option with argument */
00282 
00283     /* -ovalue style */
00284     if (*place) {
00285       optarg  = place ;
00286       place   = EMSG ;
00287       ret_val = optopt ;
00288       goto done_option ;
00289     }
00290     /* -o value style: missing argument */
00291     else if (optbegin >= argc - 1) {
00292       if (! has_colon && opterr)
00293         fprintf(stderr,
00294                 "%s: option requires an argument -- %c\n",
00295                 argv[0], optopt);
00296       place   = EMSG ;
00297       ret_val = has_colon ? BADARG : BADCH ;
00298       goto done_option ;
00299     }
00300 
00301     /* -o value style: process argument */
00302     optarg = argv [optend] ;
00303     ++ optend ;
00304     place   = EMSG ;
00305     ret_val = optopt ;
00306     goto done_option ;
00307   } /* short with argument */
00308 
00309  done_option :
00310   {
00311     int pos = optend - optbegin ;  /* n of circular shifts */
00312     int c   = pos ;
00313 
00314     while (c --) {
00315       int i ;
00316       char *tmp = argv [optend - 1] ;
00317       for (i = optend - 1 ; i > optind ; -- i) {
00318         ((char**)argv) [i] = argv [i-1] ;
00319       }
00320       ((char**)argv) [optind] = tmp ;
00321     }
00322     optind += pos ;
00323   }
00324 
00325   return ret_val ;
00326 }


libvlfeat
Author(s): Andrea Vedaldi
autogenerated on Thu Jun 6 2019 20:25:51