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

📄 testwave_app.cpp

📁 C++的一个好库。。。现在很流行
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                retval = false;
            }
            else if (debuglevel > 4) {
                std::cerr 
                    << filename << ": succeeded" << std::endl
                    << "result: " << std::endl << error << std::endl;
            }
            else if (debuglevel > 3) {
            // caught the expected error message
                std::cerr << filename << ": succeeded" << std::endl;
            }
        }
        return retval;
    }
    else {
        std::cerr 
            << filename << ": no information about expected results found"
            << std::endl;
    }
    return false;
}

///////////////////////////////////////////////////////////////////////////////
//
//  print the current version of this program
//
///////////////////////////////////////////////////////////////////////////////
int 
testwave_app::print_version()
{
// get time of last compilation of this file
boost::wave::util::time_conversion_helper compilation_time(__DATE__ " " __TIME__);

// calculate the number of days since Feb 12 2005 
// (the day the testwave project was started)
std::tm first_day;

    using namespace std;      // some platforms have memset in namespace std
    memset (&first_day, 0, sizeof(std::tm));
    first_day.tm_mon = 1;           // Feb
    first_day.tm_mday = 12;         // 12
    first_day.tm_year = 105;        // 2005

long seconds = long(std::difftime(compilation_time.get_time(), 
    std::mktime(&first_day)));

    std::cout 
        << TESTWAVE_VERSION_MAJOR << '.' 
        << TESTWAVE_VERSION_MINOR << '.'
        << TESTWAVE_VERSION_SUBMINOR << '.'
        << seconds/(3600*24)        // get number of days from seconds
        << std::endl;
    return 0;                       // exit app
}

///////////////////////////////////////////////////////////////////////////////
//
//  print the copyright statement
//
///////////////////////////////////////////////////////////////////////////////
int 
testwave_app::print_copyright()
{
    char const *copyright[] = {
        "",
        "Testwave: A test driver for the Boost.Wave C++ preprocessor library",
        "http://www.boost.org/",
        "",
        "Copyright (c) 2001-2005 Hartmut Kaiser, 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)",
        0
    };
    
    for (int i = 0; 0 != copyright[i]; ++i)
        std::cout << copyright[i] << std::endl;
        
    return 0;                       // exit app
}

///////////////////////////////////////////////////////////////////////////////
//
//  Read the given file into a string
//
///////////////////////////////////////////////////////////////////////////////
bool 
testwave_app::read_file(std::string const& filename, std::string& instr)
{
// open the given file and report error, if appropriate
    std::ifstream instream(filename.c_str());
    if (!instream.is_open()) {
        std::cerr << "testwave: could not open input file: " 
                  << filename << std::endl;
        return false;
    }
    else if (9 == debuglevel) {
        std::cerr << "read_file: succeeded to open input file: " 
                  << filename << std::endl;
    }
    instream.unsetf(std::ios::skipws);

// read the input file into a string
    
#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
// this is known to be very slow for large files on some systems
    std::copy (std::istream_iterator<char>(instream),
        std::istream_iterator<char>(), 
        std::inserter(instr, instr.end()));
#else
    instr = std::string(std::istreambuf_iterator<char>(instream.rdbuf()),
        std::istreambuf_iterator<char>());
#endif 
    
    if (9 == debuglevel) {
        std::cerr << "read_file: succeeded to read input file: " 
                  << filename << std::endl;
    }
    return true;
}

///////////////////////////////////////////////////////////////////////////////
//
//  This explicit template instantiation is needed for the function
//  extract_expected_output below, which needs the lexer to be instantiated 
//  with a std::string::const_iterator template parameter.
//
///////////////////////////////////////////////////////////////////////////////
template 
struct boost::wave::cpplexer::new_lexer_gen<std::string::const_iterator>;

namespace {

    std::string const& trim_whitespace(std::string& value)
    {
        std::string::size_type first = value.find_first_not_of(" \t");
        std::string::size_type last = std::string::npos;
        
        if (std::string::npos == first) 
            value.clear();
        else {
            last = value.find_last_not_of(" \t")+1;
            assert(std::string::npos != last);
            value = value.substr(first, last-first);
        }
        return value;
    }
}

///////////////////////////////////////////////////////////////////////////////
//
//  Extract special information from comments marked with the given letter
//
///////////////////////////////////////////////////////////////////////////////
bool 
testwave_app::extract_special_information(std::string const& filename, 
    std::string const& instr, char flag, std::string& content)
{
    if (9 == debuglevel) {
        std::cerr << "extract_special_information: extracting special information ('" 
                  << flag << "') from input file: " << filename << std::endl;
    }

// tokenize the input data into C++ tokens using the C++ lexer
    typedef boost::wave::cpplexer::lex_token<> token_type;
    typedef boost::wave::cpplexer::lex_iterator<token_type> lexer_type;
    typedef token_type::position_type position_type;
    
    boost::wave::language_support const lang_opts = 
        (boost::wave::language_support)(
            boost::wave::support_variadics | boost::wave::support_long_long |
            boost::wave::support_option_no_character_validation |
            boost::wave::support_option_convert_trigraphs);
    
    position_type pos(filename.c_str());
    lexer_type it = lexer_type(instr.begin(), instr.end(), pos, lang_opts);
    lexer_type end = lexer_type();

    try {
    // look for C or C++ comments starting with the special character
        for (/**/; it != end; ++it) {
            using namespace boost::wave;
            token_id id = token_id(*it);
            if (T_CCOMMENT == id) {
                std::string value = (*it).get_value().c_str();
                if (flag == value[2]) {
                    std::string thiscontent(value.substr(3, value.size()-5));
                    
                    if (9 == debuglevel) {
                        std::cerr << "extract_special_information: extracted: " 
                                  << thiscontent << std::endl;
                    }
                    trim_whitespace(thiscontent);
                    content += thiscontent;
                }
            }
            else if (T_CPPCOMMENT == id) {
                std::string value = (*it).get_value().c_str();
                if (flag == value[2]) {
                    std::string thiscontent(value.substr((' ' == value[3]) ? 4 : 3));

                    if (9 == debuglevel) {
                        std::cerr << "extract_special_information: extracted: " 
                                  << thiscontent;
                    }
                    trim_whitespace(content);
                    content += thiscontent;
                }
            }
        }
    }
    catch (boost::wave::cpplexer::lexing_exception const &e) {
    // some lexing error
        std::cerr 
            << e.file_name() << "(" << e.line_no() << "): "
            << e.description() << std::endl;
        return false;
    }

    if (9 == debuglevel) {
        std::cerr << "extract_special_information: succeeded extracting special information ('" 
                  << flag << "')" << std::endl;
    }
    return true;
}

