diff options
| author | Kevin Smith <git@kismith.co.uk> | 2010-04-21 11:45:51 (GMT) | 
|---|---|---|
| committer | Kevin Smith <git@kismith.co.uk> | 2010-04-23 10:54:04 (GMT) | 
| commit | 91686a86876553774452d97f3f74d5f147b19164 (patch) | |
| tree | fd0d601497f0cc757f12ec7c336b5b64213bbfd3 | |
| parent | 6bd72c67896a20041556519548650590553f47c9 (diff) | |
| download | swift-91686a86876553774452d97f3f74d5f147b19164.zip swift-91686a86876553774452d97f3f74d5f147b19164.tar.bz2 | |
Make latency stats optional.
Includes boost program_options so we can use commandline parameters.
Netbook mode is now activated with --netbook-mode.
Latency debug is activated with --latency-debug.
48 files changed, 5428 insertions, 34 deletions
| diff --git a/3rdParty/Boost/SConscript b/3rdParty/Boost/SConscript index 3e6897f..43f0180 100644 --- a/3rdParty/Boost/SConscript +++ b/3rdParty/Boost/SConscript @@ -61,7 +61,18 @@ if env["SCONS_STAGE"] == "build" :  			"src/libs/regex/src/wc_regex_traits.cpp",  			"src/libs/regex/src/wide_posix_api.cpp",  			"src/libs/regex/src/winstances.cpp", -			"src/libs/regex/src/usinstances.cpp"] +			"src/libs/regex/src/usinstances.cpp", +			"src/libs/program_options/src/cmdline.cpp", +			"src/libs/program_options/src/config_file.cpp", +			"src/libs/program_options/src/convert.cpp", +			"src/libs/program_options/src/options_description.cpp", +			"src/libs/program_options/src/parsers.cpp", +			"src/libs/program_options/src/positional_options.cpp", +			"src/libs/program_options/src/split.cpp", +			"src/libs/program_options/src/utf8_codecvt_facet.cpp", +			"src/libs/program_options/src/value_semantic.cpp", +			"src/libs/program_options/src/variables_map.cpp", +			"src/libs/program_options/src/winmain.cpp"]  	if env["PLATFORM"] != "win32" :  		sources += [ @@ -82,6 +93,7 @@ if env["SCONS_STAGE"] == "build" :  		bcp_env.Append(CPPPATH = ["src/tools/bcp"])  		bcp_env.Program("bcp", [  				"src/tools/bcp/add_path.cpp", +				"src/tools/bcp/add_dependent_lib.cpp",  				"src/tools/bcp/bcp_imp.cpp",  				"src/tools/bcp/copy_path.cpp",  				"src/tools/bcp/file_types.cpp", diff --git a/3rdParty/Boost/src/boost/program_options.hpp b/3rdParty/Boost/src/boost/program_options.hpp new file mode 100644 index 0000000..9d12b08 --- /dev/null +++ b/3rdParty/Boost/src/boost/program_options.hpp @@ -0,0 +1,25 @@ +// Copyright Vladimir Prus 2002. +// 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) + +//  See www.boost.org/libs/program_options for documentation. + +#ifndef PROGRAM_OPTIONS_VP_2003_05_19 +#define PROGRAM_OPTIONS_VP_2003_05_19 + +#if _MSC_VER >= 1020 +#pragma once +#endif + +#include <boost/program_options/options_description.hpp> +#include <boost/program_options/positional_options.hpp> +#include <boost/program_options/parsers.hpp> +#include <boost/program_options/variables_map.hpp> +#include <boost/program_options/cmdline.hpp> +#include <boost/program_options/errors.hpp> +#include <boost/program_options/option.hpp> +#include <boost/program_options/value_semantic.hpp> +#include <boost/program_options/version.hpp> + +#endif diff --git a/3rdParty/Boost/src/boost/program_options/cmdline.hpp b/3rdParty/Boost/src/boost/program_options/cmdline.hpp new file mode 100644 index 0000000..8705e60 --- /dev/null +++ b/3rdParty/Boost/src/boost/program_options/cmdline.hpp @@ -0,0 +1,90 @@ +// Copyright Vladimir Prus 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) + +#ifndef BOOST_CMDLINE_HPP_VP_2004_03_13 +#define BOOST_CMDLINE_HPP_VP_2004_03_13 + +namespace boost { namespace program_options { namespace command_line_style { +    /** Various possible styles of options. +         +    There are "long" options, which start with "--" and "short", +    which start with either "-" or "/". Both kinds can be allowed or +    disallowed, see allow_long and allow_short. The allowed character +    for short options is also configurable. + +    Option's value can be specified in the same token as name +    ("--foo=bar"), or in the next token. + +    It's possible to introduce long options by the same character as +    short options, see allow_long_disguise. + +    Finally, guessing (specifying only prefix of option) and case +    insensitive processing are supported. +    */ +    enum style_t { +        /// Allow "--long_name" style +        allow_long = 1, +        /// Allow "-<single character" style +        allow_short = allow_long << 1, +        /// Allow "-" in short options +        allow_dash_for_short = allow_short << 1, +        /// Allow "/" in short options +        allow_slash_for_short = allow_dash_for_short << 1, +        /** Allow option parameter in the same token +            for long option, like in +            @verbatim +            --foo=10 +            @endverbatim +        */ +        long_allow_adjacent = allow_slash_for_short << 1, +        /** Allow option parameter in the next token for +            long options. */ +        long_allow_next = long_allow_adjacent << 1, +        /** Allow option parameter in the same token for +            short options. */ +        short_allow_adjacent = long_allow_next << 1, +        /** Allow option parameter in the next token for +            short options. */ +        short_allow_next = short_allow_adjacent << 1, +        /** Allow to merge several short options together, +            so that "-s -k" become "-sk". All of the options +            but last should accept no parameter. For example, if +            "-s" accept a parameter, then "k" will be taken as +            parameter, not another short option.  +            Dos-style short options cannot be sticky. +        */ +        allow_sticky = short_allow_next << 1, +        /** Allow abbreviated spellings for long options, +            if they unambiguously identify long option.  +            No long option name should be prefix of other  +            long option name if guessing is in effect. +        */ +        allow_guessing = allow_sticky << 1, +        /** Ignore the difference in case for long options. +        */             +        long_case_insensitive = allow_guessing << 1,         +        /** Ignore the difference in case for short options. +        */             +        short_case_insensitive = long_case_insensitive << 1, +        /** Ignore the difference in case for all options. +        */         +        case_insensitive = (long_case_insensitive | short_case_insensitive),         +        /** Allow long options with single option starting character, +            e.g <tt>-foo=10</tt> +        */ +        allow_long_disguise = short_case_insensitive << 1, +        /** The more-or-less traditional unix style. */ +        unix_style = (allow_short | short_allow_adjacent | short_allow_next +                      | allow_long | long_allow_adjacent | long_allow_next +                      | allow_sticky | allow_guessing  +                      | allow_dash_for_short), +        /** The default style. */ +        default_style = unix_style +    }; +}}} + + +#endif + diff --git a/3rdParty/Boost/src/boost/program_options/config.hpp b/3rdParty/Boost/src/boost/program_options/config.hpp new file mode 100644 index 0000000..0c69c14 --- /dev/null +++ b/3rdParty/Boost/src/boost/program_options/config.hpp @@ -0,0 +1,55 @@ +//    Copyright (c) 2004 Hartmut Kaiser +// +//    Use, modification and distribution is subject to 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) + +#ifndef BOOST_PROGRAM_OPTIONS_CONFIG_HK_2004_01_11 +#define BOOST_PROGRAM_OPTIONS_CONFIG_HK_2004_01_11 + +#include <boost/config.hpp> +#include <boost/version.hpp> + +// Support for autolinking. +#if BOOST_VERSION >= 103100   // works beginning from Boost V1.31.0 + +/////////////////////////////////////////////////////////////////////////////// +// enable automatic library variant selection  +#if !defined(BOOST_PROGRAM_OPTIONS_SOURCE) && !defined(BOOST_ALL_NO_LIB) && \ +    !defined(BOOST_PROGRAM_OPTIONS_NO_LIB) + +// Set the name of our library, this will get undef'ed by auto_link.hpp +// once it's done with it: +#define BOOST_LIB_NAME boost_program_options +// tell the auto-link code to select a dll when required: +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_PROGRAM_OPTIONS_DYN_LINK) +#  define BOOST_DYN_LINK +#endif + +// And include the header that does the work: +#include <boost/config/auto_link.hpp> + +#endif  // auto-linking disabled + +#endif  // BOOST_VERSION + +/////////////////////////////////////////////////////////////////////////////// +// Windows DLL suport +#ifdef BOOST_HAS_DECLSPEC +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_PROGRAM_OPTIONS_DYN_LINK) +// export if this is our own source, otherwise import: +#ifdef BOOST_PROGRAM_OPTIONS_SOURCE +# define BOOST_PROGRAM_OPTIONS_DECL __declspec(dllexport) +#else +# define BOOST_PROGRAM_OPTIONS_DECL __declspec(dllimport) +#endif  // BOOST_PROGRAM_OPTIONS_SOURCE +#endif  // DYN_LINK +#endif  // BOOST_HAS_DECLSPEC + +#ifndef BOOST_PROGRAM_OPTIONS_DECL +#define BOOST_PROGRAM_OPTIONS_DECL +#endif + + +#endif // PROGRAM_OPTIONS_CONFIG_HK_2004_01_11 + diff --git a/3rdParty/Boost/src/boost/program_options/detail/cmdline.hpp b/3rdParty/Boost/src/boost/program_options/detail/cmdline.hpp new file mode 100644 index 0000000..8d60ead --- /dev/null +++ b/3rdParty/Boost/src/boost/program_options/detail/cmdline.hpp @@ -0,0 +1,138 @@ +// 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) + + +#ifndef BOOST_CMDLINE_VP_2003_05_19 +#define BOOST_CMDLINE_VP_2003_05_19 + +#include <boost/program_options/config.hpp> +#include <boost/program_options/errors.hpp> +#include <boost/program_options/cmdline.hpp> +#include <boost/program_options/option.hpp> +#include <boost/program_options/options_description.hpp> +#include <boost/program_options/positional_options.hpp> + + +#include <boost/detail/workaround.hpp> + +#include <boost/function.hpp> + +#include <string> +#include <vector> + +namespace boost { namespace program_options { namespace detail { + +    /** Command line parser class. Main requirements were: +        - Powerful enough to support all common uses. +        - Simple and easy to learn/use. +        - Minimal code size and external dependencies. +        - Extensible for custom syntaxes. + +        First all options are registered. After that, elements of command line +        are extracted using operator++.  + +        For each element, user can find +        - if it's an option or an argument +        - name of the option +        - index of the option +        - option value(s), if any +         +        Sometimes the registered option name is not equal to the encountered +        one, for example, because name abbreviation is supported.  Therefore +        two option names can be obtained:  +        - the registered one  +        - the one found at the command line + +        There are lot of style options, which can be used to tune the command +        line parsing. In addition, it's possible to install additional parser +        which will process custom option styles. + +        @todo mininal match length for guessing? +    */ +    class BOOST_PROGRAM_OPTIONS_DECL cmdline { +    public: + +        typedef ::boost::program_options::command_line_style::style_t style_t; + +        typedef function1<std::pair<std::string, std::string>,  +                          const std::string&>  +            additional_parser; + +        typedef function1<std::vector<option>, std::vector<std::string>&> +            style_parser; +         +        /** Constructs a command line parser for (argc, argv) pair. Uses +            style options passed in 'style', which should be binary or'ed values +            of style_t enum. It can also be zero, in which case a "default" +            style will be used. If 'allow_unregistered' is true, then allows  +            unregistered options. They will be assigned index 1 and are +            assumed to have optional parameter. +        */ +        cmdline(const std::vector<std::string>& args); + +        /** @overload */ +        cmdline(int argc, const char*const * argv); + +        void style(int style); +        void allow_unregistered(); + +        void set_options_description(const options_description& desc); +        void set_positional_options( +            const positional_options_description& m_positional); + +        std::vector<option> run(); + +        std::vector<option> parse_long_option(std::vector<std::string>& args); +        std::vector<option> parse_short_option(std::vector<std::string>& args); +        std::vector<option> parse_dos_option(std::vector<std::string>& args); +        std::vector<option> parse_disguised_long_option( +            std::vector<std::string>& args); +        std::vector<option> parse_terminator( +            std::vector<std::string>& args); +        std::vector<option> handle_additional_parser( +            std::vector<std::string>& args); + + +        /** Set additional parser. This will be called for each token +            of command line. If first string in pair is not empty, +            then the token is considered matched by this parser, +            and the first string will be considered an option name +            (which can be long or short), while the second will be +            option's parameter (if not empty).  +            Note that additional parser can match only one token. +        */ +        void set_additional_parser(additional_parser p); + +        void extra_style_parser(style_parser s); + +        void check_style(int style) const; +         +        bool is_style_active(style_t style) const; + +        void init(const std::vector<std::string>& args); + +        void +        finish_option(option& opt, +                      std::vector<std::string>& other_tokens, +                      const std::vector<style_parser>& style_parsers); + +        // Copies of input. +        std::vector<std::string> args; +        style_t m_style; +        bool m_allow_unregistered; + +        const options_description* m_desc; +        const positional_options_description* m_positional; + +        additional_parser m_additional_parser; +        style_parser m_style_parser; +    }; +     +    void test_cmdline_detail(); +     +}}} + +#endif + diff --git a/3rdParty/Boost/src/boost/program_options/detail/config_file.hpp b/3rdParty/Boost/src/boost/program_options/detail/config_file.hpp new file mode 100644 index 0000000..91caac7 --- /dev/null +++ b/3rdParty/Boost/src/boost/program_options/detail/config_file.hpp @@ -0,0 +1,182 @@ +// 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) + + +#ifndef BOOST_CONFIG_FILE_VP_2003_01_02 +#define BOOST_CONFIG_FILE_VP_2003_01_02 + +#include <iosfwd> +#include <string> +#include <set> + +#include <boost/noncopyable.hpp> +#include <boost/program_options/config.hpp> +#include <boost/program_options/option.hpp> +#include <boost/program_options/eof_iterator.hpp> + +#include <boost/detail/workaround.hpp> +#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) +#include <boost/program_options/detail/convert.hpp> +#endif + +#if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042)) +#include <istream> // std::getline +#endif + +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/shared_ptr.hpp> + + + +namespace boost { namespace program_options { namespace detail { + +    /** Standalone parser for config files in ini-line format. +        The parser is a model of single-pass lvalue iterator, and +        default constructor creates past-the-end-iterator. The typical usage is: +        config_file_iterator i(is, ... set of options ...), e; +        for(; i !=e; ++i) { +            *i; +        } +         +        Syntax conventions: + +        - config file can not contain positional options +        - '#' is comment character: it is ignored together with +          the rest of the line. +        - variable assignments are in the form +          name '=' value. +          spaces around '=' are trimmed. +        - Section names are given in brackets.  + +         The actual option name is constructed by combining current section +         name and specified option name, with dot between. If section_name  +         already contains dot at the end, new dot is not inserted. For example: +         @verbatim +         [gui.accessibility] +         visual_bell=yes +         @endverbatim +         will result in option "gui.accessibility.visual_bell" with value +         "yes" been returned. + +         TODO: maybe, we should just accept a pointer to options_description +         class. +     */     +    class common_config_file_iterator  +        : public eof_iterator<common_config_file_iterator, option> +    { +    public: +        common_config_file_iterator() { found_eof(); } +        common_config_file_iterator( +            const std::set<std::string>& allowed_options, +            bool allow_unregistered = false); + +        virtual ~common_config_file_iterator() {} + +    public: // Method required by eof_iterator +         +        void get(); +         +    protected: // Stubs for derived classes + +        // Obtains next line from the config file +        // Note: really, this design is a bit ugly +        // The most clean thing would be to pass 'line_iterator' to +        // constructor of this class, but to avoid templating this class +        // we'd need polymorphic iterator, which does not exist yet. +        virtual bool getline(std::string&) { return false; } +         +    private: +        /** Adds another allowed option. If the 'name' ends with +            '*', then all options with the same prefix are +            allowed. For example, if 'name' is 'foo*', then 'foo1' and +            'foo_bar' are allowed. */ +        void add_option(const char* name); + +        // Returns true if 's' is a registered option name. +        bool allowed_option(const std::string& s) const;  + +        // That's probably too much data for iterator, since +        // it will be copied, but let's not bother for now. +        std::set<std::string> allowed_options; +        // Invariant: no element is prefix of other element. +        std::set<std::string> allowed_prefixes; +        std::string m_prefix; +        bool m_allow_unregistered; +    }; + +    template<class charT> +    class basic_config_file_iterator : public common_config_file_iterator { +    public: +        basic_config_file_iterator() +        { +            found_eof(); +        } + +        /** Creates a config file parser for the specified stream.             +        */ +        basic_config_file_iterator(std::basic_istream<charT>& is,  +                                   const std::set<std::string>& allowed_options, +                                   bool allow_unregistered = false);  + +    private: // base overrides + +        bool getline(std::string&); + +    private: // internal data +        shared_ptr<std::basic_istream<charT> > is; +    }; +     +    typedef basic_config_file_iterator<char> config_file_iterator; +    typedef basic_config_file_iterator<wchar_t> wconfig_file_iterator; + + +    struct null_deleter +    { +        void operator()(void const *) const {} +    }; + + +    template<class charT> +    basic_config_file_iterator<charT>:: +    basic_config_file_iterator(std::basic_istream<charT>& is,  +                               const std::set<std::string>& allowed_options, +                               bool allow_unregistered) +    : common_config_file_iterator(allowed_options, allow_unregistered) +    { +        this->is.reset(&is, null_deleter());                  +        get(); +    } + +    // Specializing this function for wchar_t causes problems on +    // borland and vc7, as well as on metrowerks. On the first two +    // I don't know a workaround, so make use of 'to_internal' to +    // avoid specialization. +    template<class charT> +    bool +    basic_config_file_iterator<charT>::getline(std::string& s) +    { +        std::basic_string<charT> in; +        if (std::getline(*is, in)) { +            s = to_internal(in); +            return true; +        } else { +            return false; +        } +    } + +    // Specialization is needed to workaround getline bug on Comeau. +#if BOOST_WORKAROUND(__COMO_VERSION__, BOOST_TESTED_AT(4303)) || \ +        (defined(__sgi) && BOOST_WORKAROUND(_COMPILER_VERSION, BOOST_TESTED_AT(741))) +    template<> +    bool +    basic_config_file_iterator<wchar_t>::getline(std::string& s); +#endif + +     + +}}} + +#endif diff --git a/3rdParty/Boost/src/boost/program_options/detail/convert.hpp b/3rdParty/Boost/src/boost/program_options/detail/convert.hpp new file mode 100644 index 0000000..a22dd6f --- /dev/null +++ b/3rdParty/Boost/src/boost/program_options/detail/convert.hpp @@ -0,0 +1,107 @@ +// Copyright Vladimir Prus 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) + +#ifndef BOOST_CONVERT_HPP_VP_2004_04_28 +#define BOOST_CONVERT_HPP_VP_2004_04_28 + +#include <boost/program_options/config.hpp> + +#if !defined(BOOST_NO_STD_WSTRING) + +#include <boost/detail/workaround.hpp> + +#include <string> +#include <vector> +#include <locale> +// for mbstate_t +#include <cwchar> +#include <stdexcept> + +#if defined(BOOST_NO_STDC_NAMESPACE) +#include <wchar.h> +namespace std +{ +    using ::mbstate_t; +}     +#endif + +namespace boost { + +    /** Converts from local 8 bit encoding into wchar_t string using +        the specified locale facet. */ +    BOOST_PROGRAM_OPTIONS_DECL std::wstring  +    from_8_bit(const std::string& s,  +               const std::codecvt<wchar_t, char, std::mbstate_t>& cvt); + +    /** Converts from wchar_t string into local 8 bit encoding into using +        the specified locale facet. */ +    BOOST_PROGRAM_OPTIONS_DECL std::string  +    to_8_bit(const std::wstring& s,  +             const std::codecvt<wchar_t, char, std::mbstate_t>& cvt); + + +    /** Converts 's', which is assumed to be in UTF8 encoding, into wide +        string. */ +    BOOST_PROGRAM_OPTIONS_DECL std::wstring +    from_utf8(const std::string& s); +     +    /** Converts wide string 's' into string in UTF8 encoding. */ +    BOOST_PROGRAM_OPTIONS_DECL std::string +    to_utf8(const std::wstring& s); + +    /** Converts wide string 's' into local 8 bit encoding determined by +        the current locale. */ +    BOOST_PROGRAM_OPTIONS_DECL std::string +    to_local_8_bit(const std::wstring& s); + +    /** Converts 's', which is assumed to be in local 8 bit encoding, into wide +        string. */ +    BOOST_PROGRAM_OPTIONS_DECL std::wstring +    from_local_8_bit(const std::string& s); + +    namespace program_options +    { +        /** Convert the input string into internal encoding used by +            program_options. Presence of this function allows to avoid +            specializing all methods which access input on wchar_t. +        */ +        BOOST_PROGRAM_OPTIONS_DECL std::string to_internal(const std::string&); +        /** @overload */ +        BOOST_PROGRAM_OPTIONS_DECL std::string to_internal(const std::wstring&); + +        template<class T> +        std::vector<std::string> to_internal(const std::vector<T>& s) +        { +            std::vector<std::string> result; +            for (unsigned i = 0; i < s.size(); ++i) +                result.push_back(to_internal(s[i]));             +            return result; +        } + +    } + + +   +} + +#else +#include <vector> +#include <string> +namespace boost{ +   namespace program_options{ +        BOOST_PROGRAM_OPTIONS_DECL std::string to_internal(const std::string&); + +        template<class T> +        std::vector<std::string> to_internal(const std::vector<T>& s) +        { +            std::vector<std::string> result; +            for (unsigned i = 0; i < s.size(); ++i) +                result.push_back(to_internal(s[i]));             +            return result; +        } +   } +} +#endif +#endif diff --git a/3rdParty/Boost/src/boost/program_options/detail/parsers.hpp b/3rdParty/Boost/src/boost/program_options/detail/parsers.hpp new file mode 100644 index 0000000..ee19207 --- /dev/null +++ b/3rdParty/Boost/src/boost/program_options/detail/parsers.hpp @@ -0,0 +1,146 @@ +// Copyright Vladimir Prus 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) + +#ifndef BOOST_PARSERS_HPP_VP_2004_05_06 +#define BOOST_PARSERS_HPP_VP_2004_05_06 + +#include <boost/program_options/detail/convert.hpp> + +#include <iterator> + +namespace boost { namespace program_options { + +    namespace detail { +        template<class charT, class Iterator> +        std::vector<std::basic_string<charT> >  +        make_vector(Iterator i, Iterator e) +        { +            std::vector<std::basic_string<charT> > result; +            // Some compilers don't have templated constructor for  +            // vector, so we can't create vector from (argv+1, argv+argc) range +            for(; i != e; ++i) +                result.push_back(*i); +            return result;             +        } +    } + +    template<class charT> +    basic_command_line_parser<charT>:: +    basic_command_line_parser(const std::vector< +                              std::basic_string<charT> >& args) +       : detail::cmdline(to_internal(args)) +    {} + + +    template<class charT> +    basic_command_line_parser<charT>:: +    basic_command_line_parser(int argc, charT* argv[]) +    : detail::cmdline( +        // Explicit template arguments are required by gcc 3.3.1  +        // (at least mingw version), and do no harm on other compilers. +        to_internal(detail::make_vector<charT, charT**>(argv+1, argv+argc+!argc))) +    {} + +     +    template<class charT> +    basic_command_line_parser<charT>&  +    basic_command_line_parser<charT>::options(const options_description& desc) +    { +       detail::cmdline::set_options_description(desc); +        m_desc = &desc; +        return *this; +    } + +    template<class charT> +    basic_command_line_parser<charT>&  +    basic_command_line_parser<charT>::positional( +        const positional_options_description& desc) +    { +        detail::cmdline::set_positional_options(desc); +        return *this; +    } + +    template<class charT> +    basic_command_line_parser<charT>&  +    basic_command_line_parser<charT>::style(int style) +    { +        detail::cmdline::style(style); +        return *this; +    } + +    template<class charT> +    basic_command_line_parser<charT>&  +    basic_command_line_parser<charT>::extra_parser(ext_parser ext) +    { +        detail::cmdline::set_additional_parser(ext); +        return *this; +    } + +    template<class charT> +    basic_command_line_parser<charT>&  +    basic_command_line_parser<charT>::allow_unregistered() +    { +        detail::cmdline::allow_unregistered(); +        return *this; +    } + +    template<class charT> +    basic_command_line_parser<charT>&  +    basic_command_line_parser<charT>::extra_style_parser(style_parser s) +    { +        detail::cmdline::extra_style_parser(s); +        return *this; +    } + + + +    template<class charT>     +    basic_parsed_options<charT> +    basic_command_line_parser<charT>::run() +    { +        parsed_options result(m_desc); +        result.options = detail::cmdline::run(); + +        // Presense of parsed_options -> wparsed_options conversion +        // does the trick. +        return basic_parsed_options<charT>(result); +    } + + +    template<class charT> +    basic_parsed_options<charT> +    parse_command_line(int argc, charT* argv[], +                       const options_description& desc, +                       int style, +                       function1<std::pair<std::string, std::string>,  +                                 const std::string&> ext) +    { +        return basic_command_line_parser<charT>(argc, argv).options(desc). +            style(style).extra_parser(ext).run(); +    } + +    template<class charT> +    std::vector< std::basic_string<charT> >  +    collect_unrecognized(const std::vector< basic_option<charT> >& options, +                         enum collect_unrecognized_mode mode) +    { +        std::vector< std::basic_string<charT> >  result; +        for(unsigned i = 0; i < options.size(); ++i) +        { +            if (options[i].unregistered || +                (mode == include_positional && options[i].position_key != -1)) +            { +                copy(options[i].original_tokens.begin(), +                     options[i].original_tokens.end(), +                     back_inserter(result)); +            } +        } +        return result; +    } + + +}} + +#endif diff --git a/3rdParty/Boost/src/boost/program_options/detail/utf8_codecvt_facet.hpp b/3rdParty/Boost/src/boost/program_options/detail/utf8_codecvt_facet.hpp new file mode 100644 index 0000000..b77b551 --- /dev/null +++ b/3rdParty/Boost/src/boost/program_options/detail/utf8_codecvt_facet.hpp @@ -0,0 +1,25 @@ +// Copyright (c) 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu) +// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu). Permission to copy,  +// use, modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided "as is" +// without express or implied warranty, and with no claim as to its suitability +// for any purpose. + +#ifndef BOOST_PROGRAM_OPTIONS_UTF8_CODECVT_FACET_HPP +#define BOOST_PROGRAM_OPTIONS_UTF8_CODECVT_FACET_HPP + +#include <boost/program_options/config.hpp> + +#define BOOST_UTF8_BEGIN_NAMESPACE \ +     namespace boost { namespace program_options { namespace detail { + +#define BOOST_UTF8_END_NAMESPACE }}} +#define BOOST_UTF8_DECL BOOST_PROGRAM_OPTIONS_DECL + +#include <boost/detail/utf8_codecvt_facet.hpp> + +#undef BOOST_UTF8_BEGIN_NAMESPACE +#undef BOOST_UTF8_END_NAMESPACE +#undef BOOST_UTF8_DECL + +#endif diff --git a/3rdParty/Boost/src/boost/program_options/detail/value_semantic.hpp b/3rdParty/Boost/src/boost/program_options/detail/value_semantic.hpp new file mode 100644 index 0000000..464e306 --- /dev/null +++ b/3rdParty/Boost/src/boost/program_options/detail/value_semantic.hpp @@ -0,0 +1,207 @@ +// Copyright Vladimir Prus 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) + +// This file defines template functions that are declared in +// ../value_semantic.hpp. + +#include <boost/throw_exception.hpp> + +namespace boost { namespace program_options {  + +    extern BOOST_PROGRAM_OPTIONS_DECL std::string arg; +     +    template<class T, class charT> +    std::string +    typed_value<T, charT>::name() const +    { +        if (!m_implicit_value.empty() && !m_implicit_value_as_text.empty()) { +            std::string msg = "[=arg(=" + m_implicit_value_as_text + ")]"; +            if (!m_default_value.empty() && !m_default_value_as_text.empty()) +                msg += " (=" + m_default_value_as_text + ")"; +            return msg; +        } +        else if (!m_default_value.empty() && !m_default_value_as_text.empty()) { +            return arg + " (=" + m_default_value_as_text + ")"; +        } else { +            return arg; +        } +    } + +    template<class T, class charT> +    void  +    typed_value<T, charT>::notify(const boost::any& value_store) const +    { +        const T* value = boost::any_cast<T>(&value_store); +        if (m_store_to) { +            *m_store_to = *value; +        } +        if (m_notifier) { +            m_notifier(*value); +        } +    } + +    namespace validators { +        /* If v.size() > 1, throw validation_error.  +           If v.size() == 1, return v.front() +           Otherwise, returns a reference to a statically allocated +           empty string if 'allow_empty' and throws validation_error +           otherwise. */ +        template<class charT> +        const std::basic_string<charT>& get_single_string( +            const std::vector<std::basic_string<charT> >& v,  +            bool allow_empty = false) +        { +            static std::basic_string<charT> empty; +            if (v.size() > 1) +                boost::throw_exception(validation_error(validation_error::multiple_values_not_allowed)); +            else if (v.size() == 1) +                return v.front(); +            else if (!allow_empty) +                boost::throw_exception(validation_error(validation_error::at_least_one_value_required)); +            return empty; +        } + +        /* Throws multiple_occurrences if 'value' is not empty. */ +        BOOST_PROGRAM_OPTIONS_DECL void  +        check_first_occurrence(const boost::any& value); +    } + +    using namespace validators; + +    /** Validates 's' and updates 'v'. +        @pre 'v' is either empty or in the state assigned by the previous +        invocation of 'validate'. +        The target type is specified via a parameter which has the type of  +        pointer to the desired type. This is workaround for compilers without +        partial template ordering, just like the last 'long/int' parameter. +    */ +    template<class T, class charT> +    void validate(boost::any& v,  +                  const std::vector< std::basic_string<charT> >& xs,  +                  T*, long) +    { +        validators::check_first_occurrence(v); +        std::basic_string<charT> s(validators::get_single_string(xs)); +        try { +            v = any(lexical_cast<T>(s)); +        } +        catch(const bad_lexical_cast&) { +            boost::throw_exception(invalid_option_value(s)); +        } +    } + +    BOOST_PROGRAM_OPTIONS_DECL void validate(boost::any& v,  +                       const std::vector<std::string>& xs,  +                       bool*, +                       int); + +#if !defined(BOOST_NO_STD_WSTRING) +    BOOST_PROGRAM_OPTIONS_DECL void validate(boost::any& v,  +                       const std::vector<std::wstring>& xs,  +                       bool*, +                       int); +#endif +    // For some reason, this declaration, which is require by the standard, +    // cause gcc 3.2 to not generate code to specialization defined in +    // value_semantic.cpp +#if ! ( ( BOOST_WORKAROUND(__GNUC__, <= 3) &&\ +          BOOST_WORKAROUND(__GNUC_MINOR__, < 3) ) || \ +        ( BOOST_WORKAROUND(BOOST_MSVC, == 1310) ) \ +      )  +    BOOST_PROGRAM_OPTIONS_DECL void validate(boost::any& v,  +                       const std::vector<std::string>& xs, +                       std::string*, +                       int); + +#if !defined(BOOST_NO_STD_WSTRING) +    BOOST_PROGRAM_OPTIONS_DECL void validate(boost::any& v,  +                       const std::vector<std::wstring>& xs, +                       std::string*, +                       int); +#endif +#endif + +    /** Validates sequences. Allows multiple values per option occurrence +       and multiple occurrences. */ +    template<class T, class charT> +    void validate(boost::any& v,  +                  const std::vector<std::basic_string<charT> >& s,  +                  std::vector<T>*, +                  int) +    { +        if (v.empty()) { +            v = boost::any(std::vector<T>()); +        } +        std::vector<T>* tv = boost::any_cast< std::vector<T> >(&v); +        assert(NULL != tv); +        for (unsigned i = 0; i < s.size(); ++i) +        { +            try { +                /* We call validate so that if user provided +                   a validator for class T, we use it even +                   when parsing vector<T>.  */ +                boost::any a; +                std::vector<std::basic_string<charT> > v; +                v.push_back(s[i]); +                validate(a, v, (T*)0, 0);                 +                tv->push_back(boost::any_cast<T>(a)); +            } +            catch(const bad_lexical_cast& /*e*/) { +                boost::throw_exception(invalid_option_value(s[i])); +            } +        } +    } + +    template<class T, class charT> +    void  +    typed_value<T, charT>:: +    xparse(boost::any& value_store,  +           const std::vector<std::basic_string<charT> >& new_tokens) const +    { +        // If no tokens were given, and the option accepts an implicit +        // value, then assign the implicit value as the stored value; +        // otherwise, validate the user-provided token(s). +        if (new_tokens.empty() && !m_implicit_value.empty()) +            value_store = m_implicit_value; +        else +            validate(value_store, new_tokens, (T*)0, 0); +    } + +    template<class T> +    typed_value<T>* +    value() +    { +        // Explicit qualification is vc6 workaround. +        return boost::program_options::value<T>(0); +    } + +    template<class T> +    typed_value<T>* +    value(T* v) +    { +        typed_value<T>* r = new typed_value<T>(v); + +        return r;         +    } + +    template<class T> +    typed_value<T, wchar_t>* +    wvalue() +    { +        return wvalue<T>(0); +    } + +    template<class T> +    typed_value<T, wchar_t>* +    wvalue(T* v) +    { +        typed_value<T, wchar_t>* r = new typed_value<T, wchar_t>(v); + +        return r;         +    } + + + +}} diff --git a/3rdParty/Boost/src/boost/program_options/environment_iterator.hpp b/3rdParty/Boost/src/boost/program_options/environment_iterator.hpp new file mode 100644 index 0000000..c815693 --- /dev/null +++ b/3rdParty/Boost/src/boost/program_options/environment_iterator.hpp @@ -0,0 +1,51 @@ +// Copyright Vladimir Prus 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) + +#ifndef BOOST_ENVIRONMENT_ITERATOR_VP_2004_05_14 +#define BOOST_ENVIRONMENT_ITERATOR_VP_2004_05_14 + +#include "eof_iterator.hpp" + +#include <utility> +#include <string> +#include <cassert> + +namespace boost { + +    class environment_iterator  +        : public eof_iterator<environment_iterator,  +                              std::pair<std::string, std::string> > +    { +    public: +        environment_iterator(char** environment) +        : m_environment(environment) +        { +            get(); +        } +         +        environment_iterator() +        { +            found_eof(); +        } +         +        void get() +        { +            if (*m_environment == 0) +                found_eof(); +            else { +                std::string s(*m_environment); +                std::string::size_type n = s.find('='); +                assert(n != s.npos); +                value().first = s.substr(0, n); +                value().second = s.substr(n+1); +            }             +            ++m_environment; +        } +         +    private: +        char** m_environment; +    }; +} +#endif diff --git a/3rdParty/Boost/src/boost/program_options/eof_iterator.hpp b/3rdParty/Boost/src/boost/program_options/eof_iterator.hpp new file mode 100644 index 0000000..0efa6f7 --- /dev/null +++ b/3rdParty/Boost/src/boost/program_options/eof_iterator.hpp @@ -0,0 +1,97 @@ +// Copyright Vladimir Prus 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) + +#ifndef BOOST_EOF_ITERATOR_VP_2004_03_12 +#define BOOST_EOF_ITERATOR_VP_2004_03_12 + +#include <boost/iterator/iterator_facade.hpp> + +namespace boost { + +    /** The 'eof_iterator' class is useful for constructing forward iterators  +        in cases where iterator extract data from some source and it's easy  +        to detect 'eof' -- i.e. the situation where there's no data. One  +        apparent example is reading lines from a file. +         +        Implementing such iterators using 'iterator_facade' directly would +        require to create class with three core operation, a couple of  +        constructors. When using 'eof_iterator', the derived class should define  +        only one method to get new value, plus a couple of constructors. + +        The basic idea is that iterator has 'eof' bit. Two iterators are equal  +        only if both have their 'eof' bits set. The 'get' method either obtains +        the new value or sets the 'eof' bit. + +        Specifically, derived class should define: + +        1. A default constructor, which creates iterator with 'eof' bit set. The +        constructor body should call 'found_eof' method defined here. +        2. Some other constructor. It should initialize some 'data pointer' used +        in iterator operation and then call 'get'. +        3. The 'get' method. It should operate this way: +            - look at some 'data pointer' to see if new element is available; +              if not, it should call 'found_eof'. +            - extract new element and store it at location returned by the 'value'  +               method. +            - advance the data pointer. + +        Essentially, the 'get' method has the functionality of both 'increment'  +        and 'dereference'. It's very good for the cases where data extraction  +        implicitly moves data pointer, like for stream operation.          +    */ +    template<class Derived, class ValueType> +    class eof_iterator : public iterator_facade<Derived, const ValueType, +                                                forward_traversal_tag> +    { +    public: +        eof_iterator() +        : m_at_eof(false) +        {} + +    protected: // interface for derived + +        /** Returns the reference which should be used by derived +            class to store the next value. */ +        ValueType& value() +        { +            return m_value; +        } + +        /** Should be called by derived class to indicate that it can't +            produce next element. */ +        void found_eof() +        { +            m_at_eof = true; +        } +         + +    private: // iterator core operations +        friend class iterator_core_access; +     +        void increment()  +        { +            static_cast<Derived&>(*this).get(); +        } +     +        bool equal(const eof_iterator& other) const +        { +            if (m_at_eof && other.m_at_eof) +                return true; +            else +                return false; +        } +         +        const ValueType& dereference() const +        { +            return m_value; +        } + +        bool m_at_eof; +        ValueType m_value;         +    }; +} + +#endif + diff --git a/3rdParty/Boost/src/boost/program_options/errors.hpp b/3rdParty/Boost/src/boost/program_options/errors.hpp new file mode 100644 index 0000000..116af58 --- /dev/null +++ b/3rdParty/Boost/src/boost/program_options/errors.hpp @@ -0,0 +1,236 @@ +// 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) + + +#ifndef BOOST_ERRORS_VP_2003_01_02 +#define BOOST_ERRORS_VP_2003_01_02 + +#include <boost/program_options/config.hpp> + +#include <string> +#include <stdexcept> +#include <vector> + + + +namespace boost { namespace program_options { + +    /** Base class for all errors in the library. */ +    class BOOST_PROGRAM_OPTIONS_DECL error : public std::logic_error { +    public: +        error(const std::string& what) : std::logic_error(what) {} +    }; + +    class BOOST_PROGRAM_OPTIONS_DECL invalid_syntax : public error { +    public: +        enum kind_t { +            long_not_allowed = 30, +            long_adjacent_not_allowed, +            short_adjacent_not_allowed, +            empty_adjacent_parameter, +            missing_parameter, +            extra_parameter, +            unrecognized_line +        }; +         +        invalid_syntax(const std::string& tokens, kind_t kind); + +        // gcc says that throw specification on dtor is loosened +        // without this line +        ~invalid_syntax() throw() {} +         +        kind_t kind() const; +         +        const std::string& tokens() const; +         +    protected: +        /** Used to convert kind_t to a related error text */ +        static std::string error_message(kind_t kind); + +    private: +        // TODO: copy ctor might throw +        std::string m_tokens; + +        kind_t m_kind; +    }; + +    /** Class thrown when option name is not recognized. */ +    class BOOST_PROGRAM_OPTIONS_DECL unknown_option : public error { +    public: +        unknown_option(const std::string& name) +        : error(std::string("unknown option ").append(name)),  +          m_option_name(name) +        {} + +        // gcc says that throw specification on dtor is loosened +        // without this line +        ~unknown_option() throw() {} +         +        const std::string& get_option_name() const throw(); +         +    private: +        std::string m_option_name; +    }; + +    /** Class thrown when there's ambiguity amoung several possible options. */ +    class BOOST_PROGRAM_OPTIONS_DECL ambiguous_option : public error { +    public: +        ambiguous_option(const std::string& name,  +                         const std::vector<std::string>& alternatives) +        : error(std::string("ambiguous option ").append(name)) +        , m_alternatives(alternatives) +        , m_option_name(name) +        {} + +        ~ambiguous_option() throw() {} +         +        const std::string& get_option_name() const throw(); +         +        const std::vector<std::string>& alternatives() const throw(); + +    private: +        // TODO: copy ctor might throw +        std::vector<std::string> m_alternatives; +        std::string m_option_name; +    }; + +    /** Class thrown when there are several option values, but +        user called a method which cannot return them all. */ +    class BOOST_PROGRAM_OPTIONS_DECL multiple_values : public error { +    public: +        multiple_values()  +         : error("multiple values") +         , m_option_name() {} +          +        ~multiple_values() throw() {} +         +        void set_option_name(const std::string& option); +         +        const std::string& get_option_name() const throw(); +         +    private: +        std::string m_option_name; // The name of the option which +                                   // caused the exception.         +    }; + +    /** Class thrown when there are several occurrences of an +        option, but user called a method which cannot return  +        them all. */ +    class BOOST_PROGRAM_OPTIONS_DECL multiple_occurrences : public error { +    public: +        multiple_occurrences()  +         : error("multiple occurrences") +         , m_option_name() {} +          +        ~multiple_occurrences() throw() {} +         +        void set_option_name(const std::string& option); +         +        const std::string& get_option_name() const throw(); + +    private:         +        std::string m_option_name; // The name of the option which +                                   // caused the exception. +    }; + +    /** Class thrown when value of option is incorrect. */ +    class BOOST_PROGRAM_OPTIONS_DECL validation_error : public error { +    public: +        enum kind_t { +            multiple_values_not_allowed = 30, +            at_least_one_value_required,  +            invalid_bool_value, +            invalid_option_value, +            invalid_option +        }; +         +        validation_error(kind_t kind,  +                         const std::string& option_value = "", +                         const std::string& option_name = ""); +                          +        ~validation_error() throw() {} + +        void set_option_name(const std::string& option); +         +        const std::string& get_option_name() const throw(); +         +        const char* what() const throw(); +         +    protected: +        /** Used to convert kind_t to a related error text */ +        static std::string error_message(kind_t kind); + +    private: +        kind_t m_kind; +        std::string m_option_name; // The name of the option which +                                   // caused the exception. +        std::string m_option_value; // Optional: value of the option m_options_name +        mutable std::string m_message; // For on-demand formatting in 'what' + +    }; + +    /** Class thrown if there is an invalid option value givenn */ +    class BOOST_PROGRAM_OPTIONS_DECL invalid_option_value  +        : public validation_error +    { +    public: +        invalid_option_value(const std::string& value); +#ifndef BOOST_NO_STD_WSTRING +        invalid_option_value(const std::wstring& value); +#endif +    }; + +    /** Class thrown when there are too many positional options.  +        This is a programming error. +    */ +    class BOOST_PROGRAM_OPTIONS_DECL too_many_positional_options_error : public error { +    public: +        too_many_positional_options_error()  +         : error("too many positional options")  +        {} +    }; + +    /** Class thrown when there are syntax errors in given command line */ +    class BOOST_PROGRAM_OPTIONS_DECL invalid_command_line_syntax : public invalid_syntax { +    public: +        invalid_command_line_syntax(const std::string& tokens, kind_t kind); +    }; + +    /** Class thrown when there are programming error related to style */ +    class BOOST_PROGRAM_OPTIONS_DECL invalid_command_line_style : public error { +    public: +        invalid_command_line_style(const std::string& msg) +        : error(msg) +        {} +    }; + +    /** Class thrown if config file can not be read */ +    class BOOST_PROGRAM_OPTIONS_DECL reading_file : public error { +    public: +        reading_file(const char* filename) +         : error(std::string("can not read file ").append(filename)) +        {} +    }; +     +     /** Class thrown when a required/mandatory option is missing */ +     class BOOST_PROGRAM_OPTIONS_DECL required_option : public error { +     public: +        required_option(const std::string& name) +        : error(std::string("missing required option ").append(name)) +        , m_option_name(name) +        {} +  +        ~required_option() throw() {} + +        const std::string& get_option_name() const throw(); +         +     private: +        std::string m_option_name; // The name of the option which +                                   // caused the exception. +     }; +}} + + +#endif diff --git a/3rdParty/Boost/src/boost/program_options/option.hpp b/3rdParty/Boost/src/boost/program_options/option.hpp new file mode 100644 index 0000000..557c692 --- /dev/null +++ b/3rdParty/Boost/src/boost/program_options/option.hpp @@ -0,0 +1,70 @@ +// Copyright Vladimir Prus 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) + +#ifndef BOOST_OPTION_HPP_VP_2004_02_25 +#define BOOST_OPTION_HPP_VP_2004_02_25 + +#include <boost/program_options/config.hpp> + +#include <string> +#include <vector> + +namespace boost { namespace program_options { + +    /** Option found in input source. +        Contains a key and a value. The key, in turn, can be a string (name of +        an option), or an integer (position in input source) -- in case no name +        is specified. The latter is only possible for command line. +        The template parameter specifies the type of char used for storing the +        option's value. +    */ +    template<class charT> +    class basic_option { +    public: +        basic_option()  +        : position_key(-1) +        , unregistered(false)  +        , case_insensitive(false) +        {} +        basic_option(const std::string& string_key,  +               const std::vector< std::string> &value) +        : string_key(string_key) +        , value(value) +        , unregistered(false) +        , case_insensitive(false) +        {} + +        /** String key of this option. Intentionally independent of the template +            parameter. */ +        std::string string_key; +        /** Position key of this option. All options without an explicit name are +            sequentially numbered starting from 0. If an option has explicit name, +            'position_key' is equal to -1. It is possible that both +            position_key and string_key is specified, in case name is implicitly +            added. +         */ +        int position_key; +        /** Option's value */ +        std::vector< std::basic_string<charT> > value; +        /** The original unchanged tokens this option was +            created from. */ +        std::vector< std::basic_string<charT> > original_tokens; +        /** True if option was not recognized. In that case, +            'string_key' and 'value' are results of purely +            syntactic parsing of source. The original tokens can be +            recovered from the "original_tokens" member. +        */ +        bool unregistered; +        /** True if string_key has to be handled +            case insensitive. +        */ +        bool case_insensitive; +    }; +    typedef basic_option<char> option; +    typedef basic_option<wchar_t> woption; + +}} + +#endif diff --git a/3rdParty/Boost/src/boost/program_options/options_description.hpp b/3rdParty/Boost/src/boost/program_options/options_description.hpp new file mode 100644 index 0000000..0486f02 --- /dev/null +++ b/3rdParty/Boost/src/boost/program_options/options_description.hpp @@ -0,0 +1,254 @@ +// Copyright Vladimir Prus 2002-2004. +// Copyright Bertolt Mildner 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) + + +#ifndef BOOST_OPTION_DESCRIPTION_VP_2003_05_19 +#define BOOST_OPTION_DESCRIPTION_VP_2003_05_19 + +#include <boost/program_options/config.hpp> +#include <boost/program_options/errors.hpp> +#include <boost/program_options/value_semantic.hpp> + +#include <boost/function.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/detail/workaround.hpp> +#include <boost/any.hpp> + +#include <string> +#include <vector> +#include <set> +#include <map> +#include <stdexcept> + +#include <iosfwd> + +/** Boost namespace */ +namespace boost {  +/** Namespace for the library. */ +namespace program_options { + +    /** Describes one possible command line/config file option. There are two +        kinds of properties of an option. First describe it syntactically and +        are used only to validate input. Second affect interpretation of the +        option, for example default value for it or function that should be +        called  when the value is finally known. Routines which perform parsing +        never use second kind of properties -- they are side effect free. +        @sa options_description +    */ +    class BOOST_PROGRAM_OPTIONS_DECL option_description { +    public: + +        option_description(); + +        /** Initializes the object with the passed data. + +            Note: it would be nice to make the second parameter auto_ptr, +            to explicitly pass ownership. Unfortunately, it's often needed to +            create objects of types derived from 'value_semantic': +               options_description d; +               d.add_options()("a", parameter<int>("n")->default_value(1)); +            Here, the static type returned by 'parameter' should be derived +            from value_semantic. + +            Alas, derived->base conversion for auto_ptr does not really work, +            see +            http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2000/n1232.pdf +            http://std.dkuug.dk/jtc1/sc22/wg21/docs/cwg_defects.html#84 + +            So, we have to use plain old pointers. Besides, users are not +            expected to use the constructor directly. + +             +            The 'name' parameter is interpreted by the following rules: +            - if there's no "," character in 'name', it specifies long name +            - otherwise, the part before "," specifies long name and the part +            after -- long name. +        */ +        option_description(const char* name, +                           const value_semantic* s); + +        /** Initializes the class with the passed data.  +         */ +        option_description(const char* name, +                           const value_semantic* s, +                           const char* description); + +        virtual ~option_description(); + +        enum match_result { no_match, full_match, approximate_match }; + +        /** Given 'option', specified in the input source, +            return 'true' is 'option' specifies *this. +        */ +        match_result match(const std::string& option, bool approx, +                           bool long_ignore_case, bool short_ignore_case) const; + +        /** Return the key that should identify the option, in +            particular in the variables_map class. +            The 'option' parameter is the option spelling from the +            input source. +            If option name contains '*', returns 'option'. +            If long name was specified, it's the long name, otherwise +            it's a short name with prepended '-'. +        */ +        const std::string& key(const std::string& option) const; + +        const std::string& long_name() const; + +        /// Explanation of this option +        const std::string& description() const; + +        /// Semantic of option's value +        shared_ptr<const value_semantic> semantic() const; +         +        /// Returns the option name, formatted suitably for usage message.  +        std::string format_name() const; + +        /** Return the parameter name and properties, formatted suitably for +            usage message. */ +        std::string format_parameter() const; + +    private: +     +        option_description& set_name(const char* name); + +        std::string m_short_name, m_long_name, m_description; +        // shared_ptr is needed to simplify memory management in +        // copy ctor and destructor. +        shared_ptr<const value_semantic> m_value_semantic; +    }; + +    class options_description; + +    /** Class which provides convenient creation syntax to option_description.  +     */         +    class BOOST_PROGRAM_OPTIONS_DECL options_description_easy_init { +    public: +        options_description_easy_init(options_description* owner); + +        options_description_easy_init& +        operator()(const char* name, +                   const char* description); + +        options_description_easy_init& +        operator()(const char* name, +                   const value_semantic* s); +         +        options_description_easy_init& +        operator()(const char* name, +                   const value_semantic* s, +                   const char* description); +        +    private: +        options_description* owner; +    }; + + +    /** A set of option descriptions. This provides convenient interface for +        adding new option (the add_options) method, and facilities to search +        for options by name. +         +        See @ref a_adding_options "here" for option adding interface discussion. +        @sa option_description +    */ +    class BOOST_PROGRAM_OPTIONS_DECL options_description { +    public: +        static const unsigned m_default_line_length; +         +        /** Creates the instance. */ +        options_description(unsigned line_length = m_default_line_length, +                            unsigned min_description_length = m_default_line_length / 2); +        /** Creates the instance. The 'caption' parameter gives the name of +            this 'options_description' instance. Primarily useful for output. +            The 'description_length' specifies the number of columns that +            should be reserved for the description text; if the option text +            encroaches into this, then the description will start on the next +            line. +        */ +        options_description(const std::string& caption, +                            unsigned line_length = m_default_line_length, +                            unsigned min_description_length = m_default_line_length / 2); +        /** Adds new variable description. Throws duplicate_variable_error if +            either short or long name matches that of already present one.  +        */ +        void add(shared_ptr<option_description> desc); +        /** Adds a group of option description. This has the same +            effect as adding all option_descriptions in 'desc'  +            individually, except that output operator will show +            a separate group. +            Returns *this. +        */ +        options_description& add(const options_description& desc); + +    public: +        /** Returns an object of implementation-defined type suitable for adding +            options to options_description. The returned object will +            have overloaded operator() with parameter type matching  +            'option_description' constructors. Calling the operator will create +            new option_description instance and add it. +        */ +        options_description_easy_init add_options(); + +        const option_description& find(const std::string& name,  +                                       bool approx,  +                                       bool long_ignore_case = false, +                                       bool short_ignore_case = false) const; + +        const option_description* find_nothrow(const std::string& name,  +                                               bool approx, +                                               bool long_ignore_case = false, +                                               bool short_ignore_case = false) const; + + +        const std::vector< shared_ptr<option_description> >& options() const; + +        /** Produces a human readable output of 'desc', listing options, +            their descriptions and allowed parameters. Other options_description +            instances previously passed to add will be output separately. */ +        friend BOOST_PROGRAM_OPTIONS_DECL std::ostream& operator<<(std::ostream& os,  +                                             const options_description& desc); + +        /** Output 'desc' to the specified stream, calling 'f' to output each +            option_description element. */ +        void print(std::ostream& os) const; + +    private: +        typedef std::map<std::string, int>::const_iterator name2index_iterator; +        typedef std::pair<name2index_iterator, name2index_iterator>  +            approximation_range; + +        //approximation_range find_approximation(const std::string& prefix) const; + +        std::string m_caption; +        const unsigned m_line_length; +        const unsigned m_min_description_length; +         +        // Data organization is chosen because: +        // - there could be two names for one option +        // - option_add_proxy needs to know the last added option +        std::vector< shared_ptr<option_description> > m_options; + +        // Whether the option comes from one of declared groups. +#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(313)) +        // vector<bool> is buggy there, see +        // http://support.microsoft.com/default.aspx?scid=kb;en-us;837698 +        std::vector<char> belong_to_group; +#else +        std::vector<bool> belong_to_group; +#endif + +        std::vector< shared_ptr<options_description> > groups; + +    }; + +    /** Class thrown when duplicate option description is found. */ +    class BOOST_PROGRAM_OPTIONS_DECL duplicate_option_error : public error { +    public: +        duplicate_option_error(const std::string& what) : error(what) {} +    }; +}} + +#endif diff --git a/3rdParty/Boost/src/boost/program_options/parsers.hpp b/3rdParty/Boost/src/boost/program_options/parsers.hpp new file mode 100644 index 0000000..e2a4467 --- /dev/null +++ b/3rdParty/Boost/src/boost/program_options/parsers.hpp @@ -0,0 +1,262 @@ +// 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) + + +#ifndef BOOST_PARSERS_VP_2003_05_19 +#define BOOST_PARSERS_VP_2003_05_19 + +#include <boost/program_options/config.hpp> +#include <boost/program_options/option.hpp> +#include <boost/program_options/detail/cmdline.hpp> + +#include <boost/function/function1.hpp> + +#include <iosfwd> +#include <vector> +#include <utility> + +namespace boost { namespace program_options { + +    class options_description; +    class positional_options_description; + + +    /** Results of parsing an input source.  +        The primary use of this class is passing information from parsers  +        component to value storage component. This class does not makes +        much sense itself.         +    */ +    template<class charT> +    class basic_parsed_options { +    public: +        explicit basic_parsed_options(const options_description* description)  +        : description(description) {} +        /** Options found in the source. */ +        std::vector< basic_option<charT> > options; +        /** Options description that was used for parsing.  +            Parsers should return pointer to the instance of  +            option_description passed to them, and issues of lifetime are +            up to the caller. Can be NULL. +         */ +        const options_description* description; +    }; + +    /** Specialization of basic_parsed_options which: +        - provides convenient conversion from basic_parsed_options<char> +        - stores the passed char-based options for later use. +    */ +    template<> +    class BOOST_PROGRAM_OPTIONS_DECL basic_parsed_options<wchar_t> { +    public: +        /** Constructs wrapped options from options in UTF8 encoding. */ +        explicit basic_parsed_options(const basic_parsed_options<char>& po); + +        std::vector< basic_option<wchar_t> > options; +        const options_description* description; + +        /** Stores UTF8 encoded options that were passed to constructor, +            to avoid reverse conversion in some cases. */ +        basic_parsed_options<char> utf8_encoded_options;         +    }; + +    typedef basic_parsed_options<char> parsed_options; +    typedef basic_parsed_options<wchar_t> wparsed_options; + +    /** Augments basic_parsed_options<wchar_t> with conversion from +        'parsed_options' */ + + +    typedef function1<std::pair<std::string, std::string>, const std::string&> ext_parser; + +    /** Command line parser. + +        The class allows one to specify all the information needed for parsing +        and to parse the command line. It is primarily needed to +        emulate named function parameters -- a regular function with 5 +        parameters will be hard to use and creating overloads with a smaller +        nuber of parameters will be confusing. + +        For the most common case, the function parse_command_line is a better  +        alternative.         + +        There are two typedefs -- command_line_parser and wcommand_line_parser, +        for charT == char and charT == wchar_t cases. +    */ +    template<class charT> +    class basic_command_line_parser : private detail::cmdline { +    public: +        /** Creates a command line parser for the specified arguments +            list. The 'args' parameter should not include program name. +        */ +        basic_command_line_parser(const std::vector< +                                  std::basic_string<charT> >& args); +        /** Creates a command line parser for the specified arguments +            list. The parameters should be the same as passed to 'main'. +        */ +        basic_command_line_parser(int argc, charT* argv[]); + +        /** Sets options descriptions to use. */ +        basic_command_line_parser& options(const options_description& desc); +        /** Sets positional options description to use. */ +        basic_command_line_parser& positional( +            const positional_options_description& desc); + +        /** Sets the command line style. */ +        basic_command_line_parser& style(int); +        /** Sets the extra parsers. */ +        basic_command_line_parser& extra_parser(ext_parser); + +        /** Parses the options and returns the result of parsing. +            Throws on error. +        */ +        basic_parsed_options<charT> run(); + +        /** Specifies that unregistered options are allowed and should +            be passed though. For each command like token that looks +            like an option but does not contain a recognized name, an +            instance of basic_option<charT> will be added to result, +            with 'unrecognized' field set to 'true'. It's possible to +            collect all unrecognized options with the 'collect_unrecognized' +            funciton.  +        */ +        basic_command_line_parser& allow_unregistered(); +         +        using detail::cmdline::style_parser; + +        basic_command_line_parser& extra_style_parser(style_parser s); + +    private: +        const options_description* m_desc; +    }; + +    typedef basic_command_line_parser<char> command_line_parser; +    typedef basic_command_line_parser<wchar_t> wcommand_line_parser; + +    /** Creates instance of 'command_line_parser', passes parameters to it, +        and returns the result of calling the 'run' method.         +     */ +    template<class charT> +    basic_parsed_options<charT> +    parse_command_line(int argc, charT* argv[], +                       const options_description&, +                       int style = 0, +                       function1<std::pair<std::string, std::string>,  +                                 const std::string&> ext +                       = ext_parser()); + +    /** Parse a config file.  +     +        Read from given stream. +    */ +    template<class charT> +#if ! BOOST_WORKAROUND(__ICL, BOOST_TESTED_AT(700)) +    BOOST_PROGRAM_OPTIONS_DECL +#endif +    basic_parsed_options<charT> +    parse_config_file(std::basic_istream<charT>&, const options_description&, +                      bool allow_unregistered = false); + +    /** Parse a config file.  +     +        Read from file with the given name. The character type is +        passed to the file stream.  +    */ +    template<class charT> +#if ! BOOST_WORKAROUND(__ICL, BOOST_TESTED_AT(700)) +    BOOST_PROGRAM_OPTIONS_DECL +#endif +    basic_parsed_options<charT> +    parse_config_file(const char* filename, const options_description&, +                      bool allow_unregistered = false); + +    /** Controls if the 'collect_unregistered' function should +        include positional options, or not. */ +    enum collect_unrecognized_mode  +    { include_positional, exclude_positional }; + +    /** Collects the original tokens for all named options with +        'unregistered' flag set. If 'mode' is 'include_positional' +        also collects all positional options. +        Returns the vector of origianl tokens for all collected +        options. +    */ +    template<class charT> +    std::vector< std::basic_string<charT> >  +    collect_unrecognized(const std::vector< basic_option<charT> >& options, +                         enum collect_unrecognized_mode mode); + +    /** Parse environment.  + +        For each environment variable, the 'name_mapper' function is called to +        obtain the option name. If it returns empty string, the variable is  +        ignored.  + +        This is done since naming of environment variables is typically  +        different from the naming of command line options.         +    */ +    BOOST_PROGRAM_OPTIONS_DECL parsed_options +    parse_environment(const options_description&,  +                      const function1<std::string, std::string>& name_mapper); + +    /** Parse environment. + +        Takes all environment variables which start with 'prefix'. The option +        name is obtained from variable name by removing the prefix and  +        converting the remaining string into lower case. +    */ +    BOOST_PROGRAM_OPTIONS_DECL parsed_options +    parse_environment(const options_description&, const std::string& prefix); + +    /** @overload +        This function exists to resolve ambiguity between the two above  +        functions when second argument is of 'char*' type. There's implicit +        conversion to both function1 and string. +    */ +    BOOST_PROGRAM_OPTIONS_DECL parsed_options +    parse_environment(const options_description&, const char* prefix); + +    /** Splits a given string to a collection of single strings which +        can be passed to command_line_parser. The second parameter is +        used to specify a collection of possible seperator chars used +        for splitting. The seperator is defaulted to space " ". +        Splitting is done in a unix style way, with respect to quotes '"' +        and escape characters '\' +    */ +    BOOST_PROGRAM_OPTIONS_DECL std::vector<std::string> +    split_unix(const std::string& cmdline, const std::string& seperator = " \t",  +         const std::string& quote = "'\"", const std::string& escape = "\\"); +          +#ifndef BOOST_NO_STD_WSTRING +    /** @overload */ +    BOOST_PROGRAM_OPTIONS_DECL std::vector<std::wstring> +    split_unix(const std::wstring& cmdline, const std::wstring& seperator = L" \t",  +         const std::wstring& quote = L"'\"", const std::wstring& escape = L"\\"); +#endif + +    #ifdef _WIN32 +    /** Parses the char* string which is passed to WinMain function on +        windows. This function is provided for convenience, and because it's +        not clear how to portably access split command line string from +        runtime library and if it always exists. +        This function is available only on Windows. +    */ +    BOOST_PROGRAM_OPTIONS_DECL std::vector<std::string> +    split_winmain(const std::string& cmdline); + +#ifndef BOOST_NO_STD_WSTRING +    /** @overload */ +    BOOST_PROGRAM_OPTIONS_DECL std::vector<std::wstring> +    split_winmain(const std::wstring& cmdline); +    #endif +#endif +     + +}} + +#undef DECL + +#include "boost/program_options/detail/parsers.hpp" + +#endif diff --git a/3rdParty/Boost/src/boost/program_options/positional_options.hpp b/3rdParty/Boost/src/boost/program_options/positional_options.hpp new file mode 100644 index 0000000..01406e0 --- /dev/null +++ b/3rdParty/Boost/src/boost/program_options/positional_options.hpp @@ -0,0 +1,65 @@ +// Copyright Vladimir Prus 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) + +#ifndef BOOST_PROGRAM_OPTIONS_POSITIONAL_OPTIONS_VP_2004_03_02 +#define BOOST_PROGRAM_OPTIONS_POSITIONAL_OPTIONS_VP_2004_03_02 + +#include <boost/program_options/config.hpp> + +#include <vector> +#include <string> + +namespace boost { namespace program_options { + +    /** Describes positional options.  + +        The class allows to guess option names for positional options, which +        are specified on the command line and are identified by the position. +        The class uses the information provided by the user to associate a name +        with every positional option, or tell that no name is known.  + +        The primary assumption is that only the relative order of the +        positional options themselves matters, and that any interleaving +        ordinary options don't affect interpretation of positional options. +         +        The user initializes the class by specifying that first N positional  +        options should be given the name X1, following M options should be given  +        the name X2 and so on.  +    */ +    class BOOST_PROGRAM_OPTIONS_DECL positional_options_description { +    public: +        positional_options_description(); + +        /** Species that up to 'max_count' next positional options +            should be given the 'name'. The value of '-1' means 'unlimited'.  +            No calls to 'add' can be made after call with 'max_value' equal to  +            '-1'.             +        */ +        positional_options_description& +        add(const char* name, int max_count); + +        /** Returns the maximum number of positional options that can +            be present. Can return (numeric_limits<unsigned>::max)() to +            indicate unlimited number. */ +        unsigned max_total_count() const; + +        /** Returns the name that should be associated with positional +            options at 'position'.  +            Precondition: position < max_total_count() +        */ +        const std::string& name_for_position(unsigned position) const; + +    private: +        // List of names corresponding to the positions. If the number of +        // positions is unlimited, then the last name is stored in +        // m_trailing; +        std::vector<std::string> m_names; +        std::string m_trailing; +    }; + +}} + +#endif + diff --git a/3rdParty/Boost/src/boost/program_options/value_semantic.hpp b/3rdParty/Boost/src/boost/program_options/value_semantic.hpp new file mode 100644 index 0000000..033009e --- /dev/null +++ b/3rdParty/Boost/src/boost/program_options/value_semantic.hpp @@ -0,0 +1,405 @@ +// Copyright Vladimir Prus 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) + +#ifndef BOOST_VALUE_SEMANTIC_HPP_VP_2004_02_24 +#define BOOST_VALUE_SEMANTIC_HPP_VP_2004_02_24 + +#include <boost/program_options/config.hpp> +#include <boost/program_options/errors.hpp> + +#include <boost/any.hpp> +#include <boost/function/function1.hpp> +#include <boost/lexical_cast.hpp> + + +#include <string> +#include <vector> +#include <typeinfo> + +namespace boost { namespace program_options { + +    /** Class which specifies how the option's value is to be parsed +        and converted into C++ types. +    */ +    class BOOST_PROGRAM_OPTIONS_DECL value_semantic { +    public: +        /** Returns the name of the option. The name is only meaningful +            for automatic help message. +         */ +        virtual std::string name() const = 0; + +        /** The minimum number of tokens for this option that +            should be present on the command line. */ +        virtual unsigned min_tokens() const = 0; + +        /** The maximum number of tokens for this option that +            should be present on the command line. */ +        virtual unsigned max_tokens() const = 0; + +        /** Returns true if values from different sources should be composed. +            Otherwise, value from the first source is used and values from +            other sources are discarded. +        */ +        virtual bool is_composing() const = 0; + +        /** Returns true if value must be given. Non-optional value + +        */ +        virtual bool is_required() const = 0; +         +        /** Parses a group of tokens that specify a value of option. +            Stores the result in 'value_store', using whatever representation +            is desired. May be be called several times if value of the same +            option is specified more than once. +        */ +        virtual void parse(boost::any& value_store,  +                           const std::vector<std::string>& new_tokens, +                           bool utf8) const  +            = 0; + +        /** Called to assign default value to 'value_store'. Returns +            true if default value is assigned, and false if no default +            value exists. */ +        virtual bool apply_default(boost::any& value_store) const = 0; +                                    +        /** Called when final value of an option is determined.  +        */ +        virtual void notify(const boost::any& value_store) const = 0; +         +        virtual ~value_semantic() {} +    }; + +    /** Helper class which perform necessary character conversions in the  +        'parse' method and forwards the data further. +    */ +    template<class charT> +    class value_semantic_codecvt_helper { +        // Nothing here. Specializations to follow. +    }; + +    /** Helper conversion class for values that accept ascii +        strings as input. +        Overrides the 'parse' method and defines new 'xparse' +        method taking std::string. Depending on whether input +        to parse is ascii or UTF8, will pass it to xparse unmodified, +        or with UTF8->ascii conversion. +    */ +    template<> +    class BOOST_PROGRAM_OPTIONS_DECL  +    value_semantic_codecvt_helper<char> : public value_semantic { +    private: // base overrides +        void parse(boost::any& value_store,  +                   const std::vector<std::string>& new_tokens, +                   bool utf8) const; +    protected: // interface for derived classes. +        virtual void xparse(boost::any& value_store,  +                            const std::vector<std::string>& new_tokens)  +            const = 0; +    }; + +    /** Helper conversion class for values that accept ascii +        strings as input. +        Overrides the 'parse' method and defines new 'xparse' +        method taking std::wstring. Depending on whether input +        to parse is ascii or UTF8, will recode input to Unicode, or +        pass it unmodified. +    */ +    template<> +    class BOOST_PROGRAM_OPTIONS_DECL +    value_semantic_codecvt_helper<wchar_t> : public value_semantic { +    private: // base overrides +        void parse(boost::any& value_store,  +                   const std::vector<std::string>& new_tokens, +                   bool utf8) const; +    protected: // interface for derived classes. +#if !defined(BOOST_NO_STD_WSTRING) +        virtual void xparse(boost::any& value_store,  +                            const std::vector<std::wstring>& new_tokens)  +            const = 0; +#endif +    }; + +    /** Class which specifies a simple handling of a value: the value will +        have string type and only one token is allowed. */     +    class BOOST_PROGRAM_OPTIONS_DECL  +    untyped_value : public value_semantic_codecvt_helper<char>  { +    public: +        untyped_value(bool zero_tokens = false) +        : m_zero_tokens(zero_tokens) +        {} + +        std::string name() const; + +        unsigned min_tokens() const; +        unsigned max_tokens() const; + +        bool is_composing() const { return false; } + +        bool is_required() const { return false; } +         +        /** If 'value_store' is already initialized, or new_tokens +            has more than one elements, throws. Otherwise, assigns +            the first string from 'new_tokens' to 'value_store', without +            any modifications. +         */ +        void xparse(boost::any& value_store, +                    const std::vector<std::string>& new_tokens) const; + +        /** Does nothing. */ +        bool apply_default(boost::any&) const { return false; } + +        /** Does nothing. */ +        void notify(const boost::any&) const {}         +    private: +        bool m_zero_tokens; +    }; + +    /** Base class for all option that have a fixed type, and are +        willing to announce this type to the outside world. +        Any 'value_semantics' for which you want to find out the +        type can be dynamic_cast-ed to typed_value_base. If conversion +        succeeds, the 'type' method can be called. +    */ +    class typed_value_base  +    { +    public: +        // Returns the type of the value described by this +        // object. +        virtual const std::type_info& value_type() const = 0; +        // Not really needed, since deletion from this +        // class is silly, but just in case. +        virtual ~typed_value_base() {} +    }; + + +    /** Class which handles value of a specific type. */ +    template<class T, class charT = char> +    class typed_value : public value_semantic_codecvt_helper<charT>, +                        public typed_value_base +    { +    public: +        /** Ctor. The 'store_to' parameter tells where to store +            the value when it's known. The parameter can be NULL. */ +        typed_value(T* store_to)  +        : m_store_to(store_to), m_composing(false), +          m_multitoken(false), m_zero_tokens(false), +          m_required(false) +        {}  + +        /** Specifies default value, which will be used +            if none is explicitly specified. The type 'T' should +            provide operator<< for ostream. +        */ +        typed_value* default_value(const T& v) +        { +            m_default_value = boost::any(v); +            m_default_value_as_text = boost::lexical_cast<std::string>(v); +            return this; +        } + +        /** Specifies default value, which will be used +            if none is explicitly specified. Unlike the above overload, +            the type 'T' need not provide operator<< for ostream, +            but textual representation of default value must be provided +            by the user. +        */ +        typed_value* default_value(const T& v, const std::string& textual) +        { +            m_default_value = boost::any(v); +            m_default_value_as_text = textual; +            return this; +        } + +        /** Specifies an implicit value, which will be used +            if the option is given, but without an adjacent value. +            Using this implies that an explicit value is optional, but if +            given, must be strictly adjacent to the option, i.e.: '-ovalue' +            or '--option=value'.  Giving '-o' or '--option' will cause the +            implicit value to be applied. +        */ +        typed_value* implicit_value(const T &v) +        { +            m_implicit_value = boost::any(v); +            m_implicit_value_as_text = +                boost::lexical_cast<std::string>(v); +            return this; +        } + +        /** Specifies an implicit value, which will be used +            if the option is given, but without an adjacent value. +            Using this implies that an explicit value is optional, but if +            given, must be strictly adjacent to the option, i.e.: '-ovalue' +            or '--option=value'.  Giving '-o' or '--option' will cause the +            implicit value to be applied. +            Unlike the above overload, the type 'T' need not provide +            operator<< for ostream, but textual representation of default +            value must be provided by the user. +        */ +        typed_value* implicit_value(const T &v, const std::string& textual) +        { +            m_implicit_value = boost::any(v); +            m_implicit_value_as_text = textual; +            return this; +        } + +        /** Specifies a function to be called when the final value +            is determined. */ +        typed_value* notifier(function1<void, const T&> f) +        { +            m_notifier = f; +            return this; +        } + +        /** Specifies that the value is composing. See the 'is_composing'  +            method for explanation.  +        */ +        typed_value* composing() +        { +            m_composing = true; +            return this; +        } + +        /** Specifies that the value can span multiple tokens. */ +        typed_value* multitoken() +        { +            m_multitoken = true; +            return this; +        } + +        typed_value* zero_tokens()  +        { +            m_zero_tokens = true; +            return this; +        } +             +        /** Specifies that the value must occur. */ +        typed_value* required() +        { +            m_required = true; +            return this; +        } + +    public: // value semantic overrides + +        std::string name() const; + +        bool is_composing() const { return m_composing; } + +        unsigned min_tokens() const +        { +            if (m_zero_tokens || !m_implicit_value.empty()) { +                return 0; +            } else { +                return 1; +            } +        } + +        unsigned max_tokens() const { +            if (m_multitoken) { +                return 32000; +            } else if (m_zero_tokens) { +                return 0; +            } else { +                return 1; +            } +        } + +        bool is_required() const { return m_required; } + +        /** Creates an instance of the 'validator' class and calls +            its operator() to perform the actual conversion. */ +        void xparse(boost::any& value_store,  +                    const std::vector< std::basic_string<charT> >& new_tokens)  +            const; + +        /** If default value was specified via previous call to  +            'default_value', stores that value into 'value_store'. +            Returns true if default value was stored. +        */ +        virtual bool apply_default(boost::any& value_store) const +        { +            if (m_default_value.empty()) { +                return false; +            } else { +                value_store = m_default_value; +                return true; +            } +        } + +        /** If an address of variable to store value was specified +            when creating *this, stores the value there. Otherwise, +            does nothing. */ +        void notify(const boost::any& value_store) const; + +    public: // typed_value_base overrides +         +        const std::type_info& value_type() const +        { +            return typeid(T); +        } +         + +    private: +        T* m_store_to; +         +        // Default value is stored as boost::any and not +        // as boost::optional to avoid unnecessary instantiations. +        boost::any m_default_value; +        std::string m_default_value_as_text; +        boost::any m_implicit_value; +        std::string m_implicit_value_as_text; +        bool m_composing, m_implicit, m_multitoken, m_zero_tokens, m_required; +        boost::function1<void, const T&> m_notifier; +    }; + + +    /** Creates a typed_value<T> instance. This function is the primary +        method to create value_semantic instance for a specific type, which +        can later be passed to 'option_description' constructor. +        The second overload is used when it's additionally desired to store the  +        value of option into program variable. +    */ +    template<class T> +    typed_value<T>* +    value(); + +    /** @overload  +    */ +    template<class T> +    typed_value<T>* +    value(T* v); + +    /** Creates a typed_value<T> instance. This function is the primary +        method to create value_semantic instance for a specific type, which +        can later be passed to 'option_description' constructor. +    */ +    template<class T> +    typed_value<T, wchar_t>* +    wvalue(); + +    /** @overload    +    */ +    template<class T> +    typed_value<T, wchar_t>* +    wvalue(T* v); + +    /** Works the same way as the 'value<bool>' function, but the created +        value_semantic won't accept any explicit value. So, if the option  +        is present on the command line, the value will be 'true'. +    */ +    BOOST_PROGRAM_OPTIONS_DECL typed_value<bool>* +    bool_switch(); + +    /** @overload +    */ +    BOOST_PROGRAM_OPTIONS_DECL typed_value<bool>*     +    bool_switch(bool* v); + +}} + +#include "boost/program_options/detail/value_semantic.hpp" + +#endif + diff --git a/3rdParty/Boost/src/boost/program_options/variables_map.hpp b/3rdParty/Boost/src/boost/program_options/variables_map.hpp new file mode 100644 index 0000000..02c4af2 --- /dev/null +++ b/3rdParty/Boost/src/boost/program_options/variables_map.hpp @@ -0,0 +1,206 @@ +// 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) + + +#ifndef BOOST_VARIABLES_MAP_VP_2003_05_19 +#define BOOST_VARIABLES_MAP_VP_2003_05_19 + +#include <boost/program_options/config.hpp> + +#include <boost/any.hpp> +#include <boost/shared_ptr.hpp> + +#include <string> +#include <map> +#include <set> + +namespace boost { namespace program_options { + +    template<class charT> +    class basic_parsed_options; + +    class value_semantic; +    class variables_map; + +    // forward declaration + +    /** Stores in 'm' all options that are defined in 'options'.  +        If 'm' already has a non-defaulted value of an option, that value +        is not changed, even if 'options' specify some value.         +    */ +    BOOST_PROGRAM_OPTIONS_DECL  +    void store(const basic_parsed_options<char>& options, variables_map& m, +                    bool utf8 = false); + +    /** Stores in 'm' all options that are defined in 'options'.  +        If 'm' already has a non-defaulted value of an option, that value +        is not changed, even if 'options' specify some value.         +        This is wide character variant. +    */ +    BOOST_PROGRAM_OPTIONS_DECL  +    void store(const basic_parsed_options<wchar_t>& options,  +                    variables_map& m); + + +    /** Runs all 'notify' function for options in 'm'. */ +    BOOST_PROGRAM_OPTIONS_DECL void notify(variables_map& m); + +    /** Class holding value of option. Contains details about how the  +        value is set and allows to conveniently obtain the value. +    */ +    class BOOST_PROGRAM_OPTIONS_DECL variable_value { +    public: +        variable_value() : m_defaulted(false) {} +        variable_value(const boost::any& v, bool defaulted)  +        : v(v), m_defaulted(defaulted)  +        {} + +        /** If stored value if of type T, returns that value. Otherwise, +            throws boost::bad_any_cast exception. */ +       template<class T> +       const T& as() const { +           return boost::any_cast<const T&>(v); +       } +       /** @overload */ +       template<class T> +       T& as() { +           return boost::any_cast<T&>(v); +       } + +        /// Returns true if no value is stored. +        bool empty() const; +        /** Returns true if the value was not explicitly +            given, but has default value. */ +        bool defaulted() const; +        /** Returns the contained value. */ +        const boost::any& value() const; + +        /** Returns the contained value. */ +        boost::any& value(); +    private: +        boost::any v; +        bool m_defaulted; +        // Internal reference to value semantic. We need to run +        // notifications when *final* values of options are known, and +        // they are known only after all sources are stored. By that +        // time options_description for the first source might not +        // be easily accessible, so we need to store semantic here. +        shared_ptr<const value_semantic> m_value_semantic; + +        friend BOOST_PROGRAM_OPTIONS_DECL +        void store(const basic_parsed_options<char>& options,  +              variables_map& m, bool); + +        friend BOOST_PROGRAM_OPTIONS_DECL class variables_map; +    }; + +    /** Implements string->string mapping with convenient value casting +        facilities. */ +    class BOOST_PROGRAM_OPTIONS_DECL abstract_variables_map { +    public: +        abstract_variables_map(); +        abstract_variables_map(const abstract_variables_map* next); + +        virtual ~abstract_variables_map() {} + +        /** Obtains the value of variable 'name', from *this and +            possibly from the chain of variable maps. + +            - if there's no value in *this. +                - if there's next variable map, returns value from it +                - otherwise, returns empty value + +            - if there's defaulted value +                - if there's next varaible map, which has a non-defauled +                  value, return that +                - otherwise, return value from *this + +            - if there's a non-defauled value, returns it. +        */ +        const variable_value& operator[](const std::string& name) const; + +        /** Sets next variable map, which will be used to find +           variables not found in *this. */ +        void next(abstract_variables_map* next); + +    private: +        /** Returns value of variable 'name' stored in *this, or +            empty value otherwise. */ +        virtual const variable_value& get(const std::string& name) const = 0; + +        const abstract_variables_map* m_next; +    }; + +    /** Concrete variables map which store variables in real map.  +         +        This class is derived from std::map<std::string, variable_value>, +        so you can use all map operators to examine its content. +    */ +    class BOOST_PROGRAM_OPTIONS_DECL variables_map : public abstract_variables_map, +                               public std::map<std::string, variable_value> +    { +    public: +        variables_map(); +        variables_map(const abstract_variables_map* next); + +        // Resolve conflict between inherited operators. +        const variable_value& operator[](const std::string& name) const +        { return abstract_variables_map::operator[](name); } +         +        void notify(); + +    private: +        /** Implementation of abstract_variables_map::get +            which does 'find' in *this. */ +        const variable_value& get(const std::string& name) const; + +        /** Names of option with 'final' values -- which should not +            be changed by subsequence assignments. */ +        std::set<std::string> m_final; + +        friend BOOST_PROGRAM_OPTIONS_DECL +        void store(const basic_parsed_options<char>& options,  +                          variables_map& xm, +                          bool utf8); +         +        /** Names of required options, filled by parser which has +            access to options_description. */ +        std::set<std::string> m_required; +    }; + + +    /* +     * Templates/inlines +     */ + +    inline bool +    variable_value::empty() const +    { +        return v.empty(); +    } + +    inline bool +    variable_value::defaulted() const +    { +        return m_defaulted; +    } + +    inline +    const boost::any& +    variable_value::value() const +    { +        return v; +    } + +    inline +    boost::any& +    variable_value::value() +    { +        return v; +    } + +}} + +#endif diff --git a/3rdParty/Boost/src/boost/program_options/version.hpp b/3rdParty/Boost/src/boost/program_options/version.hpp new file mode 100644 index 0000000..7480943 --- /dev/null +++ b/3rdParty/Boost/src/boost/program_options/version.hpp @@ -0,0 +1,19 @@ +// Copyright Vladimir Prus 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) + +#ifndef BOOST_PROGRAM_OPTIONS_VERSION_HPP_VP_2004_04_05 +#define BOOST_PROGRAM_OPTIONS_VERSION_HPP_VP_2004_04_05 + +/** The version of the source interface. +    The value will be incremented whenever a change is made which might +    cause compilation errors for existing code. +*/ +#ifdef BOOST_PROGRAM_OPTIONS_VERSION +#error BOOST_PROGRAM_OPTIONS_VERSION already defined +#endif +#define BOOST_PROGRAM_OPTIONS_VERSION 2 + + +#endif diff --git a/3rdParty/Boost/src/libs/program_options/src/cmdline.cpp b/3rdParty/Boost/src/libs/program_options/src/cmdline.cpp new file mode 100644 index 0000000..be31385 --- /dev/null +++ b/3rdParty/Boost/src/libs/program_options/src/cmdline.cpp @@ -0,0 +1,656 @@ +// 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) + +#define BOOST_PROGRAM_OPTIONS_SOURCE +#include <boost/program_options/config.hpp> + +#include <boost/config.hpp> + +#include <boost/program_options/detail/cmdline.hpp> +#include <boost/program_options/errors.hpp> +#include <boost/program_options/value_semantic.hpp> +#include <boost/program_options/options_description.hpp> +#include <boost/program_options/positional_options.hpp> +#include <boost/throw_exception.hpp> + +#include <boost/bind.hpp> + +#include <string> +#include <utility> +#include <vector> +#include <cassert> +#include <cstring> +#include <cctype> +#include <climits> + +#include <cstdio> + +#include <iostream> + +namespace boost { namespace program_options { + +    using namespace std; +    using namespace boost::program_options::command_line_style; +     +    invalid_syntax:: +    invalid_syntax(const string& tokens, kind_t kind) +     : error(error_message(kind).append(" in '").append(tokens).append("'")) +     , m_tokens(tokens) +     , m_kind(kind)                        +    {} +     +    string  +    invalid_syntax::error_message(kind_t kind) +    { +        // Initially, store the message in 'const char*' variable, +        // to avoid conversion to string in all cases. +        const char* msg; +        switch(kind) +        { +        case long_not_allowed: +            msg = "long options are not allowed"; +            break; +        case long_adjacent_not_allowed: +            msg = "parameters adjacent to long options not allowed"; +            break; +        case short_adjacent_not_allowed: +            msg = "parameters adjust to short options are not allowed"; +            break; +        case empty_adjacent_parameter: +            msg = "adjacent parameter is empty"; +            break; +        case missing_parameter: +            msg = "required parameter is missing"; +            break; +        case extra_parameter: +            msg = "extra parameter"; +            break; +        case unrecognized_line: +            msg = "unrecognized line"; +            break; +        default: +            msg = "unknown error"; +        } +        return msg; +    } + +    invalid_syntax::kind_t  +    invalid_syntax::kind() const +    { +        return m_kind; +    } +     +    const string&  +    invalid_syntax::tokens() const +    { +        return m_tokens; +    } + +    invalid_command_line_syntax:: +    invalid_command_line_syntax(const string& tokens, kind_t kind) +    : invalid_syntax(tokens, kind) +    {} + +}} + + +namespace boost { namespace program_options { namespace detail { + +    // vc6 needs this, but borland chokes when this is added. +#if BOOST_WORKAROUND(_MSC_VER, < 1300) +    using namespace std; +    using namespace program_options; +#endif + + +    cmdline::cmdline(const vector<string>& args) +    { +        init(args); +    } + +    cmdline::cmdline(int argc, const char*const * argv) +    { +#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) +        vector<string> args; +        copy(argv+1, argv+argc+!argc, inserter(args, args.end())); +        init(args); +#else +        init(vector<string>(argv+1, argv+argc+!argc)); +#endif +    } + +    void +    cmdline::init(const vector<string>& args) +    { +        this->args = args;         +        m_style = command_line_style::default_style; +        m_desc = 0; +        m_positional = 0; +        m_allow_unregistered = false; +    } + +    void  +    cmdline::style(int style) +    { +        if (style == 0)  +            style = default_style;         + +        check_style(style); +        this->m_style = style_t(style); +    } +     +    void  +    cmdline::allow_unregistered() +    { +        this->m_allow_unregistered = true; +    } + +    void  +    cmdline::check_style(int style) const +    { +        bool allow_some_long =  +            (style & allow_long) || (style & allow_long_disguise); + +        const char* error = 0; +        if (allow_some_long &&  +            !(style & long_allow_adjacent) && !(style & long_allow_next)) +            error = "style disallows parameters for long options"; + +        if (!error && (style & allow_short) && +            !(style & short_allow_adjacent) && !(style & short_allow_next)) +            error = "style disallows parameters for short options"; + +        if (!error && (style & allow_short) && +            !(style & allow_dash_for_short) && !(style & allow_slash_for_short)) +            error = "style disallows all characters for short options"; + +        if (error) +            boost::throw_exception(invalid_command_line_style(error)); + +        // Need to check that if guessing and long disguise are enabled +        // -f will mean the same as -foo +    } +     +    bool  +    cmdline::is_style_active(style_t style) const +    { +        return ((m_style & style) ? true : false); +    }     + +    void  +    cmdline::set_options_description(const options_description& desc) +    { +        m_desc = &desc; +    } + +    void  +    cmdline::set_positional_options( +        const positional_options_description& positional) +    { +        m_positional = &positional; +    } + + +    vector<option> +    cmdline::run() +    { +        // The parsing is done by having a set of 'style parsers' +        // and trying then in order. Each parser is passed a vector +        // of unparsed tokens and can consume some of them (by +        // removing elements on front) and return a vector of options. +        // +        // We try each style parser in turn, untill some input +        // is consumed. The returned vector of option may contain the +        // result of just syntactic parsing of token, say --foo will +        // be parsed as option with name 'foo', and the style parser +        // is not required to care if that option is defined, and how +        // many tokens the value may take. +        // So, after vector is returned, we validate them. +        assert(m_desc); + +        vector<style_parser> style_parsers;       + +        if (m_style_parser) +            style_parsers.push_back(m_style_parser); + +        if (m_additional_parser) +            style_parsers.push_back( +                boost::bind(&cmdline::handle_additional_parser, this, _1)); + +        if (m_style & allow_long) +            style_parsers.push_back( +                boost::bind(&cmdline::parse_long_option, this, _1)); + +        if ((m_style & allow_long_disguise)) +            style_parsers.push_back( +                boost::bind(&cmdline::parse_disguised_long_option, this, _1)); + +        if ((m_style & allow_short) && (m_style & allow_dash_for_short)) +            style_parsers.push_back( +                boost::bind(&cmdline::parse_short_option, this, _1)); + +        if ((m_style & allow_short) && (m_style & allow_slash_for_short)) +            style_parsers.push_back(boost::bind(&cmdline::parse_dos_option, this, _1)); + +        style_parsers.push_back(boost::bind(&cmdline::parse_terminator, this, _1)); + +        vector<option> result; +        while(!args.empty()) +        { +            bool ok = false; +            for(unsigned i = 0; i < style_parsers.size(); ++i) +            { +                unsigned current_size = args.size(); +                vector<option> next = style_parsers[i](args); + +                // Check that option names +                // are valid, and that all values are in place. +                if (!next.empty()) +                { +                    vector<string> e; +                    for(unsigned k = 0; k < next.size()-1; ++k) { +                        finish_option(next[k], e, style_parsers); +                    } +                    // For the last option, pass the unparsed tokens +                    // so that they can be added to next.back()'s values +                    // if appropriate. +                    finish_option(next.back(), args, style_parsers); +                    for (unsigned j = 0; j < next.size(); ++j) +                        result.push_back(next[j]);                     +                } +                                 +                if (args.size() != current_size) { +                    ok = true; +                    break;                 +                }  +            } +             +            if (!ok) { +                option opt; +                opt.value.push_back(args[0]); +                opt.original_tokens.push_back(args[0]); +                result.push_back(opt); +                args.erase(args.begin()); +            } +        } + +        /* If an key option is followed by a positional option, +           can can consume more tokens (e.g. it's multitoke option), +           give those tokens to it.  */ +        vector<option> result2; +        for (unsigned i = 0; i < result.size(); ++i) +        { +            result2.push_back(result[i]); +            option& opt = result2.back(); + +            if (opt.string_key.empty()) +                continue; + +            const option_description* xd =  +                m_desc->find_nothrow(opt.string_key,  +                                        is_style_active(allow_guessing), +                                        is_style_active(long_case_insensitive), +                                        is_style_active(short_case_insensitive)); +            if (!xd) +                continue; + +            unsigned min_tokens = xd->semantic()->min_tokens(); +            unsigned max_tokens = xd->semantic()->max_tokens(); +            if (min_tokens < max_tokens && opt.value.size() < max_tokens) +            { +                // This option may grab some more tokens. +                // We only allow to grab tokens that are not already +                // recognized as key options. + +                int can_take_more = max_tokens - opt.value.size(); +                unsigned j = i+1; +                for (; can_take_more && j < result.size(); --can_take_more, ++j) +                { +                    option& opt2 = result[j]; +                    if (!opt2.string_key.empty()) +                        break; + +                    if (opt2.position_key == INT_MAX) +                    { +                        // We use INT_MAX to mark positional options that +                        // were found after the '--' terminator and therefore +                        // should stay positional forever. +                        break; +                    } + +                    assert(opt2.value.size() == 1); +                     +                    opt.value.push_back(opt2.value[0]); + +                    assert(opt2.original_tokens.size() == 1); + +                    opt.original_tokens.push_back(opt2.original_tokens[0]); +                } +                i = j-1; +            } +        } +        result.swap(result2); +         + +        // Assign position keys to positional options. +        int position_key = 0; +        for(unsigned i = 0; i < result.size(); ++i) { +            if (result[i].string_key.empty()) +                result[i].position_key = position_key++; +        } + +        if (m_positional) +        { +            unsigned position = 0; +            for (unsigned i = 0; i < result.size(); ++i) { +                option& opt = result[i]; +                if (opt.position_key != -1) { +                    if (position >= m_positional->max_total_count()) +                    { +                        boost::throw_exception(too_many_positional_options_error()); +                    } +                    opt.string_key = m_positional->name_for_position(position); +                    ++position; +                } +            } +        } +         +        // set case sensitive flag +        for (unsigned i = 0; i < result.size(); ++i) { +            if (result[i].string_key.size() > 2 || +                        (result[i].string_key.size() > 1 && result[i].string_key[0] != '-')) +            { +                // it is a long option +                result[i].case_insensitive = is_style_active(long_case_insensitive); +            } +            else +            { +                // it is a short option +                result[i].case_insensitive = is_style_active(short_case_insensitive); +            } +        } + +        return result; +    } + +    void +    cmdline::finish_option(option& opt, +                           vector<string>& other_tokens, +                           const vector<style_parser>& style_parsers) +    {           +        if (opt.string_key.empty()) +            return; + +        // First check that the option is valid, and get its description. +        const option_description* xd = m_desc->find_nothrow(opt.string_key,  +                is_style_active(allow_guessing), +                is_style_active(long_case_insensitive), +                is_style_active(short_case_insensitive)); + +        if (!xd) +        { +            if (m_allow_unregistered) { +                opt.unregistered = true; +                return; +            } else { +                boost::throw_exception(unknown_option(opt.string_key)); +            }                 +        } +        const option_description& d = *xd; + +        // Canonize the name +        opt.string_key = d.key(opt.string_key); + +        // We check that the min/max number of tokens for the option +        // agrees with the number of tokens we have. The 'adjacent_value' +        // (the value in --foo=1) counts as a separate token, and if present +        // must be consumed. The following tokens on the command line may be +        // left unconsumed. + +        // We don't check if those tokens look like option, or not! + +        unsigned min_tokens = d.semantic()->min_tokens(); +        unsigned max_tokens = d.semantic()->max_tokens(); +         +        unsigned present_tokens = opt.value.size() + other_tokens.size(); +         +        if (present_tokens >= min_tokens) +        { +            if (!opt.value.empty() && max_tokens == 0)  +            { +                boost::throw_exception(invalid_command_line_syntax(opt.string_key, +                                             invalid_command_line_syntax::extra_parameter)); +            } +             +            // If an option wants, at minimum, N tokens, we grab them there, +            // when adding these tokens as values to current option we check +            // if they look like options +            if (opt.value.size() <= min_tokens)  +            { +                min_tokens -= opt.value.size(); +            } +            else +            { +                min_tokens = 0; +            } + +            // Everything's OK, move the values to the result.             +            for(;!other_tokens.empty() && min_tokens--; )  +            { +                // check if extra parameter looks like a known option +                // we use style parsers to check if it is syntactically an option,  +                // additionally we check if an option_description exists +                vector<option> followed_option;   +                vector<string> next_token(1, other_tokens[0]);       +                for (unsigned i = 0; followed_option.empty() && i < style_parsers.size(); ++i) +                { +                    followed_option = style_parsers[i](next_token); +                } +                if (!followed_option.empty())  +                { +                    const option_description* od = m_desc->find_nothrow(other_tokens[0],  +                              is_style_active(allow_guessing), +                              is_style_active(long_case_insensitive), +                              is_style_active(short_case_insensitive)); +                    if (od)  +                        boost::throw_exception(invalid_command_line_syntax(opt.string_key, +                                                    invalid_command_line_syntax::missing_parameter)); +                } +                opt.value.push_back(other_tokens[0]); +                opt.original_tokens.push_back(other_tokens[0]); +                other_tokens.erase(other_tokens.begin()); +            } +        } +        else +        { +            boost::throw_exception(invalid_command_line_syntax(opt.string_key, +                                            invalid_command_line_syntax::missing_parameter));  + +        } +    } + +    vector<option>  +    cmdline::parse_long_option(vector<string>& args) +    { +        vector<option> result; +        const string& tok = args[0]; +        if (tok.size() >= 3 && tok[0] == '-' && tok[1] == '-') +        {    +            string name, adjacent; + +            string::size_type p = tok.find('='); +            if (p != tok.npos) +            { +                name = tok.substr(2, p-2); +                adjacent = tok.substr(p+1); +                if (adjacent.empty()) +                    boost::throw_exception( invalid_command_line_syntax(name, +                                                      invalid_command_line_syntax::empty_adjacent_parameter) ); +            } +            else +            { +                name = tok.substr(2); +            } +            option opt; +            opt.string_key = name; +            if (!adjacent.empty()) +                opt.value.push_back(adjacent); +            opt.original_tokens.push_back(tok); +            result.push_back(opt); +            args.erase(args.begin()); +        } +        return result; +    } + + +    vector<option>  +    cmdline::parse_short_option(vector<string>& args) +    { +        const string& tok = args[0]; +        if (tok.size() >= 2 && tok[0] == '-' && tok[1] != '-') +        {    +            vector<option> result; + +            string name = tok.substr(0,2); +            string adjacent = tok.substr(2); + +            // Short options can be 'grouped', so that +            // "-d -a" becomes "-da". Loop, processing one +            // option at a time. We exit the loop when either +            // we've processed all the token, or when the remainder +            // of token is considered to be value, not further grouped +            // option. +            for(;;) { +                const option_description* d  +                    = m_desc->find_nothrow(name, false, false, +                            is_style_active(short_case_insensitive)); + +                // FIXME: check for 'allow_sticky'. +                if (d && (m_style & allow_sticky) && +                    d->semantic()->max_tokens() == 0 && !adjacent.empty()) { +                    // 'adjacent' is in fact further option. +                    option opt; +                    opt.string_key = name; +                    result.push_back(opt); + +                    if (adjacent.empty()) +                    { +                        args.erase(args.begin()); +                        break; +                    } + +                    name = string("-") + adjacent[0]; +                    adjacent.erase(adjacent.begin()); +                } else { +                     +                    option opt; +                    opt.string_key = name; +                    opt.original_tokens.push_back(tok); +                    if (!adjacent.empty()) +                        opt.value.push_back(adjacent); +                    result.push_back(opt); +                    args.erase(args.begin());                     +                    break; +                } +            } +            return result; +        } +        return vector<option>(); +    } + +    vector<option>  +    cmdline::parse_dos_option(vector<string>& args) +    { +        vector<option> result; +        const string& tok = args[0]; +        if (tok.size() >= 2 && tok[0] == '/') +        {    +            string name = "-" + tok.substr(1,1); +            string adjacent = tok.substr(2); + +            option opt; +            opt.string_key = name; +            if (!adjacent.empty()) +                opt.value.push_back(adjacent); +            opt.original_tokens.push_back(tok); +            result.push_back(opt); +            args.erase(args.begin()); +        } +        return result; +    } + +    vector<option>  +    cmdline::parse_disguised_long_option(vector<string>& args) +    { +        const string& tok = args[0]; +        if (tok.size() >= 2 &&  +            ((tok[0] == '-' && tok[1] != '-') || +             ((m_style & allow_slash_for_short) && tok[0] == '/')))             +        { +            if (m_desc->find_nothrow(tok.substr(1, tok.find('=')-1),  +                                     is_style_active(allow_guessing), +                                     is_style_active(long_case_insensitive), +                                     is_style_active(short_case_insensitive))) +            { +                args[0].insert(0, "-"); +                if (args[0][1] == '/') +                    args[0][1] = '-'; +                return parse_long_option(args); +            } +        } +        return vector<option>(); +    } + +    vector<option>  +    cmdline::parse_terminator(vector<string>& args) +    { +        vector<option> result; +        const string& tok = args[0]; +        if (tok == "--") +        { +            for(unsigned i = 1; i < args.size(); ++i) +            { +                option opt; +                opt.value.push_back(args[i]); +                opt.original_tokens.push_back(args[i]); +                opt.position_key = INT_MAX; +                result.push_back(opt); +            } +            args.clear(); +        } +        return result; +    } + +    vector<option>  +    cmdline::handle_additional_parser(vector<string>& args) +    { +        vector<option> result; +        pair<string, string> r = m_additional_parser(args[0]); +        if (!r.first.empty()) { +            option next; +            next.string_key = r.first; +            if (!r.second.empty()) +                next.value.push_back(r.second); +            result.push_back(next); +            args.erase(args.begin()); +        } +        return result; +    } + +    void  +    cmdline::set_additional_parser(additional_parser p) +    { +        m_additional_parser = p; +    } + +    void  +    cmdline::extra_style_parser(style_parser s) +    { +        m_style_parser = s; +    } + + + +}}} diff --git a/3rdParty/Boost/src/libs/program_options/src/config_file.cpp b/3rdParty/Boost/src/libs/program_options/src/config_file.cpp new file mode 100644 index 0000000..a12844c --- /dev/null +++ b/3rdParty/Boost/src/libs/program_options/src/config_file.cpp @@ -0,0 +1,196 @@ +// 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) + + +#define BOOST_PROGRAM_OPTIONS_SOURCE +#include <boost/program_options/config.hpp> + +#include <boost/program_options/detail/config_file.hpp> +#include <boost/program_options/errors.hpp> +#include <boost/program_options/detail/convert.hpp> +#include <boost/throw_exception.hpp> + +#include <iostream> +#include <fstream> +#include <cassert> + +namespace boost { namespace program_options { namespace detail { + +    using namespace std; + +    common_config_file_iterator::common_config_file_iterator( +        const std::set<std::string>& allowed_options, +        bool allow_unregistered) +    : allowed_options(allowed_options), +      m_allow_unregistered(allow_unregistered) +    { +        for(std::set<std::string>::const_iterator i = allowed_options.begin(); +            i != allowed_options.end();  +            ++i) +        { +            add_option(i->c_str()); +        } +    } + +    void +    common_config_file_iterator::add_option(const char* name) +    { +        string s(name); +        assert(!s.empty()); +        if (*s.rbegin() == '*') { +            s.resize(s.size()-1); +            bool bad_prefixes(false); +            // If 's' is a prefix of one of allowed suffix, then +            // lower_bound will return that element. +            // If some element is prefix of 's', then lower_bound will +            // return the next element. +            set<string>::iterator i = allowed_prefixes.lower_bound(s); +            if (i != allowed_prefixes.end()) { +                if (i->find(s) == 0) +                    bad_prefixes = true;                     +            } +            if (i != allowed_prefixes.begin()) { +                --i; +                if (s.find(*i) == 0) +                    bad_prefixes = true; +            } +            if (bad_prefixes) +                boost::throw_exception(error("bad prefixes")); +            allowed_prefixes.insert(s); +        } +    } + +    namespace { +        string trim_ws(const string& s) +        { +            string::size_type n, n2; +            n = s.find_first_not_of(" \t\r\n"); +            if (n == string::npos) +                return string(); +            else { +                n2 = s.find_last_not_of(" \t\r\n"); +                return s.substr(n, n2-n+1); +            } +        } +    } + + +    void common_config_file_iterator::get() +    { +        string s; +        string::size_type n; +        bool found = false; + +        while(this->getline(s)) { + +            // strip '#' comments and whitespace +            if ((n = s.find('#')) != string::npos) +                s = s.substr(0, n); +            s = trim_ws(s); + +            if (!s.empty()) { +                // Handle section name +                if (*s.begin() == '[' && *s.rbegin() == ']') { +                    m_prefix = s.substr(1, s.size()-2); +                    if (*m_prefix.rbegin() != '.') +                        m_prefix += '.'; +                } +                else if ((n = s.find('=')) != string::npos) { + +                    string name = m_prefix + trim_ws(s.substr(0, n)); +                    string value = trim_ws(s.substr(n+1)); + +                    bool registered = allowed_option(name); +                    if (!registered && !m_allow_unregistered) +                        boost::throw_exception(unknown_option(name)); + +                    found = true; +                    this->value().string_key = name; +                    this->value().value.clear(); +                    this->value().value.push_back(value); +                    this->value().unregistered = !registered; +                    this->value().original_tokens.clear(); +                    this->value().original_tokens.push_back(name); +                    this->value().original_tokens.push_back(value); +                    break; + +                } else { +                    boost::throw_exception(invalid_syntax(s, invalid_syntax::unrecognized_line)); +                } +            } +        } +        if (!found) +            found_eof(); +    } + + +    bool  +    common_config_file_iterator::allowed_option(const std::string& s) const +    { +        set<string>::const_iterator i = allowed_options.find(s); +        if (i != allowed_options.end()) +            return true;         +        // If s is "pa" where "p" is allowed prefix then +        // lower_bound should find the element after "p".  +        // This depends on 'allowed_prefixes' invariant. +        i = allowed_prefixes.lower_bound(s); +        if (i != allowed_prefixes.begin() && s.find(*--i) == 0) +            return true; +        return false; +    } + +#if BOOST_WORKAROUND(__COMO_VERSION__, BOOST_TESTED_AT(4303)) || \ +        (defined(__sgi) && BOOST_WORKAROUND(_COMPILER_VERSION, BOOST_TESTED_AT(741))) +    template<> +    bool +    basic_config_file_iterator<wchar_t>::getline(std::string& s) +    { +        std::wstring ws; +        // On Comeau, using two-argument version causes +        // call to some internal function with std::wstring, and '\n' +        // (not L'\n') and compile can't resolve that call. + +        if (std::getline(*is, ws, L'\n')) { +            s = to_utf8(ws); +            return true; +        } else { +            return false; +        }             +    } +#endif     + +}}} + +#if 0 +using boost::program_options::config_file; + +#include <sstream> +#include <cassert> + +int main() +{ +    try { +        stringstream s( +            "a = 1\n" +            "b = 2\n"); + +        config_file cf(s); +        cf.add_option("a"); +        cf.add_option("b"); + +        assert(++cf); +        assert(cf.name() == "a"); +        assert(cf.value() == "1"); +        assert(++cf); +        assert(cf.name() == "b"); +        assert(cf.value() == "2"); +        assert(!++cf); +    } +    catch(exception& e) +    { +        cout << e.what() << "\n"; +    } +} +#endif diff --git a/3rdParty/Boost/src/libs/program_options/src/convert.cpp b/3rdParty/Boost/src/libs/program_options/src/convert.cpp new file mode 100644 index 0000000..9be759e --- /dev/null +++ b/3rdParty/Boost/src/libs/program_options/src/convert.cpp @@ -0,0 +1,161 @@ +// Copyright Vladimir Prus 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 <fstream> +#include <locale.h> +#include <locale> +#include <iostream> +#include <string> +#include <locale> +#include <stdexcept> + +#include <boost/config.hpp> + +#define BOOST_PROGRAM_OPTIONS_SOURCE +#include <boost/program_options/config.hpp> +#include <boost/program_options/detail/convert.hpp> +#include <boost/program_options/detail/utf8_codecvt_facet.hpp> +#include <boost/throw_exception.hpp> + +#include <boost/bind.hpp> + +using namespace std; + +namespace boost { namespace detail { + +    /* Internal function to actually perform conversion. +       The logic in from_8_bit and to_8_bit function is exactly +       the same, except that one calls 'in' method of codecvt and another +       calls the 'out' method, and that syntax difference makes straightforward +       template implementation impossible. + +       This functions takes a 'fun' argument, which should have the same  +       parameters and return type and the in/out methods. The actual converting +       function will pass functional objects created with boost::bind. +       Experiments show that the performance loss is less than 10%. +    */ +    template<class ToChar, class FromChar, class Fun> +    std::basic_string<ToChar> +    convert(const std::basic_string<FromChar>& s, Fun fun) +         +    { +        std::basic_string<ToChar> result; +         +        std::mbstate_t state = std::mbstate_t(); + +        const FromChar* from = s.data(); +        const FromChar* from_end = s.data() + s.size(); +        // The interface of cvt is not really iterator-like, and it's +        // not possible the tell the required output size without the conversion. +        // All we can is convert data by pieces. +        while(from != from_end) { +             +            // std::basic_string does not provide non-const pointers to the data, +            // so converting directly into string is not possible. +            ToChar buffer[32]; +             +            ToChar* to_next = buffer; +            // Need variable because boost::bind doesn't work with rvalues. +            ToChar* to_end = buffer + 32; +            std::codecvt_base::result r =  +                fun(state, from, from_end, from, buffer, to_end, to_next); +             +            if (r == std::codecvt_base::error) +                boost::throw_exception( +                    std::logic_error("character conversion failed")); +            // 'partial' is not an error, it just means not all source +            // characters were converted. However, we need to check that at +            // least one new target character was produced. If not, it means +            // the source data is incomplete, and since we don't have extra +            // data to add to source, it's error. +            if (to_next == buffer) +                boost::throw_exception( +                    std::logic_error("character conversion failed")); +             +            // Add converted characters +            result.append(buffer, to_next); +        } +         +        return result;         +    }            +}} + +namespace boost { + +#ifndef BOOST_NO_STD_WSTRING +    BOOST_PROGRAM_OPTIONS_DECL std::wstring  +    from_8_bit(const std::string& s,  +               const std::codecvt<wchar_t, char, std::mbstate_t>& cvt) +    { +        return detail::convert<wchar_t>( +            s,                  +            boost::bind(&std::codecvt<wchar_t, char, mbstate_t>::in, +                        &cvt, +                        _1, _2, _3, _4, _5, _6, _7)); +    } + +    BOOST_PROGRAM_OPTIONS_DECL std::string  +    to_8_bit(const std::wstring& s,  +             const std::codecvt<wchar_t, char, std::mbstate_t>& cvt) +    { +        return detail::convert<char>( +            s,                  +            boost::bind(&codecvt<wchar_t, char, mbstate_t>::out, +                        &cvt, +                        _1, _2, _3, _4, _5, _6, _7)); +    } + + +    namespace { +        boost::program_options::detail::utf8_codecvt_facet +            utf8_facet; +    } +     +    BOOST_PROGRAM_OPTIONS_DECL std::wstring +    from_utf8(const std::string& s) +    { +        return from_8_bit(s, utf8_facet); +    } +     +    BOOST_PROGRAM_OPTIONS_DECL std::string +    to_utf8(const std::wstring& s) +    { +        return to_8_bit(s, utf8_facet); +    } + +    BOOST_PROGRAM_OPTIONS_DECL std::wstring +    from_local_8_bit(const std::string& s) +    { +        typedef codecvt<wchar_t, char, mbstate_t> facet_type; +        return from_8_bit(s,  +                          BOOST_USE_FACET(facet_type, locale())); +    } + +    BOOST_PROGRAM_OPTIONS_DECL std::string +    to_local_8_bit(const std::wstring& s) +    { +        typedef codecvt<wchar_t, char, mbstate_t> facet_type; +        return to_8_bit(s,  +                        BOOST_USE_FACET(facet_type, locale()));                         +    } +#endif + +    namespace program_options +    { +        BOOST_PROGRAM_OPTIONS_DECL std::string to_internal(const std::string& s) +        { +            return s; +        } + +#ifndef BOOST_NO_STD_WSTRING +        BOOST_PROGRAM_OPTIONS_DECL std::string to_internal(const std::wstring& s) +        { +            return to_utf8(s); +        } +#endif +    } + + +} diff --git a/3rdParty/Boost/src/libs/program_options/src/options_description.cpp b/3rdParty/Boost/src/libs/program_options/src/options_description.cpp new file mode 100644 index 0000000..bfd113d --- /dev/null +++ b/3rdParty/Boost/src/libs/program_options/src/options_description.cpp @@ -0,0 +1,621 @@ +// Copyright Vladimir Prus 2002-2004. +// Copyright Bertolt Mildner 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) + + +#define BOOST_PROGRAM_OPTIONS_SOURCE +#include <boost/program_options/config.hpp> +#include <boost/program_options/options_description.hpp> +// FIXME: this is only to get multiple_occurences class +// should move that to a separate headers. +#include <boost/program_options/parsers.hpp> + + +#include <boost/lexical_cast.hpp> +#include <boost/tokenizer.hpp> +#include <boost/detail/workaround.hpp> +#include <boost/throw_exception.hpp> + +#include <cassert> +#include <climits> +#include <cstring> +#include <cstdarg> +#include <sstream> +#include <iterator> +using namespace std; + +namespace boost { namespace program_options { + +   namespace { + +       template< class charT > +       std::basic_string< charT >  tolower_(const std::basic_string< charT >& str) +       { +           std::basic_string< charT > result; +           for (typename std::basic_string< charT >::size_type i = 0; i < str.size(); ++i) +           { +               result.append(1, static_cast< charT >(std::tolower(str[i]))); +           }    +           return result; +       } + +    }  // unnamed namespace + + +    option_description::option_description() +    { +    } +     +    option_description:: +    option_description(const char* name, +                       const value_semantic* s) +    : m_value_semantic(s) +    { +        this->set_name(name); +    } +                                            + +    option_description:: +    option_description(const char* name, +                       const value_semantic* s, +                       const char* description) +    : m_description(description), m_value_semantic(s) +    { +        this->set_name(name); +    } + +    option_description::~option_description() +    { +    } + +    option_description::match_result +    option_description::match(const std::string& option,  +                              bool approx,  +                              bool long_ignore_case, +                              bool short_ignore_case) const +    { +        match_result result = no_match;         +         +        std::string local_long_name((long_ignore_case ? tolower_(m_long_name) : m_long_name)); +         +        if (!local_long_name.empty()) { +         +            std::string local_option = (long_ignore_case ? tolower_(option) : option); + +            if (*local_long_name.rbegin() == '*') +            { +                // The name ends with '*'. Any specified name with the given +                // prefix is OK. +                if (local_option.find(local_long_name.substr(0, local_long_name.length()-1)) +                    == 0) +                    result = approximate_match; +            } + +            if (local_long_name == local_option) +            { +                result = full_match; +            } +            else if (approx) +            { +                if (local_long_name.find(local_option) == 0) +                { +                    result = approximate_match; +                } +            } +        } +          +        if (result != full_match) +        { +            std::string local_option(short_ignore_case ? tolower_(option) : option); +            std::string local_short_name(short_ignore_case ? tolower_(m_short_name) : m_short_name); + +            if (local_short_name == local_option) +            { +                result = full_match; +            } +        } + +        return result;         +    } + +    const std::string&  +    option_description::key(const std::string& option) const +    {         +        if (!m_long_name.empty())  +            if (m_long_name.find('*') != string::npos) +                // The '*' character means we're long_name +                // matches only part of the input. So, returning +                // long name will remove some of the information, +                // and we have to return the option as specified +                // in the source. +                return option; +            else +                return m_long_name; +        else +            return m_short_name; +    } + +    const std::string& +    option_description::long_name() const +    { +        return m_long_name; +    } + +    option_description& +    option_description::set_name(const char* _name) +    { +        std::string name(_name); +        string::size_type n = name.find(','); +        if (n != string::npos) { +            assert(n == name.size()-2); +            m_long_name = name.substr(0, n); +            m_short_name = '-' + name.substr(n+1,1); +        } else { +            m_long_name = name; +        } +        return *this; +    } + +    const std::string& +    option_description::description() const +    { +        return m_description; +    } + +    shared_ptr<const value_semantic> +    option_description::semantic() const +    { +        return m_value_semantic; +    } +     +    std::string  +    option_description::format_name() const +    { +        if (!m_short_name.empty()) +            return string(m_short_name).append(" [ --"). +            append(m_long_name).append(" ]"); +        else +            return string("--").append(m_long_name); +    } + +    std::string  +    option_description::format_parameter() const +    { +        if (m_value_semantic->max_tokens() != 0) +            return m_value_semantic->name(); +        else +            return ""; +    } + +    options_description_easy_init:: +    options_description_easy_init(options_description* owner) +    : owner(owner) +    {} + +    options_description_easy_init& +    options_description_easy_init:: +    operator()(const char* name, +               const char* description) +    { +        // Create untypes semantic which accepts zero tokens: i.e.  +        // no value can be specified on command line. +        // FIXME: does not look exception-safe +        shared_ptr<option_description> d( +            new option_description(name, new untyped_value(true), description)); + +        owner->add(d); +        return *this; +    } + +    options_description_easy_init& +    options_description_easy_init:: +    operator()(const char* name, +               const value_semantic* s) +    { +        shared_ptr<option_description> d(new option_description(name, s)); +        owner->add(d); +        return *this; +    } + +    options_description_easy_init& +    options_description_easy_init:: +    operator()(const char* name, +               const value_semantic* s, +               const char* description) +    { +        shared_ptr<option_description> d(new option_description(name, s, description)); + +        owner->add(d); +        return *this; +    } + +    const unsigned options_description::m_default_line_length = 80; + +    options_description::options_description(unsigned line_length, +                                             unsigned min_description_length) +    : m_line_length(line_length) +    , m_min_description_length(min_description_length) +    { +        // we require a space between the option and description parts, so add 1. +        assert(m_min_description_length < m_line_length - 1);     +    } + +    options_description::options_description(const std::string& caption, +                                             unsigned line_length, +                                             unsigned min_description_length) +    : m_caption(caption) +    , m_line_length(line_length) +    , m_min_description_length(min_description_length) +    { +        // we require a space between the option and description parts, so add 1. +        assert(m_min_description_length < m_line_length - 1); +    } +     +    void +    options_description::add(shared_ptr<option_description> desc) +    { +        m_options.push_back(desc); +        belong_to_group.push_back(false); +    } + +    options_description& +    options_description::add(const options_description& desc) +    { +        shared_ptr<options_description> d(new options_description(desc)); +        groups.push_back(d); + +        for (size_t i = 0; i < desc.m_options.size(); ++i) { +            add(desc.m_options[i]); +            belong_to_group.back() = true; +        } + +        return *this; +    } + +    options_description_easy_init +    options_description::add_options() +    {        +        return options_description_easy_init(this); +    } + +    const option_description& +    options_description::find(const std::string& name,  +                              bool approx, +                              bool long_ignore_case, +                              bool short_ignore_case) const +    { +        const option_description* d = find_nothrow(name, approx,  +                                       long_ignore_case, short_ignore_case); +        if (!d) +            boost::throw_exception(unknown_option(name)); +        return *d; +    } + +    const std::vector< shared_ptr<option_description> >&  +    options_description::options() const +    { +        return m_options; +    } + +    const option_description* +    options_description::find_nothrow(const std::string& name,  +                                      bool approx, +                                      bool long_ignore_case, +                                      bool short_ignore_case) const +    { +        shared_ptr<option_description> found; +        vector<string> approximate_matches; +        vector<string> full_matches; +         +        // We use linear search because matching specified option +        // name with the declared option name need to take care about +        // case sensitivity and trailing '*' and so we can't use simple map. +        for(unsigned i = 0; i < m_options.size(); ++i) +        { +            option_description::match_result r =  +                m_options[i]->match(name, approx, long_ignore_case, short_ignore_case); + +            if (r == option_description::no_match) +                continue; + +            if (r == option_description::full_match) +            {                 +                full_matches.push_back(m_options[i]->key(name)); +            }  +            else  +            {                         +                // FIXME: the use of 'key' here might not +                // be the best approach. +                approximate_matches.push_back(m_options[i]->key(name)); +            } + +            found = m_options[i]; +        } +        if (full_matches.size() > 1)  +            boost::throw_exception( +                ambiguous_option(name, full_matches)); +         +        // If we have a full match, and an approximate match, +        // ignore approximate match instead of reporting error. +        // Say, if we have options "all" and "all-chroots", then +        // "--all" on the command line should select the first one, +        // without ambiguity. +        if (full_matches.empty() && approximate_matches.size() > 1) +            boost::throw_exception( +                ambiguous_option(name, approximate_matches)); + +        return found.get(); +    } + +    BOOST_PROGRAM_OPTIONS_DECL +    std::ostream& operator<<(std::ostream& os, const options_description& desc) +    { +        desc.print(os); +        return os; +    } + +    namespace { + +        /* Given a string 'par', that contains no newline characters +           outputs it to 'os' with wordwrapping, that is, as several +           line. + +           Each output line starts with 'indent' space characters,  +           following by characters from 'par'. The total length of +           line is no longer than 'line_length'. +                                       +        */ +        void format_paragraph(std::ostream& os, +                              std::string par, +                              unsigned indent, +                              unsigned line_length) +        {                     +            // Through reminder of this function, 'line_length' will +            // be the length available for characters, not including +            // indent. +            assert(indent < line_length); +            line_length -= indent; + +            // index of tab (if present) is used as additional indent relative +            // to first_column_width if paragrapth is spanned over multiple +            // lines if tab is not on first line it is ignored +            string::size_type par_indent = par.find('\t'); + +            if (par_indent == string::npos) +            { +                par_indent = 0; +            } +            else +            { +                // only one tab per paragraph allowed +                if (count(par.begin(), par.end(), '\t') > 1) +                { +                    boost::throw_exception(program_options::error( +                        "Only one tab per paragraph is allowed")); +                } +           +                // erase tab from string +                par.erase(par_indent, 1); + +                // this assert may fail due to user error or  +                // environment conditions! +                assert(par_indent < line_length); + +                // ignore tab if not on first line +                if (par_indent >= line_length) +                { +                    par_indent = 0; +                }             +            } +           +            if (par.size() < line_length) +            { +                os << par; +            } +            else +            { +                string::const_iterator       line_begin = par.begin(); +                const string::const_iterator par_end = par.end(); + +                bool first_line = true; // of current paragraph!         +             +                while (line_begin < par_end)  // paragraph lines +                { +                    if (!first_line) +                    { +                        // If line starts with space, but second character +                        // is not space, remove the leading space. +                        // We don't remove double spaces because those +                        // might be intentianal. +                        if ((*line_begin == ' ') && +                            ((line_begin + 1 < par_end) && +                             (*(line_begin + 1) != ' '))) +                        { +                            line_begin += 1;  // line_begin != line_end +                        } +                    } + +                    // Take care to never increment the iterator past +                    // the end, since MSVC 8.0 (brokenly), assumes that +                    // doing that, even if no access happens, is a bug. +                    unsigned remaining = distance(line_begin, par_end); +                    string::const_iterator line_end = line_begin +  +                        ((remaining < line_length) ? remaining : line_length); +             +                    // prevent chopped words +                    // Is line_end between two non-space characters? +                    if ((*(line_end - 1) != ' ') && +                        ((line_end < par_end) && (*line_end != ' '))) +                    { +                        // find last ' ' in the second half of the current paragraph line +                        string::const_iterator last_space = +                            find(reverse_iterator<string::const_iterator>(line_end), +                                 reverse_iterator<string::const_iterator>(line_begin), +                                 ' ') +                            .base(); +                 +                        if (last_space != line_begin) +                        {                  +                            // is last_space within the second half ot the  +                            // current line +                            if (static_cast<unsigned>(distance(last_space, line_end)) <  +                                (line_length / 2)) +                            { +                                line_end = last_space; +                            } +                        }                                                 +                    } // prevent chopped words +              +                    // write line to stream +                    copy(line_begin, line_end, ostream_iterator<char>(os)); +               +                    if (first_line) +                    { +                        indent += par_indent; +                        line_length -= par_indent; // there's less to work with now +                        first_line = false; +                    } + +                    // more lines to follow? +                    if (line_end != par_end) +                    { +                        os << '\n'; +                 +                        for(unsigned pad = indent; pad > 0; --pad) +                        { +                            os.put(' '); +                        }                                                         +                    } +               +                    // next line starts after of this line +                    line_begin = line_end;               +                } // paragraph lines +            }           +        }                               +         +        void format_description(std::ostream& os, +                                const std::string& desc,  +                                unsigned first_column_width, +                                unsigned line_length) +        { +            // we need to use one char less per line to work correctly if actual +            // console has longer lines +            assert(line_length > 1); +            if (line_length > 1) +            { +                --line_length; +            } + +            // line_length must be larger than first_column_width +            // this assert may fail due to user error or environment conditions! +            assert(line_length > first_column_width); + +            // Note: can't use 'tokenizer' as name of typedef -- borland +            // will consider uses of 'tokenizer' below as uses of +            // boost::tokenizer, not typedef. +            typedef boost::tokenizer<boost::char_separator<char> > tok; +           +            tok paragraphs( +                desc, +                char_separator<char>("\n", "", boost::keep_empty_tokens)); +           +            tok::const_iterator       par_iter = paragraphs.begin();                 +            const tok::const_iterator par_end = paragraphs.end(); + +            while (par_iter != par_end)  // paragraphs +            { +                format_paragraph(os, *par_iter, first_column_width,  +                                 line_length); +             +                ++par_iter; +             +                // prepair next line if any +                if (par_iter != par_end) +                { +                    os << '\n'; +               +                    for(unsigned pad = first_column_width; pad > 0; --pad) +                    { +                        os.put(' '); +                    }                     +                }             +            }  // paragraphs +        } +     +        void format_one(std::ostream& os, const option_description& opt,  +                        unsigned first_column_width, unsigned line_length) +        { +            stringstream ss; +            ss << "  " << opt.format_name() << ' ' << opt.format_parameter(); +             +            // Don't use ss.rdbuf() since g++ 2.96 is buggy on it. +            os << ss.str(); + +            if (!opt.description().empty()) +            { +                if (ss.str().size() >= first_column_width) +                { +                   os.put('\n'); // first column is too long, lets put description in new line +                   for (unsigned pad = first_column_width; pad > 0; --pad) +                   { +                      os.put(' '); +                   } +                } else { +                   for(unsigned pad = first_column_width - ss.str().size(); pad > 0; --pad) +                   { +                      os.put(' '); +                   } +                } +             +                format_description(os, opt.description(), +                                   first_column_width, line_length); +            } +        } +    } + +    void  +    options_description::print(std::ostream& os) const +    { +        if (!m_caption.empty()) +            os << m_caption << ":\n"; + +        /* Find the maximum width of the option column */ +        unsigned width(23); +        unsigned i; // vc6 has broken for loop scoping +        for (i = 0; i < m_options.size(); ++i) +        { +            const option_description& opt = *m_options[i]; +            stringstream ss; +            ss << "  " << opt.format_name() << ' ' << opt.format_parameter(); +            width = (max)(width, static_cast<unsigned>(ss.str().size()));             +        } +        /* this is the column were description should start, if first +           column is longer, we go to a new line */ +        const unsigned start_of_description_column = m_line_length - m_min_description_length; + +        width = (min)(width, start_of_description_column-1); +         +        /* add an additional space to improve readability */ +        ++width; +             +        /* The options formatting style is stolen from Subversion. */ +        for (i = 0; i < m_options.size(); ++i) +        { +            if (belong_to_group[i]) +                continue; + +            const option_description& opt = *m_options[i]; + +            format_one(os, opt, width, m_line_length); + +            os << "\n"; +        } + +        for (unsigned j = 0; j < groups.size(); ++j) {             +            os << "\n" << *groups[j]; +        } +    } + +}} diff --git a/3rdParty/Boost/src/libs/program_options/src/parsers.cpp b/3rdParty/Boost/src/libs/program_options/src/parsers.cpp new file mode 100644 index 0000000..bc3b858 --- /dev/null +++ b/3rdParty/Boost/src/libs/program_options/src/parsers.cpp @@ -0,0 +1,245 @@ +// 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 <boost/config.hpp> + +#define BOOST_PROGRAM_OPTIONS_SOURCE +#include <boost/program_options/config.hpp> +#include <boost/program_options/parsers.hpp> +#include <boost/program_options/options_description.hpp> +#include <boost/program_options/positional_options.hpp> +#include <boost/program_options/detail/cmdline.hpp> +#include <boost/program_options/detail/config_file.hpp> +#include <boost/program_options/environment_iterator.hpp> +#include <boost/program_options/detail/convert.hpp> + +#include <boost/bind.hpp> +#include <boost/throw_exception.hpp> + +#include <cctype> +#include <fstream> + +#if !defined(__GNUC__) || __GNUC__ < 3 +#include <iostream> +#else +#include <istream> +#endif + +#ifdef _WIN32 +#include <stdlib.h> +#else +#include <unistd.h> +#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 <crt_externs.h> +#define environ (*_NSGetEnviron())  +#else +#if defined(__MWERKS__) +#include <crtl.h> +#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<wchar_t> +    ::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<class charT> +    basic_parsed_options<charT> +    parse_config_file(std::basic_istream<charT>& is,  +                      const options_description& desc, +                      bool allow_unregistered) +    {     +        set<string> allowed_options; + +        const vector<shared_ptr<option_description> >& 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<charT>( +                 is, allowed_options, allow_unregistered),  +             detail::basic_config_file_iterator<charT>(),  +             back_inserter(result.options)); +        // Convert char strings into desired type. +        return basic_parsed_options<charT>(result); +    } + +    template +    BOOST_PROGRAM_OPTIONS_DECL basic_parsed_options<char> +    parse_config_file(std::basic_istream<char>& is,  +                      const options_description& desc, +                      bool allow_unregistered); + +#ifndef BOOST_NO_STD_WSTRING +    template +    BOOST_PROGRAM_OPTIONS_DECL basic_parsed_options<wchar_t> +    parse_config_file(std::basic_istream<wchar_t>& is,  +                      const options_description& desc, +                      bool allow_unregistered); +#endif + +    template<class charT> +    basic_parsed_options<charT> +    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<char> +    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<wchar_t> +    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<std::string, std::string>& 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)); +    } + + + + +}} diff --git a/3rdParty/Boost/src/libs/program_options/src/positional_options.cpp b/3rdParty/Boost/src/libs/program_options/src/positional_options.cpp new file mode 100644 index 0000000..55995d7 --- /dev/null +++ b/3rdParty/Boost/src/libs/program_options/src/positional_options.cpp @@ -0,0 +1,53 @@ +// Copyright Vladimir Prus 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) + +#define BOOST_PROGRAM_OPTIONS_SOURCE +#include <boost/program_options/config.hpp> + +#include <boost/program_options/positional_options.hpp> + +#include <boost/limits.hpp> + +#include <cassert> + +namespace boost { namespace program_options { + +    positional_options_description::positional_options_description() +    {} + +    positional_options_description& +    positional_options_description::add(const char* name, int max_count) +    { +        assert(max_count != -1 || m_trailing.empty()); + +        if (max_count == -1) +            m_trailing = name; +        else { +            m_names.resize(m_names.size() + max_count, name); +        } +        return *this; +    } + +    unsigned +    positional_options_description::max_total_count() const +    { +        return m_trailing.empty() ?  +          m_names.size() : (std::numeric_limits<unsigned>::max)(); +    } +     +    const std::string&  +    positional_options_description::name_for_position(unsigned position) const +    { +        assert(position < max_total_count()); + +        if (position < m_names.size()) +            return m_names[position]; +        else +            return m_trailing; +    } + + +}} + diff --git a/3rdParty/Boost/src/libs/program_options/src/split.cpp b/3rdParty/Boost/src/libs/program_options/src/split.cpp new file mode 100644 index 0000000..96da068 --- /dev/null +++ b/3rdParty/Boost/src/libs/program_options/src/split.cpp @@ -0,0 +1,62 @@ +// Copyright Sascha Ochsenknecht 2009. +// 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) + +#define BOOST_PROGRAM_OPTIONS_SOURCE + +#include <boost/program_options/parsers.hpp> +#include <boost/tokenizer.hpp> + +#include <string> +#include <vector> + +namespace boost { namespace program_options { namespace detail { + +   template< class charT > +   std::vector<std::basic_string<charT> >  +   split_unix( +         const std::basic_string<charT>& cmdline,  +         const std::basic_string<charT>& seperator,  +         const std::basic_string<charT>& quote,  +         const std::basic_string<charT>& escape) +   {    +      typedef boost::tokenizer< boost::escaped_list_separator<charT>,  +            typename std::basic_string<charT>::const_iterator,  +            std::basic_string<charT> >  tokenizerT; +          +      tokenizerT tok(cmdline.begin(), cmdline.end(),  +                boost::escaped_list_separator< charT >(escape, seperator, quote)); +          +      std::vector< std::basic_string<charT> > result; +      for (typename tokenizerT::iterator cur_token(tok.begin()), end_token(tok.end()); cur_token != end_token; ++cur_token) { +         if (!cur_token->empty()) +            result.push_back(*cur_token); +      } +      return result; +   } +    +}}}   // namespace + +namespace boost { namespace program_options { + +   // Take a command line string and splits in into tokens, according +   // to the given collection of seperators chars. +   BOOST_PROGRAM_OPTIONS_DECL std::vector<std::string>  +   split_unix(const std::string& cmdline, const std::string& seperator,  +         const std::string& quote, const std::string& escape) +   { +      return detail::split_unix< char >(cmdline, seperator, quote, escape); +   } + +#ifndef BOOST_NO_STD_WSTRING +   BOOST_PROGRAM_OPTIONS_DECL std::vector<std::wstring> +   split_unix(const std::wstring& cmdline, const std::wstring& seperator,  +         const std::wstring& quote, const std::wstring& escape) +   { +      return detail::split_unix< wchar_t >(cmdline, seperator, quote, escape); +   } +#endif + +}}  // namespace + diff --git a/3rdParty/Boost/src/libs/program_options/src/utf8_codecvt_facet.cpp b/3rdParty/Boost/src/libs/program_options/src/utf8_codecvt_facet.cpp new file mode 100644 index 0000000..c0fd7c0 --- /dev/null +++ b/3rdParty/Boost/src/libs/program_options/src/utf8_codecvt_facet.cpp @@ -0,0 +1,21 @@ +// Copyright Vladimir Prus 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) + +#define BOOST_PROGRAM_OPTIONS_SOURCE +#include <boost/program_options/config.hpp> + +#define BOOST_UTF8_BEGIN_NAMESPACE \ +     namespace boost { namespace program_options { namespace detail { + +#define BOOST_UTF8_END_NAMESPACE }}} +#define BOOST_UTF8_DECL BOOST_PROGRAM_OPTIONS_DECL + +#include "../../detail/utf8_codecvt_facet.cpp" + + +#undef BOOST_UTF8_BEGIN_NAMESPACE +#undef BOOST_UTF8_END_NAMESPACE +#undef BOOST_UTF8_DECL + diff --git a/3rdParty/Boost/src/libs/program_options/src/value_semantic.cpp b/3rdParty/Boost/src/libs/program_options/src/value_semantic.cpp new file mode 100644 index 0000000..f5770f1 --- /dev/null +++ b/3rdParty/Boost/src/libs/program_options/src/value_semantic.cpp @@ -0,0 +1,335 @@ +// Copyright Vladimir Prus 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) + +#define BOOST_PROGRAM_OPTIONS_SOURCE +#include <boost/program_options/config.hpp> +#include <boost/program_options/value_semantic.hpp> +#include <boost/program_options/detail/convert.hpp> + +#include <cctype> + +namespace boost { namespace program_options { + +    using namespace std; + +    void  +    value_semantic_codecvt_helper<char>:: +    parse(boost::any& value_store,  +          const std::vector<std::string>& new_tokens, +          bool utf8) const +    { +        if (utf8) { +#ifndef BOOST_NO_STD_WSTRING +            // Need to convert to local encoding. +            std::vector<string> local_tokens; +            for (unsigned i = 0; i < new_tokens.size(); ++i) { +                std::wstring w = from_utf8(new_tokens[i]); +                local_tokens.push_back(to_local_8_bit(w)); +            } +            xparse(value_store, local_tokens); +#else +            boost::throw_exception( +                std::runtime_error("UTF-8 conversion not supported.")); +#endif +        } else { +            // Already in local encoding, pass unmodified +            xparse(value_store, new_tokens); +        }         +    } + +#ifndef BOOST_NO_STD_WSTRING +    void  +    value_semantic_codecvt_helper<wchar_t>:: +    parse(boost::any& value_store,  +          const std::vector<std::string>& new_tokens, +          bool utf8) const +    { +        std::vector<wstring> tokens; +        if (utf8) { +            // Convert from utf8 +            for (unsigned i = 0; i < new_tokens.size(); ++i) { +                tokens.push_back(from_utf8(new_tokens[i])); +            } +                +        } else { +            // Convert from local encoding +            for (unsigned i = 0; i < new_tokens.size(); ++i) { +                tokens.push_back(from_local_8_bit(new_tokens[i])); +            } +        }       + +        xparse(value_store, tokens);   +    } +#endif + +    BOOST_PROGRAM_OPTIONS_DECL std::string arg("arg"); + +    std::string +    untyped_value::name() const +    { +        return arg; +    } +     +    unsigned  +    untyped_value::min_tokens() const +    { +        if (m_zero_tokens) +            return 0; +        else +            return 1; +    } + +    unsigned  +    untyped_value::max_tokens() const +    { +        if (m_zero_tokens) +            return 0; +        else +            return 1; +    } + + +    void  +    untyped_value::xparse(boost::any& value_store, +                          const std::vector<std::string>& new_tokens) const +    { +        if (!value_store.empty())  +            boost::throw_exception( +                multiple_occurrences()); +        if (new_tokens.size() > 1) +            boost::throw_exception(multiple_values()); +        value_store = new_tokens.empty() ? std::string("") : new_tokens.front(); +    } + +    BOOST_PROGRAM_OPTIONS_DECL typed_value<bool>* +    bool_switch() +    { +        return bool_switch(0); +    } + +    BOOST_PROGRAM_OPTIONS_DECL typed_value<bool>* +    bool_switch(bool* v) +    { +        typed_value<bool>* r = new typed_value<bool>(v); +        r->default_value(0); +        r->zero_tokens(); + +        return r; +    } + +    /* Validates bool value. +        Any of "1", "true", "yes", "on" will be converted to "1".<br> +        Any of "0", "false", "no", "off" will be converted to "0".<br> +        Case is ignored. The 'xs' vector can either be empty, in which +        case the value is 'true', or can contain explicit value. +    */ +    BOOST_PROGRAM_OPTIONS_DECL void validate(any& v, const vector<string>& xs, +                       bool*, int) +    { +        check_first_occurrence(v); +        string s(get_single_string(xs, true)); + +        for (size_t i = 0; i < s.size(); ++i) +            s[i] = char(tolower(s[i])); + +        if (s.empty() || s == "on" || s == "yes" || s == "1" || s == "true") +            v = any(true); +        else if (s == "off" || s == "no" || s == "0" || s == "false") +            v = any(false); +        else +            boost::throw_exception(validation_error(validation_error::invalid_bool_value, s)); +    } + +    // This is blatant copy-paste. However, templating this will cause a problem, +    // since wstring can't be constructed/compared with char*. We'd need to +    // create auxiliary 'widen' routine to convert from char* into  +    // needed string type, and that's more work. +#if !defined(BOOST_NO_STD_WSTRING) +    BOOST_PROGRAM_OPTIONS_DECL  +    void validate(any& v, const vector<wstring>& xs, bool*, int) +    { +        check_first_occurrence(v); +        wstring s(get_single_string(xs, true)); + +        for (size_t i = 0; i < s.size(); ++i) +            s[i] = wchar_t(tolower(s[i])); + +        if (s.empty() || s == L"on" || s == L"yes" || s == L"1" || s == L"true") +            v = any(true); +        else if (s == L"off" || s == L"no" || s == L"0" || s == L"false") +            v = any(false); +        else +            boost::throw_exception(validation_error(validation_error::invalid_bool_value)); +    } +#endif +    BOOST_PROGRAM_OPTIONS_DECL  +    void validate(any& v, const vector<string>& xs, std::string*, int) +    { +        check_first_occurrence(v); +        v = any(get_single_string(xs)); +    } + +#if !defined(BOOST_NO_STD_WSTRING) +    BOOST_PROGRAM_OPTIONS_DECL  +    void validate(any& v, const vector<wstring>& xs, std::string*, int) +    { +        check_first_occurrence(v); +        v = any(get_single_string(xs)); +    } +#endif + +    namespace validators { + +        BOOST_PROGRAM_OPTIONS_DECL  +        void check_first_occurrence(const boost::any& value) +        { +            if (!value.empty()) +                boost::throw_exception( +                    multiple_occurrences()); +        } +    } + + +    invalid_option_value:: +    invalid_option_value(const std::string& bad_value) +    : validation_error(validation_error::invalid_option_value, bad_value) +    {} + +#ifndef BOOST_NO_STD_WSTRING +    namespace +    { +        std::string convert_value(const std::wstring& s) +        { +            try { +                return to_local_8_bit(s); +            } +            catch(const std::exception&) { +                return "<unrepresentable unicode string>"; +            } +        } +    } + +    invalid_option_value:: +    invalid_option_value(const std::wstring& bad_value) +    : validation_error(validation_error::invalid_option_value, convert_value(bad_value)) +    {} +#endif +    const std::string&  +    unknown_option::get_option_name() const throw() +    {  +        return m_option_name;  +    } + +    const std::string&  +    ambiguous_option::get_option_name() const throw() +    {  +        return m_option_name;  +    } +  +    const std::vector<std::string>&  +    ambiguous_option::alternatives() const throw() +    { +        return m_alternatives; +    } + +    void  +    multiple_values::set_option_name(const std::string& option_name) +    { +        m_option_name = option_name; +    } + +    const std::string&  +    multiple_values::get_option_name() const throw() +    { +        return m_option_name; +    } +     +    void  +    multiple_occurrences::set_option_name(const std::string& option_name) +    { +        m_option_name = option_name; +    } + +    const std::string&  +    multiple_occurrences::get_option_name() const throw() +    { +        return m_option_name; +    } +         +    validation_error::     +    validation_error(kind_t kind,  +                     const std::string& option_value,  +                     const std::string& option_name) +     : error("") +     , m_kind(kind)  +     , m_option_name(option_name) +     , m_option_value(option_value) +     , m_message(error_message(kind)) +    { +       if (!option_value.empty()) +       { +          m_message.append(std::string("'") + option_value + std::string("'")); +       } +    } + +    void  +    validation_error::set_option_name(const std::string& option_name) +    { +        m_option_name = option_name; +    } + +    const std::string&  +    validation_error::get_option_name() const throw() +    { +        return m_option_name; +    } + +    std::string  +    validation_error::error_message(kind_t kind) +    { +        // Initially, store the message in 'const char*' variable, +        // to avoid conversion to std::string in all cases. +        const char* msg; +        switch(kind) +        { +        case multiple_values_not_allowed: +            msg = "multiple values not allowed"; +            break; +        case at_least_one_value_required: +            msg = "at least one value required"; +            break; +        case invalid_bool_value: +            msg = "invalid bool value"; +            break; +        case invalid_option_value: +            msg = "invalid option value"; +            break; +        case invalid_option: +            msg = "invalid option"; +            break; +        default: +            msg = "unknown error"; +        } +        return msg; +    } + +    const char*  +    validation_error::what() const throw() +    { +        if (!m_option_name.empty()) +        { +            m_message = "in option '" + m_option_name + "': "  +                + error_message(m_kind); +        } +        return m_message.c_str(); +    } +     +    const std::string&  +    required_option::get_option_name() const throw() +    { +        return m_option_name; +    } + +}} diff --git a/3rdParty/Boost/src/libs/program_options/src/variables_map.cpp b/3rdParty/Boost/src/libs/program_options/src/variables_map.cpp new file mode 100644 index 0000000..29b1de9 --- /dev/null +++ b/3rdParty/Boost/src/libs/program_options/src/variables_map.cpp @@ -0,0 +1,231 @@ +// 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) + + +#define BOOST_PROGRAM_OPTIONS_SOURCE +#include <boost/program_options/config.hpp> +#include <boost/program_options/parsers.hpp> +#include <boost/program_options/options_description.hpp> +#include <boost/program_options/value_semantic.hpp> +#include <boost/program_options/variables_map.hpp> + +#include <cassert> + +namespace boost { namespace program_options { + +    using namespace std; + +    // First, performs semantic actions for 'oa'.  +    // Then, stores in 'm' all options that are defined in 'desc'.  +    BOOST_PROGRAM_OPTIONS_DECL  +    void store(const parsed_options& options, variables_map& xm, +               bool utf8) +    {        +        // TODO: what if we have different definition +        // for the same option name during different calls +        // 'store'. +        assert(options.description); +        const options_description& desc = *options.description; + +        // We need to access map's operator[], not the overriden version +        // variables_map. Ehmm.. messy. +        std::map<std::string, variable_value>& m = xm; + +        std::set<std::string> new_final; + +        // Declared once, to please Intel in VC++ mode; +        unsigned i; + +        // First, convert/store all given options +        for (i = 0; i < options.options.size(); ++i) { + +            const string& name = options.options[i].string_key; +            // Skip positional options without name +            if (name.empty()) +                continue; + +            // Ignore unregistered option. The 'unregistered' +            // field can be true only if user has explicitly asked +            // to allow unregistered options. We can't store them +            // to variables map (lacking any information about paring),  +            // so just ignore them. +            if (options.options[i].unregistered) +                continue; + +            // If option has final value, skip this assignment +            if (xm.m_final.count(name)) +                continue; + +            const option_description& d = desc.find(name, false,  +                                                      false, false); + +            variable_value& v = m[name];             +            if (v.defaulted()) { +                // Explicit assignment here erases defaulted value +                v = variable_value(); +            } +             +            try { +                d.semantic()->parse(v.value(), options.options[i].value, utf8); +            } +#ifndef BOOST_NO_EXCEPTIONS +            catch(validation_error& e) +            { +                e.set_option_name(name); +                throw; +            } +            catch(multiple_occurrences& e) +            { +                e.set_option_name(name); +                throw; +            } +            catch(multiple_values& e)  +            { +                e.set_option_name(name); +                throw; +            } +#endif +            v.m_value_semantic = d.semantic(); +             +            // The option is not composing, and the value is explicitly +            // provided. Ignore values of this option for subsequent +            // calls to 'store'. We store this to a temporary set, +            // so that several assignment inside *this* 'store' call +            // are allowed. +            if (!d.semantic()->is_composing()) +                new_final.insert(name); +        } +        xm.m_final.insert(new_final.begin(), new_final.end()); + +         +         +        // Second, apply default values and store required options. +        const vector<shared_ptr<option_description> >& all = desc.options(); +        for(i = 0; i < all.size(); ++i) +        { +            const option_description& d = *all[i]; +            string key = d.key(""); +            // FIXME: this logic relies on knowledge of option_description +            // internals. +            // The 'key' is empty if options description contains '*'.  +            // In that  +            // case, default value makes no sense at all. +            if (key.empty()) +            { +                continue; +            } +            if (m.count(key) == 0) { +             +                boost::any def; +                if (d.semantic()->apply_default(def)) { +                    m[key] = variable_value(def, true); +                    m[key].m_value_semantic = d.semantic(); +                } +            }   + +            // add empty value if this is an required option +            if (d.semantic()->is_required()) { +               xm.m_required.insert(key); +            } +        } +    } + +    BOOST_PROGRAM_OPTIONS_DECL  +    void store(const wparsed_options& options, variables_map& m) +    { +        store(options.utf8_encoded_options, m, true); +    } + +    BOOST_PROGRAM_OPTIONS_DECL  +    void notify(variables_map& vm) +    {         +        vm.notify();                +    } + +    abstract_variables_map::abstract_variables_map() +    : m_next(0) +    {} + +    abstract_variables_map:: +    abstract_variables_map(const abstract_variables_map* next) +    : m_next(next) +    {} + +    const variable_value&  +    abstract_variables_map::operator[](const std::string& name) const +    { +        const variable_value& v = get(name); +        if (v.empty() && m_next) +            return (*m_next)[name]; +        else if (v.defaulted() && m_next) { +            const variable_value& v2 = (*m_next)[name]; +            if (!v2.empty() && !v2.defaulted()) +                return v2; +            else return v; +        } else { +            return v; +        } +    } + +    void  +    abstract_variables_map::next(abstract_variables_map* next) +    { +        m_next = next; +    } + +    variables_map::variables_map() +    {} + +    variables_map::variables_map(const abstract_variables_map* next) +    : abstract_variables_map(next) +    {} + +    const variable_value& +    variables_map::get(const std::string& name) const +    { +        static variable_value empty; +        const_iterator i = this->find(name); +        if (i == this->end()) +            return empty; +        else +            return i->second; +    } +     +    void +    variables_map::notify() +    { +        // This checks if all required options occur +        for (set<string>::const_iterator r = m_required.begin(); +             r != m_required.end(); +             ++r) +        { +            const string& opt = *r; +            map<string, variable_value>::const_iterator iter = find(opt); +            if (iter == end() || iter->second.empty())  +            { +                boost::throw_exception(required_option(opt)); +             +            } +        } + +        // Lastly, run notify actions. +        for (map<string, variable_value>::iterator k = begin();  +             k != end();  +             ++k)  +        { +            /* Users might wish to use variables_map to store their own values +               that are not parsed, and therefore will not have value_semantics +               defined. Do no crash on such values. In multi-module programs, +               one module might add custom values, and the 'notify' function +               will be called after that, so we check that value_sematics is  +               not NULL. See: +                   https://svn.boost.org/trac/boost/ticket/2782 +            */ +            if (k->second.m_value_semantic) +                k->second.m_value_semantic->notify(k->second.value()); +        }                +    } +     +}} diff --git a/3rdParty/Boost/src/libs/program_options/src/winmain.cpp b/3rdParty/Boost/src/libs/program_options/src/winmain.cpp new file mode 100644 index 0000000..64cc790 --- /dev/null +++ b/3rdParty/Boost/src/libs/program_options/src/winmain.cpp @@ -0,0 +1,96 @@ +// 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) + +#define BOOST_PROGRAM_OPTIONS_SOURCE +#include <boost/program_options/parsers.hpp> +#include <cctype> + +#ifdef _WIN32 +namespace boost { namespace program_options { + +    // Take a command line string and splits in into tokens, according +    // to the rules windows command line processor uses. +    //  +    // The rules are pretty funny, see +    //    http://article.gmane.org/gmane.comp.lib.boost.user/3005 +    //    http://msdn.microsoft.com/library/en-us/vccelng/htm/progs_12.asp +    BOOST_PROGRAM_OPTIONS_DECL +    std::vector<std::string> split_winmain(const std::string& input) +    { +        std::vector<std::string> result; + +        std::string::const_iterator i = input.begin(), e = input.end(); +        for(;i != e; ++i) +            if (!isspace((unsigned char)*i)) +                break; +        +        if (i != e) { +    +            std::string current; +            bool inside_quoted = false; +            int backslash_count = 0; +             +            for(; i != e; ++i) { +                if (*i == '"') { +                    // '"' preceded by even number (n) of backslashes generates +                    // n/2 backslashes and is a quoted block delimiter +                    if (backslash_count % 2 == 0) { +                        current.append(backslash_count / 2, '\\'); +                        inside_quoted = !inside_quoted; +                        // '"' preceded by odd number (n) of backslashes generates +                        // (n-1)/2 backslashes and is literal quote. +                    } else { +                        current.append(backslash_count / 2, '\\');                 +                        current += '"';                 +                    } +                    backslash_count = 0; +                } else if (*i == '\\') { +                    ++backslash_count; +                } else { +                    // Not quote or backslash. All accumulated backslashes should be +                    // added +                    if (backslash_count) { +                        current.append(backslash_count, '\\'); +                        backslash_count = 0; +                    } +                    if (isspace((unsigned char)*i) && !inside_quoted) { +                        // Space outside quoted section terminate the current argument +                        result.push_back(current); +                        current.resize(0); +                        for(;i != e && isspace((unsigned char)*i); ++i) +                            ; +                        --i; +                    } else {                   +                        current += *i; +                    } +                } +            } + +            // If we have trailing backslashes, add them +            if (backslash_count) +                current.append(backslash_count, '\\'); +         +            // If we have non-empty 'current' or we're still in quoted +            // section (even if 'current' is empty), add the last token. +            if (!current.empty() || inside_quoted) +                result.push_back(current);         +        } +        return result; +    } + +#ifndef BOOST_NO_STD_WSTRING +    BOOST_PROGRAM_OPTIONS_DECL std::vector<std::wstring> +    split_winmain(const std::wstring& cmdline) +    { +        std::vector<std::wstring> result; +        std::vector<std::string> aux = split_winmain(to_internal(cmdline)); +        for (unsigned i = 0, e = aux.size(); i < e; ++i) +            result.push_back(from_utf8(aux[i])); +        return result;         +    } +#endif + +}} +#endif diff --git a/3rdParty/Boost/update.sh b/3rdParty/Boost/update.sh index ed1ce06..1ef3aa5 100755 --- a/3rdParty/Boost/update.sh +++ b/3rdParty/Boost/update.sh @@ -15,8 +15,9 @@ TARGET_DIR=src  	noncopyable.hpp \  	numeric/conversion/cast.hpp \  	shared_ptr.hpp \ -  optional.hpp \ +	optional.hpp \  	signals.hpp \ +	program_options.hpp \  	thread.hpp \  	asio.hpp \  	regex.hpp \ @@ -25,7 +26,7 @@ TARGET_DIR=src  rm -rf $TARGET_DIR/libs/config  rm -rf $TARGET_DIR/libs/smart_ptr -LIBS="date_time regex system thread signals filesystem" +LIBS="date_time regex system thread signals filesystem program_options"  for lib in $LIBS; do  	rm -rf $TARGET_DIR/libs/$lib/build $TARGET_DIR/libs/$lib/*.doc $TARGET_DIR/libs/$lib/src/*.doc $TARGET_DIR/libs/$lib/src/CMakeLists.txt $TARGET_DIR/libs/$lib/test  done diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp index d05826a..6056fc5 100644 --- a/Swift/Controllers/Chat/ChatController.cpp +++ b/Swift/Controllers/Chat/ChatController.cpp @@ -21,8 +21,9 @@ namespace Swift {  /**   * The controller does not gain ownership of the stanzaChannel, nor the factory.   */ -ChatController::ChatController(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &contact, NickResolver* nickResolver, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool isInMUC) - : ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, contact, presenceOracle, avatarManager) { +ChatController::ChatController(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &contact, NickResolver* nickResolver, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool isInMUC, bool useDelayForLatency) +	: ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, contact, presenceOracle, avatarManager, useDelayForLatency) { +	isInMUC_ = isInMUC;  	chatStateNotifier_ = new ChatStateNotifier();  	chatStateMessageSender_ = new ChatStateMessageSender(chatStateNotifier_, stanzaChannel, contact);  	chatStateTracker_ = new ChatStateTracker(); diff --git a/Swift/Controllers/Chat/ChatController.h b/Swift/Controllers/Chat/ChatController.h index b044633..3821a6e 100644 --- a/Swift/Controllers/Chat/ChatController.h +++ b/Swift/Controllers/Chat/ChatController.h @@ -17,7 +17,7 @@ namespace Swift {  	class NickResolver;  	class ChatController : public ChatControllerBase {  		public: -			ChatController(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &contact, NickResolver* nickResolver, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool isInMUC); +			ChatController(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &contact, NickResolver* nickResolver, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool isInMUC, bool useDelayForLatency);  			virtual void setToJID(const JID& jid);  		private: @@ -35,6 +35,7 @@ namespace Swift {  			ChatStateNotifier* chatStateNotifier_;  			ChatStateMessageSender* chatStateMessageSender_;  			ChatStateTracker* chatStateTracker_; +			bool isInMUC_;  	};  }  #endif diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp index abd346a..f3e6bbe 100644 --- a/Swift/Controllers/Chat/ChatControllerBase.cpp +++ b/Swift/Controllers/Chat/ChatControllerBase.cpp @@ -22,7 +22,7 @@  namespace Swift { -ChatControllerBase::ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager) : selfJID_(self), stanzaChannel_(stanzaChannel), iqRouter_(iqRouter), chatWindowFactory_(chatWindowFactory), toJID_(toJID), labelsEnabled_(false), presenceOracle_(presenceOracle), avatarManager_(avatarManager) { +ChatControllerBase::ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool useDelayForLatency) : selfJID_(self), stanzaChannel_(stanzaChannel), iqRouter_(iqRouter), chatWindowFactory_(chatWindowFactory), toJID_(toJID), labelsEnabled_(false), presenceOracle_(presenceOracle), avatarManager_(avatarManager), useDelayForLatency_(useDelayForLatency)  {  	chatWindow_ = chatWindowFactory_->createChatWindow(toJID);  	chatWindow_->onAllMessagesRead.connect(boost::bind(&ChatControllerBase::handleAllMessagesRead, this));  	chatWindow_->onSendMessageRequest.connect(boost::bind(&ChatControllerBase::handleSendMessageRequest, this, _1)); @@ -73,9 +73,7 @@ void ChatControllerBase::handleSendMessageRequest(const String &body) {  		label = boost::optional<SecurityLabel>(chatWindow_->getSelectedSecurityLabel());  	}  	preSendMessageRequest(message); -	//FIXME: optional -	bool useSwiftDelay = true; -	if (useSwiftDelay) { +	if (useDelayForLatency_) {  		boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();  		message->addPayload(boost::shared_ptr<Delay>(new Delay(now, selfJID_)));  	} @@ -113,6 +111,10 @@ void ChatControllerBase::addMessage(const String& message, const String& senderN  	}  } +bool ChatControllerBase::isFromContact(const JID& from) { +	return from.toBare() == toJID_.toBare(); +} +  void ChatControllerBase::handleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent) {  	if (messageEvent->isReadable()) {  		unreadMessages_.push_back(messageEvent); @@ -131,16 +133,19 @@ void ChatControllerBase::handleIncomingMessage(boost::shared_ptr<MessageEvent> m  			return;  		}  		showChatWindow(); -		boost::shared_ptr<Delay> delayPayload = message->getPayload<Delay>(); -		if (delayPayload) { +		JID from = message->getFrom(); +		std::vector<boost::shared_ptr<Delay> > delayPayloads = message->getPayloads<Delay>(); +		for (size_t i = 0; useDelayForLatency_ && i < delayPayloads.size(); i++) { +			if (!delayPayloads[i]->getFrom()) {  +				continue; +			}  			boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();  			std::ostringstream s; -			s << "The following message took " << (now - delayPayload->getStamp()).total_milliseconds() <<  " milliseconds to be delivered."; +			s << "The following message took " << (now - delayPayloads[i]->getStamp()).total_milliseconds() / 1000.0 <<  " seconds to be delivered from " << delayPayloads[i]->getFrom()->toString() << ".";  			chatWindow_->addSystemMessage(String(s.str()));  		}  		boost::shared_ptr<SecurityLabel> label = message->getPayload<SecurityLabel>();  		boost::optional<SecurityLabel> maybeLabel = label ? boost::optional<SecurityLabel>(*label) : boost::optional<SecurityLabel>(); -		JID from = message->getFrom();  		addMessage(body, senderDisplayNameFromMessage(from), isIncomingMessageFromMe(message), maybeLabel, String(avatarManager_->getAvatarPath(from).string()));  	}  } diff --git a/Swift/Controllers/Chat/ChatControllerBase.h b/Swift/Controllers/Chat/ChatControllerBase.h index a2dfd6a..8317da8 100644 --- a/Swift/Controllers/Chat/ChatControllerBase.h +++ b/Swift/Controllers/Chat/ChatControllerBase.h @@ -40,14 +40,14 @@ namespace Swift {  			void setEnabled(bool enabled);  			virtual void setToJID(const JID& jid) {toJID_ = jid;};  		protected: -			ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager); +			ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool useDelayForLatency);  			virtual void postSendMessage(const String&) {};  			virtual String senderDisplayNameFromMessage(const JID& from) = 0;  			virtual bool isIncomingMessageFromMe(boost::shared_ptr<Message>) = 0;  			virtual void preHandleIncomingMessage(boost::shared_ptr<Message>) {};  			virtual void preSendMessageRequest(boost::shared_ptr<Message>) {}; - +			virtual bool isFromContact(const JID& from);  		private:  			void handleSendMessageRequest(const String &body); @@ -66,6 +66,7 @@ namespace Swift {  			bool labelsEnabled_;  			PresenceOracle* presenceOracle_;  			AvatarManager* avatarManager_; +			bool useDelayForLatency_;  	};  } diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp index a490a3f..6aacdbd 100644 --- a/Swift/Controllers/Chat/ChatsManager.cpp +++ b/Swift/Controllers/Chat/ChatsManager.cpp @@ -25,7 +25,7 @@ namespace Swift {  typedef std::pair<JID, ChatController*> JIDChatControllerPair;  typedef std::pair<JID, MUCController*> JIDMUCControllerPair; -ChatsManager::ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, TreeWidgetFactory* treeWidgetFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, boost::shared_ptr<DiscoInfo> serverDiscoInfo, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory) : jid_(jid) { +ChatsManager::ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, TreeWidgetFactory* treeWidgetFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, boost::shared_ptr<DiscoInfo> serverDiscoInfo, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency) : jid_(jid), useDelayForLatency_(useDelayForLatency) {  	eventController_ = eventController;  	stanzaChannel_ = stanzaChannel;  	iqRouter_ = iqRouter; @@ -165,7 +165,7 @@ ChatController* ChatsManager::getChatControllerOrFindAnother(const JID &contact)  }  ChatController* ChatsManager::createNewChatController(const JID& contact) { -	ChatController* controller = new ChatController(jid_, stanzaChannel_, iqRouter_, chatWindowFactory_, contact, nickResolver_, presenceOracle_, avatarManager_, isMUC(contact.toBare())); +	ChatController* controller = new ChatController(jid_, stanzaChannel_, iqRouter_, chatWindowFactory_, contact, nickResolver_, presenceOracle_, avatarManager_, isMUC(contact.toBare()), useDelayForLatency_);  	chatControllers_[contact] = controller;  	controller->setAvailableServerFeatures(serverDiscoInfo_);  	return controller; @@ -201,7 +201,7 @@ void ChatsManager::handleJoinMUCRequest(const JID &muc, const boost::optional<St  		//FIXME: What's correct behaviour here?  	} else {  		String nick = nickMaybe ? nickMaybe.get() : "Swift user"; -		MUCController* controller = new MUCController(jid_, muc, nick, stanzaChannel_, presenceSender_, iqRouter_, chatWindowFactory_, treeWidgetFactory_, presenceOracle_, avatarManager_, uiEventStream_); +		MUCController* controller = new MUCController(jid_, muc, nick, stanzaChannel_, presenceSender_, iqRouter_, chatWindowFactory_, treeWidgetFactory_, presenceOracle_, avatarManager_, uiEventStream_, false);  		mucControllers_[muc] = controller;  		controller->setAvailableServerFeatures(serverDiscoInfo_);  		controller->onUserLeft.connect(boost::bind(&ChatsManager::handleUserLeftMUC, this, controller)); diff --git a/Swift/Controllers/Chat/ChatsManager.h b/Swift/Controllers/Chat/ChatsManager.h index df49b0a..d45d81d 100644 --- a/Swift/Controllers/Chat/ChatsManager.h +++ b/Swift/Controllers/Chat/ChatsManager.h @@ -37,7 +37,7 @@ namespace Swift {  	class ChatsManager : public MUCRegistry {  		public: -			ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, TreeWidgetFactory* treeWidgetFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, boost::shared_ptr<DiscoInfo> serverDiscoInfo, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory); +			ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, TreeWidgetFactory* treeWidgetFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, boost::shared_ptr<DiscoInfo> serverDiscoInfo, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency);  			~ChatsManager();  			void setAvatarManager(AvatarManager* avatarManager);  			void setEnabled(bool enabled); @@ -75,5 +75,6 @@ namespace Swift {  			boost::shared_ptr<DiscoInfo> serverDiscoInfo_;  			ChatListWindow* chatListWindow_;  			boost::bsignals::scoped_connection uiEventConnection_; +			bool useDelayForLatency_;  	};  } diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp index f22bc18..737ad82 100644 --- a/Swift/Controllers/Chat/MUCController.cpp +++ b/Swift/Controllers/Chat/MUCController.cpp @@ -38,8 +38,9 @@ MUCController::MUCController (  		TreeWidgetFactory *treeWidgetFactory,  		PresenceOracle* presenceOracle,  		AvatarManager* avatarManager, -		UIEventStream* uiEventStream) : -			ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, muc, presenceOracle, avatarManager), +		UIEventStream* uiEventStream, +		bool useDelayForLatency) : +	ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, muc, presenceOracle, avatarManager, useDelayForLatency),  			muc_(new MUC(stanzaChannel, presenceSender, muc)),   			nick_(nick),   			treeWidgetFactory_(treeWidgetFactory) {  diff --git a/Swift/Controllers/Chat/MUCController.h b/Swift/Controllers/Chat/MUCController.h index d0e1980..2252357 100644 --- a/Swift/Controllers/Chat/MUCController.h +++ b/Swift/Controllers/Chat/MUCController.h @@ -32,7 +32,7 @@ namespace Swift {  	class MUCController : public ChatControllerBase {  		public: -			MUCController(const JID& self, const JID &muc, const String &nick, StanzaChannel* stanzaChannel, PresenceSender* presenceSender, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, TreeWidgetFactory *treeWidgetFactory, PresenceOracle* presenceOracle, AvatarManager* avatarManager, UIEventStream* events); +			MUCController(const JID& self, const JID &muc, const String &nick, StanzaChannel* stanzaChannel, PresenceSender* presenceSender, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, TreeWidgetFactory *treeWidgetFactory, PresenceOracle* presenceOracle, AvatarManager* avatarManager, UIEventStream* events, bool useDelayForLatency);  			~MUCController();  			boost::signal<void ()> onUserLeft; diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp index d493cf6..5caedab 100644 --- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp +++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp @@ -63,7 +63,7 @@ public:  		uiEventStream_ = new UIEventStream();  		chatListWindowFactory_ = mocks_->InterfaceMock<ChatListWindowFactory>();  		mocks_->ExpectCall(chatListWindowFactory_, ChatListWindowFactory::createWindow).With(uiEventStream_).Return(NULL); -		manager_ = new ChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, treeWidgetFactory_, nickResolver_, presenceOracle_, serverDiscoInfo_, presenceSender_, uiEventStream_, chatListWindowFactory_); +		manager_ = new ChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, treeWidgetFactory_, nickResolver_, presenceOracle_, serverDiscoInfo_, presenceSender_, uiEventStream_, chatListWindowFactory_, true);  		avatarManager_ = new MockAvatarManager();  		manager_->setAvatarManager(avatarManager_);  	}; diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp index 341fc09..3656de3 100644 --- a/Swift/Controllers/MainController.cpp +++ b/Swift/Controllers/MainController.cpp @@ -61,8 +61,8 @@ static const String CLIENT_VERSION = "0.3";  static const String CLIENT_NODE = "http://swift.im"; -MainController::MainController(ChatWindowFactory* chatWindowFactory, MainWindowFactory *mainWindowFactory, LoginWindowFactory *loginWindowFactory, TreeWidgetFactory *treeWidgetFactory, EventWindowFactory* eventWindowFactory, SettingsProvider *settings, Application* application, SystemTray* systemTray, SoundPlayer* soundPlayer, XMLConsoleWidgetFactory* xmlConsoleWidgetFactory, ChatListWindowFactory* chatListWindowFactory) -		: timerFactory_(&boostIOServiceThread_.getIOService()), idleDetector_(&idleQuerier_, &timerFactory_, 100), chatWindowFactory_(chatWindowFactory), mainWindowFactory_(mainWindowFactory), loginWindowFactory_(loginWindowFactory), treeWidgetFactory_(treeWidgetFactory), settings_(settings), loginWindow_(NULL)  { +MainController::MainController(ChatWindowFactory* chatWindowFactory, MainWindowFactory *mainWindowFactory, LoginWindowFactory *loginWindowFactory, TreeWidgetFactory *treeWidgetFactory, EventWindowFactory* eventWindowFactory, SettingsProvider *settings, Application* application, SystemTray* systemTray, SoundPlayer* soundPlayer, XMLConsoleWidgetFactory* xmlConsoleWidgetFactory, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency) +	: timerFactory_(&boostIOServiceThread_.getIOService()), idleDetector_(&idleQuerier_, &timerFactory_, 100), chatWindowFactory_(chatWindowFactory), mainWindowFactory_(mainWindowFactory), loginWindowFactory_(loginWindowFactory), treeWidgetFactory_(treeWidgetFactory), settings_(settings), loginWindow_(NULL), useDelayForLatency_(useDelayForLatency)  {  	application_ = application;  	presenceOracle_ = NULL;  	avatarManager_ = NULL; @@ -180,7 +180,7 @@ void MainController::handleConnected() {  		rosterController_->onChangeStatusRequest.connect(boost::bind(&MainController::handleChangeStatusRequest, this, _1, _2));  		rosterController_->onSignOutRequest.connect(boost::bind(&MainController::signOut, this)); -		chatsManager_ = new ChatsManager(jid_, client_, client_, eventController_, chatWindowFactory_, treeWidgetFactory_, nickResolver_, presenceOracle_, serverDiscoInfo_, presenceSender_, uiEventStream_, chatListWindowFactory_); +		chatsManager_ = new ChatsManager(jid_, client_, client_, eventController_, chatWindowFactory_, treeWidgetFactory_, nickResolver_, presenceOracle_, serverDiscoInfo_, presenceSender_, uiEventStream_, chatListWindowFactory_, useDelayForLatency_);  		nickResolver_->setMUCRegistry(chatsManager_);  		client_->onMessageReceived.connect(boost::bind(&ChatsManager::handleIncomingMessage, chatsManager_, _1));  		chatsManager_->setAvatarManager(avatarManager_); diff --git a/Swift/Controllers/MainController.h b/Swift/Controllers/MainController.h index 5ed3641..2ed922c 100644 --- a/Swift/Controllers/MainController.h +++ b/Swift/Controllers/MainController.h @@ -62,7 +62,7 @@ namespace Swift {  	class MainController {  		public: -			MainController(ChatWindowFactory* chatWindowFactory, MainWindowFactory *mainWindowFactory, LoginWindowFactory *loginWindowFactory, TreeWidgetFactory* treeWidgetFactory, EventWindowFactory* eventWindowFactory, SettingsProvider *settings, Application* application, SystemTray* systemTray, SoundPlayer* soundPlayer, XMLConsoleWidgetFactory* xmlConsoleWidgetFactory, ChatListWindowFactory* chatListWindowFactory_); +			MainController(ChatWindowFactory* chatWindowFactory, MainWindowFactory *mainWindowFactory, LoginWindowFactory *loginWindowFactory, TreeWidgetFactory* treeWidgetFactory, EventWindowFactory* eventWindowFactory, SettingsProvider *settings, Application* application, SystemTray* systemTray, SoundPlayer* soundPlayer, XMLConsoleWidgetFactory* xmlConsoleWidgetFactory, ChatListWindowFactory* chatListWindowFactory_, bool useDelayForLatency);  			~MainController(); @@ -127,5 +127,6 @@ namespace Swift {  			String certificateFile_;  			ChatListWindowFactory* chatListWindowFactory_;  			boost::shared_ptr<ErrorEvent> lastDisconnectError_; +			bool useDelayForLatency_;  	};  } diff --git a/Swift/QtUI/QtSwift.cpp b/Swift/QtUI/QtSwift.cpp index 258a7b6..fc5f4cb 100644 --- a/Swift/QtUI/QtSwift.cpp +++ b/Swift/QtUI/QtSwift.cpp @@ -40,9 +40,19 @@ namespace Swift{  #define SWIFT_APPCAST_URL ""  #endif +po::options_description QtSwift::getOptionsDescription() { +	po::options_description result("Options"); +	result.add_options() +		("help", "produce help message") +		("netbook-mode", "use netbook mode display") +		("latency-debug", "use latency debugging") +		; +	return result; +} + -QtSwift::QtSwift(bool netbookMode) : autoUpdater_(NULL) { -	if (netbookMode) { +QtSwift::QtSwift(po::variables_map options) : autoUpdater_(NULL) { +	if (options.count("netbook-mode")) {  		splitter_ = new QSplitter();  	} else {  		splitter_ = NULL; @@ -67,7 +77,7 @@ QtSwift::QtSwift(bool netbookMode) : autoUpdater_(NULL) {  	if (splitter_) {  		splitter_->show();  	} -	mainController_ = new MainController(chatWindowFactory_, rosterWindowFactory_, loginWindowFactory_, treeWidgetFactory_, eventWindowFactory_, settings_, application_, systemTray_, soundPlayer_, xmlConsoleWidgetFactory_, chatListWindowFactory_); +		mainController_ = new MainController(chatWindowFactory_, rosterWindowFactory_, loginWindowFactory_, treeWidgetFactory_, eventWindowFactory_, settings_, application_, systemTray_, soundPlayer_, xmlConsoleWidgetFactory_, chatListWindowFactory_, options.count("latency-debug") > 0);  	PlatformAutoUpdaterFactory autoUpdaterFactory;  	if (autoUpdaterFactory.isSupported()) { diff --git a/Swift/QtUI/QtSwift.h b/Swift/QtUI/QtSwift.h index 2ebc3d5..72343d8 100644 --- a/Swift/QtUI/QtSwift.h +++ b/Swift/QtUI/QtSwift.h @@ -7,6 +7,9 @@  #ifndef SWIFT_QtSwift_H  #define SWIFT_QtSwift_H +#include <boost/program_options/variables_map.hpp> +#include <boost/program_options/options_description.hpp> +  #include "Swiften/Base/String.h"  #include "Swiften/EventLoop/Qt/QtEventLoop.h"  #include "QtLoginWindowFactory.h" @@ -14,6 +17,8 @@  #include "QtChatWindowFactory.h"  #include "QtSettingsProvider.h" +namespace po = boost::program_options; +  class QSplitter;  namespace Swift { @@ -33,7 +38,8 @@ namespace Swift {  	class QtSwift : public QObject {  		Q_OBJECT  		public: -			QtSwift(bool netbookMode); +			QtSwift(po::variables_map options); +			static po::options_description getOptionsDescription();  			~QtSwift();  		private:  			MainController *mainController_; diff --git a/Swift/QtUI/main.cpp b/Swift/QtUI/main.cpp index 971d536..f8b805c 100644 --- a/Swift/QtUI/main.cpp +++ b/Swift/QtUI/main.cpp @@ -4,13 +4,21 @@   * See Documentation/Licenses/GPLv3.txt for more information.   */ +#include <boost/program_options/options_description.hpp> +#include <boost/program_options/variables_map.hpp> +#include <boost/program_options.hpp> + +  #include <QApplication>  #include "QtSwift.h"  int main(int argc, char* argv[]) {  	QApplication app(argc, argv); -	bool netbookMode = argc > 1; -	Swift::QtSwift swift(netbookMode); +	boost::program_options::options_description desc = Swift::QtSwift::getOptionsDescription(); +	boost::program_options::variables_map vm;	 +	boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm); +	boost::program_options::notify(vm); +	Swift::QtSwift swift(vm);  	return app.exec();  } diff --git a/Swiften/Elements/Stanza.h b/Swiften/Elements/Stanza.h index aa1cf4f..f42048e 100644 --- a/Swiften/Elements/Stanza.h +++ b/Swiften/Elements/Stanza.h @@ -32,6 +32,19 @@ namespace Swift {  				return boost::shared_ptr<T>();  			} +			template<typename T>  +			std::vector< boost::shared_ptr<T> > getPayloads() const { +				std::vector< boost::shared_ptr<T> > results; +				foreach (const boost::shared_ptr<Payload>& i, payloads_) { +					boost::shared_ptr<T> result(boost::dynamic_pointer_cast<T>(i)); +					if (result) { +						results.push_back(result); +					} +				} +				return results; +			} + +  			const std::vector< boost::shared_ptr<Payload> >& getPayloads() const {  				return payloads_;  			} diff --git a/Swiften/Elements/UnitTest/StanzaTest.cpp b/Swiften/Elements/UnitTest/StanzaTest.cpp index fb9b8a5..1e7e9c4 100644 --- a/Swiften/Elements/UnitTest/StanzaTest.cpp +++ b/Swiften/Elements/UnitTest/StanzaTest.cpp @@ -19,6 +19,7 @@ class StanzaTest : public CppUnit::TestFixture  		CPPUNIT_TEST_SUITE(StanzaTest);  		CPPUNIT_TEST(testConstructor_Copy);  		CPPUNIT_TEST(testGetPayload); +		CPPUNIT_TEST(testGetPayloads);  		CPPUNIT_TEST(testGetPayload_NoSuchPayload);  		CPPUNIT_TEST(testDestructor);  		CPPUNIT_TEST(testDestructor_Copy); @@ -113,6 +114,21 @@ class StanzaTest : public CppUnit::TestFixture  			CPPUNIT_ASSERT(!p);  		} +		void testGetPayloads() { +			Message m; +			boost::shared_ptr<MyPayload2> payload1(new MyPayload2()); +			boost::shared_ptr<MyPayload2> payload2(new MyPayload2()); +			m.addPayload(boost::shared_ptr<MyPayload1>(new MyPayload1())); +			m.addPayload(payload1); +			m.addPayload(boost::shared_ptr<MyPayload3>(new MyPayload3())); +			m.addPayload(payload2); + +			CPPUNIT_ASSERT_EQUAL((size_t)2, m.getPayloads<MyPayload2>().size()); +			CPPUNIT_ASSERT_EQUAL(payload1, m.getPayloads<MyPayload2>()[0]); +			CPPUNIT_ASSERT_EQUAL(payload2, m.getPayloads<MyPayload2>()[1]); +		} + +  		void testUpdatePayload_ExistingPayload() {  			Message m;  			m.addPayload(boost::shared_ptr<MyPayload1>(new MyPayload1())); | 
 Swift
 Swift