1 /* 2 * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.incubator.code.tools.renderer; 27 28 import java.io.*; 29 import java.util.ArrayList; 30 import java.util.List; 31 32 /** 33 * Created by gfrost 34 */ 35 public final class Diff { 36 private Diff() { 37 } 38 39 public static void annotate(File file, int line, int col, String msg) { 40 List<String> lines = getLines(file); 41 for (int i = Math.max(line - 2, 0); i < (line - 1); i++) { 42 System.out.printf(" %2d:%s\n", i + 1, lines.get(i)); 43 } 44 String text = lines.get(line - 1); 45 System.out.printf(" -> %2d:%s\n ", line, text); 46 for (int i = 0; i < col; i++) { 47 System.out.print(" "); 48 } 49 System.out.println("^ " + msg); 50 for (int i = line; i < Math.min(line + 2, lines.size() - 1); i++) { 51 System.out.printf(" %2d:%s\n", i + 1, lines.get(i)); 52 } 53 54 } 55 56 static List<String> getLines(File file) { 57 List<String> lines = new ArrayList<>(); 58 try { 59 BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file))); 60 for (String line = br.readLine(); line != null; line = br.readLine()) { 61 lines.add(line); 62 } 63 br.close(); 64 } catch (FileNotFoundException e) { 65 e.printStackTrace(); 66 } catch (IOException e) { 67 e.printStackTrace(); 68 } 69 return lines; 70 } 71 72 public static class DiffResult { 73 String lhs; 74 String rhs; 75 public String result; 76 public int exitStatus; 77 78 public DiffResult(String lhs, String rhs, String result, int exitStatus) { 79 this.lhs = lhs; 80 this.rhs = rhs; 81 this.result = result; 82 this.exitStatus = exitStatus; 83 } 84 } 85 86 public static DiffResult diff(String lhs, String rhs, int width) { 87 try { 88 File lhsFile = File.createTempFile("lhs", "txt"); 89 FileWriter lhsw = new FileWriter(lhsFile); 90 lhsw.append(lhs); 91 lhsw.close(); 92 File rhsFile = File.createTempFile("rhs", "txt"); 93 FileWriter rhsw = new FileWriter(rhsFile); 94 rhsw.append(rhs); 95 rhsw.close(); 96 97 List<String> command = new ArrayList<>(); 98 command.add("sdiff"); 99 command.add("--expand-tabs"); 100 command.add("--ignore-all-space"); 101 command.add("--width=" + width); 102 command.add("--ignore-blank-lines"); 103 command.add(lhsFile.getAbsolutePath()); 104 command.add(rhsFile.getAbsolutePath()); 105 106 ProcessBuilder builder = new ProcessBuilder(command); 107 final Process process = builder.start(); 108 BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream())); 109 StringBuilder out = new StringBuilder(); 110 String line; 111 while ((line = br.readLine()) != null) { 112 if (line.contains("|")) { 113 out.append(TerminalColors.Color.RED.colorize(line)).append("\n"); 114 } else { 115 out.append(TerminalColors.Color.GREEN.colorize(line)).append("\n"); 116 } 117 118 } 119 process.waitFor(); 120 br.close(); 121 lhsFile.delete(); 122 rhsFile.delete(); 123 return new DiffResult(lhs, rhs, out.toString(), process.exitValue()); 124 } catch (IOException | InterruptedException ioe) { 125 ioe.printStackTrace(); 126 } 127 return null; 128 } 129 130 131 public static File write(File file, String text) { 132 try { 133 PrintWriter pw = new PrintWriter(file); 134 pw.append(text); 135 pw.append("\n"); 136 pw.close(); 137 } catch (IOException e) { 138 e.printStackTrace(); 139 } 140 return file; 141 } 142 143 144 }