// (C) Copyright Eric Niebler 2006. // 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 #include #include #include #include #include #include #include "./regex_comparison.hpp" // // globals: // bool time_boost = false; bool time_greta = false; bool time_safe_greta = false; bool time_dynamic_xpressive = false; bool time_static_xpressive = false; //bool time_posix = false; //bool time_pcre = false; bool test_matches = false; bool test_short_twain = false; bool test_long_twain = false; std::string xml_out_file; std::string xml_contents; std::list result_list; int handle_argument(const std::string& what) { if(what == "-b") time_boost = true; else if(what == "-g") time_greta = true; else if(what == "-gs") time_safe_greta = true; else if(what == "-dx") time_dynamic_xpressive = true; else if(what == "-sx") time_static_xpressive = true; //else if(what == "-posix") // time_posix = true; //else if(what == "-pcre") // time_pcre = true; else if(what == "-all") { time_boost = true; time_greta = true; time_safe_greta = true; time_dynamic_xpressive = true; time_static_xpressive = true; //time_posix = true; //time_pcre = true; } else if(what == "-test-matches") test_matches = true; else if(what == "-test-short-twain") test_short_twain = true; else if(what == "-test-long-twain") test_long_twain = true; else if(what == "-test-all") { test_matches = true; test_short_twain = true; test_long_twain = true; } else if((what == "-h") || (what == "--help")) return show_usage(); else if((what[0] == '-') || (what[0] == '/')) { std::cerr << "Unknown argument: \"" << what << "\"" << std::endl; return 1; } else if(xml_out_file.size() == 0) { xml_out_file = what; } else { std::cerr << "Unexpected argument: \"" << what << "\"" << std::endl; return 1; } return 0; } int show_usage() { std::cout << "Usage\n" "xprperf [-h] [library options] [test options] [xml_output_file]\n" " -h Show help\n\n" " library options:\n" " -b Apply tests to boost library\n" //" -ba Apply tests to boost library with a custom allocator\n" //" -be Apply tests to experimental boost library\n" //" -g Apply tests to GRETA library\n" //" -gs Apply tests to GRETA library (in non-recursive mode)\n" " -dx Apply tests to dynamic xpressive library\n" " -sx Apply tests to static xpressive library\n" //" -posix Apply tests to POSIX library\n" //" -pcre Apply tests to PCRE library\n" " -all Apply tests to all libraries\n\n" " test options:\n" " -test-matches Test short matches\n" " -test-short-twain Test short searches\n" " -test-long-twain Test long searches\n" " -test-all Test everthing\n"; return 1; } void load_file(std::string& text, const char* file) { std::deque temp_copy; std::ifstream is(file); if(!is.good()) { std::string msg("Unable to open file: \""); msg.append(file); msg.append("\""); throw std::runtime_error(msg); } std::istreambuf_iterator it(is); std::copy(it, std::istreambuf_iterator(), std::back_inserter(temp_copy)); text.erase(); text.reserve(temp_copy.size()); text.append(temp_copy.begin(), temp_copy.end()); } struct xml_double { double d_; xml_double( double d ) : d_(d) {} friend std::ostream & operator<<( std::ostream & out, xml_double const & xd ) { std::ostringstream tmp; tmp << std::setprecision(out.precision()) << xd.d_; std::string str = tmp.str(); std::string::size_type i = str.find( '-' ); if( i != std::string::npos ) str.replace( i, 1, "‑" ); return out << str; } }; void print_result(std::ostream& os, double time, double best) { static const char* suffixes[] = {"s", "ms", "us", "ns", "ps", }; if(time < 0) { os << "NA"; return; } double rel = time / best; bool highlight = ((rel > 0) && (rel < 1.1)); unsigned suffix = 0; while(time < 0) { time *= 1000; ++suffix; } os << ""; if(highlight) os << ""; if(rel <= 1000) os << std::setprecision(3) << xml_double(rel); else os << (int)rel; os << "("; if(time <= 1000) os << std::setprecision(3) << xml_double(time); else os << (int)time; os << suffixes[suffix] << ")"; if(highlight) os << ""; os << ""; } void output_xml_results(bool show_description, const std::string& title, const std::string& filename) { std::stringstream os; // Generate the copyright and license on the output file os << "\n"; if(result_list.size()) { // calculate the number of columns in this table int num_cols = 1 + show_description + time_greta + time_safe_greta + time_dynamic_xpressive + time_static_xpressive + time_boost; // // start by outputting the table header: // os << "\n"; os << "" "" << title << "" "\n"; os << "\n"; os << "\n"; os << "\n"; if(time_static_xpressive) os << "static xpressive"; if(time_dynamic_xpressive) os << "dynamic xpressive"; if(time_greta) os << "GRETA"; if(time_safe_greta) os << "GRETA(non-recursive mode)"; if(time_boost) os << "Boost"; //if(time_posix) os << "POSIX"; //if(time_pcre) os << "PCRE"; if(show_description) os << "Text"; os << "Expression"; os << "\n\n"; os << "\n"; os << "\n"; // // Now enumerate through all the test results: // std::list::const_iterator first, last; first = result_list.begin(); last = result_list.end(); while(first != last) { os << "\n"; if(time_static_xpressive) print_result(os, first->static_xpressive_time, first->factor); if(time_dynamic_xpressive) print_result(os, first->dynamic_xpressive_time, first->factor); if(time_greta) print_result(os, first->greta_time, first->factor); if(time_safe_greta) print_result(os, first->safe_greta_time, first->factor); if(time_boost) print_result(os, first->boost_time, first->factor); //if(time_posix) print_result(os, first->posix_time, first->factor); //if(time_pcre) print_result(os, first->pcre_time, first->factor); if(show_description) os << "" << first->description << ""; os << "" << first->expression << ""; os << "\n\n"; ++first; } os << "\n" "\n" "\n"; result_list.clear(); } else { os << "Results not available...\n"; } std::ofstream file(filename.c_str()); file << os.str(); }