Clean the contrib directory with torch and machete.

We've accumulated a lot of cruft in this directory over the years: so
much, that it passed the point of being so disorganized that we no
longer browsed through it to see how bad it had gotten.

This patch (based on changes by rl1987) tries to remove the most
useless items, and split the others into reasonable directories.  It
creates a new scripts/ directory for maint and test scripts.

This patch was generated with the script below.  No other changes are made in
this patch.

#############
# new directories
mkdir -p contrib/test-tools
mkdir -p contrib/or-tools
mkdir -p contrib/dirauth-tools
mkdir -p contrib/operator-tools
mkdir -p contrib/client-tools
mkdir -p contrib/test-tools
mkdir -p contrib/dist
mkdir -p contrib/dist/suse
mkdir -p contrib/win32build

mkdir -p scripts/maint
mkdir -p scripts/test

############
# Deleted -- nobody who wants this is going to be looking for it here any
# longer.  Also, nobody wants it.
git rm contrib/auto-naming/README

# Deleted: We no longer do polipo.
git rm contrib/polipo/Makefile.mingw
git rm contrib/polipo/README
git rm contrib/polipo/polipo-mingw.nsi

# We haven't even tried to run this for ages. It is a relic of a bygone era
git rm contrib/mdd.py

# contrib/dir-tools/directory-archive/
# Tools for running a directory archive. No longer used - deleting them.
git rm contrib/directory-archive/crontab.sample
git rm contrib/directory-archive/fetch-all
git rm contrib/directory-archive/fetch-all-v3
git rm contrib/directory-archive/tar-them-up
git rm contrib/directory-archive/fetch-all-functions
git rm contrib/directory-archive/sort-into-month-folder

# This appears to be related to very old windows packaging stuff.
git rm contrib/bundle.nsi
git rm contrib/package_nsis-weasel.sh
git rm contrib/package_nsis.sh
git rm contrib/netinst.nsi
git rm contrib/torinst32.ico
git rm contrib/xenobite.ico

# This should not be needed for cross-compilation any more, should it?
git rm contrib/cross.sh

# I don't think anyone ever used this.
git rm contrib/make-signature.sh

# These are attempts to send tor controller commands from the command-line.
# They don't support modern authentication.
git rm contrib/tor-ctrl.sh

# this is for fetching about a tor server from a dirauth. But it
# doesn't authenticate the dirauth: yuck.
git rm contrib/sd

# wow, such unused, very perl4.
git rm contrib/tor-stress

####### contrib/dirauth-tools/
# Tools for running a directory authority

git mv contrib/add-tor contrib/dirauth-tools/
git mv contrib/nagios-check-tor-authority-cert contrib/dirauth-tools/

#######
# contrib/or-tools/
# Tools for examining relays
git mv contrib/check-tor contrib/or-tools/check-tor
git mv contrib/checksocks.pl contrib/or-tools/checksocks.pl
git mv contrib/exitlist contrib/or-tools/exitlist

#######
# contrib/operator-tools

# Tools for running a relay.
git mv contrib/linux-tor-prio.sh contrib/operator-tools/linux-tor-prio.sh
git mv contrib/tor-exit-notice.html contrib/operator-tools/tor-exit-notice.html
git mv contrib/tor.logrotate.in contrib/operator-tools/

######
# contrib/dist

