Home | History | Annotate | Download | only in tools
      1 #!/usr/bin/env python
      2 #
      3 
      4 import sys, cpp, kernel, glob, os, re, getopt
      5 from defaults import *
      6 from utils import *
      7 
      8 noUpdate = 1
      9 
     10 def  cleanupFile( path ):
     11     """reads an original header and perform the cleanup operation on it
     12        this functions returns the destination path and the clean header
     13        as a single string"""
     14     # check the header path
     15     src_path    = path
     16 
     17     if not os.path.exists(src_path):
     18         if noUpdate:
     19             panic( "file does not exist: '%s'\n" % path )
     20         sys.stderr.write( "warning: file does not exit: %s\n" % path )
     21         return None, None
     22 
     23     if not os.path.isfile(src_path):
     24         if noUpdate:
     25             panic( "path is not a file: '%s'\n" % path )
     26         sys.stderr.write( "warning: not a file: %s\n" % path )
     27         return None, None
     28 
     29     original_path = kernel_original_path
     30     if os.path.commonprefix( [ src_path, original_path ] ) != original_path:
     31         if noUpdate:
     32             panic( "file is not in 'original' directory: %s\n" % path );
     33         sys.stderr.write( "warning: file not in 'original' ignored: %s\n" % path )
     34         return None, None
     35 
     36     src_path = src_path[len(original_path):]
     37     if len(src_path) > 0 and src_path[0] == '/':
     38         src_path = src_path[1:]
     39 
     40     if len(src_path) == 0:
     41         panic( "oops, internal error, can't extract correct relative path" )
     42 
     43     # convert into destination path, extracting architecture if needed
     44     # and the corresponding list of known static functions
     45     #
     46     arch = None
     47     re_asm_arch = re.compile( r"asm-([\w\d_\+\.\-]+)(/.*)" )
     48     m = re_asm_arch.match(src_path)
     49     statics = kernel_known_generic_statics
     50     if m and m.group(1) != 'generic':
     51         dst_path = "arch-%s/asm/%s" % m.groups()
     52         arch     = m.group(1)
     53         statics  = statics.union( kernel_known_statics.get( arch, set() ) )
     54     else:
     55         dst_path = "common/" + src_path
     56 
     57     dst_path = os.path.normpath( original_path + "/../" + dst_path )
     58 
     59     # now, let's parse the file
     60     #
     61     list = cpp.BlockParser().parseFile(path)
     62     if not list:
     63         sys.stderr.write( "error: can't parse '%s'" % path )
     64         sys.exit(1)
     65 
     66 
     67     list.optimizeMacros( kernel_known_macros )
     68     list.optimizeIf01()
     69     list.removeVarsAndFuncs( statics )
     70     list.removeComments()
     71     list.removeEmptyLines()
     72     list.removeMacroDefines( kernel_ignored_macros )
     73     list.insertDisclaimer( kernel.kernel_disclaimer )
     74 
     75     out = StringOutput()
     76     list.write(out)
     77     return dst_path, out.get()
     78 
     79 
     80 if __name__ == "__main__":
     81 
     82     def usage():
     83         print """\
     84     usage:  %s [options] <header_path>
     85 
     86         options:
     87             -v    enable verbose mode
     88 
     89             -u    enabled update mode
     90                 this will try to update the corresponding 'clean header'
     91                 if the content has changed. with this, you can pass more
     92                 than one file on the command-line
     93 
     94         <header_path> must be in a subdirectory of 'original'
     95     """ % os.path.basename(sys.argv[0])
     96         sys.exit(1)
     97 
     98     try:
     99         optlist, args = getopt.getopt( sys.argv[1:], 'uvk:' )
    100     except:
    101         # unrecognized option
    102         sys.stderr.write( "error: unrecognized option\n" )
    103         usage()
    104 
    105     for opt, arg in optlist:
    106         if opt == '-u':
    107             noUpdate = 0
    108         elif opt == '-v':
    109             verbose = 1
    110             D_setlevel(1)
    111         elif opt == '-k':
    112             kernel_original_path = arg
    113 
    114     if len(args) == 0:
    115         usage()
    116 
    117     if noUpdate:
    118         for path in args:
    119             dst_path, newdata = cleanupFile(path)
    120             print newdata
    121 
    122         sys.exit(0)
    123 
    124     # now let's update our files.
    125 
    126     b = BatchFileUpdater()
    127 
    128     for path in args:
    129         dst_path, newdata = cleanupFile(path)
    130         if not dst_path:
    131             continue
    132 
    133         b.readFile( dst_path )
    134         r = b.editFile( dst_path, newdata )
    135         if r == 0:
    136             r = "unchanged"
    137         elif r == 1:
    138             r = "edited"
    139         else:
    140             r = "added"
    141 
    142         print "cleaning: %-*s -> %-*s (%s)" % ( 35, path, 35, dst_path, r )
    143 
    144 
    145     if os.environ.has_key("ANDROID_PRODUCT_OUT"):
    146         b.updateP4Files()
    147     else:
    148         b.updateFiles()
    149 
    150     sys.exit(0)
    151