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.
- checksums.yaml +7 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +58 -0
- data/Rakefile +12 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/ext/ooxml_crypt/extconf.rb +18 -0
- data/ext/ooxml_crypt/ooxml_crypt.c +27 -0
- data/ext/ooxml_crypt/ooxml_crypt.h +7 -0
- data/lib/ooxml_crypt/version.rb +5 -0
- data/lib/ooxml_crypt.rb +75 -0
- data/vendor/cybozulib/.github/workflows/main.yml +12 -0
- data/vendor/cybozulib/.gitignore +5 -0
- data/vendor/cybozulib/CMakeLists.txt +6 -0
- data/vendor/cybozulib/COPYRIGHT +27 -0
- data/vendor/cybozulib/Makefile +26 -0
- data/vendor/cybozulib/bin/libeay32.dll +0 -0
- data/vendor/cybozulib/bin/libmecab.dll +0 -0
- data/vendor/cybozulib/bin/ssleay32.dll +0 -0
- data/vendor/cybozulib/common.mk +116 -0
- data/vendor/cybozulib/common.props +25 -0
- data/vendor/cybozulib/cybozulib.sln +286 -0
- data/vendor/cybozulib/debug.props +14 -0
- data/vendor/cybozulib/include/cybozu/array.hpp +197 -0
- data/vendor/cybozulib/include/cybozu/atoi.hpp +238 -0
- data/vendor/cybozulib/include/cybozu/atomic.hpp +146 -0
- data/vendor/cybozulib/include/cybozu/base64.hpp +210 -0
- data/vendor/cybozulib/include/cybozu/benchmark.hpp +212 -0
- data/vendor/cybozulib/include/cybozu/bfd.hpp +105 -0
- data/vendor/cybozulib/include/cybozu/bit_operation.hpp +139 -0
- data/vendor/cybozulib/include/cybozu/bitvector.hpp +358 -0
- data/vendor/cybozulib/include/cybozu/condition_variable.hpp +113 -0
- data/vendor/cybozulib/include/cybozu/condition_variable_cs.hpp +74 -0
- data/vendor/cybozulib/include/cybozu/config.hpp +392 -0
- data/vendor/cybozulib/include/cybozu/critical_section.hpp +60 -0
- data/vendor/cybozulib/include/cybozu/crypto.hpp +321 -0
- data/vendor/cybozulib/include/cybozu/csucvector.hpp +624 -0
- data/vendor/cybozulib/include/cybozu/csv.hpp +294 -0
- data/vendor/cybozulib/include/cybozu/data_type.hpp +27 -0
- data/vendor/cybozulib/include/cybozu/endian.hpp +224 -0
- data/vendor/cybozulib/include/cybozu/env.hpp +63 -0
- data/vendor/cybozulib/include/cybozu/event.hpp +122 -0
- data/vendor/cybozulib/include/cybozu/exception.hpp +253 -0
- data/vendor/cybozulib/include/cybozu/file.hpp +626 -0
- data/vendor/cybozulib/include/cybozu/fmindex.hpp +291 -0
- data/vendor/cybozulib/include/cybozu/format.hpp +93 -0
- data/vendor/cybozulib/include/cybozu/frequency.hpp +264 -0
- data/vendor/cybozulib/include/cybozu/hash.hpp +67 -0
- data/vendor/cybozulib/include/cybozu/inttype.hpp +174 -0
- data/vendor/cybozulib/include/cybozu/itoa.hpp +336 -0
- data/vendor/cybozulib/include/cybozu/json.hpp +120 -0
- data/vendor/cybozulib/include/cybozu/line_stream.hpp +149 -0
- data/vendor/cybozulib/include/cybozu/link_libeay32.hpp +21 -0
- data/vendor/cybozulib/include/cybozu/link_mpir.hpp +18 -0
- data/vendor/cybozulib/include/cybozu/link_ssleay32.hpp +19 -0
- data/vendor/cybozulib/include/cybozu/log.hpp +237 -0
- data/vendor/cybozulib/include/cybozu/minixml.hpp +452 -0
- data/vendor/cybozulib/include/cybozu/mmap.hpp +143 -0
- data/vendor/cybozulib/include/cybozu/mutex.hpp +144 -0
- data/vendor/cybozulib/include/cybozu/nlp/mecab.hpp +96 -0
- data/vendor/cybozulib/include/cybozu/nlp/plsi.hpp +315 -0
- data/vendor/cybozulib/include/cybozu/nlp/random.hpp +74 -0
- data/vendor/cybozulib/include/cybozu/nlp/sparse.hpp +529 -0
- data/vendor/cybozulib/include/cybozu/nlp/svd.hpp +486 -0
- data/vendor/cybozulib/include/cybozu/nlp/tfidf.hpp +226 -0
- data/vendor/cybozulib/include/cybozu/nlp/top_score.hpp +75 -0
- data/vendor/cybozulib/include/cybozu/option.hpp +743 -0
- data/vendor/cybozulib/include/cybozu/parallel.hpp +88 -0
- data/vendor/cybozulib/include/cybozu/pcg.hpp +72 -0
- data/vendor/cybozulib/include/cybozu/process.hpp +324 -0
- data/vendor/cybozulib/include/cybozu/quit_signal_handler.hpp +66 -0
- data/vendor/cybozulib/include/cybozu/random_generator.hpp +144 -0
- data/vendor/cybozulib/include/cybozu/regex.hpp +463 -0
- data/vendor/cybozulib/include/cybozu/select8.hpp +279 -0
- data/vendor/cybozulib/include/cybozu/serializer.hpp +363 -0
- data/vendor/cybozulib/include/cybozu/sha1.hpp +209 -0
- data/vendor/cybozulib/include/cybozu/sha2.hpp +506 -0
- data/vendor/cybozulib/include/cybozu/siphash.hpp +105 -0
- data/vendor/cybozulib/include/cybozu/socket.hpp +785 -0
- data/vendor/cybozulib/include/cybozu/ssl.hpp +203 -0
- data/vendor/cybozulib/include/cybozu/stacktrace.hpp +291 -0
- data/vendor/cybozulib/include/cybozu/stream.hpp +269 -0
- data/vendor/cybozulib/include/cybozu/string.hpp +1746 -0
- data/vendor/cybozulib/include/cybozu/string_operation.hpp +365 -0
- data/vendor/cybozulib/include/cybozu/sucvector.hpp +378 -0
- data/vendor/cybozulib/include/cybozu/test.hpp +373 -0
- data/vendor/cybozulib/include/cybozu/thread.hpp +229 -0
- data/vendor/cybozulib/include/cybozu/time.hpp +281 -0
- data/vendor/cybozulib/include/cybozu/tls.hpp +115 -0
- data/vendor/cybozulib/include/cybozu/unordered_map.hpp +13 -0
- data/vendor/cybozulib/include/cybozu/unordered_set.hpp +13 -0
- data/vendor/cybozulib/include/cybozu/v128.hpp +376 -0
- data/vendor/cybozulib/include/cybozu/wavelet_matrix.hpp +345 -0
- data/vendor/cybozulib/include/cybozu/xorshift.hpp +189 -0
- data/vendor/cybozulib/include/cybozu/zlib.hpp +325 -0
- data/vendor/cybozulib/include/sais.hxx +364 -0
- data/vendor/cybozulib/misc/make_select8tbl.cpp +26 -0
- data/vendor/cybozulib/mk.bat +37 -0
- data/vendor/cybozulib/readme.md +29 -0
- data/vendor/cybozulib/release.props +12 -0
- data/vendor/cybozulib/sample/Makefile +30 -0
- data/vendor/cybozulib/sample/csucvector_smpl.cpp +42 -0
- data/vendor/cybozulib/sample/data/svd/org/test1.S +4 -0
- data/vendor/cybozulib/sample/data/svd/org/test1.U +4 -0
- data/vendor/cybozulib/sample/data/svd/org/test1.V +6 -0
- data/vendor/cybozulib/sample/data/svd/test1 +4 -0
- data/vendor/cybozulib/sample/data/svd/test2 +4 -0
- data/vendor/cybozulib/sample/desymbol.cpp +127 -0
- data/vendor/cybozulib/sample/exception_smpl.cpp +46 -0
- data/vendor/cybozulib/sample/fmindex_smpl.cpp +231 -0
- data/vendor/cybozulib/sample/log_smpl.cpp +19 -0
- data/vendor/cybozulib/sample/mecab_smpl.cpp +37 -0
- data/vendor/cybozulib/sample/option2_smpl.cpp +68 -0
- data/vendor/cybozulib/sample/option_smpl.cpp +42 -0
- data/vendor/cybozulib/sample/plsi_smpl.cpp +207 -0
- data/vendor/cybozulib/sample/proj/exception_smpl.vcproj +184 -0
- data/vendor/cybozulib/sample/proj/mecab_smpl.vcproj +184 -0
- data/vendor/cybozulib/sample/proj/ssl_smpl/ssl_smpl.vcxproj +85 -0
- data/vendor/cybozulib/sample/proj/ssl_smpl.vcproj +347 -0
- data/vendor/cybozulib/sample/proj/stacktrace_smpl/stacktrace_smpl.vcxproj +85 -0
- data/vendor/cybozulib/sample/proj/svd_smpl.vcproj +184 -0
- data/vendor/cybozulib/sample/quit_signal_handler.cpp +30 -0
- data/vendor/cybozulib/sample/serializer_smpl.cpp +196 -0
- data/vendor/cybozulib/sample/socket_smpl.cpp +82 -0
- data/vendor/cybozulib/sample/ssl_smpl.cpp +39 -0
- data/vendor/cybozulib/sample/stacktrace_smpl.cpp +52 -0
- data/vendor/cybozulib/sample/svd_bench_smpl.cpp +143 -0
- data/vendor/cybozulib/sample/svd_smpl.cpp +94 -0
- data/vendor/cybozulib/sample/wm_bench_smpl.cpp +182 -0
- data/vendor/cybozulib/sample/zlib_smpl.cpp +41 -0
- data/vendor/cybozulib/src/Makefile +8 -0
- data/vendor/cybozulib/src/base/Makefile +19 -0
- data/vendor/cybozulib/test/Makefile +12 -0
- data/vendor/cybozulib/test/base/Makefile +37 -0
- data/vendor/cybozulib/test/base/array_test.cpp +173 -0
- data/vendor/cybozulib/test/base/atoi_test.cpp +774 -0
- data/vendor/cybozulib/test/base/atomic_test.cpp +49 -0
- data/vendor/cybozulib/test/base/base64_test.cpp +113 -0
- data/vendor/cybozulib/test/base/bit_operation_test.cpp +134 -0
- data/vendor/cybozulib/test/base/bitvector_test.cpp +204 -0
- data/vendor/cybozulib/test/base/condition_variable_cs_test.cpp +92 -0
- data/vendor/cybozulib/test/base/condition_variable_test.cpp +88 -0
- data/vendor/cybozulib/test/base/config_test.cpp +236 -0
- data/vendor/cybozulib/test/base/crypto_test.cpp +122 -0
- data/vendor/cybozulib/test/base/csucvector_test.cpp +63 -0
- data/vendor/cybozulib/test/base/csv_test.cpp +182 -0
- data/vendor/cybozulib/test/base/data/a.xml +26 -0
- data/vendor/cybozulib/test/base/endian_test.cpp +56 -0
- data/vendor/cybozulib/test/base/env_test.cpp +22 -0
- data/vendor/cybozulib/test/base/event_test.cpp +41 -0
- data/vendor/cybozulib/test/base/file_test.cpp +233 -0
- data/vendor/cybozulib/test/base/fmindex_test.cpp +118 -0
- data/vendor/cybozulib/test/base/format_test.cpp +12 -0
- data/vendor/cybozulib/test/base/frequency_test.cpp +104 -0
- data/vendor/cybozulib/test/base/itoa_test.cpp +522 -0
- data/vendor/cybozulib/test/base/line_stream_test.cpp +208 -0
- data/vendor/cybozulib/test/base/mecab_test.cpp +41 -0
- data/vendor/cybozulib/test/base/minixml_test.cpp +103 -0
- data/vendor/cybozulib/test/base/mmap_test.cpp +15 -0
- data/vendor/cybozulib/test/base/option_test.cpp +487 -0
- data/vendor/cybozulib/test/base/parallel_test.cpp +48 -0
- data/vendor/cybozulib/test/base/proj/array_test/array_test.vcxproj +86 -0
- data/vendor/cybozulib/test/base/proj/atoi_test/atoi_test.vcxproj +86 -0
- data/vendor/cybozulib/test/base/proj/atomic_test/atomic_test.vcxproj +86 -0
- data/vendor/cybozulib/test/base/proj/base64_test/base64_test.vcxproj +86 -0
- data/vendor/cybozulib/test/base/proj/condition_variable_cs_test/condition_variable_cs_test.vcxproj +86 -0
- data/vendor/cybozulib/test/base/proj/condition_variable_test/condition_variable_test.vcxproj +86 -0
- data/vendor/cybozulib/test/base/proj/config_test/config_test.vcxproj +86 -0
- data/vendor/cybozulib/test/base/proj/csv_test/csv_test.vcxproj +86 -0
- data/vendor/cybozulib/test/base/proj/endian_test/endian_test.vcxproj +86 -0
- data/vendor/cybozulib/test/base/proj/env_test/env_test.vcxproj +86 -0
- data/vendor/cybozulib/test/base/proj/event_test/event_test.vcxproj +86 -0
- data/vendor/cybozulib/test/base/proj/file_test/file_test.vcxproj +86 -0
- data/vendor/cybozulib/test/base/proj/itoa_test/itoa_test.vcxproj +86 -0
- data/vendor/cybozulib/test/base/proj/mecab_test/mecab_test.vcxproj +88 -0
- data/vendor/cybozulib/test/base/proj/minixml_test/minixml_test.vcxproj +86 -0
- data/vendor/cybozulib/test/base/proj/mmap_test/mmap_test.vcxproj +86 -0
- data/vendor/cybozulib/test/base/proj/serializer_test/serializer_test.vcxproj +86 -0
- data/vendor/cybozulib/test/base/proj/sha1_test/sha1_test.vcxproj +86 -0
- data/vendor/cybozulib/test/base/proj/stream_test/stream_test.vcxproj +86 -0
- data/vendor/cybozulib/test/base/proj/string_operation_test/string_operation_test.vcxproj +86 -0
- data/vendor/cybozulib/test/base/proj/string_test/string_test.vcxproj +86 -0
- data/vendor/cybozulib/test/base/proj/thread_test/thread_test.vcxproj +86 -0
- data/vendor/cybozulib/test/base/proj/time_test/time_test.vcxproj +86 -0
- data/vendor/cybozulib/test/base/proj/tls_test/tls_test.vcxproj +86 -0
- data/vendor/cybozulib/test/base/proj/zlib_test/zlib_test.vcxproj +86 -0
- data/vendor/cybozulib/test/base/random_generator_test.cpp +28 -0
- data/vendor/cybozulib/test/base/regex_test.cpp +74 -0
- data/vendor/cybozulib/test/base/serializer_test.cpp +483 -0
- data/vendor/cybozulib/test/base/sha1_test.cpp +61 -0
- data/vendor/cybozulib/test/base/sha2_test.cpp +191 -0
- data/vendor/cybozulib/test/base/siphash_test.cpp +33 -0
- data/vendor/cybozulib/test/base/socket_test.cpp +76 -0
- data/vendor/cybozulib/test/base/stream_test.cpp +101 -0
- data/vendor/cybozulib/test/base/string_operation_test.cpp +340 -0
- data/vendor/cybozulib/test/base/string_test.cpp +1705 -0
- data/vendor/cybozulib/test/base/sucvector_test.cpp +312 -0
- data/vendor/cybozulib/test/base/thread_test.cpp +62 -0
- data/vendor/cybozulib/test/base/time_test.cpp +164 -0
- data/vendor/cybozulib/test/base/tls_test.cpp +50 -0
- data/vendor/cybozulib/test/base/wavelet_matrix_test.cpp +145 -0
- data/vendor/cybozulib/test/base/zlib_test.cpp +371 -0
- data/vendor/cybozulib/test/nlp/Makefile +27 -0
- data/vendor/cybozulib/test/nlp/proj/random_test.vcproj +184 -0
- data/vendor/cybozulib/test/nlp/proj/sparse_test.vcproj +184 -0
- data/vendor/cybozulib/test/nlp/proj/svd_test.vcproj +184 -0
- data/vendor/cybozulib/test/nlp/random_test.cpp +62 -0
- data/vendor/cybozulib/test/nlp/sparse_test.cpp +347 -0
- data/vendor/cybozulib/test/nlp/svd_test.cpp +234 -0
- data/vendor/cybozulib/test/nlp/top_score_test.cpp +40 -0
- data/vendor/cybozulib/tool/create_vcproj.py +186 -0
- data/vendor/cybozulib/tool/vcproj_tmpl.py +185 -0
- data/vendor/msoffice/COPYRIGHT +27 -0
- data/vendor/msoffice/Makefile +29 -0
- data/vendor/msoffice/bin/64/msoc.dll +0 -0
- data/vendor/msoffice/bin/64/msocsample.exe +0 -0
- data/vendor/msoffice/bin/64/msoffice-crypt.exe +0 -0
- data/vendor/msoffice/bin/msoc.dll +0 -0
- data/vendor/msoffice/bin/msocsample.exe +0 -0
- data/vendor/msoffice/bin/msoffice-crypt.exe +0 -0
- data/vendor/msoffice/common.mk +71 -0
- data/vendor/msoffice/common.props +26 -0
- data/vendor/msoffice/debug.props +14 -0
- data/vendor/msoffice/include/attack.hpp +211 -0
- data/vendor/msoffice/include/cfb.hpp +777 -0
- data/vendor/msoffice/include/crypto_util.hpp +450 -0
- data/vendor/msoffice/include/custom_sha1.hpp +342 -0
- data/vendor/msoffice/include/decode.hpp +240 -0
- data/vendor/msoffice/include/encode.hpp +221 -0
- data/vendor/msoffice/include/make_dataspace.hpp +316 -0
- data/vendor/msoffice/include/msoc.h +129 -0
- data/vendor/msoffice/include/resource.hpp +7 -0
- data/vendor/msoffice/include/standard_encryption.hpp +145 -0
- data/vendor/msoffice/include/uint32vec.hpp +179 -0
- data/vendor/msoffice/include/util.hpp +212 -0
- data/vendor/msoffice/lib/.emptydir +0 -0
- data/vendor/msoffice/misc/decrypt-xls.vbs +46 -0
- data/vendor/msoffice/mk.bat +1 -0
- data/vendor/msoffice/mkdll.bat +3 -0
- data/vendor/msoffice/msoc.def +13 -0
- data/vendor/msoffice/msocsample.py +178 -0
- data/vendor/msoffice/msoffice12.sln +31 -0
- data/vendor/msoffice/readme.md +110 -0
- data/vendor/msoffice/release.props +28 -0
- data/vendor/msoffice/src/Makefile +19 -0
- data/vendor/msoffice/src/attack.cpp +124 -0
- data/vendor/msoffice/src/cfb_test.cpp +77 -0
- data/vendor/msoffice/src/minisample.c +54 -0
- data/vendor/msoffice/src/msocdll.cpp +276 -0
- data/vendor/msoffice/src/msocsample.c +136 -0
- data/vendor/msoffice/src/msoffice-crypt.cpp +219 -0
- data/vendor/msoffice/src/proj/attack/attack.vcxproj +88 -0
- data/vendor/msoffice/src/proj/main/msoffice-crypt.vcxproj +88 -0
- data/vendor/msoffice/src/sha1.cpp +234 -0
- data/vendor/msoffice/test/Makefile +20 -0
- data/vendor/msoffice/test/cfb_test.cpp +74 -0
- data/vendor/msoffice/test/hash_test.cpp +59 -0
- data/vendor/msoffice/test/proj/cfb/cfb_test.vcxproj +90 -0
- data/vendor/msoffice/test/proj/hash/hash_test.vcxproj +90 -0
- data/vendor/msoffice/test/sampl.bat +8 -0
- data/vendor/msoffice/test_all.py +46 -0
- data/vendor/update +4 -0
- 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
|