changeset 8039:46ad8dfabd5f

8010136: Make jrunscript's init.js to work on nashorn Reviewed-by: lagergren, hannesw
author sundar
date Fri, 15 Mar 2013 19:30:28 +0530
parents d79503c4c56f
children c1a142965db0 3565c755c49f
files src/share/classes/com/sun/tools/script/shell/init.js
diffstat 1 files changed, 538 insertions(+), 477 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/script/shell/init.js	Thu Mar 14 11:29:16 2013 -0700
+++ b/src/share/classes/com/sun/tools/script/shell/init.js	Fri Mar 15 19:30:28 2013 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,7 @@
  */
 
 /**
- * Creates an object that delegates all method calls on 
+ * Creates an object that delegates all method calls on
  * it to the 'invoke' method on the given delegate object.<br>
  *
  * Example:
@@ -43,13 +43,13 @@
  * @constructor
  */
 function JSInvoker(obj) {
-	return new JSAdapter({
-			__get__ : function(name) {
-				return function() {
-					return obj.invoke(name, arguments);
-				}
-			}
-		});
+    return new JSAdapter({
+        __get__ : function(name) {
+            return function() {
+                return obj.invoke(name, arguments);
+            }
+        }
+    });
 }
 
 /**
@@ -58,24 +58,24 @@
  * example, env.PATH will return PATH value configured.
  */
 var env = new JSAdapter({
-	__get__ : function (name) {
-		return java.lang.System.getenv(name);
-	},
-	__has__ : function (name) {
-		return java.lang.System.getenv().containsKey(name);
-	},
-	__getIds__ : function() {
-		return java.lang.System.getenv().keySet().toArray();
-	},
-	__delete__ : function(name) {
-		println("can't delete env item");
-	},
-	__put__ : function (name, value) {
-		println("can't change env item");
-	},			
-	toString: function() {
-		return java.lang.System.getenv().toString();
-	}		
+    __get__ : function (name) {
+        return java.lang.System.getenv(name);
+    },
+    __has__ : function (name) {
+        return java.lang.System.getenv().containsKey(name);
+    },
+    __getIds__ : function() {
+        return java.lang.System.getenv().keySet().toArray();
+    },
+    __delete__ : function(name) {
+        println("can't delete env item");
+    },
+    __put__ : function (name, value) {
+        println("can't change env item");
+    },
+    toString: function() {
+        return java.lang.System.getenv().toString();
+    }
 });
 
 /**
@@ -91,36 +91,36 @@
  *     delete y['java.class.path']; // remove java.class.path System property
  * </code>
  * </pre>
- * 
+ *
  * @param map java.util.Map instance that will be wrapped
  * @constructor
  */
