/* File: Util.java * Contains: A class for useful static methods * Author: Jeff Dalton * Created: January 1998 * Updated: Sun Dec 2 00:27:17 2001 by Jeff Dalton * Copyright: (c) 1998 - 2001, AIAI, University of Edinburgh */ package ix.util; import java.util.*; import java.io.*; import javax.swing.*; import ix.util.lisp.*; /** Class for useful static methods. */ public class Util { /** * A method to print the name of the system, the release version, * and the release date. */ public static void printGreeting(String name) { System.out.println(name + ", I-X version " + ix.Release.version + ", " + ix.Release.date); System.out.println(""); } /** * Displays a text message in a dialogue box. * * @param parentComponent determines the Frame in which dialogs * are displayed. * @param text the contents of the message. */ public static void displayMessage(final java.awt.Component parentComponent, final String text) { SwingUtilities.invokeLater(new Runnable() { public void run() { JOptionPane.showMessageDialog(parentComponent, text, "Message", JOptionPane.INFORMATION_MESSAGE); } }); } /** * breakStringAtFirst takes a string containing fields separated by * a (string) delimiter and returns a two-element string array containing * the substring before the first occurrence of the char, and the * substring after. Neither substring contains the delimiter. If * the delimiter does not appear in the string at all, the values * are the string and "". */ public static String[] breakStringAtFirst(String s, String separator) { int i = s.indexOf(separator); if (i == -1) return new String[]{s, ""}; else return new String[]{ s.substring(0, i), s.substring(i + separator.length()) }; } /** * Returns the first line of a string. */ public static String firstLine(String s) { // For some reason, it doesn't work on Windows to use // System.getProperty("line.separator") here. /\/ String[] parts = breakStringAtFirst(s, "\n"); return parts[0]; } /** * Returns the rest of a string after the first line has been removed. */ public static String restLines(String s) { // For some reason, it doesn't work on Windows to use // System.getProperty("line.separator") here. /\/ String[] parts = breakStringAtFirst(s, "\n"); return parts[1]; } /** * Returns a List of the lines in a string. */ public static List breakIntoLines(String text) { LListCollector lines = new LListCollector(); while (!text.equals("")) { // For some reason, it doesn't work on Windows to // use lineSpearator here. /\/ String[] parts = Util.breakStringAtFirst(text, "\n"); lines.add(parts[0]); text = parts[1]; } return lines.contents(); } /** * Puts double quotes around a string. This is useful to indicate * the boundaries of the string when it's included in other text * such as in an error or warning message. */ public static String quote(String text) { return "\"" + text + "\""; } /** * Returns a copy of the string in which the first character * is in upper case and the rest of the string is left as it was. */ public static String capitalizeString(String s) { return s.substring(0,1).toUpperCase() + s.substring(1); } /** * Returns a String made by appending a specified string count * times. */ public static String repeatString(String s, int count) { StringBuffer buf = new StringBuffer(); for (int i = 0; i < count; i++) buf.append(s); return buf.toString(); } /** * Name generator a la gensym. */ public static class NameGenerator { protected Map counters = new HashMap(); public NameGenerator() { } public String nextName(String base) { Long count = (Long)counters.get(base); if (count == null) { count = new Long(0); counters.put(base, count); } long c = count.longValue(); counters.put(base, new Long(c + 1)); return base + "-" + c; } } private static NameGenerator defaultNameGenerator = new NameGenerator(); /** * Generates a name unique within this VM that begins with the * specified base string. (Note that "unique" means unique among * the names generated in this way; the same string might, of course, * be constructed in some other way.) */ public static String generateName(String base) { return defaultNameGenerator.nextName(base); } /** * Print the elements of a String[] array to System.out as lines. */ public static void printLines(String[] lines) { for (int i = 0; i < lines.length; i++) { System.out.println(lines[i]); } } /** * Simple, text-based user interaction. askLine prints a prompt * to System.out and returns a String containing the next line * from System.in.

* * If askLine blocks when reading, we'd like other threads to be * able to run; but that doesn't seem to happen reliably. Presumably, * this is a bug. In any case, askLine works around the problem by * having a loop that checks whether input is available and sleeps * for a second if it isn't. */ public static String askLine(String prompt) { System.out.print(prompt + " "); System.out.flush(); // /\/: Should we synchronize on System.in? try { while (System.in.available() == 0) { try { Thread.sleep(1000); } catch (InterruptedException e) {} } } catch (IOException e) { Debug.noteException(e); return ""; } return Util.readLine(System.in); } /** * Reads a line from an InputStream and returns it as a String. * In Java, we seem to have to write this ourself unless we wrap * a special stream (or Reader) around whatever we want to read. * Here we provide a static method, because that's easier to * mix with other operations. The only InputStream method * called is read(). */ public static String readLine(InputStream is) { ByteArrayOutputStream line = new ByteArrayOutputStream(80); readLoop: while (true) { int c; // a character as a "byte" try { c = is.read(); } catch (IOException e) { Debug.warn("IOException reading line from " + is); break readLoop; } if (c == '\n') // newline break readLoop; else if (c == -1) // end of stream break readLoop; else if (c == '\r') // CR ; // (ignore) else line.write(c); } return line.toString(); } } // Issues: // * Consider breaking this into separate classes such as StringUtil.