ooxml_crypt 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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