ooxml_crypt 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (264) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.md +58 -0
  5. data/Rakefile +12 -0
  6. data/bin/console +15 -0
  7. data/bin/setup +8 -0
  8. data/ext/ooxml_crypt/extconf.rb +18 -0
  9. data/ext/ooxml_crypt/ooxml_crypt.c +27 -0
  10. data/ext/ooxml_crypt/ooxml_crypt.h +7 -0
  11. data/lib/ooxml_crypt/version.rb +5 -0
  12. data/lib/ooxml_crypt.rb +75 -0
  13. data/vendor/cybozulib/.github/workflows/main.yml +12 -0
  14. data/vendor/cybozulib/.gitignore +5 -0
  15. data/vendor/cybozulib/CMakeLists.txt +6 -0
  16. data/vendor/cybozulib/COPYRIGHT +27 -0
  17. data/vendor/cybozulib/Makefile +26 -0
  18. data/vendor/cybozulib/bin/libeay32.dll +0 -0
  19. data/vendor/cybozulib/bin/libmecab.dll +0 -0
  20. data/vendor/cybozulib/bin/ssleay32.dll +0 -0
  21. data/vendor/cybozulib/common.mk +116 -0
  22. data/vendor/cybozulib/common.props +25 -0
  23. data/vendor/cybozulib/cybozulib.sln +286 -0
  24. data/vendor/cybozulib/debug.props +14 -0
  25. data/vendor/cybozulib/include/cybozu/array.hpp +197 -0
  26. data/vendor/cybozulib/include/cybozu/atoi.hpp +238 -0
  27. data/vendor/cybozulib/include/cybozu/atomic.hpp +146 -0
  28. data/vendor/cybozulib/include/cybozu/base64.hpp +210 -0
  29. data/vendor/cybozulib/include/cybozu/benchmark.hpp +212 -0
  30. data/vendor/cybozulib/include/cybozu/bfd.hpp +105 -0
  31. data/vendor/cybozulib/include/cybozu/bit_operation.hpp +139 -0
  32. data/vendor/cybozulib/include/cybozu/bitvector.hpp +358 -0
  33. data/vendor/cybozulib/include/cybozu/condition_variable.hpp +113 -0
  34. data/vendor/cybozulib/include/cybozu/condition_variable_cs.hpp +74 -0
  35. data/vendor/cybozulib/include/cybozu/config.hpp +392 -0
  36. data/vendor/cybozulib/include/cybozu/critical_section.hpp +60 -0
  37. data/vendor/cybozulib/include/cybozu/crypto.hpp +321 -0
  38. data/vendor/cybozulib/include/cybozu/csucvector.hpp +624 -0
  39. data/vendor/cybozulib/include/cybozu/csv.hpp +294 -0
  40. data/vendor/cybozulib/include/cybozu/data_type.hpp +27 -0
  41. data/vendor/cybozulib/include/cybozu/endian.hpp +224 -0
  42. data/vendor/cybozulib/include/cybozu/env.hpp +63 -0
  43. data/vendor/cybozulib/include/cybozu/event.hpp +122 -0
  44. data/vendor/cybozulib/include/cybozu/exception.hpp +253 -0
  45. data/vendor/cybozulib/include/cybozu/file.hpp +626 -0
  46. data/vendor/cybozulib/include/cybozu/fmindex.hpp +291 -0
  47. data/vendor/cybozulib/include/cybozu/format.hpp +93 -0
  48. data/vendor/cybozulib/include/cybozu/frequency.hpp +264 -0
  49. data/vendor/cybozulib/include/cybozu/hash.hpp +67 -0
  50. data/vendor/cybozulib/include/cybozu/inttype.hpp +174 -0
  51. data/vendor/cybozulib/include/cybozu/itoa.hpp +336 -0
  52. data/vendor/cybozulib/include/cybozu/json.hpp +120 -0
  53. data/vendor/cybozulib/include/cybozu/line_stream.hpp +149 -0
  54. data/vendor/cybozulib/include/cybozu/link_libeay32.hpp +21 -0
  55. data/vendor/cybozulib/include/cybozu/link_mpir.hpp +18 -0
  56. data/vendor/cybozulib/include/cybozu/link_ssleay32.hpp +19 -0
  57. data/vendor/cybozulib/include/cybozu/log.hpp +237 -0
  58. data/vendor/cybozulib/include/cybozu/minixml.hpp +452 -0
  59. data/vendor/cybozulib/include/cybozu/mmap.hpp +143 -0
  60. data/vendor/cybozulib/include/cybozu/mutex.hpp +144 -0
  61. data/vendor/cybozulib/include/cybozu/nlp/mecab.hpp +96 -0
  62. data/vendor/cybozulib/include/cybozu/nlp/plsi.hpp +315 -0
  63. data/vendor/cybozulib/include/cybozu/nlp/random.hpp +74 -0
  64. data/vendor/cybozulib/include/cybozu/nlp/sparse.hpp +529 -0
  65. data/vendor/cybozulib/include/cybozu/nlp/svd.hpp +486 -0
  66. data/vendor/cybozulib/include/cybozu/nlp/tfidf.hpp +226 -0
  67. data/vendor/cybozulib/include/cybozu/nlp/top_score.hpp +75 -0
  68. data/vendor/cybozulib/include/cybozu/option.hpp +743 -0
  69. data/vendor/cybozulib/include/cybozu/parallel.hpp +88 -0
  70. data/vendor/cybozulib/include/cybozu/pcg.hpp +72 -0
  71. data/vendor/cybozulib/include/cybozu/process.hpp +324 -0
  72. data/vendor/cybozulib/include/cybozu/quit_signal_handler.hpp +66 -0
  73. data/vendor/cybozulib/include/cybozu/random_generator.hpp +144 -0
  74. data/vendor/cybozulib/include/cybozu/regex.hpp +463 -0
  75. data/vendor/cybozulib/include/cybozu/select8.hpp +279 -0
  76. data/vendor/cybozulib/include/cybozu/serializer.hpp +363 -0
  77. data/vendor/cybozulib/include/cybozu/sha1.hpp +209 -0
  78. data/vendor/cybozulib/include/cybozu/sha2.hpp +506 -0
  79. data/vendor/cybozulib/include/cybozu/siphash.hpp +105 -0
  80. data/vendor/cybozulib/include/cybozu/socket.hpp +785 -0
  81. data/vendor/cybozulib/include/cybozu/ssl.hpp +203 -0
  82. data/vendor/cybozulib/include/cybozu/stacktrace.hpp +291 -0
  83. data/vendor/cybozulib/include/cybozu/stream.hpp +269 -0
  84. data/vendor/cybozulib/include/cybozu/string.hpp +1746 -0
  85. data/vendor/cybozulib/include/cybozu/string_operation.hpp +365 -0
  86. data/vendor/cybozulib/include/cybozu/sucvector.hpp +378 -0
  87. data/vendor/cybozulib/include/cybozu/test.hpp +373 -0
  88. data/vendor/cybozulib/include/cybozu/thread.hpp +229 -0
  89. data/vendor/cybozulib/include/cybozu/time.hpp +281 -0
  90. data/vendor/cybozulib/include/cybozu/tls.hpp +115 -0
  91. data/vendor/cybozulib/include/cybozu/unordered_map.hpp +13 -0
  92. data/vendor/cybozulib/include/cybozu/unordered_set.hpp +13 -0
  93. data/vendor/cybozulib/include/cybozu/v128.hpp +376 -0
  94. data/vendor/cybozulib/include/cybozu/wavelet_matrix.hpp +345 -0
  95. data/vendor/cybozulib/include/cybozu/xorshift.hpp +189 -0
  96. data/vendor/cybozulib/include/cybozu/zlib.hpp +325 -0
  97. data/vendor/cybozulib/include/sais.hxx +364 -0
  98. data/vendor/cybozulib/misc/make_select8tbl.cpp +26 -0
  99. data/vendor/cybozulib/mk.bat +37 -0
  100. data/vendor/cybozulib/readme.md +29 -0
  101. data/vendor/cybozulib/release.props +12 -0
  102. data/vendor/cybozulib/sample/Makefile +30 -0
  103. data/vendor/cybozulib/sample/csucvector_smpl.cpp +42 -0
  104. data/vendor/cybozulib/sample/data/svd/org/test1.S +4 -0
  105. data/vendor/cybozulib/sample/data/svd/org/test1.U +4 -0
  106. data/vendor/cybozulib/sample/data/svd/org/test1.V +6 -0
  107. data/vendor/cybozulib/sample/data/svd/test1 +4 -0
  108. data/vendor/cybozulib/sample/data/svd/test2 +4 -0
  109. data/vendor/cybozulib/sample/desymbol.cpp +127 -0
  110. data/vendor/cybozulib/sample/exception_smpl.cpp +46 -0
  111. data/vendor/cybozulib/sample/fmindex_smpl.cpp +231 -0
  112. data/vendor/cybozulib/sample/log_smpl.cpp +19 -0
  113. data/vendor/cybozulib/sample/mecab_smpl.cpp +37 -0
  114. data/vendor/cybozulib/sample/option2_smpl.cpp +68 -0
  115. data/vendor/cybozulib/sample/option_smpl.cpp +42 -0
  116. data/vendor/cybozulib/sample/plsi_smpl.cpp +207 -0
  117. data/vendor/cybozulib/sample/proj/exception_smpl.vcproj +184 -0
  118. data/vendor/cybozulib/sample/proj/mecab_smpl.vcproj +184 -0
  119. data/vendor/cybozulib/sample/proj/ssl_smpl/ssl_smpl.vcxproj +85 -0
  120. data/vendor/cybozulib/sample/proj/ssl_smpl.vcproj +347 -0
  121. data/vendor/cybozulib/sample/proj/stacktrace_smpl/stacktrace_smpl.vcxproj +85 -0
  122. data/vendor/cybozulib/sample/proj/svd_smpl.vcproj +184 -0
  123. data/vendor/cybozulib/sample/quit_signal_handler.cpp +30 -0
  124. data/vendor/cybozulib/sample/serializer_smpl.cpp +196 -0
  125. data/vendor/cybozulib/sample/socket_smpl.cpp +82 -0
  126. data/vendor/cybozulib/sample/ssl_smpl.cpp +39 -0
  127. data/vendor/cybozulib/sample/stacktrace_smpl.cpp +52 -0
  128. data/vendor/cybozulib/sample/svd_bench_smpl.cpp +143 -0
  129. data/vendor/cybozulib/sample/svd_smpl.cpp +94 -0
  130. data/vendor/cybozulib/sample/wm_bench_smpl.cpp +182 -0
  131. data/vendor/cybozulib/sample/zlib_smpl.cpp +41 -0
  132. data/vendor/cybozulib/src/Makefile +8 -0
  133. data/vendor/cybozulib/src/base/Makefile +19 -0
  134. data/vendor/cybozulib/test/Makefile +12 -0
  135. data/vendor/cybozulib/test/base/Makefile +37 -0
  136. data/vendor/cybozulib/test/base/array_test.cpp +173 -0
  137. data/vendor/cybozulib/test/base/atoi_test.cpp +774 -0
  138. data/vendor/cybozulib/test/base/atomic_test.cpp +49 -0
  139. data/vendor/cybozulib/test/base/base64_test.cpp +113 -0
  140. data/vendor/cybozulib/test/base/bit_operation_test.cpp +134 -0
  141. data/vendor/cybozulib/test/base/bitvector_test.cpp +204 -0
  142. data/vendor/cybozulib/test/base/condition_variable_cs_test.cpp +92 -0
  143. data/vendor/cybozulib/test/base/condition_variable_test.cpp +88 -0
  144. data/vendor/cybozulib/test/base/config_test.cpp +236 -0
  145. data/vendor/cybozulib/test/base/crypto_test.cpp +122 -0
  146. data/vendor/cybozulib/test/base/csucvector_test.cpp +63 -0
  147. data/vendor/cybozulib/test/base/csv_test.cpp +182 -0
  148. data/vendor/cybozulib/test/base/data/a.xml +26 -0
  149. data/vendor/cybozulib/test/base/endian_test.cpp +56 -0
  150. data/vendor/cybozulib/test/base/env_test.cpp +22 -0
  151. data/vendor/cybozulib/test/base/event_test.cpp +41 -0
  152. data/vendor/cybozulib/test/base/file_test.cpp +233 -0
  153. data/vendor/cybozulib/test/base/fmindex_test.cpp +118 -0
  154. data/vendor/cybozulib/test/base/format_test.cpp +12 -0
  155. data/vendor/cybozulib/test/base/frequency_test.cpp +104 -0
  156. data/vendor/cybozulib/test/base/itoa_test.cpp +522 -0
  157. data/vendor/cybozulib/test/base/line_stream_test.cpp +208 -0
  158. data/vendor/cybozulib/test/base/mecab_test.cpp +41 -0
  159. data/vendor/cybozulib/test/base/minixml_test.cpp +103 -0
  160. data/vendor/cybozulib/test/base/mmap_test.cpp +15 -0
  161. data/vendor/cybozulib/test/base/option_test.cpp +487 -0
  162. data/vendor/cybozulib/test/base/parallel_test.cpp +48 -0
  163. data/vendor/cybozulib/test/base/proj/array_test/array_test.vcxproj +86 -0
  164. data/vendor/cybozulib/test/base/proj/atoi_test/atoi_test.vcxproj +86 -0
  165. data/vendor/cybozulib/test/base/proj/atomic_test/atomic_test.vcxproj +86 -0
  166. data/vendor/cybozulib/test/base/proj/base64_test/base64_test.vcxproj +86 -0
  167. data/vendor/cybozulib/test/base/proj/condition_variable_cs_test/condition_variable_cs_test.vcxproj +86 -0
  168. data/vendor/cybozulib/test/base/proj/condition_variable_test/condition_variable_test.vcxproj +86 -0
  169. data/vendor/cybozulib/test/base/proj/config_test/config_test.vcxproj +86 -0
  170. data/vendor/cybozulib/test/base/proj/csv_test/csv_test.vcxproj +86 -0
  171. data/vendor/cybozulib/test/base/proj/endian_test/endian_test.vcxproj +86 -0
  172. data/vendor/cybozulib/test/base/proj/env_test/env_test.vcxproj +86 -0
  173. data/vendor/cybozulib/test/base/proj/event_test/event_test.vcxproj +86 -0
  174. data/vendor/cybozulib/test/base/proj/file_test/file_test.vcxproj +86 -0
  175. data/vendor/cybozulib/test/base/proj/itoa_test/itoa_test.vcxproj +86 -0
  176. data/vendor/cybozulib/test/base/proj/mecab_test/mecab_test.vcxproj +88 -0
  177. data/vendor/cybozulib/test/base/proj/minixml_test/minixml_test.vcxproj +86 -0
  178. data/vendor/cybozulib/test/base/proj/mmap_test/mmap_test.vcxproj +86 -0
  179. data/vendor/cybozulib/test/base/proj/serializer_test/serializer_test.vcxproj +86 -0
  180. data/vendor/cybozulib/test/base/proj/sha1_test/sha1_test.vcxproj +86 -0
  181. data/vendor/cybozulib/test/base/proj/stream_test/stream_test.vcxproj +86 -0
  182. data/vendor/cybozulib/test/base/proj/string_operation_test/string_operation_test.vcxproj +86 -0
  183. data/vendor/cybozulib/test/base/proj/string_test/string_test.vcxproj +86 -0
  184. data/vendor/cybozulib/test/base/proj/thread_test/thread_test.vcxproj +86 -0
  185. data/vendor/cybozulib/test/base/proj/time_test/time_test.vcxproj +86 -0
  186. data/vendor/cybozulib/test/base/proj/tls_test/tls_test.vcxproj +86 -0
  187. data/vendor/cybozulib/test/base/proj/zlib_test/zlib_test.vcxproj +86 -0
  188. data/vendor/cybozulib/test/base/random_generator_test.cpp +28 -0
  189. data/vendor/cybozulib/test/base/regex_test.cpp +74 -0
  190. data/vendor/cybozulib/test/base/serializer_test.cpp +483 -0
  191. data/vendor/cybozulib/test/base/sha1_test.cpp +61 -0
  192. data/vendor/cybozulib/test/base/sha2_test.cpp +191 -0
  193. data/vendor/cybozulib/test/base/siphash_test.cpp +33 -0
  194. data/vendor/cybozulib/test/base/socket_test.cpp +76 -0
  195. data/vendor/cybozulib/test/base/stream_test.cpp +101 -0
  196. data/vendor/cybozulib/test/base/string_operation_test.cpp +340 -0
  197. data/vendor/cybozulib/test/base/string_test.cpp +1705 -0
  198. data/vendor/cybozulib/test/base/sucvector_test.cpp +312 -0
  199. data/vendor/cybozulib/test/base/thread_test.cpp +62 -0
  200. data/vendor/cybozulib/test/base/time_test.cpp +164 -0
  201. data/vendor/cybozulib/test/base/tls_test.cpp +50 -0
  202. data/vendor/cybozulib/test/base/wavelet_matrix_test.cpp +145 -0
  203. data/vendor/cybozulib/test/base/zlib_test.cpp +371 -0
  204. data/vendor/cybozulib/test/nlp/Makefile +27 -0
  205. data/vendor/cybozulib/test/nlp/proj/random_test.vcproj +184 -0
  206. data/vendor/cybozulib/test/nlp/proj/sparse_test.vcproj +184 -0
  207. data/vendor/cybozulib/test/nlp/proj/svd_test.vcproj +184 -0
  208. data/vendor/cybozulib/test/nlp/random_test.cpp +62 -0
  209. data/vendor/cybozulib/test/nlp/sparse_test.cpp +347 -0
  210. data/vendor/cybozulib/test/nlp/svd_test.cpp +234 -0
  211. data/vendor/cybozulib/test/nlp/top_score_test.cpp +40 -0
  212. data/vendor/cybozulib/tool/create_vcproj.py +186 -0
  213. data/vendor/cybozulib/tool/vcproj_tmpl.py +185 -0
  214. data/vendor/msoffice/COPYRIGHT +27 -0
  215. data/vendor/msoffice/Makefile +29 -0
  216. data/vendor/msoffice/bin/64/msoc.dll +0 -0
  217. data/vendor/msoffice/bin/64/msocsample.exe +0 -0
  218. data/vendor/msoffice/bin/64/msoffice-crypt.exe +0 -0
  219. data/vendor/msoffice/bin/msoc.dll +0 -0
  220. data/vendor/msoffice/bin/msocsample.exe +0 -0
  221. data/vendor/msoffice/bin/msoffice-crypt.exe +0 -0
  222. data/vendor/msoffice/common.mk +71 -0
  223. data/vendor/msoffice/common.props +26 -0
  224. data/vendor/msoffice/debug.props +14 -0
  225. data/vendor/msoffice/include/attack.hpp +211 -0
  226. data/vendor/msoffice/include/cfb.hpp +777 -0
  227. data/vendor/msoffice/include/crypto_util.hpp +450 -0
  228. data/vendor/msoffice/include/custom_sha1.hpp +342 -0
  229. data/vendor/msoffice/include/decode.hpp +240 -0
  230. data/vendor/msoffice/include/encode.hpp +221 -0
  231. data/vendor/msoffice/include/make_dataspace.hpp +316 -0
  232. data/vendor/msoffice/include/msoc.h +129 -0
  233. data/vendor/msoffice/include/resource.hpp +7 -0
  234. data/vendor/msoffice/include/standard_encryption.hpp +145 -0
  235. data/vendor/msoffice/include/uint32vec.hpp +179 -0
  236. data/vendor/msoffice/include/util.hpp +212 -0
  237. data/vendor/msoffice/lib/.emptydir +0 -0
  238. data/vendor/msoffice/misc/decrypt-xls.vbs +46 -0
  239. data/vendor/msoffice/mk.bat +1 -0
  240. data/vendor/msoffice/mkdll.bat +3 -0
  241. data/vendor/msoffice/msoc.def +13 -0
  242. data/vendor/msoffice/msocsample.py +178 -0
  243. data/vendor/msoffice/msoffice12.sln +31 -0
  244. data/vendor/msoffice/readme.md +110 -0
  245. data/vendor/msoffice/release.props +28 -0
  246. data/vendor/msoffice/src/Makefile +19 -0
  247. data/vendor/msoffice/src/attack.cpp +124 -0
  248. data/vendor/msoffice/src/cfb_test.cpp +77 -0
  249. data/vendor/msoffice/src/minisample.c +54 -0
  250. data/vendor/msoffice/src/msocdll.cpp +276 -0
  251. data/vendor/msoffice/src/msocsample.c +136 -0
  252. data/vendor/msoffice/src/msoffice-crypt.cpp +219 -0
  253. data/vendor/msoffice/src/proj/attack/attack.vcxproj +88 -0
  254. data/vendor/msoffice/src/proj/main/msoffice-crypt.vcxproj +88 -0
  255. data/vendor/msoffice/src/sha1.cpp +234 -0
  256. data/vendor/msoffice/test/Makefile +20 -0
  257. data/vendor/msoffice/test/cfb_test.cpp +74 -0
  258. data/vendor/msoffice/test/hash_test.cpp +59 -0
  259. data/vendor/msoffice/test/proj/cfb/cfb_test.vcxproj +90 -0
  260. data/vendor/msoffice/test/proj/hash/hash_test.vcxproj +90 -0
  261. data/vendor/msoffice/test/sampl.bat +8 -0
  262. data/vendor/msoffice/test_all.py +46 -0
  263. data/vendor/update +4 -0
  264. metadata +351 -0
