summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2008-11-06 13:59:58 +0000
committerEric S. Raymond <esr@thyrsus.com>2008-11-06 13:59:58 +0000
commit95fc7de08928a7b19930be8446707ba7bfbafbe4 (patch)
tree2302e988ff296fc049924fc2ee7a9320bc3883b7
parent6da2ddf3cfb11e3336faecdd98a8424c9a13760e (diff)
downloaddeheader-95fc7de08928a7b19930be8446707ba7bfbafbe4.tar.gz
deheader-95fc7de08928a7b19930be8446707ba7bfbafbe4.tar.bz2
deheader-95fc7de08928a7b19930be8446707ba7bfbafbe4.tar.xz
deheader-95fc7de08928a7b19930be8446707ba7bfbafbe4.zip
Refactoring step.
-rwxr-xr-xdeheader84
1 files changed, 49 insertions, 35 deletions
diff --git a/deheader b/deheader
index e9a5429..2d77881 100755
--- a/deheader
+++ b/deheader
@@ -30,6 +30,20 @@ def trim(line):
else:
return `line`
+def extract_includes(sourcefile, ignores):
+ "Extract a list of #include lines used in a given sourcfile."
+ includes = []
+ for line in open(sourcefile):
+ if line.startswith("#include"):
+ if verbose:
+ print "deheader: %s requires %s" % (sourcefile, `line`)
+ for stopper in ignores:
+ if stopper in line:
+ break
+ else:
+ includes.append(line)
+ return includes
+
def compile(source, msg=""):
(stem, suffix) = os.path.splitext(source)
derived = stem + ".o"
@@ -52,6 +66,35 @@ def compile(source, msg=""):
% (sourcefile, msg, explain, end-start)
return (status, end - start)
+def c_analyze(source, includes):
+ "Given a C file and a list of includes, return those that can be omitted."
+ # We'll remove headers in reverse order, because later unnecessary
+ # headers might depend on earlier ones
+ includes.reverse()
+ unneeded = []
+ original = sourcefile + ".orig"
+ try:
+ os.rename(sourcefile, original)
+ while True:
+ keepgoing = False
+ for header in includes:
+ ofp = open(sourcefile, "w")
+ for line in open(original):
+ if line != header:
+ ofp.write(line)
+ ofp.close()
+ (st, t) = compile(sourcefile, " without %s" % trim(header))
+ if st == 0:
+ unneeded.append(header)
+ includes.remove(header)
+ keepgoing = True
+ if not keepgoing:
+ break
+ finally:
+ os.remove(sourcefile)
+ os.rename(original, sourcefile)
+ return unneeded
+
if __name__ == "__main__":
(options, arguments) = getopt.getopt(sys.argv[1:], "hrvi:",
["help", "ignore",
@@ -74,41 +117,12 @@ if __name__ == "__main__":
(st, t) = compile(sourcefile)
if st != 0:
continue
- includes = []
- for line in open(sourcefile):
- if line.startswith("#include"):
- if verbose:
- print "deheader: %s requires %s" % (sourcefile, `line`)
- for stopper in ignores:
- if stopper in line:
- break
- else:
- includes.append(line)
- # We'll remove headers in reverse order, because later unnecessary
- # headers might depend on earlier ones
- includes.reverse()
- unneeded = []
- original = sourcefile + ".orig"
- try:
- os.rename(sourcefile, original)
- while True:
- keepgoing = False
- for header in includes:
- ofp = open(sourcefile, "w")
- for line in open(original):
- if line != header:
- ofp.write(line)
- ofp.close()
- (st, t) = compile(sourcefile, " without %s" % trim(header))
- if st == 0:
- unneeded.append(header)
- includes.remove(header)
- keepgoing = True
- if not keepgoing:
- break
- finally:
- os.remove(sourcefile)
- os.rename(original, sourcefile)
+ includes = extract_includes(sourcefile, ignores)
+ if sourcefile.endswith(".c") or sourcefile.endswith(".cpp"):
+ unneeded = c_analyze(sourcefile, includes)
+ else:
+ print >>sys.stderr, "deheader: can't analyze %s" % sourcefile
+ continue
if unneeded:
print "deheader: the following headers may be omitted from %s:" % sourcefile
print "\n".join(map(trim, unneeded))