+// XGetopt.cpp Version 1.2\r
+//\r
+// Author: Hans Dietrich\r
+// hdietrich2@hotmail.com\r
+//\r
+// Description:\r
+// XGetopt.cpp implements getopt(), a function to parse command lines.\r
+//\r
+// History\r
+// Version 1.2 - 2003 May 17\r
+// - Added Unicode support\r
+//\r
+// Version 1.1 - 2002 March 10\r
+// - Added example to XGetopt.cpp module header \r
+//\r
+// This software is released into the public domain.\r
+// You are free to use it in any way you like.\r
+//\r
+// This software is provided "as is" with no expressed\r
+// or implied warranty. I accept no liability for any\r
+// damage or loss of business that this software may cause.\r
+//\r
+///////////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+\r
+///////////////////////////////////////////////////////////////////////////////\r
+// if you are not using precompiled headers then include these lines:\r
+#include <windows.h>\r
+#include <stdio.h>\r
+///////////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+#include "XGetopt.h"\r
+\r
+\r
+///////////////////////////////////////////////////////////////////////////////\r
+//\r
+// X G e t o p t . c p p\r
+//\r
+//\r
+// NAME\r
+// getopt -- parse command line options\r
+//\r
+// SYNOPSIS\r
+// int getopt(int argc, char *argv[], char *optstring)\r
+//\r
+// extern char *optarg;\r
+// extern int optind;\r
+//\r
+// DESCRIPTION\r
+// The getopt() function parses the command line arguments. Its\r
+// arguments argc and argv are the argument count and array as\r
+// passed into the application on program invocation. In the case\r
+// of Visual C++ programs, argc and argv are available via the\r
+// variables __argc and __argv (double underscores), respectively.\r
+// getopt returns the next option letter in argv that matches a\r
+// letter in optstring. (Note: Unicode programs should use\r
+// __targv instead of __argv. Also, all character and string\r
+// literals should be enclosed in _T( ) ).\r
+//\r
+// optstring is a string of recognized option letters; if a letter\r
+// is followed by a colon, the option is expected to have an argument\r
+// that may or may not be separated from it by white space. optarg\r
+// is set to point to the start of the option argument on return from\r
+// getopt.\r
+//\r
+// Option letters may be combined, e.g., "-ab" is equivalent to\r
+// "-a -b". Option letters are case sensitive.\r
+//\r
+// getopt places in the external variable optind the argv index\r
+// of the next argument to be processed. optind is initialized\r
+// to 0 before the first call to getopt.\r
+//\r
+// When all options have been processed (i.e., up to the first\r
+// non-option argument), getopt returns EOF, optarg will point\r
+// to the argument, and optind will be set to the argv index of\r
+// the argument. If there are no non-option arguments, optarg\r
+// will be set to NULL.\r
+//\r
+// The special option "--" may be used to delimit the end of the\r
+// options; EOF will be returned, and "--" (and everything after it)\r
+// will be skipped.\r
+//\r
+// RETURN VALUE\r
+// For option letters contained in the string optstring, getopt\r
+// will return the option letter. getopt returns a question mark (?)\r
+// when it encounters an option letter not included in optstring.\r
+// EOF is returned when processing is finished.\r
+//\r
+// BUGS\r
+// 1) Long options are not supported.\r
+// 2) The GNU double-colon extension is not supported.\r
+// 3) The environment variable POSIXLY_CORRECT is not supported.\r
+// 4) The + syntax is not supported.\r
+// 5) The automatic permutation of arguments is not supported.\r
+// 6) This implementation of getopt() returns EOF if an error is\r
+// encountered, instead of -1 as the latest standard requires.\r
+//\r
+// EXAMPLE\r
+// BOOL CMyApp::ProcessCommandLine(int argc, char *argv[])\r
+// {\r
+// int c;\r
+//\r
+// while ((c = getopt(argc, argv, "aBn:")) != EOF)\r
+// {\r
+// switch (c)\r
+// {\r
+// case 'a':\r
+// TRACE("option a\n");\r
+// //\r
+// // set some flag here\r
+// //\r
+// break;\r
+//\r
+// case 'B':\r
+// TRACE( "option B\n");\r
+// //\r
+// // set some other flag here\r
+// //\r
+// break;\r
+//\r
+// case 'n':\r
+// TRACE("option n: value=%d\n", atoi(optarg));\r
+// //\r
+// // do something with value here\r
+// //\r
+// break;\r
+//\r
+// case '?':\r
+// TRACE("ERROR: illegal option %s\n", argv[optind-1]);\r
+// return FALSE;\r
+// break;\r
+//\r
+// default:\r
+// TRACE("WARNING: no handler for option %c\n", c);\r
+// return FALSE;\r
+// break;\r
+// }\r
+// }\r
+// //\r
+// // check for non-option args here\r
+// //\r
+// return TRUE;\r
+// }\r
+//\r
+///////////////////////////////////////////////////////////////////////////////\r
+\r
+char *optarg; // global argument pointer\r
+int optind = 0; // global argv index\r
+\r
+int getopt(int argc, char *argv[], char *optstring)\r
+{\r
+ static char *next = NULL;\r
+ char c;\r
+ char *cp;\r
+\r
+ if (optind == 0)\r
+ next = NULL;\r
+\r
+ optarg = NULL;\r
+\r
+ if (next == NULL || *next == '\0')\r
+ {\r
+ if (optind == 0)\r
+ optind++;\r
+\r
+ if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')\r
+ {\r
+ optarg = NULL;\r
+ if (optind < argc)\r
+ optarg = argv[optind];\r
+ return EOF;\r
+ }\r
+\r
+ if (strcmp(argv[optind], "--") == 0)\r
+ {\r
+ optind++;\r
+ optarg = NULL;\r
+ if (optind < argc)\r
+ optarg = argv[optind];\r
+ return EOF;\r
+ }\r
+\r
+ next = argv[optind];\r
+ next++; // skip past -\r
+ optind++;\r
+ }\r
+\r
+ c = *next++;\r
+ cp = strchr(optstring, c);\r
+\r
+ if (cp == NULL || c == ':')\r
+ return '?';\r
+\r
+ cp++;\r
+ if (*cp == ':')\r
+ {\r
+ if (*next != '\0')\r
+ {\r
+ optarg = next;\r
+ next = NULL;\r
+ }\r
+ else if (optind < argc)\r
+ {\r
+ optarg = argv[optind];\r
+ optind++;\r
+ }\r
+ else\r
+ {\r
+ return '?';\r
+ }\r
+ }\r
+\r
+ return c;\r
+}\r