⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 diffprint.java

📁 JSPWiki,100%Java开发的一套完整WIKI程序
💻 JAVA
字号:
package bmsi.util;/* $Log: DiffPrint.java,v $/* Revision 1.2  2003/03/02 13:36:06  jalkanen/* Changed license text to refer to LGPL/*/* Revision 1.1  2002/05/22 19:24:35  jalkanen/* Initial import from BMSI source./* * Revision 1.2  2000/03/02  16:59:54  stuart * add GPL * */import java.io.*;import java.util.Vector;import bmsi.util.Diff;//import com.objectspace.jgl.predicates.UnaryPredicate;interface UnaryPredicate {    boolean execute(Object obj);}/** A simple framework for printing change lists produced by <code>Diff</code>. @see bmsi.util.Diff @author Stuart D. Gathman Copyright (C) 2000 Business Management Systems, Inc. <p> This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. <p> This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details. <p> You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */public class DiffPrint {    /** A Base class for printing edit scripts produced by Diff.     This class divides the change list into "hunks", and calls     <code>print_hunk</code> for each hunk.  Various utility methods     are provided as well.     */    public static abstract class Base {        protected Base(Object[] a, Object[] b) {            outfile = new PrintWriter(new OutputStreamWriter(System.out));            file0 = a;            file1 = b;        }        /** Set to ignore certain kinds of lines when printing         an edit script.  For example, ignoring blank lines or comments.         */        protected UnaryPredicate ignore = null;        /** Set to the lines of the files being compared.         */        protected Object[] file0, file1;        /** Divide SCRIPT into pieces by calling HUNKFUN and         print each piece with PRINTFUN.         Both functions take one arg, an edit script.         PRINTFUN takes a subscript which belongs together (with a null         link at the end) and prints it.  */        public void print_script(Diff.change script) {            Diff.change next = script;            while (next != null) {                Diff.change t, end;                /* Find a set of changes that belong together.  */                t = next;                end = hunkfun(next);                /* Disconnect them from the rest of the changes,                   making them a hunk, and remember the rest for next iteration.  */                next = end.link;                end.link = null;                //if (DEBUG)                //  debug_script(t);                /* Print this hunk.  */                print_hunk(t);                /* Reconnect the script so it will all be freed properly.  */                end.link = next;            }            outfile.flush();        }        /** Called with the tail of the script         and returns the last link that belongs together with the start         of the tail. */        protected Diff.change hunkfun(Diff.change hunk) {            return hunk;        }        protected int first0, last0, first1, last1, deletes, inserts;        protected PrintWriter outfile;        /** Look at a hunk of edit script and report the range of lines in each file         that it applies to.  HUNK is the start of the hunk, which is a chain         of `struct change'.  The first and last line numbers of file 0 are stored         in *FIRST0 and *LAST0, and likewise for file 1 in *FIRST1 and *LAST1.         Note that these are internal line numbers that count from 0.         If no lines from file 0 are deleted, then FIRST0 is LAST0+1.         Also set *DELETES nonzero if any lines of file 0 are deleted         and set *INSERTS nonzero if any lines of file 1 are inserted.         If only ignorable lines are inserted or deleted, both are         set to 0.  */        protected void analyze_hunk(Diff.change hunk) {            int f0, l0 = 0, f1, l1 = 0, show_from = 0, show_to = 0;            int i;            Diff.change next;            boolean nontrivial = (ignore == null);            show_from = show_to = 0;            f0 = hunk.line0;            f1 = hunk.line1;            for (next = hunk; next != null; next = next.link) {                l0 = next.line0 + next.deleted - 1;                l1 = next.line1 + next.inserted - 1;                show_from += next.deleted;                show_to += next.inserted;                for (i = next.line0; i <= l0 && !nontrivial; i++)                    if (!ignore.execute(file0[i]))                        nontrivial = true;                for (i = next.line1; i <= l1 && !nontrivial; i++)                    if (!ignore.execute(file1[i]))                        nontrivial = true;            }            first0 = f0;            last0 = l0;            first1 = f1;            last1 = l1;            /* If all inserted or deleted lines are ignorable,           tell the caller to ignore this hunk.  */            if (!nontrivial)                show_from = show_to = 0;            deletes = show_from;            inserts = show_to;        }        protected abstract void print_hunk(Diff.change hunk);        protected void print_1_line(String pre, Object linbuf) {            outfile.println(pre + linbuf.toString());        }        /** Print a pair of line numbers with SEPCHAR, translated for file FILE.         If the two numbers are identical, print just one number.         Args A and B are internal line numbers.         We print the translated (real) line numbers.  */        protected void print_number_range(char sepchar, int a, int b) {            /* Note: we can have B < A in the case of a range of no lines.           In this case, we should print the line number before the range,           which is B.  */            if (++b > ++a)                outfile.print("" + a + sepchar + b);            else                outfile.print(b);        }        public static char change_letter(int inserts, int deletes) {            if (inserts == 0)                return 'd';            else if (deletes == 0)                return 'a';            else                return 'c';        }    }    /** Print a change list in the standard diff format.     */    public static class NormalPrint extends Base {        public NormalPrint(Object[] a, Object[] b) {            super(a, b);        }        /** Print a hunk of a normal diff.         This is a contiguous portion of a complete edit script,         describing changes in consecutive lines.  */        protected void print_hunk(Diff.change hunk) {            /* Determine range of line numbers involved in each file.  */            analyze_hunk(hunk);            if (deletes == 0 && inserts == 0)                return;            /* Print out the line number header for this hunk */            print_number_range(',', first0, last0);            outfile.print(change_letter(inserts, deletes));            print_number_range(',', first1, last1);            outfile.println();            /* Print the lines that the first file has.  */            if (deletes != 0)                for (int i = first0; i <= last0; i++)                    print_1_line("< ", file0[i]);            if (inserts != 0 && deletes != 0)                outfile.println("---");            /* Print the lines that the second file has.  */            if (inserts != 0)                for (int i = first1; i <= last1; i++)                    print_1_line("> ", file1[i]);        }    }    /** Prints an edit script in a format suitable for input to <code>ed</code>.     The edit script must be generated with the reverse option to     be useful as actual <code>ed</code> input.     */    public static class EdPrint extends Base {        public EdPrint(Object[] a, Object[] b) {            super(a, b);        }        /** Print a hunk of an ed diff */        protected void print_hunk(Diff.change hunk) {            /* Determine range of line numbers involved in each file.  */            analyze_hunk(hunk);            if (deletes == 0 && inserts == 0)                return;            /* Print out the line number header for this hunk */            print_number_range(',', first0, last0);            outfile.println(change_letter(inserts, deletes));            /* Print new/changed lines from second file, if needed */            if (inserts != 0) {                boolean inserting = true;                for (int i = first1; i <= last1; i++) {                    /* Resume the insert, if we stopped.  */                    if (!inserting)                        outfile.println(i - first1 + first0 + "a");                    inserting = true;                    /* If the file's line is just a dot, it would confuse `ed'.                   So output it with a double dot, and set the flag LEADING_DOT                   so that we will output another ed-command later                   to change the double dot into a single dot.  */                    if (".".equals(file1[i])) {                        outfile.println("..");                        outfile.println(".");                        /* Now change that double dot to the desired single dot.  */                        outfile.println(i - first1 + first0 + 1 + "s/^\\.\\././");                        inserting = false;                    } else                    /* Line is not `.', so output it unmodified.  */                        print_1_line("", file1[i]);                }                /* End insert mode, if we are still in it.  */                if (inserting)                    outfile.println(".");            }        }    }    /** Read a text file into an array of String.  This provides basic diff     functionality.  A more advanced diff utility will use specialized     objects to represent the text lines, with options to, for example,     convert sequences of whitespace to a single space for comparison     purposes.     */    public static String[] slurp(String file) throws IOException {        BufferedReader rdr = new BufferedReader(new FileReader(file));        Vector s = new Vector();        for (; ;) {            String line = rdr.readLine();            if (line == null) break;            s.addElement(line);        }        String[] a = new String[s.size()];        s.copyInto(a);        return a;    }    public static void main(String[] argv) throws IOException {        String[] a = slurp(argv[argv.length - 2]);        String[] b = slurp(argv[argv.length - 1]);        Diff d = new Diff(a, b);        boolean edstyle = "-e".equals(argv[0]);        Diff.change script = d.diff_2(edstyle);        if (script == null)            System.err.println("No differences");        else {            Base p;            if (edstyle)                p = new EdPrint(a, b);            else                p = new NormalPrint(a, b);            p.print_script(script);        }    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -