diff options
Diffstat (limited to 'option.cc')
-rw-r--r-- | option.cc | 133 |
1 files changed, 111 insertions, 22 deletions
@@ -6,9 +6,11 @@ #include "util.h" -option_handler::option_handler(const std::string& label, - const std::string& opt_chars) - : handled(false) +static std::deque<option_t> options; + +void register_option(const std::string& label, + const std::string& opt_chars, + option_handler& option) { DEBUG_PRINT("ledger.memory.ctors", "ctor option_handler"); @@ -25,8 +27,6 @@ option_handler::option_handler(const std::string& label, *p = '\0'; opt.long_opt = buf; - handlers.insert(option_handler_pair(opt.long_opt, this)); - if (! opt_chars.empty()) { if (opt_chars[0] != ':') opt.short_opt = opt_chars[0]; @@ -35,7 +35,7 @@ option_handler::option_handler(const std::string& label, opt.wants_arg = true; } - opt.handler = this; + opt.handler = &option; options.push_back(opt); } @@ -43,29 +43,33 @@ option_handler::option_handler(const std::string& label, static inline void process_option(const option_t& opt, const char * arg = NULL) { if (! opt.handler->handled) { - opt.handler->handle_option(arg); + (*opt.handler)(arg); opt.handler->handled = true; } } bool process_option(const std::string& opt, const char * arg) { - option_handler_map::iterator handler = option_handler::handlers.find(opt); - if (handler != option_handler::handlers.end()) { - if (! (*handler).second->handled) { - (*handler).second->handle_option(arg); - (*handler).second->handled = true; + for (std::deque<option_t>::iterator i = options.begin(); + i != options.end(); + i++) + if ((*i).long_opt == opt) { + if (! (*i).handler->handled) { + (*(*i).handler)(arg); + (*i).handler->handled = true; + return true; + } + break; } - return true; - } + return false; } void process_arguments(int argc, char ** argv, const bool anywhere, std::deque<std::string>& args) { - int index = 1; - for (char ** i = argv + 1; index < argc; i++, index++) { + int index = 0; + for (char ** i = argv; index < argc; i++, index++) { if ((*i)[0] != '-') { if (anywhere) { args.push_back(*i); @@ -83,8 +87,8 @@ void process_arguments(int argc, char ** argv, const bool anywhere, if ((*i)[2] == '\0') break; - for (std::deque<option_t>::iterator j = option_handler::options.begin(); - j != option_handler::options.end(); + for (std::deque<option_t>::iterator j = options.begin(); + j != options.end(); j++) if ((*j).wants_arg) { if (const char * p = std::strchr(*i + 2, '=')) { @@ -107,8 +111,8 @@ void process_arguments(int argc, char ** argv, const bool anywhere, std::cerr << "Error: illegal option " << *i << std::endl; std::exit(1); } else { - for (std::deque<option_t>::iterator j = option_handler::options.begin(); - j != option_handler::options.end(); + for (std::deque<option_t>::iterator j = options.begin(); + j != options.end(); j++) if ((*i)[1] == (*j).short_opt) { if ((*j).wants_arg) { @@ -136,12 +140,15 @@ void process_arguments(int argc, char ** argv, const bool anywhere, void process_environment(char ** envp, const std::string& tag) { + const char * tag_p = tag.c_str(); + int tag_len = tag.length(); + for (char ** p = envp; *p; p++) - if (std::strncmp(*p, tag.c_str(), 7) == 0) { + if (std::strncmp(*p, tag_p, tag_len) == 0) { char * q; static char buf[128]; char * r = buf; - for (q = *p + 7; *q && *q != '='; q++) + for (q = *p + tag_len; *q && *q != '='; q++) if (*q == '_') *r++ += '-'; else @@ -153,3 +160,85 @@ void process_environment(char ** envp, const std::string& tag) process_option(buf, q + 1); } } + +#ifdef USE_BOOST_PYTHON + +#include <boost/python.hpp> +#include <boost/python/detail/api_placeholder.hpp> +#include <Python.h> +#include <vector> + +using namespace boost::python; + +struct func_option_wrapper : public option_handler +{ + object self; + func_option_wrapper(object _self) : self(_self) {} + + virtual void operator()(const char * arg) { + call<void>(self.ptr(), arg); + } +}; + +static std::deque<func_option_wrapper> wrappers; + +void py_register_option(const std::string& long_opt, + const std::string& short_opt, object func) +{ + wrappers.push_back(func_option_wrapper(func)); + register_option(long_opt, short_opt, wrappers.back()); +} + +bool (*process_option_1)(const std::string& opt, const char * arg) + = process_option; + +list py_process_arguments(list args, bool anywhere = false) +{ + std::vector<char *> strs; + + int l = len(args); + for (int i = 0; i < l; i++) + strs.push_back(extract<char *>(args[i])); + + std::deque<std::string> newargs; + process_arguments(strs.size(), &strs.front(), anywhere, newargs); + + list py_newargs; + for (std::deque<std::string>::iterator i = newargs.begin(); + i != newargs.end(); + i++) + py_newargs.append(*i); + return py_newargs; +} + +void py_process_environment(object env, const std::string& tag) +{ + std::vector<char *> strs; + std::vector<std::string> storage; + + list items = call_method<list>(env.ptr(), "items"); + int l = len(items); + for (int i = 0; i < l; i++) { + tuple pair = extract<tuple>(items[i]); + std::string s = extract<std::string>(pair[0]); + s += "="; + s += extract<std::string>(pair[1]); + storage.push_back(s); + strs.push_back(const_cast<char *>(storage.back().c_str())); + } + + process_environment(&strs.front(), tag); +} + +BOOST_PYTHON_FUNCTION_OVERLOADS(py_proc_args_overloads, + py_process_arguments, 1, 2) + +void export_option() +{ + def("register_option", py_register_option); + def("process_option", process_option_1); + def("process_arguments", py_process_arguments, py_proc_args_overloads()); + def("process_environment", py_process_environment); +} + +#endif // USE_BOOST_PYTHON |