]> git.lizzy.rs Git - rust.git/blob - src/etc/sugarise-doc-comments.py
cleanup: s/impl Copy/#[derive(Copy)]/g
[rust.git] / src / etc / sugarise-doc-comments.py
1 #!/usr/bin/env python
2 #
3 # Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
4 # file at the top-level directory of this distribution and at
5 # http://rust-lang.org/COPYRIGHT.
6 #
7 # Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
8 # http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
9 # <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
10 # option. This file may not be copied, modified, or distributed
11 # except according to those terms.
12
13 #
14 # this script attempts to turn doc comment attributes (#[doc = "..."])
15 # into sugared-doc-comments (/** ... */ and /// ...)
16 #
17 # it sugarises all .rs/.rc files underneath the working directory
18 #
19
20 import sys, os, fnmatch, re
21
22
23 DOC_PATTERN = '^(?P<indent>[\\t ]*)#\\[(\\s*)doc(\\s*)=' + \
24               '(\\s*)"(?P<text>(\\"|[^"])*?)"(\\s*)\\]' + \
25               '(?P<semi>;)?'
26
27 ESCAPES = [("\\'", "'"),
28            ('\\"', '"'),
29            ("\\n", "\n"),
30            ("\\r", "\r"),
31            ("\\t", "\t")]
32
33
34 def unescape(s):
35     for (find, repl) in ESCAPES:
36         s = s.replace(find, repl)
37     return s
38
39
40 def block_trim(s):
41     lns = s.splitlines()
42
43     # remove leading/trailing whitespace-lines
44     while lns and not lns[0].strip():
45         lns = lns[1:]
46     while lns and not lns[-1].strip():
47         lns = lns[:-1]
48
49     # remove leading horizontal whitespace
50     n = sys.maxint
51     for ln in lns:
52         if ln.strip():
53             n = min(n, len(re.search('^\s*', ln).group()))
54     if n != sys.maxint:
55         lns = [ln[n:] for ln in lns]
56
57     # strip trailing whitespace
58     lns = [ln.rstrip() for ln in lns]
59
60     return lns
61
62
63 def replace_doc(m):
64     indent = m.group('indent')
65     text = block_trim(unescape(m.group('text')))
66
67     if len(text) > 1:
68         inner = '!' if m.group('semi') else '*'
69         starify = lambda s: indent + ' *' + (' ' + s if s else '')
70         text = '\n'.join(map(starify, text))
71         repl = indent + '/*' + inner + '\n' + text + '\n' + indent + ' */'
72     else:
73         inner = '!' if m.group('semi') else '/'
74         repl = indent + '//' + inner + ' ' + text[0]
75
76     return repl
77
78
79 def sugarise_file(path):
80     s = open(path).read()
81
82     r = re.compile(DOC_PATTERN, re.MULTILINE | re.DOTALL)
83     ns = re.sub(r, replace_doc, s)
84
85     if s != ns:
86         open(path, 'w').write(ns)
87
88
89 for (dirpath, dirnames, filenames) in os.walk('.'):
90     for name in fnmatch.filter(filenames, '*.r[sc]'):
91         sugarise_file(os.path.join(dirpath, name))