-function jmap(map) {	
-	return new JSAdapter({
-		__get__ : function(name) {
-			if (map.containsKey(name)) {
-				return map.get(name);
-			} else {
-				return undefined;
-			}
-   		  },
-		__has__ :  function(name) {
-				return map.containsKey(name);
-			},
+function jmap(map) {
+    return new JSAdapter({
+        __get__ : function(name) {
+            if (map.containsKey(name)) {
+                return map.get(name);
+            } else {
+                return undefined;
+            }
+        },
+        __has__ :  function(name) {
+            return map.containsKey(name);
+        },
 
-		__delete__ : function (name) {
-				return map.remove(name);
-			},
-		__put__ : function(name, value) {
-				map.put(name, value);
-			},
-		__getIds__ : function() {
-				return map.keySet().toArray();		
-			},
-		toString: function() {
-				return map.toString();
-		}
-	});
+        __delete__ : function (name) {
+            return map.remove(name);
+        },
+        __put__ : function(name, value) {
+            map.put(name, value);
+        },
+        __getIds__ : function() {
+            return map.keySet().toArray();
+        },
+        toString: function() {
+            return map.toString();
+        }
+    });
 }
 
 /**
@@ -146,52 +146,72 @@
  * @constructor
  */
 function jlist(list) {
-	function isValid(index) {
-		return typeof(index) == 'number' &&
-			index > -1 && index < list.size();
-	}
-	return new JSAdapter({
-		__get__ :  function(name) {
-			if (isValid(name)) {
-				return list.get(name);
-			} else if (name == 'length') {
-				return list.size();
-			} else {
-				return undefined;
-			}
-		},
-		__has__ : function (name) {
-			return isValid(name) || name == 'length';
-		},
-		__delete__ : function(name) {				
-			if (isValid(name)) {
-				list.remove(name);	
-			}
-		},
-		__put__ : function(name, value) {
-			if (isValid(name)) {
-				list.set(name, value);
-			}
-		},
-		__getIds__: function() {
-			var res = new Array(list.size());
-			for (var i = 0; i < res.length; i++) {
-				res[i] = i;
-			}
-			return res;
-		},
-		toString: function() {
-			return list.toString();
-		}				
-	});
+    function isValid(index) {
+        return typeof(index) == 'number' &&
+            index > -1 && index < list.size();
+    }
+    return new JSAdapter({
+        __get__ :  function(name) {
+            if (isValid(name)) {
+                return list.get(name);
+            } else if (name == 'length') {
+                return list.size();
+            } else {
+                return undefined;
+            }
+        },
+        __has__ : function (name) {
+            return isValid(name) || name == 'length';
+        },
+        __delete__ : function(name) {
+            if (isValid(name)) {
+                list.remove(name);
+            }
+        },
+        __put__ : function(name, value) {
+            if (isValid(name)) {
+                list.set(name, value);
+            }
+        },
+        __getIds__: function() {
+            var res = new Array(list.size());
+            for (var i = 0; i < res.length; i++) {
+                res[i] = i;
+            }
+            return res;
+        },
+        toString: function() {
+            return list.toString();
+        }
+    });
 }
 
 /**
- * This is java.lang.System properties wrapped by jmap.
+ * This is java.lang.System properties wrapped by JSAdapter.
  * For eg. to access java.class.path property, you can use
  * the syntax sysProps["java.class.path"]
  */
-var sysProps = jmap(java.lang.System.getProperties());
+var sysProps = new JSAdapter({
+    __get__ : function (name) {
+        return java.lang.System.getProperty(name);
+    },
+    __has__ : function (name) {
+        return java.lang.System.getProperty(name) != null;
+    },
+    __getIds__ : function() {
+        return java.lang.System.getProperties().keySet().toArray();
+    },
+    __delete__ : function(name) {
+        java.lang.System.clearProperty(name);
+        return true;
+    },
+    __put__ : function (name, value) {
+        java.lang.System.setProperty(name, value);
+    },
+    toString: function() {
+        return "<system properties>";
+    }
+});
 
 // stdout, stderr & stdin
 var out = java.lang.System.out;
@@ -199,76 +219,85 @@
 // can't use 'in' because it is a JavaScript keyword :-(
 var inp = java.lang.System["in"];
 
-// useful imports for often used io, net classes
-importPackage(java.io);
-importPackage(java.net);
+var BufferedInputStream = java.io.BufferedInputStream;
+var BufferedOutputStream = java.io.BufferedOutputStream;
+var BufferedReader = java.io.BufferedReader;
+var DataInputStream = java.io.DataInputStream;
+var File = java.io.File;
+var FileInputStream = java.io.FileInputStream;
+var FileOutputStream = java.io.FileOutputStream;
+var InputStream = java.io.InputStream;
+var InputStreamReader = java.io.InputStreamReader;
+var OutputStream = java.io.OutputStream;
+var Reader = java.io.Reader;
+var URL = java.net.URL;
 
 /**
  * Generic any object to input stream mapper
- * @param str input file name, URL or InputStream 
+ * @param str input file name, URL or InputStream
  * @return InputStream object
  * @private
  */
 function inStream(str) {
-	if (typeof(str) == "string") {
-		// '-' means standard input
-		if (str == '-') {
-			return java.lang.System["in"];
-		}
-		// try file first
-		var file = null;
-		try {
-			file = pathToFile(str);
-		} catch (e) {
-		}		
-		if (file && file.exists()) {
-			return new FileInputStream(file);
-		} else {
-			try {
-				// treat the string as URL
-				return new URL(str).openStream();
-			} catch (e) {
-				throw 'file or URL ' + str + ' not found';
-			}
-		}
-	} else {
-		if (str instanceof InputStream) {
-			return str;
-		} else if (str instanceof URL) {
-			return str.openStream();
-		} else if (str instanceof File) {
-			return new FileInputStream(str);
-		}
-	}
-	// everything failed, just give input stream
-	return java.lang.System["in"];
+    if (typeof(str) == "string") {
+        // '-' means standard input
+        if (str == '-') {
+            return java.lang.System["in"];
+        }
+        // try file first
+        var file = null;
+        try {
+            file = pathToFile(str);
+        } catch (e) {
+        }
+        if (file && file.exists()) {
+            return new FileInputStream(file);
+        } else {
+            try {
+                // treat the string as URL
+                return new URL(str).openStream();
+            } catch (e) {
+                throw 'file or URL ' + str + ' not found';
+            }
+        }
+    } else {
+        if (str instanceof InputStream) {
+            return str;
+        } else if (str instanceof URL) {
+            return str.openStream();
+        } else if (str instanceof File) {
+            return new FileInputStream(str);
+        }
+    }
+    // everything failed, just give input stream
+    return java.lang.System["in"];
 }
 
 /**
  * Generic any object to output stream mapper
- * 
+ *
  * @param out output file name or stream
  * @return OutputStream object
  * @private
  */
 function outStream(out) {
-	if (typeof(out) == "string") {
-		if (out == '>') {
-			return java.lang.System.out;
-		} else {
-			// treat it as file			
-			return new FileOutputStream(pathToFile(out));
-		}
-	} else {
-		if (out instanceof OutputStream) {
-			return out;
-		} else if (out instanceof File) {
-			return new FileOutputStream(out);
-		}
-	}
+    if (typeof(out) == "string") {
+        if (out == '>') {
+            return java.lang.System.out;
+        } else {
+            // treat it as file
+            return new FileOutputStream(pathToFile(out));
+        }
+    } else {
+        if (out instanceof OutputStream) {
+            return out;
+        } else if (out instanceof File) {
+            return new FileOutputStream(out);
+        }
+    }
 
-	// everything failed, just return System.out
-	return java.lang.System.out;
+    // everything failed, just return System.out
+    return java.lang.System.out;
 }
 
 /**
@@ -276,17 +305,17 @@
  * @private
  */
 function streamClose(stream) {
-	if (stream) {
-		if (stream != java.lang.System["in"] &&
-			stream != java.lang.System.out &&
-			stream != java.lang.System.err) {
-			try {
-				stream.close();
-			} catch (e) {
-				println(e);
-			}
-		}
-	}
+    if (stream) {
+        if (stream != java.lang.System["in"] &&
+            stream != java.lang.System.out &&
+            stream != java.lang.System.err) {
+            try {
+                stream.close();
+            } catch (e) {
+                println(e);
+            }
+        }
+    }
 }
 
 /**
@@ -302,18 +331,20 @@
  *
  * @param str input from which script is loaded and evaluated
  */
-function load(str) {
-	var stream = inStream(str);
-	var bstream = new BufferedInputStream(stream);
-	var reader = new BufferedReader(new InputStreamReader(bstream));
-	var oldFilename = engine.get(engine.FILENAME);
-	engine.put(engine.FILENAME, str);	
-	try {
-		engine.eval(reader);
-	} finally {
-		engine.put(engine.FILENAME, oldFilename);
-	        streamClose(stream);
-	}
+if (typeof(load) == 'undefined') {
+    var load = function(str) {
+        var stream = inStream(str);
+        var bstream = new BufferedInputStream(stream);
+        var reader = new BufferedReader(new InputStreamReader(bstream));
+        var oldFilename = engine.get(engine.FILENAME);
+        engine.put(engine.FILENAME, str);
+        try {
+            engine.eval(reader);
+        } finally {
+            engine.put(engine.FILENAME, oldFilename);
+            streamClose(stream);
+        }
+    }
 }
 
 // file system utilities
@@ -324,7 +355,7 @@
  * @private
  */
 function javaByteArray(len) {
-	return java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, len);
+    return java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, len);
 }
 
 var curDir = new File('.');
