std::string write_ledger_as_pdf(Ledger const& ledger, fs::path const& filepath) { throw_if_interdicted(ledger); fs::path print_dir(configurable_settings::instance().print_directory()); fs::path real_filepath(orthodox_filename(filepath.leaf())); LMI_ASSERT(fs::portable_name(real_filepath.string())); if(contains(global_settings::instance().pyx(), "xml")) { fs::path xml_file = unique_filepath(print_dir / real_filepath, ".xml"); fs::ofstream ofs(xml_file, ios_out_trunc_binary()); ledger.write(ofs); ofs.close(); if(!ofs.good()) { fatal_error() << "Unable to write output file '" << xml_file << "'." << LMI_FLUSH ; } } fs::path xml_fo_file = unique_filepath(print_dir / real_filepath, ".fo.xml"); fs::ofstream ofs(xml_fo_file, ios_out_trunc_binary()); ledger.write_xsl_fo(ofs); ofs.close(); if(!ofs.good()) { fatal_error() << "Unable to write output file '" << xml_fo_file << "'." << LMI_FLUSH ; } fs::path pdf_out_file = unique_filepath(print_dir / real_filepath, ".pdf"); std::ostringstream oss; oss << configurable_settings::instance().xsl_fo_command() << " -fo " << '"' << xml_fo_file << '"' << " -pdf " << '"' << pdf_out_file << '"' ; system_command(oss.str()); return pdf_out_file.string(); }
bool bcp_implementation::is_binary_file(const fs::path& p) { if(m_cvs_mode || m_svn_mode) { std::map<fs::path, bool, path_less>::iterator pos = m_cvs_paths.find(p); if(pos != m_cvs_paths.end()) return pos->second; } static const boost::regex e( ".*\\." "(?:" "c|cxx|cpp|h|hxx|hpp|inc|html?|css|mak|in" ")" "|" "(Jamfile|makefile|configure)", boost::regex::perl | boost::regex::icase); return !boost::regex_match(p.leaf(), e); }
static void init_library_scanner(const fs::path& p, bool cvs_mode, const std::string& libname, bool recurse = false) { /* if(free_function_names.count(libname) == 0) { free_function_names[libname] = "[\\x0]"; class_names[libname] = "[\\x0]"; variable_names[libname] = "[\\x0]"; } */ // // Don't add files created by build system: // if((p.leaf() == "bin") || (p.leaf() == "bin-stage")) return; // // Don't add version control directories: // if((p.leaf() == "CVS") || (p.leaf() == ".svn")) return; // // don't add directories not under version control: // if(cvs_mode && !fs::exists(p / "CVS/Entries")) return; if(cvs_mode && !fs::exists(p / ".svn/entries")) return; // // Enumerate files and directories: // fs::directory_iterator i(p); fs::directory_iterator j; while(i != j) { if(fs::is_directory(*i)) init_library_scanner(*i, cvs_mode, libname, true); if(bcp_implementation::is_source_file(*i)) { static boost::regex function_scanner( "(?|" // Branch reset group "(?:\\<\\w+\\>[^>;{},:]*)" // Return type "(?:" "(\\<\\w+\\>)" // Maybe class name "\\s*" "(?:<[^>;{]*>)?" // Maybe template specialisation "::\\s*)?" "(\\<(?!throw|if|while|for|catch)\\w+\\>)" // function name "\\s*" "\\(" "[^\\(\\);{}]*" // argument list "\\)" "\\s*" "\\{" // start of definition "|" "(\\<\\w+\\>)" // Maybe class name "\\s*" "(?:<[^>;{]*>)?" // Maybe template specialisation "::\\s*" "~?\\1" // function name, same as class name "\\s*" "\\(" "[^\\(\\);{}]*" // argument list "\\)" "\\s*" "\\{" // start of definition ")" // end branch reset ); fileview view(*i); boost::regex_iterator<const char*> a(view.begin(), view.end(), function_scanner); boost::regex_iterator<const char*> b; while(a != b) { if((*a)[1].matched) { std::string n = a->str(1); class_names[libname].insert(n); } else { std::string n = a->str(2); free_function_names[libname].insert(n); } ++a; } } ++i; } if(recurse == false) { // // Build the regular expressions: // const char* e1 = "^(?>[[:blank:]]*)(?!#)[^;{}\\r\\n]*" "(?|" "(?:class|struct)[^:;{}#]*" "("; // list of class names goes here... const char* e2 = ")\\s*(?:<[^;{>]*>\\s*)?(?::[^;{]*)?\\{" "|" "\\<(?!return)\\w+\\>[^:;{}#=<>!~%.\\w]*("; // List of function names goes here... const char* e3 = ")\\s*\\([^;()]*\\)\\s*;)"; std::string class_name_list; std::set<std::string>::const_iterator i = class_names[libname].begin(), j = class_names[libname].end(); if(i != j) { class_name_list = *i; ++i; while(i != j) { class_name_list += "|" + *i; ++i; } } else { class_name_list = "[\\x0]"; } std::string function_name_list; i = free_function_names[libname].begin(); j = free_function_names[libname].end(); if(i != j) { function_name_list = *i; ++i; while(i != j) { function_name_list += "|" + *i; ++i; } } else { function_name_list = "[\\x0]"; } scanner[libname] = boost::regex(e1 + class_name_list + e2 + function_name_list + e3); } }
void bcp_implementation::copy_path(const fs::path& p) { assert(!fs::is_directory(m_boost_path / p)); if(fs::exists(m_dest_path / p)) { std::cout << "Copying (and overwriting) file: " << p.string() << "\n"; fs::remove(m_dest_path / p); } else std::cout << "Copying file: " << p.string() << "\n"; // // create the path to the new file if it doesn't already exist: // create_path(p.branch_path()); // // do text based copy if requested: // if(p.leaf() == "Jamroot") { static std::vector<char> v1, v2; v1.clear(); v2.clear(); std::ifstream is((m_boost_path / p).c_str()); std::copy(std::istreambuf_iterator<char>(is), std::istreambuf_iterator<char>(), std::back_inserter(v1)); static boost::regex libname_matcher; if(libname_matcher.empty()) { libname_matcher.assign("boost_"); } regex_replace(std::back_inserter(v2), v1.begin(), v1.end(), libname_matcher, m_namespace_name + "_"); std::swap(v1, v2); v2.clear(); std::ofstream os; if(m_unix_lines) os.open((m_dest_path / p).c_str(), std::ios_base::binary | std::ios_base::out); else os.open((m_dest_path / p).c_str(), std::ios_base::out); os.write(&*v1.begin(), v1.size()); os.close(); } else if(m_namespace_name.size() && m_lib_names.size() && is_jam_file(p)) { static std::vector<char> v1, v2; v1.clear(); v2.clear(); std::ifstream is((m_boost_path / p).c_str()); std::copy(std::istreambuf_iterator<char>(is), std::istreambuf_iterator<char>(), std::back_inserter(v1)); static boost::regex libname_matcher; if(libname_matcher.empty()) { std::string re = "\\<"; re += *m_lib_names.begin(); for(std::set<std::string>::const_iterator i = ++m_lib_names.begin(); i != m_lib_names.end(); ++i) { re += "|" + *i; } re += "\\>"; libname_matcher.assign(re); } regex_replace(std::back_inserter(v2), v1.begin(), v1.end(), libname_matcher, get_new_library_name(m_namespace_name)); std::swap(v1, v2); v2.clear(); std::ofstream os; if(m_unix_lines) os.open((m_dest_path / p).c_str(), std::ios_base::binary | std::ios_base::out); else os.open((m_dest_path / p).c_str(), std::ios_base::out); os.write(&*v1.begin(), v1.size()); os.close(); } else if(m_namespace_name.size() && is_source_file(p)) { // // v1 hold the current content, v2 is temp buffer. // Each time we do a search and replace the new content // ends up in v2: we then swap v1 and v2, and clear v2. // static std::vector<char> v1, v2; v1.clear(); v2.clear(); std::ifstream is((m_boost_path / p).c_str()); std::copy(std::istreambuf_iterator<char>(is), std::istreambuf_iterator<char>(), std::back_inserter(v1)); static const boost::regex namespace_matcher( "(?|" "(namespace\\s+)boost(_\\w+)?(?:(\\s*::\\s*)phoenix)?" "|" "(namespace\\s+)(adstl|phoenix|rapidxml)\\>" "|" "()\\<boost((?:_(?!intrusive_tags)\\w+)?\\s*(?:::))(?:(\\s*)phoenix)?" "|" "()\\<((?:adstl|phoenix|rapidxml)\\s*(?:::))" "|" "(namespace\\s+\\w+\\s*=\\s*(?:::\\s*)?)boost(_\\w+)?(?:(\\s*::\\s*)phoenix)?" "|" "(namespace\\s+\\w+\\s*=\\s*(?:::\\s*)?(?:\\w+\\s*::\\s*)?)(adstl|phoenix|rapidxml)\\>" "|" "(^\\s*#\\s*define\\s+\\w+\\s+)boost((?:_\\w+)?\\s*)$" "|" "(^\\s*#\\s*define[^\\n]+)((?:adstl|phoenix|rapidxml)\\s*)$" "|" "()boost(_asio_detail_posix_thread_function|_regex_free_static_mutex)" "|" "()(lw_thread_routine|at_thread_exit|on_process_enter|on_process_exit|on_thread_enter|on_thread_exit|tss_cleanup_implemented)" "|" "(BOOST_CLASS_REQUIRE4?[^;]*)boost((?:_\\w+)?\\s*,)" "|" "(\\(\\s*)boost(\\s*\\))" ")" ); regex_replace(std::back_inserter(v2), v1.begin(), v1.end(), namespace_matcher, "$1" + m_namespace_name + "$2(?3$3" + m_namespace_name + "phoenix)", boost::regex_constants::format_all); std::swap(v1, v2); v2.clear(); if(m_namespace_alias) { static const boost::regex namespace_alias( /* "namespace\\s+" + m_namespace_name + "\\s*" "(" "\\{" "(?:" "(?>[^\\{\\}/]+)" "(?>" "(?:" "(?1)" "|//[^\\n]+$" "|/[^/]" "|(?:^\\s*#[^\\n]*" "(?:(?<=\\\\)\\n[^\\n]*)*)" ")" "[^\\{\\}]+" ")*" ")*" "\\}" ")" */ /* "(namespace\\s+" + m_namespace_name + "\\s*\\{.*" "\\})([^\\{\\};]*)\\z" */ "namespace\\s+" + m_namespace_name + "\\s*\\{" ); regex_replace(std::back_inserter(v2), v1.begin(), v1.end(), namespace_alias, "namespace " + m_namespace_name + "{} namespace boost = " + m_namespace_name + "; namespace " + m_namespace_name + "{"); std::swap(v1, v2); v2.clear(); } std::ofstream os; if(m_unix_lines) os.open((m_dest_path / p).c_str(), std::ios_base::binary | std::ios_base::out); else os.open((m_dest_path / p).c_str(), std::ios_base::out); if(v1.size()) os.write(&*v1.begin(), v1.size()); os.close(); } else if(m_unix_lines && !is_binary_file(p)) { std::ifstream is((m_boost_path / p).c_str()); std::istreambuf_iterator<char> isi(is); std::istreambuf_iterator<char> end; std::ofstream os((m_dest_path / p).c_str(), std::ios_base::binary | std::ios_base::out); std::ostreambuf_iterator<char> osi(os); std::copy(isi, end, osi); } else { // binary copy: fs::copy_file(m_boost_path / p, m_dest_path / p); } }
bool FileNameMatches( const char* inPattern, const fs::path& inFile) { return FileNameMatches(inPattern, inFile.leaf()); }
void CXX_Generator:: generate (po::variables_map const& vm, Schema& schema, fs::path const& file_path) { //Name is the actual file name. #if BOOST_FILESYSTEM_VERSION == 2 std::string name (file_path.leaf ()); #else std::string name (file_path.filename ().string ()); #endif //Stores file suffixes (defaults are .hpp, ipp, and cpp) std::string hxx_suffix (vm["cxx-header-suffix"].as<std::string> ()); std::string ixx_suffix (vm["cxx-inline-suffix"].as<std::string> ()); std::string cxx_suffix (vm["cxx-source-suffix"].as<std::string> ()); //Specifies a regular expression of the form pattern/replacement //when constructing the file names. std::string hxx_expr (vm["cxx-header-regex"].as<std::string> ()); std::string ixx_expr (vm["cxx-inline-regex"].as<std::string> ()); std::string cxx_expr (vm["cxx-source-regex"].as<std::string> ()); //Output file names are named <name>.<suffix> std::string hxx_name (regex::perl_s (name, hxx_expr) + hxx_suffix); std::string ixx_name (regex::perl_s (name, ixx_expr) + ixx_suffix); std::string cxx_name (regex::perl_s (name, cxx_expr) + cxx_suffix); //File handlers are created for each file name fs::path hxx_path (hxx_name); fs::path ixx_path (ixx_name); fs::path cxx_path (cxx_name); //Files are opened for output. Note that the inline //file is only opened IF the inline_ value is true (otherwise //the file is ignored). fs::wofstream hxx (hxx_path, std::ios_base::out); fs::wofstream ixx; fs::wofstream cxx (cxx_path, std::ios_base::out); if (!hxx.is_open ()) { wcerr << hxx_name.c_str () << ": error: unable to open in write mode" << endl; return; } //Boolean value set to the "cxx-generate-inline" option value bool inline_ (vm.count ("cxx-generate-inline")); if (inline_) { ixx.open (ixx_path, std::ios_base::out); if (!ixx.is_open ()) { wcerr << ixx_name.c_str () << ": error: unable to open in write mode" << endl; return; } } if (!cxx.is_open ()) { wcerr << cxx_name.c_str () << ": error: unable to open in write mode" << endl; return; } // Banner. // //Takes in the name of a "banner" file. This banner, if it exists, will //be inserted at the head of the output files. { using namespace std; std::string name (vm["cxx-banner-file"].as<std::string> ()); fs::wifstream banner; if (!name.empty ()) { banner.open (name, ios_base::in | ios_base::binary); if (!banner.is_open ()) { wcerr << name.c_str () << ": error: unable to open in read mode" << endl; return; } } // header // { std::string bn (vm["cxx-header-banner-file"].as<std::string> ()); if (!bn.empty ()) { fs::wifstream b (bn, ios_base::in | ios_base::binary); if (!b.is_open ()) { wcerr << bn.c_str () << ": error: unable to open in read mode" << endl; return; } //If the banner is not empty, put the text into the //header file. hxx << b.rdbuf (); } else if (banner.is_open ()) { hxx << banner.rdbuf (); banner.seekg (0, ios_base::beg); } } // inline // if (inline_) { std::string bn (vm["cxx-inline-banner-file"].as<std::string> ()); if (!bn.empty ()) { fs::wifstream b (bn, ios_base::in | ios_base::binary); if (!b.is_open ()) { wcerr << bn.c_str () << ": error: unable to open in read mode" << endl; return; } //If the banner is not empty, put the text into the //inline file (if an inline file has been specified in the //program options). ixx << b.rdbuf (); } else if (banner.is_open ()) { ixx << banner.rdbuf (); banner.seekg (0, ios_base::beg); } } // source // { std::string bn (vm["cxx-header-banner-file"].as<std::string> ()); if (!bn.empty ()) { fs::wifstream b (bn, ios_base::in | ios_base::binary); if (!b.is_open ()) { wcerr << bn.c_str () << ": error: unable to open in read mode" << endl; return; } //If the banner is not empty, put the text into the //source file. cxx << b.rdbuf (); } else if (banner.is_open ()) { cxx << banner.rdbuf (); banner.seekg (0, ios_base::beg); } } } // // string char_type; { std::wostringstream ostr; ostr << vm["cxx-char-type"].as <std::string> ().c_str (); char_type = ostr.str (); } // Set auto-indentation. // Indentation::Implanter<Indentation::Cxx, wchar_t> hxx_guard (hxx); Indentation::Implanter<Indentation::Cxx, wchar_t> ixx_guard (ixx); Indentation::Implanter<Indentation::Cxx, wchar_t> cxx_guard (cxx); bool writer (vm.count ("cxx-generate-writer-types")); bool traversal (vm.count ("cxx-generate-traversal-types") || writer); bool rtti (vm.count ("cxx-generate-extended-rtti") || traversal); // Check if cdr reader/writer options are set bool cdr_reader (vm.count ("cxx-generate-cdr-reader-types")); bool cdr_writer (vm.count ("cxx-generate-cdr-writer-types")); bool cpp11 (vm.count ("cxx-cpp11")); // Check about random access sequences bool ra_sequences (vm.count ("cxx-enable-random-access-sequences")); NamespaceMapping nsm; // Default mapping. // nsm.push_back (L"#^.* (.*?/)??" L"(([a-zA-Z_]\\w*)(/[a-zA-Z_]\\w*)*)$#$2#"); if (vm.count ("cxx-namespace-regex")) { // Custom mappings. // const std::vector<std::string> &custom_nsm (vm["cxx-namespace-regex"].as< std::vector <std::string> > ()); for (std::vector<std::string>::const_iterator i = custom_nsm.begin (); i != custom_nsm.end (); ++i) { std::wostringstream o; o << i->c_str (); nsm.push_back (o.str ()); } } // Export symbol // string export_symbol; { std::wostringstream o; o << vm["cxx-export-symbol"].as<std::string> ().c_str (); export_symbol = o.str (); } // HXX // std::string guard (hxx_name); // Split words // guard = regex::perl_s (guard, "/([a-z])([A-Z])/$1_$2/"); // Upcase. // std::transform (guard.begin (), guard.end(), guard.begin (), upcase); // Replace '.' with '_'. // guard = regex::perl_s (guard, "/\\./_/"); // Replace '-' with '_'. // guard = regex::perl_s (guard, "/\\-/_/"); hxx << "#ifndef " << guard.c_str () << endl << "#define " << guard.c_str () << endl << endl; // Export header file { std::string tmp (vm["cxx-export-header"].as<std::string> ()); if (tmp != "") { hxx << "#include \"" << tmp.c_str () << '"' << endl; } } //Program options are fed into the Context { ::Context ctx (hxx, char_type, export_symbol, nsm); ctx.hxx_expr = hxx_expr.c_str (); ctx.hxx_suffix = hxx_suffix.c_str (); // Add information to generate reader/writer types ctx.cdr_reader_generation (cdr_reader); ctx.cdr_writer_generation (cdr_writer); ctx.cpp11 (cpp11); // Add additional information to the context: ctx.generate_ra_sequences (ra_sequences); //Generate output files generate_forward (ctx, schema); generate_header (ctx, schema); //@@ move expr to ctx generate_parser_header (ctx, schema); if (traversal) { generate_traversal_header (ctx, schema); } if (writer) { generate_writer_header (ctx, schema); } } if (inline_) { hxx << "#include \"" << ixx_name.c_str () << "\"" << endl << endl; } hxx << "#endif // " << guard.c_str () << endl; // IXX // if (inline_) { ::Context ctx (ixx, char_type, export_symbol, nsm); // Add information to generate reader/writer types ctx.cdr_reader_generation (cdr_reader); ctx.cdr_writer_generation (cdr_writer); ctx.cpp11 (cpp11); // Add additional information to the context: ctx.generate_ra_sequences (ra_sequences); generate_inline (ctx, schema, inline_); //@@ move inline_ to ctx } // CXX // cxx << "#include \"" << hxx_name.c_str () << "\"" << endl << endl; { ::Context ctx (cxx, char_type, export_symbol, nsm); // Add information to generate reader/writer types ctx.cdr_reader_generation (cdr_reader); ctx.cdr_writer_generation (cdr_writer); // Add additional information to the context: ctx.generate_ra_sequences (ra_sequences); ctx.cpp11 (cpp11); if (!inline_) { generate_inline (ctx, schema, inline_); } generate_source (ctx, schema); generate_parser_source (ctx, schema); if (rtti) { generate_type_info_source (ctx, schema); } if (traversal) { generate_traversal_source (ctx, schema); } if (writer) { generate_writer_source (ctx, schema); } } }