blob: de4bf85605e3bd78ae9cdb4fdc10ca06f3c9e362 [file] [log] [blame]
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001#!/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
75 out = StringOutput()
76 list.write(out)
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 <header_path> must be in a subdirectory of 'original'
95 """ % os.path.basename(sys.argv[0])
96 sys.exit(1)
97
98 try:
99 optlist, args = getopt.getopt( sys.argv[1:], 'uv' )
100 except:
101 # unrecognized option
102 sys.stderr.write( "error: unrecognized option\n" )
103 usage()
104
105 for opt, arg in optlist:
106 if opt == '-u':
107 noUpdate = 0
108 elif opt == '-v':
109 verbose = 1
110 D_setlevel(1)
111
112 if len(args) == 0:
113 usage()
114
115 if noUpdate:
116 for path in args:
117 dst_path, newdata = cleanupFile(path)
118 print newdata
119
120 sys.exit(0)
121
122 # now let's update our files.
123
124 b = BatchFileUpdater()
125
126 for path in args:
127 dst_path, newdata = cleanupFile(path)
128 if not dst_path:
129 continue
130
131 b.readFile( dst_path )
132 r = b.editFile( dst_path, newdata )
133 if r == 0:
134 r = "unchanged"
135 elif r == 1:
136 r = "edited"
137 else:
138 r = "added"
139
140 print "cleaning: %-*s -> %-*s (%s)" % ( 35, path, 35, dst_path, r )
141
142
143 if os.environ.has_key("ANDROID_PRODUCT_OUT"):
144 b.updateP4Files()
145 else:
146 b.updateFiles()
147
148 sys.exit(0)