Newer
Older
monitord / simpleopt / .svn / text-base / fullSample.cpp.svn-base
  1. // File: fullSample.cpp
  2. // Library: SimpleOpt
  3. // Author: Brodie Thiesfield <code@jellycan.com>
  4. // Source: http://code.jellycan.com/simpleopt/
  5. //
  6. // MIT LICENCE
  7. // ===========
  8. // The licence text below is the boilerplate "MIT Licence" used from:
  9. // http://www.opensource.org/licenses/mit-license.php
  10. //
  11. // Copyright (c) 2006, Brodie Thiesfield
  12. //
  13. // Permission is hereby granted, free of charge, to any person obtaining a copy
  14. // of this software and associated documentation files (the "Software"), to deal
  15. // in the Software without restriction, including without limitation the rights
  16. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  17. // copies of the Software, and to permit persons to whom the Software is furnished
  18. // to do so, subject to the following conditions:
  19. //
  20. // The above copyright notice and this permission notice shall be included in
  21. // all copies or substantial portions of the Software.
  22. //
  23. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  24. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  25. // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  26. // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  27. // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  28. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  29.  
  30. #if defined(_MSC_VER)
  31. # include <windows.h>
  32. # include <tchar.h>
  33. #else
  34. # define TCHAR char
  35. # define _T(x) x
  36. # define _tprintf printf
  37. # define _tmain main
  38. # define _ttoi atoi
  39. #endif
  40.  
  41. #include <stdio.h>
  42. #include <locale.h>
  43. #include "SimpleOpt.h"
  44. #include "SimpleGlob.h"
  45.  
  46. static void ShowUsage()
  47. {
  48. _tprintf(
  49. _T("Usage: fullSample [OPTIONS] [FILES]\n")
  50. _T("\n")
  51. _T("--exact Disallow partial matching of option names\n")
  52. _T("--noslash Disallow use of slash as an option marker on Windows\n")
  53. _T("--shortarg Permit arguments on single letter options with no equals sign\n")
  54. _T("--clump Permit single char options to be clumped as long string\n")
  55. _T("--noerr Do not generate any errors for invalid options\n")
  56. _T("--pedantic Generate an error for petty things\n")
  57. _T("\n")
  58. _T("-d -e -f -g -flag --flag Flag (no arg)\n")
  59. _T("-s ARG -sep ARG --sep ARG Separate required arg\n")
  60. _T("-cARG -c=ARG -com=ARG --com=ARG Combined required arg\n")
  61. _T("-o[ARG] -o[=ARG] -opt[=ARG] --opt[=ARG] Combined optional arg\n")
  62. _T("-man -mandy -mandate Shortcut matching tests\n")
  63. _T("--man --mandy --mandate Shortcut matching tests\n")
  64. _T("--multi0 --multi1 ARG --multi2 ARG1 ARG2 Multiple argument tests\n")
  65. _T("--multi N ARG-1 ARG-2 ... ARG-N Multiple argument tests\n")
  66. _T("open read write close zip unzip Special words\n")
  67. _T("\n")
  68. _T("-? -h -help --help Output this help.\n")
  69. _T("\n")
  70. _T("If a FILE is `-', read standard input.\n")
  71. );
  72. }
  73.  
  74. CSimpleOpt::SOption g_rgFlags[] =
  75. {
  76. { SO_O_EXACT, _T("--exact"), SO_NONE },
  77. { SO_O_NOSLASH, _T("--noslash"), SO_NONE },
  78. { SO_O_SHORTARG, _T("--shortarg"), SO_NONE },
  79. { SO_O_CLUMP, _T("--clump"), SO_NONE },
  80. { SO_O_NOERR, _T("--noerr"), SO_NONE },
  81. { SO_O_PEDANTIC, _T("--pedantic"), SO_NONE },
  82. SO_END_OF_OPTIONS
  83. };
  84.  
  85. enum { OPT_HELP = 0, OPT_MULTI = 100, OPT_MULTI0, OPT_MULTI1, OPT_MULTI2 };
  86. CSimpleOpt::SOption g_rgOptions[] =
  87. {
  88. { OPT_HELP, _T("-?"), SO_NONE },
  89. { OPT_HELP, _T("-h"), SO_NONE },
  90. { OPT_HELP, _T("-help"), SO_NONE },
  91. { OPT_HELP, _T("--help"), SO_NONE },
  92. { 1, _T("-"), SO_NONE },
  93. { 2, _T("-d"), SO_NONE },
  94. { 3, _T("-e"), SO_NONE },
  95. { 4, _T("-f"), SO_NONE },
  96. { 5, _T("-g"), SO_NONE },
  97. { 6, _T("-flag"), SO_NONE },
  98. { 7, _T("--flag"), SO_NONE },
  99. { 8, _T("-s"), SO_REQ_SEP },
  100. { 9, _T("-sep"), SO_REQ_SEP },
  101. { 10, _T("--sep"), SO_REQ_SEP },
  102. { 11, _T("-c"), SO_REQ_CMB },
  103. { 12, _T("-com"), SO_REQ_CMB },
  104. { 13, _T("--com"), SO_REQ_CMB },
  105. { 14, _T("-o"), SO_OPT },
  106. { 15, _T("-opt"), SO_OPT },
  107. { 16, _T("--opt"), SO_OPT },
  108. { 17, _T("-man"), SO_NONE },
  109. { 18, _T("-mandy"), SO_NONE },
  110. { 19, _T("-mandate"), SO_NONE },
  111. { 20, _T("--man"), SO_NONE },
  112. { 21, _T("--mandy"), SO_NONE },
  113. { 22, _T("--mandate"), SO_NONE },
  114. { 23, _T("open"), SO_NONE },
  115. { 24, _T("read"), SO_NONE },
  116. { 25, _T("write"), SO_NONE },
  117. { 26, _T("close"), SO_NONE },
  118. { 27, _T("zip"), SO_NONE },
  119. { 28, _T("unzip"), SO_NONE },
  120. { OPT_MULTI, _T("--multi"), SO_MULTI },
  121. { OPT_MULTI0, _T("--multi0"), SO_MULTI },
  122. { OPT_MULTI1, _T("--multi1"), SO_MULTI },
  123. { OPT_MULTI2, _T("--multi2"), SO_MULTI },
  124. SO_END_OF_OPTIONS
  125. };
  126.  
  127. void ShowFiles(int argc, TCHAR ** argv) {
  128. // glob files to catch expand wildcards
  129. CSimpleGlob glob(SG_GLOB_NODOT|SG_GLOB_NOCHECK);
  130. if (SG_SUCCESS != glob.Add(argc, argv)) {
  131. _tprintf(_T("Error while globbing files\n"));
  132. return;
  133. }
  134.  
  135. for (int n = 0; n < glob.FileCount(); ++n) {
  136. _tprintf(_T("file %2d: '%s'\n"), n, glob.File(n));
  137. }
  138. }
  139.  
  140. static const TCHAR *
  141. GetLastErrorText(
  142. int a_nError
  143. )
  144. {
  145. switch (a_nError) {
  146. case SO_SUCCESS: return _T("Success");
  147. case SO_OPT_INVALID: return _T("Unrecognized option");
  148. case SO_OPT_MULTIPLE: return _T("Option matched multiple strings");
  149. case SO_ARG_INVALID: return _T("Option does not accept argument");
  150. case SO_ARG_INVALID_TYPE: return _T("Invalid argument format");
  151. case SO_ARG_MISSING: return _T("Required argument is missing");
  152. case SO_ARG_INVALID_DATA: return _T("Invalid argument data");
  153. default: return _T("Unknown error");
  154. }
  155. }
  156.  
  157. static void
  158. DoMultiArgs(
  159. CSimpleOpt & args,
  160. int nMultiArgs
  161. )
  162. {
  163. TCHAR ** rgpszArg = NULL;
  164.  
  165. // get the number of arguments if necessary
  166. if (nMultiArgs == -1) {
  167. // first arg is a count of how many we have
  168. rgpszArg = args.MultiArg(1);
  169. if (!rgpszArg) {
  170. _tprintf(
  171. _T("%s: '%s' (use --help to get command line help)\n"),
  172. GetLastErrorText(args.LastError()), args.OptionText());
  173. return;
  174. }
  175.  
  176. nMultiArgs = _ttoi(rgpszArg[0]);
  177. }
  178. _tprintf(_T("%s: expecting %d args\n"), args.OptionText(), nMultiArgs);
  179.  
  180. // get the arguments to follow
  181. rgpszArg = args.MultiArg(nMultiArgs);
  182. if (!rgpszArg) {
  183. _tprintf(
  184. _T("%s: '%s' (use --help to get command line help)\n"),
  185. GetLastErrorText(args.LastError()), args.OptionText());
  186. return;
  187. }
  188.  
  189. for (int n = 0; n < nMultiArgs; ++n) {
  190. _tprintf(_T("MultiArg %d: %s\n"), n, rgpszArg[n]);
  191. }
  192. }
  193.  
  194.  
  195. int _tmain(int argc, TCHAR * argv[]) {
  196. setlocale( LC_ALL, "Japanese" );
  197.  
  198. // get the flags to use for SimpleOpt from the command line
  199. int nFlags = SO_O_USEALL;
  200. CSimpleOpt flags(argc, argv, g_rgFlags, SO_O_NOERR|SO_O_EXACT);
  201. while (flags.Next()) {
  202. nFlags |= flags.OptionId();
  203. }
  204.  
  205. // now process the remainder of the command line with these flags
  206. CSimpleOpt args(flags.FileCount(), flags.Files(), g_rgOptions, nFlags);
  207. while (args.Next()) {
  208. if (args.LastError() != SO_SUCCESS) {
  209. _tprintf(
  210. _T("%s: '%s' (use --help to get command line help)\n"),
  211. GetLastErrorText(args.LastError()), args.OptionText());
  212. continue;
  213. }
  214.  
  215. switch (args.OptionId()) {
  216. case OPT_HELP:
  217. ShowUsage();
  218. return 0;
  219. case OPT_MULTI:
  220. DoMultiArgs(args, -1);
  221. break;
  222. case OPT_MULTI0:
  223. DoMultiArgs(args, 0);
  224. break;
  225. case OPT_MULTI1:
  226. DoMultiArgs(args, 1);
  227. break;
  228. case OPT_MULTI2:
  229. DoMultiArgs(args, 2);
  230. break;
  231. default:
  232. if (args.OptionArg()) {
  233. _tprintf(_T("option: %2d, text: '%s', arg: '%s'\n"),
  234. args.OptionId(), args.OptionText(), args.OptionArg());
  235. }
  236. else {
  237. _tprintf(_T("option: %2d, text: '%s'\n"),
  238. args.OptionId(), args.OptionText());
  239. }
  240. }
  241. }
  242.  
  243. /* process files from command line */
  244. ShowFiles(args.FileCount(), args.Files());
  245.  
  246. return 0;
  247. }