1
2
3
4 package joeq.Util.IO;
5 import java.io.BufferedReader;
6 import java.io.FileReader;
7 import java.io.IOException;
8 import java.io.File;
9 import java.util.Arrays;
10 import java.text.DecimalFormat;
11
12 import joeq.Class.jq_Class;
13 import joeq.Compiler.Analysis.IPA.ProgramLocation;
14
15 /***
16 * SourceLister
17 *
18 * Maintains a set of source directories and lists source code
19 * around a given ProgramLocation.
20 *
21 * @author Godmar Back <gback@cs.utah.edu, @stanford.edu>
22 */
23 public class SourceLister {
24
25
26 public static String []defaultSrcDirs = new String[] { "." };
27 public static int defaultLinesBefore = 5;
28 public static int defaultLinesAfter = 5;
29
30 String []srcDirs;
31
32 /***
33 * Create a new source lister with the default path and before/after lines.
34 */
35 public SourceLister() {
36 this(defaultSrcDirs);
37 }
38
39 /***
40 * Create a new source lister with the specified paths and before/after lines.
41 */
42 public SourceLister(String []srcDirs) {
43 this.srcDirs = srcDirs;
44 }
45
46 /***
47 * Try to find source for this location and return a section of the source file
48 * formatted for display.
49 */
50 public String list(ProgramLocation pl) {
51 return list(pl, true, defaultLinesBefore, defaultLinesAfter);
52 }
53
54 public String list(ProgramLocation pl, String comment) {
55 return list(pl, true, defaultLinesBefore, defaultLinesAfter, comment);
56 }
57
58 public String list(ProgramLocation pl, boolean withnumbers, int linesBefore, int linesAfter) {
59 return list(pl, withnumbers, linesBefore, linesAfter, "");
60 }
61
62 public String list(ProgramLocation pl, boolean withnumbers, int linesBefore, int linesAfter, String comment) {
63 jq_Class clazz = pl.getContainingClass();
64 String clazzName = clazz.getName();
65 char fileSep = File.separatorChar;
66 int lastdot = clazzName.lastIndexOf('.');
67 String pathName = lastdot != -1 ? fileSep + clazzName.substring(0, lastdot) : "";
68 String pathSuffix = pathName.replace('.', fileSep) + fileSep + pl.getSourceFile();
69 DecimalFormat d5 = new DecimalFormat("00000");
70 int lno = pl.getLineNumber();
71
72 outer:
73 for (int i = 0; i < srcDirs.length; i++) {
74 String possibleInputFile = srcDirs[i] + pathSuffix;
75 File f = new File(possibleInputFile);
76 if (f.exists()) {
77 StringBuffer res = new StringBuffer();
78 BufferedReader r = null;
79 try {
80 r = new BufferedReader(new FileReader(possibleInputFile));
81 int l = 1;
82 if (withnumbers)
83 res.append("# " + pl.getSourceFile() + ":" + lno + "\n");
84 for (; l < lno - linesBefore; l++)
85 r.readLine();
86 for (; l < lno + linesAfter + 1; l++) {
87 String s = r.readLine();
88 if (s == null)
89 break;
90
91 if (withnumbers)
92 res.append(d5.format(l) + ": ");
93 res.append(s);
94 if (withnumbers && l == lno)
95 res.append(" <<<==================== " + comment);
96 res.append("\n");
97 }
98 } catch (IOException io) {
99 continue outer;
100 } finally {
101 if (r != null) try { r.close(); } catch (IOException _) { }
102 }
103 return res.toString();
104 }
105 }
106 return null;
107 }
108
109 public String toString() {
110 return getClass() + " " + Arrays.asList(srcDirs);
111 }
112 }