@@ -333,7 +364,7 @@
  * Print present working directory
  */
 function pwd() {
-	println(curDir.getAbsolutePath());
+    println(curDir.getAbsolutePath());
 }
 
 /**
@@ -341,17 +372,17 @@
  * @param target directory to change to. optional, defaults to user's HOME
  */
 function cd(target) {
-	if (target == undefined) {
-		target = sysProps["user.home"];
-	}
-	if (!(target instanceof File)) {
-		target = pathToFile(target);
-	}
-	if (target.exists() && target.isDirectory()) {
-		curDir = target;
-	} else {
-		println(target + " is not a directory");
-	}
+    if (target == undefined) {
+        target = sysProps["user.home"];
+    }
+    if (!(target instanceof File)) {
+        target = pathToFile(target);
+    }
+    if (target.exists() && target.isDirectory()) {
+        curDir = target;
+    } else {
+        println(target + " is not a directory");
+    }
 }
 
 /**
@@ -361,15 +392,15 @@
  * @private
  */
 function pathToFile(pathname) {
-	var tmp = pathname;
-	if (!(tmp instanceof File)) {
-		tmp = new File(tmp);
-	}
-	if (!tmp.isAbsolute()) {
-		return new File(curDir, pathname);
-	} else {
-		return tmp;
-	}
+    var tmp = pathname;
+    if (!(tmp instanceof File)) {
+        tmp = new File(tmp);
+    }
+    if (!tmp.isAbsolute()) {
+        return new File(curDir, pathname);
+    } else {
+        return tmp;
+    }
 }
 
 /**
@@ -379,22 +410,22 @@
  * @param to output stream or file
  */
 function cp(from, to) {
-	if (from == to) {
-		println("file " + from + " cannot be copied onto itself!");
-		return;
-	}
-	var inp = inStream(from);
-	var out = outStream(to);
-	var binp = new BufferedInputStream(inp);
-	var bout = new BufferedOutputStream(out);
-	var buff = javaByteArray(1024);
-	var len;
-	while ((len = binp.read(buff)) > 0 )
-		bout.write(buff, 0, len);
+    if (from == to) {
+        println("file " + from + " cannot be copied onto itself!");
+        return;
+    }
+    var inp = inStream(from);
+    var out = outStream(to);
+    var binp = new BufferedInputStream(inp);
+    var bout = new BufferedOutputStream(out);
+    var buff = javaByteArray(1024);
+    var len;
+    while ((len = binp.read(buff)) > 0 )
+        bout.write(buff, 0, len);
 
-	bout.flush();
-	streamClose(inp);
-	streamClose(out);	
+    bout.flush();
+    streamClose(inp);
+    streamClose(out);
 }
 
 /**
@@ -403,37 +434,37 @@
  * <pre>
  * <code>
  *    cat('test.txt'); // show test.txt file contents
- *    cat('http://java.net'); // show the contents from the URL http://java.net 
+ *    cat('http://java.net'); // show the contents from the URL http://java.net
  * </code>
  * </pre>
  * @param obj input to show
  * @param pattern optional. show only the lines matching the pattern
  */
 function cat(obj, pattern) {
-	if (obj instanceof File && obj.isDirectory()) {
-		ls(obj);
-		return;
-	}
-	
-	var inp = null;
-	if (!(obj instanceof Reader)) {
-		inp = inStream(obj);
-		obj = new BufferedReader(new InputStreamReader(inp));
-	}
-	var line;
-	if (pattern) {
-		var count = 1;
-		while ((line=obj.readLine()) != null) {
-			if (line.match(pattern)) {
-				println(count + "\t: " + line);
-			}
-			count++;
-		}
-	} else {
-		while ((line=obj.readLine()) != null) {
-			println(line);
-		}
-	}
+    if (obj instanceof File && obj.isDirectory()) {
+        ls(obj);
+        return;
+    }
+
+    var inp = null;
+    if (!(obj instanceof Reader)) {
+        inp = inStream(obj);
+        obj = new BufferedReader(new InputStreamReader(inp));
+    }
+    var line;
+    if (pattern) {
+        var count = 1;
+        while ((line=obj.readLine()) != null) {
+            if (line.match(pattern)) {
+                println(count + "\t: " + line);
+            }
+            count++;
+        }
+    } else {
+        while ((line=obj.readLine()) != null) {
+            println(line);
+        }
+    }
 }
 
 /**
@@ -443,13 +474,13 @@
  * @return directory part of the given file name
  */
 function dirname(pathname) {
-	var dirName = ".";
-	// Normalize '/' to local file separator before work.
-	var i = pathname.replace('/', File.separatorChar ).lastIndexOf( 
-		File.separator );
-	if ( i != -1 )
-		dirName = pathname.substring(0, i);
-	return dirName;
+    var dirName = ".";
+    // Normalize '/' to local file separator before work.
+    var i = pathname.replace('/', File.separatorChar ).lastIndexOf(
+        File.separator );
+    if ( i != -1 )
+        dirName = pathname.substring(0, i);
+    return dirName;
 }
 
 /**
@@ -458,34 +489,34 @@
  * @param dir name of the new directory
  */
 function mkdir(dir) {
-	var dir = pathToFile(dir);
-	println(dir.mkdir()? "created" : "can not create dir");
+    dir = pathToFile(dir);
+    println(dir.mkdir()? "created" : "can not create dir");
 }
 
 /**
- * Creates the directory named by given pathname, including 
+ * Creates the directory named by given pathname, including
  * any necessary but nonexistent parent directories.
  *
  * @param dir input path name
  */
 function mkdirs(dir) {
-	var dir = pathToFile(dir);
-	println(dir.mkdirs()? "created" : "can not create dirs");
+    dir = pathToFile(dir);
+    println(dir.mkdirs()? "created" : "can not create dirs");
 }
