#!/usr/bin/env python # # Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT # file at the top-level directory of this distribution and at # http://rust-lang.org/COPYRIGHT. # # Licensed under the Apache License, Version 2.0 or the MIT license # , at your # option. This file may not be copied, modified, or distributed # except according to those terms. # # this script attempts to turn doc comment attributes (#[doc = "..."]) # into sugared-doc-comments (/** ... */ and /// ...) # # it sugarises all .rs/.rc files underneath the working directory # import sys import os import fnmatch import re DOC_PATTERN = '^(?P[\\t ]*)#\\[(\\s*)doc(\\s*)=' + \ '(\\s*)"(?P(\\"|[^"])*?)"(\\s*)\\]' + \ '(?P;)?' ESCAPES = [("\\'", "'"), ('\\"', '"'), ("\\n", "\n"), ("\\r", "\r"), ("\\t", "\t")] def unescape(s): for (find, repl) in ESCAPES: s = s.replace(find, repl) return s def block_trim(s): lns = s.splitlines() # remove leading/trailing whitespace-lines while lns and not lns[0].strip(): lns = lns[1:] while lns and not lns[-1].strip(): lns = lns[:-1] # remove leading horizontal whitespace n = sys.maxint for ln in lns: if ln.strip(): n = min(n, len(re.search('^\s*', ln).group())) if n != sys.maxint: lns = [ln[n:] for ln in lns] # strip trailing whitespace lns = [ln.rstrip() for ln in lns] return lns def replace_doc(m): indent = m.group('indent') text = block_trim(unescape(m.group('text'))) if len(text) > 1: inner = '!' if m.group('semi') else '*' starify = lambda s: indent + ' *' + (' ' + s if s else '') text = '\n'.join(map(starify, text)) repl = indent + '/*' + inner + '\n' + text + '\n' + indent + ' */' else: inner = '!' if m.group('semi') else '/' repl = indent + '//' + inner + ' ' + text[0] return repl def sugarise_file(path): s = open(path).read() r = re.compile(DOC_PATTERN, re.MULTILINE | re.DOTALL) ns = re.sub(r, replace_doc, s) if s != ns: open(path, 'w').write(ns) for (dirpath, dirnames, filenames) in os.walk('.'): for name in fnmatch.filter(filenames, '*.r[sc]'): sugarise_file(os.path.join(dirpath, name))