Mercurial > hg > truffle
annotate src/share/tools/MakeDeps/Database.java @ 1716:be3f9c242c9d
6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
Summary: GC workers now recognize an intermediate transient state of blocks which are allocated but have not yet completed initialization. blk_start() calls do not attempt to determine the size of a block in the transient state, rather waiting for the block to become initialized so that it is safe to query its size. Audited and ensured the order of initialization of object fields (klass, free bit and size) to respect block state transition protocol. Also included some new assertion checking code enabled in debug mode.
Reviewed-by: chrisphi, johnc, poonam
author | ysr |
---|---|
date | Mon, 16 Aug 2010 15:58:42 -0700 |
parents | c18cbe5936b8 |
children |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
830
diff
changeset
|
2 * Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
830
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
830
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
830
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 import java.io.*; | |
26 import java.util.*; | |
27 | |
28 public class Database { | |
29 private MacroDefinitions macros; | |
30 // allFiles is kept in lexicographically sorted order. See get(). | |
31 private FileList allFiles; | |
32 // files that have implicit dependency on platform files | |
33 // e.g. os.hpp: os_<os_family>.hpp os_<os_arch>.hpp but only | |
34 // recorded if the platform file was seen. | |
35 private FileList platformFiles; | |
36 private FileList outerFiles; | |
37 private FileList indivIncludes; | |
38 private FileList grandInclude; // the results for the grand include file | |
213
8b48a7bd2bf7
6697238: missing dependencies for precompiled headers with platform dependent includes
never
parents:
0
diff
changeset
|
39 private HashMap<String,String> platformDepFiles; |
0 | 40 private long threshold; |
41 private int nOuterFiles; | |
42 private boolean missingOk; | |
43 private Platform plat; | |
44 /** These allow you to specify files not in the include database | |
45 which are prepended and appended to the file list, allowing | |
46 you to have well-known functions at the start and end of the | |
47 text segment (allows us to find out in a portable fashion | |
48 whether the current PC is in VM code or not upon a crash) */ | |
49 private String firstFile; | |
50 private String lastFile; | |
51 | |
52 public Database(Platform plat, long t) { | |
53 this.plat = plat; | |
54 macros = new MacroDefinitions(); | |
55 allFiles = new FileList("allFiles", plat); | |
56 platformFiles = new FileList("platformFiles", plat); | |
57 outerFiles = new FileList("outerFiles", plat); | |
58 indivIncludes = new FileList("IndivIncludes", plat); | |
59 grandInclude = new FileList(plat.getGIFileTemplate().nameOfList(), plat); | |
213
8b48a7bd2bf7
6697238: missing dependencies for precompiled headers with platform dependent includes
never
parents:
0
diff
changeset
|
60 platformDepFiles = new HashMap<String,String>(); |
0 | 61 |
62 threshold = t; | |
63 nOuterFiles = 0; | |
64 missingOk = false; | |
65 firstFile = null; | |
66 lastFile = null; | |
67 }; | |
68 | |
69 public FileList getAllFiles() { | |
70 return allFiles; | |
71 } | |
72 | |
73 public Iterator getMacros() { | |
74 return macros.getMacros(); | |
75 } | |
76 | |
77 public void canBeMissing() { | |
78 missingOk = true; | |
79 } | |
80 | |
81 public boolean hfileIsInGrandInclude(FileList hfile, FileList cfile) { | |
82 return ((hfile.getCount() >= threshold) && (cfile.getUseGrandInclude())); | |
83 } | |
84 | |
85 /** These allow you to specify files not in the include database | |
86 which are prepended and appended to the file list, allowing | |
87 you to have well-known functions at the start and end of the | |
88 text segment (allows us to find out in a portable fashion | |
89 whether the current PC is in VM code or not upon a crash) */ | |
90 public void setFirstFile(String fileName) { | |
91 firstFile = fileName; | |
92 } | |
93 | |
94 public void setLastFile(String fileName) { | |
95 lastFile = fileName; | |
96 } | |
97 | |
98 public void get(String platFileName, String dbFileName) | |
99 throws FileFormatException, IOException, FileNotFoundException { | |
100 macros.readFrom(platFileName, missingOk); | |
101 | |
102 BufferedReader reader = null; | |
103 try { | |
104 reader = new BufferedReader(new FileReader(dbFileName)); | |
105 } catch (FileNotFoundException e) { | |
106 if (missingOk) { | |
107 return; | |
108 } else { | |
109 throw(e); | |
110 } | |
111 } | |
112 System.out.println("\treading database: " + dbFileName); | |
113 String line; | |
114 int lineNo = 0; | |
115 do { | |
116 line = reader.readLine(); | |
117 lineNo++; | |
118 if (line != null) { | |
119 StreamTokenizer tokenizer = | |
120 new StreamTokenizer(new StringReader(line)); | |
121 tokenizer.slashSlashComments(true); | |
122 tokenizer.wordChars('_', '_'); | |
123 tokenizer.wordChars('<', '>'); | |
124 // NOTE: if we didn't have to do this line by line, | |
125 // we could trivially recognize C-style comments as | |
126 // well. | |
127 // tokenizer.slashStarComments(true); | |
128 int numTok = 0; | |
129 int res; | |
130 String unexpandedIncluder = null; | |
131 String unexpandedIncludee = null; | |
132 do { | |
133 res = tokenizer.nextToken(); | |
134 if (res != StreamTokenizer.TT_EOF) { | |
135 if (numTok == 0) { | |
136 unexpandedIncluder = tokenizer.sval; | |
137 } else if (numTok == 1) { | |
138 unexpandedIncludee = tokenizer.sval; | |
139 } else { | |
140 throw new FileFormatException( | |
141 "invalid line: \"" + line + | |
142 "\". Error position: line " + lineNo | |
143 ); | |
144 } | |
145 numTok++; | |
146 } | |
147 } while (res != StreamTokenizer.TT_EOF); | |
148 | |
149 if ((numTok != 0) && (numTok != 2)) { | |
150 throw new FileFormatException( | |
151 "invalid line: \"" + line + | |
152 "\". Error position: line " + lineNo | |
153 ); | |
154 } | |
155 | |
156 if (numTok == 2) { | |
157 // Non-empty line | |
158 String includer = macros.expand(unexpandedIncluder); | |
159 String includee = macros.expand(unexpandedIncludee); | |
160 | |
161 if (includee.equals(plat.generatePlatformDependentInclude())) { | |
162 MacroDefinitions localExpander = macros.copy(); | |
163 MacroDefinitions localExpander2 = macros.copy(); | |
164 localExpander.setAllMacroBodiesTo("pd"); | |
165 localExpander2.setAllMacroBodiesTo(""); | |
166 | |
167 // unexpanded_includer e.g. thread_<os_arch>.hpp | |
168 // thread_solaris_i486.hpp -> _thread_pd.hpp.incl | |
169 | |
170 FileName pdName = | |
171 plat.getInclFileTemplate().copyStem( | |
172 localExpander.expand(unexpandedIncluder) | |
173 ); | |
174 | |
175 // derive generic name from platform specific name | |
176 // e.g. os_<arch_os>.hpp => os.hpp. We enforce the | |
177 // restriction (imperfectly) noted in includeDB_core | |
178 // that platform specific files will have an underscore | |
179 // preceding the macro invocation. | |
180 | |
181 // First expand macro as null string. | |
182 | |
183 String newIncluder_temp = | |
184 localExpander2.expand(unexpandedIncluder); | |
185 | |
186 // Now find "_." and remove the underscore. | |
187 | |
188 String newIncluder = ""; | |
189 | |
190 int len = newIncluder_temp.length(); | |
191 int count = 0; | |
192 | |
193 for ( int i = 0; i < len - 1 ; i++ ) { | |
194 if (newIncluder_temp.charAt(i) == '_' && newIncluder_temp.charAt(i+1) == '.') { | |
195 count++; | |
196 } else { | |
197 newIncluder += newIncluder_temp.charAt(i); | |
198 } | |
199 } | |
200 newIncluder += newIncluder_temp.charAt(len-1); | |
201 | |
202 if (count != 1) { | |
203 throw new FileFormatException( | |
204 "Unexpected filename format for platform dependent file.\nline: \"" + line + | |
205 "\".\nError position: line " + lineNo | |
206 ); | |
207 } | |
208 | |
209 FileList p = allFiles.listForFile(includer); | |
210 p.setPlatformDependentInclude(pdName.dirPreStemSuff()); | |
211 | |
213
8b48a7bd2bf7
6697238: missing dependencies for precompiled headers with platform dependent includes
never
parents:
0
diff
changeset
|
212 // Record the implicit include of this file so that the |
8b48a7bd2bf7
6697238: missing dependencies for precompiled headers with platform dependent includes
never
parents:
0
diff
changeset
|
213 // dependencies for precompiled headers can mention it. |
8b48a7bd2bf7
6697238: missing dependencies for precompiled headers with platform dependent includes
never
parents:
0
diff
changeset
|
214 platformDepFiles.put(newIncluder, includer); |
8b48a7bd2bf7
6697238: missing dependencies for precompiled headers with platform dependent includes
never
parents:
0
diff
changeset
|
215 |
0 | 216 // Add an implicit dependency on platform |
217 // specific file for the generic file | |
218 | |
219 p = platformFiles.listForFile(newIncluder); | |
220 | |
221 // if this list is empty then this is 1st | |
222 // occurance of a platform dependent file and | |
223 // we need a new version of the include file. | |
224 // Otherwise we just append to the current | |
225 // file. | |
226 | |
227 PrintWriter pdFile = | |
228 new PrintWriter( | |
229 new FileWriter(pdName.dirPreStemSuff(), | |
230 !p.isEmpty()) | |
231 ); | |
232 pdFile.println("# include \"" + includer + "\""); | |
233 pdFile.close(); | |
234 | |
235 // Add the platform specific file to the list | |
236 // for this generic file. | |
237 | |
238 FileList q = allFiles.listForFile(includer); | |
239 p.addIfAbsent(q); | |
240 } else { | |
241 FileList p = allFiles.listForFile(includer); | |
242 if (isOuterFile(includer)) | |
243 outerFiles.addIfAbsent(p); | |
244 | |
245 if (includee.equals(plat.noGrandInclude())) { | |
246 p.setUseGrandInclude(false); | |
247 } else { | |
248 FileList q = allFiles.listForFile(includee); | |
249 p.addIfAbsent(q); | |
250 } | |
251 } | |
252 } | |
253 } | |
254 } while (line != null); | |
255 reader.close(); | |
256 | |
257 // Keep allFiles in well-known order so we can easily determine | |
258 // whether the known files are the same | |
259 allFiles.sortByName(); | |
260 | |
261 // Add first and last files differently to prevent a mistake | |
262 // in ordering in the include databases from breaking the | |
263 // error reporting in the VM. | |
264 if (firstFile != null) { | |
265 FileList p = allFiles.listForFile(firstFile); | |
266 allFiles.setFirstFile(p); | |
267 outerFiles.setFirstFile(p); | |
268 } | |
269 | |
270 if (lastFile != null) { | |
271 FileList p = allFiles.listForFile(lastFile); | |
272 allFiles.setLastFile(p); | |
273 outerFiles.setLastFile(p); | |
274 } | |
275 } | |
276 | |
277 public void compute() { | |
278 System.out.println("\tcomputing closures\n"); | |
279 // build both indiv and grand results | |
280 for (Iterator iter = outerFiles.iterator(); iter.hasNext(); ) { | |
281 indivIncludes.add(((FileList) iter.next()).doCFile()); | |
282 ++nOuterFiles; | |
283 } | |
284 | |
285 if (!plat.haveGrandInclude()) | |
286 return; // nothing in grand include | |
287 | |
288 // count how many times each include is included & add em to grand | |
289 for (Iterator iter = indivIncludes.iterator(); iter.hasNext(); ) { | |
290 FileList indivInclude = (FileList) iter.next(); | |
291 if (!indivInclude.getUseGrandInclude()) { | |
292 continue; // do not bump count if my files cannot be | |
293 // in grand include | |
294 } | |
295 indivInclude.doFiles(grandInclude); // put em on | |
296 // grand_include list | |
297 for (Iterator incListIter = indivInclude.iterator(); | |
298 incListIter.hasNext(); ) { | |
299 ((FileList) incListIter.next()).incrementCount(); | |
300 } | |
301 } | |
302 } | |
303 | |
304 // Not sure this is necessary in Java | |
305 public void verify() { | |
306 for (Iterator iter = indivIncludes.iterator(); iter.hasNext(); ) { | |
307 if (iter.next() == null) { | |
308 plat.abort(); | |
309 } | |
310 } | |
311 } | |
312 | |
313 public void put() throws IOException { | |
314 writeIndividualIncludes(); | |
315 | |
316 if (plat.haveGrandInclude()) | |
317 writeGrandInclude(); | |
318 | |
319 writeGrandUnixMakefile(); | |
320 } | |
321 | |
322 private void writeIndividualIncludes() throws IOException { | |
323 System.out.println("\twriting individual include files\n"); | |
324 | |
325 for (Iterator iter = indivIncludes.iterator(); iter.hasNext(); ) { | |
326 FileList list = (FileList) iter.next(); | |
327 System.out.println("\tcreating " + list.getName()); | |
328 list.putInclFile(this); | |
329 } | |
330 } | |
331 | |
332 private void writeGrandInclude() throws IOException { | |
333 System.out.println("\twriting grand include file\n"); | |
334 PrintWriter inclFile = | |
335 new PrintWriter(new FileWriter(plat.getGIFileTemplate().dirPreStemSuff())); | |
336 plat.writeGIPragma(inclFile); | |
337 for (Iterator iter = grandInclude.iterator(); iter.hasNext(); ) { | |
338 FileList list = (FileList) iter.next(); | |
339 if (list.getCount() >= threshold) { | |
340 inclFile.println("# include \"" + | |
341 plat.getGIFileTemplate().getInvDir() + | |
342 list.getName() + | |
343 "\""); | |
344 } | |
345 } | |
346 inclFile.println(); | |
347 inclFile.close(); | |
348 } | |
349 | |
350 private void writeGrandUnixMakefile() throws IOException { | |
351 if (!plat.writeDeps()) | |
352 return; | |
353 | |
354 System.out.println("\twriting dependencies file\n"); | |
355 PrintWriter gd = | |
356 new PrintWriter(new FileWriter( | |
357 plat.getGDFileTemplate().dirPreStemSuff()) | |
358 ); | |
359 gd.println("# generated by makeDeps"); | |
360 gd.println(); | |
361 | |
362 | |
363 // HACK ALERT. The compilation of ad_<arch> files is very slow. | |
364 // We want to start compiling them as early as possible. The compilation | |
605 | 365 // order on unix is dependent on the order we emit files here. |
0 | 366 // By sorting the output before emitting it, we expect |
367 // that ad_<arch> will be compiled early. | |
368 boolean shouldSortObjFiles = true; | |
369 | |
370 if (shouldSortObjFiles) { | |
371 ArrayList sortList = new ArrayList(); | |
372 | |
373 // We need to preserve the ordering of the first and last items | |
374 // in outerFiles. | |
375 int size = outerFiles.size() - 1; | |
376 String firstName = removeSuffixFrom(((FileList)outerFiles.get(0)).getName()); | |
377 String lastName = removeSuffixFrom(((FileList)outerFiles.get(size)).getName()); | |
378 | |
379 for (int i=1; i<size; i++) { | |
380 FileList anOuterFile = (FileList)outerFiles.get(i); | |
381 String stemName = removeSuffixFrom(anOuterFile.getName()); | |
382 sortList.add(stemName); | |
383 } | |
384 Collections.sort(sortList); | |
385 | |
386 // write Obj_Files = ... | |
387 gd.println("Obj_Files = \\"); | |
388 gd.println(firstName + plat.objFileSuffix() + " \\"); | |
389 for (Iterator iter = sortList.iterator(); iter.hasNext(); ) { | |
390 gd.println(iter.next() + plat.objFileSuffix() + " \\"); | |
391 } | |
392 gd.println(lastName + plat.objFileSuffix() + " \\"); | |
393 gd.println(); | |
394 gd.println(); | |
395 } else { | |
396 // write Obj_Files = ... | |
397 gd.println("Obj_Files = \\"); | |
398 for (Iterator iter = outerFiles.iterator(); iter.hasNext(); ) { | |
399 FileList anOuterFile = (FileList) iter.next(); | |
400 | |
401 String stemName = removeSuffixFrom(anOuterFile.getName()); | |
402 gd.println(stemName + plat.objFileSuffix() + " \\"); | |
403 } | |
404 gd.println(); | |
405 gd.println(); | |
406 } | |
407 | |
830
00f7ec32f290
6854027: Precompiled headers are not being updated in Linux/GCC builds
apetrusenko
parents:
605
diff
changeset
|
408 // write Precompiled_Files = ... |
00f7ec32f290
6854027: Precompiled headers are not being updated in Linux/GCC builds
apetrusenko
parents:
605
diff
changeset
|
409 gd.println("Precompiled_Files = \\"); |
00f7ec32f290
6854027: Precompiled headers are not being updated in Linux/GCC builds
apetrusenko
parents:
605
diff
changeset
|
410 for (Iterator iter = grandInclude.iterator(); iter.hasNext(); ) { |
00f7ec32f290
6854027: Precompiled headers are not being updated in Linux/GCC builds
apetrusenko
parents:
605
diff
changeset
|
411 FileList list = (FileList) iter.next(); |
00f7ec32f290
6854027: Precompiled headers are not being updated in Linux/GCC builds
apetrusenko
parents:
605
diff
changeset
|
412 if (list.getCount() >= threshold) { |
0 | 413 gd.println(list.getName() + " \\"); |
213
8b48a7bd2bf7
6697238: missing dependencies for precompiled headers with platform dependent includes
never
parents:
0
diff
changeset
|
414 String platformDep = platformDepFiles.get(list.getName()); |
8b48a7bd2bf7
6697238: missing dependencies for precompiled headers with platform dependent includes
never
parents:
0
diff
changeset
|
415 if (platformDep != null) { |
830
00f7ec32f290
6854027: Precompiled headers are not being updated in Linux/GCC builds
apetrusenko
parents:
605
diff
changeset
|
416 // make sure changes to the platform dependent file will |
00f7ec32f290
6854027: Precompiled headers are not being updated in Linux/GCC builds
apetrusenko
parents:
605
diff
changeset
|
417 // cause regeneration of the pch file. |
00f7ec32f290
6854027: Precompiled headers are not being updated in Linux/GCC builds
apetrusenko
parents:
605
diff
changeset
|
418 gd.println(platformDep + " \\"); |
213
8b48a7bd2bf7
6697238: missing dependencies for precompiled headers with platform dependent includes
never
parents:
0
diff
changeset
|
419 } |
0 | 420 } |
421 } | |
830
00f7ec32f290
6854027: Precompiled headers are not being updated in Linux/GCC builds
apetrusenko
parents:
605
diff
changeset
|
422 gd.println(); |
00f7ec32f290
6854027: Precompiled headers are not being updated in Linux/GCC builds
apetrusenko
parents:
605
diff
changeset
|
423 gd.println(); |
0 | 424 |
425 gd.println("DTraced_Files = \\"); | |
426 for (Iterator iter = outerFiles.iterator(); iter.hasNext(); ) { | |
427 FileList anOuterFile = (FileList) iter.next(); | |
428 | |
429 if (anOuterFile.hasListForFile("dtrace.hpp")) { | |
430 String stemName = removeSuffixFrom(anOuterFile.getName()); | |
431 gd.println(stemName + plat.objFileSuffix() + " \\"); | |
432 } | |
433 } | |
434 gd.println(); | |
435 gd.println(); | |
436 | |
437 { | |
438 // write each dependency | |
439 | |
440 for (Iterator iter = indivIncludes.iterator(); iter.hasNext(); ) { | |
441 | |
442 FileList anII = (FileList) iter.next(); | |
443 | |
444 String stemName = removeSuffixFrom(anII.getName()); | |
445 String inclFileName = | |
446 plat.getInclFileTemplate().copyStem(anII.getName()). | |
447 preStemSuff(); | |
448 | |
449 gd.println(stemName + plat.objFileSuffix() + " " + | |
450 stemName + plat.asmFileSuffix() + ": \\"); | |
451 | |
452 printDependentOn(gd, anII.getName()); | |
453 // this gets the include file that includes all that | |
454 // this file needs (first level) since nested includes | |
455 // are skipped to avoid cycles. | |
456 printDependentOn(gd, inclFileName); | |
457 | |
458 if ( plat.haveGrandInclude() ) { | |
459 printDependentOn(gd, | |
460 plat.getGIFileTemplate().preStemSuff()); | |
461 } | |
462 | |
463 for (Iterator iiIter = anII.iterator(); iiIter.hasNext(); ) { | |
464 FileList hfile = (FileList) iiIter.next(); | |
465 if (!hfileIsInGrandInclude(hfile, anII) || | |
466 plat.writeDependenciesOnHFilesFromGI()) { | |
467 printDependentOn(gd, hfile.getName()); | |
468 } | |
469 if (platformFiles.hasListForFile(hfile.getName())) { | |
470 FileList p = | |
471 platformFiles.listForFile(hfile.getName());; | |
472 for (Iterator hiIter = p.iterator(); | |
473 hiIter.hasNext(); ) { | |
474 FileList hi2 = (FileList) hiIter.next(); | |
475 if (!hfileIsInGrandInclude(hi2, p)) { | |
476 printDependentOn(gd, hi2.getName()); | |
477 } | |
478 } | |
479 } | |
480 } | |
481 | |
482 if (plat.includeGIDependencies() | |
483 && anII.getUseGrandInclude()) { | |
484 gd.println(" $(Precompiled_Files) \\"); | |
485 } | |
486 gd.println(); | |
487 gd.println(); | |
488 } | |
489 } | |
490 | |
491 gd.close(); | |
492 } | |
493 | |
494 public void putDiffs(Database previous) throws IOException { | |
495 System.out.println("\tupdating output files\n"); | |
496 | |
497 if (!indivIncludes.compareLists(previous.indivIncludes) | |
498 || !grandInclude.compareLists(previous.grandInclude)) { | |
499 System.out.println("The order of .c or .s has changed, or " + | |
500 "the grand include file has changed."); | |
501 put(); | |
502 return; | |
503 } | |
504 | |
505 Iterator curIter = indivIncludes.iterator(); | |
506 Iterator prevIter = previous.indivIncludes.iterator(); | |
507 | |
508 try { | |
509 while (curIter.hasNext()) { | |
510 FileList newCFileList = (FileList) curIter.next(); | |
511 FileList prevCFileList = (FileList) prevIter.next(); | |
512 if (!newCFileList.compareLists(prevCFileList)) { | |
513 System.out.println("\tupdating " + newCFileList.getName()); | |
514 newCFileList.putInclFile(this); | |
515 } | |
516 } | |
517 } | |
518 catch (Exception e) { | |
519 throw new InternalError("assertion failure: cur and prev " + | |
520 "database lists changed unexpectedly."); | |
521 } | |
522 | |
523 writeGrandUnixMakefile(); | |
524 } | |
525 | |
526 private void printDependentOn(PrintWriter gd, String name) { | |
527 gd.print(" "); | |
528 gd.print(plat.dependentPrefix() + name); | |
529 } | |
530 | |
531 private boolean isOuterFile(String s) { | |
532 int len = s.length(); | |
533 String[] suffixes = plat.outerSuffixes(); | |
534 for (int i = 0; i < suffixes.length; i++) { | |
535 String suffix = suffixes[i]; | |
536 int suffLen = suffix.length(); | |
537 if ((len >= suffLen) && | |
538 (plat.fileNameStringEquality(s.substring(len - suffLen), | |
539 suffix))) { | |
540 return true; | |
541 } | |
542 } | |
543 return false; | |
544 } | |
545 | |
546 private String removeSuffixFrom(String s) { | |
547 int idx = s.lastIndexOf('.'); | |
548 if (idx <= 0) | |
549 plat.abort(); | |
550 return s.substring(0, idx); | |
551 } | |
552 } |