Author: branden Date: 2004-07-10 18:09:53 -0500 (Sat, 10 Jul 2004) New Revision: 4
Added: trunk/bin/list_x_header_deps Log: Add list_x_header_deps script. Added: trunk/bin/list_x_header_deps =================================================================== --- trunk/bin/list_x_header_deps 2004-07-10 23:04:56 UTC (rev 3) +++ trunk/bin/list_x_header_deps 2004-07-10 23:09:53 UTC (rev 4) @@ -0,0 +1,169 @@ +#!/usr/bin/python + +# $Id$ + +# This program scans C source files (.c, .h) for #includes, and reports the +# names of the X library -dev packages that supply the included header files. + +# Usage: run this program from the top of a source tree. It takes no arguments +# or options. + +# Copyright 2004 Branden Robinson + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +import os +import re + +def has_command(command): + if command == None: + raise RuntimeError, "internal error: has_command() called without an" \ + "argument" + + which_pipe = os.popen("which %s" % (command,), "r") + + # An exit status of zero will cause close() to return None. + if which_pipe.close() != None: + return False + else: + return True + +for cmd in [ "find", "dlocate" ]: + if not has_command(cmd): + raise RuntimeError, "fatal error: \"%s\" command not found" % (cmd,) + +DEVEL_DEBUG = False +RUNTIME_DEBUG = False + +dev_packages = [ + "libdps-dev", + "libice-dev", + "libsm-dev", + "libx11-dev", + "libxaw6-dev", + "libxaw7-dev", + "libxext-dev", + "libxi-dev", + "libxmu-dev", + "libxmuu-dev", + "libxp-dev", + "libxpm-dev", + "libxrandr-dev", + "libxt-dev", + "libxtrap-dev", + "libxtst-dev", + "libxv-dev", + "pm-dev", + "x-dev", + "xlibmesa-gl-dev", + "xlibmesa-glu-dev", + "xlibosmesa-dev", + "xlibs-static-dev", +] + +source_files = [ ] +dev_package_headers = { } +header_package = { } +source_includes = { } +build_deps = [ ] + +# Build a list of source files of interest. + +find_pipe = os.popen("find -name \"*.[ch]\"", "r") + +for source_file in find_pipe.readlines(): + source_files.append(source_file.rstrip()) + +find_pipe.close() + +if DEVEL_DEBUG: + print "Will scan the following source files:" + for filename in source_files: + print filename + +# Build a dictionary mapping package names to the header files within 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()) + + 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 + +# Now build a "reverse" dictionary mapping header file names to the package +# containing them. + +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] = [ ] + 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')) + 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. + +for pkg in build_deps: + print pkg + +# vim:set ai et sts=4 sw=4 tw=80: Property changes on: trunk/bin/list_x_header_deps ___________________________________________________________________ Name: svn:executable + * Name: svn:keywords + Id