idl.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 538 行 · 第 1/2 页

CPP
538
字号
/*=============================================================================    Boost.Wave: A Standard compliant C++ preprocessor library    Sample: IDL oriented preprocessor        http://www.boost.org/    Copyright (c) 2001-2008 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 namesusing namespace boost::spirit::classic;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 versionint 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 statementint 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-2008 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 preprocessingint do_actual_work (std::string file_name, po::variables_map const &vm){// current file position is saved for exception handlingboost::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 + =
减小字号Ctrl + -
显示快捷键?