Mercurial > hg > CbC > CbC_llvm
view clang/www/make_cxx_dr_status @ 266:00f31e85ec16 default tip
Added tag current for changeset 31d058e83c98
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 14 Oct 2023 10:13:55 +0900 |
parents | 1f2b6ac9f198 |
children |
line wrap: on
line source
#! /usr/bin/env python3 import sys, os, re, urllib.request clang_www_dir = os.path.dirname(__file__) default_issue_list_path = os.path.join(clang_www_dir, 'cwg_index.html') issue_list_url = "https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_index.html" output = os.path.join(clang_www_dir, 'cxx_dr_status.html') dr_test_dir = os.path.join(clang_www_dir, '../test/CXX/drs') class DR: def __init__(self, section, issue, url, status, title): self.section, self.issue, self.url, self.status, self.title = \ section, issue, url, status, title def __repr__(self): return '%s (%s): %s' % (self.issue, self.status, self.title) def parse(dr): try: section, issue_link, status, liaison, title = [ col.split('>', 1)[1].split('</TD>')[0] for col in dr.split('</TR>', 1)[0].split('<TD')[1:] ] except Exception as ex: print(f"Parse error: {ex}\n{dr}", file=sys.stderr) sys.exit(1) _, url, issue = issue_link.split('"', 2) url = url.strip() issue = int(issue.split('>', 1)[1].split('<', 1)[0]) title = title.replace('<issue_title>', '').replace('</issue_title>', '').replace('\r\n', '\n').strip() return DR(section, issue, url, status, title) def collect_tests(): status_re = re.compile(r'\bdr([0-9]+): (.*)') status_map = {} for test_cpp in os.listdir(dr_test_dir): if not test_cpp.endswith('.cpp'): continue test_cpp = os.path.join(dr_test_dir, test_cpp) found_any = False; for match in re.finditer(status_re, open(test_cpp, 'r').read()): status_map[int(match.group(1))] = match.group(2) found_any = True if not found_any: print("warning:%s: no '// dr123: foo' comments in this file" % test_cpp, file=sys.stderr) return status_map def get_issues(path): buffer = None if not path and os.path.exists(default_issue_list_path): path = default_issue_list_path try: if path is None: print('Fetching issue list from {}'.format(issue_list_url)) with urllib.request.urlopen(issue_list_url) as f: buffer = f.read().decode('utf-8') else: print('Opening issue list from file {}'.format(path)) with open(path, 'r') as f: buffer = f.read() except Exception as ex: print('Unable to read the core issue list', file=sys.stderr) print(ex, file=sys.stderr) sys.exit(1) return sorted((parse(dr) for dr in buffer.split('<TR>')[2:]), key = lambda dr: dr.issue) issue_list_path = None if len(sys.argv) == 1: pass elif len(sys.argv) == 2: issue_list_path = sys.argv[1] else: print('Usage: {} [<path to cwg_index.html>]'.format(sys.argv[0]), file=sys.stderr) sys.exit(1) status_map = collect_tests() drs = get_issues(issue_list_path) out_file = open(output, 'w') out_file.write('''\ <!DOCTYPE html> <!-- This file is auto-generated by make_cxx_dr_status. Do not modify. --> <html> <head> <META http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Clang - C++ Defect Report Status</title> <link type="text/css" rel="stylesheet" href="menu.css"> <link type="text/css" rel="stylesheet" href="content.css"> <style type="text/css"> .none { background-color: #FFCCCC } .partial { background-color: #FFE0B0 } .unreleased { background-color: #FFFF99 } .full { background-color: #CCFF99 } .na { background-color: #DDDDDD } .open * { color: #AAAAAA } //.open { filter: opacity(0.2) } tr:target { background-color: #FFFFBB } th { background-color: #FFDDAA } </style> </head> <body> <!--#include virtual="menu.html.incl"--> <div id="content"> <!--*************************************************************************--> <h1>C++ Defect Report Support in Clang</h1> <!--*************************************************************************--> <h2 id="cxxdr">C++ defect report implementation status</h2> <p>This page tracks which C++ defect reports are implemented within Clang.</p> <table width="689" border="1" cellspacing="0"> <tr> <th>Number</th> <th>Status</th> <th>Issue title</th> <th>Available in Clang?</th> </tr>''') latest_release = 16 def availability(issue): status = status_map.get(issue, 'unknown') unresolved_status = '' if status.endswith(' open'): status = status[:-5] unresolved_status = 'open' elif status.endswith(' drafting'): status = status[:-9] unresolved_status = 'drafting' elif status.endswith(' review'): status = status[:-7] unresolved_status = 'review' avail_suffix = '' if status.endswith(' c++11'): status = status[:-6] avail_suffix = ' (C++11 onwards)' elif status.endswith(' c++14'): status = status[:-6] avail_suffix = ' (C++14 onwards)' elif status.endswith(' c++17'): status = status[:-6] avail_suffix = ' (C++17 onwards)' elif status.endswith(' c++20'): status = status[:-6] avail_suffix = ' (C++20 onwards)' if status == 'unknown': avail = 'Unknown' avail_style = ' class="none"' elif re.match('^[0-9]+\.?[0-9]*', status): avail = 'Clang %s' % status if float(status) > latest_release: avail_style = ' class="unreleased"' else: avail_style = ' class="full"' elif status == 'yes': avail = 'Yes' avail_style = ' class="full"' elif status == 'partial': avail = 'Partial' avail_style = ' class="partial"' elif status == 'no': avail = 'No' avail_style = ' class="none"' elif status == 'na': avail = 'N/A' avail_style = ' class="na"' elif status == 'na lib': avail = 'N/A (Library DR)' avail_style = ' class="na"' elif status == 'na abi': avail = 'N/A (ABI constraint)' avail_style = ' class="na"' elif status.startswith('sup '): dup = status.split(' ', 1)[1] if dup.startswith('P'): avail = 'Superseded by <a href="https://wg21.link/%s">%s</a>' % (dup, dup) avail_style = ' class="na"' else: avail = 'Superseded by <a href="#%s">%s</a>' % (dup, dup) try: _, avail_style, _ = availability(int(dup)) except: print("issue %s marked as sup %s" % (issue, dup), file=sys.stderr) avail_style = ' class="none"' elif status.startswith('dup '): dup = int(status.split(' ', 1)[1]) avail = 'Duplicate of <a href="#%s">%s</a>' % (dup, dup) _, avail_style, _ = availability(dup) else: assert False, 'unknown status %s for issue %s' % (status, dr.issue) return (avail + avail_suffix, avail_style, unresolved_status) count = {} for dr in drs: if dr.status in ('concepts',): # This refers to the old ("C++0x") concepts feature, which was not part # of any C++ International Standard or Technical Specification. continue elif dr.status == 'extension': row_style = ' class="open"' avail = 'Extension' avail_style = '' elif dr.status in ('open', 'drafting', 'review'): row_style = ' class="open"' avail, avail_style, unresolved_status = availability(dr.issue) if avail == 'Unknown': avail = 'Not resolved' avail_style = '' else: assert unresolved_status == dr.status, \ "Issue %s is marked '%s', which differs from CWG index status '%s'" \ % (dr.issue, unresolved_status, dr.status) else: row_style = '' avail, avail_style, unresolved_status = availability(dr.issue) assert not unresolved_status, \ "Issue %s is marked '%s', even though it is resolved in CWG index" \ % (dr.issue, unresolved_status) if not avail.startswith('Sup') and not avail.startswith('Dup'): count[avail] = count.get(avail, 0) + 1 out_file.write(''' <tr%s id="%s"> <td><a href="https://cplusplus.github.io/CWG/issues/%s.html">%s</a></td> <td>%s</td> <td>%s</td> <td%s align="center">%s</td> </tr>''' % (row_style, dr.issue, dr.issue, dr.issue, dr.status, dr.title, avail_style, avail)) for status, num in sorted(count.items()): print("%s: %s" % (status, num), file=sys.stderr) out_file.write('''\ </table> </div> </body> </html> ''') out_file.close()