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 + -
显示快捷键?