1 4 package gnu.bytecode; 5 6 10 11 public class SourceDebugExtAttr extends Attribute 12 { 13 byte[] data; 14 int dlength; 15 16 private String outputFileName; 17 private String defaultStratumId; 18 19 21 int fileCount; 22 26 int[] fileIDs; 27 30 String [] fileNames; 31 32 int lineCount; 33 34 int[] lines; 35 36 int curLineIndex = -1; 38 int curFileIndex = -1; 39 int maxFileID; 40 String curFileName; 41 42 private int fixLine (int sourceLine, int index) 43 { 44 int sourceMin = lines[index]; 45 int repeat = lines[index+2]; 46 if (sourceLine < sourceMin) 47 { 48 if (index > 0) 49 return -1; 50 int sourceMax = sourceMin + repeat - 1; 51 lines[index] = sourceLine; 52 lines[index+2] = sourceMax - sourceLine + 1; 53 lines[index+3] = sourceLine; 54 sourceMin = sourceLine; 55 } 56 int delta = lines[index+3] - sourceMin; 57 if (sourceLine < sourceMin + repeat) 58 return sourceLine + delta; 59 else if (index == 5 * (lineCount - 1) 60 || (index == 0 && sourceLine < lines[5+3])) 61 { lines[index+2] = sourceLine - sourceMin + 1; return sourceLine + delta; 64 } 65 return -1; 66 } 67 68 int fixLine (int sourceLine) 69 { 70 int outLine; 71 if (curLineIndex >= 0) 72 { 73 outLine = fixLine(sourceLine, curLineIndex); 74 if (outLine >= 0) 75 return outLine; 76 } 77 int i5 = 0; 78 int findex = curFileIndex; 79 for (int i = 0; i < lineCount; i++) 80 { 81 if (i5 != curLineIndex && findex == lines[i5+1]) 82 { 83 outLine = fixLine(sourceLine, i5); 84 if (outLine >= 0) 85 { 86 curLineIndex = i5; 87 return outLine; 88 } 89 } 90 i5 += 5; 91 } 92 if (lines == null) 93 lines = new int[20]; 94 else if (i5 >= lines.length) 95 { 96 int[] newLines = new int[2 * i5]; 97 System.arraycopy(lines, 0, newLines, 0, i5); 98 lines = newLines; 99 } 100 int outputStartLine; 101 int inputStartLine = sourceLine; 102 if (i5 == 0) 103 outputStartLine = sourceLine; 104 else 105 { 106 outputStartLine = lines[i5-5+3] + lines[i5-5+2]; 107 if (i5 == 5 && outputStartLine < 10000) 108 { 109 outputStartLine = 10000; 112 } 113 sourceLine = outputStartLine; 114 } 115 lines[i5] = inputStartLine; 116 lines[i5+1] = findex; 117 lines[i5+2] = 1; 118 lines[i5+3] = outputStartLine; 119 lines[i5+4] = 1; 120 curLineIndex = i5; 121 lineCount++; 122 return sourceLine; 123 } 124 125 void addFile (String fname) 126 { 127 if (curFileName == fname || (fname != null && fname.equals(curFileName))) 128 return; 129 curFileName = fname; 130 fname = SourceFileAttr.fixSourceFile(fname); 131 String fentry; 132 int slash = fname.lastIndexOf('/'); 133 if (slash >= 0) 134 { 135 String fpath = fname; 136 fname = fname.substring(slash+1); 137 fentry = fname + '\n' + fpath; 138 } 139 else 140 fentry = fname; 141 142 if (curFileIndex >= 0 && fentry.equals(fileNames[curFileIndex])) 143 return; 144 145 int n = fileCount; 146 for (int i = 0; i < n; i++) 147 { 148 if (i != curFileIndex && fentry.equals(fileNames[i])) 149 { 150 curFileIndex = i; 151 curLineIndex = -1; 152 return; 153 } 154 } 155 156 if (fileIDs == null) 157 { 158 fileIDs = new int[5]; 159 fileNames = new String [5]; 160 } 161 else if (n >= fileIDs.length) 162 { 163 int[] newIDs = new int[2 * n]; 164 String [] newNames = new String [2 * n]; 165 System.arraycopy(fileIDs, 0, newIDs, 0, n); 166 System.arraycopy(fileNames, 0, newNames, 0, n); 167 fileIDs = newIDs; 168 fileNames = newNames; 169 } 170 171 172 fileCount++; 173 int id = ++maxFileID; 174 id = id << 1; 175 if (slash >= 0) 176 id++; 177 fileNames[n] = fentry; 178 if (outputFileName == null) 179 outputFileName = fname; 180 fileIDs[n] = id; 181 curFileIndex = n; 182 curLineIndex = -1; 183 } 184 185 public void addStratum (String name) 186 { 187 defaultStratumId = name; 188 } 189 190 191 public SourceDebugExtAttr (ClassType cl) 192 { 193 super("SourceDebugExtension"); 194 addToFrontOf(cl); 195 } 196 197 void nonAsteriskString(String str, StringBuffer sbuf) 198 { 199 if (str == null || str.length() == 0 || str.charAt(0) == '*') 200 sbuf.append(' '); 201 sbuf.append(str); 202 } 203 204 public void assignConstants (ClassType cl) 205 { 206 super.assignConstants(cl); 207 208 StringBuffer sbuf = new StringBuffer (); 209 sbuf.append("SMAP\n"); 211 nonAsteriskString(outputFileName, sbuf); sbuf.append('\n'); 212 String stratum = defaultStratumId == null ? "Java" : defaultStratumId; 213 nonAsteriskString(stratum, sbuf); 214 sbuf.append('\n'); 215 sbuf.append("*S "); 217 sbuf.append(stratum); 218 sbuf.append('\n'); 219 sbuf.append("*F\n"); 221 for (int i = 0; i < fileCount; i++) 222 { 223 int id = fileIDs[i]; 224 boolean with_path = (id & 1) != 0; 225 id >>= 1; 226 if (with_path) 227 sbuf.append("+ "); 228 sbuf.append(id); sbuf.append(' '); 229 sbuf.append(fileNames[i]); sbuf.append('\n'); 230 } 231 if (lineCount > 0) 233 { 234 int prevFileID = 0; 235 sbuf.append("*L\n"); 236 int i = 0, i5 = 0; 237 do 238 { 239 int inputStartLine = lines[i5]; 240 int lineFileID = fileIDs[lines[i5+1]] >> 1; 241 int repeatCount = lines[i5+2]; 242 int outputStartLine = lines[i5+3]; 243 int outputLineIncrement = lines[i5+4]; 244 sbuf.append(inputStartLine); 245 if (lineFileID != prevFileID) 246 { 247 sbuf.append('#'); 248 sbuf.append(lineFileID); 249 prevFileID = lineFileID; 250 } 251 if (repeatCount != 1) 252 { 253 sbuf.append(','); 254 sbuf.append(repeatCount); 255 } 256 sbuf.append(':'); 257 sbuf.append(outputStartLine); 258 if (outputLineIncrement != 1) 259 { 260 sbuf.append(','); 261 sbuf.append(outputLineIncrement); 262 } 263 sbuf.append('\n'); 264 i5 += 5; 265 } 266 while (++i < lineCount); 267 } 268 sbuf.append("*E\n"); 270 try 271 { 272 data = sbuf.toString().getBytes("UTF-8"); 273 } 274 catch (Exception ex) 275 { 276 throw new RuntimeException (ex.toString()); 277 } 278 dlength = data.length; 279 } 280 281 283 public int getLength() { return dlength; } 284 285 287 public void write (java.io.DataOutputStream dstr) 288 throws java.io.IOException 289 { 290 dstr.write(data, 0, dlength); 291 } 292 293 public void print (ClassTypeWriter dst) 294 { 295 dst.print("Attribute \""); 296 dst.print(getName()); 297 dst.print("\", length:"); 298 dst.println(dlength); 299 try 300 { 301 dst.print(new String (data, 0, dlength, "UTF-8")); 302 } 303 catch (Exception ex) 304 { 305 dst.print("(Caught "); dst.print(ex); dst.println(')'); 306 } 307 if (dlength > 0 && data[dlength-1] != '\r' && data[dlength-1]!= '\n') 308 dst.println(); 309 } 310 } 311 | Popular Tags |