@@ -0,0 +1,743 @@
1
+ #pragma once
2
+ /**
3
+ @file
4
+ @brief command line parser
5
+
6
+ @author MITSUNARI Shigeo(@herumi)
7
+ */
8
+ #include <string>
9
+ #include <vector>
10
+ #include <map>
11
+ #include <sstream>
12
+ #include <iostream>
13
+ #include <limits>
14
+ #include <stdio.h>
15
+ #include <stdlib.h>
16
+ #include <assert.h>
17
+ #include <cybozu/exception.hpp>
18
+ #include <cybozu/atoi.hpp>
19
+
20
+ /*
21
+ Option parser
22
+
23
+ progName (opt1-name|opt2-name|...) param1 param2 ...
24
+ param1:param1-help
25
+ param2:param2-help
26
+ -op1-name:opt1-help
27
+ ...
28
+
29
+ How to setup
30
+ int num;
31
+ -n num ; (optional) option => appendOpt(&x, <defaultValue>, "num", "num-help");
32
+ -n num ; must option => appendMust(&x, "num", "num-help");
33
+
34
+ std::vector<int> v;
35
+ -v s1 s2 s3 ... => appendVec(&v, "v");
36
+
37
+ Remark1: terminate parsing of v if argv begins with '-[^0-9]'
38
+ Remark2: the begining character of opt-name is not a number ('0'...'9')
39
+ because avoid conflict with minus number
40
+
41
+ std::string file1;
42
+ file1 is param => appendParam(&file1, "input-file");
43
+ file2 is optional param => appendParamOpt(&file2, "output-file");
44
+
45
+ How to use
46
+ opt.parse(argc, argv);
47
+
48
+ see sample/option_smpl.cpp
49
+ */
50
+
51
+ namespace cybozu {
52
+
53
+ struct OptionError : public cybozu::Exception {
54
+ enum Type {
55
+ NoError = 0,
56
+ BAD_OPT = 1,
57
+ BAD_VALUE,
58
+ NO_VALUE,
59
+ OPT_IS_NECESSARY,
60
+ PARAM_IS_NECESSARY,
61
+ REDUNDANT_VAL,
62
+ BAD_ARGC
63
+ };
64
+ Type type;
65
+ int argPos;
66
+ OptionError()
67
+ : cybozu::Exception("OptionError", false)
68
+ , type(NoError)
69
+ , argPos(0)
70
+ {
71
+ }
72
+ cybozu::Exception& set(Type _type, int _argPos = 0)
73
+ {
74
+ this->type = _type;
75
+ this->argPos = _argPos;
76
+ switch (_type) {
77
+ case BAD_OPT:
78
+ (*this) << "bad opt";
79
+ break;
80
+ case BAD_VALUE:
81
+ (*this) << "bad value";
82
+ break;
83
+ case NO_VALUE:
84
+ (*this) << "no value";
85
+ break;
86
+ case OPT_IS_NECESSARY:
87
+ (*this) << "opt is necessary";
88
+ break;
89
+ case PARAM_IS_NECESSARY:
90
+ (*this) << "param is necessary";
91
+ break;
92
+ case REDUNDANT_VAL:
93
+ (*this) << "redundant argVal";
94
+ break;
95
+ case BAD_ARGC:
96
+ (*this) << "bad argc";
97
+ default:
98
+ break;
99
+ }
100
+ return *this;
101
+ }
102
+ };
103
+
104
+ namespace option_local {
105
+
106
+ template<class T>
107
+ bool convert(T* x, const char *str)
108
+ {
109
+ std::istringstream is(str);
110
+ is >> *x;
111
+ return !!is;
112
+ }
113
+
114
+ template<>
115
+ inline bool convert(std::string* x, const char *str)
116
+ {
117
+ *x = str;
118
+ return true;
119
+ }
120
+
121
+ template<class T>
122
+ bool convertInt(T* x, const char *str)
123
+ {
124
+ if (str[0] == '0' && str[1] == 'x') {
125
+ bool b;
126
+ *x = cybozu::hextoi(&b, str + 2);
127
+ return b;
128
+ }
129
+ size_t len = strlen(str);
130
+ int factor = 1;
131
+ if (len > 1) {
132
+ switch (str[len - 1]) {
133
+ case 'k': factor = 1000; len--; break;
134
+ case 'm': factor = 1000 * 1000; len--; break;
135
+ case 'g': factor = 1000 * 1000 * 1000; len--; break;
136
+ case 'K': factor = 1024; len--; break;
137
+ case 'M': factor = 1024 * 1024; len--; break;
138
+ case 'G': factor = 1024 * 1024 * 1024; len--; break;
139
+ default: break;
140
+ }
141
+ }
142
+ bool b;
143
+ T y = cybozu::atoi(&b, str, len);
144
+ if (!b) return false;
145
+ if (factor > 1) {
146
+ if ((std::numeric_limits<T>::min)() / factor <= y
147
+ && y <= (std::numeric_limits<T>::max)() / factor) {
148
+ *x = static_cast<T>(y * factor);
149
+ } else {
150
+ return false;
151
+ }
152
+ } else {
153
+ *x = y;
154
+ }
155
+ return true;
156
+ }
157
+
158
+ template<class T>
159
+ void convertToStr(std::ostream& os, const T* p)
160
+ {
161
+ os << *p;
162
+ }
163
+ template<>inline void convertToStr(std::ostream& os, const int8_t* p)
164
+ {
165
+ os << static_cast<int>(*p);
166
+ }
167
+ template<>inline void convertToStr(std::ostream& os, const uint8_t* p)
168
+ {
169
+ os << static_cast<int>(*p);
170
+ }
171
+
172
+ #define CYBOZU_OPTION_DEFINE_CONVERT_INT(type) \
173
+ template<>inline bool convert(type* x, const char *str) { return convertInt(x, str); }
174
+
175
+ CYBOZU_OPTION_DEFINE_CONVERT_INT(int8_t)
176
+ CYBOZU_OPTION_DEFINE_CONVERT_INT(uint8_t)
177
+
178
+ CYBOZU_OPTION_DEFINE_CONVERT_INT(int16_t)
179
+ CYBOZU_OPTION_DEFINE_CONVERT_INT(uint16_t)
180
+
181
+ CYBOZU_OPTION_DEFINE_CONVERT_INT(int)
182
+ CYBOZU_OPTION_DEFINE_CONVERT_INT(long)
183
+ CYBOZU_OPTION_DEFINE_CONVERT_INT(long long)
184
+
185
+ CYBOZU_OPTION_DEFINE_CONVERT_INT(unsigned int)
186
+ CYBOZU_OPTION_DEFINE_CONVERT_INT(unsigned long)
187
+ CYBOZU_OPTION_DEFINE_CONVERT_INT(unsigned long long)
188
+
189
+ #undef CYBOZU_OPTION_DEFINE_CONVERT_INT
190
+
191
+ struct HolderBase {
192
+ virtual ~HolderBase(){}
193
+ virtual bool set(const char*) = 0;
194
+ virtual HolderBase *clone() const = 0;
195
+ virtual std::string toStr() const = 0;
196
+ virtual const void *get() const = 0;
197
+ };
198
+
199
+ template<class T>
200
+ struct Holder : public HolderBase {
201
+ T *p_;
202
+ Holder(T *p) : p_(p) {}
203
+ HolderBase *clone() const { return new Holder(p_); }
204
+ bool set(const char *str) { return option_local::convert(p_, str); }
205
+ std::string toStr() const
206
+ {
207
+ std::ostringstream os;
208
+ convertToStr(os, p_);
209
+ return os.str();
210
+ }
211
+ const void *get() const { return (void*)p_; }
212
+ };
213
+
214
+ /*
215
+ for gcc 7 with -fnew-ttp-matching
216
+ this specialization is not necessary under -fno-new-ttp-matching
217
+ */
218
+ template struct Holder<std::string>;
219
+
220
+ template<class T, class Alloc, template<class T_, class Alloc_>class Container>
221
+ struct Holder<Container<T, Alloc> > : public HolderBase {
222
+ typedef Container<T, Alloc> Vec;
223
+ Vec *p_;
224
+ Holder(Vec *p) : p_(p) {}
225
+ HolderBase *clone() const { return new Holder<Vec>(p_); }
226
+ bool set(const char *str)
227
+ {
228
+ T t;
229
+ bool b = option_local::convert(&t, str);
230
+ if (b) p_->push_back(t);
231
+ return b;
232
+ }
233
+ std::string toStr() const
234
+ {
235
+ std::ostringstream os;
236
+ bool isFirst = true;
237
+ for (typename Vec::const_iterator i = p_->begin(), ie = p_->end(); i != ie; ++i) {
238
+ if (isFirst) {
239
+ isFirst = false;
240
+ } else {
241
+ os << ' ';
242
+ }
243
+ os << *i;
244
+ }
245
+ return os.str();
246
+ }
247
+ const void *get() const { return (void*)p_; }
248
+ };
249
+
250
+ class Var {
251
+ HolderBase *p_;
252
+ bool isSet_;
253
+ public:
254
+ Var() : p_(0), isSet_(false) { }
255
+ Var(const Var& rhs) : p_(rhs.p_->clone()), isSet_(false) { }
256
+ template<class T>
257
+ explicit Var(T *x) : p_(new Holder<T>(x)), isSet_(false) { }
258
+
259
+ ~Var() { delete p_; }
260
+
261
+ void swap(Var& rhs) CYBOZU_NOEXCEPT
262
+ {
263
+ std::swap(p_, rhs.p_);
264
+ std::swap(isSet_, rhs.isSet_);
265
+ }
266
+ void operator=(const Var& rhs)
267
+ {
268
+ Var v(rhs);
269
+ swap(v);
270
+ }
271
+ bool set(const char *str)
272
+ {
273
+ isSet_ = true;
274
+ return p_->set(str);
275
+ }
276
+ std::string toStr() const { return p_ ? p_->toStr() : ""; }
277
+ bool isSet() const { return isSet_; }
278
+ const void *get() const { return p_ ? p_->get() : 0; }
279
+ };
280
+
281
+ } // option_local
282
+
283
+ class Option {
284
+ enum Mode { // for opt
285
+ N_is0 = 0, // for bool by appendBoolOpt()
286
+ N_is1 = 1,
287
+ N_any = 2
288
+ };
289
+ enum ParamMode {
290
+ P_exact = 0, // one
291
+ P_optional = 1, // zero or one
292
+ P_variable = 2 // zero or greater
293
+ };
294
+ struct Info {
295
+ option_local::Var var;
296
+ Mode mode; // 0 or 1 or any ; for opt, not used for Param
297
+ bool isMust; // this option is must
298
+ std::string opt; // option param name without '-'
299
+ std::string help; // description of option
300
+
301
+ Info() : mode(N_is0), isMust(false) {}
302
+ template<class T>
303
+ Info(T* pvar, Mode mode, bool isMust, const char *opt, const std::string& help)
304
+ : var(pvar)
305
+ , mode(mode)
306
+ , isMust(isMust)
307
+ , opt(opt)
308
+ , help(help)
309
+ {
310
+ }
311
+ friend inline std::ostream& operator<<(std::ostream& os, const Info& self)
312
+ {
313
+ os << self.opt << '=' << self.var.toStr();
314
+ if (self.var.isSet()) {
315
+ os << " (set)";
316
+ } else {
317
+ os << " (default)";
318
+ }
319
+ return os;
320
+ }
321
+ void put() const
322
+ {
323
+ std::cout << *this;
324
+ }
325
+ void usage() const
326
+ {
327
+ printf(" -%s %s%s\n", opt.c_str(), help.c_str(), isMust ? " (must)" : "");
328
+ }
329
+ void shortUsage() const
330
+ {
331
+ printf(" -%s %s", opt.c_str(), mode == N_is0 ? "" : mode == N_is1 ? "para" : "para...");
332
+ }
333
+ bool isSet() const { return var.isSet(); }
334
+ const void *get() const { return var.get(); }
335
+ };
336
+ typedef std::vector<Info> InfoVec;
337
+ typedef std::vector<std::string> StrVec;
338
+ typedef std::map<std::string, size_t> OptMap;
339
+ InfoVec infoVec_;
340
+ InfoVec paramVec_;
341
+ Info remains_;
342
+ OptMap optMap_;
343
+ bool showOptUsage_;
344
+ ParamMode paramMode_;
345
+ std::string progName_;
346
+ std::string desc_;
347
+ std::string helpOpt_;
348
+ std::string help_;
349
+ std::string usage_;
350
+ StrVec delimiters_;
351
+ StrVec *remainsAfterDelimiter_;
352
+ int nextDelimiter_;
353
+ template<class T>
354
+ void appendSub(T *pvar, Mode mode, bool isMust, const char *opt, const std::string& help)
355
+ {
356
+ const char c = opt[0];
357
+ if ('0' <= c && c <= '9') throw cybozu::Exception("Option::appendSub:opt must begin with not number") << opt;
358
+ if (optMap_.find(opt) != optMap_.end()) {
359
+ throw cybozu::Exception("Option::append:duplicate option") << opt;
360
+ }
361
+ optMap_[opt] = infoVec_.size();
362
+ infoVec_.push_back(Info(pvar, mode, isMust, opt, help));
363
+ }
364
+
365
+ template<class T, class U>
366
+ void append(T *pvar, const U& defaultVal, bool isMust, const char *opt, const std::string& help = "")
367
+ {
368
+ *pvar = static_cast<const T&>(defaultVal);
369
+ appendSub(pvar, N_is1, isMust, opt, help);
370
+ }
371
+ /*
372
+ don't deal with negative number as option
373
+ */
374
+ bool isOpt(const char *str) const
375
+ {
376
+ if (str[0] != '-') return false;
377
+ const char c = str[1];
378
+ if ('0' <= c && c <= '9') return false;
379
+ return true;
380
+ }
381
+ void verifyParamMode()
382
+ {
383
+ if (paramMode_ != P_exact) throw cybozu::Exception("Option:appendParamVec:appendParam is forbidden after appendParamOpt/appendParamVec");
384
+ }
385
+ std::string getBaseName(const std::string& name) const
386
+ {
387
+ size_t pos = name.find_last_of("/\\");
388
+ if (pos == std::string::npos) return name;
389
+ return name.substr(pos + 1);
390
+ }
391
+ bool inDelimiters(const std::string& str) const
392
+ {
393
+ return std::find(delimiters_.begin(), delimiters_.end(), str) != delimiters_.end();
394
+ }
395
+ public:
396
+ Option()
397
+ : showOptUsage_(true)
398
+ , paramMode_(P_exact)
399
+ , remainsAfterDelimiter_(0)
400
+ , nextDelimiter_(-1)
401
+ {
402
+ }
403
+ virtual ~Option() {}
404
+ /*
405
+ append optional option with default value
406
+ @param pvar [in] pointer to option variable
407
+ @param defaultVal [in] default value
408
+ @param opt [in] option name
409
+ @param help [in] option help
410
+ @note you can use 123k, 56M if T is int/long/long long
411
+ k : *1000
412
+ m : *1000000
413
+ g : *1000000000
414
+ K : *1024
415
+ M : *1024*1024
416
+ G : *1024*1024*1024
417
+ */
418
+ template<class T, class U>
419
+ void appendOpt(T *pvar, const U& defaultVal, const char *opt, const std::string& help = "")
420
+ {
421
+ append(pvar, defaultVal, false, opt, help);
422
+ }
423
+ /*
424
+ default value of *pvar is false
425
+ */
426
+ void appendBoolOpt(bool *pvar, const char *opt, const std::string& help = "")
427
+ {
428
+ *pvar = false;
429
+ appendSub(pvar, N_is0, false, opt, help);
430
+ }
431
+ /*
432
+ append necessary option
433
+ @param pvar [in] pointer to option variable
434
+ @param opt [in] option name
435
+ @param help [in] option help
436
+ */
437
+ template<class T>
438
+ void appendMust(T *pvar, const char *opt, const std::string& help = "")
439
+ {
440
+ append(pvar, T(), true, opt, help);
441
+ }
442
+ /*
443
+ append vector option
444
+ @param pvar [in] pointer to option variable
445
+ @param opt [in] option name
446
+ @param help [in] option help
447
+ */
448
+ template<class T, class Alloc, template<class T_, class Alloc_>class Container>
449
+ void appendVec(Container<T, Alloc> *pvar, const char *opt, const std::string& help = "")
450
+ {
451
+ appendSub(pvar, N_any, false, opt, help);
452
+ }
453
+ /*
454
+ append parameter
455
+ @param pvar [in] pointer to parameter
456
+ @param opt [in] option name
457
+ @param help [in] option help
458
+ */
459
+ template<class T>
460
+ void appendParam(T *pvar, const char *opt, const std::string& help = "")
461
+ {
462
+ verifyParamMode();
463
+ paramVec_.push_back(Info(pvar, N_is1, true, opt, help));
464
+ }
465
+ /*
466
+ append optional parameter
467
+ @param pvar [in] pointer to parameter
468
+ @param defaultVal [in] default value
469
+ @param opt [in] option name
470
+ @param help [in] option help
471
+ @note you can call appendParamOpt once after appendParam
472
+ */
473
+ template<class T, class U>
474
+ void appendParamOpt(T *pvar, const U& defaultVal, const char *opt, const std::string& help = "")
475
+ {
476
+ verifyParamMode();
477
+ *pvar = defaultVal;
478
+ paramMode_ = P_optional;
479
+ paramVec_.push_back(Info(pvar, N_is1, false, opt, help));
480
+ }
481
+ /*
482
+ append remain parameter
483
+ @param pvar [in] pointer to vector of parameter
484
+ @param opt [in] option name
485
+ @param help [in] option help
486
+ @note you can call appendParamVec once after appendParam
487
+ */
488
+ template<class T, class Alloc, template<class T_, class Alloc_>class Container>
489
+ void appendParamVec(Container<T, Alloc> *pvar, const char *name, const std::string& help = "")
490
+ {
491
+ verifyParamMode();
492
+ paramMode_ = P_variable;
493
+ remains_.var = option_local::Var(pvar);
494
+ remains_.mode = N_any;
495
+ remains_.isMust = false;
496
+ remains_.opt = name;
497
+ remains_.help = help;
498
+ }
499
+ void appendHelp(const char *opt, const std::string& help = ": show this message")
500
+ {
501
+ helpOpt_ = opt;
502
+ help_ = help;
503
+ }
504
+ /*
505
+ stop parsing after delimiter is found
506
+ @param delimiter [in] string to stop
507
+ @param remain [out] set remaining strings if remain
508
+ */
509
+ void setDelimiter(const std::string& delimiter, std::vector<std::string> *remain = 0)
510
+ {
511
+ delimiters_.push_back(delimiter);
512
+ remainsAfterDelimiter_ = remain;
513
+ }
514
+ /*
515
+ stop parsing after delimiter is found
516
+ @param delimiter [in] string to stop to append list of delimiters
517
+ */
518
+ void appendDelimiter(const std::string& delimiter)
519
+ {
520
+ delimiters_.push_back(delimiter);
521
+ }
522
+ /*
523
+ clear list of delimiters
524
+ */
525
+ void clearDelimiterList() { delimiters_.clear(); }
526
+ /*
527
+ return the next position of delimiter between [0, argc]
528
+ @note return argc if delimiter is not set nor found
529
+ */
530
+ int getNextPositionOfDelimiter() const { return nextDelimiter_; }
531
+ /*
532
+ parse (argc, argv)
533
+ @param argc [in] argc of main
534
+ @param argv [in] argv of main
535
+ @param startPos [in] start position of argc
536
+ @param progName [in] used instead of argv[0]
537
+ */
538
+ bool parse(int argc, const char *const argv[], int startPos = 1, const char *progName = 0)
539
+ {
540
+ if (argc < 1 || startPos > argc) return false;
541
+ progName_ = getBaseName(progName ? progName : argv[startPos - 1]);
542
+ nextDelimiter_ = argc;
543
+ OptionError err;
544
+ for (int pos = startPos; pos < argc; pos++) {
545
+ if (inDelimiters(argv[pos])) {
546
+ nextDelimiter_ = pos + 1;
547
+ if (remainsAfterDelimiter_) {
548
+ for (int i = nextDelimiter_; i < argc; i++) {
549
+ remainsAfterDelimiter_->push_back(argv[i]);
550
+ }
551
+ }
552
+ break;
553
+ }
554
+ if (isOpt(argv[pos])) {
555
+ const std::string str = argv[pos] + 1;
556
+ if (helpOpt_ == str) {
557
+ usage();
558
+ exit(0);
559
+ }
560
+ OptMap::const_iterator i = optMap_.find(str);
561
+ if (i == optMap_.end()) {
562
+ err.set(OptionError::BAD_OPT, pos);
563
+ goto ERR;
564
+ }
565
+
566
+ Info& info = infoVec_[i->second];
567
+ switch (info.mode) {
568
+ case N_is0:
569
+ if (!info.var.set("1")) {
570
+ err.set(OptionError::BAD_VALUE, pos);
571
+ goto ERR;
572
+ }
573
+ break;
574
+ case N_is1:
575
+ pos++;
576
+ if (pos == argc) {
577
+ err.set(OptionError::BAD_VALUE, pos) << (std::string("no value for -") + info.opt);
578
+ goto ERR;
579
+ }
580
+ if (!info.var.set(argv[pos])) {
581
+ err.set(OptionError::BAD_VALUE, pos) << (std::string(argv[pos]) + " for -" + info.opt);
582
+ goto ERR;
583
+ }
584
+ break;
585
+ case N_any:
586
+ default:
587
+ {
588
+ pos++;
589
+ int j = 0;
590
+ while (pos < argc && !isOpt(argv[pos])) {
591
+ if (!info.var.set(argv[pos])) {
592
+ err.set(OptionError::BAD_VALUE, pos) << (std::string(argv[pos]) + " for -" + info.opt) << j;
593
+ goto ERR;
594
+ }
595
+ pos++;
596
+ j++;
597
+ }
598
+ if (j > 0) {
599
+ pos--;
600
+ } else {
601
+ err.set(OptionError::NO_VALUE, pos) << (std::string("for -") + info.opt);
602
+ goto ERR;
603
+ }
604
+ }
605
+ break;
606
+ }
607
+ } else {
608
+ bool used = false;
609
+ for (size_t i = 0; i < paramVec_.size(); i++) {
610
+ Info& param = paramVec_[i];
611
+ if (!param.var.isSet()) {
612
+ if (!param.var.set(argv[pos])) {
613
+ err.set(OptionError::BAD_VALUE, pos) << (std::string(argv[pos]) + " for " + param.opt);
614
+ goto ERR;
615
+ }
616
+ used = true;
617
+ break;
618
+ }
619
+ }
620
+ if (!used) {
621
+ if (paramMode_ == P_variable) {
622
+ remains_.var.set(argv[pos]);
623
+ } else {
624
+ err.set(OptionError::REDUNDANT_VAL, pos) << argv[pos];
625
+ goto ERR;
626
+ }
627
+ }
628
+ }
629
+ }
630
+ // check whether must-opt is set
631
+ for (size_t i = 0; i < infoVec_.size(); i++) {
632
+ const Info& info = infoVec_[i];
633
+ if (info.isMust && !info.var.isSet()) {
634
+ err.set(OptionError::OPT_IS_NECESSARY) << info.opt;
635
+ goto ERR;
636
+ }
637
+ }
638
+ // check whether param is set
639
+ for (size_t i = 0; i < paramVec_.size(); i++) {
640
+ const Info& param = paramVec_[i];
641
+ if (param.isMust && !param.var.isSet()) {
642
+ err.set(OptionError::PARAM_IS_NECESSARY) << param.opt;
643
+ goto ERR;
644
+ }
645
+ }
646
+ // check whether remains is set
647
+ if (paramMode_ == P_variable && remains_.isMust && !remains_.var.isSet()) {
648
+ err.set(OptionError::PARAM_IS_NECESSARY) << remains_.opt;
649
+ goto ERR;
650
+ }
651
+ return true;
652
+ ERR:
653
+ assert(err.type);
654
+ printf("%s\n", err.what());
655
+ return false;
656
+ }
657
+ /*
658
+ show desc at first in usage()
659
+ */
660
+ void setDescription(const std::string& desc)
661
+ {
662
+ desc_ = desc;
663
+ }
664
+ /*
665
+ show command line after desc
666
+ don't put option message if not showOptUsage
667
+ */
668
+ void setUsage(const std::string& usage, bool showOptUsage = false)
669
+ {
670
+ usage_ = usage;
671
+ showOptUsage_ = showOptUsage;
672
+ }
673
+ void usage() const
674
+ {
675
+ if (!desc_.empty()) printf("%s\n", desc_.c_str());
676
+ if (usage_.empty()) {
677
+ printf("usage:%s", progName_.c_str());
678
+ if (!infoVec_.empty()) printf(" [opt]");
679
+ for (size_t i = 0; i < infoVec_.size(); i++) {
680
+ if (infoVec_[i].isMust) infoVec_[i].shortUsage();
681
+ }
682
+ for (size_t i = 0; i < paramVec_.size(); i++) {
683
+ printf(" %s", paramVec_[i].opt.c_str());
684
+ }
685
+ if (paramMode_ == P_variable) {
686
+ printf(" %s", remains_.opt.c_str());
687
+ }
688
+ printf("\n");
689
+ } else {
690
+ printf("%s\n", usage_.c_str());
691
+ if (!showOptUsage_) return;
692
+ }
693
+ for (size_t i = 0; i < paramVec_.size(); i++) {
694
+ const Info& param = paramVec_[i];
695
+ if (!param.help.empty()) printf(" %s %s\n", paramVec_[i].opt.c_str(), paramVec_[i].help.c_str());
696
+ }
697
+ if (!remains_.help.empty()) printf(" %s %s\n", remains_.opt.c_str(), remains_.help.c_str());
698
+ if (!helpOpt_.empty()) {
699
+ printf(" -%s %s\n", helpOpt_.c_str(), help_.c_str());
700
+ }
701
+ for (size_t i = 0; i < infoVec_.size(); i++) {
702
+ infoVec_[i].usage();
703
+ }
704
+ }
705
+ friend inline std::ostream& operator<<(std::ostream& os, const Option& self)
706
+ {
707
+ for (size_t i = 0; i < self.paramVec_.size(); i++) {
708
+ const Info& param = self.paramVec_[i];
709
+ os << param.opt << '=' << param.var.toStr() << std::endl;
710
+ }
711
+ if (self.paramMode_ == P_variable) {
712
+ os << "remains=" << self.remains_.var.toStr() << std::endl;
713
+ }
714
+ for (size_t i = 0; i < self.infoVec_.size(); i++) {
715
+ os << self.infoVec_[i] << std::endl;
716
+ }
717
+ return os;
718
+ }
719
+ void put() const
720
+ {
721
+ std::cout << *this;
722
+ }
723
+ /*
724
+ whether pvar is set or not
725
+ */
726
+ template<class T>
727
+ bool isSet(const T* pvar) const
728
+ {
729
+ const void *p = static_cast<const void*>(pvar);
730
+ for (size_t i = 0; i < paramVec_.size(); i++) {
731
+ const Info& v = paramVec_[i];
732
+ if (v.get() == p) return v.isSet();
733
+ }
734
+ if (remains_.get() == p) return remains_.isSet();
735
+ for (size_t i = 0; i < infoVec_.size(); i++) {
736
+ const Info& v = infoVec_[i];
737
+ if (v.get() == p) return v.isSet();
738
+ }
739
+ throw cybozu::Exception("Option:isSet:no assigned var") << pvar;
740
+ }
741
+ };
742
+
743
+ } // cybozu