Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

2004
LINES

< > BotCompany Repo | #3000389 // Temp program by #1001628

JavaX source code - run with: x30.jar

1  
import java.util.*;
2  
import java.util.zip.*;
3  
import java.util.List;
4  
import java.util.regex.*;
5  
import java.util.concurrent.*;
6  
import java.util.concurrent.atomic.*;
7  
import javax.swing.*;
8  
import javax.swing.event.*;
9  
import javax.swing.text.*;
10  
import javax.swing.table.*;
11  
import java.io.*;
12  
import java.net.*;
13  
import java.lang.reflect.*;
14  
import java.lang.ref.*;
15  
import java.lang.management.*;
16  
import java.security.*;
17  
import java.security.spec.*;
18  
import java.awt.*;
19  
import java.awt.event.*;
20  
import java.awt.image.*;
21  
import javax.imageio.*;
22  
import java.math.*;
23  
public class main {
24  
public static void main(String[] args) throws Exception {
25  
26  
    for (JFrame f : allFrames()) {
27  
      List<JList> lists = findAll(f, JList.class);
28  
      if (l(lists) == 2) {
29  
        print("Yes! " + f.getTitle());
30  
        sendToLocalBot(5005,"please receive *", weakref(f));
31  
      }
32  
    }
33  
  
34  
}
35  
36  
static List<JFrame> allFrames() {
37  
  return listAllFrames();
38  
}
39  
static <A> List<A> findAll(JFrame f, Class<A> theClass) {
40  
  List<A> l = new ArrayList<A>();
41  
  scanForComponents(f, theClass, l);
42  
  return l;
43  
}
44  
static String weakref(Object o) {
45  
  return (String) call(getJavaX(), "weakref", o);
46  
}
47  
static String sendToLocalBot(String bot, String text, Object... args) {
48  
  text = format3(text, args);
49  
  
50  
  DialogIO channel = findBot(bot);
51  
  if (channel == null)
52  
    fail(quote(bot) + " not found");
53  
  try {
54  
    channel.readLine();
55  
    print(bot + "> " + shorten(text, 80));
56  
    channel.sendLine(text);
57  
    String s = channel.readLine();
58  
    print(bot + "< " + shorten(s, 80));
59  
    return s;
60  
  } catch (Throwable e) {
61  
    e.printStackTrace();
62  
    return null;
63  
  } finally {
64  
    channel.close();
65  
  }
66  
}
67  
68  
static String sendToLocalBot(int port, String text, Object... args) {
69  
  text = format3(text, args);
70  
  DialogIO channel = talkTo(port);
71  
  try {
72  
    channel.readLine();
73  
    print(port + "> " + shorten(text, 80));
74  
    channel.sendLine(text);
75  
    String s = channel.readLine();
76  
    print(port + "< " + shorten(s, 80));
77  
    return s;
78  
  } catch (Throwable e) {
79  
    e.printStackTrace();
80  
    return null;
81  
  } finally {
82  
    if (channel != null)
83  
      channel.close();
84  
  }
85  
}
86  
static int l(Object[] array) {
87  
  return array == null ? 0 : array.length;
88  
}
89  
90  
static int l(byte[] array) {
91  
  return array == null ? 0 : array.length;
92  
}
93  
94  
static int l(int[] array) {
95  
  return array == null ? 0 : array.length;
96  
}
97  
98  
static int l(char[] array) {
99  
  return array == null ? 0 : array.length;
100  
}
101  
102  
static int l(Collection c) {
103  
  return c == null ? 0 : c.size();
104  
}
105  
106  
static int l(Map m) {
107  
  return m == null ? 0 : m.size();
108  
}
109  
110  
static int l(String s) {
111  
  return s == null ? 0 : s.length();
112  
} 
113  
114  
115  
static volatile StringBuffer local_log = new StringBuffer(); // not redirected
116  
static volatile StringBuffer print_log = local_log; // might be redirected, e.g. to main bot
117  
118  
// in bytes - will cut to half that
119  
static volatile int print_log_max = 1024*1024;
120  
static volatile int local_log_max = 100*1024;
121  
122  
static void print() {
123  
  print("");
124  
}
125  
126  
// slightly overblown signature to return original object...
127  
static <A> A print(A o) {
128  
  String s = String.valueOf(o) + "\n";
129  
  StringBuffer loc = local_log;
130  
  StringBuffer buf = print_log;
131  
  int loc_max = print_log_max;
132  
  if (buf != loc && buf != null) {
133  
    print_append(buf, s, print_log_max);
134  
    loc_max = local_log_max;
135  
  }
136  
  if (loc != null) 
137  
    print_append(loc, s, loc_max);
138  
  System.out.print(s);
139  
  return o;
140  
}
141  
142  
static void print(long l) {
143  
  print(String.valueOf(l));
144  
}
145  
146  
static void print(char c) {
147  
  print(String.valueOf(c));
148  
}
149  
150  
static void print_append(StringBuffer buf, String s, int max) {
151  
  synchronized(buf) {
152  
    buf.append(s);
153  
    max /= 2;
154  
    if (buf.length() > max) try {
155  
      int newLength = max/2;
156  
      int ofs = buf.length()-newLength;
157  
      String newString = buf.substring(ofs);
158  
      buf.setLength(0);
159  
      buf.append("[...] ").append(newString);
160  
    } catch (Exception e) {
161  
      buf.setLength(0);
162  
    }
163  
  }
164  
}
165  
166  
  static Object call(Object o) {
167  
    return callFunction(o);
168  
  }
169  
  
170  
  // varargs assignment fixer for a single string array argument
171  
  static Object call(Object o, String method, String[] arg) {
172  
    return call(o, method, new Object[] {arg});
173  
  }
174  
  
175  
  static Object call(Object o, String method, Object... args) {
176  
    try {
177  
      if (o instanceof Class) {
178  
        Method m = call_findStaticMethod((Class) o, method, args, false);
179  
        m.setAccessible(true);
180  
        return m.invoke(null, args);
181  
      } else {
182  
        Method m = call_findMethod(o, method, args, false);
183  
        m.setAccessible(true);
184  
        return m.invoke(o, args);
185  
      }
186  
    } catch (Exception e) {
187  
      throw e instanceof RuntimeException ? (RuntimeException) e : new RuntimeException(e);
188  
    }
189  
  }
190  
191  
  static Method call_findStaticMethod(Class c, String method, Object[] args, boolean debug) {
192  
    Class _c = c;
193  
    while (c != null) {
194  
      for (Method m : c.getDeclaredMethods()) {
195  
        if (debug)
196  
          System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");;
197  
        if (!m.getName().equals(method)) {
198  
          if (debug) System.out.println("Method name mismatch: " + method);
199  
          continue;
200  
        }
201  
202  
        if ((m.getModifiers() & Modifier.STATIC) == 0 || !call_checkArgs(m, args, debug))
203  
          continue;
204  
205  
        return m;
206  
      }
207  
      c = c.getSuperclass();
208  
    }
209  
    throw new RuntimeException("Method '" + method + "' (static) with " + args.length + " parameter(s) not found in " + _c.getName());
210  
  }
211  
212  
  static Method call_findMethod(Object o, String method, Object[] args, boolean debug) {
213  
    Class c = o.getClass();
214  
    while (c != null) {
215  
      for (Method m : c.getDeclaredMethods()) {
216  
        if (debug)
217  
          System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");;
218  
        if (m.getName().equals(method) && call_checkArgs(m, args, debug))
219  
          return m;
220  
      }
221  
      c = c.getSuperclass();
222  
    }
223  
    throw new RuntimeException("Method '" + method + "' (non-static) with " + args.length + " parameter(s) not found in " + o.getClass().getName());
224  
  }
225  
226  
  private static boolean call_checkArgs(Method m, Object[] args, boolean debug) {
227  
    Class<?>[] types = m.getParameterTypes();
228  
    if (types.length != args.length) {
229  
      if (debug)
230  
        System.out.println("Bad parameter length: " + args.length + " vs " + types.length);
231  
      return false;
232  
    }
233  
    for (int i = 0; i < types.length; i++)
234  
      if (!(args[i] == null || isInstanceX(types[i], args[i]))) {
235  
        if (debug)
236  
          System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]);
237  
        return false;
238  
      }
239  
    return true;
240  
  }
241  
242  
243  
static DialogIO talkTo(int port) {
244  
  return talkTo("localhost", port);
245  
}
246  
247  
static DialogIO talkTo(String ip, int port) { try {
248  
 
249  
  final Socket s = new Socket(ip, port);    
250  
  //print("Talking to " + ip + ":" + port);
251  
252  
  final Writer w = new OutputStreamWriter(s.getOutputStream(), "UTF-8");
253  
  final BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream(), "UTF-8"));
