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

📄 idl.cpp

📁 C++的一个好库。。。现在很流行
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*=============================================================================
    Boost.Wave: A Standard compliant C++ preprocessor library

    Sample: IDL oriented preprocessor
    
    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)
=============================================================================*/

#include "idl.hpp"                  // global configuration

#include <boost/assert.hpp>
#include <boost/program_options.hpp>
#include <boost/filesystem/path.hpp>

///////////////////////////////////////////////////////////////////////////////
//  Include Wave itself
#include <boost/wave.hpp>

///////////////////////////////////////////////////////////////////////////////
//  Include the lexer related stuff
#include <boost/wave/cpplexer/cpp_lex_token.hpp>  // token type
#include "idllexer/idl_lex_iterator.hpp"          // lexer type

///////////////////////////////////////////////////////////////////////////////
//  include lexer specifics, import lexer names
//
#if BOOST_WAVE_SEPARATE_LEXER_INSTANTIATION == 0
#include "idllexer/idl_re2c_lexer.hpp"
#endif 

///////////////////////////////////////////////////////////////////////////////
//  include the grammar definitions, if these shouldn't be compiled separately
//  (ATTENTION: _very_ large compilation times!)
//
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION == 0
#include <boost/wave/grammars/cpp_intlit_grammar.hpp>
#include <boost/wave/grammars/cpp_chlit_grammar.hpp>
#include <boost/wave/grammars/cpp_grammar.hpp>
#include <boost/wave/grammars/cpp_expression_grammar.hpp>
#include <boost/wave/grammars/cpp_predef_macros_grammar.hpp>
#include <boost/wave/grammars/cpp_defined_grammar.hpp>
#endif 

///////////////////////////////////////////////////////////////////////////////
//  import required names
using namespace boost::spirit;

using std::string;
using std::pair;
using std::vector;
using std::getline;
using std::ifstream;
using std::cout;
using std::cerr;
using std::endl;
using std::ostream;
using std::istreambuf_iterator;

namespace po = boost::program_options;
namespace fs = boost::filesystem;

///////////////////////////////////////////////////////////////////////////////
// print the current version
int print_version()
{
    typedef boost::wave::idllexer::lex_iterator<
            boost::wave::cpplexer::lex_token<> >
        lex_iterator_type;
    typedef boost::wave::context<std::string::iterator, lex_iterator_type>
        context_type;
        
    string version (context_type::get_version_string());
    cout 
        << version.substr(1, version.size()-2)  // strip quotes
        << " (" << IDL_VERSION_DATE << ")"      // add date
        << endl;
    return 0;                       // exit app
}

///////////////////////////////////////////////////////////////////////////////
// print the copyright statement
int print_copyright()
{
    char const *copyright[] = {
        "",
        "Sample: IDL oriented preprocessor",
        "Based on: Wave, A Standard conformant C++ preprocessor library",
        "It is hosted by 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)
        cout << copyright[i] << endl;
        
    return 0;                       // exit app
}

///////////////////////////////////////////////////////////////////////////////
namespace cmd_line_util {

    // Additional command line parser which interprets '@something' as an 
    // option "config-file" with the value "something".
    pair<string, string> at_option_parser(string const&s)
    {
        if ('@' == s[0]) 
            return std::make_pair(string("config-file"), s.substr(1));
        else
            return pair<string, string>();
    }

    // class, which keeps include file information read from the command line
    class include_paths {
    public:
        include_paths() : seen_separator(false) {}

        vector<string> paths;       // stores user paths
        vector<string> syspaths;    // stores system paths
        bool seen_separator;        // command line contains a '-I-' option

        // Function which validates additional tokens from command line.
        static void 
        validate(boost::any &v, vector<string> const &tokens)
        {
            if (v.empty())
                v = boost::any(include_paths());

            include_paths *p = boost::any_cast<include_paths>(&v);

            BOOST_ASSERT(p);
            // Assume only one path per '-I' occurrence.
            string t = tokens[0];
            if (t == "-") {
            // found -I- option, so switch behaviour
                p->seen_separator = true;
            } 
            else if (p->seen_separator) {
            // store this path as a system path
                p->syspaths.push_back(t); 
            } 
            else {
            // store this path as an user path
                p->paths.push_back(t);
            }            
        }
    };

    // Read all options from a given config file, parse and add them to the
    // given variables_map
    void read_config_file_options(string const &filename, 
        po::options_description const &desc, po::variables_map &vm,
        bool may_fail = false)
    {
    ifstream ifs(filename.c_str());

        if (!ifs.is_open()) {
            if (!may_fail) {
                cerr << filename 
                    << ": command line warning: config file not found"
                    << endl;
            }
            return;
        }
        
    vector<string> options;
    string line;

        while (std::getline(ifs, line)) {
        // skip empty lines
            string::size_type pos = line.find_first_not_of(" \t");
            if (pos == string::npos) 
                continue;

        // skip comment lines
            if ('#' != line[pos])
                options.push_back(line);
        }

        if (options.size() > 0) {
            using namespace boost::program_options::command_line_style;
            po::store(po::command_line_parser(options)
                .options(desc).style(unix_style).run(), vm);
            po::notify(vm);
        }
    }

    // predicate to extract all positional arguments from the command line
    struct is_argument {
        bool operator()(po::option const &opt)
        {
          return (opt.position_key == -1) ? true : false;
        }
    };

///////////////////////////////////////////////////////////////////////////////
}

///////////////////////////////////////////////////////////////////////////////
//
//  Special validator overload, which allows to handle the -I- syntax for
//  switching the semantics of an -I option.
//
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace program_options {

  void validate(boost::any &v, std::vector<std::string> const &s,
      cmd_line_util::include_paths *, int) 
  {
      cmd_line_util::include_paths::validate(v, s);
  }

}}  // namespace boost::program_options

///////////////////////////////////////////////////////////////////////////////
//  do the actual preprocessing
int 
do_actual_work (std::string file_name, po::variables_map const &vm)
{
// current file position is saved for exception handling
boost::wave::util::file_position_type current_position;

    try {
    // process the given file
    ifstream instream(file_name.c_str());
    string instring;

        if (!instream.is_open()) {
            cerr << "waveidl: could not open input file: " << file_name << endl;
            return -1;
        }
        instream.unsetf(std::ios::skipws);
        
#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
        // this is known to be very slow for large files on some systems
        copy (istream_iterator<char>(instream),
              istream_iterator<char>(), 
              inserter(instring, instring.end()));
#else
        instring = string(istreambuf_iterator<char>(instream.rdbuf()),
                          istreambuf_iterator<char>());
#endif 

    //  This sample uses the lex_token type predefined in the Wave library, but 
    //  but uses a custom lexer type.
        typedef boost::wave::idllexer::lex_iterator<
                boost::wave::cpplexer::lex_token<> >
            lex_iterator_type;
        typedef boost::wave::context<std::string::iterator, lex_iterator_type> 
            context_type;

    // The C++ preprocessor iterators shouldn't be constructed directly. They 
    // are to be generated through a boost::wave::context<> object. This 
    // boost::wave::context object is additionally to be used to initialize and 
    // define different parameters of the actual preprocessing.
    // The preprocessing of the input stream is done on the fly behind the 
    // scenes during iteration over the context_type::iterator_type stream.
    context_type ctx (instring.begin(), instring.end(), file_name.c_str());

    // add include directories to the system include search paths
        if (vm.count("sysinclude")) {
            vector<string> const &syspaths = 
                vm["sysinclude"].as<vector<string> >();

⌨️ 快捷键说明

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