summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReiner Herrmann <reiner@reiner-h.de>2015-12-26 14:54:04 +0100
committerEric S. Raymond <esr@thyrsus.com>2016-01-12 13:59:49 -0500
commit532e7883c38ec14828542276d2ceb0be8faae187 (patch)
tree2935db854189f03e3fcc181b0c98c5888b920547
parent96e4a940795ab952e8ceccb0233393fac31c3bd3 (diff)
downloaddeheader-532e7883c38ec14828542276d2ceb0be8faae187.tar.gz
deheader-532e7883c38ec14828542276d2ceb0be8faae187.tar.bz2
deheader-532e7883c38ec14828542276d2ceb0be8faae187.tar.xz
deheader-532e7883c38ec14828542276d2ceb0be8faae187.zip
When compilation fails, also try it directly inside subdirectories
-rwxr-xr-xdeheader33
-rw-r--r--deheader.xml4
2 files changed, 25 insertions, 12 deletions
diff --git a/deheader b/deheader
index d4e38f0..8eaf329 100755
--- a/deheader
+++ b/deheader
@@ -1354,18 +1354,22 @@ def trim(line):
else:
return repr(line)
-def testcompile(source, maker, msg="", verbosity=0, showerrs=False):
+def testcompile(source, maker, msg="", verbosity=0, showerrs=False, subdir=""):
"Test-compile a sourcefile. Return the status and the compilation time"
(stem, _suffix) = os.path.splitext(source)
derived = stem + ".o"
- if os.path.exists(derived):
- os.remove(derived)
+ if os.path.exists(os.path.join(subdir, derived)):
+ os.remove(os.path.join(subdir, derived))
elif os.path.exists("CMakeList.txt"):
subprocess.call(["make","clean"])
command = maker + " " + derived
+ olddir = os.getcwd()
+ if len(subdir) > 0:
+ os.chdir(subdir)
start = time.time()
(status, output) = commands.getstatusoutput(command)
end = time.time()
+ os.chdir(olddir)
if verbosity >= COMMAND_DEBUG or (showerrs and os.WIFEXITED(status) and os.WEXITSTATUS(status) != 0):
sys.stdout.write(output + "\n")
if status:
@@ -1382,7 +1386,7 @@ def testcompile(source, maker, msg="", verbosity=0, showerrs=False):
subprocess.call(["make","clean"])
return (status, end - start)
-def c_analyze(sourcefile, maker, includes, requires, verbosity):
+def c_analyze(sourcefile, maker, includes, requires, verbosity, subdir=""):
"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
@@ -1391,7 +1395,7 @@ def c_analyze(sourcefile, maker, includes, requires, verbosity):
if verbosity == BATON_DEBUG:
baton = Baton(sourcefile + ": ", "Done")
try:
- saveit = SaveForModification(sourcefile)
+ saveit = SaveForModification(os.path.join(subdir, sourcefile))
while True:
keepgoing = False
for header in includes[:]:
@@ -1402,11 +1406,11 @@ def c_analyze(sourcefile, maker, includes, requires, verbosity):
for required in requirements:
if required in header:
if verbosity >= PROGRESS_DEBUG:
- print "deheader: in %s, %s prevents uninclusion of %s" % (sourcefile, trigger, trim(header))
+ print "deheader: in %s, %s prevents uninclusion of %s" % (os.path.join(subdir, sourcefile), trigger, trim(header))
retain += 1
if not retain:
saveit.remove_headers(unneeded + [header])
- (st, _t) = testcompile(sourcefile, maker, " without %s" % trim(header), verbosity, showerrs=False)
+ (st, _t) = testcompile(sourcefile, maker, " without %s" % trim(header), verbosity, showerrs=False, subdir=subdir)
if st == 0:
unneeded.append(header)
includes.remove(header)
@@ -1422,23 +1426,28 @@ def c_analyze(sourcefile, maker, includes, requires, verbosity):
stillhere = map(trim, includes)
for (requirement, trigger) in requires:
if not set(requirement).issubset(stillhere):
- print "deheader: in %s, %s portability requires %s." % (sourcefile, trigger, ",".join(requirement))
+ print "deheader: in %s, %s portability requires %s." % (os.path.join(subdir, sourcefile), trigger, ",".join(requirement))
return unneeded
def deheader(sourcefile, maker, includes, requires, remove, verbose):
# Sanity check against broken sourcefiles; we want this to
# complain visibly if the sourcefile won't build at all.
- (st, _t) = testcompile(sourcefile, maker, verbosity=max(1, verbose), showerrs=True)
+ subdir = ""
+ (st, _t) = testcompile(sourcefile, maker, verbosity=max(1, verbose), showerrs=False)
+ if st != 0:
+ subdir = os.path.dirname(sourcefile)
+ sourcefile = os.path.basename(sourcefile)
+ (st, _t) = testcompile(sourcefile, maker, verbosity=max(1, verbose), showerrs=True, subdir=subdir)
if st == 0:
# Now do the analysis
if sourcefile.endswith(".c") or sourcefile.endswith(".cpp") or sourcefile.endswith(".cc"):
unneeded = c_analyze(sourcefile, maker,
- includes[:], requires, verbose)
+ includes[:], requires, verbose, subdir=subdir)
if unneeded:
for line in unneeded:
- print "deheader: remove %s from %s" % (trim(line), sourcefile)
+ print "deheader: remove %s from %s" % (trim(line), os.path.join(subdir, sourcefile))
if remove:
- remove_it = SaveForModification(sourcefile)
+ remove_it = SaveForModification(os.path.join(subdir, sourcefile))
remove_it.remove_headers(unneeded)
remove_it.forget()
del remove_it
diff --git a/deheader.xml b/deheader.xml
index 2ade657..dde75f6 100644
--- a/deheader.xml
+++ b/deheader.xml
@@ -81,6 +81,10 @@ with an .orig suffix and restored on interrupt or after processing
with its original timestamp, unless the <option>-r</option> option was
given and headers removed.</para>
+<para>If the first test compilation from the top-level directory fails,
+deheader descends into the subdirectory of the source file and retries
+compiling inside there.</para>
+
<para>At verbosity level 0, only messages indicating removable headers
are issued. At verbosity 1, test compilations are timed and progess
indicated with a twirling-baton prompt. At verbosity level 2, you get