PageRenderTime 80ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/netbeans-7.3/cnd.dwarfdiscovery/src/org/netbeans/modules/cnd/dwarfdiscovery/provider/DwarfSource.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 937 lines | 887 code | 3 blank | 47 comment | 2 complexity | 1f9a7613619fbf3524deeaf9329bcc8c MD5 | raw file
  1. /*
  2. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  3. *
  4. * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
  5. *
  6. * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  7. * Other names may be trademarks of their respective owners.
  8. *
  9. * The contents of this file are subject to the terms of either the GNU
  10. * General Public License Version 2 only ("GPL") or the Common
  11. * Development and Distribution License("CDDL") (collectively, the
  12. * "License"). You may not use this file except in compliance with the
  13. * License. You can obtain a copy of the License at
  14. * http://www.netbeans.org/cddl-gplv2.html
  15. * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  16. * specific language governing permissions and limitations under the
  17. * License. When distributing the software, include this License Header
  18. * Notice in each file and include the License file at
  19. * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
  20. * particular file as subject to the "Classpath" exception as provided
  21. * by Oracle in the GPL Version 2 section of the License file that
  22. * accompanied this code. If applicable, add the following below the
  23. * License Header, with the fields enclosed by brackets [] replaced by
  24. * your own identifying information:
  25. * "Portions Copyrighted [year] [name of copyright owner]"
  26. *
  27. * Contributor(s):
  28. *
  29. * The Original Software is NetBeans. The Initial Developer of the Original
  30. * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
  31. * Microsystems, Inc. All Rights Reserved.
  32. *
  33. * If you wish your version of this file to be governed by only the CDDL
  34. * or only the GPL Version 2, indicate your decision by adding
  35. * "[Contributor] elects to include this software in this distribution
  36. * under the [CDDL or GPL Version 2] license." If you do not indicate a
  37. * single choice of license, a recipient has the option to distribute
  38. * your version of this file under either the CDDL, the GPL Version 2 or
  39. * to extend the choice of license to its licensees as provided above.
  40. * However, if you add GPL Version 2 code and therefore, elected the GPL
  41. * Version 2 license, then the option applies only if the new code is
  42. * made subject to such option by the copyright holder.
  43. */
  44. package org.netbeans.modules.cnd.dwarfdiscovery.provider;
  45. import java.io.BufferedReader;
  46. import java.io.File;
  47. import java.io.FileReader;
  48. import java.io.IOException;
  49. import java.net.InetAddress;
  50. import java.net.UnknownHostException;
  51. import java.util.ArrayList;
  52. import java.util.Collections;
  53. import java.util.HashMap;
  54. import java.util.HashSet;
  55. import java.util.Iterator;
  56. import java.util.List;
  57. import java.util.Map;
  58. import java.util.Set;
  59. import java.util.StringTokenizer;
  60. import java.util.logging.Level;
  61. import java.util.logging.Logger;
  62. import org.netbeans.modules.cnd.discovery.api.DiscoveryUtils;
  63. import org.netbeans.modules.cnd.discovery.api.ItemProperties;
  64. import org.netbeans.modules.cnd.discovery.api.SourceFileProperties;
  65. import org.netbeans.modules.cnd.dwarfdiscovery.provider.BaseDwarfProvider.GrepEntry;
  66. import org.netbeans.modules.cnd.dwarfdump.CompilationUnit;
  67. import org.netbeans.modules.cnd.dwarfdump.CompilationUnitInterface;
  68. import org.netbeans.modules.cnd.dwarfdump.dwarf.DwarfMacinfoEntry;
  69. import org.netbeans.modules.cnd.dwarfdump.dwarf.DwarfMacinfoTable;
  70. import org.netbeans.modules.cnd.dwarfdump.dwarf.DwarfStatementList;
  71. import org.netbeans.modules.cnd.makeproject.api.configurations.ConfigurationDescriptorProvider;
  72. import org.netbeans.modules.nativeexecution.api.util.LinkSupport;
  73. import org.openide.util.Exceptions;
  74. import org.openide.util.Utilities;
  75. /**
  76. *
  77. * @author Alexander Simon
  78. */
  79. public class DwarfSource extends RelocatableImpl implements SourceFileProperties {
  80. public static final Logger LOG = Logger.getLogger(DwarfSource.class.getName());
  81. private static final boolean CUT_LOCALHOST_NET_ADRESS = Boolean.getBoolean("cnd.dwarfdiscovery.cut.localhost.net.adress"); // NOI18N
  82. private static boolean ourGatherMacros = true;
  83. private static boolean ourGatherIncludes = true;
  84. private static final String CYG_DRIVE_UNIX = "/cygdrive/"; // NOI18N
  85. private static final String CYG_DRIVE_WIN = "\\cygdrive\\"; // NOI18N
  86. private static final String CYGWIN_PATH = ":/cygwin"; // NOI18N
  87. private String cygwinPath;
  88. private String sourceName;
  89. private final ItemProperties.LanguageKind language;
  90. private final ItemProperties.LanguageStandard standard;
  91. private List<String> systemIncludes;
  92. private boolean haveSystemIncludes;
  93. private Map<String, String> userMacros;
  94. private List<String> undefinedMacros;
  95. private Map<String, String> systemMacros;
  96. private boolean haveSystemMacros;
  97. private CompilerSettings normilizeProvider;
  98. private final Map<String,GrepEntry> grepBase;
  99. private String compilerName;
  100. private final CompileLineStorage storage;
  101. private int handler = -1;
  102. private final CompilerSettings compilerSettings;
  103. DwarfSource(CompilationUnitInterface cu, ItemProperties.LanguageKind lang, ItemProperties.LanguageStandard standard, CompilerSettings compilerSettings, Map<String,GrepEntry> grepBase, CompileLineStorage storage) throws IOException{
  104. language = lang;
  105. this.grepBase = grepBase;
  106. this.standard = standard;
  107. this.storage = storage;
  108. this.compilerSettings = compilerSettings;
  109. initCompilerSettings(compilerSettings, lang);
  110. initSourceSettings(cu, lang);
  111. }
  112. private void countFileName(CompilationUnitInterface cu) throws IOException {
  113. fullName = cu.getSourceFileAbsolutePath();
  114. fullName = fixFileName(fullName);
  115. //File file = new File(fullName);
  116. fullName = DiscoveryUtils.normalizeAbsolutePath(fullName);
  117. fullName = linkSupport(fullName);
  118. if (fullName != null && normilizeProvider.isWindows()) {
  119. fullName = fullName.replace('/', '\\');
  120. }
  121. fullName = PathCache.getString(fullName);
  122. if (DwarfSource.LOG.isLoggable(Level.FINE)) {
  123. DwarfSource.LOG.log(Level.FINE, "Compilation unit full name:{0}", fullName); // NOI18N
  124. }
  125. }
  126. private void initCompilerSettings(CompilerSettings compilerSettings, ItemProperties.LanguageKind lang){
  127. List<String> list = compilerSettings.getSystemIncludePaths(lang);
  128. if (list != null){
  129. systemIncludes = new ArrayList<String>(list);
  130. //if (FULL_TRACE) {
  131. // System.out.println("System Include Paths:"); // NOI18N
  132. // for (String s : list) {
  133. // System.out.println("\t"+s); // NOI18N
  134. // }
  135. //}
  136. if (compilerSettings.isWindows()) {
  137. if (DwarfSource.LOG.isLoggable(Level.FINE)) {
  138. DwarfSource.LOG.log(Level.FINE, "CompileFlavor:{0}", compilerSettings.getCompileFlavor()); // NOI18N
  139. }
  140. if (compilerSettings.getCompileFlavor() != null && compilerSettings.getCompileFlavor().isCygwinCompiler()) {
  141. cygwinPath = compilerSettings.getCygwinDrive();
  142. if (cygwinPath == null) {
  143. for(String path:list){
  144. int i = path.toLowerCase().indexOf(CYGWIN_PATH);
  145. if (i > 0) {
  146. if (cygwinPath == null) {
  147. cygwinPath = "" + Character.toUpperCase(path.charAt(0)) + CYGWIN_PATH; // NOI18N
  148. for(i = i + CYGWIN_PATH.length();i < path.length();i++){
  149. char c = path.charAt(i);
  150. if (c == '\\'){
  151. break;
  152. }
  153. cygwinPath+=""+c;
  154. }
  155. if (DwarfSource.LOG.isLoggable(Level.FINE)) {
  156. DwarfSource.LOG.log(Level.FINE, "Detect cygwinPath:{0}", cygwinPath); // NOI18N
  157. }
  158. break;
  159. }
  160. }
  161. }
  162. }
  163. }
  164. }
  165. } else {
  166. systemIncludes = new ArrayList<String>();
  167. }
  168. haveSystemIncludes = systemIncludes.size() > 0;
  169. Map<String, String> map = compilerSettings.getSystemMacroDefinitions(lang);
  170. if (map != null){
  171. systemMacros = new HashMap<String,String>(map);
  172. } else {
  173. systemMacros = new HashMap<String,String>();
  174. }
  175. haveSystemMacros = systemMacros.size() > 0;
  176. normilizeProvider = compilerSettings;
  177. }
  178. @Override
  179. public String getCompilePath() {
  180. return compilePath;
  181. }
  182. @Override
  183. public String getCompileLine() {
  184. if (storage != null && handler != -1) {
  185. return storage.getCompileLine(handler);
  186. }
  187. return null;
  188. }
  189. @Override
  190. public String getItemPath() {
  191. return fullName;
  192. }
  193. @Override
  194. public String getItemName() {
  195. return sourceName;
  196. }
  197. @Override
  198. public List<String> getUserInludePaths() {
  199. return userIncludes;
  200. }
  201. @Override
  202. public List<String> getSystemInludePaths() {
  203. return systemIncludes;
  204. }
  205. public Set<String> getIncludedFiles() {
  206. if (false && ConfigurationDescriptorProvider.VCS_WRITE) {
  207. return Collections.emptySet();
  208. }
  209. return includedFiles;
  210. }
  211. @Override
  212. public Map<String, String> getUserMacros() {
  213. return userMacros;
  214. }
  215. @Override
  216. public List<String> getUndefinedMacros() {
  217. return undefinedMacros;
  218. }
  219. @Override
  220. public Map<String, String> getSystemMacros() {
  221. return systemMacros;
  222. }
  223. @Override
  224. public ItemProperties.LanguageKind getLanguageKind() {
  225. return language;
  226. }
  227. @Override
  228. public LanguageStandard getLanguageStandard() {
  229. return standard;
  230. }
  231. @Override
  232. public String getCompilerName() {
  233. return compilerName;
  234. }
  235. private String fixFileName(String fileName) {
  236. if (fileName == null){
  237. return fileName;
  238. }
  239. if (normilizeProvider.isWindows()) {
  240. //replace /cygdrive/<something> prefix with <something>:/ prefix:
  241. if (DwarfSource.LOG.isLoggable(Level.FINE)) {
  242. DwarfSource.LOG.log(Level.FINE, "Try to fix win name:{0}", fileName); // NOI18N
  243. }
  244. if (fileName.startsWith(CYG_DRIVE_UNIX)) {
  245. fileName = fileName.substring(CYG_DRIVE_UNIX.length()); // NOI18N
  246. fileName = "" + Character.toUpperCase(fileName.charAt(0)) + ':' + fileName.substring(1); // NOI18N
  247. fileName = fileName.replace('\\', '/');
  248. if (cygwinPath == null) {
  249. cygwinPath = "" + Character.toUpperCase(fileName.charAt(0)) + CYGWIN_PATH;
  250. if (DwarfSource.LOG.isLoggable(Level.FINE)) {
  251. DwarfSource.LOG.log(Level.FINE, "Set cygwinPath:{0}", cygwinPath); // NOI18N
  252. }
  253. }
  254. } else {
  255. int i = fileName.indexOf(CYG_DRIVE_WIN);
  256. if (i > 0) {
  257. //replace D:\cygdrive\c\<something> prefix with <something>:\ prefix:
  258. if (cygwinPath == null) {
  259. cygwinPath = "" + Character.toUpperCase(fileName.charAt(0)) + CYGWIN_PATH; // NOI18N
  260. if (DwarfSource.LOG.isLoggable(Level.FINE)) {
  261. DwarfSource.LOG.log(Level.FINE, "Set cygwinPath:{0}", cygwinPath); // NOI18N
  262. }
  263. }
  264. fileName = fileName.substring(i+CYG_DRIVE_UNIX.length());
  265. fileName = "" + Character.toUpperCase(fileName.charAt(0)) + ':' + fileName.substring(1); // NOI18N
  266. fileName = fileName.replace('\\', '/');
  267. }
  268. }
  269. if (DwarfSource.LOG.isLoggable(Level.FINE)) {
  270. DwarfSource.LOG.log(Level.FINE, "\t{0}", fileName); // NOI18N
  271. }
  272. } else if (CUT_LOCALHOST_NET_ADRESS && Utilities.isUnix()) {
  273. if (fileName.startsWith("/net/")){ // NOI18N
  274. try {
  275. InetAddress addr = InetAddress.getLocalHost();
  276. String host = addr.getHostName();
  277. if (host != null && host.length()>0) {
  278. String u = "/net/"+host+"/"; // NOI18N
  279. if (fileName.startsWith(u)){
  280. fileName = fileName.substring(u.length()-1);
  281. }
  282. }
  283. } catch (UnknownHostException ex) {
  284. }
  285. }
  286. }
  287. return fileName;
  288. }
  289. private String linkSupport(String name){
  290. if (normilizeProvider.isWindows()) {
  291. if (!new File(name).exists()){
  292. String link = name+".lnk"; // NOI18N
  293. if (new File(link).exists()){
  294. String resolve = LinkSupport.getOriginalFile(link);
  295. if (resolve != null){
  296. name = resolve;
  297. }
  298. } else {
  299. StringTokenizer st = new StringTokenizer(name,"\\/"); // NOI18N
  300. StringBuilder buf = new StringBuilder();
  301. while(st.hasMoreTokens()){
  302. String token = st.nextToken();
  303. if (buf.length()>0){
  304. buf.append('\\');
  305. }
  306. buf.append(token);
  307. if (token.length()>0 && token.charAt(token.length()-1) != ':'){
  308. String path = buf.toString();
  309. if (!new File(path).exists()){
  310. link = path+".lnk"; // NOI18N
  311. if (new File(link).exists()){
  312. String resolve = LinkSupport.getOriginalFile(link);
  313. if (resolve != null){
  314. buf = new StringBuilder(resolve);
  315. } else {
  316. return name;
  317. }
  318. } else {
  319. return name;
  320. }
  321. }
  322. }
  323. }
  324. name = buf.toString();
  325. }
  326. }
  327. }
  328. return name;
  329. }
  330. static String extractCompilerName(CompilationUnitInterface cui, ItemProperties.LanguageKind lang) throws IOException {
  331. String compilerName = null;
  332. if (cui instanceof CompilationUnit) {
  333. CompilationUnit cu = (CompilationUnit) cui;
  334. if (cu.getCompileOptions() == null) {
  335. compilerName = cu.getProducer();
  336. } else {
  337. String compileOptions = cu.getCompileOptions();
  338. int startIndex = compileOptions.indexOf("R="); // NOI18N
  339. if (startIndex >=0 ) {
  340. int endIndex = compileOptions.indexOf(";", startIndex); // NOI18N
  341. if (endIndex >= 0) {
  342. compilerName = PathCache.getString(compileOptions.substring(startIndex+2, endIndex));
  343. }
  344. }
  345. if (compilerName == null) {
  346. if (lang == ItemProperties.LanguageKind.CPP) {
  347. compilerName = PathCache.getString("CC"); // NOI18N
  348. } else if (lang == ItemProperties.LanguageKind.C) {
  349. compilerName = PathCache.getString("cc"); // NOI18N
  350. } else if (lang == ItemProperties.LanguageKind.Fortran) {
  351. compilerName = PathCache.getString("fortran"); // NOI18N
  352. } else {
  353. compilerName = PathCache.getString("unknown"); // NOI18N
  354. }
  355. }
  356. }
  357. }
  358. return compilerName;
  359. }
  360. static boolean isSunStudioCompiler(CompilationUnitInterface cu) throws IOException {
  361. if (cu instanceof CompilationUnit) {
  362. return ((CompilationUnit)cu).getCompileOptions() != null;
  363. } else {
  364. return cu.getCommandLine() != null && !cu.getCommandLine().isEmpty();
  365. }
  366. }
  367. private void initSourceSettings(CompilationUnitInterface cu, ItemProperties.LanguageKind lang) throws IOException{
  368. userIncludes = new ArrayList<String>();
  369. userMacros = new HashMap<String,String>();
  370. undefinedMacros = new ArrayList<String>();
  371. includedFiles = new HashSet<String>();
  372. countFileName(cu);
  373. compilerName = PathCache.getString(extractCompilerName(cu, lang));
  374. compilePath = PathCache.getString(fixFileName(cu.getCompilationDir()));
  375. sourceName = PathCache.getString(cu.getSourceFileName());
  376. if (compilePath == null && sourceName.lastIndexOf('/')>0) {
  377. int i = sourceName.lastIndexOf('/');
  378. compilePath = sourceName.substring(0,i);
  379. sourceName = sourceName.substring(i+1);
  380. } else {
  381. if (sourceName.startsWith("/")) { // NOI18N
  382. sourceName = DiscoveryUtils.getRelativePath(compilePath, sourceName);
  383. }
  384. if (compilePath == null) {
  385. if (fullName != null && fullName.lastIndexOf('/')>0) {
  386. int i = fullName.lastIndexOf('/');
  387. compilePath = fullName.substring(0,i);
  388. } else {
  389. compilePath = ""; // NOI18N
  390. }
  391. }
  392. }
  393. }
  394. public void process(CompilationUnitInterface cu) throws IOException{
  395. String line = cu.getCommandLine();
  396. if (line != null && line.length()>0){
  397. if (storage != null) {
  398. handler = storage.putCompileLine(line);
  399. }
  400. gatherLine(line);
  401. if (cu instanceof CompilationUnit) {
  402. gatherIncludedFiles((CompilationUnit)cu);
  403. }
  404. } else {
  405. if (cu instanceof CompilationUnit) {
  406. gatherMacros((CompilationUnit)cu);
  407. gatherIncludes((CompilationUnit)cu);
  408. }
  409. }
  410. }
  411. private void addUserIncludePath(String path){
  412. if (!userIncludes.contains(path)) {
  413. userIncludes.add(path);
  414. }
  415. }
  416. private void gatherLine(String line) {
  417. // /set/c++/bin/5.9/intel-S2/prod/bin/CC -c -g -DHELLO=75 -Idist main.cc -Qoption ccfe -prefix -Qoption ccfe .XAKABILBpivFlIc.
  418. if (DwarfSource.LOG.isLoggable(Level.FINE)) {
  419. DwarfSource.LOG.log(Level.FINE, "Process command line {0}", line); // NOI18N
  420. }
  421. List<String> aUserIncludes = new ArrayList<String>();
  422. Map<String, String> aUserMacros = new HashMap<String, String>();
  423. List<String> languageArtifacts = new ArrayList<String>();
  424. List<String> aUndefinedMacros = new ArrayList<String>();
  425. DiscoveryUtils.gatherCompilerLine(line, DiscoveryUtils.LogOrigin.DwarfCompileLine, aUserIncludes, aUserMacros, aUndefinedMacros,
  426. null, languageArtifacts, compilerSettings.getProjectBridge(), this.language == LanguageKind.CPP);
  427. for(String s : aUserIncludes) {
  428. String include = PathCache.getString(s);
  429. addUserIncludePath(include);
  430. }
  431. for(String s : aUndefinedMacros) {
  432. undefinedMacros.add(PathCache.getString(s));
  433. }
  434. for(Map.Entry<String, String> entry : aUserMacros.entrySet()) {
  435. userMacros.put(PathCache.getString(entry.getKey()), entry.getValue());
  436. }
  437. }
  438. private String fixCygwinPath(String path){
  439. if (cygwinPath != null) {
  440. if (path.startsWith("/usr/lib/")){// NOI18N
  441. path = cygwinPath+path.substring(4);
  442. } else if (path.startsWith("/usr")) { // NOI18N
  443. path = cygwinPath+path;
  444. }
  445. }
  446. if (path.startsWith(CYG_DRIVE_UNIX)){
  447. path = fixFileName(path);
  448. }
  449. if (normilizeProvider.isWindows()) {
  450. path = path.replace('\\', '/');
  451. }
  452. return path;
  453. }
  454. private boolean isSystemPath(String path){
  455. path = fixCygwinPath(path);
  456. path = normalizePath(path);
  457. if (path.startsWith("/") || // NOI18N
  458. path.length()>2 && path.charAt(1)==':'){
  459. HashSet<String> bits = new HashSet<String>();
  460. for (String cp : systemIncludes){
  461. if (path.equals(cp)) {
  462. return true;
  463. }
  464. for(String sub : grepSystemFolder(cp).includes){
  465. bits.add(sub);
  466. }
  467. }
  468. for (String cp : systemIncludes){
  469. for(String sub : bits) {
  470. if (path.startsWith(cp)) {
  471. if (path.substring(cp.length()).startsWith(sub)){
  472. return true;
  473. }
  474. }
  475. }
  476. }
  477. //if (path.startsWith("/usr")) {
  478. // System.err.println("Detectes as user include"+path);
  479. //}
  480. }
  481. return false;
  482. }
  483. private void addpath(String path){
  484. if (haveSystemIncludes) {
  485. if (!isSystemPath(path)){
  486. path = fixCygwinPath(path);
  487. path = normalizePath(path);
  488. addUserIncludePath(PathCache.getString(path));
  489. if (DwarfSource.LOG.isLoggable(Level.FINE)) {
  490. DwarfSource.LOG.log(Level.FINE, "\tuser:{0}", path); // NOI18N
  491. }
  492. }
  493. } else {
  494. if (path.startsWith("/usr")) { // NOI18N
  495. path = fixCygwinPath(path);
  496. path = normalizePath(path);
  497. path = PathCache.getString(path);
  498. if (!systemIncludes.contains(path)) {
  499. systemIncludes.add(path);
  500. }
  501. if (DwarfSource.LOG.isLoggable(Level.FINE)) {
  502. DwarfSource.LOG.log(Level.FINE, "\tsystem:{0}", path); // NOI18N
  503. }
  504. } else {
  505. path = fixCygwinPath(path);
  506. path = normalizePath(path);
  507. addUserIncludePath(PathCache.getString(path));
  508. if (DwarfSource.LOG.isLoggable(Level.FINE)) {
  509. DwarfSource.LOG.log(Level.FINE, "\tuser:{0}", path); // NOI18N
  510. }
  511. }
  512. }
  513. }
  514. private String normalizePath(String path){
  515. if (path.startsWith("/") || // NOI18N
  516. path.length()>2 && path.charAt(1)==':') {
  517. return normilizeProvider.getNormalizedPath(path);
  518. }
  519. return path;
  520. }
  521. private void gatherIncludes(final CompilationUnit cu) throws IOException {
  522. if (!ourGatherIncludes) {
  523. return;
  524. }
  525. DwarfStatementList dwarfTable = cu.getStatementList();
  526. if (dwarfTable == null) {
  527. if (DwarfSource.LOG.isLoggable(Level.FINE)) {
  528. DwarfSource.LOG.log(Level.FINE, "Include paths not found"); // NOI18N
  529. }
  530. return;
  531. }
  532. for (Iterator<String> it = dwarfTable.getIncludeDirectories().iterator(); it.hasNext();) {
  533. addpath(it.next());
  534. }
  535. List<String> list = grepSourceFile(fullName).includes;
  536. for(String path : list){
  537. cutFolderPrefix(path, dwarfTable);
  538. }
  539. List<String> dwarfIncludedFiles = dwarfTable.getFilePaths();
  540. DwarfMacinfoTable dwarfMacroTable = cu.getMacrosTable();
  541. if (dwarfMacroTable != null) {
  542. List<Integer> commandLineIncludedFiles = dwarfMacroTable.getCommandLineIncludedFiles();
  543. for(int i : commandLineIncludedFiles) {
  544. String includedSource = processPath(dwarfTable.getFilePath(i));
  545. if (!fullName.replace('\\', '/').equals(includedSource)) {
  546. processPath(dwarfTable.getFilePath(i), list, dwarfTable, false);
  547. }
  548. }
  549. }
  550. for(String path : dwarfIncludedFiles){
  551. processPath(path, list, dwarfTable, true);
  552. }
  553. if (DwarfSource.LOG.isLoggable(Level.FINE)) {
  554. DwarfSource.LOG.log(Level.FINE, "Include paths:{0}", userIncludes); // NOI18N
  555. }
  556. }
  557. private void processPath(String path, List<String> list, DwarfStatementList dwarfTable, boolean isPath) {
  558. String includeFullName = processPath(path);
  559. if (isPath) {
  560. int i = includeFullName.lastIndexOf('/'); // NOI18N
  561. if (i > 0) {
  562. String userPath = includeFullName.substring(0, i);
  563. if (!isSystemPath(userPath)) {
  564. list = grepSourceFile(includeFullName).includes;
  565. for (String included : list) {
  566. cutFolderPrefix(included, dwarfTable);
  567. }
  568. addpath(userPath);
  569. }
  570. }
  571. } else {
  572. addpath(includeFullName);
  573. }
  574. includedFiles.add(PathCache.getString(includeFullName));
  575. if (DwarfSource.LOG.isLoggable(Level.FINE)) {
  576. DwarfSource.LOG.log(Level.FINE, "Included file:{0}", includeFullName); // NOI18N
  577. }
  578. }
  579. private String processPath(String path) {
  580. path = path.replace('\\', '/'); // NOI18N
  581. if (DwarfSource.LOG.isLoggable(Level.FINE)) {
  582. DwarfSource.LOG.log(Level.FINE, "Included file original:{0}", path); // NOI18N
  583. }
  584. String includeFullName;
  585. if (path.startsWith("./")) { // NOI18N
  586. includeFullName = compilePath + path.substring(1);
  587. } else if (path.startsWith("../")) { // NOI18N
  588. includeFullName = compilePath + File.separator + path;
  589. } else if (!(path.startsWith("/") || path.length()>2 && path.charAt(1)==':')) { // NOI18N
  590. includeFullName = compilePath + File.separator + path;
  591. } else {
  592. includeFullName = fixCygwinPath(path);
  593. }
  594. if (normilizeProvider.isWindows()) {
  595. includeFullName = includeFullName.replace('\\', '/'); // NOI18N
  596. }
  597. includeFullName = normalizePath(includeFullName);
  598. return includeFullName;
  599. }
  600. private void cutFolderPrefix(String path, final DwarfStatementList dwarfTable) {
  601. if (normilizeProvider.isWindows()) {
  602. path = path.replace('\\', '/'); // NOI18N
  603. }
  604. if (path.indexOf('/')>0){ // NOI18N
  605. int n = path.lastIndexOf('/'); // NOI18N
  606. String name = path.substring(n+1);
  607. String relativeDir = path.substring(0,n);
  608. String dir = "/"+relativeDir; // NOI18N
  609. List<String> paths = dwarfTable.getPathsForFile(name);
  610. if (DwarfSource.LOG.isLoggable(Level.FINE)) {
  611. DwarfSource.LOG.log(Level.FINE, "Try to find new include paths for:{0} in folder {1}", new Object[]{name, dir}); // NOI18N
  612. }
  613. for(String dwarfPath : paths){
  614. if (DwarfSource.LOG.isLoggable(Level.FINE)) {
  615. DwarfSource.LOG.log(Level.FINE, " candidate:{0}", dwarfPath); // NOI18N
  616. }
  617. if (dwarfPath.endsWith(dir)){
  618. String found = dwarfPath.substring(0,dwarfPath.length()-dir.length());
  619. found = fixCygwinPath(found);
  620. found = normalizePath(found);
  621. if (!userIncludes.contains(found)) {
  622. if (haveSystemIncludes) {
  623. boolean system = false;
  624. if (found.startsWith("/") || // NOI18N
  625. found.length()>2 && found.charAt(1)==':'){
  626. system = systemIncludes.contains(found);
  627. }
  628. if (!system){
  629. if (DwarfSource.LOG.isLoggable(Level.FINE)) {
  630. DwarfSource.LOG.log(Level.FINE, " Find new include path:{0}", found); // NOI18N
  631. }
  632. addUserIncludePath(PathCache.getString(found));
  633. }
  634. } else {
  635. if (!dwarfPath.startsWith("/usr")){ // NOI18N
  636. if (DwarfSource.LOG.isLoggable(Level.FINE)) {
  637. DwarfSource.LOG.log(Level.FINE, " Find new include path:{0}", found); // NOI18N
  638. }
  639. addUserIncludePath(PathCache.getString(found));
  640. }
  641. }
  642. }
  643. break;
  644. } else if (dwarfPath.equals(relativeDir)){
  645. String found = "."; // NOI18N
  646. if (!userIncludes.contains(found)) {
  647. if (DwarfSource.LOG.isLoggable(Level.FINE)) {
  648. DwarfSource.LOG.log(Level.FINE, " Find new include path:{0}", found); // NOI18N
  649. }
  650. addUserIncludePath(PathCache.getString(found));
  651. }
  652. break;
  653. }
  654. }
  655. }
  656. }
  657. private void gatherIncludedFiles(final CompilationUnit cu) throws IOException {
  658. if (!ourGatherIncludes) {
  659. return;
  660. }
  661. DwarfStatementList dwarfTable = cu.getStatementList();
  662. if (dwarfTable == null) {
  663. return;
  664. }
  665. for(String path :dwarfTable.getFilePaths()){
  666. String includeFullName = path;
  667. if (path.startsWith("./")) { // NOI18N
  668. includeFullName = compilePath+path.substring(1);
  669. } else if (path.startsWith("../")) { // NOI18N
  670. includeFullName = compilePath+File.separator+path;
  671. }
  672. includeFullName = normalizePath(includeFullName);
  673. includedFiles.add(PathCache.getString(includeFullName));
  674. }
  675. }
  676. private void gatherMacros(final CompilationUnit cu) throws IOException {
  677. if (!ourGatherMacros){
  678. return;
  679. }
  680. DwarfMacinfoTable dwarfTable = cu.getMacrosTable();
  681. if (dwarfTable == null) {
  682. if (DwarfSource.LOG.isLoggable(Level.FINE)) {
  683. DwarfSource.LOG.log(Level.FINE, "Macros not found"); // NOI18N
  684. }
  685. return;
  686. }
  687. int firstMacroLine = grepSourceFile(fullName).firstMacroLine;
  688. List<DwarfMacinfoEntry> table = dwarfTable.getCommandLineMarcos();
  689. for (Iterator<DwarfMacinfoEntry> it = table.iterator(); it.hasNext();) {
  690. DwarfMacinfoEntry entry = it.next();
  691. String def = entry.definition;
  692. int i = def.indexOf(' ');
  693. String macro;
  694. String value = null;
  695. if (i>0){
  696. macro = PathCache.getString(def.substring(0,i));
  697. value = PathCache.getString(def.substring(i+1).trim());
  698. } else {
  699. macro = PathCache.getString(def);
  700. }
  701. if (firstMacroLine == entry.lineNum) {
  702. if (macro.equals(grepSourceFile(fullName).firstMacro)){
  703. break;
  704. }
  705. }
  706. if (haveSystemMacros && systemMacros.containsKey(macro)){
  707. String sysValue = systemMacros.get(macro);
  708. if (equalValues(sysValue, value)) {
  709. continue;
  710. }
  711. }
  712. userMacros.put(macro,value);
  713. }
  714. if (DwarfSource.LOG.isLoggable(Level.FINE)) {
  715. DwarfSource.LOG.log(Level.FINE, "Macros:{0}", userMacros); // NOI18N
  716. }
  717. }
  718. private boolean equalValues(String sysValue, String value) {
  719. // filter out system macros
  720. // For example gcc windows dwarf contains following system macros as user:
  721. // unix=1 __unix=1 __unix__=1 __CYGWIN__=1 __CYGWIN32__=1
  722. if (value == null || "1".equals(value)) { // NOI18N
  723. return sysValue == null || "1".equals(sysValue); // NOI18N
  724. }
  725. return value.equals(sysValue); // NOI18N
  726. }
  727. private GrepEntry grepSystemFolder(String path) {
  728. GrepEntry res = grepBase.get(path);
  729. if (res != null) {
  730. return res;
  731. }
  732. res = new GrepEntry();
  733. File folder = new File(path);
  734. if (folder.exists() && folder.canRead() && folder.isDirectory()) {
  735. File[] ff = folder.listFiles();
  736. if (ff != null) {
  737. for(File f: ff){
  738. if (f.exists() && f.canRead() && !f.isDirectory()){
  739. List<String> l = grepSourceFile(f.getAbsolutePath()).includes;
  740. for (String i : l){
  741. if (i.indexOf("..")>0 || i.startsWith("/") || i.indexOf(":")>0) { // NOI18N
  742. continue;
  743. }
  744. if (i.indexOf('/')>0){ // NOI18N
  745. int n = i.lastIndexOf('/'); // NOI18N
  746. String relativeDir = i.substring(0,n);
  747. String dir = "/"+relativeDir; // NOI18N
  748. if (!res.includes.contains(dir)){
  749. res.includes.add(PathCache.getString(dir));
  750. }
  751. }
  752. }
  753. }
  754. }
  755. }
  756. }
  757. List<String> secondLevel = new ArrayList<String>();
  758. for(String sub : res.includes) {
  759. File subFolder = new File(path+sub);
  760. try {
  761. if (subFolder.getCanonicalFile().getAbsolutePath().startsWith(path + sub)) {
  762. for (String s : grepSystemFolder(path + sub).includes) {
  763. secondLevel.add(s);
  764. }
  765. }
  766. } catch (IOException ex) {
  767. Exceptions.printStackTrace(ex);
  768. }
  769. }
  770. for(String s: secondLevel){
  771. if (!res.includes.contains(s)){
  772. res.includes.add(PathCache.getString(s));
  773. }
  774. }
  775. grepBase.put(PathCache.getString(path), res);
  776. return res;
  777. }
  778. private GrepEntry grepSourceFile(String fileName){
  779. GrepEntry res = grepBase.get(fileName);
  780. if (res != null) {
  781. return res;
  782. }
  783. res = new GrepEntry();
  784. File file = new File(fileName);
  785. if (file.exists() && file.canRead() && !file.isDirectory()){
  786. try {
  787. BufferedReader in = new BufferedReader(new FileReader(file));
  788. int lineNo = 0;
  789. int size;
  790. String line;
  791. int first;
  792. fileLoop:while((line = in.readLine()) != null) {
  793. lineNo++;
  794. if ((size = line.length()) == 0) {
  795. continue;
  796. }
  797. firstLoop:for(first = 0; first < size; first++) {
  798. switch (line.charAt(first)) {
  799. case ' ':
  800. case '\t':
  801. break;
  802. case '#':
  803. break firstLoop;
  804. default:
  805. continue fileLoop;
  806. }
  807. }
  808. first++;
  809. if (first >= size) {
  810. continue;
  811. }
  812. secondLoop:for(; first < size; first++) {
  813. switch (line.charAt(first)) {
  814. case ' ':
  815. case '\t':
  816. break;
  817. case 'i':
  818. if (first + 1 < size && line.charAt(first + 1) != 'n') {
  819. // not "include" prefix
  820. continue fileLoop;
  821. }
  822. break secondLoop;
  823. case 'd':
  824. break secondLoop;
  825. default:
  826. continue fileLoop;
  827. }
  828. }
  829. if (first >= size) {
  830. continue;
  831. }
  832. line = line.substring(first);
  833. if (line.startsWith("include")){ // NOI18N
  834. line = line.substring(7).trim();
  835. if (line.length()>2) {
  836. if (line.startsWith("/*")) { // NOI18N
  837. int i = line.indexOf("*/"); // NOI18N
  838. if (i > 0) {
  839. line = line.substring(i+2).trim();
  840. }
  841. }
  842. char c = line.charAt(0);
  843. if (c == '"') {
  844. if (line.indexOf('"',1)>0){
  845. res.includes.add(PathCache.getString(line.substring(1,line.indexOf('"',1))));
  846. if (DwarfSource.LOG.isLoggable(Level.FINE)) {
  847. DwarfSource.LOG.log(Level.FINE, "find in source:{0}", line.substring(1,line.indexOf('"',1))); // NOI18N
  848. }
  849. }
  850. } else if (c == '<'){
  851. if (line.indexOf('>')>0){
  852. res.includes.add(PathCache.getString(line.substring(1,line.indexOf('>'))));
  853. if (DwarfSource.LOG.isLoggable(Level.FINE)) {
  854. DwarfSource.LOG.log(Level.FINE, "find in source:{0}", line.substring(1,line.indexOf('>'))); // NOI18N
  855. }
  856. }
  857. }
  858. }
  859. } else if (line.startsWith("define")){ // NOI18N
  860. if (res.firstMacroLine == -1) {
  861. line = line.substring(6).trim();
  862. if (line.length()>0) {
  863. if (line.startsWith("/*")) { // NOI18N
  864. int i = line.indexOf("*/"); // NOI18N
  865. if (i > 0) {
  866. line = line.substring(i+2).trim();
  867. }
  868. }
  869. StringTokenizer st = new StringTokenizer(line,"\t ("); // NOI18N
  870. while(st.hasMoreTokens()) {
  871. res.firstMacroLine = lineNo;
  872. res.firstMacro = PathCache.getString(st.nextToken());
  873. break;
  874. }
  875. }
  876. }
  877. }
  878. }
  879. in.close();
  880. } catch (IOException ex) {
  881. DwarfSource.LOG.log(Level.INFO, "Cannot grep file: "+fileName, ex); // NOI18N
  882. }
  883. } else {
  884. if (DwarfSource.LOG.isLoggable(Level.FINE)) {
  885. DwarfSource.LOG.log(Level.FINE, "Cannot grep file:{0}", fileName); // NOI18N
  886. }
  887. }
  888. res.includes.trimToSize();
  889. grepBase.put(fileName,res);
  890. return res;
  891. }
  892. }