blob: bed992662d3ff842857b31b5d2e8d11813648f30 [file] [log] [blame]
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -07001#!/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.insertDisclaimer( kernel.kernel_disclaimer )
73
74 out = StringOutput()
75 list.write(out)
76 return dst_path, out.get()
77
78
79if __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)