|
1 # |
|
2 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 # All rights reserved. |
|
4 # This component and the accompanying materials are made available |
|
5 # under the terms of "Eclipse Public License v1.0" |
|
6 # which accompanies this distribution, and is available |
|
7 # at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 # |
|
9 # Initial Contributors: |
|
10 # Nokia Corporation - initial contribution. |
|
11 # |
|
12 # Contributors: |
|
13 # |
|
14 # Description: |
|
15 # |
|
16 |
|
17 import re, sys, glob, os.path |
|
18 from optparse import OptionParser |
|
19 |
|
20 # When defreezing, these entries can exist, but only at the beginning of the exports. |
|
21 # Anything after these will be defrozen. |
|
22 ALLOWEDENTRIES = set(['_Z10jni_lookupPKc', '_Z13findDllMethodPKc']) |
|
23 |
|
24 # Pattern for entries |
|
25 RE_ENTRY = re.compile(r"^\s+([^ ]+) +@ +\d+ +NONAME( +ABSENT)?( *;.*)?$") |
|
26 |
|
27 # Transient exports which will be marked as absent. |
|
28 # See http://www.codesourcery.com/public/cxx-abi/abi.html#mangling for detailed |
|
29 # de-mangling instructions |
|
30 TRANSIENTS = set([ |
|
31 # TI = typeinfo structures |
|
32 '_ZTISi', # Si == ::std::basic_istream<char, std::char_traits<char> > |
|
33 '_ZTISo', # So == ::std::basic_ostream<char, std::char_traits<char> > |
|
34 '_ZTISd', # Sd == ::std::basic_iostream<char, std::char_traits<char> > |
|
35 '_ZTISt13basic_istreamIwSt11char_traitsIwEE', |
|
36 '_ZTISt13basic_ostreamIwSt11char_traitsIwEE', |
|
37 '_ZTISt14basic_iostreamIwSt11char_traitsIwEE', |
|
38 '_ZTISt15basic_streambufIwSt11char_traitsIwEE', |
|
39 '_ZTISt15basic_streambufIcSt11char_traitsIcEE', |
|
40 '_ZTISt13basic_filebufIcSt11char_traitsIcEE', |
|
41 '_ZTISt15basic_stringbufIcSt11char_traitsIcESaIcEE', |
|
42 '_ZTISt15basic_stringbufIwSt11char_traitsIwESaIwEE', |
|
43 '_ZTISt18basic_stringstreamIcSt11char_traitsIcESaIcEE', |
|
44 '_ZTISt18basic_stringstreamIwSt11char_traitsIwESaIwEE', |
|
45 '_ZTISt19basic_ostringstreamIcSt11char_traitsIcESaIcEE', |
|
46 '_ZTISt19basic_ostringstreamIwSt11char_traitsIwESaIwEE', |
|
47 '_ZTISt19basic_istringstreamIcSt11char_traitsIcESaIcEE', |
|
48 '_ZTISt19basic_istringstreamIwSt11char_traitsIwESaIwEE', |
|
49 |
|
50 # TV = virtual tables |
|
51 '_ZTVSi', |
|
52 '_ZTVSo', |
|
53 '_ZTVSd', |
|
54 '_ZTVSt13basic_istreamIwSt11char_traitsIwEE', |
|
55 '_ZTVSt13basic_ostreamIwSt11char_traitsIwEE', |
|
56 '_ZTVSt14basic_iostreamIwSt11char_traitsIwEE', |
|
57 '_ZTVSt15basic_streambufIwSt11char_traitsIwEE', |
|
58 '_ZTVSt15basic_streambufIcSt11char_traitsIcEE', |
|
59 '_ZTVSt13basic_filebufIcSt11char_traitsIcEE', |
|
60 '_ZTVSt15basic_stringbufIcSt11char_traitsIcESaIcEE', |
|
61 '_ZTVSt15basic_stringbufIwSt11char_traitsIwESaIwEE', |
|
62 '_ZTVSt18basic_stringstreamIcSt11char_traitsIcESaIcEE', |
|
63 '_ZTVSt18basic_stringstreamIwSt11char_traitsIwESaIwEE', |
|
64 '_ZTVSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE', |
|
65 '_ZTVSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE', |
|
66 '_ZTVSt19basic_istringstreamIcSt11char_traitsIcESaIcEE', |
|
67 '_ZTVSt19basic_istringstreamIwSt11char_traitsIwESaIwEE', |
|
68 |
|
69 # VTT structure (construction vtable index) |
|
70 '_ZTTSd', |
|
71 '_ZTTSi', |
|
72 '_ZTTSo', |
|
73 '_ZTTSt13basic_istreamIwSt11char_traitsIwEE', |
|
74 '_ZTTSt13basic_ostreamIwSt11char_traitsIwEE', |
|
75 '_ZTTSt14basic_ifstreamIcSt11char_traitsIcEE', |
|
76 '_ZTTSt14basic_iostreamIwSt11char_traitsIwEE', |
|
77 '_ZTTSt14basic_ofstreamIcSt11char_traitsIcEE', |
|
78 '_ZTTSt18basic_stringstreamIcSt11char_traitsIcESaIcEE', |
|
79 '_ZTTSt18basic_stringstreamIwSt11char_traitsIwESaIwEE', |
|
80 '_ZTTSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE', |
|
81 '_ZTTSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE', |
|
82 '_ZTTSt19basic_istringstreamIcSt11char_traitsIcESaIcEE', |
|
83 '_ZTTSt19basic_istringstreamIwSt11char_traitsIwESaIwEE' |
|
84 ]) |
|
85 |
|
86 # These are produced only by 9.2, not by 5.0 |
|
87 TRANSIENTS_92 = set([ |
|
88 '_ZTTSd', |
|
89 '_ZTTSi', |
|
90 '_ZTTSo', |
|
91 '_ZTTSt13basic_istreamIwSt11char_traitsIwEE', |
|
92 '_ZTTSt13basic_ostreamIwSt11char_traitsIwEE', |
|
93 '_ZTTSt14basic_ifstreamIcSt11char_traitsIcEE', |
|
94 '_ZTTSt14basic_iostreamIwSt11char_traitsIwEE', |
|
95 '_ZTTSt14basic_ofstreamIcSt11char_traitsIcEE' |
|
96 ]) |
|
97 |
|
98 # Only produced by stl4 - not by stl5 |
|
99 TRANSIENTS_STL4 = set([ |
|
100 '_ZTISi', |
|
101 '_ZTISt13basic_istreamIwSt11char_traitsIwEE', |
|
102 '_ZTVSi', |
|
103 '_ZTVSt13basic_istreamIwSt11char_traitsIwEE' |
|
104 ]) |
|
105 |
|
106 |
|
107 # Only produced by stl5 |
|
108 TRANSIENTS_STL5 = set([ |
|
109 '_ZTISt15basic_streambufIcSt11char_traitsIcEE', |
|
110 '_ZTISt15basic_stringbufIcSt11char_traitsIcESaIcEE', |
|
111 '_ZTISt15basic_stringbufIwSt11char_traitsIwESaIwEE', |
|
112 '_ZTISt18basic_stringstreamIcSt11char_traitsIcESaIcEE', |
|
113 '_ZTISt18basic_stringstreamIwSt11char_traitsIwESaIwEE', |
|
114 '_ZTISt19basic_ostringstreamIcSt11char_traitsIcESaIcEE', |
|
115 '_ZTISt19basic_ostringstreamIwSt11char_traitsIwESaIwEE', |
|
116 '_ZTISt19basic_istringstreamIcSt11char_traitsIcESaIcEE', |
|
117 '_ZTISt19basic_istringstreamIwSt11char_traitsIwESaIwEE', |
|
118 |
|
119 '_ZTTSt18basic_stringstreamIcSt11char_traitsIcESaIcEE', |
|
120 '_ZTTSt18basic_stringstreamIwSt11char_traitsIwESaIwEE', |
|
121 '_ZTTSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE', |
|
122 '_ZTTSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE', |
|
123 '_ZTTSt19basic_istringstreamIcSt11char_traitsIcESaIcEE', |
|
124 '_ZTTSt19basic_istringstreamIwSt11char_traitsIwESaIwEE' |
|
125 |
|
126 '_ZTVSt15basic_streambufIcSt11char_traitsIcEE', |
|
127 '_ZTVSt15basic_stringbufIcSt11char_traitsIcESaIcEE', |
|
128 '_ZTVSt15basic_stringbufIwSt11char_traitsIwESaIwEE', |
|
129 '_ZTVSt18basic_stringstreamIcSt11char_traitsIcESaIcEE', |
|
130 '_ZTVSt18basic_stringstreamIwSt11char_traitsIwESaIwEE', |
|
131 '_ZTVSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE', |
|
132 '_ZTVSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE', |
|
133 '_ZTVSt19basic_istringstreamIcSt11char_traitsIcESaIcEE', |
|
134 '_ZTVSt19basic_istringstreamIwSt11char_traitsIwESaIwEE' |
|
135 ]) |
|
136 |
|
137 TRANSIENTS_SPECIFIC = TRANSIENTS_92 | TRANSIENTS_STL4 | TRANSIENTS_STL5 |
|
138 TRANSIENTS_COMMON = TRANSIENTS - TRANSIENTS_SPECIFIC |
|
139 |
|
140 def readExports(file): |
|
141 lines = [l.rstrip() for l in open(file).readlines()] |
|
142 if lines.pop(0) != "EXPORTS": |
|
143 raise Exception("File %s is not a deffile" % file) |
|
144 |
|
145 exports = [] |
|
146 |
|
147 for l in lines: |
|
148 # Skip empty lines |
|
149 if len(l.strip()) == 0: |
|
150 continue |
|
151 |
|
152 # Read lines |
|
153 match = RE_ENTRY.match(l) |
|
154 if not match: |
|
155 raise Exception("Unrecognized line on file %s: %s" % (file, l)) |
|
156 |
|
157 (export, absent, comment) = match.groups() |
|
158 exports.append((export, absent, comment)) |
|
159 |
|
160 |
|
161 return exports |
|
162 |
|
163 def movelastTransients(exports): |
|
164 return [e for e in exports if e[0] not in TRANSIENTS] + \ |
|
165 [e for e in exports if e[0] in TRANSIENTS] |
|
166 |
|
167 def removeSpecific(exports): |
|
168 return [e for e in exports if e[0] not in TRANSIENTS_SPECIFIC] |
|
169 |
|
170 def absentTransients(exports): |
|
171 newExports = [] |
|
172 for e in exports: |
|
173 if e[0] in TRANSIENTS: |
|
174 e = (e[0], " ABSENT", e[2]) |
|
175 newExports.append(e) |
|
176 return newExports |
|
177 |
|
178 def removeTransients(exports): |
|
179 return [e for e in exports if e[0] not in TRANSIENTS] |
|
180 |
|
181 def defreeze(exports): |
|
182 defrozen = [] |
|
183 for export, absent, comment in exports: |
|
184 if export in ALLOWEDENTRIES: |
|
185 defrozen.append((export, absent, comment)) |
|
186 else: |
|
187 break |
|
188 return defrozen |
|
189 |
|
190 def generate(exports): |
|
191 output = "EXPORTS\n" |
|
192 |
|
193 for index in range(len(exports)): |
|
194 (export, absent, comment) = exports[index] |
|
195 output = output + "\t%s @ %i NONAME%s%s\n" % ( |
|
196 export, index + 1, absent or "", comment or "") |
|
197 return output + "\n" |
|
198 |
|
199 def list(exports): |
|
200 return "\n ".join(["'%s'," % e[0] for e in exports]) |
|
201 |
|
202 |
|
203 def main(): |
|
204 parser = OptionParser() |
|
205 parser.add_option("-f", dest = "outputFile") |
|
206 parser.add_option("-d", dest = "outputDir") |
|
207 parser.add_option("-o", dest = "overwrite", |
|
208 action = "store_true", default = False) |
|
209 parser.add_option("--reorder", dest = "reorder", |
|
210 action = "store_true", default = False, |
|
211 help = "reorder transient exports to last") |
|
212 parser.add_option("--removeSpecific", dest = "removeSpecific", |
|
213 action = "store_true", default = False, |
|
214 help = "remove exports which are specific to some environment") |
|
215 parser.add_option("--removeTransients", dest = "removeTransients", |
|
216 action = "store_true", default = False, |
|
217 help = "remove all exports which are transients") |
|
218 parser.add_option("--absentify", dest = "absentify", |
|
219 action = "store_true", default = False, |
|
220 help = "make absent transients exports") |
|
221 parser.add_option("--defreeze", dest = "defreeze", |
|
222 action = "store_true", default = False, |
|
223 help = "defreeze all except configured exports") |
|
224 parser.add_option("--list", dest = "list", |
|
225 action = "store_true", default = False) |
|
226 (options, args) = parser.parse_args() |
|
227 |
|
228 # Read |
|
229 for file in sum([glob.glob(arg) for arg in args], []): |
|
230 exports = readExports(file) |
|
231 |
|
232 # Modify |
|
233 if options.reorder: |
|
234 exports = movelastTransients(exports) |
|
235 if options.removeSpecific: |
|
236 exports = removeSpecific(exports) |
|
237 if options.absentify: |
|
238 exports = absentTransients(exports) |
|
239 if options.defreeze: |
|
240 exports = defreeze(exports) |
|
241 if options.removeTransients: |
|
242 exports = removeTransients(exports) |
|
243 |
|
244 # Generate / list |
|
245 if options.list: |
|
246 output = list(exports) |
|
247 else: |
|
248 output = generate(exports) |
|
249 |
|
250 # Write / print |
|
251 if options.outputFile: |
|
252 open(options.outputFile, "w").write(output) |
|
253 elif options.outputDir: |
|
254 open(os.path.join(options.outputDir, os.path.basename(file)), |
|
255 "w").write(output) |
|
256 elif options.overwrite: |
|
257 open(file, "w").write(output) |
|
258 print "Modified %s" % file |
|
259 else: |
|
260 print output |
|
261 |
|
262 if __name__ == "__main__": |
|
263 main() |
|
264 |
|
265 |