///////////////////////////////////////////////////////////////////////////////
//
//  Extract the expected output from the given input data
//
//  The expected output has to be provided inside of special comments which
//  start with a capital 'R'. All such comments are concatenated and returned
//  through the parameter 'expected'.
//
///////////////////////////////////////////////////////////////////////////////
inline bool 
testwave_app::extract_expected_output(std::string const& filename, 
    std::string const& instr, std::string& expected)
{
    return extract_special_information(filename, instr, 'R', expected);
}

///////////////////////////////////////////////////////////////////////////////
//
//  Extracts the required preprocessing options from the given input data and
//  initialises the given Wave context object accordingly. 
//  We allow the same (applicable) options to be used as are valid for the wave 
//  driver executable.
//
///////////////////////////////////////////////////////////////////////////////
template <typename Context>
bool 
testwave_app::extract_options(std::string const& filename, 
    std::string const& instr, Context& ctx)
{
    if (9 == debuglevel) {
        std::cerr << "extract_options: extracting options" << std::endl;
    }

//  extract the required information from the comments flagged by a 
//  capital 'O'
    std::string options;
    if (!extract_special_information(filename, instr, 'O', options))
        return false;

    try {        
    //  parse the configuration information into a program_options_description
    //  object
        po::variables_map local_vm;
        cmd_line_utils::read_config_options(debuglevel, options, desc_options, local_vm);
        initialise_options(ctx, local_vm);
    }
    catch (std::exception const &e) {
        std::cerr << filename << ": exception caught: " << e.what() 
                  << std::endl;
        return false;
    }
    
    if (9 == debuglevel) {
        std::cerr << "extract_options: succeeded extracting options" 
                  << std::endl;
    }

    return true;
}

namespace {

    template <typename T>
    inline T const&
    variables_map_as(po::variable_value const& v, T*)
    {
#if (__GNUC__ == 3 && (__GNUC_MINOR__ == 2 || __GNUC_MINOR__ == 3)) || \
    BOOST_WORKAROUND(__MWERKS__, < 0x3200)
// gcc 3.2.x and  3.3.x choke on vm[...].as<...>()
// CW 8.3 has problems with the v.as<T>() below
        T const* r = boost::any_cast<T>(&v.value());
        if (!r)
            throw boost::bad_any_cast();
        return *r;
#else
        return v.as<T>();
#endif
    }
}

template <typename Context>
bool 
testwave_app::initialise_options(Context& ctx, po::variables_map const& vm)
{
    if (9 == debuglevel) {
        std::cerr << "initialise_options: initialising options" << std::endl;
    }

//  initialise the given context from the parsed options
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
// enable C99 mode, if appropriate (implies variadics)
    if (vm.count("c99")) {
        if (9 == debuglevel) {
            std::cerr << "initialise_options: option: c99" << std::endl;
        }
        ctx.set_language(boost::wave::support_c99);
    }
    else if (vm.count("variadics")) {
    // enable variadics and placemarkers, if appropriate
        if (9 == debuglevel) {
            std::cerr << "initialise_options: option: variadics" << std::endl;
        }
        ctx.set_language(boost::wave::enable_variadics(ctx.get_language()));
    }
#endif // BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0

// enable long_long mode, if appropriate
    if (vm.count("long_long")) {
        if (9 == debuglevel) {
            std::cerr << "initialise_options: option: long_long" << std::endl;
        }
        ctx.set_language(boost::wave::enable_long_long(ctx.get_language()));
    }
    
// enable preserving comments mode, if appropriate
    if (vm.count("preserve")) {
        if (9 == debuglevel) {
            std::cerr << "initialise_options: option: preserve" << std::endl;
        }
        ctx.set_language(
            boost::wave::enable_preserve_comments(ctx.get_language()));
    }
    
// enable trigraph conversion
    ctx.set_language(boost::wave::set_support_options(ctx.get_language(), 
        (boost::wave::language_support)(
            boost::wave::get_support_options(ctx.get_language()) | 
            boost::wave::support_option_convert_trigraphs |
            boost::wave::support_option_single_line)
        )
    );

//  add include directories to the system include search paths
    if (vm.count("sysinclude")) {
    std::vector<std::string> const& syspaths = 
        variables_map_as(vm["sysinclude"], (std::vector<std::string> *)NULL);
    
        std::vector<std::string>::const_iterator end = syspaths.end();
        for (std::vector<std::string>::const_iterator cit = syspaths.begin(); 
              cit != end; ++cit)
        {
            if (9 == debuglevel) {
                std::cerr << "initialise_options: option: -S" << *cit 

⌨️ 快捷键说明

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