1#!/usr/bin/env python 2# 3 4import sys, cpp, kernel, glob, os, re, getopt 5from defaults import * 6from utils import * 7 8noUpdate = 1 9 10def 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 80if __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:], 'uv' ) 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 112 if len(args) == 0: 113 usage() 114 115 if noUpdate: 116 for path in args: 117 dst_path, newdata = cleanupFile(path) 118 print newdata 119 120 sys.exit(0) 121 122 # now let's update our files. 123 124 b = BatchFileUpdater() 125 126 for path in args: 127 dst_path, newdata = cleanupFile(path) 128 if not dst_path: 129 continue 130 131 b.readFile( dst_path ) 132 r = b.editFile( dst_path, newdata ) 133 if r == 0: 134 r = "unchanged" 135 elif r == 1: 136 r = "edited" 137 else: 138 r = "added" 139 140 print "cleaning: %-*s -> %-*s (%s)" % ( 35, path, 35, dst_path, r ) 141 142 143 if os.environ.has_key("ANDROID_PRODUCT_OUT"): 144 b.updateP4Files() 145 else: 146 b.updateFiles() 147 148 sys.exit(0) 149