254  
  return new DialogIO() {
255  
    boolean isLocalConnection() {
256  
      return s.getInetAddress().isLoopbackAddress();
257  
    }
258  
    
259  
    boolean isStillConnected() {
260  
      return !(eos || s.isClosed());
261  
    }
262  
    
263  
    void sendLine(String line) { try {
264  
 
265  
      w.write(line + "\n");
266  
      w.flush();
267  
    
268  
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
269  
    
270  
    String readLineImpl() { try {
271  
 
272  
      return in.readLine();
273  
    
274  
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
275  
    
276  
    void close() {
277  
      try {
278  
        s.close();
279  
      } catch (IOException e) {
280  
        // whatever
281  
      }
282  
    }
283  
    
284  
    Socket getSocket() {
285  
      return s;
286  
    }
287  
  };
288  
289  
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
290  
  static String format3(String pat, Object... args) {
291  
    if (args.length == 0) return pat;
292  
    
293  
    List<String> tok = javaTokPlusPeriod(pat);
294  
    int argidx = 0;
295  
    for (int i = 1; i < tok.size(); i += 2)
296  
      if (tok.get(i).equals("*"))
297  
        tok.set(i, format3_formatArg(argidx < args.length ? args[argidx++] : "null"));
298  
    return join(tok);
299  
  }
300  
  
301  
  static String format3_formatArg(Object arg) {
302  
    if (arg == null) return "null";
303  
    if (arg instanceof String) {
304  
      String s = (String) arg;
305  
      return isIdentifier(s) || isNonNegativeInteger(s) ? s : quote(s);
306  
    }
307  
    if (arg instanceof Integer || arg instanceof Long) return String.valueOf(arg);
308  
    return quote(structure(arg));
309  
  }
310  
  
311  
312  
static String shorten(String s, int max) {
313  
  if (s == null) return "";
314  
  return s.length() <= max ? s : s.substring(0, Math.min(s.length(), max)) + "...";
315  
}
316  
  static RuntimeException fail() {
317  
    throw new RuntimeException("fail");
318  
  }
319  
  
320  
  static RuntimeException fail(Object msg) {
321  
    throw new RuntimeException(String.valueOf(msg));
322  
  }
323  
  
324  
  static RuntimeException fail(String msg) {
325  
    throw new RuntimeException(unnull(msg));
326  
  }
327  
    
328  
  static RuntimeException fail(String msg, Object... args) {
329  
    throw new RuntimeException(format(msg, args));
330  
  }
331  
static <A> void scanForComponents(Component c, Class<A> theClass, List<A> l) {
332  
  if (theClass.isInstance(c))
333  
    l.add((A) c);
334  
  if (c instanceof Container)
335  
  for (Component comp : ((Container) c).getComponents())
336  
    scanForComponents(comp, theClass, l);
337  
}
338  
static List<JFrame> listAllFrames() {
339  
  List<JFrame> l = new ArrayList<JFrame>();
340  
  for (Frame f : Frame.getFrames())
341  
    if (f instanceof JFrame)
342  
      l.add((JFrame) f);
343  
  return l;
344  
}
345  
  static String quote(String s) {
346  
    if (s == null) return "null";
347  
    return "\"" + s.replace("\\", "\\\\").replace("\"", "\\\"").replace("\r", "\\r").replace("\n", "\\n") + "\"";
348  
  }
349  
  
350  
  static String quote(long l) {
351  
    return quote("" + l);
352  
  }
353  
  
354  
  static String quote(char c) {
355  
    return quote("" + c);
356  
  }
357  
358  
static Class __javax;
359  
360  
static Class getJavaX() {
361  
  return __javax;
362  
}
363  
static Map<String, Integer> findBot_cache = new TreeMap<String, Integer>();
364  
static int findBot_timeout = 5000;
365  
366  
static DialogIO findBot(String searchPattern) {
367  
  // first split off sub-bot suffix
368  
  String subBot = null;
369  
  int i = searchPattern.indexOf('/');
370  
  if (i >= 0 && (isJavaIdentifier(searchPattern.substring(0, i)) || isInteger(searchPattern.substring(0, i)))) {
371  
    subBot = searchPattern.substring(i+1);
372  
    searchPattern = searchPattern.substring(0, i);
373  
    if (!isInteger(searchPattern))
374  
      searchPattern = "Multi-Port at " + searchPattern + ".";
375  
  }
376  
  
377  
  // assume it's a port if it's an integer
378  
  if (isInteger(searchPattern))
379  
    return talkToSubBot(subBot, talkTo(parseInt(searchPattern)));
380  
    
381  
  if (eq(searchPattern, "remote"))
382  
    return talkToSubBot(subBot, talkTo("second.tinybrain.de", 4999));
383  
    
384  
  Integer port = findBot_cache.get(searchPattern);
385  
  if (port != null) try {
386  
    DialogIO io = talkTo("localhost", port);
387  
    io.waitForLine(/*findBot_timeout*/); // TODO: implement
388  
    String line = io.readLineNoBlock();
389  
    if (indexOfIgnoreCase(line, searchPattern) == 0) {
390  
      call(io, "pushback", line); // put hello string back in
391  
      return talkToSubBot(subBot, io);
392  
    }
393  
  } catch (Exception e) {
394  
    e.printStackTrace();
395  
  }
396  
  
397  
  List<ProgramScan.Program> bots = quickBotScan();
398  
  
399  
  // find top-level bots
400  
  for (ProgramScan.Program p : bots) {
401  
    if (indexOfIgnoreCase(p.helloString, searchPattern) == 0) { // strict matching - start of hello string only, but case-insensitive
402  
      findBot_cache.put(searchPattern, p.port);
403  
      return talkToSubBot(subBot, talkTo("localhost", p.port));
404  
    }
405  
  }
406  
  
407  
  // find sub-bots
408  
  for (ProgramScan.Program p : bots) {
409  
    String botName = firstPartOfHelloString(p.helloString);
410  
    boolean isVM = startsWithIgnoreCase(p.helloString, "This is a JavaX VM.");
411  
    boolean shouldRecurse = startsWithIgnoreCase(botName, "Multi-Port") || isVM;
412  
        
413  
    if (shouldRecurse) try {
414  
      Map<Number, String> subBots = (Map) unstructure(sendToLocalBot(p.port, "list bots"));
415  
      for (Number vport : subBots.keySet()) {
416  
        String name = subBots.get(vport);
417  
        if (startsWithIgnoreCase(name, searchPattern))
418  
          return talkToSubBot(vport.longValue(), talkTo("localhost", p.port));
419  
      }
420  
    } catch (Exception e) { e.printStackTrace(); }
421  
  }
422  
        
423  
  return null;
424  
}
425  
426  
static int parseInt(String s) {
427  
  return empty(s) ? 0 : Integer.parseInt(s);
428  
}
429  
// This is made for NL parsing.
430  
// It's javaTok extended with "..." token, "$n" and "#n" and
431  
// special quotes (which are converted to normal ones).
432  
433  
static List<String> javaTokPlusPeriod(String s) {
434  
  List<String> tok = new ArrayList<String>();
435  
  int l = s.length();
436  
  
437  
  int i = 0;
438  
  while (i < l) {
439  
    int j = i;
440  
    char c; String cc;
441  
    
442  
    // scan for whitespace
443  
    while (j < l) {
444  
      c = s.charAt(j);
445  
      cc = s.substring(j, Math.min(j+2, l));
446  
      if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
447  
        ++j;
448  
      else if (cc.equals("/*")) {
449  
        do ++j; while (j < l && !s.substring(j, Math.min(j+2, l)).equals("*/"));
450  
        j = Math.min(j+2, l);
451  
      } else if (cc.equals("//")) {
452  
        do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0);
453  
      } else
454  
        break;
455  
    }
456  
    
457  
    tok.add(s.substring(i, j));
458  
    i = j;
459  
    if (i >= l) break;
460  
    c = s.charAt(i);
461  
    cc = s.substring(i, Math.min(i+2, l));
462  
463  
    // scan for non-whitespace
464  
    if (c == '\u201C' || c == '\u201D') c = '"'; // normalize quotes
465  
    if (c == '\'' || c == '"') {
466  
      char opener = c;
467  
      ++j;
468  
      while (j < l) {
469  
        char _c = s.charAt(j);
470  
        if (_c == '\u201C' || _c == '\u201D') _c = '"'; // normalize quotes
471  
        if (_c == opener) {
472  
          ++j;
473  
          break;
474  
        } else if (s.charAt(j) == '\\' && j+1 < l)
475  
          j += 2;
476  
        else
477  
          ++j;
478  
      }
479  
      if (j-1 >= i+1) {
480  
        tok.add(opener + s.substring(i+1, j-1) + opener);
481  
        i = j;
482  
        continue;
483  
      }
484  
    } else if (Character.isJavaIdentifierStart(c))
485  
      do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || s.charAt(j) == '\'')); // for things like "this one's"
486  
    else if (Character.isDigit(c))
487  
      do ++j; while (j < l && Character.isDigit(s.charAt(j)));
488  
    else if (cc.equals("[[")) {
489  
      do ++j; while (j+1 < l && !s.substring(j, j+2).equals("]]"));
490  
      j = Math.min(j+2, l);
491  
    } else if (cc.equals("[=") && i+2 < l && s.charAt(i+2) == '[') {
492  
      do ++j; while (j+2 < l && !s.substring(j, j+3).equals("]=]"));
493  
      j = Math.min(j+3, l);
494  
    } else if (s.substring(j, Math.min(j+3, l)).equals("..."))
495  
      j += 3;
496  
    else if (c == '$' || c == '#')
497  
      do ++j; while (j < l && Character.isDigit(s.charAt(j)));
498  
    else
499  
      ++j;
500  
501  
    tok.add(s.substring(i, j));
502  
    i = j;
503  
  }
504  
  
505  
  if ((tok.size() % 2) == 0) tok.add("");
506  
  return tok;
507  
}
508  
509  
static boolean isIdentifier(String s) {
510  
  return isJavaIdentifier(s);
511  
}
512  
static class DynamicObject {
513  
  String className;
514  
  Map<String, Object> fieldValues = new TreeMap<String, Object>();
515  
}
516  
517  
static Object unstructure(String text) {
518  
  return unstructure(text, false);
519  
}
520  
521  
// TODO: backrefs for hashmap{} etc
522  
static Object unstructure(String text, final boolean allDynamic) {
523  
  if (text == null) return null;
524  
  final List<String> tok = javaTok(text);
525  
  final boolean debug = unstructure_debug;
526  
  
527  
  class X {
528  
    int i = 1;
529  
    HashMap<Integer, Object> refs = new HashMap<Integer, Object>();
530  
531  
    Object parse() {
532  
      String t = tok.get(i);
533  
      
534  
      int refID = 0;
535  
      if (t.startsWith("m") && isInteger(t.substring(1))) {
536  
        refID = parseInt(t.substring(1));
537  
        i += 2;
538  
        t = tok.get(i);
539  
      }
540  
      
541  
      if (debug)
542  
        print("parse: " + quote(t));
543  
        
544  
      if (t.startsWith("\"")) {
545  
        String s = unquote(tok.get(i));
546  
        i += 2;
547  
        return s;
548  
      }
549  
      if (t.startsWith("'")) {
550  
        char c = unquoteCharacter(tok.get(i));
551  
        i += 2;
552  
        return c;
553  
      }
554  
      if (t.equals("bigint"))
555  
        return parseBigInt();
556  
      if (t.equals("d"))
557  
        return parseDouble();
558  
      if (t.equals("false") || t.equals("f")) {
559  
        i += 2; return false;
560  
      }
561  
      if (t.equals("true") || t.equals("t")) {
562  
        i += 2; return true;
563  
      }
564  
      if (t.equals("-")) {
565  
        t = tok.get(i+2);
566  
        i += 4;
567  
        return isLongConstant(t) ? (Object) (-parseLong(t)) : (Object) (-parseInt(t));
568  
      }
569  
      if (isInteger(t) || isLongConstant(t)) {
570  
        i += 2;
571  
        if (debug)
572  
          print("isLongConstant " + quote(t) + " => " + isLongConstant(t));
573  
        return isLongConstant(t) ? (Object) parseLong(t) : (Object) parseInt(t);
574  
      }
575  
      
576  
      if (t.startsWith("r") && isInteger(t.substring(1))) {
577  
        i += 2;
578  
        int ref = Integer.parseInt(t.substring(1));
579  
        Object o = refs.get(ref);
580  
        if (o == null)
581  
          print("Warning: unsatisfied back reference " + ref);
582  
        return o;
583  
      }
584  
      
585  
      return parse_inner(refID);
586  
    }
587  
    
588  
    // everything that can be backreferenced
589  
    Object parse_inner(int refID) {
590  
      String t = tok.get(i);
591  
      
592  
      if (debug)
593  
        print("parse_inner: " + quote(t));
594  
        
595  
      if (t.equals("hashset"))
596  
        return parseHashSet();
597  
      if (t.equals("treeset"))
598  
        return parseTreeSet();
599  
      if (t.equals("hashmap"))
600  
        return parseHashMap();
601  
      if (t.equals("{"))
602  
        return parseMap();
603  
      if (t.equals("["))
604  
        return parseList();
605  
      if (t.equals("array"))
606  
        return parseArray();
607  
      if (t.equals("class"))
608  
        return parseClass();
609  
      if (t.equals("l"))
610  
        return parseLisp();
611  
      if (t.equals("null")) {
612  
        i += 2; return null;
613  
      }
614  
      if (isJavaIdentifier(t)) {
615  
        Class c = allDynamic ? null : findClass(t);
616  
        DynamicObject dO = null;
617  
        Object o = null;
618  
        if (c != null)
619  
          o = nuObject(c);
620  
        else {
621  
          dO = new DynamicObject();
622  
          dO.className = t;
623  
        }
624  
        
625  
        if (refID != 0)
626  
          refs.put(refID, o);
627  
          
628  
        i += 2;
629  
        if (i < tok.size() && tok.get(i).equals("(")) {
630  
          consume("(");
631  
          while (!tok.get(i).equals(")")) {
632  
            // It's like parsing a map.
633  
            //Object key = parse();
634  
            //if (tok.get(i).equals(")"))
635  
            //  key = onlyField();
636  
            String key = unquote(tok.get(i));
637  
            i += 2;
638  
            consume("=");
639  
            Object value = parse();
640  
            if (o != null)
641  
              setOpt(o, key, value);
642  
            else
643  
              dO.fieldValues.put(key, value);
644  
            if (tok.get(i).equals(",")) i += 2;
645  
          }
646  
          consume(")");
647  
        }
648  
        return o != null ? o : dO;
649  
      }
650  
      throw new RuntimeException("Unknown token " + (i+1) + ": " + t);
651  
    }
652  
    
653  
    Object parseSet(Set set) {
654  
      set.addAll((List) parseList());
655  
      return set;
656  
    }
657  
    
658  
    Object parseLisp() {
659  
      consume("l");
660  
      consume("(");
661  
      List list = new ArrayList();
662  
      while (!tok.get(i).equals(")")) {
663  
        list.add(parse());
664  
        if (tok.get(i).equals(",")) i += 2;
665  
      }
666  
      consume(")");
667  
      return newObject("main$Lisp", (String) list.get(0), subList(list, 1));
668  
    }
669  
    
670  
    Object parseList() {
671  
      consume("[");
672  
      List list = new ArrayList();
673  
      while (!tok.get(i).equals("]")) {
674  
        list.add(parse());
675  
        if (tok.get(i).equals(",")) i += 2;
676  
      }
677  
      consume("]");
678  
      return list;
679  
    }
680  
    
681  
    Object parseArray() {
682  
      consume("array");
683  
      consume("{");
684  
      List list = new ArrayList();
685  
      while (!tok.get(i).equals("}")) {
686  
        list.add(parse());
687  
        if (tok.get(i).equals(",")) i += 2;
688  
      }
689  
      consume("}");
690  
      return list.toArray();
691  
    }
692  
    
693  
    Object parseClass() {
694  
      consume("class");
695  
      consume("(");
696  
      String name = tok.get(i);
697  
      i += 2;
698  
      consume(")");
699  
      Class c = allDynamic ? null : findClass(name);
700  
      if (c != null) return c;
701  
      DynamicObject dO = new DynamicObject();
702  
      dO.className = "java.lang.Class";
703  
      dO.fieldValues.put("name", name);
704  
      return dO;
705  
    }
706  
    
707  
    Object parseBigInt() {
708  
      consume("bigint");
709  
      consume("(");
710  
      String val = tok.get(i);
711  
      i += 2;
712  
      if (eq(val, "-")) {
713  
        val = "-" + tok.get(i);
714  
        i += 2;
715  
      }
716  
      consume(")");
717  
      return new BigInteger(val);
718  
    }
719  
    
720  
    Object parseDouble() {
721  
      consume("d");
722  
      consume("(");
723  
      String val = unquote(tok.get(i));
724  
      i += 2;
725  
      consume(")");
726  
      return Double.parseDouble(val);
727  
    }
728  
    
729  
    Object parseHashMap() {
730  
      consume("hashmap");
731  
      return parseMap(new HashMap());
732  
    }
733  
    
734  
    Object parseHashSet() {
735  
      consume("hashset");
736  
      return parseSet(new HashSet());
737  
    }
738  
    
739  
    Object parseTreeSet() {
740  
      consume("treeset");
741  
      return parseSet(new TreeSet());
742  
    }
743  
    
744  
    Object parseMap() {
745  
      return parseMap(new TreeMap());
746  
    }
747  
    
748  
    Object parseMap(Map map) {
749  
      consume("{");
750  
      while (!tok.get(i).equals("}")) {
751  
        Object key = parse();
752  
        consume("=");
753  
        Object value = parse();
754  
        map.put(key, value);
755  
        if (tok.get(i).equals(",")) i += 2;
756  
      }
757  
      consume("}");
758  
      return map;
759  
    }
760  
    
761  
    void consume(String s) {
762  
      if (!tok.get(i).equals(s)) {
763  
        String prevToken = i-2 >= 0 ? tok.get(i-2) : "";
764  
        String nextTokens = join(tok.subList(i, Math.min(i+4, tok.size())));
765  
        fail(quote(s) + " expected: " + prevToken + " " + nextTokens + " (" + i + "/" + tok.size() + ")");
766  
      }
767  
      i += 2;
768  
    }
769  
  }
770  
  
771  
  return new X().parse();
772  
}
773  
774  
static boolean unstructure_debug;
775  
static DialogIO talkToSubBot(final long vport, final DialogIO io) {
776  
  return talkToSubBot(String.valueOf(vport), io);
777  
}
778  
779  
static DialogIO talkToSubBot(final String subBot, final DialogIO io) {
780  
  if (subBot == null) return io;
781  
  
782  
  return new DialogIO() {
783  
    // delegate all but sendLine
784  
    boolean isStillConnected() { return io.isStillConnected(); }
785  
    String readLineImpl() { return io.readLineImpl(); }
786  
    boolean isLocalConnection() { return io.isLocalConnection(); }
787  
    Socket getSocket() { return io.getSocket(); }
788  
    void close() { io.close(); }
789  
790  
    void sendLine(String line) {
791  
      io.sendLine(format3("please forward to bot *: *", subBot, line));
792  
    }
793  
  };
794  
}
795  
static boolean startsWithIgnoreCase(String a, String b) {
796  
  return a != null && a.regionMatches(true, 0, b, 0, b.length());
797  
}
798  
static boolean isJavaIdentifier(String s) {
799  
  if (s.length() == 0 || !Character.isJavaIdentifierStart(s.charAt(0)))
800  
    return false;
801  
  for (int i = 1; i < s.length(); i++)
802  
    if (!Character.isJavaIdentifierPart(s.charAt(i)))
803  
      return false;
804  
  return true;
805  
}
806  
// works on lists and strings and null
807  
808  
static int indexOfIgnoreCase(Object a, Object b) {
809  
  if (a == null) return -1;
810  
  if (a instanceof String) {
811  
     Matcher m = Pattern.compile((String) b, Pattern.CASE_INSENSITIVE + Pattern.LITERAL).matcher((String) a);
812  
     if (m.find()) return m.start(); else return -1;
813  
  }
814  
  if (a instanceof List) {
815  
    for (int i = 0; i < ((List) a).size(); i++) {
816  
      Object o = ((List) a).get(i);
817  
      if (o != null && ((String) o).equalsIgnoreCase((String) b))
818  
        return i;
819  
    }
820  
    return -1;
821  
  }
822  
  throw fail("Unknown type: " + a);
823  
}
824  
static boolean isInteger(String s) {
825  
  return s != null && Pattern.matches("\\-?\\d+", s);
826  
}
827  
static String structure(Object o) {
828  
  HashSet refd = new HashSet();
829  
  return structure_2(structure_1(o, 0, new IdentityHashMap(), refd), refd);
830  
}
831  
832  
// leave to false, unless unstructure() breaks
833  
static boolean structure_allowShortening = false;
834  
835  
static String structure_1(Object o, int stringSizeLimit, IdentityHashMap<Object, Integer> seen, HashSet<Integer> refd) {
836  
  if (o == null) return "null";
837  
  
838  
  // these are never back-referenced (for readability)
839  
  
840  
  if (o instanceof String)
841  
    return quote(stringSizeLimit != 0 ? shorten((String) o, stringSizeLimit) : (String) o);
842  
    
843  
  if (o instanceof BigInteger)
844  
    return "bigint(" + o + ")";
845  
  
846  
  if (o instanceof Double)
847  
    return "d(" + quote(str(o)) + ")";
848  
    
849  
  if (o instanceof Long)
850  
    return o + "L";
851  
  
852  
  if (o instanceof Integer)
853  
    return str(o);
854  
    
855  
  if (o instanceof Boolean)
856  
    return ((Boolean) o).booleanValue() ? "t" : "f";
857  
    
858  
  if (o instanceof Character)
859  
    return quoteCharacter((Character) o);
860  
  
861  
  Integer ref = seen.get(o);
862  
  if (ref != null) {
863  
    refd.add(ref);
864  
    return "r" + ref;
865  
  }
866  
      
867  
  ref = seen.size()+1;
868  
  seen.put(o, ref);
869  
  String r = "m" + ref + " "; // marker
870  
871  
  String name = o.getClass().getName();
872  
873  
  StringBuilder buf = new StringBuilder();
874  
  
875  
  if (o instanceof HashSet)
876  
    return r + "hashset " + structure_1(new ArrayList((Set) o), stringSizeLimit, seen, refd);
877  
878  
  if (o instanceof TreeSet)
879  
    return r + "treeset " + structure_1(new ArrayList((Set) o), stringSizeLimit, seen, refd);
880  
  
881  
  if (o instanceof Collection) {
882  
    for (Object x : (Collection) o) {
883  
      if (buf.length() != 0) buf.append(", ");
884  
      buf.append(structure_1(x, stringSizeLimit, seen, refd));
885  
    }
886  
    return r + "[" + buf + "]";
887  
  }
888  
  
889  
  if (o instanceof Map) {
890  
    for (Object e : ((Map) o).entrySet()) {
891  
      if (buf.length() != 0) buf.append(", ");
892  
      buf.append(structure_1(((Map.Entry) e).getKey(), stringSizeLimit, seen, refd));
893  
      buf.append("=");
894  
      buf.append(structure_1(((Map.Entry) e).getValue(), stringSizeLimit, seen, refd));
895  
    }
896  
    return r + (o instanceof HashMap ? "hashmap" : "") + "{" + buf + "}";
897  
  }
898  
  
899  
  if (o.getClass().isArray()) {
900  
    int n = Array.getLength(o);
901  
    for (int i = 0; i < n; i++) {
902  
      if (buf.length() != 0) buf.append(", ");
903  
      buf.append(structure_1(Array.get(o, i), stringSizeLimit, seen, refd));
904  
    }
905  
    return r + "array{" + buf + "}";
906  
  }
907  
908  
  if (o instanceof Class)
909  
    return r + "class(" + quote(((Class) o).getName()) + ")";
910  
    
911  
  if (o instanceof Throwable)
912  
    return r + "exception(" + quote(((Throwable) o).getMessage()) + ")";
913  
    
914  
  if (o instanceof BitSet) {
915  
    BitSet bs = (BitSet) o;
916  
    for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
917  
      if (buf.length() != 0) buf.append(", ");
918  
       buf.append(i);
919  
    }
920  
    return "bitset{" + buf + "}";
921  
  }
922  
    
923  
  // Need more cases? This should cover all library classes...
924  
  if (name.startsWith("java.") || name.startsWith("javax."))
925  
    return r + String.valueOf(o);
926  
    
927  
  String shortName = o.getClass().getName().replaceAll("^main\\$", "");
928  
  
929  
  if (shortName.equals("Lisp")) {
930  
    buf.append("l(" + structure_1(getOpt(o, "head"), stringSizeLimit, seen, refd));
931  
    List args = (List) ( getOpt(o, "args"));
932  
    if (nempty(args))
933  
      for (int i = 0; i < l(args); i++) {
934  
        buf.append(", ");
935  
        Object arg = args.get(i);
936  
        
937  
        // sweet shortening
938  
        if (arg != null && eq(arg.getClass().getName(), "main$Lisp") && isTrue(call(arg, "isEmpty")))
939  
          arg = get(arg, "head");
940  
          
941  
        buf.append(structure_1(arg, stringSizeLimit, seen, refd));
942  
      }
943  
    buf.append(")");
944  
    return r + str(buf);
945  
  }
946  
    
947  
  int numFields = 0;
948  
  String fieldName = "";
949  
  if (shortName.equals("DynamicObject")) {
950  
    shortName = (String) get(o, "className");
951  
    Map<String, Object> fieldValues = (Map) get(o, "fieldValues");
952  
    
953  
    for (String _fieldName : fieldValues.keySet()) {
954  
      fieldName = _fieldName;
955  
      Object value = fieldValues.get(fieldName);
956  
      if (value != null) {
957  
        if (buf.length() != 0) buf.append(", ");
958  
        buf.append(fieldName + "=" + structure_1(value, stringSizeLimit, seen, refd));
959  
      }
960  
      ++numFields;
961  
   }
962  
  } else {
963  
    // regular class
964  
    
965  
    Class c = o.getClass();
966  
    while (c != Object.class) {
967  
      Field[] fields = c.getDeclaredFields();
968  
      for (Field field : fields) {
969  
        if ((field.getModifiers() & Modifier.STATIC) != 0)
970  
          continue;
971  
        fieldName = field.getName();
972  
        
973  
        // skip outer object reference
974  
        if (fieldName.indexOf("$") >= 0) continue;
975  
  
976  
        Object value;
977  
        try {
978  
          field.setAccessible(true);
979  
          value = field.get(o);
980  
        } catch (Exception e) {
981  
          value = "?";
982  
        }
983  
        
984  
        // put special cases here...
985  
    
986  
        if (value != null) {
987  
          if (buf.length() != 0) buf.append(", ");
988  
          buf.append(fieldName + "=" + structure_1(value, stringSizeLimit, seen, refd));
989  
        }
990  
        ++numFields;
991  
      }
992  
      c = c.getSuperclass();
993  
    }
994  
  }
995  
  
996  
  String b = buf.toString();
997  
  
998  
  if (numFields == 1 && structure_allowShortening)
999  
    b = b.replaceAll("^" + fieldName + "=", ""); // drop field name if only one
1000  
  String s = shortName;
1001  
  if (buf.length() != 0)
1002  
    s += "(" + b + ")";
1003  
  return r + s;
1004  
}
1005  
1006  
// drop unused markers
1007  
static String structure_2(String s, HashSet<Integer> refd) {
1008  
  List<String> tok = javaTok(s);
1009  
  StringBuilder out = new StringBuilder();
1010  
  for (int i = 1; i < l(tok); i += 2) {
1011  
    String t = tok.get(i);
1012  
    if (t.startsWith("m") && isInteger(t.substring(1))
1013  
      && !refd.contains(parseInt(t.substring(1))))
1014  
      continue;
1015  
    out.append(t).append(tok.get(i+1));
1016  
  }
1017  
  return str(out);
1018  
}
1019  
1020  
static String firstPartOfHelloString(String s) {
1021  
  int i = s.lastIndexOf('/');
1022  
  return i < 0 ? s : rtrim(s.substring(0, i));
1023  
}
1024  
static Object callFunction(Object f, Object... args) {
1025  
  if (f == null) return null;
1026  
  if (f instanceof Runnable) {
1027  
    ((Runnable) f).run();
1028  
    return null;
1029  
  } else if (f instanceof String)
1030  
    return call(mc(), (String) f, args);
1031  
  else
1032  
    return call(f, "get", args);
1033  
  //else throw fail("Can't call a " + getClassName(f));
1034  
}
1035  
static boolean isNonNegativeInteger(String s) {
1036  
  return s != null && Pattern.matches("\\d+", s);
1037  
}
1038  
  static String format(String pat, Object... args) {
1039  
    return format3(pat, args);
1040  
  }
1041  
1042  
  public static String join(String glue, Iterable<String> strings) {
1043  
    StringBuilder buf = new StringBuilder();
1044  
    Iterator<String> i = strings.iterator();
1045  
    if (i.hasNext()) {
1046  
      buf.append(i.next());
1047  
      while (i.hasNext())
1048  
        buf.append(glue).append(i.next());
1049  
    }
1050  
    return buf.toString();
1051  
  }
1052  
  
1053  
  public static String join(String glue, String[] strings) {
1054  
    return join(glue, Arrays.asList(strings));
1055  
  }
1056  
  
1057  
  public static String join(Iterable<String> strings) {
1058  
    return join("", strings);
1059  
  }
1060  
  
1061  
  public static String join(String[] strings) {
1062  
    return join("", strings);
1063  
  }
1064  
1065  
1066  
  static String unnull(String s) {
1067  
    return s == null ? "" : s;
1068  
  }
1069  
  
1070  
  static <A> List<A> unnull(List<A> l) {
1071  
    return l == null ? emptyList() : l;
1072  
  }
1073  
  
1074  
  static Object[] unnull(Object[] a) {
1075  
    return a == null ? new Object[0] : a;
1076  
  }
1077  
static List<ProgramScan.Program> quickBotScan() {
1078  
  return ProgramScan.quickBotScan();
1079  
}
1080  
1081  
static List<ProgramScan.Program> quickBotScan(int[] preferredPorts) {
1082  
  return ProgramScan.quickBotScan(preferredPorts);
1083  
}
1084  
1085  
static List<ProgramScan.Program> quickBotScan(String searchPattern) {
1086  
  List<ProgramScan.Program> l = new ArrayList<ProgramScan.Program>();
1087  
  for (ProgramScan.Program p : ProgramScan.quickBotScan())
1088  
    if (indexOfIgnoreCase(p.helloString, searchPattern) == 0)
1089  
      l.add(p);
1090  
  return l;
1091  
}
1092  
1093  
// extended over Class.isInstance() to handle primitive types
1094  
static boolean isInstanceX(Class type, Object arg) {
1095  
  if (type == boolean.class) return arg instanceof Boolean;
1096  
  if (type == int.class) return arg instanceof Integer;
1097  
  if (type == long.class) return arg instanceof Long;
1098  
  if (type == float.class) return arg instanceof Float;
1099  
  if (type == short.class) return arg instanceof Short;
1100  
  if (type == char.class) return arg instanceof Character;
1101  
  if (type == byte.class) return arg instanceof Byte;
1102  
  if (type == double.class) return arg instanceof Double;
1103  
  return type.isInstance(arg);
1104  
}
1105  
static boolean eq(Object a, Object b) {
1106  
  if (a == null) return b == null;
1107  
  if (a.equals(b)) return true;
1108  
  if (a instanceof BigInteger) {
1109  
    if (b instanceof Integer) return a.equals(BigInteger.valueOf((Integer) b));
1110  
    if (b instanceof Long) return a.equals(BigInteger.valueOf((Long) b));
1111  
  }
1112  
  return false;
1113  
}
1114  
1115  
  static void setOpt(Object o, String field, Object value) {
1116  
    if (o instanceof Class) setOpt((Class) o, field, value);
1117  
    else try {
1118  
      Field f = setOpt_findField(o.getClass(), field);
1119  
      if (f != null)
1120  
        smartSet(f, o, value);
1121  
    } catch (Exception e) {
1122  
      throw new RuntimeException(e);
1123  
    }
1124  
  }
