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:], '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