Warning : session_start(): open(/var/lib/php/sessions/sess_jcod3sjmmin1l0br7s0u3qvhjp, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning : session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
import java.util.*;
import java.util.zip.*;
import java.util.List;
import java.util.regex.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.table.*;
import java.io.*;
import java.net.*;
import java.lang.reflect.*;
import java.lang.ref.*;
import java.lang.management.*;
import java.security.*;
import java.security.spec.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.imageio.*;
import java.math.*;
public class main {
static List data = toLinesFullTrim("\n If A likes B then A will greet B.\n If X then Y.\n If U then V. && U. => V.\n John likes Paul.\n");
static List> log;
static String toCheck = "John will greet Paul.";
static class Flow {
StringBuilder desc = new StringBuilder();
List subs = new ArrayList();
Flow sub(String desc) {
Flow flow = new Flow();
flow.append(desc);
subs.add(flow);
return flow;
}
void append(Object o) {
desc.append(o).append("\n");
}
void x(Object o) { append(o); }
public String toString() {
return str(desc) + indentx(allToStringWithLineBreaks(subs));
}
}
public static void main(String[] args) throws Exception { typeWriterConsole();
// Parse data
log = map("tok", data);
TreeSet newData = new TreeSet();
// Go through all rules
Flow flow = new Flow();
for (List tok : log) {
Map m = matchSingle("I => O", tok);
if (m == null) continue;
String i = m.get("I"), o = m.get("O");
// Parse left-hand
List tokI = tok(i);
List> is = splitAtAmpersands(tokI);
flow.x("Processing LHS: " + struct(is));
// Apply rule to input
for (Map m2 : gSatAnd(is, flow))
newData.add(join(" ", replaceVars(tok(o), m2)));
}
print(("Lines made (" + (l(newData)) + "):"));
psl(asList(newData));
printWithAsciiHeading("FLOW", flow);
}
// null = no satisfaction
// otherwise return var map
static Iterable> gSatAnd(List> statements, Flow flow) {
flow = flow.sub("gSatAnd" + struct(statements));
assertTrue(l(statements) >= 1);
if (l(statements) == 1)
return gSat(first(statements), flow);
List> l = new ArrayList>();
for (Map map : gSat(first(statements), flow)) {
flow.x("First clause satisfied. " + struct(map));
List> s2 = mapReplaceVars(dropFirst(statements), map);
flow.x("Now looking for: " + struct(s2));
for (Map map2 : gSatAnd(s2, flow)) {
flow.x("Sub gSatAnd returned: " + struct(map2));
addIfNotEmpty(l, mergeMappings(map, map2));
}
}
return l;
}
static IterableIterator> gSat(List pat, Flow flow) {
flow = flow.sub("gSat" + struct(pat));
return gMatch(pat, flow);
}
static IterableIterator> gMatch(final List pat, final Flow flow) {
return new IterableIterator>() {
int i = l(log);
Iterator> m;
public boolean hasNext() {
if (m != null && m.hasNext()) return true;
m = null;
while (--i >= 0) {
List> l = match(pat, get(log, i));
if (nempty(l)) {
flow.x("gMatch found: " + struct(l));
m = l.iterator(); return true;
}
} return false;
}
public Map next() { return m.next(); }
};
}
static List> splitAtAmpersands(List tok) {
List> l = new ArrayList>();
int iAmp;
while ((iAmp = indexOfSubList(tok, ll("&", "&"))) >= 0) {
//print("&& found at " + iAmp);
l.add(subList(tok, 0, iAmp));
tok = subList(tok, iAmp+2);
}
l.add(tok);
return l;
}
static Map matchSingle(String pat, List input) {
return getSingletonOpt(match(tok(pat), input));
}
static Map matchSingle(String pat, String input) {
return getSingletonOpt(match(pat, input));
}
static List tok(String s) {
return s == null ? null : codeTokens(nlTok(s));
}
static List> match(String pat, String input) {
return match(tok(pat), tok(input));
}
static List> match(List pat, List input) {
Map vars = singleCharacterVars(pat);
List> matches = new ArrayList>();
matchImpl(pat, vars, 0, input, 0, new HashMap(), matches);
return matches;
}
static void matchImpl(List pat, Map vars,
int iPat, List input, int iInput, Map values,
List> matches) {
if (iPat >= l(pat)) {
if (iInput < l(input)) return; // fail, too much input
//print("Match! " + struct(values));
matches.add(cloneMap(values));
return;
}
if (iInput >= l(input)) return; // out of input
String t = pat.get(iPat);
String var = vars.get(iPat);
if (var != null) {
// it's a variable, try different lengths of input as match
for (int jInput = iInput+1; jInput <= l(input); jInput++) {
String value = join(" ", subList(input, iInput, jInput));
String oldValue = values.get(var);
if (oldValue != null && !eqic(value, oldValue)) return; // fail, bad multi-assignment
if (oldValue == null)
values.put(var, value);
// proceed
matchImpl(pat, vars, iPat+1, input, jInput, values, matches);
// delete assignment
if (oldValue == null) values.remove(var); else values.put(var, oldValue);
}
} else {
// it's a literal
if (!eqic(t, input.get(iInput))) return; // fail
// match, proceed
matchImpl(pat, vars, iPat+1, input, iInput+1, values, matches);
}
}
static Map singleCharacterVars(List tok) {
Map vars = new HashMap();
for (int i = 0; i < l(tok); i++) {
String t = tok.get(i);
if (l(t) == 1 && isUpperCaseLetter(t.charAt(0)))
vars.put(i, t);
}
return vars;
}
static List> mapReplaceVars(List> patterns, final Map map) {
return map(new Object() { Object get(List pat) { return replaceVars(pat, map) ; }
public String toString() { return "replaceVars(pat, map)"; }}, patterns);
}
static List replaceVars(List tok, final Map map) {
return flattenList(map(tok, new Object() { Object get(String t) { return or((Object) tok(map.get(t)), t) ; }
public String toString() { return "or((O) tok(map.get(t)), t)"; }}));
}
static String struct(Object o) {
return structure(o);
}
static ArrayList ll(A... a) {
return litlist(a);
}
static boolean isUpperCaseLetter(char c) {
return Character.isUpperCase(c);
}
static void psl(Object o) {
print(structureLines(o));
}
static void psl(String indent, Object o) {
printIndent(indent, structureLines(o));
}
static Map mergeMappings(Map a, Map b) {
for (A var : keys(a))
if (b.containsKey(var) && neq(a.get(var), b.get(var))) return null; // fail
return mergeMaps(a, b);
}
static int indexOfSubList(List x, List y) {
return indexOfSubList(x, y, 0);
}
static int indexOfSubList(List x, List y, int i) {
outer: for (; i+l(y) <= l(x); i++) {
for (int j = 0; j < l(y); j++)
if (neq(x.get(i+j), y.get(j)))
continue outer;
return i;
}
return -1;
}
static ArrayList asList(A[] a) {
return new ArrayList (Arrays.asList(a));
}
static ArrayList asList(int[] a) {
ArrayList l = new ArrayList();
for (int i : a) l.add(i);
return l;
}
static ArrayList asList(Iterable s) {
if (s instanceof ArrayList) return (ArrayList) s;
ArrayList l = new ArrayList();
if (s != null)
for (A a : s)
l.add(a);
return l;
}
static void addIfNotEmpty(List l, String s) {
if (nempty(s))
l.add(s);
}
static void addIfNotEmpty(List l, Map m) {
if (nempty(m))
l.add(m);
}
static void assertTrue(Object o) {
assertEquals(true, o);
}
static boolean assertTrue(String msg, boolean b) {
if (!b)
throw fail(msg);
return b;
}
static boolean assertTrue(boolean b) {
if (!b)
throw fail("oops");
return b;
}
// get purpose 1: access a list/array (safer version of x.get(y))
static A get(List l, int idx) {
return idx >= 0 && idx < l(l) ? l.get(idx) : null;
}
static A get(A[] l, int idx) {
return idx >= 0 && idx < l(l) ? l[idx] : null;
}
// default to false
static boolean get(boolean[] l, int idx) {
return idx >= 0 && idx < l(l) ? l[idx] : false;
}
static Class get_dynamicObject = findClass("DynamicObject");
// get purpose 2: access a field by reflection or a map
static Object get(Object o, String field) {
try {
if (o instanceof Class) return get((Class) o, field);
if (o instanceof Map)
return ((Map) o).get(field);
Field f = getOpt_findField(o.getClass(), field);
if (f != null) {
f.setAccessible(true);
return f.get(o);
}
if (get_dynamicObject != null && get_dynamicObject.isInstance(o))
return call(get_raw(o, "fieldValues"), "get", field);
} catch (Exception e) {
throw asRuntimeException(e);
}
throw new RuntimeException("Field '" + field + "' not found in " + o.getClass().getName());
}
static Object get_raw(Object o, String field) {
try {
Field f = get_findField(o.getClass(), field);
f.setAccessible(true);
return f.get(o);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Object get(Class c, String field) {
try {
Field f = get_findStaticField(c, field);
f.setAccessible(true);
return f.get(null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Field get_findStaticField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field) && (f.getModifiers() & Modifier.STATIC) != 0)
return f;
_c = _c.getSuperclass();
} while (_c != null);
throw new RuntimeException("Static field '" + field + "' not found in " + c.getName());
}
static Field get_findField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field))
return f;
_c = _c.getSuperclass();
} while (_c != null);
throw new RuntimeException("Field '" + field + "' not found in " + c.getName());
}
static String indentx(String s) {
return indentx(indent_default, s);
}
static String indentx(int n, String s) {
return dropSuffix(repeat(' ', n), indent(n, s));
}
static String indentx(String indent, String s) {
return dropSuffix(indent, indent(indent, s));
}
public static String join(String glue, Iterable strings) {
StringBuilder buf = new StringBuilder();
Iterator i = strings.iterator();
if (i.hasNext()) {
buf.append(i.next());
while (i.hasNext())
buf.append(glue).append(i.next());
}
return buf.toString();
}
public static String join(String glue, String[] strings) {
return join(glue, Arrays.asList(strings));
}
public static String join(Iterable strings) {
return join("", strings);
}
public static String join(String[] strings) {
return join("", strings);
}
static List map(Iterable l, Object f) {
return map(f, l);
}
static List map(Object f, Iterable l) {
List x = new ArrayList();
Object mc = mc();
for (Object o : unnull(l))
x.add(callFunction(f, o));
return x;
}
static List map(Object f, Object[] l) {
return map(f, asList(l));
}
static List map(Map map, Object f) {
List x = new ArrayList();
for (Object _e : map.entrySet()) {
Map.Entry e = (Map.Entry) _e;
x.add(callFunction(f, e.getKey(), e.getValue()));
}
return x;
}
static List subList(List l, int startIndex) {
return subList(l, startIndex, l(l));
}
static List subList(List l, int startIndex, int endIndex) {
startIndex = max(0, min(l(l), startIndex));
endIndex = max(0, min(l(l), endIndex));
if (startIndex > endIndex) return litlist();
return l.subList(startIndex, endIndex);
}
static Map cloneMap(Map map) {
if (map == null) return litmap();
// assume mutex is equal to collection, which will be true unless you explicitly pass a mutex to synchronizedList() which no one ever does.
synchronized(map) {
return new HashMap(map);
}
}
static A or(A a, A b) {
return a != null ? a : b;
}
static A getSingletonOpt(List l) {
return l(l) == 1 ? first(l) : null;
}
static List codeTokens(List tok) {
return codeTokensOnly(tok);
}
static boolean nempty(Collection c) {
return !isEmpty(c);
}
static boolean nempty(CharSequence s) {
return !isEmpty(s);
}
static boolean nempty(Object[] o) {
return !isEmpty(o);
}
static boolean nempty(Map m) {
return !isEmpty(m);
}
static boolean nempty(Iterator i) {
return i != null && i.hasNext();
}
static boolean eqic(String a, String b) {
if ((a == null) != (b == null)) return false;
if (a == null) return true;
return a.equalsIgnoreCase(b);
}
static int l(Object[] a) { return a == null ? 0 : a.length; }
static int l(boolean[] a) { return a == null ? 0 : a.length; }
static int l(byte[] a) { return a == null ? 0 : a.length; }
static int l(int[] a) { return a == null ? 0 : a.length; }
static int l(float[] a) { return a == null ? 0 : a.length; }
static int l(char[] a) { return a == null ? 0 : a.length; }
static int l(Collection c) { return c == null ? 0 : c.size(); }
static int l(Map m) { return m == null ? 0 : m.size(); }
static int l(CharSequence s) { return s == null ? 0 : s.length(); }
static int l(Object o) {
return l((List) o); // incomplete
}
static List flattenList(List a) {
List l = new ArrayList();
for (Object x : a)
if (x instanceof List)
l.addAll(flattenList((List) x));
else
l.add(x);
return l;
}
static String str(Object o) {
return String.valueOf(o);
}
static String allToStringWithLineBreaks(List l) {
StringBuilder buf = new StringBuilder();
for (Object o : l)
buf.append(o).append("\n");
return str(buf);
}
static volatile StringBuffer local_log = new StringBuffer(); // not redirected
static volatile StringBuffer print_log = local_log; // might be redirected, e.g. to main bot
// in bytes - will cut to half that
static volatile int print_log_max = 1024*1024;
static volatile int local_log_max = 100*1024;
//static int print_maxLineLength = 0; // 0 = unset
static boolean print_silent; // total mute if set
static void print() {
print("");
}
// slightly overblown signature to return original object...
static A print(A o) {
ping();
if (print_silent) return o;
String s = String.valueOf(o) + "\n";
// TODO if (print_maxLineLength != 0)
StringBuffer loc = local_log;
StringBuffer buf = print_log;
int loc_max = print_log_max;
if (buf != loc && buf != null) {
print_append(buf, s, print_log_max);
loc_max = local_log_max;
}
if (loc != null)
print_append(loc, s, loc_max);
System.out.print(s);
return o;
}
static void print(long l) {
print(String.valueOf(l));
}
static void print(char c) {
print(String.valueOf(c));
}
static void print_append(StringBuffer buf, String s, int max) {
synchronized(buf) {
buf.append(s);
max /= 2;
if (buf.length() > max) try {
int newLength = max/2;
int ofs = buf.length()-newLength;
String newString = buf.substring(ofs);
buf.setLength(0);
buf.append("[...] ").append(newString);
} catch (Exception e) {
buf.setLength(0);
}
}
}
static List nlTok(String s) {
return javaTokPlusPeriod(s);
}
static List toLinesFullTrim(String s) {
List l = toLines(s);
for (ListIterator i = l.listIterator(); i.hasNext(); ) {
String line = i.next().trim();
if (line.length() == 0)
i.remove();
else
i.set(line);
}
return l;
}
static List toLinesFullTrim(File f) {
return toLinesFullTrim(loadTextFile(f));
}
static void printWithAsciiHeading(String heading, Object o) {
printAsciiHeading2(heading);
print(o);
}
static Object first(Object list) {
return ((List) list).isEmpty() ? null : ((List) list).get(0);
}
static A first(List list) {
return list.isEmpty() ? null : list.get(0);
}
static A first(A[] bla) {
return bla == null || bla.length == 0 ? null : bla[0];
}
static A first(Iterable i) {
if (i == null) return null;
Iterator it = i.iterator();
return it.hasNext() ? it.next() : null;
}
static String[] dropFirst(int n, String[] a) {
return drop(n, a);
}
static String[] dropFirst(String[] a) {
return drop(1, a);
}
static Object[] dropFirst(Object[] a) {
return drop(1, a);
}
static List dropFirst(List l) {
return dropFirst(1, l);
}
static List dropFirst(int n, List l) {
return new ArrayList(l.subList(Math.min(n, l.size()), l.size()));
}
static String dropFirst(int n, String s) {
return substring(s, n);
}
static Object callFunction(Object f, Object... args) {
if (f == null) return null;
if (f instanceof Runnable) {
((Runnable) f).run();
return null;
} else if (f instanceof String)
return call(mc(), (String) f, args);
else
return call(f, "get", args);
//else throw fail("Can't call a " + getClassName(f));
}
static void printIndent(Object o) {
print(indentx(str(o)));
}
static void printIndent(String indent, Object o) {
print(indentx(indent, str(o)));
}
static void printIndent(int indent, Object o) {
print(indentx(indent, str(o)));
}
static RuntimeException asRuntimeException(Throwable t) {
return t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
}
static Object mc() {
return getMainClass();
}
static Map mergeMaps(Map ... maps) {
Map map = new HashMap ();
for (Map m : maps)
map.putAll(m);
return map;
}
static boolean neq(Object a, Object b) {
return !eq(a, b);
}
static void printAsciiHeading2(String text) {
print(asciiHeading2(text));
}
static List codeTokensOnly(List tok) {
List l = new ArrayList();
for (int i = 1; i < tok.size(); i += 2)
l.add(tok.get(i));
return l;
}
// currently finds only inner classes of class "main"
// returns null on not found
// this is the simple version that is not case-tolerant
static Class findClass(String name) {
if (!isJavaIdentifier(name)) return null;
try {
return Class.forName("main$" + name);
} catch (ClassNotFoundException e) {
return null;
}
}
static Map litmap(Object... x) {
TreeMap map = new TreeMap();
litmap_impl(map, x);
return map;
}
static void litmap_impl(Map map, Object... x) {
for (int i = 0; i < x.length-1; i += 2)
if (x[i+1] != null)
map.put(x[i], x[i+1]);
}
static RuntimeException fail() {
throw new RuntimeException("fail");
}
static RuntimeException fail(Object msg) {
throw new RuntimeException(String.valueOf(msg));
}
static RuntimeException fail(String msg) {
throw new RuntimeException(unnull(msg));
}
// disabled for now to shorten some programs
/*static RuntimeException fail(S msg, O... args) {
throw new RuntimeException(format(msg, args));
}*/
// This is made for NL parsing.
// It's javaTok extended with "..." token, "$n" and "#n" and
// special quotes (which are converted to normal ones).
static List javaTokPlusPeriod(String s) {
List tok = new ArrayList();
int l = s.length();
int i = 0;
while (i < l) {
int j = i;
char c; String cc;
// scan for whitespace
while (j < l) {
c = s.charAt(j);
cc = s.substring(j, Math.min(j+2, l));
if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
++j;
else if (cc.equals("/*")) {
do ++j; while (j < l && !s.substring(j, Math.min(j+2, l)).equals("*/"));
j = Math.min(j+2, l);
} else if (cc.equals("//")) {
do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0);
} else
break;
}
tok.add(s.substring(i, j));
i = j;
if (i >= l) break;
c = s.charAt(i);
cc = s.substring(i, Math.min(i+2, l));
// scan for non-whitespace
if (c == '\u201C' || c == '\u201D') c = '"'; // normalize quotes
if (c == '\'' || c == '"') {
char opener = c;
++j;
while (j < l) {
char _c = s.charAt(j);
if (_c == '\u201C' || _c == '\u201D') _c = '"'; // normalize quotes
if (_c == opener) {
++j;
break;
} else if (s.charAt(j) == '\\' && j+1 < l)
j += 2;
else
++j;
}
if (j-1 >= i+1) {
tok.add(opener + s.substring(i+1, j-1) + opener);
i = j;
continue;
}
} else if (Character.isJavaIdentifierStart(c))
do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || s.charAt(j) == '\'')); // for things like "this one's"
else if (Character.isDigit(c))
do ++j; while (j < l && Character.isDigit(s.charAt(j)));
else if (cc.equals("[[")) {
do ++j; while (j+1 < l && !s.substring(j, j+2).equals("]]"));
j = Math.min(j+2, l);
} else if (cc.equals("[=") && i+2 < l && s.charAt(i+2) == '[') {
do ++j; while (j+2 < l && !s.substring(j, j+3).equals("]=]"));
j = Math.min(j+3, l);
} else if (s.substring(j, Math.min(j+3, l)).equals("..."))
j += 3;
else if (c == '$' || c == '#')
do ++j; while (j < l && Character.isDigit(s.charAt(j)));
else
++j;
tok.add(s.substring(i, j));
i = j;
}
if ((tok.size() % 2) == 0) tok.add("");
return tok;
}
static String[] drop(int n, String[] a) {
n = Math.min(n, a.length);
String[] b = new String[a.length-n];
System.arraycopy(a, n, b, 0, b.length);
return b;
}
static Object[] drop(int n, Object[] a) {
n = Math.min(n, a.length);
Object[] b = new Object[a.length-n];
System.arraycopy(a, n, b, 0, b.length);
return b;
}
static int indent_default = 2;
static String indent(int indent) {
return repeat(' ', indent);
}
static String indent(int indent, String s) {
return indent(repeat(' ', indent), s);
}
static String indent(String indent, String s) {
return indent + s.replace("\n", "\n" + indent);
}
static String indent(String s) {
return indent(indent_default, s);
}
static List indent(String indent, List lines) {
List l = new ArrayList();
for (String s : lines)
l.add(indent + s);
return l;
}
static Set keys(Map map) {
return map.keySet();
}
static Set keys(Object map) {
return keys((Map) map);
}
static volatile boolean ping_pauseAll;
static int ping_sleep = 100; // poll pauseAll flag every 100
static volatile boolean ping_anyActions;
static Map ping_actions = synchroMap(new WeakHashMap());
// returns true if it did anything
static boolean ping() {
if (ping_pauseAll) {
do
sleep(ping_sleep);
while (ping_pauseAll);
return true;
}
if (ping_anyActions) {
Object action;
synchronized(mc()) {
action = ping_actions.get(currentThread());
if (action instanceof Runnable)
ping_actions.remove(currentThread());
if (ping_actions.isEmpty()) ping_anyActions = false;
}
if (action instanceof Runnable)
((Runnable) action).run();
else if (eq(action, "cancelled"))
throw fail("Thread cancelled.");
}
return false;
}
static String unnull(String s) {
return s == null ? "" : s;
}
static List unnull(List l) {
return l == null ? emptyList() : l;
}
static Iterable unnull(Iterable i) {
return i == null ? emptyList() : i;
}
static Object[] unnull(Object[] a) {
return a == null ? new Object[0] : a;
}
static BitSet unnull(BitSet b) {
return b == null ? new BitSet() : b;
}
static String substring(String s, int x) {
return safeSubstring(s, x);
}
static String substring(String s, int x, int y) {
return safeSubstring(s, x, y);
}
static int min(int a, int b) {
return Math.min(a, b);
}
static long min(long a, long b) {
return Math.min(a, b);
}
static double min(double a, double b) {
return Math.min(a, b);
}
static double min(double[] c) {
double x = Double.MAX_VALUE;
for (double d : c) x = Math.min(x, d);
return x;
}
static byte min(byte[] c) {
byte x = 127;
for (byte d : c) if (d < x) x = d;
return x;
}
static ArrayList litlist(A... a) {
return new ArrayList (Arrays.asList(a));
}
static String repeat(char c, int n) {
n = max(n, 0);
char[] chars = new char[n];
for (int i = 0; i < n; i++)
chars[i] = c;
return new String(chars);
}
static List repeat(A a, int n) {
List l = new ArrayList ();
for (int i = 0; i < n; i++)
l.add(a);
return l;
}
static List toLines(File f) {
return toLines(loadTextFile(f));
}
public static List toLines(String s) {
List lines = new ArrayList();
if (s == null) return lines;
int start = 0;
while (true) {
int i = toLines_nextLineBreak(s, start);
if (i < 0) {
if (s.length() > start) lines.add(s.substring(start));
break;
}
lines.add(s.substring(start, i));
if (s.charAt(i) == '\r' && i+1 < s.length() && s.charAt(i+1) == '\n')
i += 2;
else
++i;
start = i;
}
return lines;
}
private static int toLines_nextLineBreak(String s, int start) {
for (int i = start; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '\r' || c == '\n')
return i;
}
return -1;
}
public static String loadTextFile(String fileName) {
try {
return loadTextFile(fileName, null);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static String loadTextFile(String fileName, String defaultContents) throws IOException {
if (!new File(fileName).exists())
return defaultContents;
FileInputStream fileInputStream = new FileInputStream(fileName);
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");
return loadTextFile(inputStreamReader);
}
public static String loadTextFile(File fileName) {
try {
return loadTextFile(fileName, null);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static String loadTextFile(File fileName, String defaultContents) throws IOException {
try {
return loadTextFile(fileName.getPath(), defaultContents);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static String loadTextFile(Reader reader) throws IOException {
StringBuilder builder = new StringBuilder();
try {
char[] buffer = new char[1024];
int n;
while (-1 != (n = reader.read(buffer)))
builder.append(buffer, 0, n);
} finally {
reader.close();
}
return builder.toString();
}
static int max(int a, int b) {
return Math.max(a, b);
}
static int max(int a, int b, int c) {
return max(max(a, b), c);
}
static long max(int a, long b) {
return Math.max((long) a, b);
}
static long max(long a, long b) {
return Math.max(a, b);
}
static double max(int a, double b) {
return Math.max((double) a, b);
}
static float max(float a, float b) {
return Math.max(a, b);
}
static int max(Collection c) {
int x = Integer.MIN_VALUE;
for (int i : c) x = max(x, i);
return x;
}
static double max(double[] c) {
if (c.length == 0) return Double.MIN_VALUE;
double x = c[0];
for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]);
return x;
}
static byte max(byte[] c) {
byte x = -128;
for (byte d : c) if (d > x) x = d;
return x;
}
static String dropSuffix(String suffix, String s) {
return s.endsWith(suffix) ? s.substring(0, l(s)-l(suffix)) : s;
}
static boolean isEmpty(Collection c) {
return c == null || c.isEmpty();
}
static boolean isEmpty(CharSequence s) {
return s == null || s.length() == 0;
}
static boolean isEmpty(Object[] a) {
return a == null || a.length == 0;
}
static boolean isEmpty(Map map) {
return map == null || map.isEmpty();
}
static A assertEquals(Object x, A y) {
return assertEquals(null, x, y);
}
static A assertEquals(String msg, Object x, A y) {
if (!(x == null ? y == null : x.equals(y)))
throw fail((msg != null ? msg + ": " : "") + structure(x) + " != " + structure(y));
return y;
}
static String structure(Object o) {
HashSet refd = new HashSet();
StringBuilder out = new StringBuilder();
structure_1(out, o, new structure_Data(refd));
return structure_2(str(out), refd);
}
// leave to false, unless unstructure() breaks
static boolean structure_allowShortening = false;
static int structure_shareStringsLongerThan = 20;
static class structure_Data {
int stringSizeLimit;
IdentityHashMap seen = new IdentityHashMap();
HashSet refd;
HashMap strings = new HashMap();
HashSet concepts = new HashSet();
Class conceptClass = findClass("Concept");
structure_Data(HashSet refd) {
this.refd = refd;}
}
static void structure_1(StringBuilder out, Object o, structure_Data d) {
if (o == null) { out.append("null"); return; }
// these are never back-referenced (for readability)
if (o instanceof BigInteger) {
out.append("bigint(").append(o).append(")"); return;
}
if (o instanceof Double) {
out.append("d(").append(quote(str(o))).append(")"); return;
}
if (o instanceof Float) {
out.append("fl ").append(quote(str(o))); return;
}
if (o instanceof Long) {
out.append(o).append("L"); return;
}
if (o instanceof Integer) {
out.append(str(o)); return;
}
if (o instanceof Boolean) {
out.append(((Boolean) o).booleanValue() ? "t" : "f"); return;
}
if (o instanceof Character) {
out.append(quoteCharacter((Character) o)); return;
}
if (o instanceof File) {
out.append("File ").append(quote(((File) o).getPath())); return;
}
// referencable objects follow
Integer ref = d.seen.get(o);
if (ref != null) {
d.refd.add(ref);
out.append("r").append(ref); return;
}
if (o instanceof String && (ref = d.strings.get((String) o)) != null) {
d.refd.add(ref);
out.append("r").append(ref); return;
}
ref = d.seen.size()+1;
d.seen.put(o, ref);
out.append("m").append(ref).append(" "); // marker
if (o instanceof String) {
String s = d.stringSizeLimit != 0 ? shorten((String) o, d.stringSizeLimit) : (String) o;
if (l(s) >= structure_shareStringsLongerThan)
d.strings.put(s, ref);
out.append(quote(s)); return;
}
String name = o.getClass().getName();
if (o instanceof HashSet) {
out.append("hashset ");
structure_1(out, new ArrayList((Set) o), d);
return;
}
if (o instanceof TreeSet) {
out.append("treeset ");
structure_1(out, new ArrayList((Set) o), d);
return;
}
if (o instanceof Collection && neq(name, "main$Concept$RefL")) {
out.append("[");
int l = out.length();
for (Object x : (Collection) o) {
if (out.length() != l) out.append(", ");
structure_1(out, x, d);
}
out.append("]");
return;
}
if (o instanceof Map) {
if (o instanceof HashMap) out.append("hm");
out.append("{");
int l = out.length();
for (Object e : ((Map) o).entrySet()) {
if (out.length() != l) out.append(", ");
structure_1(out, ((Map.Entry) e).getKey(), d);
out.append("=");
structure_1(out, ((Map.Entry) e).getValue(), d);
}
out.append("}");
return;
}
if (o.getClass().isArray()) {
if (o instanceof byte[]) {
out.append("ba ").append(quote(bytesToHex((byte[]) o))); return;
}
int n = Array.getLength(o);
if (o instanceof boolean[]) {
String hex = boolArrayToHex((boolean[]) o);
int i = l(hex);
while (i > 0 && hex.charAt(i-1) == '0' && hex.charAt(i-2) == '0') i -= 2;
out.append("boolarray ").append(n).append(" ").append(quote(substring(hex, 0, i))); return;
}
String atype = "array", sep = ", ";
if (o instanceof int[]) {
//ret "intarray " + quote(intArrayToHex((int[]) o));
atype = "intarray";
sep = " ";
}
out.append(atype).append("{");
for (int i = 0; i < n; i++) {
if (i != 0) out.append(sep);
structure_1(out, Array.get(o, i), d);
}
out.append("}"); return;
}
if (o instanceof Class) {
out.append("class(").append(quote(((Class) o).getName())).append(")"); return;
}
if (o instanceof Throwable) {
out.append("exception(").append(quote(((Throwable) o).getMessage())).append(")"); return;
}
if (o instanceof BitSet) {
BitSet bs = (BitSet) o;
out.append("bitset{");
int l = out.length();
for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
if (out.length() != l) out.append(", ");
out.append(i);
}
out.append("}"); return;
}
// Need more cases? This should cover all library classes...
if (name.startsWith("java.") || name.startsWith("javax.")) {
out.append(str(o)); return;
}
String shortName = o.getClass().getName().replaceAll("^main\\$", "");
if (shortName.equals("Lisp")) {
out.append("l(");
structure_1(out, getOpt(o, "head"), d);
List args = (List) ( getOpt(o, "args"));
if (nempty(args))
for (int i = 0; i < l(args); i++) {
out.append(", ");
Object arg = args.get(i);
// sweet shortening
if (arg != null && eq(arg.getClass().getName(), "main$Lisp") && isTrue(call(arg, "isEmpty")))
arg = get(arg, "head");
structure_1(out, arg, d);
}
out.append(")"); return;
}
Class c = o.getClass();
boolean concept = d.conceptClass != null && d.conceptClass.isInstance(o);
String dynName = shortDynamicClassName(o);
if (concept && !d.concepts.contains(dynName)) {
d.concepts.add(dynName);
out.append("c ");
}
// serialize an object with fields.
// first, collect all fields and values in fv.
TreeMap fv = new TreeMap();
while (c != Object.class) {
for (Field field : c.getDeclaredFields()) {
if ((field.getModifiers() & (Modifier.STATIC | Modifier.TRANSIENT)) != 0)
continue;
String fieldName = field.getName();
Object value;
try {
field.setAccessible(true);
value = field.get(o);
} catch (Exception e) {
value = "?";
}
// omit field "className" if equal to class's name
if (concept && eq(fieldName, "className")
&& eq(value, shortName)) value = null;
// put special cases here...
if (value != null)
fv.put(fieldName, value);
}
c = c.getSuperclass();
}
// Now we have fields & values. Process fieldValues if it's a DynamicObject.
if (o instanceof DynamicObject) {
fv.putAll((Map) fv.get("fieldValues"));
fv.remove("fieldValues");
shortName = dynName;
fv.remove("className");
}
String singleField = fv.size() == 1 ? first(fv.keySet()) : null;
// Render this$1 first because unstructure needs it for constructor call.
out.append(shortName).append("(");
int l = out.length();
if (fv.containsKey("this$1")) {
out.append("this$1=");
structure_1(out, fv.get("this$1"), d);
fv.remove("this$1");
}
// Render the other fields.
for (String fieldName : fv.keySet()) {
if (out.length() != l) out.append(", ");
out.append(fieldName).append("=");
structure_1(out, fv.get(fieldName), d);
}
/*if (structure_allowShortening && singleField != null)
b = b.replaceAll("^" + singleField + "=", ""); // drop field name if only one*/
if (out.length() == l) out.setLength(l-1); // drop "("
else out.append(")");
}
// drop unused markers
static String structure_2(String s, HashSet refd) {
List tok = javaTok(s);
StringBuilder out = new StringBuilder();
for (int i = 1; i < l(tok); i += 2) {
String t = tok.get(i);
if (t.startsWith("m") && isInteger(t.substring(1))
&& !refd.contains(parseInt(t.substring(1))))
continue;
out.append(t).append(tok.get(i+1));
}
return str(out);
}
static Object call(Object o) {
return callFunction(o);
}
// varargs assignment fixer for a single string array argument
static Object call(Object o, String method, String[] arg) {
return call(o, method, new Object[] {arg});
}
static Object call(Object o, String method, Object... args) {
try {
if (o instanceof Class) {
Method m = call_findStaticMethod((Class) o, method, args, false);
m.setAccessible(true);
return m.invoke(null, args);
} else {
Method m = call_findMethod(o, method, args, false);
m.setAccessible(true);
return m.invoke(o, args);
}
} catch (Exception e) {
throw e instanceof RuntimeException ? (RuntimeException) e : new RuntimeException(e);
}
}
static Method call_findStaticMethod(Class c, String method, Object[] args, boolean debug) {
Class _c = c;
while (c != null) {
for (Method m : c.getDeclaredMethods()) {
if (debug)
System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");;
if (!m.getName().equals(method)) {
if (debug) System.out.println("Method name mismatch: " + method);
continue;
}
if ((m.getModifiers() & Modifier.STATIC) == 0 || !call_checkArgs(m, args, debug))
continue;
return m;
}
c = c.getSuperclass();
}
throw new RuntimeException("Method '" + method + "' (static) with " + args.length + " parameter(s) not found in " + _c.getName());
}
static Method call_findMethod(Object o, String method, Object[] args, boolean debug) {
Class c = o.getClass();
while (c != null) {
for (Method m : c.getDeclaredMethods()) {
if (debug)
System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");;
if (m.getName().equals(method) && call_checkArgs(m, args, debug))
return m;
}
c = c.getSuperclass();
}
throw new RuntimeException("Method '" + method + "' (non-static) with " + args.length + " parameter(s) not found in " + o.getClass().getName());
}
private static boolean call_checkArgs(Method m, Object[] args, boolean debug) {
Class>[] types = m.getParameterTypes();
if (types.length != args.length) {
if (debug)
System.out.println("Bad parameter length: " + args.length + " vs " + types.length);
return false;
}
for (int i = 0; i < types.length; i++)
if (!(args[i] == null || isInstanceX(types[i], args[i]))) {
if (debug)
System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]);
return false;
}
return true;
}
// Try to put the structure in multiple lines
// (works for List and Map)
// For other values, defaults to structure()
static String structureLines(Object data) {
if (data instanceof Object[]) data = asList((Object[]) data);
if (data instanceof List) {
List l = new ArrayList();
for (Object x : (List) data)
l.add(structure(x));
return fromLines(l);
}
if (data instanceof Map) {
List l = new ArrayList();
for (Object key : ((Map) data).keySet()) {
Object value = ((Map) data).get(key);
l.add(structure(key) + " = " + structure(value));
}
return fromLines(l);
}
return structure(data);
}
static Object getOpt(Object o, String field) {
if (o instanceof String) o = getBot ((String) o);
if (o == null) return null;
if (o instanceof Class) return getOpt((Class) o, field);
if (o.getClass().getName().equals("main$DynamicObject"))
return ((Map) getOpt_raw(o, "fieldValues")).get(field);
if (o instanceof Map) return ((Map) o).get(field);
return getOpt_raw(o, field);
}
static Object getOpt_raw(Object o, String field) {
try {
Field f = getOpt_findField(o.getClass(), field);
if (f == null) return null;
f.setAccessible(true);
return f.get(o);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Object getOpt(Class c, String field) {
try {
if (c == null) return null;
Field f = getOpt_findStaticField(c, field);
if (f == null) return null;
f.setAccessible(true);
return f.get(null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Field getOpt_findStaticField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field) && (f.getModifiers() & Modifier.STATIC) != 0)
return f;
_c = _c.getSuperclass();
} while (_c != null);
return null;
}
static Field getOpt_findField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field))
return f;
_c = _c.getSuperclass();
} while (_c != null);
return null;
}
// hopefully covers all cases :)
static String safeSubstring(String s, int x, int y) {
if (s == null) return null;
if (x < 0) x = 0;
if (x > s.length()) return "";
if (y < x) y = x;
if (y > s.length()) y = s.length();
return s.substring(x, y);
}
static String safeSubstring(String s, int x) {
return safeSubstring(s, x, l(s));
}
public static String bytesToHex(byte[] bytes) {
return bytesToHex(bytes, 0, bytes.length);
}
public static String bytesToHex(byte[] bytes, int ofs, int len) {
StringBuilder stringBuilder = new StringBuilder(len*2);
for (int i = 0; i < len; i++) {
String s = "0" + Integer.toHexString(bytes[ofs+i]);
stringBuilder.append(s.substring(s.length()-2, s.length()));
}
return stringBuilder.toString();
}
static boolean isInteger(String s) {
return s != null && Pattern.matches("\\-?\\d+", s);
}
static String quote(Object o) {
if (o == null) return "null";
String s = str(o);
return "\"" + s.replace("\\", "\\\\").replace("\"", "\\\"").replace("\r", "\\r").replace("\n", "\\n") + "\"";
}
static String shorten(String s, int max) {
if (s == null) return "";
return s.length() <= max ? s : s.substring(0, Math.min(s.length(), max)) + "...";
}
static String asciiHeading2(String title) {
return asciiHeading(title) + "\n";
}
static Object getBot(String botID) {
return callOpt(getMainBot(), "getBot", botID);
}
static String quoteCharacter(char c) {
if (c == '\'') return "'\\''";
if (c == '\\') return "'\\\\'";
return "'" + c + "'";
}
static String shortDynamicClassName(Object o) {
return shortenClassName(dynamicClassName(o));
}
// extended over Class.isInstance() to handle primitive types
static boolean isInstanceX(Class type, Object arg) {
if (type == boolean.class) return arg instanceof Boolean;
if (type == int.class) return arg instanceof Integer;
if (type == long.class) return arg instanceof Long;
if (type == float.class) return arg instanceof Float;
if (type == short.class) return arg instanceof Short;
if (type == char.class) return arg instanceof Character;
if (type == byte.class) return arg instanceof Byte;
if (type == double.class) return arg instanceof Double;
return type.isInstance(arg);
}
static Thread currentThread() {
return Thread.currentThread();
}
static boolean eq(Object a, Object b) {
if (a == null) return b == null;
if (a.equals(b)) return true;
if (a instanceof BigInteger) {
if (b instanceof Integer) return a.equals(BigInteger.valueOf((Integer) b));
if (b instanceof Long) return a.equals(BigInteger.valueOf((Long) b));
}
return false;
}
static boolean isJavaIdentifier(String s) {
if (s.length() == 0 || !Character.isJavaIdentifierStart(s.charAt(0)))
return false;
for (int i = 1; i < s.length(); i++)
if (!Character.isJavaIdentifierPart(s.charAt(i)))
return false;
return true;
}
static Map synchroMap() {
return synchroHashMap();
}
static Map synchroMap(Map map) {
return Collections.synchronizedMap(map);
}
// replacement for class JavaTok
// maybe incomplete, might want to add floating point numbers
// todo also: extended multi-line strings
static int javaTok_n, javaTok_elements;
static boolean javaTok_opt;
static List javaTok(String s) {
return javaTok(s, null);
}
static List javaTok(String s, List existing) {
++javaTok_n;
int nExisting = javaTok_opt && existing != null ? existing.size() : 0;
List tok = existing != null ? new ArrayList(nExisting) : new ArrayList();
int l = s.length();
int i = 0, n = 0;
while (i < l) {
int j = i;
char c; String cc;
// scan for whitespace
while (j < l) {
c = s.charAt(j);
cc = s.substring(j, Math.min(j+2, l));
if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
++j;
else if (cc.equals("/*")) {
do ++j; while (j < l && !s.substring(j, Math.min(j+2, l)).equals("*/"));
j = Math.min(j+2, l);
} else if (cc.equals("//")) {
do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0);
} else
break;
}
if (n < nExisting && javaTok_isCopyable(existing.get(n), s, i, j))
tok.add(existing.get(n));
else
tok.add(quickSubstring(s, i, j));
++n;
i = j;
if (i >= l) break;
c = s.charAt(i); // cc is not needed in rest of loop body
cc = s.substring(i, Math.min(i+2, l));
// scan for non-whitespace
if (c == '\'' || c == '"') {
char opener = c;
++j;
while (j < l) {
if (s.charAt(j) == opener || s.charAt(j) == '\n') { // end at \n to not propagate unclosed string literal errors
++j;
break;
} else if (s.charAt(j) == '\\' && j+1 < l)
j += 2;
else
++j;
}
} else if (Character.isJavaIdentifierStart(c))
do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || "'".indexOf(s.charAt(j)) >= 0)); // for stuff like "don't"
else if (Character.isDigit(c)) {
do ++j; while (j < l && Character.isDigit(s.charAt(j)));
if (j < l && s.charAt(j) == 'L') ++j; // Long constants like 1L
} else if (cc.equals("[[")) {
do ++j; while (j+1 < l && !s.substring(j, j+2).equals("]]"));
j = Math.min(j+2, l);
} else if (cc.equals("[=") && i+2 < l && s.charAt(i+2) == '[') {
do ++j; while (j+2 < l && !s.substring(j, j+3).equals("]=]"));
j = Math.min(j+3, l);
} else
++j;
if (n < nExisting && javaTok_isCopyable(existing.get(n), s, i, j))
tok.add(existing.get(n));
else
tok.add(quickSubstring(s, i, j));
++n;
i = j;
}
if ((tok.size() % 2) == 0) tok.add("");
javaTok_elements += tok.size();
return tok;
}
static List javaTok(List tok) {
return javaTok(join(tok), tok);
}
static boolean javaTok_isCopyable(String t, String s, int i, int j) {
return t.length() == j-i
&& s.regionMatches(i, t, 0, j-i); // << could be left out, but that's brave
}
static String fromLines(List lines) {
StringBuilder buf = new StringBuilder();
if (lines != null)
for (String line : lines)
buf.append(line).append('\n');
return buf.toString();
}
static String fromLines(String... lines) {
return fromLines(asList(lines));
}
static void sleep(long ms) {
ping();
try {
Thread.sleep(ms);
} catch (Exception e) { throw new RuntimeException(e); }
}
static void sleep() { try {
print("Sleeping.");
synchronized(main.class) { main.class.wait(); }
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
static List emptyList() {
return new ArrayList();
//ret Collections.emptyList();
}
static Class getMainClass() { try {
return main.class;
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
static Class getMainClass(Object o) { try {
return (o instanceof Class ? (Class) o : o.getClass()).getClassLoader().loadClass("main");
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
static int parseInt(String s) {
return empty(s) ? 0 : Integer.parseInt(s);
}
// hmm, this shouldn't call functions really. That was just
// for coroutines.
static boolean isTrue(Object o) {
if (o instanceof Boolean)
return ((Boolean) o).booleanValue();
if (o == null) return false;
return ((Boolean) callF(o)).booleanValue();
}
static boolean isTrue(Object pred, Object arg) {
return booleanValue(callF(pred, arg));
}
static String boolArrayToHex(boolean[] a) {
return bytesToHex(boolArrayToBytes(a));
}
static Object callF(Object f, Object... args) {
return callFunction(f, args);
}
static String asciiHeading(String title) {
return "\n" + title + "\n" + rep(l(title), '-');
}
static byte[] boolArrayToBytes(boolean[] a) {
byte[] b = new byte[(l(a)+7)/8];
for (int i = 0; i < l(a); i++)
if (a[i])
b[i/8] |= 1 << (i & 7);
return b;
}
static String shortenClassName(String name) {
return name == null ? null : substring(name, xIndexOf(name, '$')+1);
}
static String quickSubstring(String s, int i, int j) {
if (i == j) return "";
return s.substring(i, j);
}
static Object mainBot;
static Object getMainBot() {
return mainBot;
}
static boolean empty(Collection c) {
return isEmpty(c);
}
static boolean empty(String s) {
return isEmpty(s);
}
static boolean empty(Map map) {
return map == null || map.isEmpty();
}
static boolean empty(Object[] o) {
return o == null || o.length == 0;
}
static boolean empty(Object o) {
if (o instanceof Collection) return empty((Collection) o);
if (o instanceof String) return empty((String) o);
if (o instanceof Map) return empty((Map) o);
if (o instanceof Object[]) return empty((Object[]) o);
throw fail("unknown type for 'empty': " + getType(o));
}
static boolean booleanValue(Object o) {
return eq(true, o);
}
static Object callOpt(Object o) {
if (o == null) return null;
return callF(o);
}
static Object callOpt(Object o, String method, Object... args) {
try {
if (o == null) return null;
if (o instanceof Class) {
Method m = callOpt_findStaticMethod((Class) o, method, args, false);
if (m == null) return null;
m.setAccessible(true);
return m.invoke(null, args);
} else {
Method m = callOpt_findMethod(o, method, args, false);
if (m == null) return null;
m.setAccessible(true);
return m.invoke(o, args);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Method callOpt_findStaticMethod(Class c, String method, Object[] args, boolean debug) {
Class _c = c;
while (c != null) {
for (Method m : c.getDeclaredMethods()) {
if (debug)
System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");;
if (!m.getName().equals(method)) {
if (debug) System.out.println("Method name mismatch: " + method);
continue;
}
if ((m.getModifiers() & Modifier.STATIC) == 0 || !callOpt_checkArgs(m, args, debug))
continue;
return m;
}
c = c.getSuperclass();
}
return null;
}
static Method callOpt_findMethod(Object o, String method, Object[] args, boolean debug) {
Class c = o.getClass();
while (c != null) {
for (Method m : c.getDeclaredMethods()) {
if (debug)
System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");;
if (m.getName().equals(method) && callOpt_checkArgs(m, args, debug))
return m;
}
c = c.getSuperclass();
}
return null;
}
private static boolean callOpt_checkArgs(Method m, Object[] args, boolean debug) {
Class>[] types = m.getParameterTypes();
if (types.length != args.length) {
if (debug)
System.out.println("Bad parameter length: " + args.length + " vs " + types.length);
return false;
}
for (int i = 0; i < types.length; i++)
if (!(args[i] == null || isInstanceX(types[i], args[i]))) {
if (debug)
System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]);
return false;
}
return true;
}
static String dynamicClassName(Object o) {
if (o instanceof DynamicObject && ((DynamicObject) o).className != null)
return "main$" + ((DynamicObject) o).className;
return className(o);
}
static Map synchroHashMap() {
return Collections.synchronizedMap(new HashMap());
}
// returns l(s) if not found
static int xIndexOf(String s, String sub, int i) {
if (s == null) return 0;
i = s.indexOf(sub, min(i, l(s)));
return i >= 0 ? i : l(s);
}
static int xIndexOf(String s, String sub) {
return xIndexOf(s, sub, 0);
}
static int xIndexOf(String s, char c) {
if (s == null) return 0;
int i = s.indexOf(c);
return i >= 0 ? i : l(s);
}
static String getType(Object o) {
return getClassName(o);
}
static String className(Object o) {
return getClassName(o);
}
static String rep(int n, char c) {
return repeat(c, n);
}
static String rep(char c, int n) {
return repeat(c, n);
}
static List rep(A a, int n) {
return repeat(a, n);
}
static String getClassName(Object o) {
return o == null ? "null" : o.getClass().getName();
}
static boolean DynamicObject_loading;
static class DynamicObject {
String className; // just the name, without the "main$"
Map fieldValues = new TreeMap();
DynamicObject() {}
// className = just the name, without the "main$"
DynamicObject(String className) {
this.className = className;}
}
// you still need to implement hasNext() and next()
static abstract class IterableIterator implements Iterator , Iterable {
public Iterator iterator() {
return this;
}
public void remove() {
unsupportedOperation();
}
}
static UnsupportedOperationException unsupportedOperation() {
throw new UnsupportedOperationException();
}
static void typeWriterConsole() {
if (isHeadless()) return;
Font f = typeWriterFont();
consoleFont(f);
consoleInputFont(f);
}
static Font typeWriterFont() {
return typeWriterFont(14);
}
static Font typeWriterFont(int size) {
return new Font("Courier", Font.PLAIN, size);
}
static Boolean isHeadless_cache;
static boolean isHeadless() {
if (isHeadless_cache != null) return isHeadless_cache;
if (GraphicsEnvironment.isHeadless()) return isHeadless_cache = true;
// Also check if AWT actually works.
// If DISPLAY variable is set but no X server up, this will notice.
try {
isAWTThread();
return isHeadless_cache = false;
} catch (Throwable _e) { return isHeadless_cache = true; }
}
static void consoleFont(Font font) {
callOpt(getConsoleTextArea_gen(), "setFont", font);
}
static void consoleInputFont(Font f) {
JTextField input = consoleInputField();
if (input != null) {
input.setFont(f);
revalidateFrame(input);
}
}
static boolean isAWTThread() {
return SwingUtilities.isEventDispatchThread();
}
static Object getConsoleTextArea_gen() {
return getOpt(get(getJavaX(), "console"), "textArea");
}
static void revalidateFrame(Component c) {
revalidate(getFrame(c));
}
static JTextField consoleInputField() {
return (JTextField) getOpt(get(getJavaX(), "console"), "tfInput");
}
static Class __javax;
static Class getJavaX() {
return __javax;
}
static void revalidate(Component c) {
if (c == null || !c.isShowing()) return;
// magic combo to actually relayout and repaint
c.revalidate();
c.repaint();
}
static JFrame getFrame(Object o) {
if (!(o instanceof Component)) return null;
Component c = (Component) o;
while (c != null) {
if (c instanceof JFrame) return (JFrame) c;
c = c.getParent();
}
return null;
}
}