1125  
  
1126  
  static void setOpt(Class c, String field, Object value) {
1127  
    try {
1128  
      Field f = setOpt_findStaticField(c, field);
1129  
      if (f != null)
1130  
        smartSet(f, null, value);
1131  
    } catch (Exception e) {
1132  
      throw new RuntimeException(e);
1133  
    }
1134  
  }
1135  
  
1136  
  static Field setOpt_findField(Class<?> c, String field) {
1137  
    for (Field f : c.getDeclaredFields())
1138  
      if (f.getName().equals(field))
1139  
        return f;
1140  
    return null;
1141  
  }
1142  
  
1143  
  static Field setOpt_findStaticField(Class<?> c, String field) {
1144  
    for (Field f : c.getDeclaredFields())
1145  
      if (f.getName().equals(field) && (f.getModifiers() & Modifier.STATIC) != 0)
1146  
        return f;
1147  
    return null;
1148  
  }
1149  
static String quoteCharacter(char c) {
1150  
  if (c == '\'') return "'\\''";
1151  
  if (c == '\\') return "'\\\\'";
1152  
  return "'" + c + "'";
1153  
}
1154  
1155  
static boolean empty(Collection c) {
1156  
  return isEmpty(c);
1157  
}
1158  
1159  
static boolean empty(String s) {
1160  
  return isEmpty(s);
1161  
}
1162  
1163  
static boolean empty(Map map) {
1164  
  return map == null || map.isEmpty();
1165  
}
1166  
1167  
static boolean empty(Object o) {
1168  
  if (o instanceof Collection) return empty((Collection) o);
1169  
  if (o instanceof String) return empty((String) o);
1170  
  if (o instanceof Map) return empty((Map) o);
1171  
  return false;
1172  
}
1173  
static <A> List<A> subList(List<A> l, int startIndex) {
1174  
  return subList(l, startIndex, l(l));
1175  
}
1176  
1177  
static <A> List<A> subList(List<A> l, int startIndex, int endIndex) {
1178  
  startIndex = max(0, min(l(l), startIndex));
1179  
  endIndex = max(0, min(l(l), endIndex));
1180  
  if (startIndex > endIndex) return litlist();
1181  
  return l.subList(startIndex, endIndex);
1182  
}
1183  
// get purpose 1: access a list/array (safer version of x.get(y))
1184  
1185  
static <A> A get(List<A> l, int idx) {
1186  
  return idx >= 0 && idx < l(l) ? l.get(idx) : null;
1187  
}
1188  
1189  
static <A> A get(A[] l, int idx) {
1190  
  return idx >= 0 && idx < l(l) ? l[idx] : null;
1191  
}
1192  
1193  
// get purpose 2: access a field by reflection or a map
1194  
1195  
static Object get(Object o, String field) {
1196  
  if (o instanceof Class) return get((Class) o, field);
1197  
  
1198  
  if (o instanceof Map)
1199  
    return ((Map) o).get(field);
1200  
    
1201  
  if (o.getClass().getName().equals("main$DynamicObject"))
1202  
    return call(get_raw(o, "fieldValues"), "get", field);
1203  
    
1204  
  return get_raw(o, field);
1205  
}
1206  
1207  
static Object get_raw(Object o, String field) {
1208  
  try {
1209  
    Field f = get_findField(o.getClass(), field);
1210  
    f.setAccessible(true);
1211  
    return f.get(o);
1212  
  } catch (Exception e) {
1213  
    throw new RuntimeException(e);
1214  
  }
1215  
}
1216  
1217  
static Object get(Class c, String field) {
1218  
  try {
1219  
    Field f = get_findStaticField(c, field);
1220  
    f.setAccessible(true);
1221  
    return f.get(null);
1222  
  } catch (Exception e) {
1223  
    throw new RuntimeException(e);
1224  
  }
1225  
}
1226  
1227  
static Field get_findStaticField(Class<?> c, String field) {
1228  
  Class _c = c;
1229  
  do {
1230  
    for (Field f : _c.getDeclaredFields())
1231  
      if (f.getName().equals(field) && (f.getModifiers() & Modifier.STATIC) != 0)
1232  
        return f;
1233  
    _c = _c.getSuperclass();
1234  
  } while (_c != null);
1235  
  throw new RuntimeException("Static field '" + field + "' not found in " + c.getName());
1236  
}
1237  
1238  
static Field get_findField(Class<?> c, String field) {
1239  
  Class _c = c;
1240  
  do {
1241  
    for (Field f : _c.getDeclaredFields())
1242  
      if (f.getName().equals(field))
1243  
        return f;
1244  
    _c = _c.getSuperclass();
1245  
  } while (_c != null);
1246  
  throw new RuntimeException("Field '" + field + "' not found in " + c.getName());
1247  
}
1248  
static boolean isLongConstant(String s) {
1249  
  if (!s.endsWith("L")) return false;
1250  
  s = s.substring(0, l(s)-1);
1251  
  return isInteger(s);
1252  
}
1253  
static long parseLong(String s) {
1254  
  if (s == null) return 0;
1255  
  return Long.parseLong(dropSuffix("L", s));
1256  
}
1257  
1258  
static long parseLong(Object s) {
1259  
  return Long.parseLong((String) s);
1260  
}
1261  
static String str(Object o) {
1262  
  return String.valueOf(o);
1263  
}
1264  
static double parseDouble(String s) {
1265  
  return Double.parseDouble(s);
1266  
}
1267  
static Object nuObject(String className, Object... args) { try {
1268  
 
1269  
  return nuObject(Class.forName(className), args);
1270  
1271  
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
1272  
1273  
static Object nuObject(Object realm, String className, Object... args) {
1274  
  return nuObject(_getClass(realm, className), args);
1275  
}
1276  
1277  
static Object nuObject(Class c, Object... args) { try {
1278  
 
1279  
  Constructor m = nuObject_findConstructor(c, args);
1280  
  m.setAccessible(true);
1281  
  return m.newInstance(args);
1282  
1283  
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
1284  
1285  
static Constructor nuObject_findConstructor(Class c, Object... args) {
1286  
  for (Constructor m : c.getDeclaredConstructors()) {
1287  
    if (!nuObject_checkArgs(m.getParameterTypes(), args, false))
1288  
      continue;
1289  
    return m;
1290  
  }
1291  
  throw new RuntimeException("Constructor with " + args.length + " matching parameter(s) not found in " + c.getName());
1292  
}
1293  
1294  
 static boolean nuObject_checkArgs(Class[] types, Object[] args, boolean debug) {
1295  
    if (types.length != args.length) {
1296  
      if (debug)
1297  
        System.out.println("Bad parameter length: " + args.length + " vs " + types.length);
1298  
      return false;
1299  
    }
1300  
    for (int i = 0; i < types.length; i++)
1301  
      if (!(args[i] == null || isInstanceX(types[i], args[i]))) {
1302  
        if (debug)
1303  
          System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]);
1304  
        return false;
1305  
      }
1306  
    return true;
1307  
  }
1308  
static Object newObject(Class c, Object... args) {
1309  
  return nuObject(c, args);
1310  
}
1311  
1312  
static Object newObject(String className, Object... args) {
1313  
  return nuObject(className, args);
1314  
}
1315  
1316  
  public static String unquote(String s) {
1317  
    if (s.startsWith("[")) {
1318  
      int i = 1;
1319  
      while (i < s.length() && s.charAt(i) == '=') ++i;
1320  
      if (i < s.length() && s.charAt(i) == '[') {
1321  
        String m = s.substring(1, i);
1322  
        if (s.endsWith("]" + m + "]"))
1323  
          return s.substring(i+1, s.length()-i-1);
1324  
      }
1325  
    }
1326  
    
1327  
    if (s.startsWith("\"") /*&& s.endsWith("\"")*/ && s.length() > 1) {
1328  
      String st = s.substring(1, s.endsWith("\"") ? s.length()-1 : s.length());
1329  
      StringBuilder sb = new StringBuilder(st.length());
1330  
  
1331  
      for (int i = 0; i < st.length(); i++) {
1332  
        char ch = st.charAt(i);
1333  
        if (ch == '\\') {
1334  
          char nextChar = (i == st.length() - 1) ? '\\' : st
1335  
                  .charAt(i + 1);
1336  
          // Octal escape?
1337  
          if (nextChar >= '0' && nextChar <= '7') {
1338  
              String code = "" + nextChar;
1339  
              i++;
1340  
              if ((i < st.length() - 1) && st.charAt(i + 1) >= '0'
1341  
                      && st.charAt(i + 1) <= '7') {
1342  
                  code += st.charAt(i + 1);
1343  
                  i++;
1344  
                  if ((i < st.length() - 1) && st.charAt(i + 1) >= '0'
1345  
                          && st.charAt(i + 1) <= '7') {
1346  
                      code += st.charAt(i + 1);
1347  
                      i++;
1348  
                  }
1349  
              }
1350  
              sb.append((char) Integer.parseInt(code, 8));
1351  
              continue;
1352  
          }
1353  
          switch (nextChar) {
1354  
          case '\\':
1355  
              ch = '\\';
1356  
              break;
1357  
          case 'b':
1358  
              ch = '\b';
1359  
              break;
1360  
          case 'f':
1361  
              ch = '\f';
1362  
              break;
1363  
          case 'n':
1364  
              ch = '\n';
1365  
              break;
1366  
          case 'r':
1367  
              ch = '\r';
1368  
              break;
1369  
          case 't':
1370  
              ch = '\t';
1371  
              break;
1372  
          case '\"':
1373  
              ch = '\"';
1374  
              break;
1375  
          case '\'':
1376  
              ch = '\'';
1377  
              break;
1378  
          // Hex Unicode: u????
1379  
          case 'u':
1380  
              if (i >= st.length() - 5) {
1381  
                  ch = 'u';
1382  
                  break;
1383  
              }
1384  
              int code = Integer.parseInt(
1385  
                      "" + st.charAt(i + 2) + st.charAt(i + 3)
1386  
                              + st.charAt(i + 4) + st.charAt(i + 5), 16);
1387  
              sb.append(Character.toChars(code));
1388  
              i += 5;
1389  
              continue;
1390  
          default:
1391  
            ch = nextChar; // added by Stefan
1392  
          }
1393  
          i++;
1394  
        }
1395  
        sb.append(ch);
1396  
      }
1397  
      return sb.toString();      
1398  
    } else
1399  
      return s; // return original
1400  
  }
1401  
static Class mc() {
1402  
  return getMainClass();
1403  
}
1404  
// currently finds only inner classes of class "main"
1405  
// returns null on not found
1406  
// this is the simple version that is not case-tolerant
1407  
static Class findClass(String name) {
1408  
  try {
1409  
    return Class.forName("main$" + name);
1410  
  } catch (ClassNotFoundException e) {
1411  
    return null;
1412  
  }
1413  
}
1414  
static boolean isTrue(Object o) {
1415  
  return booleanValue(o);
1416  
}
1417  
static boolean nempty(Collection c) {
1418  
  return !isEmpty(c);
1419  
}
1420  
1421  
static boolean nempty(CharSequence s) {
1422  
  return !isEmpty(s);
1423  
}
1424  
1425  
static boolean nempty(Object[] o) {
1426  
  return !isEmpty(o);
1427  
}
1428  
1429  
static char unquoteCharacter(String s) {
1430  
  assertTrue(s.startsWith("'") && s.length() > 1);
1431  
  return unquote("\"" + s.substring(1, s.endsWith("'") ? s.length()-1 : s.length()) + "\"").charAt(0);
1432  
}
1433  
public static String rtrim(String s) {
1434  
  int i = s.length();
1435  
  while (i > 0 && " \t\r\n".indexOf(s.charAt(i-1)) >= 0)
1436  
    --i;
1437  
  return i < s.length() ? s.substring(0, i) : s;
1438  
}
1439  
static List emptyList() {
1440  
  return new ArrayList();
1441  
  //ret Collections.emptyList();
1442  
}
1443  
static Object getOpt(Object o, String field) {
1444  
  if (o instanceof String) o = getBot ((String) o);
1445  
  if (o == null) return null;
1446  
  if (o instanceof Class) return getOpt((Class) o, field);
1447  
  
1448  
  if (o.getClass().getName().equals("main$DynamicObject"))
1449  
    return call(getOpt_raw(o, "fieldValues"), "get", field);
1450  
  
1451  
  if (o instanceof Map) return ((Map) o).get(field);
1452  
  
1453  
  return getOpt_raw(o, field);
1454  
}
1455  
1456  
static Object getOpt_raw(Object o, String field) {
1457  
  try {
1458  
    Field f = getOpt_findField(o.getClass(), field);
1459  
    if (f == null) return null;
1460  
    f.setAccessible(true);
1461  
    return f.get(o);
1462  
  } catch (Exception e) {
1463  
    throw new RuntimeException(e);
1464  
  }
1465  
}
1466  
1467  
static Object getOpt(Class c, String field) {
1468  
  try {
1469  
    Field f = getOpt_findStaticField(c, field);
1470  
    if (f == null) return null;
1471  
    f.setAccessible(true);
1472  
    return f.get(null);
1473  
  } catch (Exception e) {
1474  
    throw new RuntimeException(e);
1475  
  }
1476  
}
1477  
1478  
static Field getOpt_findStaticField(Class<?> c, String field) {
1479  
  Class _c = c;
1480  
  do {
1481  
    for (Field f : _c.getDeclaredFields())
1482  
      if (f.getName().equals(field) && (f.getModifiers() & Modifier.STATIC) != 0)
1483  
        return f;
1484  
    _c = _c.getSuperclass();
1485  
  } while (_c != null);
1486  
  return null;
1487  
}
1488  
1489  
static Field getOpt_findField(Class<?> c, String field) {
1490  
  Class _c = c;
1491  
  do {
1492  
    for (Field f : _c.getDeclaredFields())
1493  
      if (f.getName().equals(field))
1494  
        return f;
1495  
    _c = _c.getSuperclass();
1496  
  } while (_c != null);
1497  
  return null;
1498  
}
1499  
// replacement for class JavaTok
1500  
// maybe incomplete, might want to add floating point numbers
1501  
// todo also: extended multi-line strings
1502  
1503  
static List<String> javaTok(String s) {
1504  
  List<String> tok = new ArrayList<String>();
1505  
  int l = s.length();
1506  
  
1507  
  int i = 0;
1508  
  while (i < l) {
1509  
    int j = i;
1510  
    char c; String cc;
1511  
    
1512  
    // scan for whitespace
1513  
    while (j < l) {
1514  
      c = s.charAt(j);
1515  
      cc = s.substring(j, Math.min(j+2, l));
1516  
      if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
1517  
        ++j;
1518  
      else if (cc.equals("/*")) {
1519  
        do ++j; while (j < l && !s.substring(j, Math.min(j+2, l)).equals("*/"));
1520  
        j = Math.min(j+2, l);
1521  
      } else if (cc.equals("//")) {
1522  
        do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0);
1523  
      } else
1524  
        break;
1525  
    }
1526  
    
1527  
    tok.add(s.substring(i, j));
1528  
    i = j;
1529  
    if (i >= l) break;
1530  
    c = s.charAt(i); // cc is not needed in rest of loop body
1531  
    cc = s.substring(i, Math.min(i+2, l));
1532  
1533  
    // scan for non-whitespace
1534  
    if (c == '\'' || c == '"') {
1535  
      char opener = c;
1536  
      ++j;
1537  
      while (j < l) {
1538  
        if (s.charAt(j) == opener || s.charAt(j) == '\n') { // end at \n to not propagate unclosed string literal errors
1539  
          ++j;
1540  
          break;
1541  
        } else if (s.charAt(j) == '\\' && j+1 < l)
1542  
          j += 2;
1543  
        else
1544  
          ++j;
1545  
      }
1546  
    } else if (Character.isJavaIdentifierStart(c))
1547  
      do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || "'".indexOf(s.charAt(j)) >= 0)); // for stuff like "don't"
1548  
    else if (Character.isDigit(c)) {
1549  
      do ++j; while (j < l && Character.isDigit(s.charAt(j)));
1550  
      if (j < l && s.charAt(j) == 'L') ++j; // Long constants like 1L
1551  
    } else if (cc.equals("[[")) {
1552  
      do ++j; while (j+1 < l && !s.substring(j, j+2).equals("]]"));
1553  
      j = Math.min(j+2, l);
1554  
    } else if (cc.equals("[=") && i+2 < l && s.charAt(i+2) == '[') {
1555  
      do ++j; while (j+2 < l && !s.substring(j, j+3).equals("]=]"));
1556  
      j = Math.min(j+3, l);
1557  
    } else
1558  
      ++j;
1559  
1560  
    tok.add(s.substring(i, j));
1561  
    i = j;
1562  
  }