-	
+
 /**
- * Removes a given file 
+ * Removes a given file
  *
- * @param pathname name of the file 
+ * @param pathname name of the file
  */
 function rm(pathname) {
-    	file = pathToFile(pathname);
-	if (!file.exists()) {
-		println("file not found: " + pathname);
-		return false;
-	}
-	// note that delete is a keyword in JavaScript!
-	println(file["delete"]()? "deleted" : "can not delete");
+    var file = pathToFile(pathname);
+    if (!file.exists()) {
+        println("file not found: " + pathname);
+        return false;
+    }
+    // note that delete is a keyword in JavaScript!
+    println(file["delete"]()? "deleted" : "can not delete");
 }
 
 /**
@@ -494,14 +525,14 @@
  * @param pathname name of the directory
  */
 function rmdir(pathname) {
-	rm(pathname);
+    rm(pathname);
 }
 
 /**
  * Synonym for 'rm'
  */
 function del(pathname) {
-	rm(pathname);
+    rm(pathname);
 }
 
 /**
@@ -511,62 +542,62 @@
  * @param to new name for the file
  */
 function mv(from, to) {
-	println(pathToFile(from).renameTo(pathToFile(to))? 
-		"moved" : "can not move");
+    println(pathToFile(from).renameTo(pathToFile(to))?
+        "moved" : "can not move");
 }
 
 /**
  * Synonym for 'mv'.
  */
 function ren(from, to) {
-	mv(from, to);
+    mv(from, to);
 }
 
