[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / clang / docs / tools / generate_formatted_state.py
blob41d5cd9d400434c264af9eb93a61bebcf469446d
1 #!/usr/bin/env python
2 # A tool to parse creates a document outlining how clang formatted the
3 # LLVM project is.
5 import sys
6 import os
7 import subprocess
8 from datetime import datetime
11 def get_git_revision_short_hash():
12 return subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD']
13 ).decode(sys.stdout.encoding).strip()
16 def get_style(count, passed):
17 if passed == count:
18 return ":good:"
19 elif passed != 0:
20 return ":part:"
21 else:
22 return ":none:"
25 TOP_DIR = os.path.join(os.path.dirname(__file__), '../../..')
26 CLANG_DIR = os.path.join(os.path.dirname(__file__), '../..')
27 DOC_FILE = os.path.join(CLANG_DIR, 'docs/ClangFormattedStatus.rst')
29 rootdir = TOP_DIR
31 skipped_dirs = [".git", "test"]
32 suffixes = (".cpp", ".h")
34 rst_prefix = """\
35 .. raw:: html
37 <style type="text/css">
38 .none {{ background-color: #FFCC99 }}
39 .part {{ background-color: #FFFF99 }}
40 .good {{ background-color: #2CCCFF }}
41 .total {{ font-weight: bold; }}
42 </style>
44 .. role:: none
45 .. role:: part
46 .. role:: good
47 .. role:: total
49 ======================
50 Clang Formatted Status
51 ======================
53 :doc:`ClangFormattedStatus` describes the state of LLVM source
54 tree in terms of conformance to :doc:`ClangFormat` as of: {today} (`{sha} <https://github.com/llvm/llvm-project/commit/{sha}>`_).
57 .. list-table:: LLVM Clang-Format Status
58 :widths: 50 25 25 25 25
59 :header-rows: 1\n
60 * - Directory
61 - Total Files
62 - Formatted Files
63 - Unformatted Files
64 - % Complete
65 """
67 table_row = """\
68 * - {path}
69 - {style}`{count}`
70 - {style}`{passes}`
71 - {style}`{fails}`
72 - {style2}`{percent}%`
73 """
75 FNULL = open(os.devnull, 'w')
77 with open(DOC_FILE, 'wb') as output:
78 sha = get_git_revision_short_hash()
79 today = datetime.now().strftime("%B %d, %Y %H:%M:%S")
80 output.write(bytes(rst_prefix.format(today=today,
81 sha=sha).encode("utf-8")))
83 total_files_count = 0
84 total_files_pass = 0
85 total_files_fail = 0
86 for root, subdirs, files in os.walk(rootdir):
87 for subdir in subdirs:
88 if any(sd == subdir for sd in skipped_dirs):
89 subdirs.remove(subdir)
90 else:
91 act_sub_dir = os.path.join(root, subdir)
92 # Check the git index to see if the directory contains tracked
93 # files. Reditect the output to a null descriptor as we aren't
94 # interested in it, just the return code.
95 git_check = subprocess.Popen(
96 ["git", "ls-files", "--error-unmatch", act_sub_dir],
97 stdout=FNULL,
98 stderr=FNULL)
99 if git_check.wait() != 0:
100 print("Skipping directory: ", act_sub_dir)
101 subdirs.remove(subdir)
103 path = os.path.relpath(root, TOP_DIR)
104 path = path.replace('\\', '/')
106 file_count = 0
107 file_pass = 0
108 file_fail = 0
109 for filename in files:
110 file_path = os.path.join(root, filename)
111 ext = os.path.splitext(file_path)[-1].lower()
112 if not ext.endswith(suffixes):
113 continue
115 file_count += 1
117 args = ["clang-format", "-n", file_path]
118 cmd = subprocess.Popen(args, stderr=subprocess.PIPE)
119 stdout, err = cmd.communicate()
121 relpath = os.path.relpath(file_path, TOP_DIR)
122 relpath = relpath.replace('\\', '/')
123 if err.decode(sys.stdout.encoding).find(': warning:') > 0:
124 print(relpath, ":", "FAIL")
125 file_fail += 1
126 else:
127 print(relpath, ":", "PASS")
128 file_pass += 1
130 total_files_count += file_count
131 total_files_pass += file_pass
132 total_files_fail += file_fail
134 if file_count > 0:
135 percent = (int(100.0 * (float(file_pass)/float(file_count))))
136 style = get_style(file_count, file_pass)
137 output.write(bytes(table_row.format(path=path,
138 count=file_count,
139 passes=file_pass,
140 fails=file_fail,
141 percent=str(percent), style="",
142 style2=style).encode("utf-8")))
143 output.flush()
145 print("----\n")
146 print(path, file_count, file_pass, file_fail, percent)
147 print("----\n")
149 total_percent = (float(total_files_pass)/float(total_files_count))
150 percent_str = str(int(100.0 * total_percent))
151 output.write(bytes(table_row.format(path="Total",
152 count=total_files_count,
153 passes=total_files_pass,
154 fails=total_files_fail,
155 percent=percent_str, style=":total:",
156 style2=":total:").encode("utf-8")))