Warning: session_start(): open(/var/lib/php/sessions/sess_61nl8uvmq7qpgqt3nr5jedm67c, 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.math.*;
import javax.imageio.*;
import java.awt.image.*;
import java.awt.event.*;
import java.awt.*;
import java.security.spec.*;
import java.security.*;
import java.lang.management.*;
import java.lang.ref.*;
import java.lang.reflect.*;
import java.net.*;
import java.io.*;
import javax.swing.table.*;
import javax.swing.text.*;
import javax.swing.event.*;
import javax.swing.*;
import java.util.concurrent.atomic.*;
import java.util.concurrent.*;
import java.util.regex.*;
import java.util.List;
import java.util.zip.*;
import java.util.*;
public class main {
static class TableFinder {
List tok; // list of tokens in HTML document
List table; // list of tokens in table
List> rows; // for every row, list of tokens in row
List> data; // for every row, for every cell, inner data
void go(String html) {
tok = htmlcoarsetok(html);
findTable();
}
void findTable() {
print("Finding table.");
for (int i = 1; i < tok.size(); i += 2)
if (isTag(tok.get(i), "table"))
for (int j = i+2; j < tok.size(); j += 2)
if (isTag(tok.get(j), "/table")) {
print("Table found!");
table = tok.subList(i-1, j+2);
findRows();
return;
}
}
void findRows() {
List tok = table;
rows = new ArrayList>();
data = new ArrayList>();
int rowStart = 0;
for (int i = 1; i < table.size(); i += 2) {
//print(tok.get(i));
if (isTag(tok.get(i), "tr"))
rowStart = i;
else if (isTag(tok.get(i), "/tr") && rowStart != 0) {
List row = table.subList(rowStart-1, i+2);
rows.add(row);
data.add(getData(row));
}
}
print(rows.size() + " row(s)");
print("Top left cell: " + data.get(0).get(0));
}
boolean isTag(String token, String tag) {
return token.regionMatches(true, 0, "<" + tag + " ", 0, tag.length()+2)
|| token.regionMatches(true, 0, "<" + tag + ">", 0, tag.length()+2);
}
// called internally
List getData(List row) {
int colStart = 0;
List cols = new ArrayList();
for (int i = 1; i < row.size(); i += 2) {
String t = row.get(i);
if (isTag(t, "td") || isTag(t, "th"))
colStart = i;
else if ((isTag(t, "/td") || isTag(t, "/th")) && colStart != 0)
cols.add(join(row.subList(colStart+1, i)));
}
return cols;
}
// for clients
List getRow(int row) {
return data.get(row);
}
}
// TableFinder
static String html(String subUri) {
List tok = javaTok(subUri);
int i = matchMeta(tok, "/", "");
// single post
if (i == 1) {
String postID = "#" + tok.get(3);
String title = getSnippetTitle(postID);
return fromLines(litlist(
"" + title + "
",
"",
loadSnippet(postID)));
}
// headlines
List headlines;
headlines = litlist("Line A", "Headline B", "Headline C");
try { headlines = getLatestHeadlines(); } catch (Throwable __e) { __e.printStackTrace(); }
return join("
", headlines);
}
static List getLatestHeadlines() {
String html = loadPage("http://tinybrain.de:8080/tb/snippets.php?type=49");
TableFinder finder = new TableFinder();
finder.go(html);
List l = new ArrayList();
for (int i = 1; i < finder.data.size(); i++) {
List row = finder.getRow(i);
String title = dropAllTags(row.get(0));
String id = dropAllTags(row.get(1));
//S link = "http://tinybrain.de/" + parseSnippetID(id);
String link = "/" + parseSnippetID(getProgramID()) + "/raw/" + parseSnippetID(id);
l.add("" + htmlencode(title) + "");
}
return l;
}
static int matchMeta(List tok, String... tokens) {
outer: for (int i = 1; i+l(tokens)*2-2 < l(tok); i += 2) {
for (int j = 0; j < l(tokens); j++) {
String p = tokens[j];
String t = tok.get(i+j*2);
boolean ok;
if (eq(p, ""))
ok = isInteger(t);
else if (eq(p, "*"))
ok = true;
else
ok = eq(p, t);
if (!ok)
continue outer;
}
return i;
}
return -1;
}
static String htmlQuote(String s) {
return "\"" + htmlencode(s) + "\"";
}
static String htmlencode(Object o) {
return htmlencode(string(o));
}
static String htmlencode(String s) {
if (s == null) return "";
StringBuilder out = new StringBuilder(Math.max(16, s.length()));
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c > 127 || c == '"' || c == '<' || c == '>' || c == '&') {
out.append("");
out.append((int) c);
out.append(';');
} else {
out.append(c);
}
}
return out.toString();
}
static boolean isTag(String token, String tag) {
return token.regionMatches(true, 0, "<" + tag + " ", 0, tag.length()+2)
|| token.regionMatches(true, 0, "<" + tag + ">", 0, tag.length()+2);
}
static String programID;
static String getProgramID() {
return programID;
}
// TODO: ask JavaX instead
static String getProgramID(Class c) {
return or((String) getOpt(c, "programID"), "?");
}
static ArrayList litlist(A... a) {
return new ArrayList(Arrays.asList(a));
}
static String getSnippetTitle(String id) { try {
return loadPage(new URL("http://tinybrain.de:8080/tb-int/getfield.php?id=" + parseSnippetID(id) + "&field=title"));
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
// tok should be the output of htmlcoarsetok
static List dropAllTags(List tok) {
List list = new ArrayList();
for (int i = 0; i < tok.size(); i++) {
String t = tok.get(i);
if (t.startsWith("<")) {
list.set(list.size()-1, list.get(list.size()-1) + tok.get(i+1));
++i;
} else
list.add(tok.get(i));
}
return list;
}
// alternatively, call this convenient function
static String dropAllTags(String html) {
return join(dropAllTags(htmlcoarsetok(html)));
}
// replacement for class JavaTok
// maybe incomplete, might want to add floating point numbers
// todo also: extended multi-line strings
static List javaTok(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 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) {
++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)));
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
++j;
tok.add(s.substring(i, j));
i = j;
}
if ((tok.size() % 2) == 0) tok.add("");
return tok;
}
static List javaTok(List tok) {
return javaTok(join(tok));
}
// TODO: process CDATA?
static List htmlcoarsetok(String s) {
List tok = new ArrayList();
int l = s.length();
int i = 0;
while (i < l) {
int j = i;
char c;
// scan for non-tags
while (j < l) {
if (s.charAt(j) != '<')
// regular character
++j;
else if (s.substring(j, Math.min(j+4, l)).equals(""));
j = Math.min(j+3, l);
} else
// it's a tag
break;
}
tok.add(s.substring(i, j));
i = j;
if (i >= l) break;
c = s.charAt(i);
// scan for tags
if (c == '<') {
++j;
while (j < l && s.charAt(j) != '>') ++j; // TODO: strings?
if (j < l) ++j;
}
tok.add(s.substring(i, j));
i = j;
}
if ((tok.size() % 2) == 0) tok.add("");
return tok;
}
static StringBuffer print_log;
static void print() {
print("");
}
static void print(Object o) {
String s = String.valueOf(o) + "\n";
synchronized(StringBuffer.class) {
if (print_log == null) print_log = new StringBuffer();
}
print_log.append(s);
System.out.print(s);
}
static void print(long l) {
print(String.valueOf(l));
}
public static String fromLines(List lines) {
StringBuilder buf = new StringBuilder();
for (String line : lines) {
buf.append(line).append('\n');
}
return buf.toString();
}
static boolean preferCached = false;
public static String loadSnippet(String snippetID) {
try {
return loadSnippet(parseSnippetID(snippetID), preferCached);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static String loadSnippet(String snippetID, boolean preferCached) throws IOException {
return loadSnippet(parseSnippetID(snippetID), preferCached);
}
public static String loadSnippet(long snippetID, boolean preferCached) throws IOException {
String text = getSnippetFromBossBot(snippetID);
if (text != null) return text;
initSnippetCache();
text = DiskSnippetCache_get(snippetID);
if (preferCached && text != null)
return text;
try {
if (text != null) System.err.println("md5: " + md5(text));
URL url = new URL("http://tinybrain.de:8080/getraw.php?id=" + snippetID + "&utf8=1");
text = loadPage(url);
} catch (RuntimeException e) {
e.printStackTrace();
throw new IOException("Snippet #" + snippetID + " not found or not public");
}
try {
initSnippetCache();
DiskSnippetCache_put(snippetID, text);
} catch (IOException e) {
System.err.println("Minor warning: Couldn't save snippet to cache (" + DiskSnippetCache_getDir() + ")");
}
return text;
}
static File DiskSnippetCache_dir;
public static void initDiskSnippetCache(File dir) {
DiskSnippetCache_dir = dir;
dir.mkdirs();
}
public static synchronized String DiskSnippetCache_get(long snippetID) throws IOException {
return loadTextFile(DiskSnippetCache_getFile(snippetID).getPath(), null);
}
private static File DiskSnippetCache_getFile(long snippetID) {
return new File(DiskSnippetCache_dir, "" + snippetID);
}
public static synchronized void DiskSnippetCache_put(long snippetID, String snippet) throws IOException {
saveTextFile(DiskSnippetCache_getFile(snippetID).getPath(), snippet);
}
public static File DiskSnippetCache_getDir() {
return DiskSnippetCache_dir;
}
public static void initSnippetCache() {
if (DiskSnippetCache_dir == null)
initDiskSnippetCache(new File(System.getProperty("user.home"), ".tinybrain/snippet-cache"));
}
public static String loadPageSilently(String url) {
try {
return loadPageSilently(new URL(loadPage_preprocess(url)));
} catch (IOException e) { throw new RuntimeException(e); }
}
public static String loadPageSilently(URL url) {
try {
IOException e = null;
for (int tries = 0; tries < 5; tries++)
try {
URLConnection con = url.openConnection();
return loadPage(con, url);
} catch (IOException _e) {
e = _e;
print("Retrying because of: " + e);
}
throw e;
} catch (IOException e) { throw new RuntimeException(e); }
}
static String loadPage_preprocess(String url) {
if (url.startsWith("tb/"))
url = "tinybrain.de:8080/" + url;
if (url.indexOf("://") < 0)
url = "http://" + url;
return url;
}
public static String loadPage(String url) {
try {
return loadPage(new URL(loadPage_preprocess(url)));
} catch (IOException e) { throw new RuntimeException(e); }
}
public static String loadPage(URL url) {
print("Loading: " + url.toExternalForm());
return loadPageSilently(url);
}
public static String loadPage(URLConnection con, URL url) throws IOException {
String contentType = con.getContentType();
if (contentType == null)
throw new IOException("Page could not be read: " + url);
//Log.info("Content-Type: " + contentType);
String charset = loadPage_guessCharset(contentType);
Reader r = new InputStreamReader(con.getInputStream(), charset);
StringBuilder buf = new StringBuilder();
while (true) {
int ch = r.read();
if (ch < 0)
break;
//Log.info("Chars read: " + buf.length());
buf.append((char) ch);
}
return buf.toString();
}
static String loadPage_guessCharset(String contentType) {
Pattern p = Pattern.compile("text/html;\\s+charset=([^\\s]+)\\s*");
Matcher m = p.matcher(contentType);
/* If Content-Type doesn't match this pre-conception, choose default and hope for the best. */
return m.matches() ? m.group(1) : "ISO-8859-1";
}
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);
}
public static long parseSnippetID(String snippetID) {
long id = Long.parseLong(shortenSnippetID(snippetID));
if (id == 0) fail("0 is not a snippet ID");
return id;
}
static String string(Object o) {
return String.valueOf(o);
}
static String or(String a, String b) {
return a != null ? a : b;
}
static int l(Object[] array) {
return array == null ? 0 : array.length;
}
static int l(List list) {
return list == null ? 0 : list.size();
}
static int l(String s) {
return s == null ? 0 : s.length();
}
static String getSnippetFromBossBot(long snippetID) {
return boss(format3("get text for *", snippetID));
}
static Object getOpt(Object o, String field) {
if (o == null) return null;
if (o instanceof Class) return getOpt((Class) o, field);
if (o.getClass().getName().equals("main$DynamicObject"))
return call(getOpt_raw(o, "fieldValues"), "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 {
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) {
for (Field f : c.getDeclaredFields())
if (f.getName().equals(field) && (f.getModifiers() & Modifier.STATIC) != 0)
return f;
return null;
}
static Field getOpt_findField(Class> c, String field) {
for (Field f : c.getDeclaredFields())
if (f.getName().equals(field))
return f;
return null;
}
static boolean eq(Object a, Object b) {
return a == null ? b == null : a.equals(b);
}
static String md5(String text) { try {
if (text == null) return "-";
return bytesToHex(md5_impl(text.getBytes("UTF-8"))); // maybe different than the way PHP does it...
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
static String md5(byte[] data) {
return bytesToHex(md5_impl(data));
}
static byte[] md5_impl(byte[] data) {
try {
return MessageDigest.getInstance("MD5").digest(data);
} catch (Exception e) { throw e instanceof RuntimeException ? (RuntimeException) e : new RuntimeException(e); }
}
static String md5(File file) { try {
return md5(loadBinaryFile(file));
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
/** writes safely (to temp file, then rename) */
public static void saveTextFile(String fileName, String contents) throws IOException {
File file = new File(fileName);
File parentFile = file.getParentFile();
if (parentFile != null)
parentFile.mkdirs();
String tempFileName = fileName + "_temp";
if (contents != null) {
FileOutputStream fileOutputStream = new FileOutputStream(tempFileName);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, "UTF-8");
PrintWriter printWriter = new PrintWriter(outputStreamWriter);
printWriter.print(contents);
printWriter.close();
}
if (file.exists() && !file.delete())
throw new IOException("Can't delete " + fileName);
if (contents != null)
if (!new File(tempFileName).renameTo(file))
throw new IOException("Can't rename " + tempFileName + " to " + fileName);
}
public static void saveTextFile(File fileName, String contents) {
try {
saveTextFile(fileName.getPath(), contents);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
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 RuntimeException fail() {
throw new RuntimeException("fail");
}
static RuntimeException fail(Object msg) {
throw new RuntimeException(String.valueOf(msg));
}
static boolean isInteger(String s) {
return s != null && Pattern.matches("\\-?\\d+", s);
}
static String shortenSnippetID(String snippetID) {
if (snippetID.startsWith("#"))
snippetID = snippetID.substring(1);
String httpBlaBla = "http://tinybrain.de/";
if (snippetID.startsWith(httpBlaBla))
snippetID = snippetID.substring(httpBlaBla.length());
return snippetID;
}
static String boss(String line) {
try {
//S s = sendToLocalBotOpt("Boss Bot", line);
DialogIO io = talkTo(4990); // Boss Bot port
io.readLine();
io.sendLine(line);
String s = io.readLine();
Matches m = new Matches();
if (match3("text: *", s, m))
return unquote(m.m[0]);
return null;
} catch (Exception e) {
//e.printStackTrace();
return null;
}
}
static String format3(String pat, Object... args) {
if (args.length == 0) return pat;
List tok = javaTokPlusPeriod(pat);
int argidx = 0;
for (int i = 1; i < tok.size(); i += 2)
if (tok.get(i).equals("*"))
tok.set(i, format3_formatArg(argidx < args.length ? args[argidx++] : "null"));
return join(tok);
}
static String format3_formatArg(Object arg) {
if (arg == null) return "null";
if (arg instanceof String) {
String s = (String) arg;
return isIdentifier(s) ? s : quote(s);
}
if (arg instanceof Integer || arg instanceof Long) return String.valueOf(arg);
return quote(structure(arg));
}
public static byte[] loadBinaryFile(String fileName) throws IOException {
if (!new File(fileName).exists())
return null;
FileInputStream in = new FileInputStream(fileName);
byte buf[] = new byte[1024];
ByteArrayOutputStream out = new ByteArrayOutputStream();
int l;
while (true) {
l = in.read(buf);
if (l <= 0) break;
out.write(buf, 0, l);
}
in.close();
return out.toByteArray();
}
public static byte[] loadBinaryFile(File file) throws IOException {
return loadBinaryFile(file.getPath());
}
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();
}
// 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;
}
static boolean isIdentifier(String s) {
return isJavaIdentifier(s);
}
static String quote(String s) {
if (s == null) return "null";
return "\"" + s.replace("\\", "\\\\").replace("\"", "\\\"").replace("\r", "\\r").replace("\n", "\\n") + "\"";
}
static String quote(long l) {
return quote("" + l);
}
static class Matches {
String[] m;
String get(int i) { return m[i]; }
String unq(int i) { return unquote(m[i]); }
String fsi(int i) { return formatSnippetID(unq(i)); }
boolean bool(int i) { return "true".equals(unq(i)); }
String rest() { return m[m.length-1]; } // for matchStart
}
// class Matches
static boolean match3(String pat, String s) {
return match3(pat, s, null);
}
static boolean match3(String pat, String s, Matches matches) {
if (s == null) return false;
return match3(pat, parse3(s), matches);
}
static boolean match3(String pat, List toks, Matches matches) {
List tokpat = parse3(pat);
String[] m = match2(tokpat, toks);
//print(structure(tokpat) + " on " + structure(toks) + " => " + structure(m));
if (m == null)
return false;
else {
if (matches != null) matches.m = m;
return true;
}
}
static abstract class DialogIO {
String line;
boolean eos;
abstract String readLineImpl();
abstract boolean isStillConnected();
abstract void sendLine(String line);
abstract boolean isLocalConnection();
abstract Socket getSocket();
abstract void close();
int getPort() { return getSocket().getPort(); }
boolean helloRead;
String readLineNoBlock() {
String l = line;
line = null;
return l;
}
boolean waitForLine() { try {
if (line != null) return true;
//print("Readline");
line = readLineImpl();
//print("Readline done: " + line);
if (line == null) eos = true;
return line != null;
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
String readLine() {
waitForLine();
helloRead = true;
return readLineNoBlock();
}
String ask(String s, Object... args) {
if (!helloRead) readLine();
if (args.length != 0) s = format3(s, args);
sendLine(s);
return readLine();
}
String askLoudly(String s, Object... args) {
if (!helloRead) readLine();
if (args.length != 0) s = format3(s, args);
print("> " + s);
sendLine(s);
String answer = readLine();
print("< " + answer);
return answer;
}
void pushback(String l) {
if (line != null)
fail();
line = l;
helloRead = false;
}
}
static abstract class DialogHandler {
abstract void run(DialogIO io);
} // DialogIO
static DialogIO talkTo(int port) {
return talkTo("localhost", port);
}
static DialogIO talkTo(String ip, int port) { try {
final Socket s = new Socket(ip, port);
print("Talking to " + ip + ":" + port);
final Writer w = new OutputStreamWriter(s.getOutputStream(), "UTF-8");
final BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream(), "UTF-8"));
return new DialogIO() {
boolean isLocalConnection() {
return s.getInetAddress().isLoopbackAddress();
}
boolean isStillConnected() {
return !(eos || s.isClosed());
}
void sendLine(String line) { try {
w.write(line + "\n");
w.flush();
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
String readLineImpl() { try {
return in.readLine();
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
void close() {
try {
s.close();
} catch (IOException e) {
// whatever
}
}
Socket getSocket() {
return s;
}
};
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
// 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;
return type.isInstance(arg);
}
// This is made for NL parsing.
// It's javaTok extended with "..." token, "$n" and "#n"
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 == '\'' || c == '"') {
char opener = c;
++j;
while (j < l) {
if (s.charAt(j) == opener) {
++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)) || 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 (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;
}
public static String unquote(String s) {
if (s.startsWith("[")) {
int i = 1;
while (i < s.length() && s.charAt(i) == '=') ++i;
if (i < s.length() && s.charAt(i) == '[') {
String m = s.substring(1, i);
if (s.endsWith("]" + m + "]"))
return s.substring(i+1, s.length()-i-1);
}
}
if (s.startsWith("\"") && s.endsWith("\"") && s.length() > 1) {
String st = s.substring(1, s.length()-1);
StringBuilder sb = new StringBuilder(st.length());
for (int i = 0; i < st.length(); i++) {
char ch = st.charAt(i);
if (ch == '\\') {
char nextChar = (i == st.length() - 1) ? '\\' : st
.charAt(i + 1);
// Octal escape?
if (nextChar >= '0' && nextChar <= '7') {
String code = "" + nextChar;
i++;
if ((i < st.length() - 1) && st.charAt(i + 1) >= '0'
&& st.charAt(i + 1) <= '7') {
code += st.charAt(i + 1);
i++;
if ((i < st.length() - 1) && st.charAt(i + 1) >= '0'
&& st.charAt(i + 1) <= '7') {
code += st.charAt(i + 1);
i++;
}
}
sb.append((char) Integer.parseInt(code, 8));
continue;
}
switch (nextChar) {
case '\\':
ch = '\\';
break;
case 'b':
ch = '\b';
break;
case 'f':
ch = '\f';
break;
case 'n':
ch = '\n';
break;
case 'r':
ch = '\r';
break;
case 't':
ch = '\t';
break;
case '\"':
ch = '\"';
break;
case '\'':
ch = '\'';
break;
// Hex Unicode: u????
case 'u':
if (i >= st.length() - 5) {
ch = 'u';
break;
}
int code = Integer.parseInt(
"" + st.charAt(i + 2) + st.charAt(i + 3)
+ st.charAt(i + 4) + st.charAt(i + 5), 16);
sb.append(Character.toChars(code));
i += 5;
continue;
default:
ch = nextChar; // added by Stefan
}
i++;
}
sb.append(ch);
}
return sb.toString();
} else
return s; // return original
}
static String structure(Object o) {
return structure(o, 0);
}
// leave to false, unless unstructure() breaks
static boolean structure_allowShortening = false;
static String structure(Object o, int stringSizeLimit) {
if (o == null) return "null";
String name = o.getClass().getName();
StringBuilder buf = new StringBuilder();
if (o instanceof Collection) { // TODO: store the type (e.g. HashSet/TreeSet)
for (Object x : (Collection) o) {
if (buf.length() != 0) buf.append(", ");
buf.append(structure(x, stringSizeLimit));
}
return "[" + buf + "]";
}
if (o instanceof Map) {
for (Object e : ((Map) o).entrySet()) {
if (buf.length() != 0) buf.append(", ");
buf.append(structure(((Map.Entry) e).getKey(), stringSizeLimit));
buf.append("=");
buf.append(structure(((Map.Entry) e).getValue(), stringSizeLimit));
}
return "{" + buf + "}";
}
if (o.getClass().isArray()) {
int n = Array.getLength(o);
for (int i = 0; i < n; i++) {
if (buf.length() != 0) buf.append(", ");
buf.append(structure(Array.get(o, i), stringSizeLimit));
}
return "array{" + buf + "}";
}
if (o instanceof String)
return quote(stringSizeLimit != 0 ? shorten((String) o, stringSizeLimit) : (String) o);
if (o instanceof Class)
return "class(" + quote(((Class) o).getName()) + ")";
if (o instanceof Throwable)
return "exception(" + quote(((Throwable) o).getMessage()) + ")";
// Need more cases? This should cover all library classes...
if (name.startsWith("java.") || name.startsWith("javax."))
return String.valueOf(o);
String shortName = o.getClass().getName().replaceAll("^main\\$", "");
int numFields = 0;
String fieldName = "";
if (shortName.equals("DynamicObject")) {
shortName = (String) get(o, "className");
Map fieldValues = (Map) get(o, "fieldValues");
for (String _fieldName : fieldValues.keySet()) {
fieldName = _fieldName;
Object value = fieldValues.get(fieldName);
if (value != null) {
if (buf.length() != 0) buf.append(", ");
buf.append(fieldName + "=" + structure(value, stringSizeLimit));
}
++numFields;
}
} else {
// regular class
// TODO: go to superclasses too
Field[] fields = o.getClass().getDeclaredFields();
for (Field field : fields) {
if ((field.getModifiers() & Modifier.STATIC) != 0)
continue;
Object value;
try {
field.setAccessible(true);
value = field.get(o);
} catch (Exception e) {
value = "?";
}
fieldName = field.getName();
// put special cases here...
if (value != null) {
if (buf.length() != 0) buf.append(", ");
buf.append(fieldName + "=" + structure(value, stringSizeLimit));
}
++numFields;
}
}
String b = buf.toString();
if (numFields == 1 && structure_allowShortening)
b = b.replaceAll("^" + fieldName + "=", ""); // drop field name if only one
String s = shortName;
if (buf.length() != 0)
s += "(" + b + ")";
return s;
}
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 List parse3(String s) {
return dropPunctuation(javaTokPlusPeriod(s));
}
// match2 matches multiple "*" (matches a single token) wildcards and zero or one "..." wildcards (matches multiple tokens)
static String[] match2(List pat, List tok) {
// standard case (no ...)
int i = pat.indexOf("...");
if (i < 0) return match2_match(pat, tok);
pat = new ArrayList(pat); // We're modifying it, so copy first
pat.set(i, "*");
while (pat.size() < tok.size()) {
pat.add(i, "*");
pat.add(i+1, ""); // doesn't matter
}
return match2_match(pat, tok);
}
static String[] match2_match(List pat, List tok) {
List result = new ArrayList();
if (pat.size() != tok.size()) {
/*if (debug)
print("Size mismatch: " + structure(pat) + " vs " + structure(tok));*/
return null;
}
for (int i = 1; i < pat.size(); i += 2) {
String p = pat.get(i), t = tok.get(i);
/*if (debug)
print("Checking " + p + " against " + t);*/
if ("*".equals(p))
result.add(t);
else if (!p.equalsIgnoreCase(t))
return null;
}
return result.toArray(new String[result.size()]);
}
static Object get(Object o, String field) {
if (o instanceof Class) return get((Class) o, field);
if (o.getClass().getName().equals("main$DynamicObject"))
return call(get_raw(o, "fieldValues"), "get", field);
return get_raw(o, field);
}
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) {
for (Field f : c.getDeclaredFields())
if (f.getName().equals(field) && (f.getModifiers() & Modifier.STATIC) != 0)
return f;
throw new RuntimeException("Static field '" + field + "' not found in " + c.getName());
}
static Field get_findField(Class> c, String field) {
for (Field f : c.getDeclaredFields())
if (f.getName().equals(field))
return f;
throw new RuntimeException("Field '" + field + "' not found in " + c.getName());
}
static String shorten(String s, int max) {
return s.length() <= max ? s : s.substring(0, Math.min(s.length(), max)) + "...";
}
static List dropPunctuation(List tok) {
tok = new ArrayList(tok);
for (int i = 1; i < tok.size(); i += 2) {
String t = tok.get(i);
if (t.length() == 1 && !Character.isLetter(t.charAt(0)) && !Character.isDigit(t.charAt(0)) && !t.equals("*")) {
tok.set(i-1, tok.get(i-1) + tok.get(i+1));
tok.remove(i);
tok.remove(i);
i -= 2;
}
}
return tok;
}
static String dropPunctuation(String s) {
return join(dropPunctuation(nlTok(s)));
}
static List nlTok(String s) {
return javaTokPlusPeriod(s);
}
static Class run(String progID) {
Class main = hotwire(progID);
callMain(main);
return main;
}
static BufferedReader readLine_reader;
static String readLine() {
return (String) call(getJavaX(), "readLine");
}
static String formatSnippetID(String id) {
return "#" + parseSnippetID(id);
}
static String formatSnippetID(long id) {
return "#" + id;
}
static Class __javax;
static Class getJavaX() {
return __javax;
}
static void callMain(Object c, String... args) {
callOpt(c, "main", new Object[] {args});
}
// compile JavaX source, load classes & return main class
// src can be a snippet ID or actual source code
// TODO: record injection?
static Class> hotwire(String src) {
try {
Class j = getJavaX();
synchronized(j) { // hopefully this goes well...
List libraries = new ArrayList();
File srcDir = (File) call(j, "transpileMain", src, libraries);
if (srcDir == null)
fail("transpileMain returned null (src=" + quote(src) + ")");
Object androidContext = get(j, "androidContext");
if (androidContext != null)
return (Class) call(j, "loadx2android", srcDir, src);
File classesDir = (File) call(j, "TempDirMaker_make");
String javacOutput = (String) call(j, "compileJava", srcDir, libraries, classesDir);
System.out.println(javacOutput);
URL[] urls = new URL[libraries.size()+1];
urls[0] = classesDir.toURI().toURL();
for (int i = 0; i < libraries.size(); i++)
urls[i+1] = libraries.get(i).toURI().toURL();
// make class loader
URLClassLoader classLoader = new URLClassLoader(urls);
// load & return main class
Class> theClass = classLoader.loadClass("main");
call(j, "setVars", theClass, isSnippetID(src) ? src: null);
if (isSnippetID(src))
callOpt(j, "addInstance", src, theClass);
return theClass;
}
} catch (Exception e) {
throw e instanceof RuntimeException ? (RuntimeException) e : new RuntimeException(e);
}
}
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;
}
public static boolean isSnippetID(String s) {
try {
parseSnippetID(s);
return true;
} catch (RuntimeException e) {
return false;
}
}
}