getoptv.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /*====================================================================*
  2. *
  3. * int getoptv (int argc, char const * argv[], char const * optv[]);
  4. *
  5. * getoptv.h
  6. *
  7. * this is a posix compliant getopt() function that supports no
  8. * extensions; see the posix website for specification details;
  9. *
  10. * <http://www.opengroup.org/onlinepubs/007904975/functions/getopt.html>
  11. *
  12. * we implemented this function to ensure that linux and windows
  13. * consoles act the same; microsoft c++ would not compile the
  14. * debian version of getopt and so, after trying to fix things,
  15. * we decided to start fresh; the debian version is too complex;
  16. *
  17. * this function conforms to posix standard; it does not support
  18. * gnu style extensions like "--option" for arguments or "ab::c"
  19. * for operands; if you don't know what that means then you won't
  20. * care, either; you should avoid such extentions, anyway;
  21. *
  22. * the posix standard says that command options and operands must
  23. * precede other arguments; this version of getopt allows options
  24. * and operands to appear anywhere and makes non-compliant argv[]
  25. * compliant in the process;
  26. *
  27. * we define characters instead of coding them so that microsoft
  28. * folks can use '/' instead of '-' and still preserve the posix
  29. * behaviour;
  30. *
  31. * we declare optarg as "char const *" so that the target cannot
  32. * be changed by the application; this is not POSIX compliant so
  33. * it will conflict with other getopt variants; getopt.h is often
  34. * included with unistd.h which is a common file;
  35. *
  36. * systems.
  37. *
  38. * this version calls virtually no functions and should compile
  39. * on any posix system;
  40. *
  41. * you may include getoptv.h or declare these variables:
  42. *
  43. * extern char const *optarg;
  44. * extern int optopt;
  45. * extern int optind;
  46. * extern int opterr;
  47. *
  48. * you may cut and paste this c language code segment to get you
  49. * started; you must insert your own code and case breaks;
  50. *
  51. * signed c;
  52. * optind = 1;
  53. * opterr = 1;
  54. *
  55. * while ((c = getoptv(argc, argv, * optv)) != -1)
  56. * {
  57. * switch(c)
  58. * {
  59. * case 'a': // optopt is 'a'; optarg is NULL;
  60. * case 'b': // optopt is 'b'; optarg is operand;
  61. * case ':': // optopt is option; optarg is NULL; missing operand;
  62. * case '?': // optopt is option; optarg is NULL; illegal option;
  63. * default: // optopt is option: optarg is NULL; illegal option;
  64. * }
  65. * }
  66. *
  67. * after options and operands are processed, optind points to
  68. * the next argv [] string; loop until optind equals argc or
  69. * argv[optind] is NULL; we check both but either will do;
  70. *
  71. * while ((optind < argc) && (argv [optind]))
  72. * {
  73. * // do stuff to argv[optind++].
  74. * }
  75. *
  76. * alternately, and even better, the following works just fine:
  77. *
  78. * argc -= optind;
  79. * argv += optind;
  80. * while ((argc) && (* argv))
  81. * {
  82. * // do stuff to * argv.
  83. *
  84. * }
  85. *
  86. * Motley Tools by Charles Maier;
  87. * Copyright (c) 2001-2006 by Charles Maier Associates;
  88. * licensed under the Internet Software Consortium License;
  89. *
  90. *--------------------------------------------------------------------*/
  91. #ifndef GETOPTV_SOURCE
  92. #define GETOPTV_SOURCE
  93. #include <stdio.h>
  94. #include <stdlib.h>
  95. #include <string.h>
  96. #include "../tools/getoptv.h"
  97. #include "../tools/putoptv.h"
  98. #include "../tools/version.h"
  99. #include "../tools/error.h"
  100. char const * program_name = "program";
  101. char * optarg = (char *) (0);
  102. signed optopt = (char) (0);
  103. signed optind = 1;
  104. signed opterr = 1;
  105. signed optmin = 0;
  106. signed getoptv (int argc, char const * argv [], char const * optv [])
  107. {
  108. static char const * string;
  109. static char const * option;
  110. static signed count;
  111. signed index;
  112. if ((optind == 0) || (optind == 1))
  113. {
  114. for (program_name = string = * argv; * string; string++)
  115. {
  116. if ((* string == '/') || (* string == '\\'))
  117. {
  118. program_name = string + 1;
  119. }
  120. }
  121. string = (char *) (0);
  122. if (argc == optmin)
  123. {
  124. putoptv (optv);
  125. exit (0);
  126. }
  127. count = optind = 1;
  128. }
  129. while ((count < argc) || (string))
  130. {
  131. if (string)
  132. {
  133. if (*string)
  134. {
  135. optarg = (char *) (0);
  136. optopt = *string++;
  137. for (option = * optv; * option; option++)
  138. {
  139. if (optopt == GETOPTV_C_OPERAND)
  140. {
  141. continue;
  142. }
  143. if (*option == GETOPTV_C_OPERAND)
  144. {
  145. continue;
  146. }
  147. if (*option == optopt)
  148. {
  149. option++;
  150. if (*option != GETOPTV_C_OPERAND)
  151. {
  152. return (optopt);
  153. }
  154. if (*string)
  155. {
  156. optarg = (char *) (string);
  157. string = (char *) (0);
  158. return (optopt);
  159. }
  160. if (count < argc)
  161. {
  162. optarg = (char *)(argv [count]);
  163. for (index = count++; index > optind; index--)
  164. {
  165. argv [index] = argv [index - 1];
  166. }
  167. argv [optind++] = optarg;
  168. return (optopt);
  169. }
  170. if (opterr)
  171. {
  172. error (1, 0, "option '%c' needs an operand.", optopt);
  173. }
  174. if (** optv == GETOPTV_C_OPERAND)
  175. {
  176. return (GETOPTV_C_OPERAND);
  177. }
  178. return (GETOPTV_C_ILLEGAL);
  179. }
  180. }
  181. if (opterr)
  182. {
  183. error (1, 0, "option '%c' has no meaning.", optopt);
  184. }
  185. return (GETOPTV_C_ILLEGAL);
  186. }
  187. else
  188. {
  189. string = (char *) (0);
  190. }
  191. }
  192. if (count < argc)
  193. {
  194. string = argv [count];
  195. if (*string == GETOPTV_C_OPTION)
  196. {
  197. for (index = count; index > optind; index--)
  198. {
  199. argv [index] = argv [index - 1];
  200. }
  201. argv [optind++] = string++;
  202. if (*string == GETOPTV_C_VERSION)
  203. {
  204. version ();
  205. exit (0);
  206. }
  207. if (*string == GETOPTV_C_SUMMARY)
  208. {
  209. putoptv (optv);
  210. exit (0);
  211. }
  212. if (*string == GETOPTV_C_OPTION)
  213. {
  214. string++;
  215. if (!strcmp (string, ""))
  216. {
  217. optarg = (char *) (0);
  218. optopt = (char) (0);
  219. return (-1);
  220. }
  221. if (!strcmp (string, "version"))
  222. {
  223. version ();
  224. exit (0);
  225. }
  226. if (!strcmp (string, "help"))
  227. {
  228. putoptv (optv);
  229. exit (0);
  230. }
  231. optarg = (char *)(string);
  232. optopt = GETOPTV_C_OPTION;
  233. return (-1);
  234. }
  235. }
  236. else
  237. {
  238. string = (char *) (0);
  239. }
  240. count++;
  241. }
  242. }
  243. optarg = (char *) (0);
  244. optopt = (char) (0);
  245. return (-1);
  246. }
  247. #endif