1 | [21902 ms] 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 java.util.concurrent.locks.*; |
8 | import javax.swing.*; |
9 | import javax.swing.event.*; |
10 | import javax.swing.text.*; |
11 | import javax.swing.table.*; |
12 | import java.io.*; |
13 | import java.net.*; |
14 | import java.lang.reflect.*; |
15 | import java.lang.ref.*; |
16 | import java.lang.management.*; |
17 | import java.security.*; |
18 | import java.security.spec.*; |
19 | import java.awt.*; |
20 | import java.awt.event.*; |
21 | import java.awt.image.*; |
22 | import javax.imageio.*; |
23 | import java.math.*; |
24 | class main { |
25 | |
26 | static Map<Thread, Boolean> _registerThread_threads = newWeakHashMap(); |
27 | |
28 | static Thread _registerThread(Thread t) { |
29 | _registerThread_threads.put(t, true); |
30 | return t; |
31 | } |
32 | |
33 | static void _registerThread() { _registerThread(Thread.currentThread()); } |
34 | static Pair<String, List<String>> tok_parseFunctionCall(String s) { |
35 | return tok_parseFunctionCall(javaTok(s)); |
36 | } |
37 | |
38 | static Pair<String, List<String>> tok_parseFunctionCall(List<String> tok) { |
39 | if (!(isIdentifier(get(tok, 1)) && eqGet(tok, 3, "("))) return null; |
40 | Map<Integer, Integer> bracketMap = getBracketMap(tok); |
41 | if (neq(bracketMap.get(3), l(tok)-2)) return null; |
42 | int i = 5, argStart = 5; |
43 | List<String> args = new ArrayList(); |
44 | while (i < l(tok)-2) { |
45 | Integer j = bracketMap.get(i); |
46 | if (j != null) { i = j+2; continue; } |
47 | if (eqGetOneOf(tok, i, ",")) { |
48 | if (i > argStart) args.add(trimJoinSubList(tok, argStart, i)); |
49 | argStart = i+2; |
50 | } |
51 | i += 2; |
52 | } |
53 | if (i > argStart) args.add(trimJoinSubList(tok, argStart, i)); |
54 | return pair(tok.get(1), args); |
55 | } |
56 | |
57 | |
58 | static boolean isIdentifier(String s) { |
59 | return isJavaIdentifier(s); |
60 | } |
61 | // map: index of opening bracket -> index of closing bracket |
62 | static Map<Integer, Integer> getBracketMap(List tok) { |
63 | TreeMap<Integer,Integer> map = new TreeMap(); |
64 | List<Integer> stack = new ArrayList(); |
65 | for (int i = 1; i < l(tok); i+= 2) { |
66 | if (getBracketMap_opening.contains(tok.get(i))) |
67 | stack.add(i); |
68 | else if (getBracketMap_closing.contains(tok.get(i))) { |
69 | if (!empty(stack)) |
70 | map.put(liftLast(stack), i); |
71 | } |
72 | } |
73 | return map; |
74 | } |
75 | |
76 | static List<String> getBracketMap_opening = ll("{", "("); |
77 | static List<String> getBracketMap_closing = ll("}", ")"); |
78 | static <A> boolean eqGetOneOf(List<A> l, int i, A... options) { |
79 | return eqOneOf(get(l, i), options); |
80 | } |
81 | // replacement for class JavaTok |
82 | // maybe incomplete, might want to add floating point numbers |
83 | // todo also: extended multi-line strings |
84 | |
85 | static int javaTok_n, javaTok_elements; |
86 | static boolean javaTok_opt; |
87 | |
88 | static List<String> javaTok(String s) { |
89 | return javaTok(s, null); |
90 | } |
91 | |
92 | static List<String> javaTok(String s, List<String> existing) { |
93 | ++javaTok_n; |
94 | int nExisting = javaTok_opt && existing != null ? existing.size() : 0; |
95 | ArrayList<String> tok = existing != null ? new ArrayList(nExisting) : new ArrayList(); |
96 | int l = s.length(); |
97 | |
98 | int i = 0, n = 0; |
99 | while (i < l) { |
100 | int j = i; |
101 | char c, d; |
102 | |
103 | // scan for whitespace |
104 | while (j < l) { |
105 | c = s.charAt(j); |
106 | d = j+1 >= l ? '\0' : s.charAt(j+1); |
107 | if (c == ' ' || c == '\t' || c == '\r' || c == '\n') |
108 | ++j; |
109 | else if (c == '/' && d == '*') { |
110 | do ++j; while (j < l && !s.substring(j, Math.min(j+2, l)).equals("*/")); |
111 | j = Math.min(j+2, l); |
112 | } else if (c == '/' && d == '/') { |
113 | do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0); |
114 | } else |
115 | break; |
116 | } |
117 | |
118 | if (n < nExisting && javaTok_isCopyable(existing.get(n), s, i, j)) |
119 | tok.add(existing.get(n)); |
120 | else |
121 | tok.add(javaTok_substringN(s, i, j)); |
122 | ++n; |
123 | i = j; |
124 | if (i >= l) break; |
125 | c = s.charAt(i); |
126 | d = i+1 >= l ? '\0' : s.charAt(i+1); |
127 | |
128 | // scan for non-whitespace |
129 | |
130 | // Special JavaX syntax: 'identifier |
131 | if (c == '\'' && Character.isJavaIdentifierStart(d) && i+2 < l && "'\\".indexOf(s.charAt(i+2)) < 0) { |
132 | j += 2; |
133 | while (j < l && Character.isJavaIdentifierPart(s.charAt(j))) |
134 | ++j; |
135 | } else if (c == '\'' || c == '"') { |
136 | char opener = c; |
137 | ++j; |
138 | while (j < l) { |
139 | if (s.charAt(j) == opener /*|| s.charAt(j) == '\n'*/) { // allow multi-line strings |
140 | ++j; |
141 | break; |
142 | } else if (s.charAt(j) == '\\' && j+1 < l) |
143 | j += 2; |
144 | else |
145 | ++j; |
146 | } |
147 | } else if (Character.isJavaIdentifierStart(c)) |
148 | do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || "'".indexOf(s.charAt(j)) >= 0)); // for stuff like "don't" |
149 | else if (Character.isDigit(c)) { |
150 | do ++j; while (j < l && Character.isDigit(s.charAt(j))); |
151 | if (j < l && s.charAt(j) == 'L') ++j; // Long constants like 1L |
152 | } else if (c == '[' && d == '[') { |
153 | do ++j; while (j+1 < l && !s.substring(j, j+2).equals("]]")); |
154 | j = Math.min(j+2, l); |
155 | } else if (c == '[' && d == '=' && i+2 < l && s.charAt(i+2) == '[') { |
156 | do ++j; while (j+2 < l && !s.substring(j, j+3).equals("]=]")); |
157 | j = Math.min(j+3, l); |
158 | } else |
159 | ++j; |
160 | |
161 | if (n < nExisting && javaTok_isCopyable(existing.get(n), s, i, j)) |
162 | tok.add(existing.get(n)); |
163 | else |
164 | tok.add(javaTok_substringC(s, i, j)); |
165 | ++n; |
166 | i = j; |
167 | } |
168 | |
169 | if ((tok.size() % 2) == 0) tok.add(""); |
170 | javaTok_elements += tok.size(); |
171 | return tok; |
172 | } |
173 | |
174 | static List<String> javaTok(List<String> tok) { |
175 | return javaTok(join(tok), tok); |
176 | } |
177 | |
178 | static boolean javaTok_isCopyable(String t, String s, int i, int j) { |
179 | return t.length() == j-i |
180 | && s.regionMatches(i, t, 0, j-i); // << could be left out, but that's brave |
181 | } |
182 | static boolean eqGet(List l, int i, Object o) { |
183 | return eq(get(l, i), o); |
184 | } |
185 | static <A, B> Map<A, B> newWeakHashMap() { |
186 | return _registerWeakMap(synchroMap(new WeakHashMap())); |
187 | } |
188 | static int l(Object[] a) { return a == null ? 0 : a.length; } |
189 | static int l(boolean[] a) { return a == null ? 0 : a.length; } |
190 | static int l(byte[] a) { return a == null ? 0 : a.length; } |
191 | static int l(int[] a) { return a == null ? 0 : a.length; } |
192 | static int l(float[] a) { return a == null ? 0 : a.length; } |
193 | static int l(char[] a) { return a == null ? 0 : a.length; } |
194 | static int l(Collection c) { return c == null ? 0 : c.size(); } |
195 | static int l(Map m) { return m == null ? 0 : m.size(); } |
196 | static int l(CharSequence s) { return s == null ? 0 : s.length(); } static long l(File f) { return f == null ? 0 : f.length(); } |
197 | |
198 | static int l(Object o) { |
199 | return o instanceof String ? l((String) o) |
200 | : o instanceof Map ? l((Map) o) |
201 | : l((Collection) o); // incomplete |
202 | } |
203 | |
204 | |
205 | |
206 | |
207 | static <A, B> Pair<A, B> pair(A a, B b) { |
208 | return new Pair(a, b); |
209 | } |
210 | |
211 | static <A> Pair<A, A> pair(A a) { |
212 | return new Pair(a, a); |
213 | } |
214 | // get purpose 1: access a list/array/map (safer version of x.get(y)) |
215 | |
216 | static <A> A get(List<A> l, int idx) { |
217 | return l != null && idx >= 0 && idx < l(l) ? l.get(idx) : null; |
218 | } |
219 | |
220 | // seems to conflict with other signatures |
221 | /*static <A, B> B get(Map<A, B> map, A key) { |
222 | ret map != null ? map.get(key) : null; |
223 | }*/ |
224 | |
225 | static <A> A get(A[] l, int idx) { |
226 | return idx >= 0 && idx < l(l) ? l[idx] : null; |
227 | } |
228 | |
229 | // default to false |
230 | static boolean get(boolean[] l, int idx) { |
231 | return idx >= 0 && idx < l(l) ? l[idx] : false; |
232 | } |
233 | |
234 | // get purpose 2: access a field by reflection or a map |
235 | |
236 | static Object get(Object o, String field) { |
237 | try { |
238 | if (o instanceof Class) return get((Class) o, field); |
239 | |
240 | if (o instanceof Map) |
241 | return ((Map) o).get(field); |
242 | |
243 | Field f = getOpt_findField(o.getClass(), field); |
244 | if (f != null) { |
245 | f.setAccessible(true); |
246 | return f.get(o); |
247 | } |
248 | |
249 | |
250 | } catch (Exception e) { |
251 | throw asRuntimeException(e); |
252 | } |
253 | throw new RuntimeException("Field '" + field + "' not found in " + o.getClass().getName()); |
254 | } |
255 | |
256 | static Object get_raw(Object o, String field) { |
257 | try { |
258 | Field f = get_findField(o.getClass(), field); |
259 | f.setAccessible(true); |
260 | return f.get(o); |
261 | } catch (Exception e) { |
262 | throw new RuntimeException(e); |
263 | } |
264 | } |
265 | |
266 | static Object get(Class c, String field) { |
267 | try { |
268 | Field f = get_findStaticField(c, field); |
269 | f.setAccessible(true); |
270 | return f.get(null); |
271 | } catch (Exception e) { |
272 | throw new RuntimeException(e); |
273 | } |
274 | } |
275 | |
276 | static Field get_findStaticField(Class<?> c, String field) { |
277 | Class _c = c; |
278 | do { |
279 | for (Field f : _c.getDeclaredFields()) |
280 | if (f.getName().equals(field) && (f.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0) |
281 | return f; |
282 | _c = _c.getSuperclass(); |
283 | } while (_c != null); |
284 | throw new RuntimeException("Static field '" + field + "' not found in " + c.getName()); |
285 | } |
286 | |
287 | static Field get_findField(Class<?> c, String field) { |
288 | Class _c = c; |
289 | do { |
290 | for (Field f : _c.getDeclaredFields()) |
291 | if (f.getName().equals(field)) |
292 | return f; |
293 | _c = _c.getSuperclass(); |
294 | } while (_c != null); |
295 | throw new RuntimeException("Field '" + field + "' not found in " + c.getName()); |
296 | } |
297 | |
298 | static boolean neq(Object a, Object b) { |
299 | return !eq(a, b); |
300 | } |
301 | static String trimJoinSubList(List<String> l, int i, int j) { |
302 | return trim(join(subList(l, i, j))); |
303 | } |
304 | |
305 | static String trimJoinSubList(List<String> l, int i) { |
306 | return trim(join(subList(l, i))); |
307 | } |
308 | |
309 | |
310 | static <A> List<A> ll(A... a) { |
311 | ArrayList l = new ArrayList(a.length); |
312 | for (A x : a) l.add(x); |
313 | return l; |
314 | } |
315 | static Map synchroMap() { |
316 | return synchroHashMap(); |
317 | } |
318 | |
319 | static <A, B> Map<A, B> synchroMap(Map<A, B> map) { |
320 | return Collections.synchronizedMap(map); |
321 | } |
322 | static <A> A liftLast(List<A> l) { |
323 | if (l.isEmpty()) return null; |
324 | int i = l(l)-1; |
325 | A a = l.get(i); |
326 | l.remove(i); |
327 | return a; |
328 | } |
329 | static String javaTok_substringC(String s, int i, int j) { |
330 | return s.substring(i, j); |
331 | } |
332 | static String javaTok_substringN(String s, int i, int j) { |
333 | if (i == j) return ""; |
334 | if (j == i+1 && s.charAt(i) == ' ') return " "; |
335 | return s.substring(i, j); |
336 | } |
337 | static boolean empty(Collection c) { return c == null || c.isEmpty(); } |
338 | static boolean empty(String s) { return s == null || s.length() == 0; } |
339 | static boolean empty(Map map) { return map == null || map.isEmpty(); } |
340 | static boolean empty(Object[] o) { return o == null || o.length == 0; } |
341 | static boolean empty(Object o) { |
342 | if (o instanceof Collection) return empty((Collection) o); |
343 | if (o instanceof String) return empty((String) o); |
344 | if (o instanceof Map) return empty((Map) o); |
345 | if (o instanceof Object[]) return empty((Object[]) o); |
346 | if (o == null) return true; |
347 | throw fail("unknown type for 'empty': " + getType(o)); |
348 | } |
349 | |
350 | static boolean empty(float[] a) { return a == null || a.length == 0; } |
351 | static boolean empty(int[] a) { return a == null || a.length == 0; } |
352 | static boolean empty(long[] a) { return a == null || a.length == 0; } |
353 | static RuntimeException asRuntimeException(Throwable t) { |
354 | |
355 | if (t instanceof Error) |
356 | _handleError((Error) t); |
357 | |
358 | return t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t); |
359 | } |
360 | static String trim(String s) { return s == null ? null : s.trim(); } |
361 | static String trim(StringBuilder buf) { return buf.toString().trim(); } |
362 | static String trim(StringBuffer buf) { return buf.toString().trim(); } |
363 | public static String join(String glue, Iterable<String> strings) { |
364 | if (strings == null) return ""; |
365 | StringBuilder buf = new StringBuilder(); |
366 | Iterator<String> i = strings.iterator(); |
367 | if (i.hasNext()) { |
368 | buf.append(i.next()); |
369 | while (i.hasNext()) |
370 | buf.append(glue).append(i.next()); |
371 | } |
372 | return buf.toString(); |
373 | } |
374 | |
375 | public static String join(String glue, String... strings) { |
376 | return join(glue, Arrays.asList(strings)); |
377 | } |
378 | |
379 | static String join(Iterable<String> strings) { |
380 | return join("", strings); |
381 | } |
382 | |
383 | static String join(Iterable<String> strings, String glue) { |
384 | return join(glue, strings); |
385 | } |
386 | |
387 | public static String join(String[] strings) { |
388 | return join("", strings); |
389 | } |
390 | |
391 | |
392 | static String join(String glue, Pair p) { |
393 | return p == null ? "" : str(p.a) + glue + str(p.b); |
394 | } |
395 | |
396 | static <A> List<A> subList(List<A> l, int startIndex) { |
397 | return subList(l, startIndex, l(l)); |
398 | } |
399 | |
400 | static <A> List<A> subList(List<A> l, int startIndex, int endIndex) { |
401 | startIndex = max(0, min(l(l), startIndex)); |
402 | endIndex = max(0, min(l(l), endIndex)); |
403 | if (startIndex > endIndex) return litlist(); |
404 | return l.subList(startIndex, endIndex); |
405 | } |
406 | |
407 | |
408 | static boolean eqOneOf(Object o, Object... l) { |
409 | for (Object x : l) if (eq(o, x)) return true; return false; |
410 | } |
411 | static boolean eq(Object a, Object b) { |
412 | return a == null ? b == null : a == b || a.equals(b); |
413 | } |
414 | |
415 | // a little kludge for stuff like eq(symbol, "$X") |
416 | |
417 | static List _registerWeakMap_preList; |
418 | |
419 | static <A> A _registerWeakMap(A map) { |
420 | if (javax() == null) { |
421 | // We're in class init |
422 | if (_registerWeakMap_preList == null) _registerWeakMap_preList = synchroList(); |
423 | _registerWeakMap_preList.add(map); |
424 | return map; |
425 | } |
426 | |
427 | try { |
428 | call(javax(), "_registerWeakMap", map); |
429 | } catch (Throwable e) { |
430 | printException(e); |
431 | print("Upgrade JavaX!!"); |
432 | } |
433 | return map; |
434 | } |
435 | |
436 | static void _onLoad_registerWeakMap() { |
437 | assertNotNull(javax()); |
438 | if (_registerWeakMap_preList == null) return; |
439 | for (Object o : _registerWeakMap_preList) |
440 | _registerWeakMap(o); |
441 | _registerWeakMap_preList = null; |
442 | } |
443 | static Field getOpt_findField(Class<?> c, String field) { |
444 | Class _c = c; |
445 | do { |
446 | for (Field f : _c.getDeclaredFields()) |
447 | if (f.getName().equals(field)) |
448 | return f; |
449 | _c = _c.getSuperclass(); |
450 | } while (_c != null); |
451 | return null; |
452 | } |
453 | static boolean isJavaIdentifier(String s) { |
454 | if (empty(s) || !Character.isJavaIdentifierStart(s.charAt(0))) |
455 | return false; |
456 | for (int i = 1; i < s.length(); i++) |
457 | if (!Character.isJavaIdentifierPart(s.charAt(i))) |
458 | return false; |
459 | return true; |
460 | } |
461 | |
462 | |
463 | static AtomicLong _handleError_nonVMErrors = new AtomicLong(); |
464 | static AtomicLong _handleError_vmErrors = new AtomicLong(); |
465 | static AtomicLong _handleError_outOfMemoryErrors = new AtomicLong(); |
466 | static volatile long _handleError_lastOutOfMemoryError; |
467 | static volatile Error _handleError_lastHardError; |
468 | |
469 | static void _handleError(Error e) { |
470 | if (!(e instanceof VirtualMachineError)) { |
471 | incAtomicLong(_handleError_nonVMErrors); |
472 | return; |
473 | } |
474 | |
475 | print("\nHARD ERROR\n"); |
476 | printStackTrace2(e); |
477 | print("\nHARD ERROR\n"); |
478 | _handleError_lastHardError = e; |
479 | |
480 | incAtomicLong(_handleError_vmErrors); |
481 | if (e instanceof OutOfMemoryError) { |
482 | incAtomicLong(_handleError_outOfMemoryErrors); |
483 | _handleError_lastOutOfMemoryError = sysNow(); |
484 | } |
485 | } |
486 | static int min(int a, int b) { |
487 | return Math.min(a, b); |
488 | } |
489 | |
490 | static long min(long a, long b) { |
491 | return Math.min(a, b); |
492 | } |
493 | |
494 | static float min(float a, float b) { return Math.min(a, b); } |
495 | static float min(float a, float b, float c) { return min(min(a, b), c); } |
496 | |
497 | static double min(double a, double b) { |
498 | return Math.min(a, b); |
499 | } |
500 | |
501 | static double min(double[] c) { |
502 | double x = Double.MAX_VALUE; |
503 | for (double d : c) x = Math.min(x, d); |
504 | return x; |
505 | } |
506 | |
507 | static float min(float[] c) { |
508 | float x = Float.MAX_VALUE; |
509 | for (float d : c) x = Math.min(x, d); |
510 | return x; |
511 | } |
512 | |
513 | static byte min(byte[] c) { |
514 | byte x = 127; |
515 | for (byte d : c) if (d < x) x = d; |
516 | return x; |
517 | } |
518 | |
519 | static short min(short[] c) { |
520 | short x = 0x7FFF; |
521 | for (short d : c) if (d < x) x = d; |
522 | return x; |
523 | } |
524 | static Class javax() { |
525 | return getJavaX(); |
526 | } |
527 | static <A> ArrayList<A> litlist(A... a) { |
528 | ArrayList l = new ArrayList(a.length); |
529 | for (A x : a) l.add(x); |
530 | return l; |
531 | } |
532 | static <A> A assertNotNull(A a) { |
533 | assertTrue(a != null); |
534 | return a; |
535 | } |
536 | |
537 | static <A> A assertNotNull(String msg, A a) { |
538 | assertTrue(msg, a != null); |
539 | return a; |
540 | } |
541 | static <A> List<A> synchroList() { |
542 | return Collections.synchronizedList(new ArrayList<A>()); |
543 | } |
544 | |
545 | static <A> List<A> synchroList(List<A> l) { |
546 | return Collections.synchronizedList(l); |
547 | } |
548 | |
549 | static int max(int a, int b) { return Math.max(a, b); } |
550 | static int max(int a, int b, int c) { return max(max(a, b), c); } |
551 | static long max(int a, long b) { return Math.max((long) a, b); } |
552 | static long max(long a, long b) { return Math.max(a, b); } |
553 | static double max(int a, double b) { return Math.max((double) a, b); } |
554 | static float max(float a, float b) { return Math.max(a, b); } |
555 | static double max(double a, double b) { return Math.max(a, b); } |
556 | |
557 | static int max(Collection<Integer> c) { |
558 | int x = Integer.MIN_VALUE; |
559 | for (int i : c) x = max(x, i); |
560 | return x; |
561 | } |
562 | |
563 | static double max(double[] c) { |
564 | if (c.length == 0) return Double.MIN_VALUE; |
565 | double x = c[0]; |
566 | for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]); |
567 | return x; |
568 | } |
569 | |
570 | static float max(float[] c) { |
571 | if (c.length == 0) return Float.MAX_VALUE; |
572 | float x = c[0]; |
573 | for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]); |
574 | return x; |
575 | } |
576 | |
577 | static byte max(byte[] c) { |
578 | byte x = -128; |
579 | for (byte d : c) if (d > x) x = d; |
580 | return x; |
581 | } |
582 | |
583 | static short max(short[] c) { |
584 | short x = -0x8000; |
585 | for (short d : c) if (d > x) x = d; |
586 | return x; |
587 | } |
588 | static void printException(Throwable e) { |
589 | printStackTrace(e); |
590 | } |
591 | static String str(Object o) { |
592 | return o == null ? "null" : o.toString(); |
593 | } |
594 | |
595 | static String str(char[] c) { |
596 | return new String(c); |
597 | } |
598 | static Object call(Object o) { |
599 | return callFunction(o); |
600 | } |
601 | |
602 | // varargs assignment fixer for a single string array argument |
603 | static Object call(Object o, String method, String[] arg) { |
604 | return call(o, method, new Object[] {arg}); |
605 | } |
606 | |
607 | static Object call(Object o, String method, Object... args) { |
608 | try { |
609 | if (o instanceof Class) { |
610 | Method m = call_findStaticMethod((Class) o, method, args, false); |
611 | m.setAccessible(true); |
612 | return m.invoke(null, args); |
613 | } else { |
614 | Method m = call_findMethod(o, method, args, false); |
615 | m.setAccessible(true); |
616 | return m.invoke(o, args); |
617 | } |
618 | } catch (Exception e) { |
619 | throw e instanceof RuntimeException ? (RuntimeException) e : new RuntimeException(e); |
620 | } |
621 | } |
622 | |
623 | static Method call_findStaticMethod(Class c, String method, Object[] args, boolean debug) { |
624 | Class _c = c; |
625 | while (c != null) { |
626 | for (Method m : c.getDeclaredMethods()) { |
627 | if (debug) |
628 | System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");; |
629 | if (!m.getName().equals(method)) { |
630 | if (debug) System.out.println("Method name mismatch: " + method); |
631 | continue; |
632 | } |
633 | |
634 | if ((m.getModifiers() & java.lang.reflect.Modifier.STATIC) == 0 || !call_checkArgs(m, args, debug)) |
635 | continue; |
636 | |
637 | return m; |
638 | } |
639 | c = c.getSuperclass(); |
640 | } |
641 | throw new RuntimeException("Method '" + method + "' (static) with " + args.length + " parameter(s) not found in " + _c.getName()); |
642 | } |
643 | |
644 | static Method call_findMethod(Object o, String method, Object[] args, boolean debug) { |
645 | Class c = o.getClass(); |
646 | while (c != null) { |
647 | for (Method m : c.getDeclaredMethods()) { |
648 | if (debug) |
649 | System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");; |
650 | if (m.getName().equals(method) && call_checkArgs(m, args, debug)) |
651 | return m; |
652 | } |
653 | c = c.getSuperclass(); |
654 | } |
655 | throw new RuntimeException("Method '" + method + "' (non-static) with " + args.length + " parameter(s) not found in " + o.getClass().getName()); |
656 | } |
657 | |
658 | private static boolean call_checkArgs(Method m, Object[] args, boolean debug) { |
659 | Class<?>[] types = m.getParameterTypes(); |
660 | if (types.length != args.length) { |
661 | if (debug) |
662 | System.out.println("Bad parameter length: " + args.length + " vs " + types.length); |
663 | return false; |
664 | } |
665 | for (int i = 0; i < types.length; i++) |
666 | if (!(args[i] == null || isInstanceX(types[i], args[i]))) { |
667 | if (debug) |
668 | System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]); |
669 | return false; |
670 | } |
671 | return true; |
672 | } |
673 | static RuntimeException fail() { throw new RuntimeException("fail"); } |
674 | static RuntimeException fail(Throwable e) { throw asRuntimeException(e); } |
675 | static RuntimeException fail(Object msg) { throw new RuntimeException(String.valueOf(msg)); } |
676 | static RuntimeException fail(String msg) { throw new RuntimeException(msg == null ? "" : msg); } |
677 | static RuntimeException fail(String msg, Throwable innerException) { throw new RuntimeException(msg, innerException); } |
678 | |
679 | static volatile StringBuffer local_log = new StringBuffer(); // not redirected |
680 | static volatile StringBuffer print_log = local_log; // might be redirected, e.g. to main bot |
681 | |
682 | // in bytes - will cut to half that |
683 | static volatile int print_log_max = 1024*1024; |
684 | static volatile int local_log_max = 100*1024; |
685 | //static int print_maxLineLength = 0; // 0 = unset |
686 | |
687 | static boolean print_silent; // total mute if set |
688 | |
689 | static Object print_byThread_lock = new Object(); |
690 | static volatile ThreadLocal<Object> print_byThread; // special handling by thread - prefers F1<S, Bool> |
691 | |
692 | static void print() { |
693 | print(""); |
694 | } |
695 | |
696 | // slightly overblown signature to return original object... |
697 | static <A> A print(A o) { |
698 | ping(); |
699 | if (print_silent) return o; |
700 | String s = String.valueOf(o) + "\n"; |
701 | print_noNewLine(s); |
702 | return o; |
703 | } |
704 | |
705 | static void print_noNewLine(String s) { |
706 | |
707 | if (print_byThread != null) { |
708 | Object f = print_byThread.get(); |
709 | if (f != null) |
710 | if (isFalse(f instanceof F1 ? ((F1) f).get(s) : callF(f, s))) return; |
711 | } |
712 | |
713 | |
714 | print_raw(s); |
715 | } |
716 | |
717 | static void print_raw(String s) { |
718 | s = fixNewLines(s); |
719 | // TODO if (print_maxLineLength != 0) |
720 | StringBuffer loc = local_log; |
721 | StringBuffer buf = print_log; |
722 | int loc_max = print_log_max; |
723 | if (buf != loc && buf != null) { |
724 | print_append(buf, s, print_log_max); |
725 | loc_max = local_log_max; |
726 | } |
727 | if (loc != null) |
728 | print_append(loc, s, loc_max); |
729 | System.out.print(s); |
730 | } |
731 | |
732 | static void print(long l) { |
733 | print(String.valueOf(l)); |
734 | } |
735 | |
736 | static void print(char c) { |
737 | print(String.valueOf(c)); |
738 | } |
739 | |
740 | static void print_append(StringBuffer buf, String s, int max) { |
741 | synchronized(buf) { |
742 | buf.append(s); |
743 | max /= 2; |
744 | if (buf.length() > max) try { |
745 | int newLength = max/2; |
746 | int ofs = buf.length()-newLength; |
747 | String newString = buf.substring(ofs); |
748 | buf.setLength(0); |
749 | buf.append("[...] ").append(newString); |
750 | } catch (Exception e) { |
751 | buf.setLength(0); |
752 | } |
753 | } |
754 | } |
755 | static String getType(Object o) { |
756 | return getClassName(o); |
757 | } |
758 | static Map synchroHashMap() { |
759 | return Collections.synchronizedMap(new HashMap()); |
760 | } |
761 | |
762 | |
763 | |
764 | static WeakHashMap<Class, ArrayList<Method>> callF_cache = new WeakHashMap(); |
765 | |
766 | |
767 | |
768 | |
769 | static <A, B> B callF(F1<A, B> f, A a) { |
770 | return f == null ? null : f.get(a); |
771 | } |
772 | |
773 | |
774 | static Object callF(Object f, Object... args) { try { |
775 | if (f instanceof String) |
776 | return callMC((String) f, args); |
777 | if (f instanceof Runnable) { |
778 | ((Runnable) f).run(); |
779 | return null; |
780 | } |
781 | if (f == null) return null; |
782 | |
783 | Class c = f.getClass(); |
784 | ArrayList<Method> methods; |
785 | synchronized(callF_cache) { |
786 | methods = callF_cache.get(c); |
787 | if (methods == null) |
788 | methods = callF_makeCache(c); |
789 | } |
790 | |
791 | int n = l(methods); |
792 | if (n == 0) throw fail("No get method in " + getClassName(c)); |
793 | if (n == 1) return methods.get(0).invoke(f, args); |
794 | for (int i = 0; i < n; i++) { |
795 | Method m = methods.get(i); |
796 | if (call_checkArgs(m, args, false)) |
797 | return m.invoke(f, args); |
798 | } |
799 | throw fail("No matching get method in " + getClassName(c)); |
800 | } catch (Exception __e) { throw rethrow(__e); } } |
801 | |
802 | // used internally |
803 | static ArrayList<Method> callF_makeCache(Class c) { |
804 | ArrayList<Method> l = new ArrayList(); |
805 | Class _c = c; |
806 | do { |
807 | for (Method m : _c.getDeclaredMethods()) |
808 | if (m.getName().equals("get")) { |
809 | m.setAccessible(true); |
810 | l.add(m); |
811 | } |
812 | if (!l.isEmpty()) break; |
813 | _c = _c.getSuperclass(); |
814 | } while (_c != null); |
815 | callF_cache.put(c, l); |
816 | return l; |
817 | } |
818 | static Object callFunction(Object f, Object... args) { |
819 | return callF(f, args); |
820 | } |
821 | // extended over Class.isInstance() to handle primitive types |
822 | static boolean isInstanceX(Class type, Object arg) { |
823 | if (type == boolean.class) return arg instanceof Boolean; |
824 | if (type == int.class) return arg instanceof Integer; |
825 | if (type == long.class) return arg instanceof Long; |
826 | if (type == float.class) return arg instanceof Float; |
827 | if (type == short.class) return arg instanceof Short; |
828 | if (type == char.class) return arg instanceof Character; |
829 | if (type == byte.class) return arg instanceof Byte; |
830 | if (type == double.class) return arg instanceof Double; |
831 | return type.isInstance(arg); |
832 | } |
833 | static Throwable printStackTrace(Throwable e) { |
834 | // we go to system.out now - system.err is nonsense |
835 | print(getStackTrace(e)); |
836 | return e; |
837 | } |
838 | |
839 | static void printStackTrace() { |
840 | printStackTrace(new Throwable()); |
841 | } |
842 | |
843 | static void printStackTrace(String msg) { |
844 | printStackTrace(new Throwable(msg)); |
845 | } |
846 | |
847 | /*static void printStackTrace(S indent, Throwable e) { |
848 | if (endsWithLetter(indent)) indent += " "; |
849 | printIndent(indent, getStackTrace(e)); |
850 | }*/ |
851 | static boolean isFalse(Object o) { |
852 | return eq(false, o); |
853 | } |
854 | static String getClassName(Object o) { |
855 | return o == null ? "null" : o instanceof Class ? ((Class) o).getName() : o.getClass().getName(); |
856 | } |
857 | static String fixNewLines(String s) { |
858 | return s.replace("\r\n", "\n").replace("\r", "\n"); |
859 | } |
860 | static volatile boolean ping_pauseAll; |
861 | static int ping_sleep = 100; // poll pauseAll flag every 100 |
862 | |
863 | static volatile boolean ping_anyActions; |
864 | static Map<Thread, Object> ping_actions = newWeakHashMap(); |
865 | |
866 | |
867 | // always returns true |
868 | static boolean ping() { |
869 | if (ping_pauseAll || ping_anyActions ) ping_impl(); |
870 | return true; |
871 | } |
872 | |
873 | // returns true when it slept |
874 | static boolean ping_impl() { try { |
875 | if (ping_pauseAll && !isAWTThread()) { |
876 | do |
877 | Thread.sleep(ping_sleep); |
878 | while (ping_pauseAll); |
879 | return true; |
880 | } |
881 | |
882 | |
883 | if (ping_anyActions) { |
884 | Object action; |
885 | synchronized(ping_actions) { |
886 | action = ping_actions.get(currentThread()); |
887 | if (action instanceof Runnable) |
888 | ping_actions.remove(currentThread()); |
889 | if (ping_actions.isEmpty()) ping_anyActions = false; |
890 | } |
891 | |
892 | if (action instanceof Runnable) |
893 | ((Runnable) action).run(); |
894 | else if (eq(action, "cancelled")) |
895 | throw fail("Thread cancelled."); |
896 | } |
897 | |
898 | |
899 | return false; |
900 | } catch (Exception __e) { throw rethrow(__e); } } |
901 | static long sysNow() { |
902 | return System.nanoTime()/1000000; |
903 | } |
904 | static void assertTrue(Object o) { |
905 | if (!(eq(o, true) /*|| isTrue(pcallF(o))*/)) |
906 | throw fail(str(o)); |
907 | } |
908 | |
909 | static boolean assertTrue(String msg, boolean b) { |
910 | if (!b) |
911 | throw fail(msg); |
912 | return b; |
913 | } |
914 | |
915 | static boolean assertTrue(boolean b) { |
916 | if (!b) |
917 | throw fail("oops"); |
918 | return b; |
919 | } |
920 | static void incAtomicLong(AtomicLong l) { |
921 | l.incrementAndGet(); |
922 | } |
923 | static Class __javax; |
924 | |
925 | static Class getJavaX() { |
926 | return __javax; |
927 | } |
928 | static Throwable printStackTrace2(Throwable e) { |
929 | // we go to system.out now - system.err is nonsense |
930 | print(getStackTrace2(e)); |
931 | return e; |
932 | } |
933 | |
934 | static void printStackTrace2() { |
935 | printStackTrace2(new Throwable()); |
936 | } |
937 | |
938 | static void printStackTrace2(String msg) { |
939 | printStackTrace2(new Throwable(msg)); |
940 | } |
941 | |
942 | /*static void printStackTrace2(S indent, Throwable e) { |
943 | if (endsWithLetter(indent)) indent += " "; |
944 | printIndent(indent, getStackTrace2(e)); |
945 | }*/ |
946 | |
947 | |
948 | static HashMap<String, List<Method>> callMC_cache = new HashMap(); |
949 | static String callMC_key; |
950 | static Method callMC_value; |
951 | |
952 | // varargs assignment fixer for a single string array argument |
953 | static Object callMC(String method, String[] arg) { |
954 | return callMC(method, new Object[] {arg}); |
955 | } |
956 | |
957 | static Object callMC(String method, Object... args) { try { |
958 | Method me; |
959 | if (callMC_cache == null) callMC_cache = new HashMap(); // initializer time workaround |
960 | synchronized(callMC_cache) { |
961 | me = method == callMC_key ? callMC_value : null; |
962 | } |
963 | if (me != null) try { |
964 | return me.invoke(null, args); |
965 | } catch (IllegalArgumentException e) { |
966 | throw new RuntimeException("Can't call " + me + " with arguments " + classNames(args), e); |
967 | } |
968 | |
969 | List<Method> m; |
970 | synchronized(callMC_cache) { |
971 | m = callMC_cache.get(method); |
972 | } |
973 | if (m == null) { |
974 | if (callMC_cache.isEmpty()) { |
975 | callMC_makeCache(); |
976 | m = callMC_cache.get(method); |
977 | } |
978 | if (m == null) throw fail("Method named " + method + " not found in main"); |
979 | } |
980 | int n = m.size(); |
981 | if (n == 1) { |
982 | me = m.get(0); |
983 | synchronized(callMC_cache) { |
984 | callMC_key = method; |
985 | callMC_value = me; |
986 | } |
987 | try { |
988 | return me.invoke(null, args); |
989 | } catch (IllegalArgumentException e) { |
990 | throw new RuntimeException("Can't call " + me + " with arguments " + classNames(args), e); |
991 | } |
992 | } |
993 | for (int i = 0; i < n; i++) { |
994 | me = m.get(i); |
995 | if (call_checkArgs(me, args, false)) |
996 | return me.invoke(null, args); |
997 | } |
998 | throw fail("No method called " + method + " with matching arguments found in main"); |
999 | } catch (Exception __e) { throw rethrow(__e); } } |
1000 | |
1001 | static void callMC_makeCache() { |
1002 | synchronized(callMC_cache) { |
1003 | callMC_cache.clear(); |
1004 | Class _c = (Class) mc(), c = _c; |
1005 | while (c != null) { |
1006 | for (Method m : c.getDeclaredMethods()) |
1007 | if ((m.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0) { |
1008 | m.setAccessible(true); |
1009 | multiMapPut(callMC_cache, m.getName(), m); |
1010 | } |
1011 | c = c.getSuperclass(); |
1012 | } |
1013 | } |
1014 | } |
1015 | static String getStackTrace(Throwable throwable) { |
1016 | lastException(throwable); |
1017 | return getStackTrace_noRecord(throwable); |
1018 | } |
1019 | |
1020 | static String getStackTrace_noRecord(Throwable throwable) { |
1021 | StringWriter writer = new StringWriter(); |
1022 | throwable.printStackTrace(new PrintWriter(writer)); |
1023 | return hideCredentials(writer.toString()); |
1024 | } |
1025 | |
1026 | static String getStackTrace() { |
1027 | return getStackTrace_noRecord(new Throwable()); |
1028 | } |
1029 | // TODO: test if android complains about this |
1030 | static boolean isAWTThread() { |
1031 | if (isAndroid()) return false; |
1032 | if (isHeadless()) return false; |
1033 | return isAWTThread_awt(); |
1034 | } |
1035 | |
1036 | static boolean isAWTThread_awt() { |
1037 | return SwingUtilities.isEventDispatchThread(); |
1038 | } |
1039 | static String getStackTrace2(Throwable throwable) { |
1040 | return hideCredentials(getStackTrace(throwable) + replacePrefix("java.lang.RuntimeException: ", "FAIL: ", |
1041 | hideCredentials(str(getInnerException(throwable)))) + "\n"); |
1042 | } |
1043 | static Thread currentThread() { |
1044 | return Thread.currentThread(); |
1045 | } |
1046 | static RuntimeException rethrow(Throwable e) { |
1047 | throw asRuntimeException(e); |
1048 | } |
1049 | |
1050 | |
1051 | static volatile Throwable lastException_lastException; |
1052 | |
1053 | static Throwable lastException() { |
1054 | return lastException_lastException; |
1055 | } |
1056 | |
1057 | static void lastException(Throwable e) { |
1058 | lastException_lastException = e; |
1059 | } |
1060 | static Boolean isHeadless_cache; |
1061 | |
1062 | static boolean isHeadless() { |
1063 | if (isHeadless_cache != null) return isHeadless_cache; |
1064 | if (GraphicsEnvironment.isHeadless()) return isHeadless_cache = true; |
1065 | |
1066 | // Also check if AWT actually works. |
1067 | // If DISPLAY variable is set but no X server up, this will notice. |
1068 | |
1069 | try { |
1070 | SwingUtilities.isEventDispatchThread(); |
1071 | return isHeadless_cache = false; |
1072 | } catch (Throwable e) { return isHeadless_cache = true; } |
1073 | } |
1074 | static List<String> classNames(Collection l) { |
1075 | return getClassNames(l); |
1076 | } |
1077 | |
1078 | static List<String> classNames(Object[] l) { |
1079 | return getClassNames(Arrays.asList(l)); |
1080 | } |
1081 | static Class mc() { |
1082 | return main.class; |
1083 | } |
1084 | static <A, B> void multiMapPut(Map<A, List<B>> map, A a, B b) { |
1085 | List<B> l = map.get(a); |
1086 | if (l == null) |
1087 | map.put(a, l = new ArrayList()); |
1088 | l.add(b); |
1089 | } |
1090 | static String replacePrefix(String prefix, String replacement, String s) { |
1091 | if (!startsWith(s, prefix)) return s; |
1092 | return replacement + substring(s, l(prefix)); |
1093 | } |
1094 | static String hideCredentials(URL url) { return url == null ? null : hideCredentials(str(url)); } |
1095 | |
1096 | static String hideCredentials(String url) { |
1097 | return url.replaceAll("([&?])_pass=[^&\\s\"]*", "$1_pass=<hidden>"); |
1098 | } |
1099 | static Throwable getInnerException(Throwable e) { |
1100 | while (e.getCause() != null) |
1101 | e = e.getCause(); |
1102 | return e; |
1103 | } |
1104 | static int isAndroid_flag; |
1105 | |
1106 | static boolean isAndroid() { |
1107 | if (isAndroid_flag == 0) |
1108 | isAndroid_flag = System.getProperty("java.vendor").toLowerCase().indexOf("android") >= 0 ? 1 : -1; |
1109 | return isAndroid_flag > 0; |
1110 | } |
1111 | |
1112 | |
1113 | |
1114 | static String substring(String s, int x) { |
1115 | return substring(s, x, l(s)); |
1116 | } |
1117 | |
1118 | static String substring(String s, int x, int y) { |
1119 | if (s == null) return null; |
1120 | if (x < 0) x = 0; |
1121 | if (x > s.length()) return ""; |
1122 | if (y < x) y = x; |
1123 | if (y > s.length()) y = s.length(); |
1124 | return s.substring(x, y); |
1125 | } |
1126 | |
1127 | |
1128 | static List<String> getClassNames(Collection l) { |
1129 | List<String> out = new ArrayList(); |
1130 | if (l != null) for (Object o : l) |
1131 | out.add(o == null ? null : getClassName(o)); |
1132 | return out; |
1133 | } |
1134 | static boolean startsWith(String a, String b) { |
1135 | return a != null && a.startsWith(b); |
1136 | } |
1137 | |
1138 | static boolean startsWith(String a, char c) { |
1139 | return nempty(a) && a.charAt(0) == c; |
1140 | } |
1141 | |
1142 | |
1143 | |
1144 | static boolean startsWith(List a, List b) { |
1145 | if (a == null || l(b) > l(a)) return false; |
1146 | for (int i = 0; i < l(b); i++) |
1147 | if (neq(a.get(i), b.get(i))) |
1148 | return false; |
1149 | return true; |
1150 | } |
1151 | |
1152 | |
1153 | |
1154 | |
1155 | static boolean nempty(Collection c) { |
1156 | return !isEmpty(c); |
1157 | } |
1158 | |
1159 | static boolean nempty(CharSequence s) { |
1160 | return !isEmpty(s); |
1161 | } |
1162 | |
1163 | static boolean nempty(Object[] o) { |
1164 | return !isEmpty(o); |
1165 | } |
1166 | |
1167 | static boolean nempty(Map m) { |
1168 | return !isEmpty(m); |
1169 | } |
1170 | |
1171 | static boolean nempty(Iterator i) { |
1172 | return i != null && i.hasNext(); |
1173 | } |
1174 | |
1175 | |
1176 | static boolean isEmpty(Collection c) { |
1177 | return c == null || c.isEmpty(); |
1178 | } |
1179 | |
1180 | static boolean isEmpty(CharSequence s) { |
1181 | return s == null || s.length() == 0; |
1182 | } |
1183 | |
1184 | static boolean isEmpty(Object[] a) { |
1185 | return a == null || a.length == 0; |
1186 | } |
1187 | |
1188 | static boolean isEmpty(Map map) { |
1189 | return map == null || map.isEmpty(); |
1190 | } |
1191 | |
1192 | |
1193 | static abstract class F1<A, B> { |
1194 | abstract B get(A a); |
1195 | }static class Pair<A, B> { |
1196 | A a; |
1197 | B b; |
1198 | |
1199 | Pair() {} |
1200 | Pair(A a, B b) { |
1201 | this.b = b; |
1202 | this.a = a;} |
1203 | |
1204 | public int hashCode() { |
1205 | return hashCodeFor(a) + 2*hashCodeFor(b); |
1206 | } |
1207 | |
1208 | public boolean equals(Object o) { |
1209 | if (o == this) return true; |
1210 | if (!(o instanceof Pair)) return false; |
1211 | Pair t = (Pair) o; |
1212 | return eq(a, t.a) && eq(b, t.b); |
1213 | } |
1214 | |
1215 | public String toString() { |
1216 | return "<" + a + ", " + b + ">"; |
1217 | } |
1218 | } |
1219 | |
1220 | static int hashCodeFor(Object a) { |
1221 | return a == null ? 0 : a.hashCode(); |
1222 | } |
1223 | |
1224 | } |
Snippet is not live.
Travelled to 12 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #3000489 |
Snippet name: | Smart Bot's answer to: !eval transpileRaw("please include function tok_parseFunctionCall.") |
Eternal ID of this version: | #3000489/1 |
Text MD5: | 341ad459d7668e3b69cf6c9ac71e23f1 |
Author: | someone |
Category: | |
Type: | New Tinybrain snippet |
Gummipassword: | smart-bot-for-user |
Uploaded from IP: | 82.83.65.128 |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2017-12-25 18:32:52 |
Source code size: | 34903 bytes / 1224 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 318 / 98 |
Referenced in: | [show references] |