#!/usr/bin/env python
# Generate the wiki Home.md page from the contained doc comments
# requires the checked out wiki in ../rust-clippy.wiki/
# with -c option, print a warning and set exit status 1 if the file would be
# changed.
import os
import re
import sys


def parse_path(p="src"):
    d = {}
    for f in os.listdir(p):
        if f.endswith(".rs"):
            parse_file(d, os.path.join(p, f))
    return d

START = 0
LINT = 1


def parse_file(d, f):
    last_comment = []
    comment = True

    with open(f) as rs:
        for line in rs:
            if comment:
                if line.startswith("///"):
                    if line.startswith("/// "):
                        last_comment.append(line[4:])
                    else:
                        last_comment.append(line[3:])
                elif line.startswith("declare_lint!"):
                    comment = False
                else:
                    last_comment = []
            if not comment:
                l = line.strip()
                m = re.search(r"pub\s+([A-Z_]+)", l)
                if m:
                    print("found %s in %s" % (m.group(1).lower(), f))
                    d[m.group(1).lower()] = last_comment
                    last_comment = []
                    comment = True
                if "}" in l:
                    print("Warning: Missing Lint-Name in", f)
                    comment = True

PREFIX = """Welcome to the rust-clippy wiki!

Here we aim to collect further explanations on the lints clippy provides. So \
without further ado:

"""

WARNING = """
# A word of warning

Clippy works as a *plugin* to the compiler, which means using an unstable \
internal API. We have gotten quite good at keeping pace with the API \
evolution, but the consequence is that clippy absolutely needs to be compiled \
with the version of `rustc` it will run on, otherwise you will get strange \
errors of missing symbols."""


def write_wiki_page(d, f):
    keys = list(d.keys())
    keys.sort()
    with open(f, "w") as w:
        w.write(PREFIX)
        for k in keys:
            w.write("[`%s`](#%s)\n" % (k, k))
        w.write(WARNING)
        for k in keys:
            w.write("\n# `%s`\n\n%s" % (k, "".join(d[k])))


def check_wiki_page(d, f):
    errors = []
    with open(f) as w:
        for line in w:
            m = re.match("# `([a-z_]+)`", line)
            if m:
                v = d.pop(m.group(1), "()")
                if v == "()":
                    errors.append("Missing wiki entry: " + m.group(1))
    keys = list(d.keys())
    keys.sort()
    for k in keys:
        errors.append("Spurious wiki entry: " + k)
    if errors:
        print("\n".join(errors))
        sys.exit(1)


def main():
    d = parse_path()
    if "-c" in sys.argv:
        check_wiki_page(d, "../rust-clippy.wiki/Home.md")
    else:
        write_wiki_page(d, "../rust-clippy.wiki/Home.md")

if __name__ == "__main__":
    main()

@@ -257,16 +257,73 @@
 t sys%0A%0A%0A
+level_re = re.compile(r'''(Forbid%7CDeny%7CWarn%7CAllow)''')%0A%0A%0A
 def pars
@@ -1115,16 +1115,17 @@
 +)%22, l)%0A
+%0A
         
@@ -1162,101 +1162,388 @@
     
-print(%22found %25s in %25s%22 %25 (m.group(1).lower(), f))%0A                    d%5Bm.group(1).lower()%5D =
+name = m.group(1).lower()%0A%0A                    while True:%0A                        m = re.search(level_re, line)%0A                        if m:%0A                            level = m.group(0)%0A                            break%0A%0A                        line = next(rs)%0A%0A                    print(%22found %25s with level %25s in %25s%22 %25 (name, level, f))%0A                    d%5Bname%5D = (level,
  las
@@ -1551,16 +1551,17 @@
 _comment
+)
 %0A       
@@ -1899,17 +1899,16 @@
 er ado:%0A
-%0A
 %22%22%22%0A%0AWAR
@@ -2269,16 +2269,71 @@
 symbols.
+%0A%0A%22%22%22%0A%0A%0Atemplate = %22%22%22# %60%25s%60%0A%0A**Default level:** %25s%0A%0A%25s
 %22%22%22%0A%0A%0Ade
@@ -2451,39 +2451,209 @@
 PREFIX)%0A
-        for k in keys:%0A
+%0A        for level in ('Deny', 'Warn', 'Allow'):%0A            w.write(%22%5Cn**Those lints are %25s by default**:%5Cn%5Cn%22 %25 level)%0A            for k in keys:%0A                if d%5Bk%5D%5B0%5D == level:%0A        
         
@@ -2690,16 +2690,17 @@
 (k, k))%0A
+%0A
         
@@ -2763,29 +2763,30 @@
 ite(
-%22%5Cn# %60%25s%60%5Cn%5Cn%25s%22 %25 (k
+template %25 (k, d%5Bk%5D%5B0%5D
 , %22%22
@@ -2795,16 +2795,19 @@
 oin(d%5Bk%5D
+%5B1%5D
 )))%0A%0A%0Ade

Update `update_wiki.py` to extract default lint level