VLFeat.org

API docs

  • Home
    • Download and Install
    • API docs
    • Matlab docs
    • About VLFeat
  • Tutorials
    • SIFT
    • MSER
    • IKM
    • HIKM
    • AIB
    • Utils
  • Main Page
  • Related Pages
  • Data Structures
  • Files
  • Examples

getopt_long.c

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