Change 117522 by jkristian@jkristian-home on 2003/11/11 00:46:57 Renamed UnixStyleFilter to UnixCommand. Improved. Affected files ... ... //users/jkristian/lib/UnixCommandResources.properties#1 branch ... //users/jkristian/lib/UnixStyleFilterResources.properties#2 delete ... //users/jkristian/lib/p4d2pResources.properties#3 edit ... //users/jkristian/src/UnixCommand.java#1 add ... //users/jkristian/src/UnixStyleFilter.java#3 delete ... //users/jkristian/src/p4d2p.java#3 edit Differences ... ==== //users/jkristian/lib/p4d2pResources.properties#3 (text) ==== Index: //users/jkristian/lib/p4d2pResources.properties --- users/jkristian/lib/p4d2pResources.properties #2 +++ users/jkristian/lib/p4d2pResources.properties #3 @@ -46,3 +46,4 @@ \ John Kristian . Thanks to Gurusamy Sarathy for\n\ \ inspiration; but I accept all blame.\n\ +diff.default: converting default diff (not recommended for `patch`)\n ==== //users/jkristian/src/p4d2p.java#3 (text) ==== Index: //users/jkristian/src/p4d2p.java --- users/jkristian/src/p4d2p.java #2 +++ users/jkristian/src/p4d2p.java #3 @@ -1,8 +1,5 @@ import java.io.File; -import java.io.BufferedReader; -import java.io.InputStreamReader; import java.io.IOException; -import java.io.PushbackReader; import java.io.Writer; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -17,51 +14,65 @@ public class p4d2p implements LineWriter { public static void main(String[] ARGV) throws IOException { - UnixStyleFilter filter = new UnixStyleFilter(p4d2p.class, "hi::o:p:v", ARGV); + UnixCommand command = new UnixCommand(p4d2p.class, "hi::o:p:v", ARGV); try { - Properties options = filter.getOptions(); - if (options.getProperty("h") != null) { - filter.writeError(filter.getHelp()); + Properties options = command.getOptions(); + if (options.get("h") != null) { + command.writeError(command.getHelp()); } else { - filter.setEditInPlace(options.getProperty("i")); - LineWriter self = new p4d2p(filter, filter.getOutputWriter()); - while (filter.getFile()) { - Copier.copyAll(filter.getInputLineReader(), self); + command.setEditInPlace(options.getProperty("i")); + LineWriter self = new p4d2p(command); + while (command.getFile()) { + Copier.copyAll(command.getInputLineReader(), self); self.close(); } } } finally { - filter.flush(); + command.flush(); } } - private String oldFile = null; - private String oldNote; - private String newFile; - private String newNote; - private List movedFiles = new ArrayList(); + protected p4d2p(UnixCommand command) throws IOException { + this.command = command; + this.options = command.getOptions(); + this.verbose = (options.get("v") != null); + this.out = command.getOutputWriter(); + } + + protected static DateFormat timeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z"); // ISO 8601 + protected static String epoch = timeFormat.format(new Date(0)); + + protected String now = timeFormat.format(new Date()); + protected UnixCommand command; + protected Properties options; + protected boolean verbose; + protected Writer out; + protected Writer err; - private static final Pattern P4_DESCRIBE_MOVE = Pattern.compile("^\\.\\.\\. (//.+?\\#\\d+ (add|branch|delete))$", Pattern.MULTILINE); - private static final Pattern P4_MOVED_FILE = Pattern.compile("//(.+?)(\\#\\d+) (\\w*)$", Pattern.MULTILINE); - private static final Pattern P4_DESCRIBE_HEADER = Pattern.compile("^==== //(.+?)(\\#\\d+) .*?====( \\(.+\\))?$", Pattern.MULTILINE); - private static final Pattern P4_DIFF_HEADER = Pattern.compile("^==== //(.+?)(\\#\\d+) +- +(.+?) +====( \\(.+\\))?$", Pattern.MULTILINE); - private static final Pattern P4_DIFF2_HEADER = Pattern.compile("^==== //(.+?)(\\#\\d+) +\\(.+?\\) +- +(.+?)(\\#\\d+) +\\(.+?\\) +==== +\\w+$", Pattern.MULTILINE); + protected String oldFile = null; + protected String oldNote; + protected String newFile; + protected String newNote; + protected List movedFiles = new ArrayList(); - private static final Pattern VERSION = Pattern.compile("\\#(\\d+)"); - private static final Pattern UNIFIED_DIFF = Pattern.compile("^\\@\\@\\s.*\\s\\@\\@$", Pattern.MULTILINE); - private static final Pattern CONTEXT_DIFF = Pattern.compile("^\\*+$", Pattern.MULTILINE); - private static final Pattern DEFAULT_DIFF = Pattern.compile("^\\d+(,\\d+)?[acd]\\d+", Pattern.MULTILINE); + protected static Pattern P4_DESCRIBE_MOVE = Pattern.compile("^\\.\\.\\. (//.+?\\#\\d+ (add|branch|delete))$", Pattern.MULTILINE); + protected static Pattern P4_MOVED_FILE = Pattern.compile("//(.+?)(\\#\\d+) (\\w*)$", Pattern.MULTILINE); + protected static Pattern P4_DESCRIBE_HEADER = Pattern.compile("^==== //(.+?)(\\#\\d+) .*?====( \\(.+\\))?$", Pattern.MULTILINE); + protected static Pattern P4_DIFF_HEADER = Pattern.compile("^==== //(.+?)(\\#\\d+) +- +(.+?) +====( \\(.+\\))?$", Pattern.MULTILINE); + protected static Pattern P4_DIFF2_HEADER = Pattern.compile("^==== //(.+?)(\\#\\d+) +\\(.+?\\) +- +(.+?)(\\#\\d+) +\\(.+?\\) +==== +\\w+$", + Pattern.MULTILINE); + protected static Pattern VERSION = Pattern.compile("\\#(\\d+)"); + protected static Pattern UNIFIED_DIFF = Pattern.compile("^\\@\\@\\s.*\\s\\@\\@$", Pattern.MULTILINE); + protected static Pattern CONTEXT_DIFF = Pattern.compile("^\\*+$", Pattern.MULTILINE); + protected static Pattern DEFAULT_DIFF = Pattern.compile("^\\d+(,\\d+)?[acd]\\d+", Pattern.MULTILINE); public void write(StringBuffer line) throws IOException { - //if (verbose) out.write("// write(line)\n"); Matcher m; if ((m = P4_DESCRIBE_MOVE.matcher(line)).find()) { // add, branch or delete - if (verbose) out.write("// p4 describe move\n"); movedFiles.add(m.group(1)); } else if ((m = P4_DIFF_HEADER.matcher(line)).find()) { - if (verbose) out.write("// p4 diff header\n"); oldFile = m.group(1); newFile = m.group(3); oldNote = " " + options.getProperty("o", m.group(2)); @@ -69,14 +80,12 @@ newNote = " " + ((lastModified == 0) ? now : timeFormat.format(new Date(lastModified))); } else if ((m = P4_DIFF2_HEADER.matcher(line)).find()) { - if (verbose) out.write("// p4 diff2 header\n"); oldFile = m.group(1); newFile = m.group(3); oldNote = " " + options.getProperty("o", m.group(2)); newNote = " " + m.group(4); } else if ((m = P4_DESCRIBE_HEADER.matcher(line)).find()) { - if (verbose) out.write("// p4 describe header\n"); newFile = m.group(1); newNote = " " + m.group(2); oldFile = newFile; @@ -87,26 +96,25 @@ } else if (oldFile != null) { if ((m = UNIFIED_DIFF.matcher(line)).find()) { // the preferred format for `patch` - if (verbose) System.err.println("emitting diff -u header"); out.write("Index: //" + oldFile + "\n"); out.write("--- " + oldFile + oldNote + "\n"); out.write("+++ " + oldFile + newNote + "\n"); oldFile = null; } else if ((m = CONTEXT_DIFF.matcher(line)).find()) { - if (verbose) System.err.println("emitting diff -c header"); out.write("Index: //" + oldFile + "\n"); out.write("*** " + oldFile + oldNote + "\n"); out.write("--- " + oldFile + newNote + "\n"); oldFile = null; } else if ((m = DEFAULT_DIFF.matcher(line)).find()) { - if (verbose) System.err.println("emitting diff header (not recommended for `patch`)"); + if (verbose) command.writeError(command.getResource("diff.default")); out.write("Index: " + oldFile + "\n"); out.write("diff -r //" + oldFile + " " + newFile + "\n"); oldFile = null; } } + out.write(line.toString()); } @@ -123,12 +131,10 @@ newFile = m.group(1); newNote = m.group(2); verb = m.group(3); - if (verbose) System.err.println(verb); oldFile = newFile; - if (verb.equals("delete")) { - Matcher version = VERSION.matcher(newNote); - version.find(); - oldNote = "#" + (Long.parseLong(version.group(1)) - 1); + if ("delete".equals(verb)) { + (m = VERSION.matcher(newNote)).find(); + oldNote = "#" + (Long.parseLong(m.group(1)) - 1); newNote = epoch; file = p4print("//" + oldFile + oldNote); } else { // add or branch @@ -144,7 +150,7 @@ out.write("--- " + oldFile + oldNote + "\n"); out.write("+++ " + newFile + newNote + "\n"); String prefix; - if (verb.equals("delete")) { + if ("delete".equals(verb)) { out.write("@@ -1" + lines + " +0,0 @@\n"); prefix = "-"; } else { // add or branch @@ -165,7 +171,7 @@ oldFile = null; } - private List p4print(String name) throws IOException { + protected List p4print(String name) throws IOException { CommandLine cmd = (new CommandLine(options.getProperty("p", "p4 print -q"))).append(name); // Sadly, executing `p4 print` will consume some input. // Which is one reason not to emit files immediately @@ -173,26 +179,9 @@ ProcessInputStream p = new ProcessInputStream(cmd.exec()); List file = (new LineReader(p)).readList(); if (p.exitValue() != 0) { - System.err.println("exit " + p.exitValue() + " from " + cmd); + command.writeError("exit " + p.exitValue() + " from " + cmd + "\n"); } return file; } - protected UnixStyleFilter filter; - protected Properties options; - protected boolean verbose; - protected Writer out; - - private p4d2p(UnixStyleFilter filter, Writer out) { - this.filter = filter; - this.options = filter.getOptions(); - this.verbose = (options.getProperty("v") != null); - this.out = out; - } - - private static DateFormat timeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z"); // ISO 8601 - private static final String epoch = timeFormat.format(new Date(0)); - - private String now = timeFormat.format(new Date()); - } Index: //users/jkristian/lib/UnixCommandResources.properties --- users/jkristian/lib/UnixCommandResources.properties 1970-01-01 00:00:00Z +++ users/jkristian/lib/UnixCommandResources.properties #1 @@ -0,0 +1,2 @@ +usage: usage: {0} +rename: can''t move {0} to {1} Index: //users/jkristian/lib/UnixStyleFilterResources.properties --- users/jkristian/lib/UnixStyleFilterResources.properties #1 +++ users/jkristian/lib/UnixStyleFilterResources.properties 1970-01-01 00:00:00Z @@ -1,2 +0,0 @@ -usage: usage: {0} -rename: can''t move {0} to {1} Index: //users/jkristian/src/UnixCommand.java --- users/jkristian/src/UnixCommand.java 1970-01-01 00:00:00Z +++ users/jkristian/src/UnixCommand.java #1 @@ -0,0 +1,250 @@ +import gnu.getopt.Getopt; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FilterInputStream; +import java.io.FilterOutputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PushbackReader; +import java.io.Reader; +import java.io.Writer; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Locale; +import java.util.List; +import java.util.Properties; +import java.util.ResourceBundle; + +class UnixCommand { + + public UnixCommand(Class command, String options, String[] ARGV) { + this.command = command; + String commandName = command.getName(); + this.resourceBundleName = commandName + "Resources"; + Getopt g = new Getopt(commandName, ARGV, options); + { + boolean error = false; + for (int c; (c = g.getopt()) != -1; ) { + // System.err.println("option " + (char)c); + if (c == '?') { + error = true; + } else { + this.options.put((char)c + "", + (options.indexOf((char)c + ":") < 0) ? "1" : + ((g.getOptarg() == null) ? "" : g.getOptarg())); + } + } + if (error) { + try { + writeError(getUsage()); + } catch(IOException ignored) {} + exit(1); + } + } + for (int i = g.getOptind(); i < ARGV.length; ++i) { + fileNames.add(ARGV[i]); + } + if (fileNames.isEmpty()) { + fileNames.add(STDIN_NAME); + } + } + + public void exit(int status) { + try { + flush(); + } catch(IOException ignored) {} + Runtime.getRuntime().exit(1); + } + + public static final String STDIN_NAME = "-"; + + protected Class command; + protected Properties options = new Properties(); + private Locale locale; + private String resourceBundleName; + protected String backupFileSuffix = null; + protected List fileNames = new ArrayList(); + protected SteerableInputStream inputStream = new SteerableInputStream(null); + protected PushbackReader inputReader; + protected LineReader inputLineReader; + protected SteerableOutputStream outputStream = new SteerableOutputStream(System.out); + protected Writer outputWriter; + protected Writer errorWriter; + + protected static class SteerableInputStream extends FilterInputStream { + public SteerableInputStream(InputStream in) { super(in); } + public void setInput(InputStream in) { this.in = in; } + } + + protected static class SteerableOutputStream extends FilterOutputStream { + public SteerableOutputStream(OutputStream out) { super(out); } + public void setOutput(OutputStream out) { this.out = out; } + } + + public Properties getOptions() { + return options; + } + + public Class getCommand() { + return command; + } + + public String getResourceBundleName() { + return resourceBundleName; + } + + public void setResourceBundleName(String name) { + resourceBundleName = name; + } + + public Locale getLocale() { + if (locale == null) { + setLocale(Locale.getDefault()); + } + return locale; + } + + public void setLocale(Locale locale) { + this.locale = locale; + } + + public ResourceBundle getResourceBundle() + { + return ResourceBundle.getBundle(getResourceBundleName(), getLocale(), command.getClassLoader()); + } + + public String getResource(String name) + { + return getResourceBundle().getString(name); + } + + public void setEditInPlace(String suffix) + { + this.backupFileSuffix = (suffix == null || suffix.length() > 0) ? suffix : "~"; + } + + public boolean getFile() throws IOException { + if (fileNames.isEmpty()) return false; + String fileName = (String)(fileNames.remove(0)); + if (fileName.equals(STDIN_NAME)) { + inputStream.setInput(System.in); + outputStream.setOutput(System.out); + + } else if (backupFileSuffix == null) { + inputStream.setInput(new FileInputStream(fileName)); + outputStream.setOutput(System.out); + + } else { // edit in place + File inputFile = new File(fileName + backupFileSuffix); + File outputFile = new File(fileName); + inputFile.delete(); + if ( ! outputFile.renameTo(inputFile)) { + throw new IOException(MessageFormat.format(getMessage("rename"), + new String[]{outputFile.getPath(), inputFile.getPath()})); + } + inputStream.setInput(new FileInputStream(inputFile)); + outputStream.setOutput(new FileOutputStream(outputFile)); + } + return true; + } + + public void flush() throws IOException + { + IOException ex = null; + if (outputWriter != null) try { + outputWriter.flush(); + } catch(IOException e) { + ex = e; + } + if (outputStream != null) try { + outputStream.flush(); + } catch(IOException e) { + ex = e; + } + if (errorWriter != null) try { + errorWriter.flush(); + } catch(IOException e) { + ex = e; + } + System.err.flush(); + if (ex != null) throw ex; + } + + public PushbackReader getInputReader() throws IOException { + if (inputReader == null) { + inputReader = new PushbackReader(new InputStreamReader(inputStream)); + } + return inputReader; + } + + public LineReader getInputLineReader() throws IOException { + if (inputLineReader == null) { + inputLineReader = new LineReader(getInputReader()); + } + return inputLineReader; + } + + public Writer getOutputWriter() throws IOException { + if (outputWriter == null) { + outputWriter = new OutputStreamWriter(outputStream); + } + return outputWriter; + } + + public Writer getErrorWriter() throws IOException { + if (errorWriter == null) { + errorWriter = new OutputStreamWriter(System.err); + } + return errorWriter; + } + + public void writeError(String s) throws IOException { + Writer err = getErrorWriter(); + err.write(s); + err.flush(); + } + + public void writeError(Object o) throws IOException { + writeError(o + ""); + } + + public String getUsage() { + String message = getMessage("usage"); + return (message == null) ? getHelp().toString() : + MessageFormat.format(message, + new String[]{MessageFormat.format(getResourceBundle().getString("usage"), + new String[]{command.getName()})}); + } + + public StringBuffer getHelp() { + ResourceBundle resource = getResourceBundle(); + StringBuffer message = new StringBuffer(resource.getString("help")); + replaceAll(message, "{usage}", resource.getString("usage")); + message.replace(0, message.length(), + MessageFormat.format(message.toString(), + new String[]{command.getName()})); + return message; + } + + protected String getMessage(String name) { + return getResourceBundle(UnixCommand.class).getString(name); + } + + protected ResourceBundle getResourceBundle(Class base) { + return ResourceBundle.getBundle(base.getName() + "Resources", + getLocale(), + base.getClassLoader()); + } + + protected static void replaceAll(StringBuffer s, String find, String replace) + { + for (int i = 0; (i = s.indexOf(find, i)) >= 0; i += replace.length()) { + s.replace(i, i + find.length(), replace); + } + } + +} Index: //users/jkristian/src/UnixStyleFilter.java --- users/jkristian/src/UnixStyleFilter.java #2 +++ users/jkristian/src/UnixStyleFilter.java 1970-01-01 00:00:00Z @@ -1,250 +0,0 @@ -import gnu.getopt.Getopt; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.FilterInputStream; -import java.io.FilterOutputStream; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PushbackReader; -import java.io.Reader; -import java.io.Writer; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Locale; -import java.util.List; -import java.util.Properties; -import java.util.ResourceBundle; - -class UnixStyleFilter { - - public UnixStyleFilter(Class command, String options, String[] ARGV) { - this.command = command; - String commandName = command.getName(); - this.resourceBundleName = commandName + "Resources"; - Getopt g = new Getopt(commandName, ARGV, options); - { - boolean error = false; - for (int c; (c = g.getopt()) != -1; ) { - // System.err.println("option " + (char)c); - if (c == '?') { - error = true; - } else { - this.options.put((char)c + "", - (options.indexOf((char)c + ":") < 0) ? "1" : - ((g.getOptarg() == null) ? "" : g.getOptarg())); - } - } - if (error) { - try { - writeError(getUsage()); - } catch(IOException ignored) {} - exit(1); - } - } - for (int i = g.getOptind(); i < ARGV.length; ++i) { - fileNames.add(ARGV[i]); - } - if (fileNames.isEmpty()) { - fileNames.add(STDIN_NAME); - } - } - - public void exit(int status) { - try { - flush(); - } catch(IOException ignored) {} - Runtime.getRuntime().exit(1); - } - - public static final String STDIN_NAME = "-"; - - protected Class command; - protected Properties options = new Properties(); - private Locale locale; - private String resourceBundleName; - protected String backupFileSuffix = null; - protected List fileNames = new ArrayList(); - protected SteerableInputStream inputStream = new SteerableInputStream(null); - protected PushbackReader inputReader; - protected LineReader inputLineReader; - protected SteerableOutputStream outputStream = new SteerableOutputStream(System.out); - protected Writer outputWriter; - protected Writer errorWriter; - - protected static class SteerableInputStream extends FilterInputStream { - public SteerableInputStream(InputStream in) { super(in); } - public void setInput(InputStream in) { this.in = in; } - } - - protected static class SteerableOutputStream extends FilterOutputStream { - public SteerableOutputStream(OutputStream out) { super(out); } - public void setOutput(OutputStream out) { this.out = out; } - } - - public Properties getOptions() { - return options; - } - - public Class getCommand() { - return command; - } - - public String getResourceBundleName() { - return resourceBundleName; - } - - public void setResourceBundleName(String name) { - resourceBundleName = name; - } - - public Locale getLocale() { - if (locale == null) { - setLocale(Locale.getDefault()); - } - return locale; - } - - public void setLocale(Locale locale) { - this.locale = locale; - } - - public ResourceBundle getResourceBundle() - { - return ResourceBundle.getBundle(getResourceBundleName(), getLocale(), command.getClassLoader()); - } - - public String getResource(String name) - { - return getResourceBundle().getString(name); - } - - public void setEditInPlace(String suffix) - { - this.backupFileSuffix = (suffix == null || suffix.length() > 0) ? suffix : "~"; - } - - public boolean getFile() throws IOException { - if (fileNames.isEmpty()) return false; - String fileName = (String)(fileNames.remove(0)); - if (fileName.equals(STDIN_NAME)) { - inputStream.setInput(System.in); - outputStream.setOutput(System.out); - - } else if (backupFileSuffix == null) { - inputStream.setInput(new FileInputStream(fileName)); - outputStream.setOutput(System.out); - - } else { // edit in place - File inputFile = new File(fileName + backupFileSuffix); - File outputFile = new File(fileName); - inputFile.delete(); - if ( ! outputFile.renameTo(inputFile)) { - throw new IOException(MessageFormat.format(getMessage("rename"), - new String[]{outputFile.getPath(), inputFile.getPath()})); - } - inputStream.setInput(new FileInputStream(inputFile)); - outputStream.setOutput(new FileOutputStream(outputFile)); - } - return true; - } - - public void flush() throws IOException - { - IOException ex = null; - if (outputWriter != null) try { - outputWriter.flush(); - } catch(IOException e) { - ex = e; - } - if (outputStream != null) try { - outputStream.flush(); - } catch(IOException e) { - ex = e; - } - if (errorWriter != null) try { - errorWriter.flush(); - } catch(IOException e) { - ex = e; - } - System.err.flush(); - if (ex != null) throw ex; - } - - public PushbackReader getInputReader() throws IOException { - if (inputReader == null) { - inputReader = new PushbackReader(new InputStreamReader(inputStream)); - } - return inputReader; - } - - public LineReader getInputLineReader() throws IOException { - if (inputLineReader == null) { - inputLineReader = new LineReader(getInputReader()); - } - return inputLineReader; - } - - public Writer getOutputWriter() throws IOException { - if (outputWriter == null) { - outputWriter = new OutputStreamWriter(outputStream); - } - return outputWriter; - } - - public Writer getErrorWriter() throws IOException { - if (errorWriter == null) { - errorWriter = new OutputStreamWriter(System.err); - } - return errorWriter; - } - - public void writeError(String s) throws IOException { - Writer err = getErrorWriter(); - err.write(s); - err.flush(); - } - - public void writeError(Object o) throws IOException { - writeError(o + ""); - } - - public String getUsage() { - String message = getMessage("usage"); - return (message == null) ? getHelp().toString() : - MessageFormat.format(message, - new String[]{MessageFormat.format(getResourceBundle().getString("usage"), - new String[]{command.getName()})}); - } - - public StringBuffer getHelp() { - ResourceBundle resource = getResourceBundle(); - StringBuffer message = new StringBuffer(resource.getString("help")); - replaceAll(message, "{usage}", resource.getString("usage")); - message.replace(0, message.length(), - MessageFormat.format(message.toString(), - new String[]{command.getName()})); - return message; - } - - protected String getMessage(String name) { - return getResourceBundle(UnixStyleFilter.class).getString(name); - } - - protected ResourceBundle getResourceBundle(Class base) { - return ResourceBundle.getBundle(base.getName() + "Resources", - getLocale(), - base.getClassLoader()); - } - - protected static void replaceAll(StringBuffer s, String find, String replace) - { - for (int i = 0; (i = s.indexOf(find, i)) >= 0; i += replace.length()) { - s.replace(i, i + find.length(), replace); - } - } - -}