Author: branden Date: 2004-07-12 23:17:37 -0500 (Mon, 12 Jul 2004) New Revision: 5
Modified: trunk/bin/list_x_header_deps Log: Improve efficiency by getting rid of unnecessary dictionary manipulations. Thanks to Jeff Licquia for his assistance. Note how we might embroider this to handle C++ sources. Sort the list of build dependencies before printing it. Modified: trunk/bin/list_x_header_deps =================================================================== --- trunk/bin/list_x_header_deps 2004-07-10 23:09:53 UTC (rev 4) +++ trunk/bin/list_x_header_deps 2004-07-13 04:17:37 UTC (rev 5) @@ -74,13 +74,12 @@ ] source_files = [ ] -dev_package_headers = { } header_package = { } -source_includes = { } build_deps = [ ] # Build a list of source files of interest. +# XXX: might want to recognize: *.cc *.C *.cpp *.cxx *.hxx *.hpp find_pipe = os.popen("find -name \"*.[ch]\"", "r") for source_file in find_pipe.readlines(): @@ -93,76 +92,58 @@ for filename in source_files: print filename -# Build a dictionary mapping package names to the header files within them. +# Build a dictionary mapping header file names to the package containing them. for pkg in dev_packages: dlocate_pipe = os.popen("dlocate -L %s" % (pkg,), "r") - dev_package_headers[pkg] = [ ] - for package_file in dlocate_pipe.readlines(): if re.search("\.h$", package_file): - include_file = re.sub("/usr/(X11R6/)?include/", "", package_file) - dev_package_headers[pkg].append(include_file.rstrip()) + header_file = re.sub("/usr/(X11R6/)?include/", "", package_file).rstrip() + if header_package.has_key(header_file) \ + and pkg != header_package[header_file]: + raise RuntimeError, \ +"""More than one package appears to claim to contain the header file +\"%s\". +It appears to be in both the packages \"%s\" and \"%s\".""" \ + % (header_file, pkg, header_package[header_file]) + else: + header_package[header_file] = pkg dlocate_pipe.close() if DEVEL_DEBUG: - for pkg in dev_package_headers.keys(): - print "package %s contains the following header files:" % (pkg,) - for header_file in dev_package_headers[pkg]: - print header_file + for header_file in header_package.keys(): + print "Header file \"%s\" is in package \"%s\"." \ + % (header_file, header_package[header_file]) -# Now build a "reverse" dictionary mapping header file names to the package -# containing them. +# Walk through each source file of interest, identifying #include directives and +# identifying which package provides the specified header file. Only identify a +# given package one time (i.e., if we depend on 5 different headers from one +# package, only record the package name once). -for pkg in dev_package_headers.keys(): - for header_file in dev_package_headers[pkg]: - if header_package.has_key(header_file) \ - and pkg != header_package[header_file]: - raise RuntimeError, \ -"""More than one package appears to claim to contain the header file -\"%s\". -It appears to be in both the packages \"%s\" and \"%s\".""" \ - % (header_file, pkg, header_package[header_file]) - else: - header_package[header_file] = pkg - -# Build a dictionary mapping source files of interest to the header files they -# reference. - for filename in source_files: - source_includes[filename] = [ ] + if RUNTIME_DEBUG: + print "Debug: scanning source file %s for \"#include\"s" % (filename,) source_file = open(filename) for line in source_file.readlines(): included_header = re.search(r'#\s*include\s+<([^>]+)>', line) if included_header: - source_includes[filename].append(included_header.expand(r'\1')) + if RUNTIME_DEBUG: + print "Debug: looking up header file %s" % (header_file,) + header_file = included_header.expand(r'\1') + if header_package.has_key(header_file): + if header_package[header_file] not in build_deps: + build_deps.append(header_package[header_file]) + else: + if RUNTIME_DEBUG: + print "Warning: skipping header file %s" % (header_file,) source_file.close() -if DEVEL_DEBUG: - for filename in source_includes.keys(): - print "source file %s #includes the following header files:" \ - % (filename,) - for header_file in source_includes[filename]: - print header_file - -# Step through all header files included by the source and determine what -# packages they are in, storing the package names in a unique list. - -for source_file in source_includes.keys(): - for header_file in source_includes[source_file]: - if RUNTIME_DEBUG: - print "Debug: looking up header file %s" % (header_file,) - if header_package.has_key(header_file): - if header_package[header_file] not in build_deps: - build_deps.append(header_package[header_file]) - else: - if RUNTIME_DEBUG: - print "Warning: skipping header file %s" % (header_file,) - # Report the list of packages the source files appear to depend upon. +build_deps.sort() + for pkg in build_deps: print pkg