// Copyright Vladimir Prus 2002-2004. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) #include #define BOOST_PROGRAM_OPTIONS_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #if !defined(__GNUC__) || __GNUC__ < 3 #include #else #include #endif #ifdef _WIN32 #include #else #include #endif // The 'environ' should be declared in some cases. E.g. Linux man page says: // (This variable must be declared in the user program, but is declared in // the header file unistd.h in case the header files came from libc4 or libc5, // and in case they came from glibc and _GNU_SOURCE was defined.) // To be safe, declare it here. // It appears that on Mac OS X the 'environ' variable is not // available to dynamically linked libraries. // See: http://article.gmane.org/gmane.comp.lib.boost.devel/103843 // See: http://lists.gnu.org/archive/html/bug-guile/2004-01/msg00013.html #if defined(__APPLE__) && defined(__DYNAMIC__) #include #define environ (*_NSGetEnviron()) #else #if defined(__MWERKS__) #include #else #if !defined(_WIN32) || defined(__COMO_VERSION__) extern char** environ; #endif #endif #endif using namespace std; namespace boost { namespace program_options { #ifndef BOOST_NO_STD_WSTRING namespace { woption woption_from_option(const option& opt) { woption result; result.string_key = opt.string_key; result.position_key = opt.position_key; result.unregistered = opt.unregistered; std::transform(opt.value.begin(), opt.value.end(), back_inserter(result.value), boost::bind(from_utf8, _1)); std::transform(opt.original_tokens.begin(), opt.original_tokens.end(), back_inserter(result.original_tokens), boost::bind(from_utf8, _1)); return result; } } basic_parsed_options ::basic_parsed_options(const parsed_options& po) : description(po.description), utf8_encoded_options(po) { for (unsigned i = 0; i < po.options.size(); ++i) options.push_back(woption_from_option(po.options[i])); } #endif template basic_parsed_options parse_config_file(std::basic_istream& is, const options_description& desc, bool allow_unregistered) { set allowed_options; const vector >& options = desc.options(); for (unsigned i = 0; i < options.size(); ++i) { const option_description& d = *options[i]; if (d.long_name().empty()) boost::throw_exception( error("long name required for config file")); allowed_options.insert(d.long_name()); } // Parser return char strings parsed_options result(&desc); copy(detail::basic_config_file_iterator( is, allowed_options, allow_unregistered), detail::basic_config_file_iterator(), back_inserter(result.options)); // Convert char strings into desired type. return basic_parsed_options(result); } template BOOST_PROGRAM_OPTIONS_DECL basic_parsed_options parse_config_file(std::basic_istream& is, const options_description& desc, bool allow_unregistered); #ifndef BOOST_NO_STD_WSTRING template BOOST_PROGRAM_OPTIONS_DECL basic_parsed_options parse_config_file(std::basic_istream& is, const options_description& desc, bool allow_unregistered); #endif template basic_parsed_options parse_config_file(const char* filename, const options_description& desc, bool allow_unregistered) { // Parser return char strings std::basic_ifstream< charT > strm(filename); if (!strm) { boost::throw_exception(reading_file(filename)); } return parse_config_file(strm, desc, allow_unregistered); } template BOOST_PROGRAM_OPTIONS_DECL basic_parsed_options parse_config_file(const char* filename, const options_description& desc, bool allow_unregistered); #ifndef BOOST_NO_STD_WSTRING template BOOST_PROGRAM_OPTIONS_DECL basic_parsed_options parse_config_file(const char* filename, const options_description& desc, bool allow_unregistered); #endif // This versio, which accepts any options without validation, is disabled, // in the hope that nobody will need it and we cant drop it altogether. // Besides, probably the right way to handle all options is the '*' name. #if 0 BOOST_PROGRAM_OPTIONS_DECL parsed_options parse_config_file(std::istream& is) { detail::config_file_iterator cf(is, false); parsed_options result(0); copy(cf, detail::config_file_iterator(), back_inserter(result.options)); return result; } #endif BOOST_PROGRAM_OPTIONS_DECL parsed_options parse_environment(const options_description& desc, const function1& name_mapper) { parsed_options result(&desc); for(environment_iterator i(environ), e; i != e; ++i) { string option_name = name_mapper(i->first); if (!option_name.empty()) { option n; n.string_key = option_name; n.value.push_back(i->second); result.options.push_back(n); } } return result; } namespace detail { class prefix_name_mapper { public: prefix_name_mapper(const std::string& prefix) : prefix(prefix) {} std::string operator()(const std::string& s) { string result; if (s.find(prefix) == 0) { for(string::size_type n = prefix.size(); n < s.size(); ++n) { // Intel-Win-7.1 does not understand // push_back on string. result += tolower(s[n]); } } return result; } private: std::string prefix; }; } BOOST_PROGRAM_OPTIONS_DECL parsed_options parse_environment(const options_description& desc, const std::string& prefix) { return parse_environment(desc, detail::prefix_name_mapper(prefix)); } BOOST_PROGRAM_OPTIONS_DECL parsed_options parse_environment(const options_description& desc, const char* prefix) { return parse_environment(desc, string(prefix)); } }}