Added shell command: cmp.
[jnode:svn-mirror.git] / cli / src / commands / org / jnode / command / file / CmpCommand.java
1 package org.jnode.command.file;
2
3 import java.io.BufferedInputStream;
4 import java.io.File;
5 import java.io.FileInputStream;
6 import java.io.IOException;
7 import java.io.PrintWriter;
8 import org.jnode.shell.AbstractCommand;
9 import org.jnode.shell.syntax.Argument;
10 import org.jnode.shell.syntax.FileArgument;
11
12 /**
13  * Compare two files and report the first difference.
14  *
15  * @author Levente S\u00e1ntha
16  */
17 public class CmpCommand extends AbstractCommand {
18
19     private static final int BUFFER_SIZE = 64 * 1024;
20
21     private static final String HELP_SUPER = "Compare two files";
22     private static final String HELP_FILE = "a file to compare";
23     private static final String ERR_FILE_INVALID = "%s is not a file%n";
24     private static final String MSG_DIFFER = "%s %s differ: byte %d, line %d%n";
25     private static final String MSG_EOF = "cmp: EOF on %s%n";
26
27     private final FileArgument file1Arg;
28     private final FileArgument file2Arg;
29
30     public CmpCommand() {
31         super(HELP_SUPER);
32
33         file1Arg = new FileArgument("file1", Argument.MANDATORY | Argument.EXISTING, HELP_FILE);
34         file2Arg = new FileArgument("file2", Argument.MANDATORY | Argument.EXISTING, HELP_FILE);
35
36         registerArguments(file1Arg, file2Arg);
37     }
38
39     public static void main(String[] args) throws Exception {
40         new CmpCommand().execute(args);
41     }
42
43     @Override
44     public void execute() throws IOException {
45
46         File file1 = file1Arg.getValue();
47         File file2 = file2Arg.getValue();
48
49         PrintWriter err = getError().getPrintWriter();
50
51         if (!file1.isFile()) {
52             err.format(ERR_FILE_INVALID, file1);
53             exit(1);
54         }
55
56         if (!file2.isFile()) {
57             err.format(ERR_FILE_INVALID, file2);
58             exit(1);
59         }
60
61         BufferedInputStream bis1 = null;
62         BufferedInputStream bis2 = null;
63
64         try {
65             bis1 = new BufferedInputStream(new FileInputStream(file1), BUFFER_SIZE);
66             bis2 = new BufferedInputStream(new FileInputStream(file2), BUFFER_SIZE);
67
68             long bc = 1;
69             long lc = 1;
70
71             while (true) {
72                 int b1 = bis1.read();
73                 int b2 = bis2.read();
74
75                 if (b1 == -1 && b2 == -1)
76                     //done
77                     break;
78
79                 if (b1 == -1) {
80                     PrintWriter out = getOutput().getPrintWriter();
81                     out.format(MSG_EOF, file1.toString());
82                     exit(1);
83                     return;
84                 }
85
86                 if (b2 == -1) {
87                     PrintWriter out = getOutput().getPrintWriter();
88                     out.format(MSG_EOF, file2.toString());
89                     exit(1);
90                     return;
91                 }
92
93                 if (b1 != b2) {
94                     PrintWriter out = getOutput().getPrintWriter();
95                     out.format(MSG_DIFFER, file1.toString(), file2.toString(), bc, lc);
96                     exit(1);
97                     return;
98                 }
99
100                 bc++;
101
102                 if (b1 == (byte) '\n')
103                     lc++;
104             }
105         } finally {
106             if (bis1 != null) {
107                 try {
108                     bis1.close();
109                 } catch (IOException x) {
110                     //ignore
111                 }
112             }
113
114             if (bis2 != null) {
115                 try {
116                     bis2.close();
117                 } catch (IOException x) {
118                     //ignore
119                 }
120             }
121         }
122     }
123 }