The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 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 | |
Elliott Hughes | fddbafd | 2014-05-01 10:17:27 -0700 | [diff] [blame] | 10 | def cleanupFile(path, original_path): |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 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 |
David 'Digit' Turner | fc26931 | 2010-10-11 22:11:06 +0200 | [diff] [blame] | 15 | src_path = path |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 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 | |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 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: |
Glenn Kasten | c61f990 | 2011-12-19 11:27:50 -0800 | [diff] [blame] | 40 | panic( "oops, internal error, can't extract correct relative path\n" ) |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 41 | |
| 42 | # convert into destination path, extracting architecture if needed |
| 43 | # and the corresponding list of known static functions |
| 44 | # |
| 45 | arch = None |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 46 | statics = kernel_known_generic_statics |
Ben Cheng | 8bea2b6 | 2013-10-16 15:28:56 -0700 | [diff] [blame] | 47 | m = re.match(r"asm-([\w\d_\+\.\-]+)(/.*)", src_path) |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 48 | if m and m.group(1) != 'generic': |
| 49 | dst_path = "arch-%s/asm/%s" % m.groups() |
| 50 | arch = m.group(1) |
| 51 | statics = statics.union( kernel_known_statics.get( arch, set() ) ) |
| 52 | else: |
Ben Cheng | 8bea2b6 | 2013-10-16 15:28:56 -0700 | [diff] [blame] | 53 | # process headers under the uapi directory |
| 54 | # note the "asm" level has been explicitly added in the original |
| 55 | # kernel header tree for architectural-dependent uapi headers |
| 56 | m_uapi = re.match(r"(uapi)/([\w\d_\+\.\-]+)(/.*)", src_path) |
| 57 | if m_uapi: |
| 58 | dst_path = src_path |
| 59 | m_uapi_arch = re.match(r"asm-([\w\d_\+\.\-]+)", m_uapi.group(2)) |
| 60 | if m_uapi_arch and m_uapi_arch.group(1) != 'generic': |
| 61 | arch = m_uapi_arch.group(1) |
| 62 | statics = statics.union( kernel_known_statics.get( arch, set() ) ) |
| 63 | # common headers (ie non-asm and non-uapi) |
| 64 | else: |
| 65 | dst_path = "common/" + src_path |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 66 | |
David 'Digit' Turner | fc26931 | 2010-10-11 22:11:06 +0200 | [diff] [blame] | 67 | dst_path = os.path.normpath( kernel_cleaned_path + "/" + dst_path ) |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 68 | |
| 69 | # now, let's parse the file |
| 70 | # |
David 'Digit' Turner | fc26931 | 2010-10-11 22:11:06 +0200 | [diff] [blame] | 71 | blocks = cpp.BlockParser().parseFile(path) |
| 72 | if not blocks: |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 73 | sys.stderr.write( "error: can't parse '%s'" % path ) |
| 74 | sys.exit(1) |
| 75 | |
Andrew Hsieh | 126601d | 2012-03-23 23:07:36 +0800 | [diff] [blame] | 76 | macros = kernel_known_macros.copy() |
| 77 | if arch and arch in kernel_default_arch_macros: |
| 78 | macros.update(kernel_default_arch_macros[arch]) |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 79 | |
Raghu Gandham | a864c2c | 2013-01-16 16:42:47 -0800 | [diff] [blame] | 80 | if arch and arch in kernel_arch_token_replacements: |
| 81 | blocks.replaceTokens( kernel_arch_token_replacements[arch] ) |
| 82 | |
Andrew Hsieh | 126601d | 2012-03-23 23:07:36 +0800 | [diff] [blame] | 83 | blocks.optimizeMacros( macros ) |
David 'Digit' Turner | fc26931 | 2010-10-11 22:11:06 +0200 | [diff] [blame] | 84 | blocks.optimizeIf01() |
| 85 | blocks.removeVarsAndFuncs( statics ) |
| 86 | blocks.replaceTokens( kernel_token_replacements ) |
| 87 | blocks.removeComments() |
| 88 | blocks.removeMacroDefines( kernel_ignored_macros ) |
| 89 | blocks.removeWhiteSpace() |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 90 | |
| 91 | out = StringOutput() |
David 'Digit' Turner | fc26931 | 2010-10-11 22:11:06 +0200 | [diff] [blame] | 92 | out.write( kernel_disclaimer ) |
| 93 | blocks.writeWithWarning(out, kernel_warning, 4) |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 94 | return dst_path, out.get() |
| 95 | |
| 96 | |
| 97 | if __name__ == "__main__": |
| 98 | |
| 99 | def usage(): |
| 100 | print """\ |
| 101 | usage: %s [options] <header_path> |
| 102 | |
| 103 | options: |
| 104 | -v enable verbose mode |
| 105 | |
| 106 | -u enabled update mode |
| 107 | this will try to update the corresponding 'clean header' |
| 108 | if the content has changed. with this, you can pass more |
| 109 | than one file on the command-line |
| 110 | |
David 'Digit' Turner | fc26931 | 2010-10-11 22:11:06 +0200 | [diff] [blame] | 111 | -k<path> specify path of original kernel headers |
| 112 | -d<path> specify path of cleaned kernel headers |
| 113 | |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 114 | <header_path> must be in a subdirectory of 'original' |
| 115 | """ % os.path.basename(sys.argv[0]) |
| 116 | sys.exit(1) |
| 117 | |
| 118 | try: |
David 'Digit' Turner | fc26931 | 2010-10-11 22:11:06 +0200 | [diff] [blame] | 119 | optlist, args = getopt.getopt( sys.argv[1:], 'uvk:d:' ) |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 120 | except: |
| 121 | # unrecognized option |
| 122 | sys.stderr.write( "error: unrecognized option\n" ) |
| 123 | usage() |
| 124 | |
| 125 | for opt, arg in optlist: |
| 126 | if opt == '-u': |
| 127 | noUpdate = 0 |
| 128 | elif opt == '-v': |
| 129 | verbose = 1 |
| 130 | D_setlevel(1) |
Dima Zavin | 4c4a963 | 2009-08-05 17:55:30 -0700 | [diff] [blame] | 131 | elif opt == '-k': |
| 132 | kernel_original_path = arg |
David 'Digit' Turner | fc26931 | 2010-10-11 22:11:06 +0200 | [diff] [blame] | 133 | elif opt == '-d': |
| 134 | kernel_cleaned_path = arg |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 135 | |
| 136 | if len(args) == 0: |
| 137 | usage() |
| 138 | |
| 139 | if noUpdate: |
| 140 | for path in args: |
Frank Maker | 7b6795d | 2011-05-25 11:07:04 -0700 | [diff] [blame] | 141 | dst_path, newdata = cleanupFile(path,kernel_original_path) |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 142 | print newdata |
| 143 | |
| 144 | sys.exit(0) |
| 145 | |
| 146 | # now let's update our files. |
| 147 | |
| 148 | b = BatchFileUpdater() |
| 149 | |
| 150 | for path in args: |
Frank Maker | 7b6795d | 2011-05-25 11:07:04 -0700 | [diff] [blame] | 151 | dst_path, newdata = cleanupFile(path,kernel_original_path) |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 152 | if not dst_path: |
| 153 | continue |
| 154 | |
| 155 | b.readFile( dst_path ) |
| 156 | r = b.editFile( dst_path, newdata ) |
| 157 | if r == 0: |
| 158 | r = "unchanged" |
| 159 | elif r == 1: |
| 160 | r = "edited" |
| 161 | else: |
| 162 | r = "added" |
| 163 | |
| 164 | print "cleaning: %-*s -> %-*s (%s)" % ( 35, path, 35, dst_path, r ) |
| 165 | |
| 166 | |
David 'Digit' Turner | fc26931 | 2010-10-11 22:11:06 +0200 | [diff] [blame] | 167 | b.updateGitFiles() |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 168 | |
| 169 | sys.exit(0) |