diff --git a/feed/history/boost_1_66_0.qbk b/feed/history/boost_1_66_0.qbk index 0f42065a..dc7f8e6e 100644 --- a/feed/history/boost_1_66_0.qbk +++ b/feed/history/boost_1_66_0.qbk @@ -154,11 +154,72 @@ Boost's primary test compilers are: -* /TODO/ +* Linux: + * Clang: 3.0, 4.0.1, 5.0.1 + * Clang, C++0x: 3.0 + * Clang, C++11: 3.0, 3.1, 3.2, 3.3, 3.4, 4.0.1, 5.0.1 + * Clang, C++14: 3.5.0, 3.6.0, 3.7.1, 3.8.0, 3.9.1, 4.0.0, 4.0.1, 5.0.1 + * Clang, C++17: 5.0.1 + * GCC: 4.4.7, 4.5.3, 4.6.3, 4.7.2, 5.4.0, 7.2.0 + * GCC, C++0x: 4.4.7 + * GCC, C++11: 4.7.2, 4.7.3, 4.8.5, 4.9.4, 6.4.0, 7.1.0, 7.2.0 + * GCC, C++14: 5.4.1, 6.3.0, 6.4.0, 7.1.0, 7.2.0, 7.2.1 + * GCC, C++17: 7.2.0 + * Intel, C++14: 1800 +* OS X: + * Clang: 9.0.0 +* Windows: + * GCC: 3.4.5, 4.1.2, 4.2.4, 4.3.3, 4.4.0, 4.5.4 + * GCC, C++0x: 4.6.4 + * GCC, C++11: 4.7.3 + * Visual C++: 7.1, 8.0, 9.0, 10.0, 11.0, 12.0, 14.0, 14.1 +* Android: + * Clang: 3.6, 3.7, 3.8 + * GCC: 4.9, 5.4 + * GCC, C++14: 6.2 +* FreeBSD: + * Clang: 4.0.0 + * Clang, C++11: 4.0.0 + * Clang, C++14: 4.0.0 + * Clang, C++1z: 4.0.0 +* QNX: + * QCC, C++0x: 4.4.2 + * QCC, C++11: 4.7.3 Boost's additional test compilers include: -* /TODO/ +* Linux: + * Clang: 3.0, 3.8.1, 4.0.1, 5.0.1 + * Clang, C++0x: 3.0 + * Clang, C++11: 3.0, 3.1, 3.2, 3.3, 3.4, 4.0.1, 5.0.1 + * Clang, C++14: 3.5.0, 3.6.0, 3.7.1, 3.8.0, 3.9.1, 4.0.0, 4.0.1, 5.0.1 + * Clang, C++17: 5.0.1 + * GCC: 4.4.7, 4.5.3, 4.6.3, 4.7.2, 5.4.0, 7.2.0 + * GCC, C++0x: 4.4.7 + * GCC, C++11: 4.7.2, 4.7.3, 4.8.5, 4.9.4, 5.4.0, 6.4.0, 7.1.0, 7.2.0 + * GCC, C++14: 5.4.1, 6.3.0, 6.4.0, 7.1.0, 7.2.0, 7.2.1, 8.0.0 + * GCC, C++17: 7.2.0 + * Intel, C++14: 1800 +* OS X: + * Clang: 6.0.0, 9.0.0 +* Windows: + * GCC: 3.4.5, 4.1.2, 4.2.4, 4.3.3, 4.4.0, 4.5.4 + * GCC, C++0x: 4.6.4 + * GCC, C++11: 4.7.3, 4.8.1, 4.9.3 + * GCC, C++14: 5.1.0, 5.2.0, 5.3.0, 6.1.0, 6.2.0, 6.3.0, 6.4.0, 7.1.0 + * Visual C++: 7.1, 8.0, 9.0, 10.0, 11.0, 12.0, 14.0, 14.1 +* Android: + * Clang: 3.6, 3.7, 3.8 + * GCC: 4.9, 5.4 + * GCC, C++14: 6.2 +* FreeBSD: + * Clang: 4.0.0 + * Clang, C++11: 4.0.0 + * Clang, C++14: 4.0.0 + * Clang, C++1z: 4.0.0 +* QNX: + * QCC, C++0x: 4.4.2 + * QCC, C++11: 4.7.3 [endsect] diff --git a/site-tools/.gitignore b/site-tools/.gitignore new file mode 100644 index 00000000..0a2101fa --- /dev/null +++ b/site-tools/.gitignore @@ -0,0 +1 @@ +/cache/ diff --git a/site-tools/list-test-compilers.php b/site-tools/list-test-compilers.php new file mode 100644 index 00000000..62ba3b8b --- /dev/null +++ b/site-tools/list-test-compilers.php @@ -0,0 +1,285 @@ +#!/usr/bin/env php + 'GCC', + 'Microsoft Visual C++' => 'Visual C++', + 'Intel C++ C++0x mode' => 'Intel', + 'Clang' => 'Clang', + ); + $url_path = "/development/tests/{$branch}/developer/config_.html"; + $test_links = get_test_links($branch, $url_path); + + $test_compilers = array(); + + foreach($test_links as $link_details) { + $test_results = download_test_results(resolve_url_path($link_details['link'], $url_path)); + if (!$test_results) { + echo "No test results for {$branch}:\n"; + print_r($link_details); + echo "\n"; + continue; + } + + $test_results = explode('*********************************************************************', $test_results); + $compiler_info = trim($test_results[0]); + if (!preg_match('@^(.*)version[ \t]*([0-9.]+)(?:[- ]+.*)?$@m', $compiler_info, $match)) { + throw new RuntimeException("Unable to match compiler + version: $compiler_info"); + } + $compiler = trim($match[1]); + if (array_key_exists($compiler, $compiler_conversion)) { + $compiler = $compiler_conversion[$compiler]; + } else { + echo "Unknown Compiler: {$compiler}\n"; + } + $compiler_version = trim($match[2]); + $variables = substr($compiler_info, strlen($match[0])); + if (preg_match_all('@^[ \t]*(\w*)[ \t]*=(.*)$@m', $variables, $matches, PREG_SET_ORDER)) { + $variables = array(); + foreach ($matches as $match) { + $variables[$match[1]] = $match[2]; + } + + if (array_key_exists('__QNX__', $variables)) { + $compiler = 'QCC'; + } + $language_version = false; + if (array_key_exists('__cplusplus', $variables)) { + if (preg_match('@^(\d{6})L?$@', $variables['__cplusplus'], $match)) { + if ($match[1] < 201103) { + $language_version = 'C++03'; + } else if ($match[1] < 201402) { + $language_version = 'C++11'; + } else if ($match[1] < 201406) { + $language_version = 'C++14'; + } else if ($match[1] < 201703) { + $language_version = 'C++1z'; + } else { + $language_version = 'C++17'; + } + } + } + if (!$language_version) { + if (array_key_exists('__GXX_EXPERIMENTAL_CXX0X__', $variables)) { + $language_version = 'C++0x'; + } else if ($compiler == 'GCC' || $compiler == 'Clang') { + $language_version = 'C++03'; + } + } + if (!$language_version) { + echo "No language version for: {$compiler}\n"; + print_r($variables); + $language_version = 'C++03'; + } + } + + $test_compilers[$link_details['os']][$compiler][$language_version][$compiler_version] = true; + } + + return $test_compilers; +} + +function get_test_links($branch, $url_path) { + $config_summary_dom = DOMDocument::loadHTML(download_page($url_path)); + if (!$config_summary_dom) { + throw new RuntimeException("Error parsing summary for branch {$branch}"); + } + + $xpath = new DOMXPath($config_summary_dom); + + // Operating System: Android, Darwin, FreeBSD, etc + $os_columns = array(); + foreach($xpath->query("//table[@class='library-table']/thead/tr[1]/td") as $node) { + $colspan = $node->hasAttribute('colspan') ? $node->getAttribute('colspan') : 1; + for ($i = 0; $i < $colspan; ++$i) { + $os = trim($node->textContent); + if (strtolower($os) == 'darwin') { $os = 'OS X'; } + $os_columns[] = $os; + } + } + + // Runner: CrystaX-apilevel-19-armeabi-v7a-gnu-libstdc++, teeks99-02-dc3.5-14-Docker-64on64 + $runner_columns = array(); + foreach($xpath->query("//table[@class='library-table']/thead/tr[2]/td") as $node) { + $colspan = $node->hasAttribute('colspan') ? $node->getAttribute('colspan') : 1; + for ($i = 0; $i < $colspan; ++$i) { + $runner_columns[] = trim($node->textContent); + } + } + + // Toolset name: clang-gnu-linux-3.6, gcc-gnu-4.9, etc. + $toolset_columns = array(); + foreach($xpath->query("//table[@class='library-table']/thead/tr[5]/td") as $node) { + $colspan = $node->hasAttribute('colspan') ? $node->getAttribute('colspan') : 1; + for ($i = 0; $i < $colspan; ++$i) { + $toolset_columns[] = preg_replace('@\s+@', '', $node->textContent); + } + } + + // config_info links + $config_info_columns = array(); + $config_info_row = $xpath->query("//table[@class='library-table']/tbody/tr". + "[td[@class='test-name']/a[text()[normalize-space() = 'config_info']]]"); + if ($config_info_row->length != 1) { + throw new RuntimeException("Unable to find config_info row"); + } + foreach($config_info_row->item(0)->getElementsByTagName("td") as $td_node) { + $a_nodes = $td_node->getElementsByTagName("a"); + if ($a_nodes->length > 1) { + throw new RuntimeException("Multiple links in config_info cell"); + } + $link = null; + if ($a_nodes->length == 1 && trim($a_nodes->item(0)->textContent) == 'pass' && $a_nodes->item(0)->hasAttribute('href')) { + $link = $a_nodes->item(0)->getAttribute('href'); + } + $colspan = $td_node->hasAttribute('colspan') ? $td_node->getAttribute('colspan') : 1; + for ($i = 0; $i < $colspan; ++$i) { + $config_info_columns[] = $link; + } + } + + $test_links = []; + foreach ($config_info_columns as $index => $link) { + if ($link && $os_columns[$index]) { + $test_links[] = array( + 'os' => $os_columns[$index], + 'runner' => $runner_columns[$index], + 'toolset' => $toolset_columns[$index], + 'link' => $link, + ); + } + } + + return $test_links; +} + +function download_test_results($url_path) { + $frame_link = get_frame_link_from_frameset($url_path); + return get_test_results_from_frame(resolve_url_path($frame_link, $url_path)); +} + +function get_frame_link_from_frameset($url_path) { + $frame_set = DOMDocument::loadHTML(download_page($url_path)); + if (!$frame_set) { + throw new RuntimeException("Error downloading test results frame"); + } + + $xpath = new DOMXPath($frame_set); + $frame_node = $xpath->query("//frame[@name='docframe']"); + if ($frame_node->length != 1) { + throw new RuntimeException("Error getting docframe"); + } + return $frame_node->item(0)->getAttribute('src'); +} + +function get_test_results_from_frame($url_path) { + $page = DOMDocument::loadHTML(download_page($url_path)); + if (!$page) { + throw new RuntimeException("Error downloading test results"); + } + + // If $page has links to multiple test results, use the first one. + $a_nodes = $page->getElementsByTagName('a'); + if ($a_nodes->length) { + $page = DOMDocument::loadHTML(download_page( + resolve_url_path($a_nodes->item(0)->getAttribute('href'), $url_path))); + if (!$page) { + throw new RuntimeException("Error downloading test results"); + } + } + + $xpath = new DOMXPath($page); + foreach($xpath->query("//div[@class='log-linker-output-title']") as $node) { + if (preg_match('@^Run \[.*\]: (.*)@', trim($node->textContent), $match)) { + do { $node = $node->nextSibling; } while($node && $node->nodeType != XML_ELEMENT_NODE); + if (!$node) { return null; } + return $node->textContent; + } + } +} + +function download_page($url_path) { + $cache_path = __DIR__."/cache{$url_path}"; + if (!is_file($cache_path)) { + $parent_dir = dirname($cache_path); + if (!is_dir($parent_dir)) { mkdir($parent_dir, 0777, true); } + $page = file_get_contents("http://www.boost.org{$url_path}"); + if (!$page) { + throw new RuntimeException("Error downloading: {$url_path}"); + } + file_put_contents($cache_path, $page); + return $page; + } else { + return file_get_contents($cache_path); + } +} + +function resolve_url_path($url_path, $base) { + if (strpos($url_path, ':') !== false) { + throw new RuntimeException("Absolute URL"); + } + if ($url_path[0] == '/') { return $url_path; } + $base = preg_replace('@[^/]*$@', '', $base); + return $base ? $base.$url_path : '/'.$url_path; +} + +main(); \ No newline at end of file