w_getopt.cpp

00001 /*<std-header orig-src='shore'>
00002 
00003  $Id: w_getopt.cpp,v 1.2 2010/05/26 01:20:25 nhall Exp $
00004 
00005 SHORE -- Scalable Heterogeneous Object REpository
00006 
00007 Copyright (c) 1994-99 Computer Sciences Department, University of
00008                       Wisconsin -- Madison
00009 All Rights Reserved.
00010 
00011 Permission to use, copy, modify and distribute this software and its
00012 documentation is hereby granted, provided that both the copyright
00013 notice and this permission notice appear in all copies of the
00014 software, derivative works or modified versions, and any portions
00015 thereof, and that both notices appear in supporting documentation.
00016 
00017 THE AUTHORS AND THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY
00018 OF WISCONSIN - MADISON ALLOW FREE USE OF THIS SOFTWARE IN ITS
00019 "AS IS" CONDITION, AND THEY DISCLAIM ANY LIABILITY OF ANY KIND
00020 FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
00021 
00022 This software was developed with support by the Advanced Research
00023 Project Agency, ARPA order number 018 (formerly 8230), monitored by
00024 the U.S. Army Research Laboratory under contract DAAB07-91-C-Q518.
00025 Further funding for this work was provided by DARPA through
00026 Rome Research Laboratory Contract No. F30602-97-2-0247.
00027 
00028 */
00029 
00030 #include "w_defines.h"
00031 
00032 /*  -- do not edit anything above this line --   </std-header>*/
00033 
00034 #include "w_getopt.h"
00035 #ifndef HAVE_GETOPT
00036 #include <w_stream.h>
00037 #include <cstring>
00038 
00039 char*        optarg = 0;
00040 int        optind = 1;
00041 int        opterr = 1;    /* print error message by default */
00042 int        optopt = 0;
00043 
00044 /* implements unix (3C) getopt function
00045 
00046    getopt takes the argc and argv variables passed to a program and
00047    extracts option flags and values from them.
00048 
00049    it does this by checking to see if the next argument exists and
00050    begins with a '-'.  if it does then the argument is assumed to
00051    contain a set of flags.  if it does not them the processing returns
00052    EOF and optind is the index into argv where processing stopped.
00053 
00054    if the argument contains a set of flags the value of the flag
00055    is checked to see if it is in the optstring parameter, and if it
00056    is then the flag is valid, if not it is an error.  if the next
00057    character in optstring is a ':' then this signifies that the option
00058    takes a value, which is considered to be the rest of the argument
00059    if there is any or the next argument (it is an error if there is no
00060    next argument) if the flag is at the end of the argument.
00061 
00062    the function returns the option flag if no error occurred, a '?' if
00063    an error occurred, or EOF if the end of the options was found.  optarg
00064    contains the value of the option if the option has one and no error
00065    occurred.  optopt always contains the character for the flag
00066    regardless of an error.  optind contains the argv index where the
00067    next flag will be found or one place beyond where options processing
00068    concluded.
00069 
00070    an argument of "--" signals the end of options processing and causes
00071    getopt to return EOF and to set optind to one beyond where "--" was
00072    found.
00073 
00074    this function is not thread safe since if relies on global variables.
00075    also it is not safe to restart option processing by resetting optind
00076    to 1, until getopt has returned EOF.
00077 
00078    to be compatible with the unix version of getopt, setting optind to
00079    0 now resets option processing to begin at argv[1].  if you wish to
00080    restart option processing at some other argv index you need to first
00081    call getopt repeatedly until it returns EOF, which sets the argIndex
00082    to 0, and then you can set optind to the index value.  both of these
00083    behaviors are non-portable.
00084 */
00085 
00086 int PrintError(const char* errMsg, const char* progName, char optChar);
00087 
00088 int getopt(int argc, char* const * argv, const char* optstring)
00089 {
00090     /* used to keep track of where we are in the arg when multiple flags
00091        are combined in the same argument */
00092     static int    argIndex = 0;
00093 
00094     /* restart option processing if optind is 0 */
00095     if (optind == 0)  {
00096     optind = 1;
00097     argIndex = 0;
00098     }
00099 
00100     optarg = 0;
00101     optopt = 0;
00102 
00103     /* if we've run out of args exit */
00104     if (optind == argc)  {
00105     return EOF;
00106     }
00107 
00108     /* if the current arg doesn't start with '-' exit */
00109     if (argIndex == 0 && argv[optind][0] != '-')  {
00110     return EOF;
00111     }
00112 
00113     /* skip past the '-', if we're looking at one */
00114     if (argIndex == 0)  {
00115     argIndex++;
00116 
00117     /* getopt man page says "--" signals end of args, so check for it */
00118     if (argv[optind][argIndex] == '-' && argv[optind][argIndex + 1] == 0)  {
00119         ++optind;
00120         argIndex = 0;
00121         return EOF;
00122     }
00123     }
00124 
00125     optopt = argv[optind][argIndex++];
00126 
00127     const char* optStringPos = 0;
00128     if ((optStringPos = strchr(optstring, optopt)))  {
00129     if (optStringPos[1] == ':')  {
00130 
00131         /* flag has a value */
00132         if (argv[optind][argIndex] != 0)  {
00133         /* value is the rest of the arg */
00134         optarg = &argv[optind][argIndex];
00135         ++optind;
00136         argIndex = 0;
00137 
00138         }  else  {
00139         /* value is next arg if there is one */
00140         ++optind;
00141         argIndex = 0;
00142         if (argv[optind] != 0)  {
00143             optarg = &argv[optind++][argIndex];
00144         }  else  {
00145             return PrintError("option requires an argument", argv[0], optopt);
00146         }
00147         }
00148     }  else  {
00149         /* flag is just a flag */
00150         if (argv[optind][argIndex] == 0)  {
00151         /* advance to next arg if we are at the end of the current arg */
00152         ++optind;
00153         argIndex = 0;
00154         }
00155     }
00156     }  else  {
00157     /* bad flag */
00158     if (argv[optind][argIndex] == 0)  {
00159         ++optind;
00160         argIndex = 0;
00161     }
00162     return PrintError("illegal option", argv[0], optopt);
00163     }
00164 
00165     return optopt;
00166 }
00167 
00168 
00169 int PrintError(const char* errMsg, const char* progName, char optChar)
00170 {
00171     if (opterr)
00172         cerr << progName << ": " << errMsg << " -- " << optChar << endl;
00173 
00174     return '?';
00175 }
00176 
00177 #endif

Generated on Wed Jul 7 17:22:32 2010 for Shore Storage Manager by  doxygen 1.4.7