regrtest.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. // boost compilation regression test
  2. // Usage: regrtest [*|compiler] [*|library/program]
  3. //
  4. // Default: regrtest * *
  5. //
  6. // Compilers: bcc = Borland 5.5.1
  7. // cw = Metrowerks CodeWarrior
  8. // gcc = GNU GCC
  9. // gcc-stlport = GNU GCC with STLport library
  10. // como = Comeau C++
  11. // vc = Microsoft Visual C++
  12. // vcstlport = Microsoft Visual C++ with STLport library
  13. //
  14. // Examples: regrtest
  15. // regrtest
  16. // regrtest gcc
  17. // regrtest * smart_ptr/smart_ptr_test.cpp
  18. // regrtest gcc smart_ptr/smart_ptr_test.cpp
  19. //
  20. // If the program argument is * or left out, then the file
  21. // ./regrtest_files.txt will be used as the list of files to be
  22. // tested. Each line of regrtest_files.txt must have the form:
  23. //
  24. // file-name mode [input-file]
  25. //
  26. // Where mode is
  27. // C compile
  28. // F compile, expecting failure
  29. // R compile and run
  30. //
  31. // The path to the input-file should be relative to where regrtest is
  32. // running.
  33. //
  34. // Required environment variables:
  35. // BOOST_PATH The directory containing the "boost/" header file directory.
  36. // OSTYPE The operating system, should be one of ...
  37. // BOOST_STLPORT_PATH The directory containing STLport headers
  38. // BOOST_BCC55_PATH The directory container Borland headers
  39. //
  40. // Note: use the following command line syntax if output is to be redirected:
  41. // python regrtest.py [*|compiler] [*|library/program] >log 2>&1
  42. // Revision history:
  43. // 17 Dec 00 Rewrote in C++ and retrieve file list from a file. (Jeremy Siek)
  44. // 21 Jun 00 Redesign to allow specifying compiler and program (Beman Dawes)
  45. // 18 Jun 00 Initial Version (Beman Dawes)
  46. // The Metrowerks and Microsoft compilers require various environment variables be set.
  47. // See mwcc -help
  48. // See http://msdn.microsoft.com/library/devprods/vs6/visualc/vccore/_core_building_on_the_command_line.3a_.overview.htm
  49. // Others:
  50. // See bcb4.hlp. Don't bother with bcb4tools.hlp; it has a bad link to the command line options
  51. #include <iostream>
  52. #include <fstream>
  53. #include <string>
  54. #include <stdlib.h> // for getenv()
  55. #include <time.h> // for ctime()
  56. #include <stdio.h> // for sscanf()
  57. #include <string.h> // for strtok()
  58. // Enumerated Types
  59. // Global variables
  60. std::string path, compiler_arg, program_arg,
  61. exe_suffix, exe_invoke_prefix = "./";
  62. std::ofstream outfile;
  63. //-----------------------------------------------------------------------------
  64. std::string platform()
  65. {
  66. char* os_ptr = getenv("OSTYPE");
  67. if (os_ptr == 0) {
  68. std::cerr << "The \"OSTYPE\" environment variable is not defined"
  69. << std::endl;
  70. exit(1);
  71. return "unknown";
  72. } else {
  73. std::string os = os_ptr;
  74. if (os == "linux")
  75. return "linux";
  76. else if (os == "solaris")
  77. return "sunos";
  78. else
  79. return "unknown";
  80. }
  81. }
  82. //-----------------------------------------------------------------------------
  83. void invoke(std::string desc,
  84. std::string command,
  85. char invoke_mode,
  86. std::string invoke_args,
  87. std::string program_name)
  88. {
  89. std::cout << " " << desc << std::endl;
  90. std::cout << " invoke mode: " << invoke_mode << std::endl;
  91. std::cout << " " << command << std::endl;
  92. outfile << "<td>";
  93. int rs = system(command.c_str());
  94. std::cout << " compile return status: " << rs << std::endl;
  95. switch (invoke_mode) {
  96. case 'C': // compile
  97. if (rs==0)
  98. outfile << "<FONT COLOR=#008000>yes</FONT>";
  99. else
  100. outfile << "<FONT COLOR=#800000>failed to compile</FONT>";
  101. break;
  102. case 'F': // compile, fail expected
  103. if (rs==0)
  104. outfile
  105. << "<FONT COLOR=#800000>failed to cause error</FONT>";
  106. else
  107. outfile
  108. << "<FONT COLOR=#008000>yes</FONT>";
  109. break;
  110. case 'R': // run
  111. if (rs==0) {
  112. //script debugging aid
  113. std::cout << " executing: " << exe_invoke_prefix << program_name
  114. << " " << invoke_args << std::endl;
  115. std::string cmd_line = exe_invoke_prefix + program_name
  116. + " " + invoke_args;
  117. rs = system(cmd_line.c_str());
  118. if (rs==0)
  119. outfile
  120. << "<FONT COLOR=#008000>yes</FONT>";
  121. else
  122. outfile << "<FONT COLOR=#800000>exited with code "
  123. << rs << "</FONT>";
  124. } else
  125. outfile << "<FONT COLOR=#800000>failed to compile</FONT>";
  126. break;
  127. default:
  128. outfile << "scripting error";
  129. } // switch (invoke_mode)
  130. outfile << "</td>" << std::endl;
  131. }
  132. //-----------------------------------------------------------------------------
  133. void compile(std::string program,
  134. char invoke_mode,
  135. std::string invoke_args,
  136. std::string program_name)
  137. {
  138. std::string fullpath = path + "/libs/" + program;
  139. std::cout << std::endl
  140. << "*****" << program << "*****" << std::endl;
  141. outfile << "<tr>" << std::endl
  142. << "<td><a href=\"" << program << "\">" << program << "</a></td>"
  143. << std::endl;
  144. std::string gcc_flags
  145. = "-Wall -pedantic -ftemplate-depth-30 -Wno-long-long";
  146. // should add -Werror
  147. std::string kcc_flags
  148. // = "--strict";
  149. = "--strict_warnings";
  150. std::string mwcc_flags = "-maxerrors 10 -cwd source";
  151. //John Maddock says use /Zm400 switch; it increases compiler memory
  152. std::string msvc_flags = "/nologo /Zm400 /MDd /W3 /GR /GX /GZ /D \"WIN32\" /D \"_DEBUG\" /D \"_MBCS\" /D \"_CONSOLE\"";
  153. if (platform() == "linux") {
  154. if (compiler_arg == "*" || compiler_arg == "gcc")
  155. invoke("GCC 2.95.2", "g++ " + gcc_flags
  156. + " -o " + program_name
  157. + " -I" + path + " " + fullpath,
  158. invoke_mode, invoke_args, program_name);
  159. if (compiler_arg == "*" || compiler_arg == "gcc-stlport")
  160. invoke( "GCC 2.95.2 STLport 4.0",
  161. "g++ -V 2.95.2-stlport " + gcc_flags
  162. + " -o " + program_name
  163. + " -I" + path + " " + fullpath,
  164. invoke_mode, invoke_args, program_name );
  165. if (compiler_arg == "*" || compiler_arg == "como")
  166. invoke( "Comeau C++ 4.2.44 beta3", "como -o " + program_name
  167. + " -I" + path + " " + fullpath,
  168. invoke_mode, invoke_args, program_name);
  169. } else if (platform() == "sunos") {
  170. if (compiler_arg == "*" || compiler_arg == "gcc")
  171. invoke("GCC 2.95.2",
  172. "g++ " + gcc_flags
  173. + " -o " + program_name
  174. + " -I" + path + " " + fullpath,
  175. invoke_mode, invoke_args, program_name);
  176. if (compiler_arg == "*" || compiler_arg == "kcc")
  177. invoke("KCC 3.4g", "KCC " + kcc_flags
  178. + " -o " + program_name
  179. + " -I" + path + " " + fullpath,
  180. invoke_mode, invoke_args, program_name);
  181. } else if (platform() == "beos") {
  182. if (compiler_arg=="*" || compiler_arg=="gcc")
  183. invoke( "GNU GCC", "c++ " + gcc_flags
  184. +" -o " + program_name
  185. + " -I" + path + " " + fullpath,
  186. invoke_mode, invoke_args, program_name );
  187. // shouldn't this next one be called gcc-stlport instead of gcc-sgi?
  188. if (compiler_arg=="*" || compiler_arg=="gcc-sgi")
  189. invoke("GNU GCC", "c++ " + gcc_flags
  190. + " -o " + program_name
  191. + " -I/boot/home/config/stlport/stl330 -I" + path
  192. + " " + fullpath,
  193. invoke_mode, invoke_args, program_name );
  194. } else {
  195. if (compiler_arg=="*" || compiler_arg=="bcc") {
  196. char* path_ptr = getenv("BOOST_BCC55_PATH");
  197. if (path_ptr == 0) {
  198. std::cerr << "Environment variable BOOST_BCC55_PATH not defined"
  199. << std::endl;
  200. exit(1);
  201. }
  202. std::string bcc55_path = path_ptr;
  203. invoke( "Borland C++ 5.5.1", "\"" + bcc55_path
  204. + "/bcc32\" -e" + program_name
  205. + " -I" + path + " -j10 -q -Ve" + fullpath,
  206. invoke_mode, invoke_args, program_name );
  207. }
  208. if (compiler_arg=="gcc") {
  209. // TODO: fix the absolute STLport paths
  210. invoke( "GNU GCC", "c++ " + gcc_flags
  211. + " -o " + program_name
  212. + " -I" + path + " -IC:/stl/STLport-4.0b8/stlport "
  213. + fullpath
  214. + " c:/stl/STLport-4.0b8/lib/libstlport_gcc.a",
  215. invoke_mode, invoke_args, program_name );
  216. }
  217. if (compiler_arg=="*" || compiler_arg=="cw")
  218. invoke( "Metrowerks CodeWarrior",
  219. "mwcc " + mwcc_flags
  220. + " -I- -o " + program_name
  221. + " -I" + path + " " + fullpath,
  222. invoke_mode, invoke_args, program_name );
  223. if (compiler_arg=="*" || compiler_arg=="vc")
  224. invoke( "VC++ with MS library",
  225. "cl -o " + program_name
  226. + " " + msvc_flags
  227. + " /I " + path + fullpath + " user32.lib",
  228. invoke_mode, invoke_args, program_name );
  229. if (compiler_arg=="*" || compiler_arg=="vcstlport") {
  230. char* path_ptr = getenv("BOOST_STLPORT_PATH");
  231. if (path_ptr == 0) {
  232. std::cerr << "Environment variable BOOST_STLPORT_PATH not defined"
  233. << std::endl;
  234. exit(1);
  235. }
  236. std::string stlport = path_ptr;
  237. invoke( "VC++ with STLport library",
  238. "cl -o " + program_name + msvc_flags
  239. + "/I " + stlport + " /I " + path + fullpath + " user32.lib",
  240. invoke_mode, invoke_args, program_name );
  241. }
  242. }
  243. outfile << "</tr>" << std::endl;
  244. }
  245. //-----------------------------------------------------------------------------
  246. void library()
  247. {
  248. std::cout << std::endl
  249. << "***** Boost Library *****" << std::endl;
  250. outfile << "<tr>" << std::endl
  251. << "<td>Boost library build</td>" << std::endl;
  252. // ...
  253. outfile << "</tr>" << std::endl;
  254. }
  255. //-----------------------------------------------------------------------------
  256. int main(int argc, char* argv[])
  257. {
  258. char* path_ptr = getenv("BOOST_PATH");
  259. if (path_ptr == 0) {
  260. std::cerr << "Environment variable BOOST_PATH not defined" << std::endl;
  261. return -1;
  262. }
  263. path = path_ptr;
  264. compiler_arg = "*";
  265. if (argc > 1)
  266. compiler_arg = argv[1];
  267. program_arg = "*";
  268. if (argc > 2)
  269. program_arg = argv[2];
  270. if (platform() == "unkown") {
  271. std::cerr << "**** Error: unknown platform ****" << std::endl;
  272. return 1;
  273. }
  274. std::string filename = "cs-" + platform() + ".htm";
  275. outfile.open(filename.c_str());
  276. time_t today;
  277. time(&today);
  278. outfile << "<html>\n<head>\n<title>\nCompiler Status: " << platform() << "\n</title>\n</head>"
  279. << "<body bgcolor=\"#FFFFFF\" text=\"#000000\">" << std::endl
  280. << "<h1><img border=\"0\" src=\"../c++boost.gif\" width=\"277\" height=\"86\"></h1>" << std::endl
  281. << "<h1>Compiler Status: " << platform() << "</h1>" << std::endl
  282. << "<p><b>Run Date:</b> " << ctime(&today)
  283. << "</p>" << std::endl
  284. << "<p>" << std::endl
  285. << "<table border=\"1\" cellspacing=\"0\" cellpadding=\"5\">" << std::endl
  286. << "<tr>" << std::endl
  287. << "<td>Program</td>" << std::endl;
  288. if (platform() == "linux") {
  289. if (compiler_arg == "*" || compiler_arg == "gcc")
  290. outfile << "<td>GNU<br>GCC<br>2.95.2</td>" << std::endl;
  291. if (compiler_arg == "*" || compiler_arg == "gcc-stlport")
  292. outfile << "<td>GNU<br>GCC<br>2.95.2<br>STLport<br>4.0</td>"
  293. << std::endl;
  294. #if 0
  295. if (compiler_arg == "*" || compiler_arg == "gcc-exp")
  296. outfile << "<td>GNU<br>GCC<br>pre-2.97 experimental</td>" << std::endl;
  297. #endif
  298. if (compiler_arg == "*" || compiler_arg == "como")
  299. outfile << "<td>Comeau C++<br>4.2.44 beta3<br>STLport<br>4.0</td>"
  300. << std::endl;
  301. #if 0
  302. if (compiler_arg == "*" || compiler_arg == "occ")
  303. outfile << "<td>OpenC++<br>2.5.9</td>" << std::endl;
  304. #endif
  305. } else if (platform() == "sunos") {
  306. if (compiler_arg == "*" || compiler_arg == "suncc")
  307. outfile << "<td>Sun C++<br>Sun WorkShop 6, C++ 5.1</td>" << std::endl;
  308. if (compiler_arg == "*" || compiler_arg == "gcc")
  309. outfile << "<td>GNU<br>GCC<br>2.95.2</td>" << std::endl;
  310. if (compiler_arg == "*" || compiler_arg == "kcc")
  311. outfile << "<td>KAI<br>KCC<br>3.4g</td>" << std::endl;
  312. } else if (platform() == "beos") {
  313. if (compiler_arg == "*" || compiler_arg == "gcc")
  314. outfile << "<td>GNUPro<br>GCC&nbsp;2.9</td>" << std::endl;
  315. if (compiler_arg == "*" || compiler_arg == "gcc-sgi")
  316. outfile
  317. << "<td>GNUPro<br>GCC&nbsp;2.9<br>+<br>SGI&nbsp;STL&nbsp;3.3</td>"
  318. << std::endl;
  319. } else {
  320. #if 0
  321. if (compiler_arg=="*" || compiler_arg=="bcc54")
  322. outfile << "<td>Borland<br>BCC<br>5.4 up2</td>" << std::endl;
  323. #endif
  324. if (compiler_arg=="*" || compiler_arg=="bcc")
  325. outfile << "<td>Borland<br>BCC<br>5.5.1</td>" << std::endl;
  326. // GCC 2.95.2 is looping on some tests, so only invoke if asked
  327. // for by name
  328. if (compiler_arg=="gcc")
  329. outfile << "<td>GNU<br>GCC<br>2.95.2<br>STLport<br>4.0 beta 8</td>"
  330. << std::endl;
  331. if (compiler_arg=="*" || compiler_arg=="cw")
  332. outfile << "<td>Metrowerks<br>CodeWarrior<br>6.0</td>" << std::endl;
  333. if (compiler_arg=="*" || compiler_arg=="vc")
  334. outfile << "<td>Microsoft<br>VC++<br>6.0 SP4</td>" << std::endl;
  335. if (compiler_arg=="*" || compiler_arg=="vcstlport")
  336. outfile << "<td>Microsoft<br>VC++<br>6.0 SP4<br>STLport<br>4.0</td>"
  337. << std::endl;
  338. }
  339. outfile << "</tr>" << std::endl;
  340. if (program_arg == "*") {
  341. std::string filelist = "regrtest_files.txt";
  342. std::ifstream regr_files(filelist.c_str());
  343. if (regr_files) {
  344. const int max_line = 1000;
  345. char line[max_line];
  346. while (regr_files.getline(line, max_line)) {
  347. char *program_ptr, *mode_ptr, *arg_ptr;
  348. program_ptr = strtok(line, " ");
  349. if (program_ptr == 0) {
  350. std::cerr << "file format error, no program file name" << std::endl;
  351. return -1;
  352. }
  353. mode_ptr = strtok(0, " \n");
  354. if (mode_ptr == 0) {
  355. std::cerr << "file format error, no mode character" << std::endl;
  356. return -1;
  357. }
  358. arg_ptr = strtok(0, " \n");
  359. char* empty_string = "";
  360. if (arg_ptr == 0)
  361. arg_ptr = empty_string;
  362. compile(program_ptr, *mode_ptr, arg_ptr, "regress" + exe_suffix);
  363. }
  364. } else {
  365. std::cerr << "Could not open regression test file list: "
  366. << filelist << std::endl;
  367. return -1;
  368. }
  369. } else
  370. compile(program_arg, 'C', "", "regress" + exe_suffix);
  371. outfile << "</table>" << std::endl;
  372. if (platform() == "linux")
  373. outfile << "<p>\nNote: A hand-crafted &lt;limits&gt; "
  374. << "Standard header has been applied to all configurations."
  375. << std::endl;
  376. outfile << "</body>\n</html>" << std::endl;
  377. return 0;
  378. }
粤ICP备19079148号