00001 // XGetopt.cpp Version 1.1 00002 // 00003 // Author: Hans Dietrich 00004 // hdietrich2@hotmail.com 00005 // 00006 // Modified: David Smith 00007 // dave.s@earthcorp.com 00008 // Moved two char declarations from body of function so 00009 // that it can compile as a C function. 00010 // Thanks so much Hans 00011 // 00012 // This software is released into the public domain. 00013 // You are free to use it in any way you like. 00014 // 00015 // This software is provided "as is" with no expressed 00016 // or implied warranty. I accept no liability for any 00017 // damage or loss of business that this software may cause. 00018 // 00020 00021 #ifndef __MINGW32__ /* mingw has getopt() */ 00022 00023 #include "define.h" 00024 00025 00027 // 00028 // X G e t o p t . c p p 00029 // 00030 // 00031 // NAME 00032 // getopt -- parse command line options 00033 // 00034 // SYNOPSIS 00035 // int getopt(int argc, char* const* argv, const char *optstring) 00036 // 00037 // extern char *optarg; 00038 // extern int optind; 00039 // 00040 // DESCRIPTION 00041 // The getopt() function parses the command line arguments. Its 00042 // arguments argc and argv are the argument count and array as 00043 // passed into the application on program invocation. In the case 00044 // of Visual C++ programs, argc and argv are available via the 00045 // variables __argc and __argv (double underscores), respectively. 00046 // getopt returns the next option letter in argv that matches a 00047 // letter in optstring. 00048 // 00049 // optstring is a string of recognized option letters; if a letter 00050 // is followed by a colon, the option is expected to have an argument 00051 // that may or may not be separated from it by white space. optarg 00052 // is set to point to the start of the option argument on return from 00053 // getopt. 00054 // 00055 // Option letters may be combined, e.g., "-ab" is equivalent to 00056 // "-a -b". Option letters are case sensitive. 00057 // 00058 // getopt places in the external variable optind the argv index 00059 // of the next argument to be processed. optind is initialized 00060 // to 0 before the first call to getopt. 00061 // 00062 // When all options have been processed (i.e., up to the first 00063 // non-option argument), getopt returns EOF, optarg will point 00064 // to the argument, and optind will be set to the argv index of 00065 // the argument. If there are no non-option arguments, optarg 00066 // will be set to NULL. 00067 // 00068 // The special option "--" may be used to delimit the end of the 00069 // options; EOF will be returned, and "--" (and everything after it) 00070 // will be skipped. 00071 // 00072 // RETURN VALUE 00073 // For option letters contained in the string optstring, getopt 00074 // will return the option letter. getopt returns a question mark (?) 00075 // when it encounters an option letter not included in optstring. 00076 // EOF is returned when processing is finished. 00077 // 00078 // BUGS 00079 // 1) Long options are not supported. 00080 // 2) The GNU double-colon extension is not supported. 00081 // 3) The environment variable POSIXLY_CORRECT is not supported. 00082 // 4) The + syntax is not supported. 00083 // 5) The automatic permutation of arguments is not supported. 00084 // 6) This implementation of getopt() returns EOF if an error is 00085 // encountered, instead of -1 as the latest standard requires. 00086 // 00087 // EXAMPLE 00088 // BOOL CMyApp::ProcessCommandLine(int argc, char *argv[]) 00089 // { 00090 // int c; 00091 // 00092 // while ((c = getopt(argc, argv, "aBn:")) != EOF) 00093 // { 00094 // switch (c) 00095 // { 00096 // case 'a': 00097 // TRACE(_T("option a\n")); 00098 // // 00099 // // set some flag here 00100 // // 00101 // break; 00102 // 00103 // case 'B': 00104 // TRACE( _T("option B\n")); 00105 // // 00106 // // set some other flag here 00107 // // 00108 // break; 00109 // 00110 // case 'n': 00111 // TRACE(_T("option n: value=%d\n"), atoi(optarg)); 00112 // // 00113 // // do something with value here 00114 // // 00115 // break; 00116 // 00117 // case '?': 00118 // TRACE(_T("ERROR: illegal option %s\n"), argv[optind-1]); 00119 // return FALSE; 00120 // break; 00121 // 00122 // default: 00123 // TRACE(_T("WARNING: no handler for option %c\n"), c); 00124 // return FALSE; 00125 // break; 00126 // } 00127 // } 00128 // // 00129 // // check for non-option args here 00130 // // 00131 // return TRUE; 00132 // } 00133 // 00135 00136 char *optarg; // global argument pointer 00137 int optind = 0; // global argv index 00138 00139 int getopt(int argc, char* const* argv, char *optstring) 00140 { 00141 static char *next = NULL; 00142 char c, *cp; 00143 if (optind == 0) 00144 next = NULL; 00145 00146 optarg = NULL; 00147 00148 if (next == NULL || *next == '\0') 00149 { 00150 if (optind == 0) 00151 optind++; 00152 00153 if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0') 00154 { 00155 optarg = NULL; 00156 if (optind < argc) 00157 optarg = argv[optind]; 00158 return EOF; 00159 } 00160 00161 if (strcmp(argv[optind], "--") == 0) 00162 { 00163 optind++; 00164 optarg = NULL; 00165 if (optind < argc) 00166 optarg = argv[optind]; 00167 return EOF; 00168 } 00169 00170 next = argv[optind]+1; 00171 optind++; 00172 } 00173 00174 c = *next++; 00175 cp = strchr(optstring, c); 00176 00177 if (cp == NULL || c == ':') 00178 return '?'; 00179 00180 cp++; 00181 if (*cp == ':') 00182 { 00183 if (*next != '\0') 00184 { 00185 optarg = next; 00186 next = NULL; 00187 } 00188 else if (optind < argc) 00189 { 00190 optarg = argv[optind]; 00191 optind++; 00192 } 00193 else 00194 { 00195 return '?'; 00196 } 00197 } 00198 00199 return c; 00200 } 00201 00202 #endif /* !__MINGW32__ */