You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

xgetopt.c 6.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. // XGetopt.cpp Version 1.2
  2. //
  3. // Author: Hans Dietrich
  4. // hdietrich2@hotmail.com
  5. //
  6. // Description:
  7. // XGetopt.cpp implements getopt(), a function to parse command lines.
  8. //
  9. // History
  10. // Version 1.2 - 2003 May 17
  11. // - Added Unicode support
  12. //
  13. // Version 1.1 - 2002 March 10
  14. // - Added example to XGetopt.cpp module header
  15. //
  16. // This software is released into the public domain.
  17. // You are free to use it in any way you like.
  18. //
  19. // This software is provided "as is" with no expressed
  20. // or implied warranty. I accept no liability for any
  21. // damage or loss of business that this software may cause.
  22. //
  23. ///////////////////////////////////////////////////////////////////////////////
  24. ///////////////////////////////////////////////////////////////////////////////
  25. // if you are using precompiled headers then include this line:
  26. //#include "stdafx.h"
  27. ///////////////////////////////////////////////////////////////////////////////
  28. ///////////////////////////////////////////////////////////////////////////////
  29. // if you are not using precompiled headers then include these lines:
  30. //#include
  31. //#include
  32. //#include
  33. ///////////////////////////////////////////////////////////////////////////////
  34. #include <stdio.h>
  35. #include <string.h>
  36. #include "xgetopt.h"
  37. ///////////////////////////////////////////////////////////////////////////////
  38. //
  39. // X G e t o p t . c p p
  40. //
  41. //
  42. // NAME
  43. // getopt -- parse command line options
  44. //
  45. // SYNOPSIS
  46. // int getopt(int argc, char *argv[], char *optstring)
  47. //
  48. // extern char *optarg;
  49. // extern int optind;
  50. //
  51. // DESCRIPTION
  52. // The getopt() function parses the command line arguments. Its
  53. // arguments argc and argv are the argument count and array as
  54. // passed into the application on program invocation. In the case
  55. // of Visual C++ programs, argc and argv are available via the
  56. // variables __argc and __argv (double underscores), respectively.
  57. // getopt returns the next option letter in argv that matches a
  58. // letter in optstring. (Note: Unicode programs should use
  59. // __targv instead of __argv. Also, all character and string
  60. // literals should be enclosed in _T( ) ).
  61. //
  62. // optstring is a string of recognized option letters; if a letter
  63. // is followed by a colon, the option is expected to have an argument
  64. // that may or may not be separated from it by white space. optarg
  65. // is set to point to the start of the option argument on return from
  66. // getopt.
  67. //
  68. // Option letters may be combined, e.g., "-ab" is equivalent to
  69. // "-a -b". Option letters are case sensitive.
  70. //
  71. // getopt places in the external variable optind the argv index
  72. // of the next argument to be processed. optind is initialized
  73. // to 0 before the first call to getopt.
  74. //
  75. // When all options have been processed (i.e., up to the first
  76. // non-option argument), getopt returns EOF, optarg will point
  77. // to the argument, and optind will be set to the argv index of
  78. // the argument. If there are no non-option arguments, optarg
  79. // will be set to NULL.
  80. //
  81. // The special option "--" may be used to delimit the end of the
  82. // options; EOF will be returned, and "--" (and everything after it)
  83. // will be skipped.
  84. //
  85. // RETURN VALUE
  86. // For option letters contained in the string optstring, getopt
  87. // will return the option letter. getopt returns a question mark (?)
  88. // when it encounters an option letter not included in optstring.
  89. // EOF is returned when processing is finished.
  90. //
  91. // BUGS
  92. // 1) Long options are not supported.
  93. // 2) The GNU double-colon extension is not supported.
  94. // 3) The environment variable POSIXLY_CORRECT is not supported.
  95. // 4) The + syntax is not supported.
  96. // 5) The automatic permutation of arguments is not supported.
  97. // 6) This implementation of getopt() returns EOF if an error is
  98. // encountered, instead of -1 as the latest standard requires.
  99. //
  100. // EXAMPLE
  101. // BOOL CMyApp::ProcessCommandLine(int argc, char *argv[])
  102. // {
  103. // int c;
  104. //
  105. // while ((c = getopt(argc, argv, _T("aBn:"))) != EOF)
  106. // {
  107. // switch (c)
  108. // {
  109. // case _T('a'):
  110. // TRACE(_T("option a\n"));
  111. // //
  112. // // set some flag here
  113. // //
  114. // break;
  115. //
  116. // case _T('B'):
  117. // TRACE( _T("option B\n"));
  118. // //
  119. // // set some other flag here
  120. // //
  121. // break;
  122. //
  123. // case _T('n'):
  124. // TRACE(_T("option n: value=%d\n"), atoi(optarg));
  125. // //
  126. // // do something with value here
  127. // //
  128. // break;
  129. //
  130. // case _T('?'):
  131. // TRACE(_T("ERROR: illegal option %s\n"), argv[optind-1]);
  132. // return FALSE;
  133. // break;
  134. //
  135. // default:
  136. // TRACE(_T("WARNING: no handler for option %c\n"), c);
  137. // return FALSE;
  138. // break;
  139. // }
  140. // }
  141. // //
  142. // // check for non-option args here
  143. // //
  144. // return TRUE;
  145. // }
  146. //
  147. ///////////////////////////////////////////////////////////////////////////////
  148. char *optarg; // global argument pointer
  149. int optind = 0; // global argv index
  150. int getopt(int argc, char *argv[], char *optstring)
  151. {
  152. char c = 0;
  153. char *cp = NULL;
  154. static char *next = NULL;
  155. if (optind == 0)
  156. next = NULL;
  157. optarg = NULL;
  158. if (next == NULL || *next == '\0') {
  159. if (optind == 0)
  160. optind++;
  161. if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0') {
  162. optarg = NULL;
  163. if (optind < argc)
  164. optarg = argv[optind];
  165. return EOF;
  166. }
  167. if (strcmp(argv[optind], "--") == 0) {
  168. optind++;
  169. optarg = NULL;
  170. if (optind < argc)
  171. optarg = argv[optind];
  172. return EOF;
  173. }
  174. next = argv[optind];
  175. next++; // skip past -
  176. optind++;
  177. }
  178. c = *next++;
  179. cp = strchr(optstring, c);
  180. if (cp == NULL || c == ':')
  181. return '?';
  182. cp++;
  183. if (*cp == ':') {
  184. if (*next != '\0') {
  185. optarg = next;
  186. next = NULL;
  187. } else if (optind < argc) {
  188. optarg = argv[optind];
  189. optind++;
  190. } else {
  191. return '?';
  192. }
  193. }
  194. return c;
  195. }