command_line.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. // (C) Copyright Eric Niebler 2006.
  2. // Distributed under the Boost
  3. // Software License, Version 1.0. (See accompanying file
  4. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #include <iostream>
  6. #include <iomanip>
  7. #include <fstream>
  8. #include <deque>
  9. #include <sstream>
  10. #include <stdexcept>
  11. #include <iterator>
  12. #include "./regex_comparison.hpp"
  13. //
  14. // globals:
  15. //
  16. bool time_boost = false;
  17. bool time_greta = false;
  18. bool time_safe_greta = false;
  19. bool time_dynamic_xpressive = false;
  20. bool time_static_xpressive = false;
  21. //bool time_posix = false;
  22. //bool time_pcre = false;
  23. bool test_matches = false;
  24. bool test_short_twain = false;
  25. bool test_long_twain = false;
  26. std::string xml_out_file;
  27. std::string xml_contents;
  28. std::list<results> result_list;
  29. int handle_argument(const std::string& what)
  30. {
  31. if(what == "-b")
  32. time_boost = true;
  33. else if(what == "-g")
  34. time_greta = true;
  35. else if(what == "-gs")
  36. time_safe_greta = true;
  37. else if(what == "-dx")
  38. time_dynamic_xpressive = true;
  39. else if(what == "-sx")
  40. time_static_xpressive = true;
  41. //else if(what == "-posix")
  42. // time_posix = true;
  43. //else if(what == "-pcre")
  44. // time_pcre = true;
  45. else if(what == "-all")
  46. {
  47. time_boost = true;
  48. time_greta = true;
  49. time_safe_greta = true;
  50. time_dynamic_xpressive = true;
  51. time_static_xpressive = true;
  52. //time_posix = true;
  53. //time_pcre = true;
  54. }
  55. else if(what == "-test-matches")
  56. test_matches = true;
  57. else if(what == "-test-short-twain")
  58. test_short_twain = true;
  59. else if(what == "-test-long-twain")
  60. test_long_twain = true;
  61. else if(what == "-test-all")
  62. {
  63. test_matches = true;
  64. test_short_twain = true;
  65. test_long_twain = true;
  66. }
  67. else if((what == "-h") || (what == "--help"))
  68. return show_usage();
  69. else if((what[0] == '-') || (what[0] == '/'))
  70. {
  71. std::cerr << "Unknown argument: \"" << what << "\"" << std::endl;
  72. return 1;
  73. }
  74. else if(xml_out_file.size() == 0)
  75. {
  76. xml_out_file = what;
  77. }
  78. else
  79. {
  80. std::cerr << "Unexpected argument: \"" << what << "\"" << std::endl;
  81. return 1;
  82. }
  83. return 0;
  84. }
  85. int show_usage()
  86. {
  87. std::cout <<
  88. "Usage\n"
  89. "xprperf [-h] [library options] [test options] [xml_output_file]\n"
  90. " -h Show help\n\n"
  91. " library options:\n"
  92. " -b Apply tests to boost library\n"
  93. //" -ba Apply tests to boost library with a custom allocator\n"
  94. //" -be Apply tests to experimental boost library\n"
  95. //" -g Apply tests to GRETA library\n"
  96. //" -gs Apply tests to GRETA library (in non-recursive mode)\n"
  97. " -dx Apply tests to dynamic xpressive library\n"
  98. " -sx Apply tests to static xpressive library\n"
  99. //" -posix Apply tests to POSIX library\n"
  100. //" -pcre Apply tests to PCRE library\n"
  101. " -all Apply tests to all libraries\n\n"
  102. " test options:\n"
  103. " -test-matches Test short matches\n"
  104. " -test-short-twain Test short searches\n"
  105. " -test-long-twain Test long searches\n"
  106. " -test-all Test everthing\n";
  107. return 1;
  108. }
  109. void load_file(std::string& text, const char* file)
  110. {
  111. std::deque<char> temp_copy;
  112. std::ifstream is(file);
  113. if(!is.good())
  114. {
  115. std::string msg("Unable to open file: \"");
  116. msg.append(file);
  117. msg.append("\"");
  118. throw std::runtime_error(msg);
  119. }
  120. std::istreambuf_iterator<char> it(is);
  121. std::copy(it, std::istreambuf_iterator<char>(), std::back_inserter(temp_copy));
  122. text.erase();
  123. text.reserve(temp_copy.size());
  124. text.append(temp_copy.begin(), temp_copy.end());
  125. }
  126. struct xml_double
  127. {
  128. double d_;
  129. xml_double( double d ) : d_(d) {}
  130. friend std::ostream & operator<<( std::ostream & out, xml_double const & xd )
  131. {
  132. std::ostringstream tmp;
  133. tmp << std::setprecision(out.precision()) << xd.d_;
  134. std::string str = tmp.str();
  135. std::string::size_type i = str.find( '-' );
  136. if( i != std::string::npos )
  137. str.replace( i, 1, "&#8209;" );
  138. return out << str;
  139. }
  140. };
  141. void print_result(std::ostream& os, double time, double best)
  142. {
  143. static const char* suffixes[] = {"s", "ms", "us", "ns", "ps", };
  144. if(time < 0)
  145. {
  146. os << "<entry>NA</entry>";
  147. return;
  148. }
  149. double rel = time / best;
  150. bool highlight = ((rel > 0) && (rel < 1.1));
  151. unsigned suffix = 0;
  152. while(time < 0)
  153. {
  154. time *= 1000;
  155. ++suffix;
  156. }
  157. os << "<entry>";
  158. if(highlight)
  159. os << "<phrase role=\"highlight\">";
  160. if(rel <= 1000)
  161. os << std::setprecision(3) << xml_double(rel);
  162. else
  163. os << (int)rel;
  164. os << "<para/>(";
  165. if(time <= 1000)
  166. os << std::setprecision(3) << xml_double(time);
  167. else
  168. os << (int)time;
  169. os << suffixes[suffix] << ")";
  170. if(highlight)
  171. os << "</phrase>";
  172. os << "</entry>";
  173. }
  174. void output_xml_results(bool show_description, const std::string& title, const std::string& filename)
  175. {
  176. std::stringstream os;
  177. // Generate the copyright and license on the output file
  178. os << "<!--\n"
  179. " Copyright 2004 Eric Niebler.\n"
  180. "\n"
  181. " Distributed under the Boost Software License, Version 1.0.\n"
  182. " (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n"
  183. "-->\n";
  184. if(result_list.size())
  185. {
  186. // calculate the number of columns in this table
  187. int num_cols = 1 + show_description + time_greta + time_safe_greta
  188. + time_dynamic_xpressive + time_static_xpressive + time_boost;
  189. //
  190. // start by outputting the table header:
  191. //
  192. os << "<informaltable frame=\"all\">\n";
  193. os << "<bridgehead renderas=\"sect4\">"
  194. "<phrase role=\"table-title\">" << title << "</phrase>"
  195. "</bridgehead>\n";
  196. os << "<tgroup cols=\"" << num_cols << "\">\n";
  197. os << "<thead>\n";
  198. os << "<row>\n";
  199. if(time_static_xpressive) os << "<entry>static xpressive</entry>";
  200. if(time_dynamic_xpressive) os << "<entry>dynamic xpressive</entry>";
  201. if(time_greta) os << "<entry>GRETA</entry>";
  202. if(time_safe_greta) os << "<entry>GRETA<para/>(non-recursive mode)</entry>";
  203. if(time_boost) os << "<entry>Boost</entry>";
  204. //if(time_posix) os << "<entry>POSIX</entry>";
  205. //if(time_pcre) os << "<entry>PCRE</entry>";
  206. if(show_description) os << "<entry>Text</entry>";
  207. os << "<entry>Expression</entry>";
  208. os << "\n</row>\n";
  209. os << "</thead>\n";
  210. os << "<tbody>\n";
  211. //
  212. // Now enumerate through all the test results:
  213. //
  214. std::list<results>::const_iterator first, last;
  215. first = result_list.begin();
  216. last = result_list.end();
  217. while(first != last)
  218. {
  219. os << "<row>\n";
  220. if(time_static_xpressive) print_result(os, first->static_xpressive_time, first->factor);
  221. if(time_dynamic_xpressive) print_result(os, first->dynamic_xpressive_time, first->factor);
  222. if(time_greta) print_result(os, first->greta_time, first->factor);
  223. if(time_safe_greta) print_result(os, first->safe_greta_time, first->factor);
  224. if(time_boost) print_result(os, first->boost_time, first->factor);
  225. //if(time_posix) print_result(os, first->posix_time, first->factor);
  226. //if(time_pcre) print_result(os, first->pcre_time, first->factor);
  227. if(show_description) os << "<entry>" << first->description << "</entry>";
  228. os << "<entry><literal>" << first->expression << "</literal></entry>";
  229. os << "\n</row>\n";
  230. ++first;
  231. }
  232. os << "</tbody>\n"
  233. "</tgroup>\n"
  234. "</informaltable>\n";
  235. result_list.clear();
  236. }
  237. else
  238. {
  239. os << "<para><emphasis>Results not available...</emphasis></para>\n";
  240. }
  241. std::ofstream file(filename.c_str());
  242. file << os.str();
  243. }