1563  
  
1564  
  if ((tok.size() % 2) == 0) tok.add("");
1565  
  return tok;
1566  
}
1567  
1568  
static List<String> javaTok(List<String> tok) {
1569  
  return javaTok(join(tok));
1570  
}
1571  
1572  
static Class getMainClass() { try {
1573  
 
1574  
  return Class.forName("main");
1575  
1576  
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
1577  
1578  
static Class getMainClass(Object o) { try {
1579  
 
1580  
  return (o instanceof Class ? (Class) o : o.getClass()).getClassLoader().loadClass("main");
1581  
1582  
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
1583  
static boolean booleanValue(Object o) {
1584  
  return eq(true, o);
1585  
}
1586  
static boolean isEmpty(Collection c) {
1587  
  return c == null || c.isEmpty();
1588  
}
1589  
1590  
static boolean isEmpty(CharSequence s) {
1591  
  return s == null || s.length() == 0;
1592  
}
1593  
1594  
static boolean isEmpty(Object[] a) {
1595  
  return a == null || a.length == 0;
1596  
}
1597  
1598  
static boolean isEmpty(Map map) {
1599  
  return map == null || map.isEmpty();
1600  
}
1601  
static String dropSuffix(String suffix, String s) {
1602  
  return s.endsWith(suffix) ? s.substring(0, l(s)-l(suffix)) : s;
1603  
}
1604  
static <A> ArrayList<A> litlist(A... a) {
1605  
  return new ArrayList<A>(Arrays.asList(a));
1606  
}
1607  
static Class<?> _getClass(String name) {
1608  
  try {
1609  
    return Class.forName(name);
1610  
  } catch (ClassNotFoundException e) {
1611  
    return null;
1612  
  }
1613  
}
1614  
1615  
static Class _getClass(Object o) {
1616  
  return o instanceof Class ? (Class) o : o.getClass();
1617  
}
1618  
1619  
static Class _getClass(Object realm, String name) { try {
1620  
 
1621  
  return getClass(realm).getClassLoader().loadClass(classNameToVM(name));
1622  
1623  
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
1624  
static void assertTrue(Object o) {
1625  
  assertEquals(true, o);
1626  
}
1627  
  
1628  
static boolean assertTrue(String msg, boolean b) {
1629  
  if (!b)
1630  
    fail(msg);
1631  
  return b;
1632  
}
1633  
1634  
static boolean assertTrue(boolean b) {
1635  
  if (!b)
1636  
    fail("oops");
1637  
  return b;
1638  
}
1639  
static int min(int a, int b) {
1640  
  return Math.min(a, b);
1641  
}
1642  
1643  
static double min(double[] c) {
1644  
  double x = Double.MAX_VALUE;
1645  
  for (double d : c) x = Math.min(x, d);
1646  
  return x;
1647  
}
1648  
1649  
static byte min(byte[] c) {
1650  
  byte x = 127;
1651  
  for (byte d : c) if (d < x) x = d;
1652  
  return x;
1653  
}
1654  
static int max(int a, int b) {
1655  
  return Math.max(a, b);
1656  
}
1657  
1658  
static long max(int a, long b) {
1659  
  return Math.max((long) a, b);
1660  
}
1661  
1662  
static long max(long a, long b) {
1663  
  return Math.max(a, b);
1664  
}
1665  
1666  
static double max(int a, double b) {
1667  
  return Math.max((double) a, b);
1668  
}
1669  
1670  
static int max(Collection<Integer> c) {
1671  
  int x = Integer.MIN_VALUE;
1672  
  for (int i : c) x = max(x, i);
1673  
  return x;
1674  
}
1675  
1676  
static double max(double[] c) {
1677  
  if (c.length == 0) return Double.MIN_VALUE;
1678  
  double x = c[0];
1679  
  for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]);
1680  
  return x;
1681  
}
1682  
1683  
static byte max(byte[] c) {
1684  
  byte x = -128;
1685  
  for (byte d : c) if (d > x) x = d;
1686  
  return x;
1687  
}
1688  
static void smartSet(Field f, Object o, Object value) throws Exception {
1689  
  f.setAccessible(true);
1690  
  
1691  
  // take care of common case (long to int)
1692  
  if (f.getType() == int.class && value instanceof Long)
1693  
    value = ((Long) value).intValue();
1694  
    
1695  
  f.set(o, value);
1696  
}
1697  
static Object getBot(String botID) {
1698  
  return callOpt(getMainBot(), "getBot", botID);
1699  
}
1700  
1701  
1702  
static String classNameToVM(String name) {
1703  
  return name.replace(".", "$");
1704  
}
1705  
static void assertEquals(Object x, Object y) {
1706  
  assertEquals(null, x, y);
1707  
}
1708  
1709  
static void assertEquals(String msg, Object x, Object y) {
1710  
  if (!(x == null ? y == null : x.equals(y)))
1711  
    fail((msg != null ? msg + ": " : "") + structure(x) + " != " + structure(y));
1712  
}
1713  
  static Object callOpt(Object o, String method, Object... args) {
1714  
    try {
1715  
      if (o == null) return null;
1716  
      if (o instanceof Class) {
1717  
        Method m = callOpt_findStaticMethod((Class) o, method, args, false);
1718  
        if (m == null) return null;
1719  
        m.setAccessible(true);
1720  
        return m.invoke(null, args);
1721  
      } else {
1722  
        Method m = callOpt_findMethod(o, method, args, false);
1723  
        if (m == null) return null;
1724  
        m.setAccessible(true);
1725  
        return m.invoke(o, args);
1726  
      }
1727  
    } catch (Exception e) {
1728  
      throw new RuntimeException(e);
1729  
    }
1730  
  }
1731  
1732  
  static Method callOpt_findStaticMethod(Class c, String method, Object[] args, boolean debug) {
1733  
    Class _c = c;
1734  
    while (c != null) {
1735  
      for (Method m : c.getDeclaredMethods()) {
1736  
        if (debug)
1737  
          System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");;
1738  
        if (!m.getName().equals(method)) {
1739  
          if (debug) System.out.println("Method name mismatch: " + method);
1740  
          continue;
1741  
        }
1742  
1743  
        if ((m.getModifiers() & Modifier.STATIC) == 0 || !callOpt_checkArgs(m, args, debug))
1744  
          continue;
1745  
1746  
        return m;
1747  
      }
1748  
      c = c.getSuperclass();
1749  
    }
1750  
    return null;
1751  
  }
1752  
1753  
  static Method callOpt_findMethod(Object o, String method, Object[] args, boolean debug) {
1754  
    Class c = o.getClass();
1755  
    while (c != null) {
1756  
      for (Method m : c.getDeclaredMethods()) {
1757  
        if (debug)
1758  
          System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");;
1759  
        if (m.getName().equals(method) && callOpt_checkArgs(m, args, debug))
1760  
          return m;
1761  
      }
1762  
      c = c.getSuperclass();
1763  
    }
1764  
    return null;
1765  
  }
1766  
1767  
  private static boolean callOpt_checkArgs(Method m, Object[] args, boolean debug) {
1768  
    Class<?>[] types = m.getParameterTypes();
1769  
    if (types.length != args.length) {
1770  
      if (debug)
1771  
        System.out.println("Bad parameter length: " + args.length + " vs " + types.length);
1772  
      return false;
1773  
    }
1774  
    for (int i = 0; i < types.length; i++)
1775  
      if (!(args[i] == null || isInstanceX(types[i], args[i]))) {
1776  
        if (debug)
1777  
          System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]);
1778  
        return false;
1779  
      }
1780  
    return true;
1781  
  }
1782  
1783  
1784  
static Object mainBot;
1785  
1786  
static Object getMainBot() {
1787  
  return mainBot;
1788  
}
1789  
static Class<?> getClass(String name) {
1790  
  try {
1791  
    return Class.forName(name);
1792  
  } catch (ClassNotFoundException e) {
1793  
    return null;
1794  
  }
1795  
}
1796  
1797  
static Class getClass(Object o) {
1798  
  return o instanceof Class ? (Class) o : o.getClass();
1799  
}
1800  
1801  
static Class getClass(Object realm, String name) { try {
1802  
 
1803  
  return getClass(realm).getClassLoader().loadClass(classNameToVM(name));
1804  
1805  
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
1806  
1807  
static class ProgramScan {
1808  
  static int threads = isWindows() ? 500 : 10;
1809  
  static int timeout = 5000; // hmm...
1810  
  static String ip = "127.0.0.1";
1811  
  static int quickScanFrom = 10000, quickScanTo = 10999;
1812  
  static int maxNumberOfBotPorts = 100;
1813  
  static boolean verbose;
1814  
  
1815  
  static class Program {
1816  
    int port;
1817  
    String helloString;
1818  
    
1819  
    Program(int port, String helloString) {
1820  
  this.helloString = helloString;
1821  
  this.port = port;}
1822  
  }
1823  
  
1824  
  static List<Program> scan() { try {
1825  
 
1826  
    return scan(1, 65535);
1827  
  
1828  
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
1829  
  
1830  
  static List<Program> scan(int fromPort, int toPort) {
1831  
    return scan(fromPort, toPort, new int[0]);
1832  
  }
1833  
  
1834  
  static List<Program> scan(int fromPort, int toPort, int[] preferredPorts) { try {
1835  
 
1836  
    Set<Integer> preferredPortsSet = new HashSet<Integer>(asList(preferredPorts));
1837  
    String name = toPort < 10000 ? "bot" : "program";
1838  
    final ExecutorService es = Executors.newFixedThreadPool(threads);
1839  
    if (verbose) print(firstToUpper(name) + "-scanning " + ip + " with timeout " + timeout + " ms in " + threads + " threads.");
1840  
    startTiming();
1841  
    List<Future<Program>> futures = new ArrayList<Future<Program>>();
1842  
    for (int port : preferredPorts)
1843  
      futures.add(checkPort(es, ip, port, timeout));
1844  
    for (int port = fromPort; port <= toPort; port++)
1845  
      if (!preferredPortsSet.contains(port))
1846  
        futures.add(checkPort(es, ip, port, timeout));
1847  
    es.shutdown();
1848  
    List<Program> programs = new ArrayList<Program>();
1849  
    for (final Future<Program> f : futures) {
1850  
      Program p = f.get();
1851  
      if (p != null)
1852  
        programs.add(p);
1853  
    }
1854  
    stopTiming();
1855  
    if (verbose) print("Found " + programs.size() + " " + name + "(s) on " + ip);
1856  
    return programs;
1857  
  
1858  
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
1859  
1860  
  static Future<Program> checkPort(final ExecutorService es, final String ip, final int port, final int timeout) {
1861  
    return es.submit(new Callable<Program>() {
1862  
        @Override public Program call() {
1863  
          try {
1864  
            Socket socket = new Socket();
1865  
            socket.setSoTimeout(timeout);
1866  
            socket.connect(new InetSocketAddress(ip, port), timeout);
1867  
            if (verbose) print("Connected to " + ip + ":" + port);
1868  
            BufferedReader in = new BufferedReader(
1869  
              new InputStreamReader(socket.getInputStream(), "UTF-8"));
1870  
            String hello = or(in.readLine(), "?");
1871  
            socket.close();
1872  
            return new Program(port, hello);
1873  
          } catch (Exception ex) {
1874  
            return null;
1875  
          }
1876  
        }
1877  
     });
1878  
  }
1879  
  
1880  
  static List<Program> quickScan() {
1881  
    return scan(quickScanFrom, quickScanTo);
1882  
  }
1883  
  
1884  
  static List<Program> quickBotScan() {
1885  
    return quickBotScan(new int[0]);
1886  
  }
1887  
  
1888  
  static List<Program> quickBotScan(int[] preferredPorts) {
1889  
    return scan(4990, 5000+maxNumberOfBotPorts-1, preferredPorts);
1890  
  }
1891  
}
1892  
1893  
  static abstract class DialogIO {
1894  
    String line;
1895  
    boolean eos;
1896  
    
1897  
    abstract String readLineImpl();
1898  
    abstract boolean isStillConnected();
1899  
    abstract void sendLine(String line);
1900  
    abstract boolean isLocalConnection();
1901  
    abstract Socket getSocket();
1902  
    abstract void close();
1903  
    
1904  
    int getPort() { return getSocket().getPort(); }
1905  
    
1906  
    boolean helloRead;
1907  
    
1908  
    String readLineNoBlock() {
1909  
      String l = line;
1910  
      line = null;
1911  
      return l;
1912  
    }
1913  
    
1914  
    boolean waitForLine() { try {
1915  
 
1916  
      if (line != null) return true;
1917  
      //print("Readline");
1918  
      line = readLineImpl();
1919  
      //print("Readline done: " + line);
1920  
      if (line == null) eos = true;
1921  
      return line != null;
1922  
    
1923  
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
1924  
    
1925  
    String readLine() {
1926  
      waitForLine();
1927  
      helloRead = true;
1928  
      return readLineNoBlock();
1929  
    }
1930  
    
1931  
    String ask(String s, Object... args) {
1932  
      if (!helloRead) readLine();
1933  
      if (args.length != 0) s = format3(s, args);
1934  
      sendLine(s);
1935  
      return readLine();
1936  
    }
1937  
    
1938  
    String askLoudly(String s, Object... args) {
1939  
      if (!helloRead) readLine();
1940  
      if (args.length != 0) s = format3(s, args);
1941  
      print("> " + s);
1942  
      sendLine(s);
1943  
      String answer = readLine();
1944  
      print("< " + answer);
1945  
      return answer;
1946  
    }
1947  
    
1948  
    void pushback(String l) {
1949  
      if (line != null)
1950  
        fail();
1951  
      line = l;
1952  
      helloRead = false;
1953  
    }
1954  
  }
1955  
  
1956  
  static abstract class DialogHandler {
1957  
    abstract void run(DialogIO io);
1958  
  }
1959  
1960  
static long startTiming_startTime;
1961  
static void startTiming() {
1962  
  startTiming_startTime = now();
1963  
}
1964  
1965  
static void stopTiming() {
1966  
  long end = now();
1967  
  print("Time: " + (end-startTiming_startTime) + " ms");
1968  
}
1969  
public static boolean isWindows() {
1970  
  return System.getProperty("os.name").contains("Windows");
1971  
}
1972  
static <A> A or(A a, A b) {
1973  
  return a != null ? a : b;
1974  
}
1975  
static String firstToUpper(String s) {
1976  
  if (s.length() == 0) return s;
1977  
  return Character.toUpperCase(s.charAt(0)) + s.substring(1);
1978  
}
1979  
static BufferedReader readLine_reader;
1980  
1981  
static String readLine() {
1982  
  return (String) call(getJavaX(), "readLine");
1983  
}
1984  
static <A> ArrayList<A> asList(A[] a) {
1985  
  return new ArrayList<A>(Arrays.asList(a));
1986  
}
1987  
1988  
static ArrayList<Integer> asList(int[] a) {
1989  
  ArrayList<Integer> l = new ArrayList();
1990  
  for (int i : a) l.add(i);
1991  
  return l;
1992  
}
1993  
1994  
static <A> ArrayList<A> asList(Collection<A> s) {
1995  
  return s == null ? new ArrayList() 
1996  
    : s instanceof ArrayList ? (ArrayList) s : new ArrayList(s);
1997  
}
1998  
1999  
static long now_virtualTime;
2000  
static long now() {
2001  
  return now_virtualTime != 0 ? now_virtualTime : System.currentTimeMillis();
2002  
}
2003  
2004  
}

download  show line numbers  debug dex  old transpilations   

Travelled to 14 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, ddnzoavkxhuk, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #3000389
Snippet name: Temp program by #1001628
Eternal ID of this version: #3000389/1
Text MD5: 56a4d6e854f19b18e87a1840ad817b6b
Author: someone
Category:
Type: JavaX source code
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2016-07-17 23:46:08
Source code size: 57407 bytes / 2004 lines
Pitched / IR pitched: No / No
Views / Downloads: 534 / 504
Referenced in: [show references]