clean_header.py revision c9205dba43c45dc5a185aa26e1160c3f62e9b471
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 list.replaceTokens( kernel_token_replacements ) 75 76 out = StringOutput() 77 list.write(out) 78 return dst_path, out.get() 79 80 81if __name__ == "__main__": 82 83 def usage(): 84 print """\ 85 usage: %s [options] <header_path> 86 87 options: 88 -v enable verbose mode 89 90 -u enabled update mode 91 this will try to update the corresponding 'clean header' 92 if the content has changed. with this, you can pass more 93 than one file on the command-line 94 95 <header_path> must be in a subdirectory of 'original' 96 """ % os.path.basename(sys.argv[0]) 97 sys.exit(1) 98 99 try: 100 optlist, args = getopt.getopt( sys.argv[1:], 'uvk:' ) 101 except: 102 # unrecognized option 103 sys.stderr.write( "error: unrecognized option\n" ) 104 usage() 105 106 for opt, arg in optlist: 107 if opt == '-u': 108 noUpdate = 0 109 elif opt == '-v': 110 verbose = 1 111 D_setlevel(1) 112 elif opt == '-k': 113 kernel_original_path = arg 114 115 if len(args) == 0: 116 usage() 117 118 if noUpdate: 119 for path in args: 120 dst_path, newdata = cleanupFile(path) 121 print newdata 122 123 sys.exit(0) 124 125 # now let's update our files. 126 127 b = BatchFileUpdater() 128 129 for path in args: 130 dst_path, newdata = cleanupFile(path) 131 if not dst_path: 132 continue 133 134 b.readFile( dst_path ) 135 r = b.editFile( dst_path, newdata ) 136 if r == 0: 137 r = "unchanged" 138 elif r == 1: 139 r = "edited" 140 else: 141 r = "added" 142 143 print "cleaning: %-*s -> %-*s (%s)" % ( 35, path, 35, dst_path, r ) 144 145 146 if os.environ.has_key("ANDROID_PRODUCT_OUT"): 147 b.updateP4Files() 148 else: 149 b.updateFiles() 150 151 sys.exit(0) 152