summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorRuss White <russ@riw.us>2018-02-27 14:55:38 +0100
committerGitHub <noreply@github.com>2018-02-27 14:55:38 +0100
commitb92aee6e7c7b35b02d5089bfb37bcadc4f7b0d54 (patch)
tree3cb762beb11c3030d4e76fcfaa579d120bb3e64c /tools
parentMerge pull request #1772 from qlyoung/fix-keepalive-sentinel (diff)
parent*: move random tools into tools/ (diff)
downloadfrr-b92aee6e7c7b35b02d5089bfb37bcadc4f7b0d54.tar.xz
frr-b92aee6e7c7b35b02d5089bfb37bcadc4f7b0d54.zip
Merge pull request #1770 from qlyoung/random-tools
*: move random tools into tools/
Diffstat (limited to 'tools')
-rw-r--r--tools/git-reindent-branch.py89
-rw-r--r--tools/indent.py47
-rw-r--r--tools/render_md.py28
3 files changed, 164 insertions, 0 deletions
diff --git a/tools/git-reindent-branch.py b/tools/git-reindent-branch.py
new file mode 100644
index 000000000..c207f5946
--- /dev/null
+++ b/tools/git-reindent-branch.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import sys, os
+import subprocess, argparse, tempfile
+import indent
+
+def run(cmd):
+ proc = subprocess.Popen(cmd, stdout = subprocess.PIPE)
+ rv = proc.communicate('')[0].decode('UTF-8')
+ proc.wait()
+ return rv
+
+clangfmt = run(['git', 'show', 'master:.clang-format'])
+
+argp = argparse.ArgumentParser(description = 'git whitespace-fixing tool')
+argp.add_argument('branch', metavar='BRANCH', type = str, nargs = '?', default = 'HEAD')
+args = argp.parse_args()
+
+branch = args.branch
+commit = run(['git', 'rev-list', '-n', '1', branch, '--']).strip()
+
+# frr-3.1-dev = first commit that is on master but not on stable/3.0
+masterid = run(['git', 'rev-list', '-n', '1', 'frr-3.1-dev', '--']).strip()
+masterbase = run(['git', 'merge-base', commit, masterid]).strip()
+
+if masterbase == masterid:
+ refbranch = 'master'
+else:
+ refbranch = '3.0'
+
+sys.stderr.write('autodetected base: %s (can be 3.0 or master)\n' % refbranch)
+
+beforeid = run(['git', 'rev-list', '-n', '1', 'reindent-%s-before' % refbranch, '--']).strip()
+afterid = run(['git', 'rev-list', '-n', '1', 'reindent-%s-after' % refbranch, '--']).strip()
+
+beforebase = run(['git', 'merge-base', commit, beforeid]).strip()
+afterbase = run(['git', 'merge-base', commit, afterid]).strip()
+
+if afterbase == afterid:
+ sys.stderr.write('this branch was already rebased\n')
+ sys.exit(1)
+
+if beforebase != beforeid:
+ sys.stderr.write('you need to rebase your branch onto the tag "reindent-%s-before"\n' % refbranch)
+ sys.exit(1)
+
+revs = run(['git', 'rev-list', 'reindent-%s-before..%s' % (refbranch, commit)]).strip().split('\n')
+revs.reverse()
+
+srcdir = os.getcwd()
+tmpdir = tempfile.mkdtemp('frrindent')
+os.chdir(tmpdir)
+
+sys.stderr.write('using temporary directory %s; %d revisions\n' % (tmpdir, len(revs)))
+run(['git', 'clone', '-s', '-b', 'reindent-%s-after' % refbranch, srcdir, 'repo'])
+os.chdir('repo')
+
+with open('.clang-format', 'w') as fd:
+ fd.write(clangfmt)
+
+prev = beforeid
+for rev in revs:
+ filestat = run(['git', 'diff', '-z', '--name-status', prev, rev]).rstrip('\0').split('\0')
+ changes = zip(filestat[0::2], filestat[1::2])
+ sys.stderr.write('%s: %d files\n' % (rev, len(changes)))
+
+ for typ, name in changes:
+ if typ == 'D':
+ run(['git', 'rm', name])
+ elif typ in ['A', 'M']:
+ run(['git', 'checkout', rev, '--', name])
+ if name.endswith('.c') or name.endswith('.h'):
+ for d in ['babeld/', 'ldpd/', 'nhrpd/']:
+ if name.startswith(d):
+ break
+ else:
+ sys.stderr.write('\t%s\n' % name)
+ indent.wrap_file(name)
+ run(['git', 'add', name])
+
+ run(['git', 'commit', '-C', rev])
+ prev = rev
+
+run(['git', 'push', 'origin', 'HEAD:refs/heads/reindented-branch'])
+sys.stderr.write('\n\n"reindented-branch" should now be OK.\n')
+sys.stderr.write('you could use "git reset --hard reindented-branch" to set your current branch to the reindented output\n')
+sys.stderr.write('\033[31;1mplease always double-check the output\033[m\n')
+
diff --git a/tools/indent.py b/tools/indent.py
new file mode 100644
index 000000000..560c13c77
--- /dev/null
+++ b/tools/indent.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# 2017 by David Lamparter, placed in public domain
+
+import sys, re, subprocess, os
+
+# find all DEFUNs
+defun_re = re.compile(
+ r'^((DEF(UN(_NOSH|_HIDDEN)?|PY)|ALIAS)\s*\(.*?)^(?=\s*\{)',
+ re.M | re.S)
+define_re = re.compile(
+ r'((^#\s*define[^\n]+[^\\]\n)+)',
+ re.M | re.S)
+# find clang-format control that we just inserted
+clean_re = re.compile(
+ r'^/\* \$FRR indent\$ \*/\s*\n\s*/\* clang-format (on|off) \*/\s*\n',
+ re.M)
+
+def wrap_file(fn):
+ with open(fn, 'r') as fd:
+ text = fd.read()
+
+ repl = r'/* $FRR indent$ */\n/* clang-format off */\n' + \
+ r'\1' + \
+ r'/* $FRR indent$ */\n/* clang-format on */\n'
+
+ # around each DEFUN, insert an indent-on/off comment
+ text = defun_re.sub(repl, text)
+ text = define_re.sub(repl, text)
+
+ ci = subprocess.Popen(['clang-format'], stdin = subprocess.PIPE, stdout = subprocess.PIPE)
+ stdout, ign = ci.communicate(text)
+ ci.wait()
+ if ci.returncode != 0:
+ raise IOError('clang-format returned %d' % (ci.returncode))
+
+ # remove the bits we inserted above
+ final = clean_re.sub('', stdout)
+
+ tmpname = fn + '.indent'
+ with open(tmpname, 'w') as ofd:
+ ofd.write(final)
+ os.rename(tmpname, fn)
+
+if __name__ == '__main__':
+ for fn in sys.argv[1:]:
+ wrap_file(fn)
diff --git a/tools/render_md.py b/tools/render_md.py
new file mode 100644
index 000000000..16c4bbe8a
--- /dev/null
+++ b/tools/render_md.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+# written 2016 by David Lamparter, placed in Public Domain.
+import sys, markdown
+
+template = '''<html><head><meta charset="UTF-8"><style type="text/css">
+body { max-width: 45em; margin: auto; margin-top: 2em; margin-bottom: 2em;
+ font-family:Fira Sans,sans-serif; text-align: justify;
+ counter-reset: ch2; }
+pre, code { font-family:Fira Mono,monospace; }
+pre > code { display: block; padding:0.5em; border:1px solid black;
+ background-color:#eee; color:#000; }
+h2:before { content: counter(ch2) ". "; counter-increment: ch2; }
+h2 { clear: both; margin-top: 3em; text-decoration: underline; counter-reset: ch3; }
+h3:before { content: counter(ch2) "." counter(ch3) ". "; counter-increment: ch3; }
+h3 { clear: both; margin-top: 2em; font-weight: normal; font-style: italic; }
+h4 { font-weight: normal; font-style: italic; }
+img[alt~="float-right"] { float:right; margin-left:2em; margin-bottom:2em; }
+</style></head><body>
+%s
+</body></html>
+'''
+
+md = markdown.Markdown(extensions=['extra', 'toc'])
+
+for fn in sys.argv[1:]:
+ with open(fn, 'r') as ifd:
+ with open('%s.html' % (fn), 'w') as ofd:
+ ofd.write((template % (md.convert(ifd.read().decode('UTF-8')))).encode('UTF-8'))