-var months = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", 
-		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ];
+var months = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ];
 
 /**
  * Helper function called by ls
  * @private
- */	
+ */
 function printFile(f) {
-	var sb = new java.lang.StringBuffer();
-	sb.append(f.isDirectory()? "d" : "-");
-	sb.append(f.canRead() ? "r": "-" );
-	sb.append(f.canWrite() ? "w": "-" );		
-	sb.append(" ");
+    var sb = new java.lang.StringBuffer();
+    sb.append(f.isDirectory()? "d" : "-");
+    sb.append(f.canRead() ? "r": "-" );
+    sb.append(f.canWrite() ? "w": "-" );
+    sb.append(" ");
 
-	var d = new java.util.Date(f.lastModified());
-	var c = new java.util.GregorianCalendar();
-	c.setTime(d);
-	var day	= c.get(java.util.Calendar.DAY_OF_MONTH);
-	sb.append(months[c.get(java.util.Calendar.MONTH)]
-		 + " " + day );
-	if (day < 10) {
-		sb.append(" ");
-	}
+    var d = new java.util.Date(f.lastModified());
+    var c = new java.util.GregorianCalendar();
+    c.setTime(d);
+    var day    = c.get(java.util.Calendar.DAY_OF_MONTH);
+    sb.append(months[c.get(java.util.Calendar.MONTH)]
+         + " " + day );
+    if (day < 10) {
+        sb.append(" ");
+    }
 
-	// to get fixed length 'length' field
-	var fieldlen = 8;
-	var len = new java.lang.StringBuffer();
-	for(var j=0; j<fieldlen; j++)
-		len.append(" ");
-	len.insert(0, java.lang.Long.toString(f.length()));
-	len.setLength(fieldlen);
-	// move the spaces to the front
-	var si = len.toString().indexOf(" ");
-	if ( si != -1 ) {
-		var pad = len.toString().substring(si);
-		len.setLength(si);
-		len.insert(0, pad);
-	}
-	sb.append(len.toString());
-	sb.append(" ");
-	sb.append(f.getName());
-	if (f.isDirectory()) {
-		sb.append('/');
-	}
-	println(sb.toString());
+    // to get fixed length 'length' field
+    var fieldlen = 8;
+    var len = new java.lang.StringBuffer();
+    for(var j=0; j<fieldlen; j++)
+        len.append(" ");
+    len.insert(0, java.lang.Long.toString(f.length()));
+    len.setLength(fieldlen);
+    // move the spaces to the front
+    var si = len.toString().indexOf(" ");
+    if ( si != -1 ) {
+        var pad = len.toString().substring(si);
+        len.setLength(si);
+        len.insert(0, pad);
+    }
+    sb.append(len.toString());
+    sb.append(" ");
+    sb.append(f.getName());
+    if (f.isDirectory()) {
+        sb.append('/');
+    }
+    println(sb.toString());
 }
 
 /**
@@ -576,32 +607,32 @@
  * @param filter pattern to filter the files listed. optional, default is '.'.
  */
 function ls(dir, filter) {
-	if (dir) {
-		dir = pathToFile(dir);		
-	} else {
-		dir = curDir;
-	}
-	if (dir.isDirectory()) {
-		var files = dir.listFiles();
-		for (var i in files) {
-			var f = files[i];
-			if (filter) {			
-				if(!f.getName().match(filter)) {
-					continue;
-				}
-			}
-			printFile(f);
-		}
-	} else {
-		printFile(dir);
-	}
+    if (dir) {
+        dir = pathToFile(dir);
+    } else {
+        dir = curDir;
+    }
+    if (dir.isDirectory()) {
+        var files = dir.listFiles();
+        for (var i in files) {
+            var f = files[i];
+            if (filter) {
+                if(!f.getName().match(filter)) {
+                    continue;
+                }
+            }
+            printFile(f);
+        }
+    } else {
+        printFile(dir);
+    }
 }
 
 /**
  * Synonym for 'ls'.
  */
 function dir(d, filter) {
-	ls(d, filter);
+    ls(d, filter);
 }
 
 /**
@@ -611,24 +642,24 @@
  * @param files one or more files
  */
 function grep(pattern, files /*, one or more files */) {
-	if (arguments.length < 2) return;
-	for (var i = 1; i < arguments.length; i++) {
-		println(arguments[i] + ":");
-		cat(arguments[i], pattern);
-	}
+    if (arguments.length < 2) return;
+    for (var i = 1; i < arguments.length; i++) {
+        println(arguments[i] + ":");
+        cat(arguments[i], pattern);
+    }
 }
 
 /**
  * Find in files. Calls arbitrary callback function
  * for each matching file.<br>
  *
- * Examples: 
+ * Examples:
  * <pre>
  * <code>
- *    find('.') 
- *    find('.', '.*\.class', rm);  // remove all .class files 
- *    find('.', '.*\.java');       // print fullpath of each .java file 
- *    find('.', '.*\.java', cat);  // print all .java files 
+ *    find('.')
+ *    find('.', '.*\.class', rm);  // remove all .class files
+ *    find('.', '.*\.java');       // print fullpath of each .java file
+ *    find('.', '.*\.java', cat);  // print all .java files
  * </code>
  * </pre>
  *
@@ -637,23 +668,23 @@
  * @param callback function to call for matching files
  */
 function find(dir, pattern, callback) {
-	dir = pathToFile(dir);
-	if (!callback) callback = print;
-	var files = dir.listFiles();
-	for (var f in files) {
-		var file = files[f];
-		if (file.isDirectory()) {
-			find(file, pattern, callback);
-		} else {
-			if (pattern) {
-				if (file.getName().match(pattern)) {
-					callback(file);
-				}
-			} else {
-				callback(file);
-			}
-		}
-	}	
+    dir = pathToFile(dir);
+    if (!callback) callback = print;
+    var files = dir.listFiles();
+    for (var f in files) {
+        var file = files[f];
+        if (file.isDirectory()) {
+            find(file, pattern, callback);
+        } else {
+            if (pattern) {
+                if (file.getName().match(pattern)) {
+                    callback(file);
+                }
+            } else {
+                callback(file);
+            }
+        }
+    }
 }
 
 // process utilities
