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, 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" ) 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 66 blocks.optimizeMacros( kernel_known_macros ) 67 blocks.optimizeIf01() 68 blocks.removeVarsAndFuncs( statics ) 69 blocks.replaceTokens( kernel_token_replacements ) 70 blocks.removeComments() 71 blocks.removeMacroDefines( kernel_ignored_macros ) 72 blocks.removeWhiteSpace() 73 74 out = StringOutput() 75 out.write( kernel_disclaimer ) 76 blocks.writeWithWarning(out, kernel_warning, 4) 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 -k<path> specify path of original kernel headers 95 -d<path> specify path of cleaned kernel headers 96 97 <header_path> must be in a subdirectory of 'original' 98 """ % os.path.basename(sys.argv[0]) 99 sys.exit(1) 100 101 try: 102 optlist, args = getopt.getopt( sys.argv[1:], 'uvk:d:' ) 103 except: 104 # unrecognized option 105 sys.stderr.write( "error: unrecognized option\n" ) 106 usage() 107 108 for opt, arg in optlist: 109 if opt == '-u': 110 noUpdate = 0 111 elif opt == '-v': 112 verbose = 1 113 D_setlevel(1) 114 elif opt == '-k': 115 kernel_original_path = arg 116 elif opt == '-d': 117 kernel_cleaned_path = arg 118 119 if len(args) == 0: 120 usage() 121 122 if noUpdate: 123 for path in args: 124 dst_path, newdata = cleanupFile(path,kernel_original_path) 125 print newdata 126 127 sys.exit(0) 128 129 # now let's update our files. 130 131 b = BatchFileUpdater() 132 133 for path in args: 134 dst_path, newdata = cleanupFile(path,kernel_original_path) 135 if not dst_path: 136 continue 137 138 b.readFile( dst_path ) 139 r = b.editFile( dst_path, newdata ) 140 if r == 0: 141 r = "unchanged" 142 elif r == 1: 143 r = "edited" 144 else: 145 r = "added" 146 147 print "cleaning: %-*s -> %-*s (%s)" % ( 35, path, 35, dst_path, r ) 148 149 150 b.updateGitFiles() 151 152 sys.exit(0) 153