├── .gitignore ├── .travis.yml ├── LICENSE ├── Makefile ├── OptionParser.cpp ├── OptionParser.h ├── README.md ├── t └── testprog ├── test.sh └── testprog.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | /testprog 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | compiler: 3 | - clang 4 | - gcc 5 | env: 6 | - CPP11=0 7 | - CPP11=1 8 | script: make test WARN=1 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2010 Johannes Weißl 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(WARN),1) 2 | ifeq ($(CXX),g++) 3 | WARN_FLAGS = -O3 -g -Wall -Wextra -Wabi -Wctor-dtor-privacy -Wnon-virtual-dtor -Wreorder -Wstrict-null-sentinel -Woverloaded-virtual -Wshadow -Wcast-align -Wpointer-arith -Wwrite-strings -Wundef -Wredundant-decls -Werror # -Weffc++ 4 | else ifeq ($(CXX),clang++) 5 | WARN_FLAGS = -O3 -g -Werror 6 | else ifeq ($(CXX),icpc) 7 | WARN_FLAGS = -O3 -ipo -g -Wall -wd981 -wd383 -wd2259 -Werror # -Weffc++ 8 | endif 9 | endif 10 | 11 | ifeq ($(CPP11),1) 12 | STD_FLAGS = -std=c++0x 13 | endif 14 | 15 | BIN = testprog 16 | OBJECTS = OptionParser.o testprog.o 17 | 18 | $(BIN): $(OBJECTS) 19 | $(CXX) -o $@ $(OBJECTS) $(WARN_FLAGS) $(STD_FLAGS) $(LINKFLAGS) 20 | 21 | %.o: %.cpp OptionParser.h 22 | $(CXX) $(WARN_FLAGS) $(STD_FLAGS) $(CXXFLAGS) -c $< -o $@ 23 | 24 | .PHONY: clean test 25 | 26 | test: testprog 27 | ./test.sh 28 | 29 | clean: 30 | rm -f *.o $(BIN) 31 | -------------------------------------------------------------------------------- /OptionParser.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2010 Johannes Weißl 3 | * License: MIT License 4 | * URL: https://github.com/weisslj/cpp-optparse 5 | */ 6 | 7 | #include "OptionParser.h" 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #if defined(ENABLE_NLS) && ENABLE_NLS 15 | # include 16 | # define _(s) gettext(s) 17 | #else 18 | # define _(s) ((const char *) (s)) 19 | #endif 20 | 21 | using namespace std; 22 | 23 | namespace optparse { 24 | 25 | ////////// auxiliary (string) functions { ////////// 26 | class str_wrap { 27 | public: 28 | str_wrap(const string& l, const string& r) : lwrap(l), rwrap(r) {} 29 | str_wrap(const string& w) : lwrap(w), rwrap(w) {} 30 | string operator() (const string& s) { return lwrap + s + rwrap; } 31 | const string lwrap, rwrap; 32 | }; 33 | template 34 | static string str_join_trans(const string& sep, InputIterator begin, InputIterator end, UnaryOperator op) { 35 | string buf; 36 | for (InputIterator it = begin; it != end; ++it) { 37 | if (it != begin) 38 | buf += sep; 39 | buf += op(*it); 40 | } 41 | return buf; 42 | } 43 | template 44 | static string str_join(const string& sep, InputIterator begin, InputIterator end) { 45 | return str_join_trans(sep, begin, end, str_wrap("")); 46 | } 47 | static string& str_replace(string& s, const string& patt, const string& repl) { 48 | size_t pos = 0, n = patt.length(); 49 | while (true) { 50 | pos = s.find(patt, pos); 51 | if (pos == string::npos) 52 | break; 53 | s.replace(pos, n, repl); 54 | pos += repl.size(); 55 | } 56 | return s; 57 | } 58 | static string str_replace(const string& s, const string& patt, const string& repl) { 59 | string tmp = s; 60 | str_replace(tmp, patt, repl); 61 | return tmp; 62 | } 63 | static string str_format(const string& str, size_t pre, size_t len, bool running_text = true, bool indent_first = true) { 64 | string s = str; 65 | stringstream ss; 66 | string p; 67 | len -= 2; // Python seems to not use full length 68 | if (running_text) 69 | replace(s.begin(), s.end(), '\n', ' '); 70 | if (indent_first) 71 | p = string(pre, ' '); 72 | 73 | size_t pos = 0, linestart = 0; 74 | size_t line = 0; 75 | while (true) { 76 | bool wrap = false; 77 | 78 | size_t new_pos = s.find_first_of(" \n\t", pos); 79 | if (new_pos == string::npos) 80 | break; 81 | if (s[new_pos] == '\n') { 82 | pos = new_pos + 1; 83 | wrap = true; 84 | } 85 | if (line == 1) 86 | p = string(pre, ' '); 87 | if (wrap || new_pos + pre > linestart + len) { 88 | ss << p << s.substr(linestart, pos - linestart - 1) << endl; 89 | linestart = pos; 90 | line++; 91 | } 92 | pos = new_pos + 1; 93 | } 94 | ss << p << s.substr(linestart) << endl; 95 | return ss.str(); 96 | } 97 | static string str_inc(const string& s) { 98 | stringstream ss; 99 | string v = (s != "") ? s : "0"; 100 | long i; 101 | istringstream(v) >> i; 102 | ss << i+1; 103 | return ss.str(); 104 | } 105 | static unsigned int cols() { 106 | unsigned int n = 80; 107 | #ifndef _WIN32 108 | const char *s = getenv("COLUMNS"); 109 | if (s) 110 | istringstream(s) >> n; 111 | #endif 112 | return n; 113 | } 114 | static string basename(const string& s) { 115 | string b = s; 116 | size_t i = b.find_last_not_of('/'); 117 | if (i == string::npos) { 118 | if (b[0] == '/') 119 | b.erase(1); 120 | return b; 121 | } 122 | b.erase(i+1, b.length()-i-1); 123 | i = b.find_last_of("/"); 124 | if (i != string::npos) 125 | b.erase(0, i+1); 126 | return b; 127 | } 128 | ////////// } auxiliary (string) functions ////////// 129 | 130 | 131 | ////////// class OptionContainer { ////////// 132 | Option& OptionContainer::add_option(const string& opt) { 133 | const string tmp[1] = { opt }; 134 | return add_option(vector(&tmp[0], &tmp[1])); 135 | } 136 | Option& OptionContainer::add_option(const string& opt1, const string& opt2) { 137 | const string tmp[2] = { opt1, opt2 }; 138 | return add_option(vector(&tmp[0], &tmp[2])); 139 | } 140 | Option& OptionContainer::add_option(const string& opt1, const string& opt2, const string& opt3) { 141 | const string tmp[3] = { opt1, opt2, opt3 }; 142 | return add_option(vector(&tmp[0], &tmp[3])); 143 | } 144 | Option& OptionContainer::add_option(const vector& v) { 145 | _opts.resize(_opts.size()+1, Option(get_parser())); 146 | Option& option = _opts.back(); 147 | string dest_fallback; 148 | for (vector::const_iterator it = v.begin(); it != v.end(); ++it) { 149 | if (it->substr(0,2) == "--") { 150 | const string s = it->substr(2); 151 | if (option.dest() == "") 152 | option.dest(str_replace(s, "-", "_")); 153 | option._long_opts.insert(s); 154 | _optmap_l[s] = &option; 155 | } else { 156 | const string s = it->substr(1,1); 157 | if (dest_fallback == "") 158 | dest_fallback = s; 159 | option._short_opts.insert(s); 160 | _optmap_s[s] = &option; 161 | } 162 | } 163 | if (option.dest() == "") 164 | option.dest(dest_fallback); 165 | return option; 166 | } 167 | string OptionContainer::format_option_help(unsigned int indent /* = 2 */) const { 168 | stringstream ss; 169 | 170 | if (_opts.empty()) 171 | return ss.str(); 172 | 173 | for (list