@@ -664,40 +695,44 @@
  * @param cmd command to execute in child process
  */
 function exec(cmd) {
-	var process = java.lang.Runtime.getRuntime().exec(cmd);
-	var inp = new DataInputStream(process.getInputStream());
-	var line = null;
-	while ((line = inp.readLine()) != null) {
-		println(line);
-	}
-	process.waitFor();
-	$exit = process.exitValue();
+    var process = java.lang.Runtime.getRuntime().exec(cmd);
+    var inp = new DataInputStream(process.getInputStream());
+    var line = null;
+    while ((line = inp.readLine()) != null) {
+        println(line);
+    }
+    process.waitFor();
+    $exit = process.exitValue();
 }
 
-/**
- * Exit the shell program.
- *
- * @param exitCode integer code returned to OS shell.
- * optional, defaults to 0
- */
-function exit(code) {
-	if (code) {
-		java.lang.System.exit(code + 0);		
-	} else {
-		java.lang.System.exit(0);		
-	}
+if (typeof(exit) == 'undefined') {
+    /**
+     * Exit the shell program.
+     *
+     * @param exitCode integer code returned to OS shell.
+     * optional, defaults to 0
+     */
+    var exit = function (code) {
+        if (code) {
+            java.lang.System.exit(code + 0);
+        } else {
+            java.lang.System.exit(0);
+        }
+    }
 }
 
-/**
- * synonym for exit
- */
-function quit(code) {
-	exit(code);
+if (typeof(quit) == 'undefined') {
+    /**
+     * synonym for exit
+     */
+    var quit = function (code) {
+        exit(code);
+    }
 }
 
 // XML utilities
 
-/** 
+/**
  * Converts input to DOM Document object
  *
  * @param inp file or reader. optional, without this param,
@@ -705,17 +740,17 @@
  * @return returns a DOM Document object
  */
 function XMLDocument(inp) {
-	var factory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
-	var builder = factory.newDocumentBuilder();
-	if (inp) {
-		if (typeof(inp) == "string") {
-			return builder.parse(pathToFile(inp));
-		} else {
-			return builder.parse(inp);
-		}
-	} else {
-		return builder.newDocument();
-	}
+    var factory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
+    var builder = factory.newDocumentBuilder();
+    if (inp) {
+        if (typeof(inp) == "string") {
+            return builder.parse(pathToFile(inp));
+        } else {
+            return builder.parse(inp);
+        }
+    } else {
+        return builder.newDocument();
+    }
 }
 
 /**
@@ -725,14 +760,14 @@
  * @return XMLSource object
  */
 function XMLSource(inp) {
-	if (inp instanceof javax.xml.transform.Source) {
-		return inp;
-	} else if (inp instanceof Packages.org.w3c.dom.Document) {
-		return new javax.xml.transform.dom.DOMSource(inp);
-	} else {
-		inp = new BufferedInputStream(inStream(inp));
-		return new javax.xml.transform.stream.StreamSource(inp);
-	}
+    if (inp instanceof javax.xml.transform.Source) {
+        return inp;
+    } else if (inp instanceof Packages.org.w3c.dom.Document) {
+        return new javax.xml.transform.dom.DOMSource(inp);
+    } else {
+        inp = new BufferedInputStream(inStream(inp));
+        return new javax.xml.transform.stream.StreamSource(inp);
+    }
 }
 
 /**
@@ -742,73 +777,73 @@
  * @return XMLResult object
  */
 function XMLResult(out) {
-	if (out instanceof javax.xml.transform.Result) {
-		return out;
-	} else if (out instanceof Packages.org.w3c.dom.Document) {
-		return new javax.xml.transform.dom.DOMResult(out);
-	} else {
-		out = new BufferedOutputStream(outStream(out));
-		return new javax.xml.transform.stream.StreamResult(out);
-	}
+    if (out instanceof javax.xml.transform.Result) {
+        return out;
+    } else if (out instanceof Packages.org.w3c.dom.Document) {
+        return new javax.xml.transform.dom.DOMResult(out);
+    } else {
+        out = new BufferedOutputStream(outStream(out));
+        return new javax.xml.transform.stream.StreamResult(out);
+    }
 }
 
 /**
- * Perform XSLT transform 
+ * Perform XSLT transform
  *
  * @param inp Input XML to transform (URL, File or InputStream)
  * @param style XSL Stylesheet to be used (URL, File or InputStream). optional.
  * @param out Output XML (File or OutputStream
  */
 function XSLTransform(inp, style, out) {
-	switch (arguments.length) {
-	case 2:
-		inp = arguments[0];
-		out = arguments[1];
-		break;
-	case 3:
-		inp = arguments[0];
-		style = arguments[1];
-		out = arguments[2];
-		break;
-	default:
-		println("XSL tranform requires 2 or 3 arguments");
-		return;
-	}
+    switch (arguments.length) {
+    case 2:
+        inp = arguments[0];
+        out = arguments[1];
+        break;
+    case 3:
+        inp = arguments[0];
+        style = arguments[1];
+        out = arguments[2];
+        break;
+    default:
+        println("XSL tranform requires 2 or 3 arguments");
+        return;
+    }
 
-	var factory = javax.xml.transform.TransformerFactory.newInstance();
-	var tranformer;
-	if (style) {		
-		transformer = factory.newTransformer(XMLSource(style));	
-	} else {
-		transformer = factory.newTransformer();
-	}
-	var source = XMLSource(inp);
-	var result = XMLResult(out);
-	transformer.transform(source, result);
-	if (source.getInputStream) {
-		streamClose(source.getInputStream());
-	}
-	if (result.getOutputStream) {
-		streamClose(result.getOutputStream());
-	}
+    var factory = javax.xml.transform.TransformerFactory.newInstance();
+    var transformer;
+    if (style) {
+        transformer = factory.newTransformer(XMLSource(style));
+    } else {
+        transformer = factory.newTransformer();
+    }
+    var source = XMLSource(inp);
+    var result = XMLResult(out);
+    transformer.transform(source, result);
+    if (source.getInputStream) {
+        streamClose(source.getInputStream());
+    }
+    if (result.getOutputStream) {
+        streamClose(result.getOutputStream());
+    }
 }
 
 // miscellaneous utilities
 
 /**
- * Prints which command is selected from PATH 
+ * Prints which command is selected from PATH
  *
  * @param cmd name of the command searched from PATH
  */
 function which(cmd) {
-	var st = new java.util.StringTokenizer(env.PATH, File.pathSeparator);
-	while (st.hasMoreTokens()) {
-		var file = new File(st.nextToken(), cmd);
-		if (file.exists()) {
-			println(file.getAbsolutePath());
-			return;
-		}
-	}
+    var st = new java.util.StringTokenizer(env.PATH, File.pathSeparator);
+    while (st.hasMoreTokens()) {
+        var file = new File(st.nextToken(), cmd);
+        if (file.exists()) {
+            println(file.getAbsolutePath());
+            return;
+        }
+    }
 }
 
 /**
@@ -817,41 +852,43 @@
  * @param name domain name
  */
 function ip(name) {
-	var addrs = InetAddress.getAllByName(name);	
-	for (var i in addrs) {
-		println(addrs[i]);
-	}
+    var addrs = InetAddress.getAllByName(name);
+    for (var i in addrs) {
+        println(addrs[i]);
+    }
 }
 
 /**
  * Prints current date in current locale
  */
 function date() {
-	println(new Date().toLocaleString());
+    println(new Date().toLocaleString());
 }
 
 /**
  * Echoes the given string arguments
  */
 function echo(x) {
-	for (var i = 0; i < arguments.length; i++) {
-		println(arguments[i]);
-	}
+    for (var i = 0; i < arguments.length; i++) {
+        println(arguments[i]);
+    }
 }
 
-/**
- * This is C-like printf 
- *
- * @param format string to format the rest of the print items
- * @param args variadic argument list
- */
-function printf(format, args/*, more args*/) {	
-	var array = java.lang.reflect.Array.newInstance(java.lang.Object, 
-			arguments.length - 1);
-	for (var i = 0; i < array.length; i++) {
-		array[i] = arguments[i+1];
-	}
-	return java.lang.System.out.printf(format, array);
+if (typeof(printf) == 'undefined') {
+    /**
+     * This is C-like printf 
+     *
+     * @param format string to format the rest of the print items
+     * @param args variadic argument list
+     */
+    var printf = function (format, args/*, more args*/) {  
+        var array = java.lang.reflect.Array.newInstance(java.lang.Object, 
+                    arguments.length - 1);
+        for (var i = 0; i < array.length; i++) {
+            array[i] = arguments[i+1];
+        }
+        java.lang.System.out.printf(format, array);
+    }
 }
 
 /**
@@ -861,24 +898,48 @@
  * @param multiline to tell whether to read single line or multiple lines
  */
 function read(prompt, multiline) {
-	if (!prompt) {
-		prompt = '>';
-	}	
-	var inp = java.lang.System["in"];
-	var reader = new BufferedReader(new InputStreamReader(inp));
-	if (multiline) {
-		var line = '';
-		while (true) {
-			java.lang.System.err.print(prompt);
-			java.lang.System.err.flush();
-			var tmp = reader.readLine();
-			if (tmp == '' || tmp == null) break;
-			line += tmp + '\n';
-		}
-		return line;
-	} else {
-		java.lang.System.err.print(prompt);
-		java.lang.System.err.flush();	
-		return reader.readLine();
-	}
+    if (!prompt) {
+        prompt = '>';
+    }
+    var inp = java.lang.System["in"];
+    var reader = new BufferedReader(new InputStreamReader(inp));
+    if (multiline) {
+        var line = '';
+        while (true) {
+            java.lang.System.err.print(prompt);
+            java.lang.System.err.flush();
+            var tmp = reader.readLine();
+            if (tmp == '' || tmp == null) break;
+            line += tmp + '\n';
+        }
+        return line;
+    } else {
+        java.lang.System.err.print(prompt);
+        java.lang.System.err.flush();
+        return reader.readLine();
+    }
 }
+
+if (typeof(println) == 'undefined') {
+    var print = function(str, newline) {
+        if (typeof(str) == 'undefined') {
+            str = 'undefined';
+        } else if (str == null) {
+            str = 'null';
+        }
+
+        if (!(out instanceof java.io.PrintWriter)) {
+            out = new java.io.PrintWriter(out);
+        }
+
+        out.print(String(str));
+        if (newline) {
+            out.print('\n');
+        }
+        out.flush();
+    }
+
+    var println = function(str) {
+        print(str, true);
+    };
+}