These files are a subset of the python-2.7.2.tgz distribution from python.org. Changed files from PyMod-2.7.2 have been copied into the corresponding directories of this tree, replacing the original files in the distribution. Signed-off-by: daryl.mcdaniel@intel.com git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13197 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			168 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			168 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #! /usr/bin/env python
 | |
| 
 | |
| # pdeps
 | |
| #
 | |
| # Find dependencies between a bunch of Python modules.
 | |
| #
 | |
| # Usage:
 | |
| #       pdeps file1.py file2.py ...
 | |
| #
 | |
| # Output:
 | |
| # Four tables separated by lines like '--- Closure ---':
 | |
| # 1) Direct dependencies, listing which module imports which other modules
 | |
| # 2) The inverse of (1)
 | |
| # 3) Indirect dependencies, or the closure of the above
 | |
| # 4) The inverse of (3)
 | |
| #
 | |
| # To do:
 | |
| # - command line options to select output type
 | |
| # - option to automatically scan the Python library for referenced modules
 | |
| # - option to limit output to particular modules
 | |
| 
 | |
| 
 | |
| import sys
 | |
| import re
 | |
| import os
 | |
| 
 | |
| 
 | |
| # Main program
 | |
| #
 | |
| def main():
 | |
|     args = sys.argv[1:]
 | |
|     if not args:
 | |
|         print 'usage: pdeps file.py file.py ...'
 | |
|         return 2
 | |
|     #
 | |
|     table = {}
 | |
|     for arg in args:
 | |
|         process(arg, table)
 | |
|     #
 | |
|     print '--- Uses ---'
 | |
|     printresults(table)
 | |
|     #
 | |
|     print '--- Used By ---'
 | |
|     inv = inverse(table)
 | |
|     printresults(inv)
 | |
|     #
 | |
|     print '--- Closure of Uses ---'
 | |
|     reach = closure(table)
 | |
|     printresults(reach)
 | |
|     #
 | |
|     print '--- Closure of Used By ---'
 | |
|     invreach = inverse(reach)
 | |
|     printresults(invreach)
 | |
|     #
 | |
|     return 0
 | |
| 
 | |
| 
 | |
| # Compiled regular expressions to search for import statements
 | |
| #
 | |
| m_import = re.compile('^[ \t]*from[ \t]+([^ \t]+)[ \t]+')
 | |
| m_from = re.compile('^[ \t]*import[ \t]+([^#]+)')
 | |
| 
 | |
| 
 | |
| # Collect data from one file
 | |
| #
 | |
| def process(filename, table):
 | |
|     fp = open(filename, 'r')
 | |
|     mod = os.path.basename(filename)
 | |
|     if mod[-3:] == '.py':
 | |
|         mod = mod[:-3]
 | |
|     table[mod] = list = []
 | |
|     while 1:
 | |
|         line = fp.readline()
 | |
|         if not line: break
 | |
|         while line[-1:] == '\\':
 | |
|             nextline = fp.readline()
 | |
|             if not nextline: break
 | |
|             line = line[:-1] + nextline
 | |
|         if m_import.match(line) >= 0:
 | |
|             (a, b), (a1, b1) = m_import.regs[:2]
 | |
|         elif m_from.match(line) >= 0:
 | |
|             (a, b), (a1, b1) = m_from.regs[:2]
 | |
|         else: continue
 | |
|         words = line[a1:b1].split(',')
 | |
|         # print '#', line, words
 | |
|         for word in words:
 | |
|             word = word.strip()
 | |
|             if word not in list:
 | |
|                 list.append(word)
 | |
| 
 | |
| 
 | |
| # Compute closure (this is in fact totally general)
 | |
| #
 | |
| def closure(table):
 | |
|     modules = table.keys()
 | |
|     #
 | |
|     # Initialize reach with a copy of table
 | |
|     #
 | |
|     reach = {}
 | |
|     for mod in modules:
 | |
|         reach[mod] = table[mod][:]
 | |
|     #
 | |
|     # Iterate until no more change
 | |
|     #
 | |
|     change = 1
 | |
|     while change:
 | |
|         change = 0
 | |
|         for mod in modules:
 | |
|             for mo in reach[mod]:
 | |
|                 if mo in modules:
 | |
|                     for m in reach[mo]:
 | |
|                         if m not in reach[mod]:
 | |
|                             reach[mod].append(m)
 | |
|                             change = 1
 | |
|     #
 | |
|     return reach
 | |
| 
 | |
| 
 | |
| # Invert a table (this is again totally general).
 | |
| # All keys of the original table are made keys of the inverse,
 | |
| # so there may be empty lists in the inverse.
 | |
| #
 | |
| def inverse(table):
 | |
|     inv = {}
 | |
|     for key in table.keys():
 | |
|         if not inv.has_key(key):
 | |
|             inv[key] = []
 | |
|         for item in table[key]:
 | |
|             store(inv, item, key)
 | |
|     return inv
 | |
| 
 | |
| 
 | |
| # Store "item" in "dict" under "key".
 | |
| # The dictionary maps keys to lists of items.
 | |
| # If there is no list for the key yet, it is created.
 | |
| #
 | |
| def store(dict, key, item):
 | |
|     if dict.has_key(key):
 | |
|         dict[key].append(item)
 | |
|     else:
 | |
|         dict[key] = [item]
 | |
| 
 | |
| 
 | |
| # Tabulate results neatly
 | |
| #
 | |
| def printresults(table):
 | |
|     modules = table.keys()
 | |
|     maxlen = 0
 | |
|     for mod in modules: maxlen = max(maxlen, len(mod))
 | |
|     modules.sort()
 | |
|     for mod in modules:
 | |
|         list = table[mod]
 | |
|         list.sort()
 | |
|         print mod.ljust(maxlen), ':',
 | |
|         if mod in list:
 | |
|             print '(*)',
 | |
|         for ref in list:
 | |
|             print ref,
 | |
|         print
 | |
| 
 | |
| 
 | |
| # Call main and honor exit status
 | |
| if __name__ == '__main__':
 | |
|     try:
 | |
|         sys.exit(main())
 | |
|     except KeyboardInterrupt:
 | |
|         sys.exit(1)
 |