001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.cnd.dwarfdiscovery.provider;
043:
044: import java.io.BufferedReader;
045: import java.io.File;
046: import java.io.FileReader;
047: import java.io.IOException;
048: import java.net.InetAddress;
049: import java.net.UnknownHostException;
050: import java.util.ArrayList;
051: import java.util.HashMap;
052: import java.util.HashSet;
053: import java.util.Iterator;
054: import java.util.List;
055: import java.util.Map;
056: import java.util.Set;
057: import java.util.StringTokenizer;
058: import org.netbeans.modules.cnd.discovery.api.ItemProperties;
059: import org.netbeans.modules.cnd.discovery.api.SourceFileProperties;
060: import org.netbeans.modules.cnd.dwarfdump.CompilationUnit;
061: import org.netbeans.modules.cnd.dwarfdump.dwarf.DwarfMacinfoEntry;
062: import org.netbeans.modules.cnd.dwarfdump.dwarf.DwarfMacinfoTable;
063: import org.netbeans.modules.cnd.dwarfdump.dwarf.DwarfStatementList;
064: import org.netbeans.modules.cnd.dwarfdiscovery.provider.BaseDwarfProvider.CompilerSettings;
065: import org.openide.filesystems.FileUtil;
066: import org.openide.util.Utilities;
067:
068: /**
069: *
070: * @author Alexander Simon
071: */
072: public class DwarfSource implements SourceFileProperties {
073: private static final boolean FULL_TRACE = Boolean
074: .getBoolean("cnd.dwarfdiscovery.trace.read.source"); // NOI18N
075: private static boolean ourGatherMacros = true;
076: private static boolean ourGatherIncludes = true;
077: private static final String CYG_DRIVE_UNIX = "/cygdrive/"; // NOI18N
078: private static final String CYG_DRIVE_WIN = "\\cygdrive\\"; // NOI18N
079: private static final String CYGWIN_PATH = ":/cygwin"; // NOI18N
080: private String cygwinPath;
081:
082: private String compilePath;
083: private String sourceName;
084: private String fullName;
085: private ItemProperties.LanguageKind language;
086: private List<String> userIncludes;
087: private List<String> systemIncludes;
088: private boolean haveSystemIncludes;
089: private Map<String, String> userMacros;
090: private Map<String, String> systemMacros;
091: private boolean haveSystemMacros;
092: private Set<String> includedFiles;
093: private CompilerSettings normilizeProvider;
094: private Map<String, List<String>> grepBase;
095:
096: DwarfSource(CompilationUnit cu, boolean isCPP,
097: CompilerSettings compilerSettings,
098: Map<String, List<String>> grepBase) {
099: initCompilerSettings(compilerSettings, isCPP);
100: this .grepBase = grepBase;
101: initSourceSettings(cu, isCPP);
102: }
103:
104: private void countFileName(CompilationUnit cu) {
105: fullName = cu.getSourceFileAbsolutePath();
106: fullName = fixFileName(fullName);
107: File file = new File(fullName);
108: fullName = FileUtil.normalizeFile(file).getAbsolutePath();
109: fullName = linkSupport(fullName);
110: if (fullName != null && Utilities.isWindows()) {
111: fullName = fullName.replace('/', '\\');
112: }
113: fullName = PathCache.getString(fullName);
114: if (FULL_TRACE)
115: System.out
116: .println("Compilation unit full name:" + fullName); // NOI18N
117: }
118:
119: private void initCompilerSettings(
120: CompilerSettings compilerSettings, boolean isCPP) {
121: List<String> list = compilerSettings
122: .getSystemIncludePaths(isCPP);
123: if (list != null) {
124: systemIncludes = new ArrayList<String>(list);
125: //if (FULL_TRACE) {
126: // System.out.println("System Include Paths:"); // NOI18N
127: // for (String s : list) {
128: // System.out.println("\t"+s); // NOI18N
129: // }
130: //}
131: if (Utilities.isWindows()) {
132: if (FULL_TRACE)
133: System.out.println("CompileFlavor:"
134: + compilerSettings.getCompileFlavor()); // NOI18N
135: if ("Cygwin"
136: .equals(compilerSettings.getCompileFlavor())) { // NOI18N
137: //cygwinPath = compilerSettings.getCompileDirectory();
138: for (String path : list) {
139: int i = path.toLowerCase().indexOf(CYGWIN_PATH);
140: if (i > 0) {
141: if (cygwinPath == null) {
142: cygwinPath = ""
143: + Character.toUpperCase(path
144: .charAt(0))
145: + CYGWIN_PATH; // NOI18N
146: if (FULL_TRACE)
147: System.out
148: .println("Detect cygwinPath:"
149: + cygwinPath); // NOI18N
150: break;
151: }
152: }
153: }
154: }
155: }
156: } else {
157: systemIncludes = new ArrayList<String>();
158: }
159: haveSystemIncludes = systemIncludes.size() > 0;
160: Map<String, String> map = compilerSettings
161: .getSystemMacroDefinitions(isCPP);
162: if (map != null) {
163: systemMacros = new HashMap<String, String>(map);
164: } else {
165: systemMacros = new HashMap<String, String>();
166: }
167: haveSystemMacros = systemMacros.size() > 0;
168: normilizeProvider = compilerSettings;
169: }
170:
171: public String getCompilePath() {
172: return compilePath;
173: }
174:
175: public String getItemPath() {
176: return fullName;
177: }
178:
179: public String getItemName() {
180: return sourceName;
181: }
182:
183: public List<String> getUserInludePaths() {
184: return userIncludes;
185: }
186:
187: public List<String> getSystemInludePaths() {
188: return systemIncludes;
189: }
190:
191: public Set<String> getIncludedFiles() {
192: return includedFiles;
193: }
194:
195: public Map<String, String> getUserMacros() {
196: return userMacros;
197: }
198:
199: public Map<String, String> getSystemMacros() {
200: return systemMacros;
201: }
202:
203: public ItemProperties.LanguageKind getLanguageKind() {
204: return language;
205: }
206:
207: /**
208: * Path is include path like:
209: * .
210: * ../
211: * include
212: * Returns path in unix style
213: */
214: public static String convertRelativePathToAbsolute(
215: SourceFileProperties source, String path) {
216: if (!(path.startsWith("/") || (path.length() > 1 && path
217: .charAt(1) == ':'))) { // NOI18N
218: if (path.equals(".")) { // NOI18N
219: path = source.getCompilePath();
220: } else {
221: path = source.getCompilePath() + File.separator + path;
222: }
223: File file = new File(path);
224: path = FileUtil.normalizeFile(file).getAbsolutePath();
225: }
226: if (Utilities.isWindows()) {
227: path = path.replace('\\', '/');
228: }
229: return path;
230: }
231:
232: public static final String getRelativePath(String base, String path) {
233: if (path.equals(base)) {
234: return path;
235: } else if (path.startsWith(base + '/')) {
236: return path.substring(base.length() + 1);
237: } else if (path.startsWith(base + '\\')) {
238: return path.substring(base.length() + 1);
239: } else if (!(path.startsWith("/") || path.startsWith("\\") || // NOI18N
240: path.length() > 2 && path.charAt(2) == ':')) {
241: return path;
242: } else {
243: StringTokenizer stb = new StringTokenizer(base, "\\/"); // NOI18N
244: StringTokenizer stp = new StringTokenizer(path, "\\/"); // NOI18N
245: int match = 0;
246: String pstring = null;
247: while (stb.hasMoreTokens() && stp.hasMoreTokens()) {
248: String bstring = stb.nextToken();
249: pstring = stp.nextToken();
250: if (bstring.equals(pstring)) {
251: match++;
252: } else {
253: break;
254: }
255: }
256: if (match <= 1) {
257: return path;
258: }
259: StringBuilder s = new StringBuilder();
260: while (stb.hasMoreTokens()) {
261: String bstring = stb.nextToken();
262: s.append(".." + File.separator); // NOI18N
263: }
264: s.append(".." + File.separator + pstring); // NOI18N
265: while (stp.hasMoreTokens()) {
266: s.append(File.separator + stp.nextToken()); // NOI18N
267: }
268: return s.toString();
269: }
270: }
271:
272: private String fixFileName(String fileName) {
273: if (fileName == null) {
274: return fileName;
275: }
276: if (Utilities.isWindows()) {
277: //replace /cygdrive/<something> prefix with <something>:/ prefix:
278: if (FULL_TRACE)
279: System.out.println("Try to fix win name:" + fileName); // NOI18N
280: if (fileName.startsWith(CYG_DRIVE_UNIX)) {
281: fileName = fileName.substring(CYG_DRIVE_UNIX.length()); // NOI18N
282: fileName = ""
283: + Character.toUpperCase(fileName.charAt(0))
284: + ':' + fileName.substring(1); // NOI18N
285: fileName = fileName.replace('\\', '/');
286: if (cygwinPath == null) {
287: cygwinPath = ""
288: + Character.toUpperCase(fileName.charAt(0))
289: + CYGWIN_PATH;
290: if (FULL_TRACE)
291: System.out.println("Set cygwinPath:"
292: + cygwinPath); // NOI18N
293: }
294: } else {
295: int i = fileName.indexOf(CYG_DRIVE_WIN);
296: if (i > 0) {
297: //replace D:\cygdrive\c\<something> prefix with <something>:\ prefix:
298: if (cygwinPath == null) {
299: cygwinPath = ""
300: + Character.toUpperCase(fileName
301: .charAt(0)) + CYGWIN_PATH; // NOI18N
302: if (FULL_TRACE)
303: System.out.println("Set cygwinPath:"
304: + cygwinPath); // NOI18N
305: }
306: fileName = fileName.substring(i
307: + CYG_DRIVE_UNIX.length());
308: fileName = ""
309: + Character.toUpperCase(fileName.charAt(0))
310: + ':' + fileName.substring(1); // NOI18N
311: fileName = fileName.replace('\\', '/');
312: }
313: }
314: if (FULL_TRACE)
315: System.out.println("\t" + fileName); // NOI18N
316: } else if (Utilities.isUnix()) {
317: if (fileName.startsWith("/net/")) { // NOI18N
318: try {
319: InetAddress addr = InetAddress.getLocalHost();
320: String host = addr.getHostName();
321: if (host != null && host.length() > 0) {
322: String u = "/net/" + host + "/"; // NOI18N
323: if (fileName.startsWith(u)) {
324: fileName = fileName
325: .substring(u.length() - 1);
326: }
327: }
328: } catch (UnknownHostException ex) {
329: }
330: }
331: }
332: return fileName;
333: }
334:
335: private String linkSupport(String name) {
336: if (Utilities.isWindows()) {
337: if (!new File(name).exists()) {
338: String link = name + ".lnk"; // NOI18N
339: if (new File(link).exists()) {
340: try {
341: LinkReader linkReader = new LinkReader(link);
342: if (linkReader.getSource() != null) {
343: name = linkReader.getSource();
344: }
345: } catch (Exception ex) {
346: ex.printStackTrace();
347: }
348: } else {
349: StringTokenizer st = new StringTokenizer(name,
350: "\\/"); // NOI18N
351: StringBuilder buf = new StringBuilder();
352: while (st.hasMoreTokens()) {
353: String token = st.nextToken();
354: if (buf.length() > 0) {
355: buf.append('\\');
356: }
357: buf.append(token);
358: if (token.length() > 0
359: && token.charAt(token.length() - 1) != ':') {
360: String path = buf.toString();
361: if (!new File(path).exists()) {
362: link = path + ".lnk"; // NOI18N
363: if (new File(link).exists()) {
364: try {
365: LinkReader linkReader = new LinkReader(
366: link);
367: if (linkReader.getSource() != null) {
368: buf = new StringBuilder(
369: linkReader
370: .getSource());
371: }
372: } catch (Exception ex) {
373: ex.printStackTrace();
374: return name;
375: }
376: } else {
377: return name;
378: }
379: }
380: }
381: }
382: name = buf.toString();
383: }
384: }
385: }
386: return name;
387: }
388:
389: private void initSourceSettings(CompilationUnit cu, boolean isCPP) {
390: userIncludes = new ArrayList<String>();
391: userMacros = new HashMap<String, String>();
392: includedFiles = new HashSet<String>();
393: countFileName(cu);
394: compilePath = PathCache.getString(fixFileName(cu
395: .getCompilationDir()));
396: sourceName = PathCache.getString(cu.getSourceFileName());
397:
398: if (compilePath == null && sourceName.lastIndexOf('/') > 0) {
399: int i = sourceName.lastIndexOf('/');
400: compilePath = sourceName.substring(0, i);
401: sourceName = sourceName.substring(i + 1);
402: } else {
403: if (sourceName.startsWith("/")) { // NOI18N
404: sourceName = getRelativePath(compilePath, sourceName);
405: }
406: }
407: if (isCPP) {
408: language = ItemProperties.LanguageKind.CPP;
409: } else {
410: language = ItemProperties.LanguageKind.C;
411: }
412: }
413:
414: public void process(CompilationUnit cu) {
415: String line = cu.getCommandLine();
416: if (line != null && line.length() > 0) {
417: gatherLine(line);
418: gatherIncludedFiles(cu);
419: } else {
420: gatherMacros(cu);
421: gatherIncludes(cu);
422: }
423: }
424:
425: private void addUserIncludePath(String path) {
426: userIncludes.add(path);
427: }
428:
429: // public because method is used in unit tests.
430: public static List<String> scanCommandLine(String line) {
431: List<String> res = new ArrayList<String>();
432: int i = 0;
433: StringBuilder current = new StringBuilder();
434: boolean isSingleQuoteMode = false;
435: boolean isDoubleQuoteMode = false;
436: while (i < line.length()) {
437: char c = line.charAt(i);
438: i++;
439: if (c == '\'') {
440: if (isSingleQuoteMode) {
441: isSingleQuoteMode = false;
442: } else if (!isDoubleQuoteMode) {
443: isSingleQuoteMode = true;
444: }
445: current.append(c);
446: continue;
447: } else if (c == '\"') {
448: if (isDoubleQuoteMode) {
449: isDoubleQuoteMode = false;
450: } else if (!isSingleQuoteMode) {
451: isDoubleQuoteMode = true;
452: }
453: current.append(c);
454: continue;
455: } else if (isSingleQuoteMode || isDoubleQuoteMode) {
456: current.append(c);
457: continue;
458: }
459: if (Character.isWhitespace(c)) {
460: if (current.length() > 0) {
461: res.add(current.toString());
462: current.setLength(0);
463: }
464: } else {
465: current.append(c);
466: }
467: }
468: if (current.length() > 0) {
469: res.add(current.toString());
470: }
471: return res;
472: }
473:
474: private void gatherLine(String line) {
475: // /set/c++/bin/5.9/intel-S2/prod/bin/CC -c -g -DHELLO=75 -Idist main.cc -Qoption ccfe -prefix -Qoption ccfe .XAKABILBpivFlIc.
476: if (FULL_TRACE)
477: System.out.println("Process command line " + line); // NOI18N
478: Iterator<String> st = scanCommandLine(line).iterator();
479: while (st.hasNext()) {
480: String option = st.next();
481: if (option.startsWith("-D")) { // NOI18N
482: String macro = option.substring(2);
483: int i = macro.indexOf('=');
484: if (i > 0) {
485: String value = macro.substring(i + 1).trim();
486: if (value.length() >= 2
487: && (value.charAt(0) == '\''
488: && value.charAt(value.length() - 1) == '\'' || // NOI18N
489: value.charAt(0) == '"'
490: && value.charAt(value.length() - 1) == '"')) { // NOI18N
491: value = value.substring(1, value.length() - 1);
492: }
493: userMacros.put(PathCache.getString(macro.substring(
494: 0, i)), PathCache.getString(value));
495: } else {
496: userMacros.put(PathCache.getString(macro), null);
497: }
498: } else if (option.startsWith("-I")) { // NOI18N
499: String path = option.substring(2);
500: if (path.length() == 0 && st.hasNext()) {
501: path = st.next();
502: }
503: String include = PathCache.getString(path);
504: addUserIncludePath(include);
505: } else if (option.startsWith("-Y")) { // NOI18N
506: String defaultSearchPath = option.substring(2);
507: if (defaultSearchPath.length() == 0 && st.hasNext()) {
508: defaultSearchPath = st.next();
509: }
510: if (defaultSearchPath.startsWith("I,")) { // NOI18N
511: defaultSearchPath = defaultSearchPath.substring(2);
512: String include = PathCache
513: .getString(defaultSearchPath);
514: addUserIncludePath(include);
515: }
516: } else if (option.equals("-fopenmp")) { // NOI18N
517: userMacros.put("_OPENMP", null); // NOI18N
518: }
519: }
520: }
521:
522: private String fixCygwinPath(String path) {
523: if (cygwinPath != null) {
524: if (path.startsWith("/usr/lib/")) {// NOI18N
525: path = cygwinPath + path.substring(4);
526: } else if (path.startsWith("/usr")) { // NOI18N
527: path = cygwinPath + path;
528: }
529: }
530: if (path.startsWith(CYG_DRIVE_UNIX)) {
531: path = fixFileName(path);
532: }
533: if (Utilities.isWindows()) {
534: path = path.replace('\\', '/');
535: }
536: return path;
537: }
538:
539: private boolean isSystemPath(String path) {
540: path = fixCygwinPath(path);
541: path = normalizePath(path);
542: if (path.startsWith("/") || // NOI18N
543: path.length() > 2 && path.charAt(1) == ':') {
544: for (String cp : systemIncludes) {
545: if (path.startsWith(cp)) {
546: return true;
547: }
548: }
549: }
550: return false;
551: }
552:
553: private void addpath(String path) {
554: if (haveSystemIncludes) {
555: if (!isSystemPath(path)) {
556: addUserIncludePath(PathCache.getString(path));
557: if (FULL_TRACE)
558: System.out.println("\tuser:" + path); // NOI18N
559: }
560: } else {
561: if (path.startsWith("/usr")) { // NOI18N
562: path = fixCygwinPath(path);
563: path = normalizePath(path);
564: systemIncludes.add(PathCache.getString(path));
565: if (FULL_TRACE)
566: System.out.println("\tsystem:" + path); // NOI18N
567: } else {
568: path = fixCygwinPath(path);
569: path = normalizePath(path);
570: addUserIncludePath(PathCache.getString(path));
571: if (FULL_TRACE)
572: System.out.println("\tuser:" + path); // NOI18N
573: }
574: }
575: }
576:
577: private String normalizePath(String path) {
578: if (path.startsWith("/") || // NOI18N
579: path.length() > 2 && path.charAt(1) == ':') {
580: return normilizeProvider.getNormalizedPath(path);
581: }
582: return path;
583: }
584:
585: private void gatherIncludes(final CompilationUnit cu) {
586: if (!ourGatherIncludes) {
587: return;
588: }
589: DwarfStatementList dwarfTable = cu.getStatementList();
590: if (dwarfTable == null) {
591: if (FULL_TRACE)
592: System.out.println("Include paths not found"); // NOI18N
593: return;
594: }
595: for (Iterator<String> it = dwarfTable.getIncludeDirectories()
596: .iterator(); it.hasNext();) {
597: addpath(it.next());
598: }
599: List<String> list = grepSourceFile(fullName);
600: for (String path : list) {
601: cutFolderPrefix(path, dwarfTable);
602: }
603: ArrayList<String> dwarfIncludedFiles = dwarfTable
604: .getFilePaths();
605: for (String path : dwarfIncludedFiles) {
606: String includeFullName = path;
607: if (FULL_TRACE)
608: System.out.println("Included file original:" + path); // NOI18N
609: if (path.startsWith("./")) { // NOI18N
610: includeFullName = compilePath + path.substring(1);
611: } else if (path.startsWith("../")) { // NOI18N
612: includeFullName = compilePath + File.separator + path;
613: } else if (!path.startsWith("/")) { // NOI18N
614: includeFullName = compilePath + File.separator + path;
615: } else {
616: includeFullName = fixCygwinPath(path);
617: includeFullName = normalizePath(includeFullName);
618: }
619: if (Utilities.isWindows()) {
620: includeFullName = includeFullName.replace('\\', '/');
621: }
622: if (!isSystemPath(includeFullName)) {
623: list = grepSourceFile(includeFullName);
624: for (String included : list) {
625: cutFolderPrefix(included, dwarfTable);
626: }
627: }
628: includedFiles.add(PathCache.getString(includeFullName));
629: if (FULL_TRACE)
630: System.out.println("Included file:" + includeFullName); // NOI18N
631: }
632: if (FULL_TRACE)
633: System.out.println("Include paths:" + userIncludes); // NOI18N
634: }
635:
636: private void cutFolderPrefix(String path,
637: final DwarfStatementList dwarfTable) {
638: if (Utilities.isWindows()) {
639: path = path.replace('\\', '/'); // NOI18N
640: }
641: if (path.indexOf('/') > 0) { // NOI18N
642: int n = path.lastIndexOf('/'); // NOI18N
643: String name = path.substring(n + 1);
644: String relativeDir = path.substring(0, n);
645: String dir = "/" + relativeDir; // NOI18N
646: ArrayList<String> paths = dwarfTable.getPathsForFile(name);
647: if (FULL_TRACE)
648: System.out.println("Try to find new include paths for:"
649: + name + " in folder " + dir); // NOI18N
650: for (String dwarfPath : paths) {
651: if (FULL_TRACE)
652: System.out.println(" candidate:" + dwarfPath); // NOI18N
653: if (dwarfPath.endsWith(dir)) {
654: String found = dwarfPath.substring(0, dwarfPath
655: .length()
656: - dir.length());
657: found = fixCygwinPath(found);
658: found = normalizePath(found);
659: if (!userIncludes.contains(found)) {
660: if (haveSystemIncludes) {
661: boolean system = false;
662: if (found.startsWith("/")
663: || // NOI18N
664: found.length() > 2
665: && found.charAt(1) == ':') {
666: system = systemIncludes.contains(found);
667: }
668: if (!system) {
669: if (FULL_TRACE)
670: System.out
671: .println(" Find new include path:"
672: + found); // NOI18N
673: addUserIncludePath(PathCache
674: .getString(found));
675: }
676: } else {
677: if (!dwarfPath.startsWith("/usr")) { // NOI18N
678: if (FULL_TRACE)
679: System.out
680: .println(" Find new include path:"
681: + found); // NOI18N
682: addUserIncludePath(PathCache
683: .getString(found));
684: }
685: }
686: }
687: break;
688: } else if (dwarfPath.equals(relativeDir)) {
689: String found = "."; // NOI18N
690: if (!userIncludes.contains(found)) {
691: if (FULL_TRACE)
692: System.out
693: .println(" Find new include path:"
694: + found); // NOI18N
695: addUserIncludePath(PathCache.getString(found));
696: }
697: break;
698: }
699: }
700: }
701: }
702:
703: private void gatherIncludedFiles(final CompilationUnit cu) {
704: if (!ourGatherIncludes) {
705: return;
706: }
707: DwarfStatementList dwarfTable = cu.getStatementList();
708: if (dwarfTable == null) {
709: return;
710: }
711: for (String path : dwarfTable.getFilePaths()) {
712: String includeFullName = path;
713: if (path.startsWith("./")) { // NOI18N
714: includeFullName = compilePath + path.substring(1);
715: } else if (path.startsWith("../")) { // NOI18N
716: includeFullName = compilePath + File.separator + path;
717: }
718: includeFullName = normalizePath(includeFullName);
719: includedFiles.add(PathCache.getString(includeFullName));
720: }
721: }
722:
723: private void gatherMacros(final CompilationUnit cu) {
724: if (!ourGatherMacros) {
725: return;
726: }
727: DwarfMacinfoTable dwarfTable = cu.getMacrosTable();
728: if (dwarfTable == null) {
729: if (FULL_TRACE)
730: System.out.println("Macros not found"); // NOI18N
731: return;
732: }
733: ArrayList<DwarfMacinfoEntry> table = dwarfTable
734: .getCommandLineMarcos();
735: for (Iterator<DwarfMacinfoEntry> it = table.iterator(); it
736: .hasNext();) {
737: DwarfMacinfoEntry entry = it.next();
738: String def = entry.definition;
739: int i = def.indexOf(' ');
740: String macro;
741: String value = null;
742: if (i > 0) {
743: macro = PathCache.getString(def.substring(0, i));
744: value = PathCache
745: .getString(def.substring(i + 1).trim());
746: } else {
747: macro = PathCache.getString(def);
748: }
749: if (haveSystemMacros && systemMacros.containsKey(macro)) {
750: String sysValue = systemMacros.get(macro);
751: if (equalValues(sysValue, value)) {
752: continue;
753: }
754: }
755: userMacros.put(macro, value);
756: }
757: if (FULL_TRACE)
758: System.out.println("Macros:" + userMacros); // NOI18N
759: }
760:
761: private boolean equalValues(String sysValue, String value) {
762: // filter out system macros
763: // For example gcc windows dwarf contains following system macros as user:
764: // unix=1 __unix=1 __unix__=1 __CYGWIN__=1 __CYGWIN32__=1
765: if (value == null || "1".equals(value)) { // NOI18N
766: return sysValue == null || "1".equals(sysValue); // NOI18N
767: }
768: return value.equals(sysValue); // NOI18N
769: }
770:
771: private List<String> grepSourceFile(String fileName) {
772: List<String> res = grepBase.get(fileName);
773: if (res != null) {
774: return res;
775: }
776: res = new ArrayList<String>();
777: File file = new File(fileName);
778: if (file.exists() && file.canRead()) {
779: try {
780: BufferedReader in = new BufferedReader(new FileReader(
781: file));
782: while (true) {
783: String line = in.readLine();
784: if (line == null) {
785: break;
786: }
787: line = line.trim();
788: if (!line.startsWith("#")) { // NOI18N
789: continue;
790: }
791: line = line.substring(1).trim();
792: if (line.startsWith("include")) { // NOI18N
793: line = line.substring(7).trim();
794: if (line.length() > 2) {
795: char c = line.charAt(0);
796: if (c == '"') {
797: if (line.indexOf('"', 1) > 0) {
798: res.add(line.substring(1, line
799: .indexOf('"', 1)));
800: if (FULL_TRACE)
801: System.out
802: .println("find in source:"
803: + line
804: .substring(
805: 1,
806: line
807: .indexOf(
808: '"',
809: 1))); // NOI18N
810: }
811: } else if (c == '<') {
812: if (line.indexOf('>') > 0) {
813: res.add(line.substring(1, line
814: .indexOf('>')));
815: if (FULL_TRACE)
816: System.out
817: .println("find in source:"
818: + line
819: .substring(
820: 1,
821: line
822: .indexOf('>'))); // NOI18N
823: }
824: }
825: }
826: }
827: }
828: in.close();
829: } catch (IOException ex) {
830: ex.printStackTrace();
831: }
832: } else {
833: if (FULL_TRACE)
834: System.out.println("Cannot grep file:" + fileName); // NOI18N
835: }
836: grepBase.put(fileName, res);
837: return res;
838: }
839: }
|