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