summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2008-11-08 13:51:20 +0000
committerEric S. Raymond <esr@thyrsus.com>2008-11-08 13:51:20 +0000
commitd937a77abc7445a834faf45834c3bf32837074c8 (patch)
treea1f63818b1a22cddb8e74a6adfc40f290d73d3e8
parent460b651d3cb425d9da664a59e4888cc25754cca7 (diff)
downloaddeheader-d937a77abc7445a834faf45834c3bf32837074c8.tar.gz
deheader-d937a77abc7445a834faf45834c3bf32837074c8.tar.bz2
deheader-d937a77abc7445a834faf45834c3bf32837074c8.tar.xz
deheader-d937a77abc7445a834faf45834c3bf32837074c8.zip
Refactor dependency mapping.
-rwxr-xr-xdeheader92
1 files changed, 90 insertions, 2 deletions
diff --git a/deheader b/deheader
index 4579300..623dd11 100755
--- a/deheader
+++ b/deheader
@@ -25,10 +25,96 @@ on interrupt or after processing with its original timestamp, unless the
import sys, os, tempfile, getopt, time, re
+class Baton:
+ "Ship progress indications to stderr."
+ def __init__(self, prompt, endmsg=None):
+ self.stream = sys.stderr
+ self.stream.write(prompt + "...")
+ if os.isatty(self.stream.fileno()):
+ self.stream.write(" \010")
+ self.stream.flush()
+ self.count = 0
+ self.endmsg = endmsg
+ self.time = time.time()
+ return
+
+ def twirl(self, ch=None):
+ if self.stream is None:
+ return
+ if os.isatty(self.stream.fileno()):
+ if ch:
+ self.stream.write(ch)
+ else:
+ self.stream.write("-/|\\"[self.count % 4])
+ self.stream.write("\010")
+ self.stream.flush()
+ self.count = self.count + 1
+ return
+
+ def end(self, msg=None):
+ if msg == None:
+ msg = self.endmsg
+ if self.stream:
+ self.stream.write("...(%2.2f sec) %s.\n" % (time.time() - self.time, msg))
+ return
+
def c_source(filename):
"Predicate: return true idf the filename appears to be C or C++ source."
return filename.endswith(".c") or filename.endswith(".cpp")
+class InclusionMap:
+ "Map the inclusion dependebies of a set of files and directories."
+ def __init__(self, roots, ignore, verbosity):
+ "Build the initial inclusion map."
+ self.verbosity = verbosity
+ self.files = []
+ for root in roots:
+ if not os.path.isdir(root):
+ if c_source(root):
+ self.files.append(root)
+ else:
+ for root, dirs, files in os.walk(root):
+ dirs = filter(lambda x: not x.startswith("."), dirs)
+ for name in files:
+ if c_source(name):
+ self.files.append(os.path.join(root, name))
+ self.c_to_h = {}
+ for sourcefile in self.files:
+ includes = []
+ ifdepth = 0
+ for line in open(sourcefile):
+ if line.startswith("#ifdef") or line.startswith("#ifndef"):
+ ifdepth += 1
+ elif line.startswith("#endif"):
+ ifdepth -= 1
+ elif line.startswith("#include"):
+ if verbosity:
+ name = trim(line)
+ print "deheader: %s requires %s" % (sourcefile, name)
+ if ignore.search(line):
+ if verbosity:
+ print "deheader: ignoring %s (exclusion match with %s)." % (name, ignore.pattern)
+ continue
+ if ifdepth == 0:
+ includes.append(line)
+ elif verbose:
+ print "deheader: ignoring %s (conditional inclusion)" % name
+ self.c_to_h[sourcefile] = includes
+ def delete(self, original, altered, includes):
+ "Delete specified headers from a sourcefile,"
+ for header in includes:
+ ofp = open(altered, "w")
+ for line in open(original):
+ if line != header:
+ ofp.write(line)
+ ofp.close()
+ def forget(self, sourcefile, header):
+ "Forget a header dependency."
+ self.c_to_h[altered].remove(header)
+ def remember(self, sourcefile, include):
+ "Undo forgetting of a dependency from the map."
+ self.c_to_h[sourcefile].append(header)
+
def sourcefiles(roots):
"Get the names of sourcefiles at or beneath specified locations."
files = []
@@ -175,5 +261,7 @@ if __name__ == "__main__":
if not arguments:
arguments = ["."]
- for sourcefile in sourcefiles(arguments):
- deheader(sourcefile, ignore, remove, verbose)
+ #for sourcefile in sourcefiles(arguments):
+ # deheader(sourcefile, ignore, remove, verbose)
+ imap = InclusionMap(arguments, ignore, verbose)
+ print imap.c_to_h