]>
Commit | Line | Data |
---|---|---|
85aaf69f SL |
1 | # Copyright 2015 The Rust Project Developers. See the COPYRIGHT |
2 | # file at the top-level directory of this distribution and at | |
3 | # http://rust-lang.org/COPYRIGHT. | |
4 | # | |
5 | # Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | # http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | # <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | # option. This file may not be copied, modified, or distributed | |
9 | # except according to those terms. | |
10 | ||
11 | # Digs error codes out of files named 'diagnostics.rs' across | |
12 | # the tree, and ensures thare are no duplicates. | |
13 | ||
14 | import sys | |
15 | import os | |
16 | import re | |
17 | ||
18 | if len(sys.argv) < 2: | |
62682a34 | 19 | print("usage: errorck.py <src-dir>") |
85aaf69f SL |
20 | sys.exit(1) |
21 | ||
22 | src_dir = sys.argv[1] | |
23 | errcode_map = {} | |
24 | error_re = re.compile("(E\d\d\d\d)") | |
25 | ||
c1a9b12d SL |
26 | # In the register_long_diagnostics! macro, entries look like this: |
27 | # | |
28 | # EXXXX: r##" | |
29 | # <Long diagnostic message> | |
30 | # "##, | |
31 | # | |
32 | # These two variables are for detecting the beginning and end of diagnostic | |
33 | # messages so that duplicate error codes are not reported when a code occurs | |
34 | # inside a diagnostic message | |
35 | long_diag_begin = "r##\"" | |
36 | long_diag_end = "\"##" | |
37 | ||
85aaf69f SL |
38 | for (dirpath, dirnames, filenames) in os.walk(src_dir): |
39 | if "src/test" in dirpath or "src/llvm" in dirpath: | |
40 | # Short circuit for fast | |
41 | continue | |
42 | ||
43 | for filename in filenames: | |
44 | if filename != "diagnostics.rs": | |
45 | continue | |
46 | ||
47 | path = os.path.join(dirpath, filename) | |
48 | ||
49 | with open(path, 'r') as f: | |
c1a9b12d | 50 | inside_long_diag = False |
85aaf69f | 51 | for line_num, line in enumerate(f, start=1): |
c1a9b12d SL |
52 | if inside_long_diag: |
53 | # Skip duplicate error code checking for this line | |
54 | if long_diag_end in line: | |
55 | inside_long_diag = False | |
56 | continue | |
57 | ||
85aaf69f SL |
58 | match = error_re.search(line) |
59 | if match: | |
60 | errcode = match.group(1) | |
61 | new_record = [(errcode, path, line_num, line)] | |
62 | existing = errcode_map.get(errcode) | |
63 | if existing is not None: | |
64 | # This is a dupe | |
65 | errcode_map[errcode] = existing + new_record | |
66 | else: | |
67 | errcode_map[errcode] = new_record | |
68 | ||
c1a9b12d SL |
69 | if long_diag_begin in line: |
70 | inside_long_diag = True | |
71 | ||
85aaf69f SL |
72 | errors = False |
73 | all_errors = [] | |
74 | ||
75 | for errcode, entries in errcode_map.items(): | |
76 | all_errors.append(entries[0][0]) | |
77 | if len(entries) > 1: | |
78 | print("error: duplicate error code " + errcode) | |
79 | for entry in entries: | |
80 | print("{1}: {2}\n{3}".format(*entry)) | |
81 | errors = True | |
82 | ||
83 | ||
84 | print("* {0} error codes".format(len(errcode_map))) | |
85 | print("* highest error code: " + max(all_errors)) | |
86 | ||
87 | ||
88 | if errors: | |
89 | sys.exit(1) |