git mv contrib/rc.subr contrib/dist/
git mv contrib/tor.sh.in contrib/dist/
git mv contrib/torctl.in contrib/dist/
git mv contrib/suse/* contrib/dist/suse/

######
# client-tools
git mv contrib/torify contrib/client-tools/torify
git mv contrib/tor-resolve.py contrib/client-tools/

######
# win32build

git mv contrib/package_nsis-mingw.sh contrib/win32build/
git mv contrib/tor.nsi.in contrib/win32build/
# Erinn didn't ask for this...
git mv contrib/tor-mingw.nsi.in contrib/win32build/
git mv contrib/tor.ico contrib/win32build/

######
# scripts/test
git mv contrib/cov-blame scripts/test/cov-blame
git mv contrib/cov-diff scripts/test/cov-diff
git mv contrib/coverage scripts/test/coverage
git mv contrib/scan-build.sh scripts/test/

######## scripts/maint
# Maintainance scripts
#
# These are scripts for developers to use when hacking on Tor.  They mostly
# look at the Tor source in one way or another.
git mv contrib/findMergedChanges.pl scripts/maint/findMergedChanges.pl
git mv contrib/checkOptionDocs.pl scripts/maint/checkOptionDocs.pl
git mv contrib/checkSpace.pl scripts/maint/checkSpace.pl
git mv contrib/redox.py scripts/maint/redox.py
git mv contrib/updateVersions.pl scripts/maint/updateVersions.pl
git mv contrib/checkLogs.pl scripts/maint/checkLogs.pl
git mv contrib/format_changelog.py scripts/maint/
This commit is contained in:
Nick Mathewson
2014-04-28 11:34:53 -04:00
parent 78b431d3e3
commit 9230bc7c65
52 changed files with 0 additions and 1853 deletions
+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/perl -w
use strict;
my %count = ();
my $more = 0;
my $last = "";
while (<>) {
if ($more) {
if (/LD_BUG/) {
$more = 0;
next;
}
if (/\"((?:[^\"\\]+|\\.*)+)\"(.*)/) {
$last .= $1;
if ($2 !~ /[,\)]/) {
$more = 1;
} else {
$count{lc $last}++;
$more = 0;
}
} elsif (/[,\)]/) {
$count{lc $last}++;
$more = 0;
} elsif ($more == 2) {
print "SKIPPED more\n";
}
} elsif (/log_(?:warn|err|notice)\(\s*(LD_[A-Z_]*)\s*,\s*\"((?:[^\"\\]+|\\.)*)\"(.*)/) {
next if ($1 eq 'LD_BUG');
my $s = $2;
if ($3 =~ /[,\)]/ ) {
$count{lc $s}++;
} else {
$more = 1;
$last = $s;
}
} elsif (/log_(?:warn|err|notice)\(\s*((?:LD_[A-Z_]*)?)(.*)/) {
next if ($1 eq 'LD_BUG');
my $extra = $2;
chomp $extra;
$last = "";
$more = 2 if ($extra eq '');
}
}
while ((my $phrase, my $count) = each %count) {
if ($count > 1) {
print "$count\t$phrase\n";
}
}
+70
View File
@@ -0,0 +1,70 @@
#!/usr/bin/perl -w
use strict;
my %options = ();
my %descOptions = ();
my %torrcSampleOptions = ();
my %manPageOptions = ();
# Load the canonical list as actually accepted by Tor.
open(F, "./src/or/tor --list-torrc-options |") or die;
while (<F>) {
next if m!\[notice\] Tor v0\.!;
if (m!^([A-Za-z0-9_]+)!) {
$options{$1} = 1;
} else {
print "Unrecognized output> ";
print;
}
}
close F;
# Load the contents of torrc.sample
sub loadTorrc {
my ($fname, $options) = @_;
local *F;
open(F, "$fname") or die;
while (<F>) {
next if (m!##+!);
if (m!#([A-Za-z0-9_]+)!) {
$options->{$1} = 1;
}
}
close F;
0;
}
loadTorrc("./src/config/torrc.sample.in", \%torrcSampleOptions);
# Try to figure out what's in the man page.
my $considerNextLine = 0;
open(F, "./doc/tor.1.txt") or die;
while (<F>) {
if (m!^\*\*([A-Za-z0-9_]+)\*\*!) {
$manPageOptions{$1} = 1;
}
}
close F;
# Now, display differences:
sub subtractHashes {
my ($s, $a, $b) = @_;
my @lst = ();
for my $k (keys %$a) {
push @lst, $k unless (exists $b->{$k});
}
print "$s: ", join(' ', sort @lst), "\n\n";
0;
}
# subtractHashes("No online docs", \%options, \%descOptions);
# subtractHashes("Orphaned online docs", \%descOptions, \%options);
subtractHashes("Orphaned in torrc.sample.in", \%torrcSampleOptions, \%options);
subtractHashes("Not in man page", \%options, \%manPageOptions);
subtractHashes("Orphaned in man page", \%manPageOptions, \%options);
+138
View File
@@ -0,0 +1,138 @@
#!/usr/bin/perl -w
if ($ARGV[0] =~ /^-/) {
$lang = shift @ARGV;
$C = ($lang eq '-C');
# $TXT = ($lang eq '-txt');
}
for $fn (@ARGV) {
open(F, "$fn");
$lastnil = 0;
$lastline = "";
$incomment = 0;
while (<F>) {
## Warn about windows-style newlines.
if (/\r/) {
print " CR:$fn:$.\n";
}
## Warn about tabs.
if (/\t/) {
print " TAB:$fn:$.\n";
}
## Warn about markers that don't have a space in front of them
if (/^[a-zA-Z_][a-zA-Z_0-9]*:/) {
print "nosplabel:$fn:$.\n";
}
## Warn about trailing whitespace.
if (/ +$/) {
print "Space\@EOL:$fn:$.\n";
}
## Warn about control keywords without following space.
if ($C && /\s(?:if|while|for|switch)\(/) {
print " KW(:$fn:$.\n";
}
## Warn about #else #if instead of #elif.
if (($lastline =~ /^\# *else/) and ($_ =~ /^\# *if/)) {
print " #else#if:$fn:$.\n";
}
## Warn about some K&R violations
if (/^\s+\{/ and $lastline =~ /^\s*(if|while|for|else if)/ and
$lastline !~ /\{$/) {
print "non-K&R {:$fn:$.\n";
}
if (/^\s*else/ and $lastline =~ /\}$/) {
print " }\\nelse:$fn:$.\n";
}
$lastline = $_;
## Warn about unnecessary empty lines.
if ($lastnil && /^\s*}\n/) {
print " UnnecNL:$fn:$.\n";
}
## Warn about multiple empty lines.
if ($lastnil && /^$/) {
print " DoubleNL:$fn:$.\n";
} elsif (/^$/) {
$lastnil = 1;
} else {
$lastnil = 0;
}
## Terminals are still 80 columns wide in my world. I refuse to
## accept double-line lines.
if (/^.{80}/) {
print " Wide:$fn:$.\n";
}
### Juju to skip over comments and strings, since the tests
### we're about to do are okay there.
if ($C) {
if ($incomment) {
if (m!\*/!) {
s!.*?\*/!!;
$incomment = 0;
} else {
next;
}
}
if (m!/\*.*?\*/!) {
s!\s*/\*.*?\*/!!;
} elsif (m!/\*!) {
s!\s*/\*!!;
$incomment = 1;
next;
}
s!"(?:[^\"]+|\\.)*"!"X"!g;
next if /^\#/;
## Warn about C++-style comments.
if (m!//!) {
# print " //:$fn:$.\n";
s!//.*!!;
}
## Warn about unquoted braces preceded by non-space.
if (/([^\s'])\{/) {
print " $1\{:$fn:$.\n";
}
## Warn about multiple internal spaces.
#if (/[^\s,:]\s{2,}[^\s\\=]/) {
# print " X X:$fn:$.\n";
#}
## Warn about { with stuff after.
#s/\s+$//;
#if (/\{[^\}\\]+$/) {
# print " {X:$fn:$.\n";
#}
## Warn about function calls with space before parens.
if (/(\w+)\s\(([A-Z]*)/) {
if ($1 ne "if" and $1 ne "while" and $1 ne "for" and
$1 ne "switch" and $1 ne "return" and $1 ne "int" and
$1 ne "elsif" and $1 ne "WINAPI" and $2 ne "WINAPI" and
$1 ne "void" and $1 ne "__attribute__" and $1 ne "op") {
print " fn ():$fn:$.\n";
}
}
## Warn about functions not declared at start of line.
if ($in_func_head ||
($fn !~ /\.h$/ && /^[a-zA-Z0-9_]/ &&
! /^(?:const |static )*(?:typedef|struct|union)[^\(]*$/ &&
! /= *\{$/ && ! /;$/)) {
if (/.\{$/){
print "fn() {:$fn:$.\n";
$in_func_head = 0;
} elsif (/^\S[^\(]* +\**[a-zA-Z0-9_]+\(/) {
$in_func_head = -1; # started with tp fn
} elsif (/;$/) {
$in_func_head = 0;
} elsif (/\{/) {
if ($in_func_head == -1) {
print "tp fn():$fn:$.\n";
}
$in_func_head = 0;
}
}
}
}
if (! $lastnil) {
print " EOL\@EOF:$fn:$.\n";
}
close(F);
}
+73
View File
@@ -0,0 +1,73 @@
#!/usr/bin/perl
use warnings;
use strict;
sub nChanges {
my ($branches, $fname) = @_;
local *F;
# requires perl 5.8. Avoids shell issues if we ever get a changes
# file named by the parents of Little Johnny Tables.
open F, "-|", "git", "log", "--no-merges", "--pretty=format:%H", $branches, "--", $fname
or die "$!";
my @changes = <F>;
return scalar @changes
}
my $look_for_type = "merged";
if (! @ARGV) {
print <<EOF
Usage:
findMergedChanges.pl [--merged/--unmerged/--weird/--list] [--branch=<branchname] [--head=<branchname>] changes/*
A change is "merged" if it has ever been merged to release-0.2.4 and it has had
no subsequent changes in master.
A change is "unmerged" if it has never been merged to release-0.2.4 and it
has had changes in master.
A change is "weird" if it has been merged to release-0.2.4 and it *has* had
subsequent changes in master.
Suggested application:
findMergedChanges.pl --merged changes/* | xargs -n 1 git rm
EOF
}
my $target_branch = "origin/release-0.2.4";
my $head = "origin/master";
while (@ARGV and $ARGV[0] =~ /^--/) {
my $flag = shift @ARGV;
if ($flag =~ /^--(weird|merged|unmerged|list)/) {
$look_for_type = $1;
} elsif ($flag =~ /^--branch=(\S+)/) {
$target_branch = $1;
} elsif ($flag =~ /^--head=(\S+)/) {
$head = $1;
} else {
die "Unrecognized flag $flag";
}
}
for my $changefile (@ARGV) {
my $n_merged = nChanges($target_branch, $changefile);
my $n_postmerged = nChanges("${target_branch}..${head}", $changefile);
my $type;
if ($n_merged != 0 and $n_postmerged == 0) {
$type = "merged";
} elsif ($n_merged == 0 and $n_postmerged != 0) {
$type = "unmerged";
} else {
$type = "weird";
}
if ($type eq $look_for_type) {
print "$changefile\n";
} elsif ($look_for_type eq 'list') {
printf "% 8s: %s\n", $type, $changefile;
}
}
+162
View File
@@ -0,0 +1,162 @@
#!/usr/bin/python
# Copyright (c) 2014, The Tor Project, Inc.
# See LICENSE for licensing information
#
# This script reformats a section of the changelog to wrap everything to
# the right width and put blank lines in the right places. Eventually,
# it might include a linter.
#
# To run it, pipe a section of the changelog (starting with "Changes
# in Tor 0.x.y.z-alpha" through the script.)
import os
import re
import sys
import textwrap
TP_MAINHEAD = 0
TP_HEADTEXT = 1
TP_BLANK = 2
TP_SECHEAD = 3
TP_ITEMFIRST = 4
TP_ITEMBODY = 5
TP_END = 6
def head_parser(line):
if re.match(r'^[A-Z]', line):
return TP_MAINHEAD
elif re.match(r'^ o ', line):
return TP_SECHEAD
elif re.match(r'^\s*$', line):
return TP_BLANK
else:
return TP_HEADTEXT
def body_parser(line):
if re.match(r'^ o ', line):
return TP_SECHEAD
elif re.match(r'^ -',line):
return TP_ITEMFIRST
elif re.match(r'^ \S', line):
return TP_ITEMBODY
elif re.match(r'^\s*$', line):
return TP_BLANK
elif re.match(r'^Changes in', line):
return TP_END
else:
print "Weird line %r"%line
class ChangeLog(object):
def __init__(self):
self.mainhead = None
self.headtext = []
self.curgraf = None
self.sections = []
self.cursection = None
self.lineno = 0
def addLine(self, tp, line):
self.lineno += 1
if tp == TP_MAINHEAD:
assert not self.mainhead
self.mainhead = line
elif tp == TP_HEADTEXT:
if self.curgraf is None:
self.curgraf = []
self.headtext.append(self.curgraf)
self.curgraf.append(line)
elif tp == TP_BLANK:
self.curgraf = None
elif tp == TP_SECHEAD:
self.cursection = [ self.lineno, line, [] ]
self.sections.append(self.cursection)
elif tp == TP_ITEMFIRST:
item = ( self.lineno, [ [line] ])
self.curgraf = item[1][0]
self.cursection[2].append(item)
elif tp == TP_ITEMBODY:
if self.curgraf is None:
self.curgraf = []
self.cursection[2][1][-1].append(self.curgraf)
self.curgraf.append(line)
else:
assert "This" is "unreachable"
def lint_head(self, line, head):
m = re.match(r'^ *o ([^\(]+)((?:\([^\)]+\))?):', head)
if not m:
print >>sys.stderr, "Weird header format on line %s"%line
def lint_item(self, line, grafs, head_type):
pass
def lint(self):
self.head_lines = {}
for sec_line, sec_head, items in self.sections:
head_type = self.lint_head(sec_line, sec_head)
for item_line, grafs in items:
self.lint_item(item_line, grafs, head_type)
def dumpGraf(self,par,indent1,indent2=-1):
if indent2 == -1:
indent2 = indent1
text = " ".join(re.sub(r'\s+', ' ', line.strip()) for line in par)
print textwrap.fill(text, width=72,
initial_indent=" "*indent1,
subsequent_indent=" "*indent2,
break_on_hyphens=False)
def dump(self):
print self.mainhead
for par in self.headtext:
self.dumpGraf(par, 2)
print
for _,head,items in self.sections:
if not head.endswith(':'):
print >>sys.stderr, "adding : to %r"%head
head = head + ":"
print head
for _,grafs in items:
self.dumpGraf(grafs[0],4,6)
for par in grafs[1:]:
print
self.dumpGraf(par,6,6)
print
print
CL = ChangeLog()
parser = head_parser
sys.stdin = open('ChangeLog', 'r')
for line in sys.stdin:
line = line.rstrip()
tp = parser(line)
if tp == TP_SECHEAD:
parser = body_parser
elif tp == TP_END:
nextline = line
break
CL.addLine(tp,line)
CL.lint()
sys.stdout = open('ChangeLog.new', 'w')
CL.dump()
print nextline
for line in sys.stdin:
sys.stdout.write(line)
os.rename('ChangeLog.new', 'ChangeLog')
+228
View File
@@ -0,0 +1,228 @@
#!/usr/bin/python
#
# Copyright (c) 2008-2013, The Tor Project, Inc.
# See LICENSE for licensing information.
#
# Hi!
# I'm redox.py, the Tor redocumentation tool!
# I am a horrible hack!
# I read the output of doxygen from stderr, and add missing DOCDOC comments
# to tell you where documentation should go!
# To use me, edit the stuff below...
# ...and run 'make doxygen 2>doxygen.stderr' ...
# ...and run ./contrib/redox.py < doxygen.stderr !
# I'll make a bunch of new files by adding missing DOCDOC comments to your
# source. Those files will have names like ./src/common/util.c.newdoc.
# You will want to look over the changes by hand before checking them in.
#
# So, here's your workflow:
#
# 0. Make sure you're running a bourne shell for the redirects below.
# 1. make doxygen 1>doxygen.stdout 2>doxygen.stderr.
# 2. grep Warning doxygen.stderr | grep -v 'is not documented' | less
# [This will tell you about all the bogus doxygen output you have]
# 3. python ./contrib/redox.py <doxygen.stderr
# [This will make lots of .newdoc files with DOCDOC comments for
# whatever was missing documentation.]
# 4. Look over those .newdoc files, and see which docdoc comments you
# want to merge into the main file. If it's all good, just run
# "mv fname.c.newdoc fname.c". Otherwise, you'll need to merge
# the parts you like by hand.
# Which files should we ignore warning from? Mostly, these are external
# files that we've snarfed in from somebody else, whose C we do no intend
# to document for them.
SKIP_FILES = [ "OpenBSD_malloc_Linux.c",
"eventdns.c",
"eventdns.h",
"strlcat.c",
"strlcpy.c",
"sha256.c",
"sha256.h",
"aes.c",
"aes.h" ]
# What names of things never need javadoc
SKIP_NAME_PATTERNS = [ r'^.*_c_id$',
r'^.*_H_ID$' ]
# Which types of things should get DOCDOC comments added if they are
# missing documentation? Recognized types are in KINDS below.
ADD_DOCDOCS_TO_TYPES = [ 'function', 'type', 'typedef' ]
ADD_DOCDOCS_TO_TYPES += [ 'variable', ]
# ====================
# The rest of this should not need hacking.
import re
import sys
KINDS = [ "type", "field", "typedef", "define", "function", "variable",
"enumeration" ]
NODOC_LINE_RE = re.compile(r'^([^:]+):(\d+): (\w+): (.*) is not documented\.$')
THING_RE = re.compile(r'^Member ([a-zA-Z0-9_]+).*\((typedef|define|function|variable|enumeration|macro definition)\) of (file|class) ')
SKIP_NAMES = [re.compile(s) for s in SKIP_NAME_PATTERNS]
def parsething(thing):
"""I figure out what 'foobar baz in quux quum is not documented' means,
and return: the name of the foobar, and the kind of the foobar.
"""
if thing.startswith("Compound "):
tp, name = "type", thing.split()[1]
else:
m = THING_RE.match(thing)
if not m:
print thing, "???? Format didn't match."
return None, None
else:
name, tp, parent = m.groups()
if parent == 'class':
if tp == 'variable' or tp == 'function':
tp = 'field'
return name, tp
def read():
"""I snarf doxygen stderr from stdin, and parse all the "foo has no
documentation messages. I return a map from filename to lists
of tuples of (alleged line number, name of thing, kind of thing)
"""
errs = {}
for line in sys.stdin:
m = NODOC_LINE_RE.match(line)
if m:
file, line, tp, thing = m.groups()
assert tp.lower() == 'warning'
name, kind = parsething(thing)
errs.setdefault(file, []).append((int(line), name, kind))
return errs
def findline(lines, lineno, ident):
"""Given a list of all the lines in the file (adjusted so 1-indexing works),
a line number that ident is alledgedly on, and ident, I figure out
the line where ident was really declared."""
lno = lineno
for lineno in xrange(lineno, 0, -1):
try:
if ident in lines[lineno]:
return lineno
except IndexError:
continue
return None
FUNC_PAT = re.compile(r"^[A-Za-z0-9_]+\(")
def hascomment(lines, lineno, kind):
"""I return true if it looks like there's already a good comment about
the thing on lineno of lines of type kind. """
if "*/" in lines[lineno-1]:
return True
if kind == 'function' and FUNC_PAT.match(lines[lineno]):
if "*/" in lines[lineno-2]:
return True
return False
def hasdocdoc(lines, lineno, kind):
"""I return true if it looks like there's already a docdoc comment about
the thing on lineno of lines of type kind."""
try:
if "DOCDOC" in lines[lineno]:
return True
except IndexError:
pass
try:
if "DOCDOC" in lines[lineno-1]:
return True
except IndexError:
pass
if kind == 'function' and FUNC_PAT.match(lines[lineno]):
if "DOCDOC" in lines[lineno-2]:
return True
return False
def checkf(fn, errs):
"""I go through the output of read() for a single file, and build a list
of tuples of things that want DOCDOC comments. Each tuple has:
the line number where the comment goes; the kind of thing; its name.
"""
for skip in SKIP_FILES:
if fn.endswith(skip):
print "Skipping",fn
return
comments = []
lines = [ None ]
try:
lines.extend( open(fn, 'r').readlines() )
except IOError:
return
for line, name, kind in errs:
if any(pat.match(name) for pat in SKIP_NAMES):
continue
if kind not in ADD_DOCDOCS_TO_TYPES:
continue
ln = findline(lines, line, name)
if ln == None:
print "Couldn't find the definition of %s allegedly on %s of %s"%(
name, line, fn)
else:
if hasdocdoc(lines, line, kind):
# print "Has a DOCDOC"
# print fn, line, name, kind
# print "\t",lines[line-2],
# print "\t",lines[line-1],
# print "\t",lines[line],
# print "-------"
pass
else:
if kind == 'function' and FUNC_PAT.match(lines[ln]):
ln = ln - 1
comments.append((ln, kind, name))
return comments
def applyComments(fn, entries):
"""I apply lots of comments to the file in fn, making a new .newdoc file.
"""
N = 0
lines = [ None ]
try:
lines.extend( open(fn, 'r').readlines() )
except IOError:
return
# Process the comments in reverse order by line number, so that
# the line numbers for the ones we haven't added yet remain valid
# until we add them. Standard trick.
entries.sort()
entries.reverse()
for ln, kind, name in entries:
lines.insert(ln, "/* DOCDOC %s */\n"%name)
N += 1
outf = open(fn+".newdoc", 'w')
for line in lines[1:]:
outf.write(line)
outf.close()
print "Added %s DOCDOCs to %s" %(N, fn)
e = read()
for fn, errs in e.iteritems():
print `(fn, errs)`
comments = checkf(fn, errs)
if comments:
applyComments(fn, comments)
+59
View File
@@ -0,0 +1,59 @@
#!/usr/bin/perl -w
$CONFIGURE_IN = './configure.ac';
$ORCONFIG_H = './src/win32/orconfig.h';
$TOR_NSI = './contrib/tor-mingw.nsi.in';
$quiet = 1;
sub demand {
my $fn = shift;
die "Missing file $fn" unless (-f $fn);
}
demand($CONFIGURE_IN);
demand($ORCONFIG_H);
demand($TOR_NSI);
# extract version from configure.ac
open(F, $CONFIGURE_IN) or die "$!";
$version = undef;
while (<F>) {
if (/AC_INIT\(\[tor\],\s*\[([^\]]*)\]\)/) {
$version = $1;
last;
}
}
die "No version found" unless $version;
print "Tor version is $version\n" unless $quiet;
close F;
sub correctversion {
my ($fn, $defchar) = @_;
undef $/;
open(F, $fn) or die "$!";
my $s = <F>;
close F;
if ($s =~ /^$defchar(?:)define\s+VERSION\s+\"([^\"]+)\"/m) {
$oldver = $1;
if ($oldver ne $version) {
print "Version mismatch in $fn: It thinks that the version is $oldver. I think it's $version. Fixing.\n";
$line = $defchar . "define VERSION \"$version\"";
open(F, ">$fn.bak");
print F $s;
close F;
$s =~ s/^$defchar(?:)define\s+VERSION.*?$/$line/m;
open(F, ">$fn");
print F $s;
close F;
} else {
print "$fn has the correct version. Good.\n" unless $quiet;
}
} else {
print "Didn't find a version line in $fn -- uh oh.\n";
}
}
correctversion($TOR_NSI, "!");
correctversion($ORCONFIG_H, "#");
+48
View File
@@ -0,0 +1,48 @@
#!/usr/bin/python
import os
import re
import subprocess
import sys
def handle_file(source_fname, cov_fname):
lines_blm = subprocess.Popen(["git", "blame", source_fname], stdout=subprocess.PIPE).stdout.readlines()
lines_cov = open(cov_fname).readlines()
# XXXX expensive!
while re.match(r'\s*-:\s*0:', lines_cov[0]):
del lines_cov[0]
if len(lines_blm) != len(lines_cov):
print >>sys.stderr, "MISMATCH IN NUMBER OF LINES in",source_fname
for b,c in zip(lines_blm, lines_cov):
m = re.match(r'\s*([^\s:]+):', c)
if not m:
print >>sys.stderr, "CONFUSING LINE %r"% c
cov = 'X'
elif m.group(1) == '-':
cov = '-'
elif m.group(1)[0] == '#':
cov = '#'
elif m.group(1)[0].isdigit():
cov = '1'
else:
print >>sys.stderr, "CONFUSING LINE %r"% c
cov = 'X'
print cov, b,
COV_DIR = sys.argv[1]
SOURCES = sys.argv[2:]
for fn in SOURCES:
_, base = os.path.split(fn)
cfn = os.path.join(COV_DIR, base)
cfn += ".gcov"
if os.path.exists(cfn):
handle_file(fn, cfn)
else:
print >>sys.stderr, "NO FILE EXISTS CALLED ",cfn
+17
View File
@@ -0,0 +1,17 @@
#!/bin/sh
# Copyright 2013 The Tor Project, Inc.
# See LICENSE for licensing information.
# cov-diff -- compare two directories full of gcov files.
DIRA="$1"
DIRB="$2"
for A in $DIRA/*; do
B=$DIRB/`basename $A`
perl -pe 's/^\s*\d+:/ 1:/; s/^([^:]+:)[\d\s]+:/$1/;' "$A" > "$A.tmp"
perl -pe 's/^\s*\d+:/ 1:/; s/^([^:]+:)[\d\s]+:/$1/;' "$B" > "$B.tmp"
diff -u "$A.tmp" "$B.tmp"
rm "$A.tmp" "$B.tmp"
done
+46
View File
@@ -0,0 +1,46 @@
#!/bin/sh
# Copyright 2013 The Tor Project, Inc.
# See LICENSE for licensing information.
# coverage -- run gcov on the appropriate set of object files to extract
# coverage information.
dst=$1
for fn in src/or/*.c src/common/*.c; do
BN=`basename $fn`
DN=`dirname $fn`
F=`echo $BN | sed -e 's/\.c$//;'`
GC="${BN}.gcov"
# Figure out the object file names
ONS=`echo ${DN}/src_*-${F}.o`
ONS_WILDCARD_LITERAL="${DN}/src_*-${F}.o"
# If the wildcard didn't expand, no files
if [ "$ONS" != "${ONS_WILDCARD_LITERAL}" ]
then
for on in $ONS; do
# We should have a gcno file
GCNO=`echo $on | sed -e 's/\.o$/\.gcno/;'`
if [ -e $GCNO ]
then
# No need to test for gcda, since gcov assumes no execution
# if it's absent
rm -f $GC
gcov -o $on $fn
if [ -e $GC ]
then
if [ -n $dst ]
then
mv $GC $dst/$GC
fi
else
echo "gcov -o $on $fn didn't make a .gcov file"
fi
else
echo "Couldn't find gcno file for $on"
fi
done
else
echo "No object file found matching source file $fn"
fi
done
+49
View File
@@ -0,0 +1,49 @@
#!/bin/sh
# Copyright 2014 The Tor Project, Inc
# See LICENSE for licensing information
#
# This script is used for running a bunch of clang scan-build checkers
# on Tor.
#
# It has hardwired paths for Nick's desktop at the moment.
CHECKERS="\
--use-analyzer=/opt/clang-3.4/bin/clang \
-disable-checker deadcode.DeadStores \
-enable-checker alpha.core.CastSize \
-enable-checker alpha.core.CastToStruct \
-enable-checker alpha.core.IdenticalExpr \
-enable-checker alpha.core.SizeofPtr \
-enable-checker alpha.security.ArrayBoundV2 \
-enable-checker alpha.security.MallocOverflow \
-enable-checker alpha.security.ReturnPtrRange \
-enable-checker alpha.unix.SimpleStream
-enable-checker alpha.unix.cstring.BufferOverlap \
-enable-checker alpha.unix.cstring.NotNullTerminated \
-enable-checker alpha.unix.cstring.OutOfBounds \
-enable-checker alpha.core.FixedAddr \
-enable-checker security.insecureAPI.strcpy
"
/opt/clang-3.4/bin/scan-build/scan-build \
$CHECKERS \
--use-analyzer=/opt/clang-3.4/bin/clang \
./configure
/opt/clang-3.4/bin/scan-build/scan-build \
$CHECKERS \
--use-analyzer=/opt/clang-3.4/bin/clang \
make -j2
# Haven't tried this yet.
# -enable-checker alpha.unix.PthreadLock
# This one gives a false positive on every strcmp.
# -enable-checker alpha.core.PointerSub
# This one hates it when we stick a nonzero const in a pointer.
# -enable-checker alpha.core.FixedAddr
# This one crashes sometimes for me.
# -enable-checker alpha.deadcode.IdempotentOperations