1 #!/usr/bin/python2.6
   2 #
   3 # CDDL HEADER START
   4 #
   5 # The contents of this file are subject to the terms of the
   6 # Common Development and Distribution License (the "License").
   7 # You may not use this file except in compliance with the License.
   8 #
   9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10 # or http://www.opensolaris.org/os/licensing.
  11 # See the License for the specific language governing permissions
  12 # and limitations under the License.
  13 #
  14 # When distributing Covered Code, include this CDDL HEADER in each
  15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16 # If applicable, add the following below this CDDL HEADER, with the
  17 # fields enclosed by brackets "[]" replaced with your own identifying
  18 # information: Portions Copyright [yyyy] [name of copyright owner]
  19 #
  20 # CDDL HEADER END
  21 #
  22 
  23 #
  24 # Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  25 #
  26 
  27 #
  28 # Check for valid link-editor mapfile comment blocks in source files.
  29 #
  30 
  31 import sys, os, getopt, fnmatch
  32 
  33 sys.path.insert(1, os.path.join(os.path.dirname(__file__), "..", "lib",
  34                                 "python%d.%d" % sys.version_info[:2]))
  35 
  36 # Allow running from the source tree, using the modules in the source tree
  37 sys.path.insert(2, os.path.join(os.path.dirname(__file__), '..'))
  38 
  39 from onbld.Checks.Mapfile import mapfilechk
  40 
  41 class ExceptionList(object):
  42         def __init__(self):
  43                 self.dirs = []
  44                 self.files = []
  45                 self.extensions = []
  46 
  47         def load(self, exfile):
  48                 fh = None
  49                 try:
  50                         fh = open(exfile, 'r')
  51                 except IOError, e:
  52                         sys.stderr.write('Failed to open exception list: '
  53                                          '%s: %s\n' % (e.filename, e.strerror))
  54                         sys.exit(2)
  55 
  56                 for line in fh:
  57                         line = line.strip()
  58 
  59                         if line.strip().endswith('/'):
  60                                 self.dirs.append(line[0:-1])
  61                         elif line.startswith('*.'):
  62                                 self.extensions.append(line)
  63                         else:
  64                                 self.files.append(line)
  65 
  66                 fh.close()
  67 
  68         def match(self, filename):
  69                 if os.path.isdir(filename):
  70                         return filename in self.dirs
  71                 else:
  72                         if filename in self.files:
  73                                 return True
  74 
  75                         for pat in self.extensions:
  76                                 if fnmatch.fnmatch(filename, pat):
  77                                         return True
  78 
  79         def __contains__(self, elt):
  80                 return self.match(elt)
  81 
  82 def usage():
  83         progname = os.path.split(sys.argv[0])[1]
  84         sys.stderr.write('''Usage: %s [-v] [-x exceptions] paths...
  85         -v              report on all files, not just those with errors.
  86         -x exceptions   load an exceptions file
  87 ''' % progname)
  88         sys.exit(2)
  89 
  90 
  91 def check(filename, opts):
  92         try:
  93                 fh = open(filename, 'r')
  94         except IOError, e:
  95                 sys.stderr.write("failed to open '%s': %s\n" %
  96                                  (e.filename, e.strerror))
  97                 return 1
  98         else:
  99                 return mapfilechk(fh, verbose=opts['verbose'],
 100                                output=sys.stdout)
 101 
 102 def walker(opts, dirname, fnames):
 103         for f in fnames:
 104                 path = os.path.join(dirname, f)
 105 
 106                 if not os.path.isdir(path):
 107                         if not path in opts['exclude']:
 108                                 opts['status'] |= check(path, opts)
 109                 else:
 110                         if path in opts['exclude']:
 111                                 fnames.remove(f)
 112 
 113 def walkpath(path, opts):
 114         if os.path.isdir(path):
 115                 os.path.walk(path, walker, opts)
 116         else:
 117                 if not path in opts['exclude']:
 118                         opts['status'] |= check(path, opts)
 119 
 120 def main(args):
 121         options = {
 122                 'status': 0,
 123                 'verbose': False,
 124                 'exclude': ExceptionList()
 125         }
 126 
 127         try:
 128                 opts, args = getopt.getopt(sys.argv[1:], 'avx:')
 129         except getopt.GetoptError:
 130                 usage()
 131                 sys.exit(2)
 132 
 133         for opt, arg in opts:
 134                 if opt == '-v':
 135                         options['verbose'] = True
 136                 elif opt == '-x':
 137                         options['exclude'].load(arg)
 138 
 139         for path in args:
 140                 walkpath(path, options)
 141 
 142         return options['status']
 143 
 144 if __name__ == '__main__':
 145         sys.exit(main(sys.argv[1:]))