⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmdline_test.cpp

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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/program_options/cmdline.hpp>#include <boost/program_options/options_description.hpp>#include <boost/program_options/detail/cmdline.hpp>using namespace boost::program_options;using boost::program_options::detail::cmdline;#include <iostream>#include <sstream>#include <vector>#include <cassert>using namespace std;#include "minitest.hpp"/* To facilitate testing, declare a number of error codes. Otherwise,   we'd have to specify the type of exception that should be thrown.*/const int s_success = 0;const int s_unknown_option = 1;const int s_ambiguous_option = 2;const int s_long_not_allowed = 3;const int s_long_adjacent_not_allowed = 4;const int s_short_adjacent_not_allowed = 5;const int s_empty_adjacent_parameter = 6;const int s_missing_parameter = 7;const int s_extra_parameter = 8;int translate_syntax_error_kind(invalid_command_line_syntax::kind_t k){    invalid_command_line_syntax::kind_t table[] = {        invalid_command_line_syntax::long_not_allowed,        invalid_command_line_syntax::long_adjacent_not_allowed,        invalid_command_line_syntax::short_adjacent_not_allowed,        invalid_command_line_syntax::empty_adjacent_parameter,        invalid_command_line_syntax::missing_parameter,        invalid_command_line_syntax::extra_parameter,    };    invalid_command_line_syntax::kind_t *b, *e, *i;    b = table;    e = table + sizeof(table)/sizeof(table[0]);    i = std::find(b, e, k);    assert(i != e);    return std::distance(b, i) + 3;}struct test_case {    const char* input;    int expected_status;    const char* expected_result;};/* Parses the syntax description in 'syntax' and initialized   'cmd' accordingly'    The "boost::program_options" in parameter type is needed because CW9    has std::detail and it causes an ambiguity.*/void apply_syntax(options_description& desc,                   const char* syntax){       string s;    stringstream ss;    ss << syntax;    while(ss >> s) {        value_semantic* v = 0;                if (*(s.end()-1) == '=') {            v = value<string>();            s.resize(s.size()-1);        } else if (*(s.end()-1) == '?') {            //v = value<string>()->implicit();            v = value<string>();            s.resize(s.size()-1);        } else if (*(s.end()-1) == '*') {            v = value<vector<string> >()->multitoken();            s.resize(s.size()-1);        } else if (*(s.end()-1) == '+') {            v = value<vector<string> >()->multitoken();            s.resize(s.size()-1);        }        if (v) {            desc.add_options()                (s.c_str(), v, "");        } else {            desc.add_options()                (s.c_str(), "");        }    }}void test_cmdline(const char* syntax,                   command_line_style::style_t style,                  const test_case* cases){    for (int i = 0; cases[i].input; ++i) {        // Parse input        vector<string> xinput;        {            string s;            stringstream ss;            ss << cases[i].input;            while (ss >> s) {                xinput.push_back(s);            }        }        options_description desc;        apply_syntax(desc, syntax);        cmdline cmd(xinput);        cmd.style(style);        cmd.set_options_description(desc);        string result;        int status = 0;        try {            vector<option> options = cmd.run();            for(unsigned i = 0; i < options.size(); ++i)            {                option opt = options[i];                if (opt.position_key != -1) {                    if (!result.empty())                        result += " ";                    result += opt.value[0];                } else {                    if (!result.empty())                        result += " ";                    result += opt.string_key + ":";                    for (size_t j = 0; j < opt.value.size(); ++j) {                        if (j != 0)                            result += "-";                        result += opt.value[j];                    }                                    }            }        }        catch(unknown_option& e) {            status = s_unknown_option;        }        catch(ambiguous_option& e) {            status = s_ambiguous_option;        }        catch(invalid_command_line_syntax& e) {            status = translate_syntax_error_kind(e.kind());        }        BOOST_CHECK_EQUAL(status, cases[i].expected_status);        BOOST_CHECK_EQUAL(result, cases[i].expected_result);    }}void test_long_options(){    using namespace command_line_style;    cmdline::style_t style = cmdline::style_t(        allow_long | long_allow_adjacent);    test_case test_cases1[] = {        // Test that long options are recognized and everything else        // is treated like arguments        {"--foo foo -123 /asd", s_success, "foo: foo -123 /asd"},        // Unknown option        {"--unk", s_unknown_option, ""},        // Test that abbreviated names do not work        {"--fo", s_unknown_option, ""},        // Test for disallowed parameter        {"--foo=13", s_extra_parameter, ""},        // Test option with required parameter        {"--bar=", s_empty_adjacent_parameter, ""},        {"--bar", s_missing_parameter, ""},        {"--bar=123", s_success, "bar:123"},        {0}    };    test_cmdline("foo bar=", style, test_cases1);    style = cmdline::style_t(        allow_long | long_allow_next);    test_case test_cases2[] = {        {"--bar 10", s_success, "bar:10"},        {"--bar", s_missing_parameter,  ""},        // Since --bar accepts a parameter, --foo is        // considered a value, even though it looks like        // an option.        {"--bar --foo", s_success, "bar:--foo"},        {0}    };    test_cmdline("foo bar=", style, test_cases2);    style = cmdline::style_t(        allow_long | long_allow_adjacent        | long_allow_next);    test_case test_cases3[] = {        {"--bar=10", s_success, "bar:10"},        {"--bar 11", s_success, "bar:11"},        {0}    };    test_cmdline("foo bar=", style, test_cases3);    style = cmdline::style_t(        allow_long | long_allow_adjacent        | long_allow_next | case_insensitive);// FIXME: restore#if 0    // Test case insensitive style.    // Note that option names are normalized to lower case.    test_case test_cases4[] = {        {"--foo", s_success, "foo:"},        {"--Foo", s_success, "foo:"},        {"--bar=Ab", s_success, "bar:Ab"},        {"--Bar=ab", s_success, "bar:ab"},        {"--giz", s_success, "Giz:"},        {0}    };    test_cmdline("foo bar= baz? Giz", style, test_cases4);#endif}void test_short_options(){    using namespace command_line_style;    cmdline::style_t style;    style = cmdline::style_t(        allow_short | allow_dash_for_short         | short_allow_adjacent);    test_case test_cases1[] = {        {"-d d /bar", s_success, "-d: d /bar"},        // This is treated as error when long options are disabled        {"--foo", s_success, "--foo"},        {"-d13", s_extra_parameter, ""},        {"-f14", s_success, "-f:14"},        {"-g -f1", s_success, "-g: -f:1"},        {"-f", s_missing_parameter, ""},        {0}    };    test_cmdline(",d ,f= ,g", style, test_cases1);    style = cmdline::style_t(        allow_short | allow_dash_for_short        | short_allow_next);    test_case test_cases2[] = {        {"-f 13", s_success, "-f:13"},        {"-f -13", s_success, "-f:-13"},        {"-f", s_missing_parameter, ""},        {"-f /foo", s_success, "-f:/foo"},        {"-f -d", s_success, "-f:-d"},        {0}    };    test_cmdline(",d ,f=", style, test_cases2);    style = cmdline::style_t(        allow_short | short_allow_next        | allow_dash_for_short | short_allow_adjacent);    test_case test_cases3[] = {        {"-f10", s_success, "-f:10"},        {"-f 10", s_success, "-f:10"},        {"-f -d", s_success, "-f:-d"},        {0}    };    test_cmdline(",d ,f=", style, test_cases3);    style = cmdline::style_t(        allow_short | short_allow_next        | allow_dash_for_short        | short_allow_adjacent | allow_sticky);    test_case test_cases4[] = {        {"-de", s_success, "-d: -e:"},        {"-df10", s_success, "-d: -f:10"},        // FIXME: review        //{"-d12", s_extra_parameter, ""},        {"-f12", s_success, "-f:12"},        {"-fe", s_success, "-f:e"},        {0}    };    test_cmdline(",d ,f= ,e", style, test_cases4);}void test_dos_options(){    using namespace command_line_style;    cmdline::style_t style;    style = cmdline::style_t(        allow_short        | allow_slash_for_short | short_allow_adjacent);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -