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, original_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     if os.path.commonprefix( [ src_path, original_path ] ) != original_path:
     30         if noUpdate:
     31             panic( "file is not in 'original' directory: %s\n" % path );
     32         sys.stderr.write( "warning: file not in 'original' ignored: %s\n" % path )
     33         return None, None
     34 
     35     src_path = src_path[len(original_path):]
     36     if len(src_path) > 0 and src_path[0] == '/':
     37         src_path = src_path[1:]
     38 
     39     if len(src_path) == 0:
     40         panic( "oops, internal error, can't extract correct relative path\n" )
     41 
     42     # convert into destination path, extracting architecture if needed
     43     # and the corresponding list of known static functions
     44     #
     45     arch = None
     46     re_asm_arch = re.compile( r"asm-([\w\d_\+\.\-]+)(/.*)" )
     47     m = re_asm_arch.match(src_path)
     48     statics = kernel_known_generic_statics
     49     if m and m.group(1) != 'generic':
     50         dst_path = "arch-%s/asm/%s" % m.groups()
     51         arch     = m.group(1)
     52         statics  = statics.union( kernel_known_statics.get( arch, set() ) )
     53     else:
     54         dst_path = "common/" + src_path
     55 
     56     dst_path = os.path.normpath( kernel_cleaned_path + "/" + dst_path )
     57 
     58     # now, let's parse the file
     59     #
     60     blocks = cpp.BlockParser().parseFile(path)
     61     if not blocks:
     62         sys.stderr.write( "error: can't parse '%s'" % path )
     63         sys.exit(1)
     64 
     65     macros = kernel_known_macros.copy()
     66     if arch and arch in kernel_default_arch_macros:
     67         macros.update(kernel_default_arch_macros[arch])
     68 
     69     blocks.optimizeMacros( macros )
     70     blocks.optimizeIf01()
     71     blocks.removeVarsAndFuncs( statics )
     72     blocks.replaceTokens( kernel_token_replacements )
     73     blocks.removeComments()
     74     blocks.removeMacroDefines( kernel_ignored_macros )
     75     blocks.removeWhiteSpace()
     76 
     77     out = StringOutput()
     78     out.write( kernel_disclaimer )
     79     blocks.writeWithWarning(out, kernel_warning, 4)
     80     return dst_path, out.get()
     81 
     82 
     83 if __name__ == "__main__":
     84 
     85     def usage():
     86         print """\
     87     usage:  %s [options] <header_path>
     88 
     89         options:
     90             -v    enable verbose mode
     91 
     92             -u    enabled update mode
     93                 this will try to update the corresponding 'clean header'
     94                 if the content has changed. with this, you can pass more
     95                 than one file on the command-line
     96 
     97             -k<path>  specify path of original kernel headers
     98             -d<path>  specify path of cleaned kernel headers
     99 
    100         <header_path> must be in a subdirectory of 'original'
    101     """ % os.path.basename(sys.argv[0])
    102         sys.exit(1)
    103 
    104     try:
    105         optlist, args = getopt.getopt( sys.argv[1:], 'uvk:d:' )
    106     except:
    107         # unrecognized option
    108         sys.stderr.write( "error: unrecognized option\n" )
    109         usage()
    110 
    111     for opt, arg in optlist:
    112         if opt == '-u':
    113             noUpdate = 0
    114         elif opt == '-v':
    115             verbose = 1
    116             D_setlevel(1)
    117         elif opt == '-k':
    118             kernel_original_path = arg
    119         elif opt == '-d':
    120             kernel_cleaned_path = arg
    121 
    122     if len(args) == 0:
    123         usage()
    124 
    125     if noUpdate:
    126         for path in args:
    127             dst_path, newdata = cleanupFile(path,kernel_original_path)
    128             print newdata
    129 
    130         sys.exit(0)
    131 
    132     # now let's update our files.
    133 
    134     b = BatchFileUpdater()
    135 
    136     for path in args:
    137         dst_path, newdata = cleanupFile(path,kernel_original_path)
    138         if not dst_path:
    139             continue
    140 
    141         b.readFile( dst_path )
    142         r = b.editFile( dst_path, newdata )
    143         if r == 0:
    144             r = "unchanged"
    145         elif r == 1:
    146             r = "edited"
    147         else:
    148             r = "added"
    149 
    150         print "cleaning: %-*s -> %-*s (%s)" % ( 35, path, 35, dst_path, r )
    151 
    152 
    153     b.updateGitFiles()
    154 
    155     sys.exit(0)
    156