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